1
0
mirror of https://github.com/Infisical/infisical.git synced 2025-03-19 19:00:44 +00:00

Compare commits

..

106 Commits

Author SHA1 Message Date
f45074a2dd Fix: Learn more button 2024-03-04 17:16:59 +01:00
9e38076d45 Merge pull request from rhythmbhiwani/remove-nested-anchor-tags
Changed <a> to <div> to avoid nested <a>
2024-03-04 11:58:32 +05:30
d3a6da187b add execute + polling interval 2024-03-03 23:59:40 -05:00
7a90fa472d Changed span to div 2024-03-03 15:05:04 +05:30
0dd34eae60 Update components.mdx 2024-03-02 13:39:15 -08:00
846e2f21cc Merge pull request from Grraahaam/fix/typo
chore(doc): fix typo
2024-03-02 16:36:26 -05:00
16acace648 Change <a> to <span> to avoid nested <a> 2024-03-02 20:00:47 +05:30
60134cf8ac chore(doc): fix typo 2024-03-02 14:24:37 +01:00
5feb942d79 Add API-level length restrictions to name and slug for organizations and projects 2024-03-01 19:04:42 -08:00
ae2706542c Merge pull request from Infisical/google-saml
Add support and docs for Google SAML
2024-03-01 17:00:35 -08:00
d5861493bf Add support and docs for Google SAML 2024-03-01 16:56:37 -08:00
53044f3d39 reduce ttl 2024-03-01 15:06:36 -05:00
93268f5767 increase license server ttl 2024-03-01 13:06:00 -05:00
318dedb987 Merge pull request from akhilmhdh/fix/delay-audit-log
feat(server): moved back audit log to queue now with keystore license
2024-03-01 12:36:22 -05:00
291edf71aa feat(server): moved back audit log to queue now with keystore license 2024-03-01 23:01:18 +05:30
342665783e Merge pull request from akhilmhdh/fix/delay-audit-log
feat(server): changed license service to use redis cache keystore
2024-03-01 11:53:58 -05:00
6a7241d7d1 feat(server): uninstalled node-cache 2024-03-01 22:20:25 +05:30
51fb680f9c feat(server): changed license service to use redis cache keystore 2024-03-01 22:16:08 +05:30
0710c9a84a Merge pull request from rhythmbhiwani/fix-etag-hash-mistype
Fixed mistype from Hash to Etag to fix the cli issue
2024-03-01 17:31:09 +01:00
e46bce1520 Update requirements.mdx 2024-03-01 10:55:19 -05:00
3919393d33 Merge pull request from akhilmhdh/fix/audit-log-queue
fix(server): auditlog won't push if retention period is zero
2024-03-01 10:27:49 -05:00
c8b7c37aee fix(server): identity login audit log fixed 2024-03-01 20:10:27 +05:30
2641fccce5 add etag field 2024-03-01 09:05:44 -05:00
213f2ed29b fix(server): auditlog won't push if retention period is zero 2024-03-01 19:24:29 +05:30
4dcd000dd1 Fixed mistype from Hash to Etag to fix the cli issue 2024-03-01 17:43:47 +05:30
f64cb10282 Merge pull request from Infisical/daniel/agent-improvements
Feat: Agent exec and custom polling interval
2024-03-01 02:13:13 -05:00
a0ea2627ed change hash to etag 2024-03-01 02:11:50 -05:00
5c40b538af remove ExecuteCommandWithTimeout 2024-03-01 02:11:27 -05:00
8dd94a4e10 move ExecuteCommandWithTimeout to agent file 2024-03-01 02:11:03 -05:00
041c4a20a0 example config 2024-03-01 02:10:26 -05:00
4a2a5f42a8 Renamed to exec to execute, and cleanup 🧼 2024-03-01 07:26:31 +01:00
9fcdf17a04 Update agent.go 2024-03-01 07:17:27 +01:00
97ac8cb45a Update agent.go 2024-03-01 07:02:26 +01:00
e952659415 Update agent.go 2024-03-01 07:02:04 +01:00
1f3f061a06 Fix: Agent output 2024-03-01 06:46:09 +01:00
5096ce3bdc Feat: Agent improvements 2024-03-01 06:41:17 +01:00
621683f787 Merge pull request from Infisical/changelog
Update changelog to include updates for Feb
2024-02-29 19:19:37 -08:00
f63850e9e9 Add February updates to changelog 2024-02-29 19:17:58 -08:00
4ee0a2ec6c update mongo to postgres pin 2024-02-29 18:03:04 -05:00
9569d3971a update helm secrets def in docs 2024-02-29 18:01:57 -05:00
443b8f747b Update kubernetes-helm.mdx 2024-02-29 17:54:53 -05:00
803393c385 Update 20240226094411_instance-id.ts 2024-02-29 17:47:24 -05:00
8e95189fd2 Merge pull request from Infisical/snyk-upgrade-f77609d160bda3cea5e59890389a6fda
[Snyk] Upgrade posthog-node from 3.6.0 to 3.6.2
2024-02-29 17:40:32 -05:00
c5f38b6ade Merge pull request from Infisical/patch-super-user-migration
update admin config to  default uuid if it doesn't exist
2024-02-29 17:11:15 -05:00
30a1c5ac86 only add admin config if it doesn't exist 2024-02-29 17:01:03 -05:00
bbad2ba047 fix: upgrade posthog-node from 3.6.0 to 3.6.2
Snyk has created this PR to upgrade posthog-node from 3.6.0 to 3.6.2.

See this package in npm:
https://www.npmjs.com/package/posthog-node

See this project in Snyk:
https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr
2024-02-29 21:47:31 +00:00
1445df7015 Merge pull request from Infisical/patch-super-user-migration
patch super user migration
2024-02-29 16:35:56 -05:00
ae4a2089d5 ignore whole file 2024-02-29 16:30:58 -05:00
0b924b6e45 add ignore type script 2024-02-29 16:28:36 -05:00
1fcac4cadf ignore multi line eslint 2024-02-29 16:15:52 -05:00
155e315347 skip verify 2024-02-29 16:00:28 -05:00
3dce03180f patch super user migration 2024-02-29 15:35:54 -05:00
4748b546c2 Merge pull request from Infisical/add-cert-to-knex-command
Add postgres cert to migration knex command
2024-02-29 15:05:55 -05:00
96887cdbfa add cert support to knex migration 2024-02-29 14:37:01 -05:00
553b56e57e fix make down command from Makefile 2024-02-29 14:18:33 -05:00
a33f542647 Merge pull request from akhilmhdh/fix/dup-sec-del
fix(server): duplicate secret deletion made possible
2024-02-29 14:16:44 -05:00
06b03fc450 update fnSecretBlindIndexCheck function comment 2024-02-29 14:01:32 -05:00
031a834ab1 Merge pull request from Salman2301/feat-cloud-worker-path
feat: add support for secret path for cloud worker
2024-02-29 12:24:44 -05:00
89e942fea3 Merge pull request from Infisical/tag-migration-guide
update mongo to postgres doc
2024-02-29 22:28:43 +05:30
3c0908a788 update mongo to postgres doc 2024-02-29 11:56:48 -05:00
14e42b7ff2 feat: add support for secret path for cloud worker 2024-02-29 21:40:19 +05:30
9476594978 Merge pull request from akhilmhdh/fix/migration-admin-bug
fix(pg-migrator): added uuid 0000 for admin config
2024-02-29 10:57:26 -05:00
02be9ebd5e Merge pull request from akhilmhdh/fix/create-tag 2024-02-29 09:03:18 -05:00
eb29d1dc28 fix(pg-migrator): added uuid 0000 for admin config 2024-02-29 15:38:45 +05:30
21d5c44ea1 fix(server): duplicate secret deletion made possible 2024-02-29 14:58:45 +05:30
114a4b1412 fix(server): resolved broken create tag scoped to project 2024-02-29 13:02:09 +05:30
fb8c4bd415 Feat: Agent improvements 2024-02-29 07:12:30 +01:00
48bf41ac8c Update cli.go 2024-02-29 07:12:18 +01:00
1ad916a784 Feat: Agent improvements, Secrets state manager 2024-02-29 07:12:10 +01:00
c91456838e Update model.go 2024-02-29 07:12:01 +01:00
79efe64504 Feat: Agent improvements, get ETag from secrets request 2024-02-29 07:11:56 +01:00
cde8cef8b0 Merge pull request from 24601/patch-1
fix(helm-charts): standalone chart rbac fix for jobs
2024-02-28 22:41:27 -05:00
7207997cea update chart version 2024-02-28 22:40:15 -05:00
aaabfb7870 fix(helm-charts): standalone chart rbac fix for jobs 2024-02-28 19:31:16 -07:00
40cb5c4394 Merge pull request from quinton11/feat/cli-export-with-tag-slugs
feat: cli export allow filtering with tags
2024-02-28 18:32:22 -05:00
60b73879df Update postgres.mdx 2024-02-28 14:40:04 -08:00
4339ef4737 Merge pull request from Infisical/snyk-upgrade-14579311c8ea1dfb5d579851318fccc5
[Snyk] Upgrade posthog-js from 1.104.4 to 1.105.4
2024-02-28 16:59:28 -05:00
d98669700d Merge pull request from nhedger/docs/docker
docs: improve docker page
2024-02-28 16:59:18 -05:00
162f339149 Merge pull request from Infisical/snyk-upgrade-978758f53696a9f0d6b71883b9614b0a
[Snyk] Upgrade aws-sdk from 2.1549.0 to 2.1553.0
2024-02-28 16:48:35 -05:00
d3eb0c4cc9 Merge pull request from Kiskadee-dev/patch-1
fix postgresql volume path on docker-compose.prod.yml
2024-02-28 16:35:15 -05:00
4b4295f53d fix: upgrade aws-sdk from 2.1549.0 to 2.1553.0
Snyk has created this PR to upgrade aws-sdk from 2.1549.0 to 2.1553.0.

See this package in npm:
https://www.npmjs.com/package/aws-sdk

See this project in Snyk:
https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr
2024-02-28 21:11:42 +00:00
6c4d193b12 Update docker-compose.prod.yml
/data/db doesn't seems to exist, would never persist data otherwise
2024-02-28 16:27:16 -03:00
d08d412f54 improve more 2024-02-28 20:21:43 +01:00
bb4810470f docs: rewording 2024-02-28 20:20:39 +01:00
24e9c0a39f Merge pull request from nhedger/docs/secrets
docs: fix typo
2024-02-28 14:07:00 -05:00
3161d0ee67 docs: fix typo 2024-02-28 20:01:57 +01:00
8a7e18dc7c fix: upgrade posthog-js from 1.104.4 to 1.105.4
Snyk has created this PR to upgrade posthog-js from 1.104.4 to 1.105.4.

See this package in npm:
https://www.npmjs.com/package/posthog-js

See this project in Snyk:
https://app.snyk.io/org/maidul98/project/53d4ecb6-6cc1-4918-aa73-bf9cae4ffd13?utm_source=github&utm_medium=referral&page=upgrade-pr
2024-02-28 18:49:06 +00:00
0497c3b49e Merge pull request from akhilmhdh/feat/i18n-removal
feat(ui): secret blind index banner in secret main page and removed i18n to keep only english for now
2024-02-28 11:09:35 -05:00
e6a89fb9d0 feat(ui): secret blind index banner in secret main page and removed i18n translations for now by keeping en as only option 2024-02-28 14:47:50 +05:30
d9828db2ec update gamma helm values 2024-02-27 18:51:36 -05:00
f11efc9e3f Merge pull request from Infisical/snyk-upgrade-430437d73f24d5cfbeaa8f5f8f1fa7dc
[Snyk] Upgrade posthog-js from 1.103.0 to 1.104.4
2024-02-27 18:43:09 -05:00
32bad10c0e Merge branch 'main' into snyk-upgrade-430437d73f24d5cfbeaa8f5f8f1fa7dc 2024-02-27 18:43:03 -05:00
41064920f7 Merge pull request from Infisical/snyk-upgrade-29c4ba3e253755510159e658916d2c3f
[Snyk] Upgrade @fastify/cookie from 9.2.0 to 9.3.1
2024-02-27 18:41:33 -05:00
8d8e23add2 Merge pull request from akhilmhdh/feat/telemetry-aggregation
Telemetry stats event for self hosted instance on midnight
2024-02-27 18:36:29 -05:00
a2a959cc32 disable telemetry for local dev by default 2024-02-27 18:26:15 -05:00
d6cde48181 set posthog flush to zero and fix typos 2024-02-27 18:23:24 -05:00
23966c12e2 Merge pull request from Infisical/daniel/fix-invite-all-members
Fix: Invite all members to project when there are no members to invite
2024-02-27 17:38:52 -05:00
2a233ea43c Fix: Inviting all members when there's only 1 user in the organization 2024-02-27 23:15:40 +01:00
fe497d87c0 add INFISICAL_CLOUD env back from old backend 2024-02-27 16:38:18 -05:00
3b9ceff21c refactor(server): updated all telemetry send events to await as changed to async 2024-02-26 19:52:38 +05:30
d64d935d7d feat(server): added telemetry queue for self hosted to upload instance stats to posthog on midnight 2024-02-26 19:52:38 +05:30
8aaed739d5 feat(server): resolved a possible race condition on replication on frest first boot up and fixed making values optional on create rows for generate schema 2024-02-26 19:52:38 +05:30
7d8b399102 feat(server): added keystore and made server cfg fetch from keystore to avoid db calls 2024-02-26 19:52:38 +05:30
1594165768 fix: upgrade @fastify/cookie from 9.2.0 to 9.3.1
Snyk has created this PR to upgrade @fastify/cookie from 9.2.0 to 9.3.1.

