mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-19 19:00:44 +00:00
Compare commits
106 Commits
oidc
...
daniel/fix
Author | SHA1 | Date | |
---|---|---|---|
f45074a2dd | |||
9e38076d45 | |||
d3a6da187b | |||
7a90fa472d | |||
0dd34eae60 | |||
846e2f21cc | |||
16acace648 | |||
60134cf8ac | |||
5feb942d79 | |||
ae2706542c | |||
d5861493bf | |||
53044f3d39 | |||
93268f5767 | |||
318dedb987 | |||
291edf71aa | |||
342665783e | |||
6a7241d7d1 | |||
51fb680f9c | |||
0710c9a84a | |||
e46bce1520 | |||
3919393d33 | |||
c8b7c37aee | |||
2641fccce5 | |||
213f2ed29b | |||
4dcd000dd1 | |||
f64cb10282 | |||
a0ea2627ed | |||
5c40b538af | |||
8dd94a4e10 | |||
041c4a20a0 | |||
4a2a5f42a8 | |||
9fcdf17a04 | |||
97ac8cb45a | |||
e952659415 | |||
1f3f061a06 | |||
5096ce3bdc | |||
621683f787 | |||
f63850e9e9 | |||
4ee0a2ec6c | |||
9569d3971a | |||
443b8f747b | |||
803393c385 | |||
8e95189fd2 | |||
c5f38b6ade | |||
30a1c5ac86 | |||
bbad2ba047 | |||
1445df7015 | |||
ae4a2089d5 | |||
0b924b6e45 | |||
1fcac4cadf | |||
155e315347 | |||
3dce03180f | |||
4748b546c2 | |||
96887cdbfa | |||
553b56e57e | |||
a33f542647 | |||
06b03fc450 | |||
031a834ab1 | |||
89e942fea3 | |||
3c0908a788 | |||
14e42b7ff2 | |||
9476594978 | |||
02be9ebd5e | |||
eb29d1dc28 | |||
21d5c44ea1 | |||
114a4b1412 | |||
fb8c4bd415 | |||
48bf41ac8c | |||
1ad916a784 | |||
c91456838e | |||
79efe64504 | |||
cde8cef8b0 | |||
7207997cea | |||
aaabfb7870 | |||
40cb5c4394 | |||
60b73879df | |||
4339ef4737 | |||
d98669700d | |||
162f339149 | |||
d3eb0c4cc9 | |||
4b4295f53d | |||
6c4d193b12 | |||
d08d412f54 | |||
bb4810470f | |||
24e9c0a39f | |||
3161d0ee67 | |||
8a7e18dc7c | |||
0497c3b49e | |||
e6a89fb9d0 | |||
d9828db2ec | |||
f11efc9e3f | |||
32bad10c0e | |||
41064920f7 | |||
8d8e23add2 | |||
a2a959cc32 | |||
d6cde48181 | |||
23966c12e2 | |||
2a233ea43c | |||
fe497d87c0 | |||
3b9ceff21c | |||
d64d935d7d | |||
8aaed739d5 | |||
7d8b399102 | |||
1594165768 | |||
29d91d83ab | |||
4057e2c6ab |
.github
Makefilebackend
e2e-test
package-lock.jsonpackage.jsonscripts
src
cache
db
knexfile.ts
migrations
schemas
api-keys.tsaudit-logs.tsauth-token-sessions.tsauth-tokens.tsbackup-private-key.tsgit-app-install-sessions.tsgit-app-org.tsidentities.tsidentity-access-tokens.tsidentity-org-memberships.tsidentity-project-memberships.tsidentity-ua-client-secrets.tsidentity-universal-auths.tsincident-contacts.tsintegration-auths.tsintegrations.tsorg-bots.tsorg-memberships.tsorg-roles.tsorganizations.tsproject-bots.tsproject-environments.tsproject-keys.tsproject-memberships.tsproject-roles.tsprojects.tssaml-configs.tsscim-tokens.tssecret-approval-policies-approvers.tssecret-approval-policies.tssecret-approval-request-secret-tags.tssecret-approval-requests-reviewers.tssecret-approval-requests-secrets.tssecret-approval-requests.tssecret-blind-indexes.tssecret-folder-versions.tssecret-folders.tssecret-imports.tssecret-rotation-outputs.tssecret-rotations.tssecret-scanning-git-risks.tssecret-snapshot-folders.tssecret-snapshot-secrets.tssecret-snapshots.tssecret-tag-junction.tssecret-tags.tssecret-version-tag-junction.tssecret-versions.tssecrets.tsservice-tokens.tssuper-admin.tstrusted-ips.tsuser-actions.tsuser-encryption-keys.tsusers.tswebhooks.ts
ee
routes/v1
services
audit-log
license
saml-config
secret-rotation/secret-rotation-queue
secret-scanning/secret-scanning-queue
keystore
lib/config
main.tsqueue
server
app.ts
routes
services
identity-ua
project-membership
secret-tag
secret
super-admin
telemetry
cli
docker-compose.dev.ymldocker-compose.prod.ymldocs
changelog
documentation
getting-started
platform
images/sso/google-saml
attribute-mapping.pngcreate-custom-saml-app.pngcustom-saml-app-config-2.pngcustom-saml-app-config.pngenable-saml.pnginfisical-config.pnginit-config.pngname-custom-saml-app.pnguser-access-assign.pnguser-access.png
infisical-agent
integrations/platforms
internals
mint.jsonself-hosting
frontend
package-lock.jsonpackage.json
src
components/v2
i18n.tspages/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
.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
|
||||
|
2
Makefile
2
Makefile
@ -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
|
||||
|
30
backend/e2e-test/mocks/keystore.ts
Normal file
30
backend/e2e-test/mocks/keystore.ts
Normal file
@ -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
|
||||
|
79
backend/package-lock.json
generated
79
backend/package-lock.json
generated
@ -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>>;
|
||||
`
|
||||
);
|
||||
}
|
||||
|
6
backend/src/cache/redis.ts
vendored
6
backend/src/cache/redis.ts
vendored
@ -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
|
||||
|
25
backend/src/db/migrations/20240226094411_instance-id.ts
Normal file
25
backend/src/db/migrations/20240226094411_instance-id.ts
Normal file
@ -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: {
|
||||
|
20
backend/src/keystore/keystore.ts
Normal file
20
backend/src/keystore/keystore.ts
Normal file
@ -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 ({
|
||||
|
39
backend/src/services/telemetry/telemetry-dal.ts
Normal file
39
backend/src/services/telemetry/telemetry-dal.ts
Normal file
@ -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 };
|
||||
};
|
78
backend/src/services/telemetry/telemetry-queue.ts
Normal file
78
backend/src/services/telemetry/telemetry-queue.ts
Normal file
@ -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
Reference in New Issue
Block a user