See this package in npm:
https://www.npmjs.com/package/@fastify/cookie

See this project in Snyk:
https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr
2024-02-25 03:14:18 +00:00
29d91d83ab fix: upgrade posthog-js from 1.103.0 to 1.104.4
Snyk has created this PR to upgrade posthog-js from 1.103.0 to 1.104.4.

See this package in npm:
https://www.npmjs.com/package/posthog-js

See this project in Snyk:
https://app.snyk.io/org/maidul98/project/53d4ecb6-6cc1-4918-aa73-bf9cae4ffd13?utm_source=github&utm_medium=referral&page=upgrade-pr
2024-02-24 04:51:43 +00:00
4057e2c6ab feat: cli export allow filtering with tags 2024-01-24 19:05:16 +00:00
143 changed files with 1127 additions and 572 deletions
.github
Makefile
backend
e2e-test
package-lock.jsonpackage.json
scripts
src
cache
db
ee
routes/v1
services
audit-log
license
saml-config
secret-rotation/secret-rotation-queue
secret-scanning/secret-scanning-queue
keystore
lib/config
main.ts
queue
server
services
cli
docker-compose.dev.ymldocker-compose.prod.yml
docs
frontend
package-lock.jsonpackage.json
src
components/v2
Menu
UpgradeProjectAlert
i18n.ts
pages/integrations/cloudflare-workers
views
SecretMainPage
Settings
OrgSettingsPage/components/OrgAuthTab
PersonalSettingsPage/PersonalGeneralTab
helm-charts/infisical-standalone-postgres
pg-migrator/src

13
.github/values.yaml vendored

@ -13,11 +13,10 @@ fullnameOverride: ""
##
infisical:
## @param backend.enabled Enable backend
##
autoDatabaseSchemaMigration: false
enabled: false
## @param backend.name Backend name
##
name: infisical
replicaCount: 3
image:
@ -50,3 +49,9 @@ ingress:
- secretName: letsencrypt-prod
hosts:
- gamma.infisical.com
postgresql:
enabled: false
redis:
enabled: false

@ -11,4 +11,4 @@ up-prod:
docker-compose -f docker-compose.prod.yml up --build
down:
docker-compose down
docker compose -f docker-compose.dev.yml down

@ -0,0 +1,30 @@
import { TKeyStoreFactory } from "@app/keystore/keystore";
export const mockKeyStore = (): TKeyStoreFactory => {
const store: Record<string, string | number | Buffer> = {};
return {
setItem: async (key, value) => {
store[key] = value;
return "OK";
},
setItemWithExpiry: async (key, value) => {
store[key] = value;
return "OK";
},
deleteItem: async (key) => {
delete store[key];
return 1;
},
getItem: async (key) => {
const value = store[key];
if (typeof value === "string") {
return value;
}
return null;
},
incrementBy: async () => {
return 1;
}
};
};

@ -14,6 +14,7 @@ import { AuthTokenType } from "@app/services/auth/auth-type";
import { mockQueue } from "./mocks/queue";
import { mockSmtpServer } from "./mocks/smtp";
import { mockKeyStore } from "./mocks/keystore";
dotenv.config({ path: path.join(__dirname, "../../.env.test"), debug: true });
export default {
@ -41,7 +42,8 @@ export default {
await db.seed.run();
const smtp = mockSmtpServer();
const queue = mockQueue();
const server = await main({ db, smtp, logger, queue });
const keyStore = mockKeyStore();
const server = await main({ db, smtp, logger, queue, keyStore });
// @ts-expect-error type
globalThis.testServer = server;
// @ts-expect-error type

@ -11,7 +11,7 @@
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.504.0",
"@casl/ability": "^6.5.0",
"@fastify/cookie": "^9.2.0",
"@fastify/cookie": "^9.3.1",
"@fastify/cors": "^8.5.0",
"@fastify/etag": "^5.1.0",
"@fastify/formbody": "^7.4.0",
@ -29,7 +29,7 @@
"@ucast/mongo2js": "^1.3.4",
"ajv": "^8.12.0",
"argon2": "^0.31.2",
"aws-sdk": "^2.1549.0",
"aws-sdk": "^2.1553.0",
"axios": "^1.6.7",
"axios-retry": "^4.0.0",
"bcrypt": "^5.1.1",
@ -47,17 +47,15 @@
"lodash.isequal": "^4.5.0",
"mysql2": "^3.9.1",
"nanoid": "^5.0.4",
"node-cache": "^5.1.2",
"nodemailer": "^6.9.9",
"ora": "^7.0.1",
"passport-github": "^1.1.0",
"passport-gitlab2": "^5.0.0",
"passport-google-oauth20": "^2.0.0",
"passport-openidconnect": "^0.1.2",
"pg": "^8.11.3",
"picomatch": "^3.0.1",
"pino": "^8.16.2",
"posthog-node": "^3.6.0",
"posthog-node": "^3.6.2",
"probot": "^13.0.0",
"smee-client": "^2.0.0",
"tweetnacl": "^1.0.3",
@ -77,7 +75,6 @@
"@types/nodemailer": "^6.4.14",
"@types/passport-github": "^1.1.12",
"@types/passport-google-oauth20": "^2.0.14",
"@types/passport-openidconnect": "^0.1.3",
"@types/pg": "^8.10.9",
"@types/picomatch": "^2.3.3",
"@types/prompt-sync": "^4.2.3",
@ -1689,9 +1686,9 @@
}
},
"node_modules/@fastify/cookie": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/@fastify/cookie/-/cookie-9.2.0.tgz",
"integrity": "sha512-fkg1yjjQRHPFAxSHeLC8CqYuNzvR6Lwlj/KjrzQcGjNBK+K82nW+UfCjfN71g1GkoVoc1GTOgIWkFJpcMfMkHQ==",
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@fastify/cookie/-/cookie-9.3.1.tgz",
"integrity": "sha512-h1NAEhB266+ZbZ0e9qUE6NnNR07i7DnNXWG9VbbZ8uC6O/hxHpl+Zoe5sw1yfdZ2U6XhToUGDnzQtWJdCaPwfg==",
"dependencies": {
"cookie-signature": "^1.1.0",
"fastify-plugin": "^4.0.0"
@ -4074,18 +4071,6 @@
"@types/passport": "*"
}
},
"node_modules/@types/passport-openidconnect": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@types/passport-openidconnect/-/passport-openidconnect-0.1.3.tgz",
"integrity": "sha512-k1Ni7bG/9OZNo2Qpjg2W6GajL+pww6ZPaNWMXfpteCX4dXf4QgaZLt2hjR5IiPrqwBT9+W8KjCTJ/uhGIoBx/g==",
"dev": true,
"dependencies": {
"@types/express": "*",
"@types/oauth": "*",
"@types/passport": "*",
"@types/passport-strategy": "*"
}
},
"node_modules/@types/passport-strategy": {
"version": "0.2.38",
"resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
@ -5200,9 +5185,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/aws-sdk": {
"version": "2.1549.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1549.0.tgz",
"integrity": "sha512-SoVfrrV3A2mxH+NV2tA0eMtG301glhewvhL3Ob4107qLWjvwjy/CoWLclMLmfXniTGxbI8tsgN0r5mLZUKey3Q==",
"version": "2.1553.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1553.0.tgz",
"integrity": "sha512-CfZaw8dR9e642aBOeFhkFL7KoQApeLR15uH2IQqfL/12snWYayAAesYh0tEaU+XbhrH0CUsf2Zro5IraEXEZMg==",
"dependencies": {
"buffer": "4.9.2",
"events": "1.1.1",
@ -5720,14 +5705,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
@ -9272,17 +9249,6 @@
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
},
"node_modules/node-cache": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz",
"integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==",
"dependencies": {
"clone": "2.x"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@ -9808,27 +9774,6 @@
"url": "https://github.com/sponsors/jaredhanson"
}
},
"node_modules/passport-openidconnect": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/passport-openidconnect/-/passport-openidconnect-0.1.2.tgz",
"integrity": "sha512-JX3rTyW+KFZ/E9OF/IpXJPbyLO9vGzcmXB5FgSP2jfL3LGKJPdV7zUE8rWeKeeI/iueQggOeFa3onrCmhxXZTg==",
"dependencies": {
"oauth": "0.10.x",
"passport-strategy": "1.x.x"
},
"engines": {
"node": ">= 0.6.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/jaredhanson"
}
},
"node_modules/passport-openidconnect/node_modules/oauth": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.0.tgz",
"integrity": "sha512-1orQ9MT1vHFGQxhuy7E/0gECD3fd2fCC+PIX+/jgmU/gI3EpRocXtmtvxCO5x3WZ443FLTLFWNDjl5MPJf9u+Q=="
},
"node_modules/passport-strategy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
@ -10353,9 +10298,9 @@
"dev": true
},
"node_modules/posthog-node": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-3.6.0.tgz",
"integrity": "sha512-N/4//SIQR4fhwbHnDdJ2rQCYdu9wo0EVPK4lVgZswp5R/E42RKlpuO6ZfPsBl+Bcg06OYiOd/WR/jLV90FCoSw==",
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-3.6.2.tgz",
"integrity": "sha512-tVIaShR3SxBx17AlAUS86jQTweKuJIFRedBB504fCz7YPnXJTYSrVcUHn5IINE2wu4jUQimQK6ihQr90Djrdrg==",
"dependencies": {
"axios": "^1.6.2",
"rusha": "^0.8.14"

@ -41,7 +41,6 @@
"@types/nodemailer": "^6.4.14",
"@types/passport-github": "^1.1.12",
"@types/passport-google-oauth20": "^2.0.14",
"@types/passport-openidconnect": "^0.1.3",
"@types/pg": "^8.10.9",
"@types/picomatch": "^2.3.3",
"@types/prompt-sync": "^4.2.3",
@ -73,7 +72,7 @@
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.504.0",
"@casl/ability": "^6.5.0",
"@fastify/cookie": "^9.2.0",
"@fastify/cookie": "^9.3.1",
"@fastify/cors": "^8.5.0",
"@fastify/etag": "^5.1.0",
"@fastify/formbody": "^7.4.0",
@ -91,7 +90,7 @@
"@ucast/mongo2js": "^1.3.4",
"ajv": "^8.12.0",
"argon2": "^0.31.2",
"aws-sdk": "^2.1549.0",
"aws-sdk": "^2.1553.0",
"axios": "^1.6.7",
"axios-retry": "^4.0.0",
"bcrypt": "^5.1.1",
@ -109,17 +108,15 @@
"lodash.isequal": "^4.5.0",
"mysql2": "^3.9.1",
"nanoid": "^5.0.4",
"node-cache": "^5.1.2",
"nodemailer": "^6.9.9",
"ora": "^7.0.1",
"passport-github": "^1.1.0",
"passport-gitlab2": "^5.0.0",
"passport-google-oauth20": "^2.0.0",
"passport-openidconnect": "^0.1.2",
"pg": "^8.11.3",
"picomatch": "^3.0.1",
"pino": "^8.16.2",
"posthog-node": "^3.6.0",
"posthog-node": "^3.6.2",
"probot": "^13.0.0",
"smee-client": "^2.0.0",
"tweetnacl": "^1.0.3",

@ -44,7 +44,7 @@ const getZodDefaultValue = (type: unknown, value: string | number | boolean | Ob
if (!value || value === "null") return;
switch (type) {
case "uuid":
return;
return `.default("00000000-0000-0000-0000-000000000000")`;
case "character varying": {
if (value === "gen_random_uuid()") return;
if (typeof value === "string" && value.includes("::")) {
@ -100,7 +100,8 @@ const main = async () => {
const columnName = columnNames[colNum];
const colInfo = columns[columnName];
let ztype = getZodPrimitiveType(colInfo.type);
if (colInfo.defaultValue) {
// don't put optional on id
if (colInfo.defaultValue && columnName !== "id") {
const { defaultValue } = colInfo;
const zSchema = getZodDefaultValue(colInfo.type, defaultValue);
if (zSchema) {
@ -120,6 +121,7 @@ const main = async () => {
.split("_")
.reduce((prev, curr) => prev + `${curr.at(0)?.toUpperCase()}${curr.slice(1).toLowerCase()}`, "");
// the insert and update are changed to zod input type to use default cases
writeFileSync(
path.join(__dirname, "../src/db/schemas", `${dashcase}.ts`),
`// Code generated by automation script, DO NOT EDIT.
@ -134,8 +136,8 @@ import { TImmutableDBKeys } from "./models";
export const ${pascalCase}Schema = z.object({${schema}});
export type T${pascalCase} = z.infer<typeof ${pascalCase}Schema>;
export type T${pascalCase}Insert = Omit<T${pascalCase}, TImmutableDBKeys>;
export type T${pascalCase}Update = Partial<Omit<T${pascalCase}, TImmutableDBKeys>>;
export type T${pascalCase}Insert = Omit<z.input<typeof ${pascalCase}Schema>, TImmutableDBKeys>;
export type T${pascalCase}Update = Partial<Omit<z.input<typeof ${pascalCase}Schema>, TImmutableDBKeys>>;
`
);
}

@ -1,6 +0,0 @@
import Redis from "ioredis";
export const initRedisConnection = (redisUrl: string) => {
const redis = new Redis(redisUrl);
return redis;
};

@ -17,7 +17,15 @@ dotenv.config({
export default {
development: {
client: "postgres",
connection: process.env.DB_CONNECTION_URI,
connection: {
connectionString: process.env.DB_CONNECTION_URI,
ssl: process.env.DB_ROOT_CERT
? {
rejectUnauthorized: true,
ca: Buffer.from(process.env.DB_ROOT_CERT, "base64").toString("ascii")
}
: false
},
pool: {
min: 2,
max: 10
@ -31,7 +39,15 @@ export default {
},
production: {
client: "postgres",
connection: process.env.DB_CONNECTION_URI,
connection: {
connectionString: process.env.DB_CONNECTION_URI,
ssl: process.env.DB_ROOT_CERT
? {
rejectUnauthorized: true,
ca: Buffer.from(process.env.DB_ROOT_CERT, "base64").toString("ascii")
}
: false
},
pool: {
min: 2,
max: 10

@ -0,0 +1,25 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import { Knex } from "knex";
import { TableName } from "../schemas";
const ADMIN_CONFIG_UUID = "00000000-0000-0000-0000-000000000000";
export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable(TableName.SuperAdmin, (t) => {
t.uuid("instanceId").notNullable().defaultTo(knex.fn.uuid());
});
const superUserConfigExists = await knex(TableName.SuperAdmin).where("id", ADMIN_CONFIG_UUID).first();
if (!superUserConfigExists) {
// eslint-disable-next-line
await knex(TableName.SuperAdmin).update({ id: ADMIN_CONFIG_UUID }).whereNotNull("id").limit(1);
}
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.alterTable(TableName.SuperAdmin, (t) => {
t.dropColumn("instanceId");
});
}

@ -19,5 +19,5 @@ export const ApiKeysSchema = z.object({
});
export type TApiKeys = z.infer<typeof ApiKeysSchema>;
export type TApiKeysInsert = Omit<TApiKeys, TImmutableDBKeys>;
export type TApiKeysUpdate = Partial<Omit<TApiKeys, TImmutableDBKeys>>;
export type TApiKeysInsert = Omit<z.input<typeof ApiKeysSchema>, TImmutableDBKeys>;
export type TApiKeysUpdate = Partial<Omit<z.input<typeof ApiKeysSchema>, TImmutableDBKeys>>;

@ -24,5 +24,5 @@ export const AuditLogsSchema = z.object({
});
export type TAuditLogs = z.infer<typeof AuditLogsSchema>;
export type TAuditLogsInsert = Omit<TAuditLogs, TImmutableDBKeys>;
export type TAuditLogsUpdate = Partial<Omit<TAuditLogs, TImmutableDBKeys>>;
export type TAuditLogsInsert = Omit<z.input<typeof AuditLogsSchema>, TImmutableDBKeys>;
export type TAuditLogsUpdate = Partial<Omit<z.input<typeof AuditLogsSchema>, TImmutableDBKeys>>;

@ -20,5 +20,5 @@ export const AuthTokenSessionsSchema = z.object({
});
export type TAuthTokenSessions = z.infer<typeof AuthTokenSessionsSchema>;
export type TAuthTokenSessionsInsert = Omit<TAuthTokenSessions, TImmutableDBKeys>;
export type TAuthTokenSessionsUpdate = Partial<Omit<TAuthTokenSessions, TImmutableDBKeys>>;
export type TAuthTokenSessionsInsert = Omit<z.input<typeof AuthTokenSessionsSchema>, TImmutableDBKeys>;
export type TAuthTokenSessionsUpdate = Partial<Omit<z.input<typeof AuthTokenSessionsSchema>, TImmutableDBKeys>>;

@ -21,5 +21,5 @@ export const AuthTokensSchema = z.object({
});
export type TAuthTokens = z.infer<typeof AuthTokensSchema>;
export type TAuthTokensInsert = Omit<TAuthTokens, TImmutableDBKeys>;
export type TAuthTokensUpdate = Partial<Omit<TAuthTokens, TImmutableDBKeys>>;
export type TAuthTokensInsert = Omit<z.input<typeof AuthTokensSchema>, TImmutableDBKeys>;
export type TAuthTokensUpdate = Partial<Omit<z.input<typeof AuthTokensSchema>, TImmutableDBKeys>>;

@ -22,5 +22,5 @@ export const BackupPrivateKeySchema = z.object({
});
export type TBackupPrivateKey = z.infer<typeof BackupPrivateKeySchema>;
export type TBackupPrivateKeyInsert = Omit<TBackupPrivateKey, TImmutableDBKeys>;
export type TBackupPrivateKeyUpdate = Partial<Omit<TBackupPrivateKey, TImmutableDBKeys>>;
export type TBackupPrivateKeyInsert = Omit<z.input<typeof BackupPrivateKeySchema>, TImmutableDBKeys>;
export type TBackupPrivateKeyUpdate = Partial<Omit<z.input<typeof BackupPrivateKeySchema>, TImmutableDBKeys>>;

@ -17,5 +17,5 @@ export const GitAppInstallSessionsSchema = z.object({
});
export type TGitAppInstallSessions = z.infer<typeof GitAppInstallSessionsSchema>;
export type TGitAppInstallSessionsInsert = Omit<TGitAppInstallSessions, TImmutableDBKeys>;
export type TGitAppInstallSessionsUpdate = Partial<Omit<TGitAppInstallSessions, TImmutableDBKeys>>;
export type TGitAppInstallSessionsInsert = Omit<z.input<typeof GitAppInstallSessionsSchema>, TImmutableDBKeys>;
export type TGitAppInstallSessionsUpdate = Partial<Omit<z.input<typeof GitAppInstallSessionsSchema>, TImmutableDBKeys>>;

@ -17,5 +17,5 @@ export const GitAppOrgSchema = z.object({
});
export type TGitAppOrg = z.infer<typeof GitAppOrgSchema>;
export type TGitAppOrgInsert = Omit<TGitAppOrg, TImmutableDBKeys>;
export type TGitAppOrgUpdate = Partial<Omit<TGitAppOrg, TImmutableDBKeys>>;
export type TGitAppOrgInsert = Omit<z.input<typeof GitAppOrgSchema>, TImmutableDBKeys>;
export type TGitAppOrgUpdate = Partial<Omit<z.input<typeof GitAppOrgSchema>, TImmutableDBKeys>>;

@ -16,5 +16,5 @@ export const IdentitiesSchema = z.object({
});
export type TIdentities = z.infer<typeof IdentitiesSchema>;
export type TIdentitiesInsert = Omit<TIdentities, TImmutableDBKeys>;
export type TIdentitiesUpdate = Partial<Omit<TIdentities, TImmutableDBKeys>>;
export type TIdentitiesInsert = Omit<z.input<typeof IdentitiesSchema>, TImmutableDBKeys>;
export type TIdentitiesUpdate = Partial<Omit<z.input<typeof IdentitiesSchema>, TImmutableDBKeys>>;

@ -23,5 +23,5 @@ export const IdentityAccessTokensSchema = z.object({
});
export type TIdentityAccessTokens = z.infer<typeof IdentityAccessTokensSchema>;
export type TIdentityAccessTokensInsert = Omit<TIdentityAccessTokens, TImmutableDBKeys>;
export type TIdentityAccessTokensUpdate = Partial<Omit<TIdentityAccessTokens, TImmutableDBKeys>>;
export type TIdentityAccessTokensInsert = Omit<z.input<typeof IdentityAccessTokensSchema>, TImmutableDBKeys>;
export type TIdentityAccessTokensUpdate = Partial<Omit<z.input<typeof IdentityAccessTokensSchema>, TImmutableDBKeys>>;

@ -18,5 +18,7 @@ export const IdentityOrgMembershipsSchema = z.object({
});
export type TIdentityOrgMemberships = z.infer<typeof IdentityOrgMembershipsSchema>;
export type TIdentityOrgMembershipsInsert = Omit<TIdentityOrgMemberships, TImmutableDBKeys>;
export type TIdentityOrgMembershipsUpdate = Partial<Omit<TIdentityOrgMemberships, TImmutableDBKeys>>;
export type TIdentityOrgMembershipsInsert = Omit<z.input<typeof IdentityOrgMembershipsSchema>, TImmutableDBKeys>;
export type TIdentityOrgMembershipsUpdate = Partial<
Omit<z.input<typeof IdentityOrgMembershipsSchema>, TImmutableDBKeys>
>;

@ -18,5 +18,10 @@ export const IdentityProjectMembershipsSchema = z.object({
});
export type TIdentityProjectMemberships = z.infer<typeof IdentityProjectMembershipsSchema>;
export type TIdentityProjectMembershipsInsert = Omit<TIdentityProjectMemberships, TImmutableDBKeys>;
export type TIdentityProjectMembershipsUpdate = Partial<Omit<TIdentityProjectMemberships, TImmutableDBKeys>>;
export type TIdentityProjectMembershipsInsert = Omit<
z.input<typeof IdentityProjectMembershipsSchema>,
TImmutableDBKeys
>;
export type TIdentityProjectMembershipsUpdate = Partial<
Omit<z.input<typeof IdentityProjectMembershipsSchema>, TImmutableDBKeys>
>;

@ -23,5 +23,7 @@ export const IdentityUaClientSecretsSchema = z.object({
});
export type TIdentityUaClientSecrets = z.infer<typeof IdentityUaClientSecretsSchema>;
export type TIdentityUaClientSecretsInsert = Omit<TIdentityUaClientSecrets, TImmutableDBKeys>;
export type TIdentityUaClientSecretsUpdate = Partial<Omit<TIdentityUaClientSecrets, TImmutableDBKeys>>;
export type TIdentityUaClientSecretsInsert = Omit<z.input<typeof IdentityUaClientSecretsSchema>, TImmutableDBKeys>;
export type TIdentityUaClientSecretsUpdate = Partial<
Omit<z.input<typeof IdentityUaClientSecretsSchema>, TImmutableDBKeys>
>;

@ -21,5 +21,7 @@ export const IdentityUniversalAuthsSchema = z.object({
});
export type TIdentityUniversalAuths = z.infer<typeof IdentityUniversalAuthsSchema>;
export type TIdentityUniversalAuthsInsert = Omit<TIdentityUniversalAuths, TImmutableDBKeys>;
export type TIdentityUniversalAuthsUpdate = Partial<Omit<TIdentityUniversalAuths, TImmutableDBKeys>>;
export type TIdentityUniversalAuthsInsert = Omit<z.input<typeof IdentityUniversalAuthsSchema>, TImmutableDBKeys>;
export type TIdentityUniversalAuthsUpdate = Partial<
Omit<z.input<typeof IdentityUniversalAuthsSchema>, TImmutableDBKeys>
>;

@ -16,5 +16,5 @@ export const IncidentContactsSchema = z.object({
});
export type TIncidentContacts = z.infer<typeof IncidentContactsSchema>;
export type TIncidentContactsInsert = Omit<TIncidentContacts, TImmutableDBKeys>;
export type TIncidentContactsUpdate = Partial<Omit<TIncidentContacts, TImmutableDBKeys>>;
export type TIncidentContactsInsert = Omit<z.input<typeof IncidentContactsSchema>, TImmutableDBKeys>;
export type TIncidentContactsUpdate = Partial<Omit<z.input<typeof IncidentContactsSchema>, TImmutableDBKeys>>;

@ -33,5 +33,5 @@ export const IntegrationAuthsSchema = z.object({
});
export type TIntegrationAuths = z.infer<typeof IntegrationAuthsSchema>;
export type TIntegrationAuthsInsert = Omit<TIntegrationAuths, TImmutableDBKeys>;
export type TIntegrationAuthsUpdate = Partial<Omit<TIntegrationAuths, TImmutableDBKeys>>;
export type TIntegrationAuthsInsert = Omit<z.input<typeof IntegrationAuthsSchema>, TImmutableDBKeys>;
export type TIntegrationAuthsUpdate = Partial<Omit<z.input<typeof IntegrationAuthsSchema>, TImmutableDBKeys>>;

@ -31,5 +31,5 @@ export const IntegrationsSchema = z.object({
});
export type TIntegrations = z.infer<typeof IntegrationsSchema>;
export type TIntegrationsInsert = Omit<TIntegrations, TImmutableDBKeys>;
export type TIntegrationsUpdate = Partial<Omit<TIntegrations, TImmutableDBKeys>>;
export type TIntegrationsInsert = Omit<z.input<typeof IntegrationsSchema>, TImmutableDBKeys>;
export type TIntegrationsUpdate = Partial<Omit<z.input<typeof IntegrationsSchema>, TImmutableDBKeys>>;

@ -27,5 +27,5 @@ export const OrgBotsSchema = z.object({
});
export type TOrgBots = z.infer<typeof OrgBotsSchema>;
export type TOrgBotsInsert = Omit<TOrgBots, TImmutableDBKeys>;
export type TOrgBotsUpdate = Partial<Omit<TOrgBots, TImmutableDBKeys>>;
export type TOrgBotsInsert = Omit<z.input<typeof OrgBotsSchema>, TImmutableDBKeys>;
export type TOrgBotsUpdate = Partial<Omit<z.input<typeof OrgBotsSchema>, TImmutableDBKeys>>;

@ -20,5 +20,5 @@ export const OrgMembershipsSchema = z.object({
});
export type TOrgMemberships = z.infer<typeof OrgMembershipsSchema>;
export type TOrgMembershipsInsert = Omit<TOrgMemberships, TImmutableDBKeys>;
export type TOrgMembershipsUpdate = Partial<Omit<TOrgMemberships, TImmutableDBKeys>>;
export type TOrgMembershipsInsert = Omit<z.input<typeof OrgMembershipsSchema>, TImmutableDBKeys>;
export type TOrgMembershipsUpdate = Partial<Omit<z.input<typeof OrgMembershipsSchema>, TImmutableDBKeys>>;

@ -19,5 +19,5 @@ export const OrgRolesSchema = z.object({
});
export type TOrgRoles = z.infer<typeof OrgRolesSchema>;
export type TOrgRolesInsert = Omit<TOrgRoles, TImmutableDBKeys>;
export type TOrgRolesUpdate = Partial<Omit<TOrgRoles, TImmutableDBKeys>>;
export type TOrgRolesInsert = Omit<z.input<typeof OrgRolesSchema>, TImmutableDBKeys>;
export type TOrgRolesUpdate = Partial<Omit<z.input<typeof OrgRolesSchema>, TImmutableDBKeys>>;

@ -19,5 +19,5 @@ export const OrganizationsSchema = z.object({
});
export type TOrganizations = z.infer<typeof OrganizationsSchema>;
export type TOrganizationsInsert = Omit<TOrganizations, TImmutableDBKeys>;
export type TOrganizationsUpdate = Partial<Omit<TOrganizations, TImmutableDBKeys>>;
export type TOrganizationsInsert = Omit<z.input<typeof OrganizationsSchema>, TImmutableDBKeys>;
export type TOrganizationsUpdate = Partial<Omit<z.input<typeof OrganizationsSchema>, TImmutableDBKeys>>;

@ -26,5 +26,5 @@ export const ProjectBotsSchema = z.object({
});
export type TProjectBots = z.infer<typeof ProjectBotsSchema>;
export type TProjectBotsInsert = Omit<TProjectBots, TImmutableDBKeys>;
export type TProjectBotsUpdate = Partial<Omit<TProjectBots, TImmutableDBKeys>>;
export type TProjectBotsInsert = Omit<z.input<typeof ProjectBotsSchema>, TImmutableDBKeys>;
export type TProjectBotsUpdate = Partial<Omit<z.input<typeof ProjectBotsSchema>, TImmutableDBKeys>>;

@ -18,5 +18,5 @@ export const ProjectEnvironmentsSchema = z.object({
});
export type TProjectEnvironments = z.infer<typeof ProjectEnvironmentsSchema>;
export type TProjectEnvironmentsInsert = Omit<TProjectEnvironments, TImmutableDBKeys>;
export type TProjectEnvironmentsUpdate = Partial<Omit<TProjectEnvironments, TImmutableDBKeys>>;
export type TProjectEnvironmentsInsert = Omit<z.input<typeof ProjectEnvironmentsSchema>, TImmutableDBKeys>;
export type TProjectEnvironmentsUpdate = Partial<Omit<z.input<typeof ProjectEnvironmentsSchema>, TImmutableDBKeys>>;

@ -19,5 +19,5 @@ export const ProjectKeysSchema = z.object({
});
export type TProjectKeys = z.infer<typeof ProjectKeysSchema>;
export type TProjectKeysInsert = Omit<TProjectKeys, TImmutableDBKeys>;
export type TProjectKeysUpdate = Partial<Omit<TProjectKeys, TImmutableDBKeys>>;
export type TProjectKeysInsert = Omit<z.input<typeof ProjectKeysSchema>, TImmutableDBKeys>;
export type TProjectKeysUpdate = Partial<Omit<z.input<typeof ProjectKeysSchema>, TImmutableDBKeys>>;

@ -18,5 +18,5 @@ export const ProjectMembershipsSchema = z.object({
});
export type TProjectMemberships = z.infer<typeof ProjectMembershipsSchema>;
export type TProjectMembershipsInsert = Omit<TProjectMemberships, TImmutableDBKeys>;
export type TProjectMembershipsUpdate = Partial<Omit<TProjectMemberships, TImmutableDBKeys>>;
export type TProjectMembershipsInsert = Omit<z.input<typeof ProjectMembershipsSchema>, TImmutableDBKeys>;
export type TProjectMembershipsUpdate = Partial<Omit<z.input<typeof ProjectMembershipsSchema>, TImmutableDBKeys>>;

@ -19,5 +19,5 @@ export const ProjectRolesSchema = z.object({
});
export type TProjectRoles = z.infer<typeof ProjectRolesSchema>;
export type TProjectRolesInsert = Omit<TProjectRoles, TImmutableDBKeys>;
export type TProjectRolesUpdate = Partial<Omit<TProjectRoles, TImmutableDBKeys>>;
export type TProjectRolesInsert = Omit<z.input<typeof ProjectRolesSchema>, TImmutableDBKeys>;
export type TProjectRolesUpdate = Partial<Omit<z.input<typeof ProjectRolesSchema>, TImmutableDBKeys>>;

@ -20,5 +20,5 @@ export const ProjectsSchema = z.object({
});
export type TProjects = z.infer<typeof ProjectsSchema>;
export type TProjectsInsert = Omit<TProjects, TImmutableDBKeys>;
export type TProjectsUpdate = Partial<Omit<TProjects, TImmutableDBKeys>>;
export type TProjectsInsert = Omit<z.input<typeof ProjectsSchema>, TImmutableDBKeys>;
export type TProjectsUpdate = Partial<Omit<z.input<typeof ProjectsSchema>, TImmutableDBKeys>>;

@ -27,5 +27,5 @@ export const SamlConfigsSchema = z.object({
});
export type TSamlConfigs = z.infer<typeof SamlConfigsSchema>;
export type TSamlConfigsInsert = Omit<TSamlConfigs, TImmutableDBKeys>;
export type TSamlConfigsUpdate = Partial<Omit<TSamlConfigs, TImmutableDBKeys>>;
export type TSamlConfigsInsert = Omit<z.input<typeof SamlConfigsSchema>, TImmutableDBKeys>;
export type TSamlConfigsUpdate = Partial<Omit<z.input<typeof SamlConfigsSchema>, TImmutableDBKeys>>;

@ -17,5 +17,5 @@ export const ScimTokensSchema = z.object({
});
export type TScimTokens = z.infer<typeof ScimTokensSchema>;
export type TScimTokensInsert = Omit<TScimTokens, TImmutableDBKeys>;
export type TScimTokensUpdate = Partial<Omit<TScimTokens, TImmutableDBKeys>>;
export type TScimTokensInsert = Omit<z.input<typeof ScimTokensSchema>, TImmutableDBKeys>;
export type TScimTokensUpdate = Partial<Omit<z.input<typeof ScimTokensSchema>, TImmutableDBKeys>>;

@ -16,5 +16,10 @@ export const SecretApprovalPoliciesApproversSchema = z.object({
});
export type TSecretApprovalPoliciesApprovers = z.infer<typeof SecretApprovalPoliciesApproversSchema>;
export type TSecretApprovalPoliciesApproversInsert = Omit<TSecretApprovalPoliciesApprovers, TImmutableDBKeys>;
export type TSecretApprovalPoliciesApproversUpdate = Partial<Omit<TSecretApprovalPoliciesApprovers, TImmutableDBKeys>>;
export type TSecretApprovalPoliciesApproversInsert = Omit<
z.input<typeof SecretApprovalPoliciesApproversSchema>,
TImmutableDBKeys
>;
export type TSecretApprovalPoliciesApproversUpdate = Partial<
Omit<z.input<typeof SecretApprovalPoliciesApproversSchema>, TImmutableDBKeys>
>;

@ -18,5 +18,7 @@ export const SecretApprovalPoliciesSchema = z.object({
});
export type TSecretApprovalPolicies = z.infer<typeof SecretApprovalPoliciesSchema>;
export type TSecretApprovalPoliciesInsert = Omit<TSecretApprovalPolicies, TImmutableDBKeys>;
export type TSecretApprovalPoliciesUpdate = Partial<Omit<TSecretApprovalPolicies, TImmutableDBKeys>>;
export type TSecretApprovalPoliciesInsert = Omit<z.input<typeof SecretApprovalPoliciesSchema>, TImmutableDBKeys>;
export type TSecretApprovalPoliciesUpdate = Partial<
Omit<z.input<typeof SecretApprovalPoliciesSchema>, TImmutableDBKeys>
>;

@ -16,5 +16,10 @@ export const SecretApprovalRequestSecretTagsSchema = z.object({
});
export type TSecretApprovalRequestSecretTags = z.infer<typeof SecretApprovalRequestSecretTagsSchema>;
export type TSecretApprovalRequestSecretTagsInsert = Omit<TSecretApprovalRequestSecretTags, TImmutableDBKeys>;
export type TSecretApprovalRequestSecretTagsUpdate = Partial<Omit<TSecretApprovalRequestSecretTags, TImmutableDBKeys>>;
export type TSecretApprovalRequestSecretTagsInsert = Omit<
z.input<typeof SecretApprovalRequestSecretTagsSchema>,
TImmutableDBKeys
>;
export type TSecretApprovalRequestSecretTagsUpdate = Partial<
Omit<z.input<typeof SecretApprovalRequestSecretTagsSchema>, TImmutableDBKeys>
>;

@ -17,5 +17,10 @@ export const SecretApprovalRequestsReviewersSchema = z.object({
});
export type TSecretApprovalRequestsReviewers = z.infer<typeof SecretApprovalRequestsReviewersSchema>;
export type TSecretApprovalRequestsReviewersInsert = Omit<TSecretApprovalRequestsReviewers, TImmutableDBKeys>;
export type TSecretApprovalRequestsReviewersUpdate = Partial<Omit<TSecretApprovalRequestsReviewers, TImmutableDBKeys>>;
export type TSecretApprovalRequestsReviewersInsert = Omit<
z.input<typeof SecretApprovalRequestsReviewersSchema>,
TImmutableDBKeys
>;
export type TSecretApprovalRequestsReviewersUpdate = Partial<
Omit<z.input<typeof SecretApprovalRequestsReviewersSchema>, TImmutableDBKeys>
>;

@ -35,5 +35,10 @@ export const SecretApprovalRequestsSecretsSchema = z.object({
});
export type TSecretApprovalRequestsSecrets = z.infer<typeof SecretApprovalRequestsSecretsSchema>;
export type TSecretApprovalRequestsSecretsInsert = Omit<TSecretApprovalRequestsSecrets, TImmutableDBKeys>;
export type TSecretApprovalRequestsSecretsUpdate = Partial<Omit<TSecretApprovalRequestsSecrets, TImmutableDBKeys>>;
export type TSecretApprovalRequestsSecretsInsert = Omit<
z.input<typeof SecretApprovalRequestsSecretsSchema>,
TImmutableDBKeys
>;
export type TSecretApprovalRequestsSecretsUpdate = Partial<
Omit<z.input<typeof SecretApprovalRequestsSecretsSchema>, TImmutableDBKeys>
>;

@ -22,5 +22,7 @@ export const SecretApprovalRequestsSchema = z.object({
});
export type TSecretApprovalRequests = z.infer<typeof SecretApprovalRequestsSchema>;
export type TSecretApprovalRequestsInsert = Omit<TSecretApprovalRequests, TImmutableDBKeys>;
export type TSecretApprovalRequestsUpdate = Partial<Omit<TSecretApprovalRequests, TImmutableDBKeys>>;
export type TSecretApprovalRequestsInsert = Omit<z.input<typeof SecretApprovalRequestsSchema>, TImmutableDBKeys>;
export type TSecretApprovalRequestsUpdate = Partial<
Omit<z.input<typeof SecretApprovalRequestsSchema>, TImmutableDBKeys>
>;

@ -20,5 +20,5 @@ export const SecretBlindIndexesSchema = z.object({
});
export type TSecretBlindIndexes = z.infer<typeof SecretBlindIndexesSchema>;
export type TSecretBlindIndexesInsert = Omit<TSecretBlindIndexes, TImmutableDBKeys>;
export type TSecretBlindIndexesUpdate = Partial<Omit<TSecretBlindIndexes, TImmutableDBKeys>>;
export type TSecretBlindIndexesInsert = Omit<z.input<typeof SecretBlindIndexesSchema>, TImmutableDBKeys>;
export type TSecretBlindIndexesUpdate = Partial<Omit<z.input<typeof SecretBlindIndexesSchema>, TImmutableDBKeys>>;

@ -18,5 +18,5 @@ export const SecretFolderVersionsSchema = z.object({
});
export type TSecretFolderVersions = z.infer<typeof SecretFolderVersionsSchema>;
export type TSecretFolderVersionsInsert = Omit<TSecretFolderVersions, TImmutableDBKeys>;
export type TSecretFolderVersionsUpdate = Partial<Omit<TSecretFolderVersions, TImmutableDBKeys>>;
export type TSecretFolderVersionsInsert = Omit<z.input<typeof SecretFolderVersionsSchema>, TImmutableDBKeys>;
export type TSecretFolderVersionsUpdate = Partial<Omit<z.input<typeof SecretFolderVersionsSchema>, TImmutableDBKeys>>;

@ -18,5 +18,5 @@ export const SecretFoldersSchema = z.object({
});
export type TSecretFolders = z.infer<typeof SecretFoldersSchema>;
export type TSecretFoldersInsert = Omit<TSecretFolders, TImmutableDBKeys>;
export type TSecretFoldersUpdate = Partial<Omit<TSecretFolders, TImmutableDBKeys>>;
export type TSecretFoldersInsert = Omit<z.input<typeof SecretFoldersSchema>, TImmutableDBKeys>;
export type TSecretFoldersUpdate = Partial<Omit<z.input<typeof SecretFoldersSchema>, TImmutableDBKeys>>;

@ -19,5 +19,5 @@ export const SecretImportsSchema = z.object({
});
export type TSecretImports = z.infer<typeof SecretImportsSchema>;
export type TSecretImportsInsert = Omit<TSecretImports, TImmutableDBKeys>;
export type TSecretImportsUpdate = Partial<Omit<TSecretImports, TImmutableDBKeys>>;
export type TSecretImportsInsert = Omit<z.input<typeof SecretImportsSchema>, TImmutableDBKeys>;
export type TSecretImportsUpdate = Partial<Omit<z.input<typeof SecretImportsSchema>, TImmutableDBKeys>>;

@ -15,5 +15,5 @@ export const SecretRotationOutputsSchema = z.object({
});
export type TSecretRotationOutputs = z.infer<typeof SecretRotationOutputsSchema>;
export type TSecretRotationOutputsInsert = Omit<TSecretRotationOutputs, TImmutableDBKeys>;
export type TSecretRotationOutputsUpdate = Partial<Omit<TSecretRotationOutputs, TImmutableDBKeys>>;
export type TSecretRotationOutputsInsert = Omit<z.input<typeof SecretRotationOutputsSchema>, TImmutableDBKeys>;
export type TSecretRotationOutputsUpdate = Partial<Omit<z.input<typeof SecretRotationOutputsSchema>, TImmutableDBKeys>>;

@ -26,5 +26,5 @@ export const SecretRotationsSchema = z.object({
});
export type TSecretRotations = z.infer<typeof SecretRotationsSchema>;
export type TSecretRotationsInsert = Omit<TSecretRotations, TImmutableDBKeys>;
export type TSecretRotationsUpdate = Partial<Omit<TSecretRotations, TImmutableDBKeys>>;
export type TSecretRotationsInsert = Omit<z.input<typeof SecretRotationsSchema>, TImmutableDBKeys>;
export type TSecretRotationsUpdate = Partial<Omit<z.input<typeof SecretRotationsSchema>, TImmutableDBKeys>>;

@ -42,5 +42,7 @@ export const SecretScanningGitRisksSchema = z.object({
});
export type TSecretScanningGitRisks = z.infer<typeof SecretScanningGitRisksSchema>;
export type TSecretScanningGitRisksInsert = Omit<TSecretScanningGitRisks, TImmutableDBKeys>;
export type TSecretScanningGitRisksUpdate = Partial<Omit<TSecretScanningGitRisks, TImmutableDBKeys>>;
export type TSecretScanningGitRisksInsert = Omit<z.input<typeof SecretScanningGitRisksSchema>, TImmutableDBKeys>;
export type TSecretScanningGitRisksUpdate = Partial<
Omit<z.input<typeof SecretScanningGitRisksSchema>, TImmutableDBKeys>
>;

@ -17,5 +17,5 @@ export const SecretSnapshotFoldersSchema = z.object({
});
export type TSecretSnapshotFolders = z.infer<typeof SecretSnapshotFoldersSchema>;
export type TSecretSnapshotFoldersInsert = Omit<TSecretSnapshotFolders, TImmutableDBKeys>;
export type TSecretSnapshotFoldersUpdate = Partial<Omit<TSecretSnapshotFolders, TImmutableDBKeys>>;
export type TSecretSnapshotFoldersInsert = Omit<z.input<typeof SecretSnapshotFoldersSchema>, TImmutableDBKeys>;
export type TSecretSnapshotFoldersUpdate = Partial<Omit<z.input<typeof SecretSnapshotFoldersSchema>, TImmutableDBKeys>>;

@ -17,5 +17,5 @@ export const SecretSnapshotSecretsSchema = z.object({
});
export type TSecretSnapshotSecrets = z.infer<typeof SecretSnapshotSecretsSchema>;
export type TSecretSnapshotSecretsInsert = Omit<TSecretSnapshotSecrets, TImmutableDBKeys>;
export type TSecretSnapshotSecretsUpdate = Partial<Omit<TSecretSnapshotSecrets, TImmutableDBKeys>>;
export type TSecretSnapshotSecretsInsert = Omit<z.input<typeof SecretSnapshotSecretsSchema>, TImmutableDBKeys>;
export type TSecretSnapshotSecretsUpdate = Partial<Omit<z.input<typeof SecretSnapshotSecretsSchema>, TImmutableDBKeys>>;

@ -17,5 +17,5 @@ export const SecretSnapshotsSchema = z.object({
});
export type TSecretSnapshots = z.infer<typeof SecretSnapshotsSchema>;
export type TSecretSnapshotsInsert = Omit<TSecretSnapshots, TImmutableDBKeys>;
export type TSecretSnapshotsUpdate = Partial<Omit<TSecretSnapshots, TImmutableDBKeys>>;
export type TSecretSnapshotsInsert = Omit<z.input<typeof SecretSnapshotsSchema>, TImmutableDBKeys>;
export type TSecretSnapshotsUpdate = Partial<Omit<z.input<typeof SecretSnapshotsSchema>, TImmutableDBKeys>>;

@ -14,5 +14,5 @@ export const SecretTagJunctionSchema = z.object({
});
export type TSecretTagJunction = z.infer<typeof SecretTagJunctionSchema>;
export type TSecretTagJunctionInsert = Omit<TSecretTagJunction, TImmutableDBKeys>;
export type TSecretTagJunctionUpdate = Partial<Omit<TSecretTagJunction, TImmutableDBKeys>>;
export type TSecretTagJunctionInsert = Omit<z.input<typeof SecretTagJunctionSchema>, TImmutableDBKeys>;
export type TSecretTagJunctionUpdate = Partial<Omit<z.input<typeof SecretTagJunctionSchema>, TImmutableDBKeys>>;

@ -19,5 +19,5 @@ export const SecretTagsSchema = z.object({
});
export type TSecretTags = z.infer<typeof SecretTagsSchema>;
export type TSecretTagsInsert = Omit<TSecretTags, TImmutableDBKeys>;
export type TSecretTagsUpdate = Partial<Omit<TSecretTags, TImmutableDBKeys>>;
export type TSecretTagsInsert = Omit<z.input<typeof SecretTagsSchema>, TImmutableDBKeys>;
export type TSecretTagsUpdate = Partial<Omit<z.input<typeof SecretTagsSchema>, TImmutableDBKeys>>;

@ -14,5 +14,7 @@ export const SecretVersionTagJunctionSchema = z.object({
});
export type TSecretVersionTagJunction = z.infer<typeof SecretVersionTagJunctionSchema>;
export type TSecretVersionTagJunctionInsert = Omit<TSecretVersionTagJunction, TImmutableDBKeys>;
export type TSecretVersionTagJunctionUpdate = Partial<Omit<TSecretVersionTagJunction, TImmutableDBKeys>>;
export type TSecretVersionTagJunctionInsert = Omit<z.input<typeof SecretVersionTagJunctionSchema>, TImmutableDBKeys>;
export type TSecretVersionTagJunctionUpdate = Partial<
Omit<z.input<typeof SecretVersionTagJunctionSchema>, TImmutableDBKeys>
>;

@ -36,5 +36,5 @@ export const SecretVersionsSchema = z.object({
});
export type TSecretVersions = z.infer<typeof SecretVersionsSchema>;
export type TSecretVersionsInsert = Omit<TSecretVersions, TImmutableDBKeys>;
export type TSecretVersionsUpdate = Partial<Omit<TSecretVersions, TImmutableDBKeys>>;
export type TSecretVersionsInsert = Omit<z.input<typeof SecretVersionsSchema>, TImmutableDBKeys>;
export type TSecretVersionsUpdate = Partial<Omit<z.input<typeof SecretVersionsSchema>, TImmutableDBKeys>>;

@ -34,5 +34,5 @@ export const SecretsSchema = z.object({
});
export type TSecrets = z.infer<typeof SecretsSchema>;
export type TSecretsInsert = Omit<TSecrets, TImmutableDBKeys>;
export type TSecretsUpdate = Partial<Omit<TSecrets, TImmutableDBKeys>>;
export type TSecretsInsert = Omit<z.input<typeof SecretsSchema>, TImmutableDBKeys>;
export type TSecretsUpdate = Partial<Omit<z.input<typeof SecretsSchema>, TImmutableDBKeys>>;

@ -25,5 +25,5 @@ export const ServiceTokensSchema = z.object({
});
export type TServiceTokens = z.infer<typeof ServiceTokensSchema>;
export type TServiceTokensInsert = Omit<TServiceTokens, TImmutableDBKeys>;
export type TServiceTokensUpdate = Partial<Omit<TServiceTokens, TImmutableDBKeys>>;
export type TServiceTokensInsert = Omit<z.input<typeof ServiceTokensSchema>, TImmutableDBKeys>;
export type TServiceTokensUpdate = Partial<Omit<z.input<typeof ServiceTokensSchema>, TImmutableDBKeys>>;

@ -13,9 +13,10 @@ export const SuperAdminSchema = z.object({
allowSignUp: z.boolean().default(true).nullable().optional(),
createdAt: z.date(),
updatedAt: z.date(),
allowedSignUpDomain: z.string().nullable().optional()
allowedSignUpDomain: z.string().nullable().optional(),
instanceId: z.string().uuid().default("00000000-0000-0000-0000-000000000000")
});
export type TSuperAdmin = z.infer<typeof SuperAdminSchema>;
export type TSuperAdminInsert = Omit<TSuperAdmin, TImmutableDBKeys>;
export type TSuperAdminUpdate = Partial<Omit<TSuperAdmin, TImmutableDBKeys>>;
export type TSuperAdminInsert = Omit<z.input<typeof SuperAdminSchema>, TImmutableDBKeys>;
export type TSuperAdminUpdate = Partial<Omit<z.input<typeof SuperAdminSchema>, TImmutableDBKeys>>;

@ -20,5 +20,5 @@ export const TrustedIpsSchema = z.object({
});
export type TTrustedIps = z.infer<typeof TrustedIpsSchema>;
export type TTrustedIpsInsert = Omit<TTrustedIps, TImmutableDBKeys>;
export type TTrustedIpsUpdate = Partial<Omit<TTrustedIps, TImmutableDBKeys>>;
export type TTrustedIpsInsert = Omit<z.input<typeof TrustedIpsSchema>, TImmutableDBKeys>;
export type TTrustedIpsUpdate = Partial<Omit<z.input<typeof TrustedIpsSchema>, TImmutableDBKeys>>;

@ -16,5 +16,5 @@ export const UserActionsSchema = z.object({
});
export type TUserActions = z.infer<typeof UserActionsSchema>;
export type TUserActionsInsert = Omit<TUserActions, TImmutableDBKeys>;
export type TUserActionsUpdate = Partial<Omit<TUserActions, TImmutableDBKeys>>;
export type TUserActionsInsert = Omit<z.input<typeof UserActionsSchema>, TImmutableDBKeys>;
export type TUserActionsUpdate = Partial<Omit<z.input<typeof UserActionsSchema>, TImmutableDBKeys>>;

@ -25,5 +25,5 @@ export const UserEncryptionKeysSchema = z.object({
});
export type TUserEncryptionKeys = z.infer<typeof UserEncryptionKeysSchema>;
export type TUserEncryptionKeysInsert = Omit<TUserEncryptionKeys, TImmutableDBKeys>;
export type TUserEncryptionKeysUpdate = Partial<Omit<TUserEncryptionKeys, TImmutableDBKeys>>;
export type TUserEncryptionKeysInsert = Omit<z.input<typeof UserEncryptionKeysSchema>, TImmutableDBKeys>;
export type TUserEncryptionKeysUpdate = Partial<Omit<z.input<typeof UserEncryptionKeysSchema>, TImmutableDBKeys>>;

@ -24,5 +24,5 @@ export const UsersSchema = z.object({
});
export type TUsers = z.infer<typeof UsersSchema>;
export type TUsersInsert = Omit<TUsers, TImmutableDBKeys>;
export type TUsersUpdate = Partial<Omit<TUsers, TImmutableDBKeys>>;
export type TUsersInsert = Omit<z.input<typeof UsersSchema>, TImmutableDBKeys>;
export type TUsersUpdate = Partial<Omit<z.input<typeof UsersSchema>, TImmutableDBKeys>>;

@ -25,5 +25,5 @@ export const WebhooksSchema = z.object({
});
export type TWebhooks = z.infer<typeof WebhooksSchema>;
export type TWebhooksInsert = Omit<TWebhooks, TImmutableDBKeys>;
export type TWebhooksUpdate = Partial<Omit<TWebhooks, TImmutableDBKeys>>;
export type TWebhooksInsert = Omit<z.input<typeof WebhooksSchema>, TImmutableDBKeys>;
export type TWebhooksUpdate = Partial<Omit<z.input<typeof WebhooksSchema>, TImmutableDBKeys>>;

@ -27,6 +27,7 @@ type TSAMLConfig = {
cert: string;
audience: string;
wantAuthnResponseSigned?: boolean;
wantAssertionsSigned?: boolean;
disableRequestedAuthnContext?: boolean;
};
@ -82,6 +83,10 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
samlConfig.audience = `spn:${ssoConfig.issuer}`;
}
}
if (ssoConfig.authProvider === SamlProviders.GOOGLE_SAML) {
samlConfig.wantAssertionsSigned = false;
}
(req as unknown as FastifyRequest).ssoConfig = ssoConfig;
done(null, samlConfig);
} catch (error) {

@ -24,7 +24,7 @@ export const auditLogQueueServiceFactory = ({
const pushToLog = async (data: TCreateAuditLogDTO) => {
await queueService.queue(QueueName.AuditLog, QueueJobs.AuditLog, data, {
removeOnFail: {
count: 5
count: 3
},
removeOnComplete: true
});
@ -46,6 +46,7 @@ export const auditLogQueueServiceFactory = ({
const ttl = plan.auditLogsRetentionDays * MS_IN_DAY;
// skip inserting if audit log retention is 0 meaning its not supported
if (ttl === 0) return;
await auditLogDAL.create({
actor: actor.type,
actorMetadata: actor.metadata,

@ -5,8 +5,8 @@
// TODO(akhilmhdh): With tony find out the api structure and fill it here
import { ForbiddenError } from "@casl/ability";
import NodeCache from "node-cache";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
@ -39,6 +39,7 @@ type TLicenseServiceFactoryDep = {
orgDAL: Pick<TOrgDALFactory, "findOrgById">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseDAL: TLicenseDALFactory;
keyStore: Pick<TKeyStoreFactory, "setItemWithExpiry" | "getItem" | "deleteItem">;
};
export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>;
@ -46,12 +47,18 @@ export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>;
const LICENSE_SERVER_CLOUD_LOGIN = "/api/auth/v1/license-server-login";
const LICENSE_SERVER_ON_PREM_LOGIN = "/api/auth/v1/license-login";
const FEATURE_CACHE_KEY = (orgId: string, projectId?: string) => `${orgId}-${projectId || ""}`;
export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }: TLicenseServiceFactoryDep) => {
const LICENSE_SERVER_CLOUD_PLAN_TTL = 30; // 30 second
const FEATURE_CACHE_KEY = (orgId: string) => `infisical-cloud-plan-${orgId}`;
export const licenseServiceFactory = ({
orgDAL,
permissionService,
licenseDAL,
keyStore
}: TLicenseServiceFactoryDep) => {
let isValidLicense = false;
let instanceType = InstanceType.OnPrem;
let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures();
const featureStore = new NodeCache({ stdTTL: 60 });
const appCfg = getConfig();
const licenseServerCloudApi = setupLicenceRequestWithStore(
@ -75,6 +82,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
isValidLicense = true;
return;
}
if (appCfg.LICENSE_KEY) {
const token = await licenseServerOnPremApi.refreshLicence();
if (token) {
@ -100,22 +108,21 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
logger.info(`getPlan: attempting to fetch plan for [orgId=${orgId}] [projectId=${projectId}]`);
try {
if (instanceType === InstanceType.Cloud) {
const cachedPlan = featureStore.get<TFeatureSet>(FEATURE_CACHE_KEY(orgId, projectId));
if (cachedPlan) return cachedPlan;
const cachedPlan = await keyStore.getItem(FEATURE_CACHE_KEY(orgId));
if (cachedPlan) return JSON.parse(cachedPlan) as TFeatureSet;
const org = await orgDAL.findOrgById(orgId);
if (!org) throw new BadRequestError({ message: "Org not found" });
const {
data: { currentPlan }
} = await licenseServerCloudApi.request.get<{ currentPlan: TFeatureSet }>(
`/api/license-server/v1/customers/${org.customerId}/cloud-plan`,
{
params: {
workspaceId: projectId
}
}
`/api/license-server/v1/customers/${org.customerId}/cloud-plan`
);
await keyStore.setItemWithExpiry(
FEATURE_CACHE_KEY(org.id),
LICENSE_SERVER_CLOUD_PLAN_TTL,
JSON.stringify(currentPlan)
);
featureStore.set(FEATURE_CACHE_KEY(org.id, projectId), currentPlan);
return currentPlan;
}
} catch (error) {
@ -123,15 +130,20 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
`getPlan: encountered an error when fetching pan [orgId=${orgId}] [projectId=${projectId}] [error]`,
error
);
await keyStore.setItemWithExpiry(
FEATURE_CACHE_KEY(orgId),
LICENSE_SERVER_CLOUD_PLAN_TTL,
JSON.stringify(onPremFeatures)
);
return onPremFeatures;
}
return onPremFeatures;
};
const refreshPlan = async (orgId: string, projectId?: string) => {
const refreshPlan = async (orgId: string) => {
if (instanceType === InstanceType.Cloud) {
featureStore.del(FEATURE_CACHE_KEY(orgId, projectId));
await getPlan(orgId, projectId);
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
await getPlan(orgId);
}
};
@ -166,7 +178,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
quantity: count
});
}
featureStore.del(orgId);
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
} else if (instanceType === InstanceType.EnterpriseOnPrem) {
const usedSeats = await licenseDAL.countOfOrgMembers(null);
await licenseServerOnPremApi.request.patch(`/api/license/v1/license`, { usedSeats });
@ -215,7 +227,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
`/api/license-server/v1/customers/${organization.customerId}/session/trial`,
{ success_url }
);
featureStore.del(FEATURE_CACHE_KEY(orgId));
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
return { url };
};
@ -505,6 +517,9 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
get isValidLicense() {
return isValidLicense;
},
getInstanceType() {
return instanceType;
},
getPlan,
updateSubscriptionOrgMemberCount,
refreshPlan,

@ -4,7 +4,8 @@ import { ActorType } from "@app/services/auth/auth-type";
export enum SamlProviders {
OKTA_SAML = "okta-saml",
AZURE_SAML = "azure-saml",
JUMPCLOUD_SAML = "jumpcloud-saml"
JUMPCLOUD_SAML = "jumpcloud-saml",
GOOGLE_SAML = "google-saml"
}
export type TCreateSamlCfgDTO = {

@ -240,7 +240,7 @@ export const secretRotationQueueFactory = ({
);
});
telemetryService.sendPostHogEvents({
await telemetryService.sendPostHogEvents({
event: PostHogEventTypes.SecretRotated,
distinctId: "",
properties: {

@ -158,7 +158,7 @@ export const secretScanningQueueFactory = ({
});
}
telemetryService.sendPostHogEvents({
await telemetryService.sendPostHogEvents({
event: PostHogEventTypes.SecretScannerPush,
distinctId: repository.fullName,
properties: {
@ -228,7 +228,7 @@ export const secretScanningQueueFactory = ({
});
}
telemetryService.sendPostHogEvents({
await telemetryService.sendPostHogEvents({
event: PostHogEventTypes.SecretScannerFull,
distinctId: repository.fullName,
properties: {

@ -0,0 +1,20 @@
import { Redis } from "ioredis";
export type TKeyStoreFactory = ReturnType<typeof keyStoreFactory>;
export const keyStoreFactory = (redisUrl: string) => {
const redis = new Redis(redisUrl);
const setItem = async (key: string, value: string | number | Buffer) => redis.set(key, value);
const getItem = async (key: string) => redis.get(key);
const setItemWithExpiry = async (key: string, exp: number | string, value: string | number | Buffer) =>
redis.setex(key, exp, value);
const deleteItem = async (key: string) => redis.del(key);
const incrementBy = async (key: string, value: number) => redis.incrby(key, value);
return { setItem, getItem, setItemWithExpiry, deleteItem, incrementBy };
};

@ -94,14 +94,17 @@ const envSchema = z
SECRET_SCANNING_WEBHOOK_SECRET: zpStr(z.string().optional()),
SECRET_SCANNING_GIT_APP_ID: zpStr(z.string().optional()),
SECRET_SCANNING_PRIVATE_KEY: zpStr(z.string().optional()),
// LICENCE
// LICENSE
LICENSE_SERVER_URL: zpStr(z.string().optional().default("https://portal.infisical.com")),
LICENSE_SERVER_KEY: zpStr(z.string().optional()),
LICENSE_KEY: zpStr(z.string().optional()),
// GENERIC
STANDALONE_MODE: z
.enum(["true", "false"])
.transform((val) => val === "true")
.optional()
.optional(),
INFISICAL_CLOUD: zodStrBool.default("false")
})
.transform((data) => ({
...data,

@ -1,6 +1,7 @@
import dotenv from "dotenv";
import { initDbConnection } from "./db";
import { keyStoreFactory } from "./keystore/keystore";
import { formatSmtpConfig, initEnvConfig } from "./lib/config/env";
import { initLogger } from "./lib/logger";
import { queueServiceFactory } from "./queue";
@ -19,8 +20,9 @@ const run = async () => {
const smtp = smtpServiceFactory(formatSmtpConfig());
const queue = queueServiceFactory(appCfg.REDIS_URL);
const keyStore = keyStoreFactory(appCfg.REDIS_URL);
const server = await main({ db, smtp, logger, queue });
const server = await main({ db, smtp, logger, queue, keyStore });
const bootstrap = await bootstrapCheck({ db });
// eslint-disable-next-line
process.on("SIGINT", async () => {

@ -13,6 +13,7 @@ export enum QueueName {
SecretReminder = "secret-reminder",
AuditLog = "audit-log",
AuditLogPrune = "audit-log-prune",
TelemetryInstanceStats = "telemtry-self-hosted-stats",
IntegrationSync = "sync-integrations",
SecretWebhook = "secret-webhook",
SecretFullRepoScan = "secret-full-repo-scan",
@ -26,6 +27,7 @@ export enum QueueJobs {
AuditLog = "audit-log-job",
AuditLogPrune = "audit-log-prune-job",
SecWebhook = "secret-webhook-trigger",
TelemetryInstanceStats = "telemetry-self-hosted-stats",
IntegrationSync = "secret-integration-pull",
SecretScan = "secret-scan",
UpgradeProjectToGhost = "upgrade-project-to-ghost-job"
@ -67,7 +69,6 @@ export type TQueueJobTypes = {
payload: TScanFullRepoEventPayload;
};
[QueueName.SecretPushEventScan]: { name: QueueJobs.SecretScan; payload: TScanPushEventPayload };
[QueueName.UpgradeProjectToGhost]: {
name: QueueJobs.UpgradeProjectToGhost;
payload: {
@ -81,6 +82,10 @@ export type TQueueJobTypes = {
};
};
};
[QueueName.TelemetryInstanceStats]: {
name: QueueJobs.TelemetryInstanceStats;
payload: undefined;
};
};
export type TQueueServiceFactory = ReturnType<typeof queueServiceFactory>;

@ -14,6 +14,7 @@ import fasitfy from "fastify";
import { Knex } from "knex";
import { Logger } from "pino";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { TQueueServiceFactory } from "@app/queue";
import { TSmtpService } from "@app/services/smtp/smtp-service";
@ -31,10 +32,11 @@ type TMain = {
smtp: TSmtpService;
logger?: Logger;
queue: TQueueServiceFactory;
keyStore: TKeyStoreFactory;
};
// Run the server!
export const main = async ({ db, smtp, logger, queue }: TMain) => {
export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {
const appCfg = getConfig();
const server = fasitfy({
logger: appCfg.NODE_ENV === "test" ? false : logger,
@ -70,7 +72,7 @@ export const main = async ({ db, smtp, logger, queue }: TMain) => {
}
await server.register(helmet, { contentSecurityPolicy: false });
await server.register(registerRoutes, { smtp, queue, db });
await server.register(registerRoutes, { smtp, queue, db, keyStore });
if (appCfg.isProductionMode) {
await server.register(registerExternalNextjs, {

@ -34,6 +34,7 @@ import { snapshotFolderDALFactory } from "@app/ee/services/secret-snapshot/snaps
import { snapshotSecretDALFactory } from "@app/ee/services/secret-snapshot/snapshot-secret-dal";
import { trustedIpDALFactory } from "@app/ee/services/trusted-ip/trusted-ip-dal";
import { trustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-service";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { TQueueServiceFactory } from "@app/queue";
import { apiKeyDALFactory } from "@app/services/api-key/api-key-dal";
@ -96,6 +97,8 @@ import { serviceTokenServiceFactory } from "@app/services/service-token/service-
import { TSmtpService } from "@app/services/smtp/smtp-service";
import { superAdminDALFactory } from "@app/services/super-admin/super-admin-dal";
import { getServerCfg, superAdminServiceFactory } from "@app/services/super-admin/super-admin-service";
import { telemetryDALFactory } from "@app/services/telemetry/telemetry-dal";
import { telemetryQueueServiceFactory } from "@app/services/telemetry/telemetry-queue";
import { telemetryServiceFactory } from "@app/services/telemetry/telemetry-service";
import { userDALFactory } from "@app/services/user/user-dal";
import { userServiceFactory } from "@app/services/user/user-service";
@ -112,7 +115,12 @@ import { registerV3Routes } from "./v3";
export const registerRoutes = async (
server: FastifyZodProvider,
{ db, smtp: smtpService, queue: queueService }: { db: Knex; smtp: TSmtpService; queue: TQueueServiceFactory }
{
db,
smtp: smtpService,
queue: queueService,
keyStore
}: { db: Knex; smtp: TSmtpService; queue: TQueueServiceFactory; keyStore: TKeyStoreFactory }
) => {
await server.register(registerSecretScannerGhApp, { prefix: "/ss-webhook" });
@ -159,6 +167,7 @@ export const registerRoutes = async (
const auditLogDAL = auditLogDALFactory(db);
const trustedIpDAL = trustedIpDALFactory(db);
const scimDAL = scimDALFactory(db);
const telemetryDAL = telemetryDALFactory(db);
// ee db layer ops
const permissionDAL = permissionDALFactory(db);
@ -185,7 +194,7 @@ export const registerRoutes = async (
projectRoleDAL,
serviceTokenDAL
});
const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL });
const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL, keyStore });
const trustedIpService = trustedIpServiceFactory({
licenseService,
projectDAL,
@ -226,7 +235,16 @@ export const registerRoutes = async (
smtpService
});
const telemetryService = telemetryServiceFactory();
const telemetryService = telemetryServiceFactory({
keyStore,
licenseService
});
const telemetryQueue = telemetryQueueServiceFactory({
keyStore,
telemetryDAL,
queueService
});
const tokenService = tokenServiceFactory({ tokenDAL: authTokenDAL, userDAL });
const userService = userServiceFactory({ userDAL });
const loginService = authLoginServiceFactory({ userDAL, smtpService, tokenService });
@ -263,7 +281,8 @@ export const registerRoutes = async (
userDAL,
authService: loginService,
serverCfgDAL: superAdminDAL,
orgService
orgService,
keyStore
});
const apiKeyService = apiKeyServiceFactory({ apiKeyDAL, userDAL });
@ -491,9 +510,13 @@ export const registerRoutes = async (
});
await superAdminService.initServerCfg();
await auditLogQueue.startAuditLogPruneJob();
//
// setup the communication with license key server
await licenseService.init();
await auditLogQueue.startAuditLogPruneJob();
await telemetryQueue.startTelemetryCheck();
// inject all services
server.decorate<FastifyZodProvider["services"]>("services", {
login: loginService,

@ -16,7 +16,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
schema: {
response: {
200: z.object({
config: SuperAdminSchema
config: SuperAdminSchema.omit({ createdAt: true, updatedAt: true })
})
}
},
@ -90,7 +90,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
userAgent: req.headers["user-agent"] || ""
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.AdminInit,
distinctId: user.user.email,
properties: {

@ -51,7 +51,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.MachineIdentityCreated,
distinctId: getTelemetryDistinctId(req),
properties: {

@ -39,11 +39,12 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}
},
handler: async (req) => {
const { identityUa, accessToken, identityAccessToken, validClientSecretInfo } =
const { identityUa, accessToken, identityAccessToken, validClientSecretInfo, identityMembershipOrg } =
await server.services.identityUa.login(req.body.clientId, req.body.clientSecret, req.realIp);
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
event: {
type: EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH,
metadata: {

@ -82,7 +82,7 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.IntegrationCreated,
distinctId: getTelemetryDistinctId(req),
properties: {

@ -32,7 +32,7 @@ export const registerInviteOrgRouter = async (server: FastifyZodProvider) => {
actorOrgId: req.permission.orgId
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.UserOrgInvitation,
distinctId: getTelemetryDistinctId(req),
properties: {

@ -87,11 +87,12 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
schema: {
params: z.object({ organizationId: z.string().trim() }),
body: z.object({
name: z.string().trim().optional(),
name: z.string().trim().max(64, { message: "Name must be 64 or fewer characters" }).optional(),
slug: z
.string()
.trim()
.regex(/^[a-zA-Z0-9-]+$/, "Name must only contain alphanumeric characters or hyphens")
.max(64, { message: "Slug must be 64 or fewer characters" })
.regex(/^[a-zA-Z0-9-]+$/, "Slug must only contain alphanumeric characters or hyphens")
.optional(),
authEnforced: z.boolean().optional(),
scimEnabled: z.boolean().optional()

@ -222,7 +222,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
workspaceId: z.string().trim()
}),
body: z.object({
name: z.string().trim().optional(),
name: z.string().trim().max(64, { message: "Name must be 64 or fewer characters" }).optional(),
autoCapitalization: z.boolean().optional()
}),
response: {

@ -8,12 +8,9 @@
import { Authenticator } from "@fastify/passport";
import fastifySession from "@fastify/session";
// import { FastifyRequest } from "fastify";
import { Strategy as GitHubStrategy } from "passport-github";
import { Strategy as GitLabStrategy } from "passport-gitlab2";
import { Strategy as GoogleStrategy } from "passport-google-oauth20";
import { Strategy as OpenIDConnectStrategy } from "passport-openidconnect";
// const OpenIDConnectStrategy = require('passport-openidconnect');
import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
@ -136,136 +133,6 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
);
}
/**
* TODO:
* 1. Test w static config
* 2. Fetch config from db
*/
// const getOIDCConfiguration = (req: FastifyRequest, callback: any) => {
// // Fetching things from database or whatever
// const { username } = req.body as { username: string };
// process.nextTick(() => {
// const opts = {
// issuer: "",
// authorizationURL: "",
// tokenURL: "",
// userInfoURL: "",
// clientID: "",
// clientSecret: "",
// callbackURL: `${'test'}/api/sso/oidc`,
// // issuer: ISSUER_URL_OIDC_LOGIN,
// // authorizationURL: AUTHORIZATION_URL_OIDC_LOGIN,
// // tokenURL: TOKEN_URL_OIDC_LOGIN,
// // userInfoURL: USER_INFO_URL_OIDC_LOGIN,
// // clientID: CLIENT_ID_OIDC_LOGIN,
// // clientSecret: CLIENT_SECRET_OIDC_LOGIN,
// // callbackURL: `${SITE_URL}/api/sso/oidc`,
// scope: ['profile', 'email'],
// passReqToCallback: true
// }
// callback(null, opts);
// });
// };
const ISSUER_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/";
const AUTHORIZATION_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/oauth2/auth";
const TOKEN_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/oauth2/token";
const USER_INFO_URL_OIDC_LOGIN = "https://oauth.id.jumpcloud.com/userinfo";
const CLIENT_ID_OIDC_LOGIN = "";
const CLIENT_SECRET_OIDC_LOGIN = "";
const SITE_URL = "";
const config = {
issuer: ISSUER_URL_OIDC_LOGIN,
authorizationURL: AUTHORIZATION_URL_OIDC_LOGIN,
tokenURL: TOKEN_URL_OIDC_LOGIN,
userInfoURL: USER_INFO_URL_OIDC_LOGIN,
clientID: CLIENT_ID_OIDC_LOGIN,
clientSecret: CLIENT_SECRET_OIDC_LOGIN,
callbackURL: `${SITE_URL}/api/v1/sso/oidc`,
scope: ["profile", "email"],
passReqToCallback: true
};
if (config) {
passport.use(
new OpenIDConnectStrategy(config, (req: any, issuer: any, profile: any, done: any) => {
try {
console.log("oidc");
console.log("oidc issuer: ", issuer);
console.log("oidc profile: ", profile);
// const { name: { familyName, givenName }, emails } = profile;
done(null, profile);
} catch (err) {
console.log("oidc err: ", err);
done(null, false);
}
})
);
}
server.route({
url: "/login/oidc",
method: "GET",
preValidation: (req, res) => {
console.log("oidc login");
return (
passport.authenticate("openidconnect", {
session: false,
scope: ["profile", "email"]
}) as any
)(req, res);
},
handler: async (req, res) => {
console.log("oidc login 2");
if (req.passportUser) {
return res.code(200).send({ message: "Authentication successful", user: req.passportUser });
}
return res.code(401).send({ error: "Authentication failed" });
}
});
server.route({
url: "/oidc",
method: "GET",
preValidation: (req, res) => {
console.log("oidcx req: ", req); // code, state
return (
passport.authenticate("openidconnect", {
session: false,
failureRedirect: "/api/v1/sso/login/provider/error",
failureMessage: true
}) as any
)(req, res);
},
handler: (req, res) => {
console.log("oidc 3");
if (req.passportUser.isUserCompleted) {
// login
return res.redirect(`${SITE_URL}/login/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}`);
}
// signup
return res.redirect(`${SITE_URL}/signup/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}`);
}
});
server.route({
url: "/login/provider/error",
method: "GET",
handler: (req, res) => {
console.log("reqyx: ", req);
console.log("resyx: ", res);
return res.status(500).send({
error: "Authentication error",
details: req.query
});
}
});
server.route({
url: "/redirect/google",
method: "GET",

@ -154,7 +154,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
slug: req.body.slug
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.ProjectCreated,
distinctId: getTelemetryDistinctId(req),
properties: {

@ -95,7 +95,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretPulled,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -185,7 +185,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretPulled,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -261,7 +261,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretCreated,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -336,7 +336,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretUpdated,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -406,7 +406,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretDeleted,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -512,7 +512,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
(req.headers["user-agent"] !== "k8-operator" || shouldRecordK8Event);
const approximateNumberTotalSecrets = secrets.length * 20;
if (shouldCapture) {
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretPulled,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -589,7 +589,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretPulled,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -752,7 +752,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretCreated,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -934,7 +934,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretUpdated,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -1052,7 +1052,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretDeleted,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -1172,7 +1172,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretCreated,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -1292,7 +1292,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretUpdated,
distinctId: getTelemetryDistinctId(req),
properties: {
@ -1400,7 +1400,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
});
server.services.telemetry.sendPostHogEvents({
await server.services.telemetry.sendPostHogEvents({
event: PostHogEventTypes.SecretDeleted,
distinctId: getTelemetryDistinctId(req),
properties: {

@ -54,6 +54,8 @@ export const identityUaServiceFactory = ({
const identityUa = await identityUaDAL.findOne({ clientId });
if (!identityUa) throw new UnauthorizedError();
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityUa.identityId });
checkIPAgainstBlocklist({
ipAddress: ip,
trustedIps: identityUa.clientSecretTrustedIps as TIp[]
@ -131,7 +133,7 @@ export const identityUaServiceFactory = ({
}
);
return { accessToken, identityUa, validClientSecretInfo, identityAccessToken };
return { accessToken, identityUa, validClientSecretInfo, identityAccessToken, identityMembershipOrg };
};
const attachUa = async ({

@ -238,6 +238,8 @@ export const projectMembershipServiceFactory = ({
if (orgMembers.length !== emails.length) throw new BadRequestError({ message: "Some users are not part of org" });
if (!orgMembers.length) return [];
const existingMembers = await projectMembershipDAL.find({
projectId,
$in: { userId: orgMembers.map(({ user }) => user.id).filter(Boolean) }

@ -19,7 +19,7 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Tags);
const existingTag = await secretTagDAL.findOne({ slug });
const existingTag = await secretTagDAL.findOne({ slug, projectId });
if (existingTag) throw new BadRequestError({ message: "Tag already exist" });
const newTag = await secretTagDAL.create({

@ -7,7 +7,7 @@ import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/
import { getConfig } from "@app/lib/config/env";
import { buildSecretBlindIndexFromName, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
import { BadRequestError } from "@app/lib/errors";
import { groupBy, pick } from "@app/lib/fn";
import { groupBy, pick, unique } from "@app/lib/fn";
import { logger } from "@app/lib/logger";
import { ActorType } from "../auth/auth-type";
@ -202,12 +202,13 @@ export const secretServiceFactory = ({
return deletedSecrets;
};
// this is a utility function for secret modification
// this will check given secret name blind index exist or not
// if its a created secret set isNew to true
// thus if these blindindex exist it will throw an error
// vice versa when u need to check for updated secret
// this will also return the blind index grouped by secretName
/**
* Checks and handles secrets using a blind index method.
* The function generates mappings between secret names and their blind indexes, validates user IDs for personal secrets, and retrieves secrets from the database based on their blind indexes.
* For new secrets (isNew = true), it ensures they don't already exist in the database.
* For existing secrets, it verifies their presence in the database.
* If discrepancies are found, errors are thrown. The function returns mappings and the fetched secrets.
*/
const fnSecretBlindIndexCheck = async ({
inputSecrets,
folderId,
@ -242,10 +243,18 @@ export const secretServiceFactory = ({
if (isNew) {
if (secrets.length) throw new BadRequestError({ message: "Secret already exist" });
} else if (secrets.length !== inputSecrets.length)
throw new BadRequestError({
message: `Secret not found: blind index ${JSON.stringify(keyName2BlindIndex)}`
});
} else {
const secretKeysInDB = unique(secrets, (el) => el.secretBlindIndex as string).map(
(el) => blindIndex2KeyName[el.secretBlindIndex as string]
);
const hasUnknownSecretsProvided = secretKeysInDB.length !== inputSecrets.length;
if (hasUnknownSecretsProvided) {
const keysMissingInDB = Object.keys(keyName2BlindIndex).filter((key) => !secretKeysInDB.includes(key));
throw new BadRequestError({
message: `Secret not found: blind index ${keysMissingInDB.join(",")}`
});
}
}
return { blindIndex2KeyName, keyName2BlindIndex, secrets };
};

@ -1,4 +1,5 @@
import { TSuperAdmin, TSuperAdminUpdate } from "@app/db/schemas";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
@ -14,6 +15,7 @@ type TSuperAdminServiceFactoryDep = {
userDAL: TUserDALFactory;
authService: Pick<TAuthLoginFactory, "generateUserTokens">;
orgService: Pick<TOrgServiceFactory, "createOrganization">;
keyStore: Pick<TKeyStoreFactory, "getItem" | "setItemWithExpiry" | "deleteItem">;
};
export type TSuperAdminServiceFactory = ReturnType<typeof superAdminServiceFactory>;
@ -21,26 +23,53 @@ export type TSuperAdminServiceFactory = ReturnType<typeof superAdminServiceFacto
// eslint-disable-next-line
export let getServerCfg: () => Promise<TSuperAdmin>;
const ADMIN_CONFIG_KEY = "infisical-admin-cfg";
const ADMIN_CONFIG_KEY_EXP = 60; // 60s
const ADMIN_CONFIG_DB_UUID = "00000000-0000-0000-0000-000000000000";
export const superAdminServiceFactory = ({
serverCfgDAL,
userDAL,
authService,
orgService
orgService,
keyStore
}: TSuperAdminServiceFactoryDep) => {
const initServerCfg = async () => {
// TODO(akhilmhdh): bad pattern time less change this later to me itself
getServerCfg = () => serverCfgDAL.findOne({});
getServerCfg = async () => {
const config = await keyStore.getItem(ADMIN_CONFIG_KEY);
// missing in keystore means fetch from db
if (!config) {
const serverCfg = await serverCfgDAL.findById(ADMIN_CONFIG_DB_UUID);
if (serverCfg) {
await keyStore.setItemWithExpiry(ADMIN_CONFIG_KEY, ADMIN_CONFIG_KEY_EXP, JSON.stringify(serverCfg)); // insert it back to keystore
}
return serverCfg;
}
const serverCfg = await serverCfgDAL.findOne({});
const keyStoreServerCfg = JSON.parse(config) as TSuperAdmin;
return {
...keyStoreServerCfg,
// this is to allow admin router to work
createdAt: new Date(keyStoreServerCfg.createdAt),
updatedAt: new Date(keyStoreServerCfg.updatedAt)
};
};
// reset on initialized
await keyStore.deleteItem(ADMIN_CONFIG_KEY);
const serverCfg = await serverCfgDAL.findById(ADMIN_CONFIG_DB_UUID);
if (serverCfg) return;
const newCfg = await serverCfgDAL.create({ initialized: false, allowSignUp: true });
// @ts-expect-error id is kept as fixed for idempotence and to avoid race condition
const newCfg = await serverCfgDAL.create({ initialized: false, allowSignUp: true, id: ADMIN_CONFIG_DB_UUID });
return newCfg;
};
const updateServerCfg = async (data: TSuperAdminUpdate) => {
const serverCfg = await getServerCfg();
const cfg = await serverCfgDAL.updateById(serverCfg.id, data);
return cfg;
const updatedServerCfg = await serverCfgDAL.updateById(ADMIN_CONFIG_DB_UUID, data);
await keyStore.setItemWithExpiry(ADMIN_CONFIG_KEY, ADMIN_CONFIG_KEY_EXP, JSON.stringify(updatedServerCfg));
return updatedServerCfg;
};
const adminSignUp = async ({

@ -0,0 +1,39 @@
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
export type TTelemetryDALFactory = ReturnType<typeof telemetryDALFactory>;
export const telemetryDALFactory = (db: TDbClient) => {
const getTelemetryInstanceStats = async () => {
try {
const userCount = (await db(TableName.Users).where({ isGhost: false }).count().first())?.count as string;
const users = parseInt(userCount || "0", 10);
const identityCount = (await db(TableName.Identity).count().first())?.count as string;
const identities = parseInt(identityCount || "0", 10);
const projectCount = (await db(TableName.Project).count().first())?.count as string;
const projects = parseInt(projectCount || "0", 10);
const secretCount = (await db(TableName.Secret).count().first())?.count as string;
const secrets = parseInt(secretCount || "0", 10);
const organizationNames = await db(TableName.Organization).select("name");
const organizations = organizationNames.length;
return {
users,
identities,
projects,
secrets,
organizations,
organizationNames: organizationNames.map(({ name }) => name)
};
} catch (error) {
throw new DatabaseError({ error, name: "TelemtryInstanceStats" });
}
};
return { getTelemetryInstanceStats };
};

@ -0,0 +1,78 @@
import { PostHog } from "posthog-node";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { logger } from "@app/lib/logger";
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
import { getServerCfg } from "../super-admin/super-admin-service";
import { TTelemetryDALFactory } from "./telemetry-dal";
import { TELEMETRY_SECRET_OPERATIONS_KEY, TELEMETRY_SECRET_PROCESSED_KEY } from "./telemetry-service";
import { PostHogEventTypes } from "./telemetry-types";
type TTelemetryQueueServiceFactoryDep = {
queueService: TQueueServiceFactory;
keyStore: Pick<TKeyStoreFactory, "getItem" | "deleteItem">;
telemetryDAL: TTelemetryDALFactory;
};
export type TTelemetryQueueServiceFactory = ReturnType<typeof telemetryQueueServiceFactory>;
export const telemetryQueueServiceFactory = ({
queueService,
keyStore,
telemetryDAL
}: TTelemetryQueueServiceFactoryDep) => {
const appCfg = getConfig();
const postHog =
appCfg.isProductionMode && appCfg.TELEMETRY_ENABLED
? new PostHog(appCfg.POSTHOG_PROJECT_API_KEY, { host: appCfg.POSTHOG_HOST, flushAt: 1, flushInterval: 0 })
: undefined;
queueService.start(QueueName.TelemetryInstanceStats, async () => {
const { instanceId } = await getServerCfg();
const telemtryStats = await telemetryDAL.getTelemetryInstanceStats();
// parse the redis values into integer
const numberOfSecretOperationsMade = parseInt((await keyStore.getItem(TELEMETRY_SECRET_OPERATIONS_KEY)) || "0", 10);
const numberOfSecretProcessed = parseInt((await keyStore.getItem(TELEMETRY_SECRET_PROCESSED_KEY)) || "0", 10);
const stats = { ...telemtryStats, numberOfSecretProcessed, numberOfSecretOperationsMade };
// send to postHog
postHog?.capture({
event: PostHogEventTypes.TelemetryInstanceStats,
distinctId: instanceId,
properties: stats
});
// reset the stats
await keyStore.deleteItem(TELEMETRY_SECRET_PROCESSED_KEY);
await keyStore.deleteItem(TELEMETRY_SECRET_OPERATIONS_KEY);
});
// every day at midnight a telemetry job executes on self hosted
// this sends some telemetry information like instance id secrets operated etc
const startTelemetryCheck = async () => {
// this is a fast way to check its cloud or not
if (appCfg.INFISICAL_CLOUD) return;
// clear previous job
await queueService.stopRepeatableJob(
QueueName.TelemetryInstanceStats,
QueueJobs.TelemetryInstanceStats,
{ pattern: "0 0 * * *", utc: true },
QueueName.TelemetryInstanceStats // just a job id
);
if (postHog) {
await queueService.queue(QueueName.TelemetryInstanceStats, QueueJobs.TelemetryInstanceStats, undefined, {
jobId: QueueName.TelemetryInstanceStats,
repeat: { pattern: "0 0 * * *", utc: true }
});
}
};
queueService.listen(QueueName.TelemetryInstanceStats, "failed", (err) => {
logger.error(err?.failedReason, `${QueueName.TelemetryInstanceStats}: failed`);
});
return {
startTelemetryCheck
};
};

@ -1,15 +1,24 @@
import { PostHog } from "posthog-node";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { InstanceType } from "@app/ee/services/license/license-types";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { request } from "@app/lib/config/request";
import { logger } from "@app/lib/logger";
import { TPostHogEvent } from "./telemetry-types";
import { PostHogEventTypes, TPostHogEvent, TSecretModifiedEvent } from "./telemetry-types";
export const TELEMETRY_SECRET_PROCESSED_KEY = "telemetry-secret-processed";
export const TELEMETRY_SECRET_OPERATIONS_KEY = "telemetry-secret-operations";
export type TTelemetryServiceFactory = ReturnType<typeof telemetryServiceFactory>;
export type TTelemetryServiceFactoryDep = {
keyStore: Pick<TKeyStoreFactory, "getItem" | "incrementBy">;
licenseService: Pick<TLicenseServiceFactory, "getInstanceType">;
};
// type TTelemetryServiceFactoryDep = {};
export const telemetryServiceFactory = () => {
export const telemetryServiceFactory = ({ keyStore, licenseService }: TTelemetryServiceFactoryDep) => {
const appCfg = getConfig();
if (appCfg.isProductionMode && !appCfg.TELEMETRY_ENABLED) {
@ -21,10 +30,9 @@ To opt into telemetry, you can set "TELEMETRY_ENABLED=true" within the environme
`);
}
const postHog =
appCfg.isProductionMode && appCfg.TELEMETRY_ENABLED
? new PostHog(appCfg.POSTHOG_PROJECT_API_KEY, { host: appCfg.POSTHOG_HOST })
: undefined;
const postHog = appCfg.TELEMETRY_ENABLED
? new PostHog(appCfg.POSTHOG_PROJECT_API_KEY, { host: appCfg.POSTHOG_HOST })
: undefined;
// used for email marketting email sending purpose
const sendLoopsEvent = async (email: string, firstName?: string, lastName?: string) => {
@ -51,13 +59,33 @@ To opt into telemetry, you can set "TELEMETRY_ENABLED=true" within the environme
}
};
const sendPostHogEvents = (event: TPostHogEvent) => {
const sendPostHogEvents = async (event: TPostHogEvent) => {
if (postHog) {
postHog.capture({
event: event.event,
distinctId: event.distinctId,
properties: event.properties
});
const instanceType = licenseService.getInstanceType();
// capture posthog only when its cloud or signup event happens in self hosted
if (instanceType === InstanceType.Cloud || event.event === PostHogEventTypes.UserSignedUp) {
postHog.capture({
event: event.event,
distinctId: event.distinctId,
properties: event.properties
});
return;
}
if (
[
PostHogEventTypes.SecretPulled,
PostHogEventTypes.SecretCreated,
PostHogEventTypes.SecretDeleted,
PostHogEventTypes.SecretUpdated
].includes(event.event)
) {
await keyStore.incrementBy(
TELEMETRY_SECRET_PROCESSED_KEY,
(event as TSecretModifiedEvent).properties.numberOfSecrets
);
await keyStore.incrementBy(TELEMETRY_SECRET_OPERATIONS_KEY, 1);
}
}
};

@ -12,7 +12,8 @@ export enum PostHogEventTypes {
ProjectCreated = "Project Created",
IntegrationCreated = "Integration Created",
MachineIdentityCreated = "Machine Identity Created",
UserOrgInvitation = "User Org Invitation"
UserOrgInvitation = "User Org Invitation",
TelemetryInstanceStats = "Self Hosted Instance Stats"
}
export type TSecretModifiedEvent = {
@ -101,6 +102,20 @@ export type TUserOrgInvitedEvent = {
};
};
export type TTelemetryInstanceStatsEvent = {
event: PostHogEventTypes.TelemetryInstanceStats;
properties: {
users: number;
identities: number;
projects: number;
secrets: number;
organizations: number;
organizationNames: number;
numberOfSecretOperationsMade: number;
numberOfSecretProcessed: number;
};
};
export type TPostHogEvent = { distinctId: string } & (
| TSecretModifiedEvent
| TAdminInitEvent
@ -110,4 +125,5 @@ export type TPostHogEvent = { distinctId: string } & (
| TMachineIdentityCreatedEvent
| TIntegrationCreatedEvent
| TProjectCreateEvent
| TTelemetryInstanceStatsEvent
);

@ -1,5 +1,5 @@
infisical:
address: "http://localhost:8080"
address: "https://app.infisical.com/"
auth:
type: "universal-auth"
config:
@ -13,3 +13,12 @@ sinks:
templates:
- source-path: my-dot-ev-secret-template
destination-path: my-dot-env.env
config:
polling-interval: 60s
execute:
command: docker-compose -f docker-compose.prod.yml down && docker-compose -f docker-compose.prod.yml up -d
- source-path: my-dot-ev-secret-template1
destination-path: my-dot-env-1.env
config:
exec:
command: mkdir hello-world1

@ -490,5 +490,7 @@ func CallGetRawSecretsV3(httpClient *resty.Client, request GetRawSecretsV3Reques
return GetRawSecretsV3Response{}, fmt.Errorf("CallGetRawSecretsV3: Unsuccessful response [%v %v] [status-code=%v] [response=%v]", response.Request.Method, response.Request.URL, response.StatusCode(), response.String())
}
getRawSecretsV3Response.ETag = response.Header().Get(("etag"))
return getRawSecretsV3Response, nil
}

@ -505,4 +505,5 @@ type GetRawSecretsV3Response struct {
SecretComment string `json:"secretComment"`
} `json:"secrets"`
Imports []any `json:"imports"`
ETag string
}

Some files were not shown because too many files have changed in this diff Show More