diff --git a/.github/workflows/build-staging-and-deploy-aws.yml b/.github/workflows/build-staging-and-deploy-aws.yml index 78a193d30..4341d19f5 100644 --- a/.github/workflows/build-staging-and-deploy-aws.yml +++ b/.github/workflows/build-staging-and-deploy-aws.yml @@ -74,21 +74,21 @@ jobs: uses: pr-mpt/actions-commit-hash@v2 - name: Download task definition run: | - aws ecs describe-task-definition --task-definition infisical-prod-platform --query taskDefinition > task-definition.json + aws ecs describe-task-definition --task-definition infisical-core-platform --query taskDefinition > task-definition.json - name: Render Amazon ECS task definition id: render-web-container uses: aws-actions/amazon-ecs-render-task-definition@v1 with: task-definition: task-definition.json - container-name: infisical-prod-platform + container-name: infisical-core-platform image: infisical/staging_infisical:${{ steps.commit.outputs.short }} environment-variables: "LOG_LEVEL=info" - name: Deploy to Amazon ECS service uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.render-web-container.outputs.task-definition }} - service: infisical-prod-platform - cluster: infisical-prod-platform + service: infisical-core-platform + cluster: infisical-core-platform wait-for-service-stability: true production-postgres-deployment: @@ -135,6 +135,6 @@ jobs: uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.render-web-container.outputs.task-definition }} - service: infisical-prod-platform - cluster: infisical-prod-platform + service: infisical-core-platform + cluster: infisical-core-platform wait-for-service-stability: true diff --git a/backend/src/@types/fastify.d.ts b/backend/src/@types/fastify.d.ts index 7f44b6ec3..994b324f6 100644 --- a/backend/src/@types/fastify.d.ts +++ b/backend/src/@types/fastify.d.ts @@ -32,7 +32,7 @@ import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-se import { TGroupProjectServiceFactory } from "@app/services/group-project/group-project-service"; import { TIdentityServiceFactory } from "@app/services/identity/identity-service"; import { TIdentityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service"; -import { TIdentityAwsIamAuthServiceFactory } from "@app/services/identity-aws-iam-auth/identity-aws-iam-auth-service"; +import { TIdentityAwsAuthServiceFactory } from "@app/services/identity-aws-auth/identity-aws-auth-service"; import { TIdentityGcpAuthServiceFactory } from "@app/services/identity-gcp-auth/identity-gcp-auth-service"; import { TIdentityProjectServiceFactory } from "@app/services/identity-project/identity-project-service"; import { TIdentityUaServiceFactory } from "@app/services/identity-ua/identity-ua-service"; @@ -118,7 +118,7 @@ declare module "fastify" { identityProject: TIdentityProjectServiceFactory; identityUa: TIdentityUaServiceFactory; identityGcpAuth: TIdentityGcpAuthServiceFactory; - identityAwsIamAuth: TIdentityAwsIamAuthServiceFactory; + identityAwsAuth: TIdentityAwsAuthServiceFactory; accessApprovalPolicy: TAccessApprovalPolicyServiceFactory; accessApprovalRequest: TAccessApprovalRequestServiceFactory; secretApprovalPolicy: TSecretApprovalPolicyServiceFactory; diff --git a/backend/src/@types/knex.d.ts b/backend/src/@types/knex.d.ts index c8884bde4..3a6aa549d 100644 --- a/backend/src/@types/knex.d.ts +++ b/backend/src/@types/knex.d.ts @@ -59,9 +59,9 @@ import { TIdentityAccessTokens, TIdentityAccessTokensInsert, TIdentityAccessTokensUpdate, - TIdentityAwsIamAuths, - TIdentityAwsIamAuthsInsert, - TIdentityAwsIamAuthsUpdate, + TIdentityAwsAuths, + TIdentityAwsAuthsInsert, + TIdentityAwsAuthsUpdate, TIdentityGcpAuths, TIdentityGcpAuthsInsert, TIdentityGcpAuthsUpdate, @@ -337,10 +337,10 @@ declare module "knex/types/tables" { TIdentityGcpAuthsInsert, TIdentityGcpAuthsUpdate >; - [TableName.IdentityAwsIamAuth]: Knex.CompositeTableType< - TIdentityAwsIamAuths, - TIdentityAwsIamAuthsInsert, - TIdentityAwsIamAuthsUpdate + [TableName.IdentityAwsAuth]: Knex.CompositeTableType< + TIdentityAwsAuths, + TIdentityAwsAuthsInsert, + TIdentityAwsAuthsUpdate >; [TableName.IdentityUaClientSecret]: Knex.CompositeTableType< TIdentityUaClientSecrets, diff --git a/backend/src/db/migrations/20240330075120_org-memberships-unique-constraint.ts b/backend/src/db/migrations/20240405000045_org-memberships-unique-constraint.ts similarity index 100% rename from backend/src/db/migrations/20240330075120_org-memberships-unique-constraint.ts rename to backend/src/db/migrations/20240405000045_org-memberships-unique-constraint.ts diff --git a/backend/src/db/migrations/20240507210655_identity-aws-iam-auth.ts b/backend/src/db/migrations/20240507210655_identity-aws-auth.ts similarity index 71% rename from backend/src/db/migrations/20240507210655_identity-aws-iam-auth.ts rename to backend/src/db/migrations/20240507210655_identity-aws-auth.ts index 0728d4f28..f182425c3 100644 --- a/backend/src/db/migrations/20240507210655_identity-aws-iam-auth.ts +++ b/backend/src/db/migrations/20240507210655_identity-aws-auth.ts @@ -4,8 +4,8 @@ import { TableName } from "../schemas"; import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.IdentityAwsIamAuth))) { - await knex.schema.createTable(TableName.IdentityAwsIamAuth, (t) => { + if (!(await knex.schema.hasTable(TableName.IdentityAwsAuth))) { + await knex.schema.createTable(TableName.IdentityAwsAuth, (t) => { t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); t.bigInteger("accessTokenTTL").defaultTo(7200).notNullable(); t.bigInteger("accessTokenMaxTTL").defaultTo(7200).notNullable(); @@ -14,16 +14,17 @@ export async function up(knex: Knex): Promise { t.timestamps(true, true, true); t.uuid("identityId").notNullable().unique(); t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); + t.string("type").notNullable(); t.string("stsEndpoint").notNullable(); t.string("allowedPrincipalArns").notNullable(); t.string("allowedAccountIds").notNullable(); }); } - await createOnUpdateTrigger(knex, TableName.IdentityAwsIamAuth); + await createOnUpdateTrigger(knex, TableName.IdentityAwsAuth); } export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.IdentityAwsIamAuth); - await dropOnUpdateTrigger(knex, TableName.IdentityAwsIamAuth); + await knex.schema.dropTableIfExists(TableName.IdentityAwsAuth); + await dropOnUpdateTrigger(knex, TableName.IdentityAwsAuth); } diff --git a/backend/src/db/schemas/identity-aws-iam-auths.ts b/backend/src/db/schemas/identity-aws-auths.ts similarity index 65% rename from backend/src/db/schemas/identity-aws-iam-auths.ts rename to backend/src/db/schemas/identity-aws-auths.ts index 8912c71b3..f4444b00f 100644 --- a/backend/src/db/schemas/identity-aws-iam-auths.ts +++ b/backend/src/db/schemas/identity-aws-auths.ts @@ -7,7 +7,7 @@ import { z } from "zod"; import { TImmutableDBKeys } from "./models"; -export const IdentityAwsIamAuthsSchema = z.object({ +export const IdentityAwsAuthsSchema = z.object({ id: z.string().uuid(), accessTokenTTL: z.coerce.number().default(7200), accessTokenMaxTTL: z.coerce.number().default(7200), @@ -16,11 +16,12 @@ export const IdentityAwsIamAuthsSchema = z.object({ createdAt: z.date(), updatedAt: z.date(), identityId: z.string().uuid(), + type: z.string(), stsEndpoint: z.string(), allowedPrincipalArns: z.string(), allowedAccountIds: z.string() }); -export type TIdentityAwsIamAuths = z.infer; -export type TIdentityAwsIamAuthsInsert = Omit, TImmutableDBKeys>; -export type TIdentityAwsIamAuthsUpdate = Partial, TImmutableDBKeys>>; +export type TIdentityAwsAuths = z.infer; +export type TIdentityAwsAuthsInsert = Omit, TImmutableDBKeys>; +export type TIdentityAwsAuthsUpdate = Partial, TImmutableDBKeys>>; diff --git a/backend/src/db/schemas/index.ts b/backend/src/db/schemas/index.ts index 9ad2c3e46..4993003f9 100644 --- a/backend/src/db/schemas/index.ts +++ b/backend/src/db/schemas/index.ts @@ -17,7 +17,7 @@ export * from "./group-project-memberships"; export * from "./groups"; export * from "./identities"; export * from "./identity-access-tokens"; -export * from "./identity-aws-iam-auths"; +export * from "./identity-aws-auths"; export * from "./identity-gcp-auths"; export * from "./identity-org-memberships"; export * from "./identity-project-additional-privilege"; diff --git a/backend/src/db/schemas/models.ts b/backend/src/db/schemas/models.ts index 952d18539..4951de99e 100644 --- a/backend/src/db/schemas/models.ts +++ b/backend/src/db/schemas/models.ts @@ -46,7 +46,7 @@ export enum TableName { IdentityUniversalAuth = "identity_universal_auths", IdentityGcpAuth = "identity_gcp_auths", IdentityUaClientSecret = "identity_ua_client_secrets", - IdentityAwsIamAuth = "identity_aws_iam_auths", + IdentityAwsAuth = "identity_aws_auths", IdentityOrgMembership = "identity_org_memberships", IdentityProjectMembership = "identity_project_memberships", IdentityProjectMembershipRole = "identity_project_membership_role", @@ -146,5 +146,5 @@ export enum ProjectUpgradeStatus { export enum IdentityAuthMethod { Univeral = "universal-auth", GCP_AUTH = "gcp-auth", - AWS_IAM_AUTH = "aws-iam-auth" + AWS_AUTH = "aws-auth" } diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 86fe56c52..81554a92f 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -70,10 +70,10 @@ export enum EventType { ADD_IDENTITY_GCP_AUTH = "add-identity-gcp -auth", UPDATE_IDENTITY_GCP_AUTH = "update-identity-gcp-auth", GET_IDENTITY_GCP_AUTH = "get-identity-gcp-auth", - LOGIN_IDENTITY_AWS_IAM_AUTH = "login-identity-aws-iam-auth", - ADD_IDENTITY_AWS_IAM_AUTH = "add-identity-aws-iam-auth", - UPDATE_IDENTITY_AWS_IAM_AUTH = "update-identity-aws-iam-auth", - GET_IDENTITY_AWS_IAM_AUTH = "get-identity-aws-iam-auth", + LOGIN_IDENTITY_AWS_AUTH = "login-identity-aws-auth", + ADD_IDENTITY_AWS_AUTH = "add-identity-aws-auth", + UPDATE_IDENTITY_AWS_AUTH = "update-identity-aws-auth", + GET_IDENTITY_AWS_AUTH = "get-identity-aws-auth", CREATE_ENVIRONMENT = "create-environment", UPDATE_ENVIRONMENT = "update-environment", DELETE_ENVIRONMENT = "delete-environment", @@ -460,17 +460,17 @@ interface GetIdentityGcpAuthEvent { }; } -interface LoginIdentityAwsIamAuthEvent { - type: EventType.LOGIN_IDENTITY_AWS_IAM_AUTH; +interface LoginIdentityAwsAuthEvent { + type: EventType.LOGIN_IDENTITY_AWS_AUTH; metadata: { identityId: string; - identityAwsIamAuthId: string; + identityAwsAuthId: string; identityAccessTokenId: string; }; } -interface AddIdentityAwsIamAuthEvent { - type: EventType.ADD_IDENTITY_AWS_IAM_AUTH; +interface AddIdentityAwsAuthEvent { + type: EventType.ADD_IDENTITY_AWS_AUTH; metadata: { identityId: string; stsEndpoint: string; @@ -483,8 +483,8 @@ interface AddIdentityAwsIamAuthEvent { }; } -interface UpdateIdentityAwsIamAuthEvent { - type: EventType.UPDATE_IDENTITY_AWS_IAM_AUTH; +interface UpdateIdentityAwsAuthEvent { + type: EventType.UPDATE_IDENTITY_AWS_AUTH; metadata: { identityId: string; stsEndpoint?: string; @@ -497,8 +497,8 @@ interface UpdateIdentityAwsIamAuthEvent { }; } -interface GetIdentityAwsIamAuthEvent { - type: EventType.GET_IDENTITY_AWS_IAM_AUTH; +interface GetIdentityAwsAuthEvent { + type: EventType.GET_IDENTITY_AWS_AUTH; metadata: { identityId: string; }; @@ -762,10 +762,10 @@ export type Event = | AddIdentityGcpAuthEvent | UpdateIdentityGcpAuthEvent | GetIdentityGcpAuthEvent - | LoginIdentityAwsIamAuthEvent - | AddIdentityAwsIamAuthEvent - | UpdateIdentityAwsIamAuthEvent - | GetIdentityAwsIamAuthEvent + | LoginIdentityAwsAuthEvent + | AddIdentityAwsAuthEvent + | UpdateIdentityAwsAuthEvent + | GetIdentityAwsAuthEvent | CreateEnvironmentEvent | UpdateEnvironmentEvent | DeleteEnvironmentEvent diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index 336385472..4af0c303b 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -92,7 +92,7 @@ export const UNIVERSAL_AUTH = { } } as const; -export const AWS_IAM_AUTH = { +export const AWS_AUTH = { LOGIN: { identityId: "The ID of the identity to login.", iamHttpRequestMethod: "The HTTP request method used in the signed request.", @@ -288,7 +288,8 @@ export const RAW_SECRETS = { recursive: "Whether or not to fetch all secrets from the specified base path, and all of its subdirectories. Note, the max depth is 20 deep.", workspaceId: "The ID of the project to list secrets from.", - workspaceSlug: "The slug of the project to list secrets from. This parameter is only usable by machine identities.", + workspaceSlug: + "The slug of the project to list secrets from. This parameter is only applicable by machine identities.", environment: "The slug of the environment to list secrets from.", secretPath: "The secret path to list secrets from.", includeImports: "Weather to include imported secrets or not." @@ -307,6 +308,7 @@ export const RAW_SECRETS = { GET: { secretName: "The name of the secret to get.", workspaceId: "The ID of the project to get the secret from.", + workspaceSlug: "The slug of the project to get the secret from.", environment: "The slug of the environment to get the secret from.", secretPath: "The path of the secret to get.", version: "The version of the secret to get.", @@ -625,7 +627,8 @@ export const INTEGRATION = { shouldAutoRedeploy: "Used by Render to trigger auto deploy.", secretGCPLabel: "The label for GCP secrets.", secretAWSTag: "The tags for AWS secrets.", - kmsKeyId: "The ID of the encryption key from AWS KMS." + kmsKeyId: "The ID of the encryption key from AWS KMS.", + shouldDisableDelete: "The flag to disable deletion of secrets in AWS Parameter Store." } }, UPDATE: { diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index e14329b9d..5eb46e861 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -78,8 +78,8 @@ import { identityOrgDALFactory } from "@app/services/identity/identity-org-dal"; import { identityServiceFactory } from "@app/services/identity/identity-service"; import { identityAccessTokenDALFactory } from "@app/services/identity-access-token/identity-access-token-dal"; import { identityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service"; -import { identityAwsIamAuthDALFactory } from "@app/services/identity-aws-iam-auth/identity-aws-iam-auth-dal"; -import { identityAwsIamAuthServiceFactory } from "@app/services/identity-aws-iam-auth/identity-aws-iam-auth-service"; +import { identityAwsAuthDALFactory } from "@app/services/identity-aws-auth/identity-aws-auth-dal"; +import { identityAwsAuthServiceFactory } from "@app/services/identity-aws-auth/identity-aws-auth-service"; import { identityGcpAuthDALFactory } from "@app/services/identity-gcp-auth/identity-gcp-auth-dal"; import { identityGcpAuthServiceFactory } from "@app/services/identity-gcp-auth/identity-gcp-auth-service"; import { identityProjectDALFactory } from "@app/services/identity-project/identity-project-dal"; @@ -205,7 +205,7 @@ export const registerRoutes = async ( const identityUaDAL = identityUaDALFactory(db); const identityUaClientSecretDAL = identityUaClientSecretDALFactory(db); - const identityAwsIamAuthDAL = identityAwsIamAuthDALFactory(db); + const identityAwsAuthDAL = identityAwsAuthDALFactory(db); const identityGcpAuthDAL = identityGcpAuthDALFactory(db); @@ -716,9 +716,9 @@ export const registerRoutes = async ( licenseService }); - const identityAWSIAMAuthService = identityAwsIamAuthServiceFactory({ + const identityAwsAuthService = identityAwsAuthServiceFactory({ identityAccessTokenDAL, - identityAwsIamAuthDAL, + identityAwsAuthDAL, identityOrgMembershipDAL, identityDAL, licenseService, @@ -794,7 +794,7 @@ export const registerRoutes = async ( identityProject: identityProjectService, identityUa: identityUaService, identityGcpAuth: identityGcpAuthService, - identityAwsIamAuth: identityAWSIAMAuthService, + identityAwsAuth: identityAwsAuthService, secretApprovalPolicy: sapService, accessApprovalPolicy: accessApprovalPolicyService, accessApprovalRequest: accessApprovalRequestService, diff --git a/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts b/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts index 12003a158..f8c045168 100644 --- a/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts +++ b/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts @@ -1,8 +1,8 @@ import { z } from "zod"; -import { IdentityAwsIamAuthsSchema } from "@app/db/schemas"; +import { IdentityAwsAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { AWS_IAM_AUTH } from "@app/lib/api-docs"; +import { AWS_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -10,22 +10,22 @@ import { TIdentityTrustedIp } from "@app/services/identity/identity-types"; import { validateAccountIds, validatePrincipalArns -} from "@app/services/identity-aws-iam-auth/identity-aws-iam-auth-validators"; +} from "@app/services/identity-aws-auth/identity-aws-auth-validators"; -export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvider) => { +export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider) => { server.route({ method: "POST", - url: "/aws-iam-auth/login", + url: "/aws-auth/login", config: { rateLimit: writeLimit }, schema: { - description: "Login with AWS IAM Auth", + description: "Login with AWS Auth", body: z.object({ - identityId: z.string().describe(AWS_IAM_AUTH.LOGIN.identityId), - iamHttpRequestMethod: z.string().default("POST").describe(AWS_IAM_AUTH.LOGIN.iamHttpRequestMethod), - iamRequestBody: z.string().describe(AWS_IAM_AUTH.LOGIN.iamRequestBody), - iamRequestHeaders: z.string().describe(AWS_IAM_AUTH.LOGIN.iamRequestHeaders) + identityId: z.string().describe(AWS_AUTH.LOGIN.identityId), + iamHttpRequestMethod: z.string().default("POST").describe(AWS_AUTH.LOGIN.iamHttpRequestMethod), + iamRequestBody: z.string().describe(AWS_AUTH.LOGIN.iamRequestBody), + iamRequestHeaders: z.string().describe(AWS_AUTH.LOGIN.iamRequestHeaders) }), response: { 200: z.object({ @@ -37,18 +37,18 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide } }, handler: async (req) => { - const { identityAwsIamAuth, accessToken, identityAccessToken, identityMembershipOrg } = - await server.services.identityAwsIamAuth.login(req.body); + const { identityAwsAuth, accessToken, identityAccessToken, identityMembershipOrg } = + await server.services.identityAwsAuth.login(req.body); await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, orgId: identityMembershipOrg?.orgId, event: { - type: EventType.LOGIN_IDENTITY_AWS_IAM_AUTH, + type: EventType.LOGIN_IDENTITY_AWS_AUTH, metadata: { - identityId: identityAwsIamAuth.identityId, + identityId: identityAwsAuth.identityId, identityAccessTokenId: identityAccessToken.id, - identityAwsIamAuthId: identityAwsIamAuth.id + identityAwsAuthId: identityAwsAuth.id } } }); @@ -56,21 +56,21 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide return { accessToken, tokenType: "Bearer" as const, - expiresIn: identityAwsIamAuth.accessTokenTTL, - accessTokenMaxTTL: identityAwsIamAuth.accessTokenMaxTTL + expiresIn: identityAwsAuth.accessTokenTTL, + accessTokenMaxTTL: identityAwsAuth.accessTokenMaxTTL }; } }); server.route({ method: "POST", - url: "/aws-iam-auth/identities/:identityId", + url: "/aws-auth/identities/:identityId", config: { rateLimit: writeLimit }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { - description: "Attach AWS IAM Auth configuration onto identity", + description: "Attach AWS Auth configuration onto identity", security: [ { bearerAuth: [] @@ -109,12 +109,12 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide }), response: { 200: z.object({ - identityAwsIamAuth: IdentityAwsIamAuthsSchema + identityAwsAuth: IdentityAwsAuthsSchema }) } }, handler: async (req) => { - const identityAwsIamAuth = await server.services.identityAwsIamAuth.attachAwsIamAuth({ + const identityAwsAuth = await server.services.identityAwsAuth.attachAwsAuth({ actor: req.permission.type, actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, @@ -125,35 +125,35 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, - orgId: identityAwsIamAuth.orgId, + orgId: identityAwsAuth.orgId, event: { - type: EventType.ADD_IDENTITY_AWS_IAM_AUTH, + type: EventType.ADD_IDENTITY_AWS_AUTH, metadata: { - identityId: identityAwsIamAuth.identityId, - stsEndpoint: identityAwsIamAuth.stsEndpoint, - allowedPrincipalArns: identityAwsIamAuth.allowedPrincipalArns, - allowedAccountIds: identityAwsIamAuth.allowedAccountIds, - accessTokenTTL: identityAwsIamAuth.accessTokenTTL, - accessTokenMaxTTL: identityAwsIamAuth.accessTokenMaxTTL, - accessTokenTrustedIps: identityAwsIamAuth.accessTokenTrustedIps as TIdentityTrustedIp[], - accessTokenNumUsesLimit: identityAwsIamAuth.accessTokenNumUsesLimit + identityId: identityAwsAuth.identityId, + stsEndpoint: identityAwsAuth.stsEndpoint, + allowedPrincipalArns: identityAwsAuth.allowedPrincipalArns, + allowedAccountIds: identityAwsAuth.allowedAccountIds, + accessTokenTTL: identityAwsAuth.accessTokenTTL, + accessTokenMaxTTL: identityAwsAuth.accessTokenMaxTTL, + accessTokenTrustedIps: identityAwsAuth.accessTokenTrustedIps as TIdentityTrustedIp[], + accessTokenNumUsesLimit: identityAwsAuth.accessTokenNumUsesLimit } } }); - return { identityAwsIamAuth }; + return { identityAwsAuth }; } }); server.route({ method: "PATCH", - url: "/aws-iam-auth/identities/:identityId", + url: "/aws-auth/identities/:identityId", config: { rateLimit: writeLimit }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { - description: "Update AWS IAM Auth configuration on identity", + description: "Update AWS Auth configuration on identity", security: [ { bearerAuth: [] @@ -185,12 +185,12 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide }), response: { 200: z.object({ - identityAwsIamAuth: IdentityAwsIamAuthsSchema + identityAwsAuth: IdentityAwsAuthsSchema }) } }, handler: async (req) => { - const identityAwsIamAuth = await server.services.identityAwsIamAuth.updateAwsIamAuth({ + const identityAwsAuth = await server.services.identityAwsAuth.updateAwsAuth({ actor: req.permission.type, actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, @@ -201,35 +201,35 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, - orgId: identityAwsIamAuth.orgId, + orgId: identityAwsAuth.orgId, event: { - type: EventType.UPDATE_IDENTITY_AWS_IAM_AUTH, + type: EventType.UPDATE_IDENTITY_AWS_AUTH, metadata: { - identityId: identityAwsIamAuth.identityId, - stsEndpoint: identityAwsIamAuth.stsEndpoint, - allowedPrincipalArns: identityAwsIamAuth.allowedPrincipalArns, - allowedAccountIds: identityAwsIamAuth.allowedAccountIds, - accessTokenTTL: identityAwsIamAuth.accessTokenTTL, - accessTokenMaxTTL: identityAwsIamAuth.accessTokenMaxTTL, - accessTokenTrustedIps: identityAwsIamAuth.accessTokenTrustedIps as TIdentityTrustedIp[], - accessTokenNumUsesLimit: identityAwsIamAuth.accessTokenNumUsesLimit + identityId: identityAwsAuth.identityId, + stsEndpoint: identityAwsAuth.stsEndpoint, + allowedPrincipalArns: identityAwsAuth.allowedPrincipalArns, + allowedAccountIds: identityAwsAuth.allowedAccountIds, + accessTokenTTL: identityAwsAuth.accessTokenTTL, + accessTokenMaxTTL: identityAwsAuth.accessTokenMaxTTL, + accessTokenTrustedIps: identityAwsAuth.accessTokenTrustedIps as TIdentityTrustedIp[], + accessTokenNumUsesLimit: identityAwsAuth.accessTokenNumUsesLimit } } }); - return { identityAwsIamAuth }; + return { identityAwsAuth }; } }); server.route({ method: "GET", - url: "/aws-iam-auth/identities/:identityId", + url: "/aws-auth/identities/:identityId", config: { rateLimit: readLimit }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { - description: "Retrieve AWS IAM Auth configuration on identity", + description: "Retrieve AWS Auth configuration on identity", security: [ { bearerAuth: [] @@ -240,12 +240,12 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide }), response: { 200: z.object({ - identityAwsIamAuth: IdentityAwsIamAuthsSchema + identityAwsAuth: IdentityAwsAuthsSchema }) } }, handler: async (req) => { - const identityAwsIamAuth = await server.services.identityAwsIamAuth.getAwsIamAuth({ + const identityAwsAuth = await server.services.identityAwsAuth.getAwsAuth({ identityId: req.params.identityId, actor: req.permission.type, actorId: req.permission.id, @@ -255,15 +255,15 @@ export const registerIdentityAwsIamAuthRouter = async (server: FastifyZodProvide await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, - orgId: identityAwsIamAuth.orgId, + orgId: identityAwsAuth.orgId, event: { - type: EventType.GET_IDENTITY_AWS_IAM_AUTH, + type: EventType.GET_IDENTITY_AWS_AUTH, metadata: { - identityId: identityAwsIamAuth.identityId + identityId: identityAwsAuth.identityId } } }); - return { identityAwsIamAuth }; + return { identityAwsAuth }; } }); }; diff --git a/backend/src/server/routes/v1/index.ts b/backend/src/server/routes/v1/index.ts index 406f78be6..75d6a80ff 100644 --- a/backend/src/server/routes/v1/index.ts +++ b/backend/src/server/routes/v1/index.ts @@ -2,7 +2,7 @@ import { registerAdminRouter } from "./admin-router"; import { registerAuthRoutes } from "./auth-router"; import { registerProjectBotRouter } from "./bot-router"; import { registerIdentityAccessTokenRouter } from "./identity-access-token-router"; -import { registerIdentityAwsIamAuthRouter } from "./identity-aws-iam-auth-router"; +import { registerIdentityAwsAuthRouter } from "./identity-aws-iam-auth-router"; import { registerIdentityGcpAuthRouter } from "./identity-gcp-auth-router"; import { registerIdentityRouter } from "./identity-router"; import { registerIdentityUaRouter } from "./identity-ua"; @@ -30,8 +30,9 @@ export const registerV1Routes = async (server: FastifyZodProvider) => { await authRouter.register(registerAuthRoutes); await authRouter.register(registerIdentityUaRouter); await authRouter.register(registerIdentityGcpAuthRouter); - await authRouter.register(registerIdentityAwsIamAuthRouter); await authRouter.register(registerIdentityAccessTokenRouter); + await authRouter.register(registerIdentityAccessTokenRouter); + await authRouter.register(registerIdentityAwsAuthRouter); }, { prefix: "/auth" } ); diff --git a/backend/src/server/routes/v1/integration-router.ts b/backend/src/server/routes/v1/integration-router.ts index f908aa1fc..975e6e7c8 100644 --- a/backend/src/server/routes/v1/integration-router.ts +++ b/backend/src/server/routes/v1/integration-router.ts @@ -66,7 +66,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => { ) .optional() .describe(INTEGRATION.CREATE.metadata.secretAWSTag), - kmsKeyId: z.string().optional().describe(INTEGRATION.CREATE.metadata.kmsKeyId) + kmsKeyId: z.string().optional().describe(INTEGRATION.CREATE.metadata.kmsKeyId), + shouldDisableDelete: z.boolean().optional().describe(INTEGRATION.CREATE.metadata.shouldDisableDelete) }) .default({}) }), diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index cae51f858..e2d8ddb12 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -293,6 +293,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }), querystring: z.object({ workspaceId: z.string().trim().optional().describe(RAW_SECRETS.GET.workspaceId), + workspaceSlug: z.string().trim().optional().describe(RAW_SECRETS.GET.workspaceSlug), environment: z.string().trim().optional().describe(RAW_SECRETS.GET.environment), secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.GET.secretPath), version: z.coerce.number().optional().describe(RAW_SECRETS.GET.version), @@ -311,6 +312,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { + const { workspaceSlug } = req.query; let { secretPath, environment, workspaceId } = req.query; if (req.auth.actor === ActorType.SERVICE) { const scope = ServiceTokenScopes.parse(req.auth.serviceToken.scopes); @@ -322,7 +324,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } } - if (!workspaceId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" }); + if (!environment) throw new BadRequestError({ message: "Missing environment" }); + if (!workspaceId && !workspaceSlug) + throw new BadRequestError({ message: "You must provide workspaceSlug or workspaceId" }); const secret = await server.services.secret.getSecretByNameRaw({ actorId: req.permission.id, @@ -331,6 +335,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { actorOrgId: req.permission.orgId, environment, projectId: workspaceId, + projectSlug: workspaceSlug, path: secretPath, secretName: req.params.secretName, type: req.query.type, @@ -339,7 +344,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }); await server.services.auditLog.createAuditLog({ - projectId: req.query.workspaceId, + projectId: secret.workspace, ...req.auditLogInfo, event: { type: EventType.GET_SECRET, @@ -358,7 +363,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, - workspaceId, + workspaceId: secret.workspace, environment, secretPath: req.query.secretPath, channel: getUserAgentType(req.headers["user-agent"]), diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-dal.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-dal.ts new file mode 100644 index 000000000..6ce215c58 --- /dev/null +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-dal.ts @@ -0,0 +1,11 @@ +import { TDbClient } from "@app/db"; +import { TableName } from "@app/db/schemas"; +import { ormify } from "@app/lib/knex"; + +export type TIdentityAwsAuthDALFactory = ReturnType; + +export const identityAwsAuthDALFactory = (db: TDbClient) => { + const awsAuthOrm = ormify(db, TableName.IdentityAwsAuth); + + return awsAuthOrm; +}; diff --git a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-fns.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-fns.ts similarity index 100% rename from backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-fns.ts rename to backend/src/services/identity-aws-auth/identity-aws-auth-fns.ts diff --git a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-service.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts similarity index 71% rename from backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-service.ts rename to backend/src/services/identity-aws-auth/identity-aws-auth-service.ts index 95deba2d8..a58944909 100644 --- a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-service.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts @@ -16,48 +16,43 @@ import { TIdentityDALFactory } from "../identity/identity-dal"; import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; -import { TIdentityAwsIamAuthDALFactory } from "./identity-aws-iam-auth-dal"; -import { extractPrincipalArn } from "./identity-aws-iam-auth-fns"; +import { TIdentityAwsAuthDALFactory } from "./identity-aws-auth-dal"; +import { extractPrincipalArn } from "./identity-aws-auth-fns"; import { - TAttachAWSIAMAuthDTO, - TAWSGetCallerIdentityHeaders, - TGetAWSIAMAuthDTO, + TAttachAwsAuthDTO, + TAwsGetCallerIdentityHeaders, + TGetAwsAuthDTO, TGetCallerIdentityResponse, - TLoginAWSIAMAuthDTO, - TUpdateAWSIAMAuthDTO -} from "./identity-aws-iam-auth-types"; + TLoginAwsAuthDTO, + TUpdateAwsAuthDTO +} from "./identity-aws-auth-types"; -type TIdentityAwsIamAuthServiceFactoryDep = { +type TIdentityAwsAuthServiceFactoryDep = { identityAccessTokenDAL: Pick; - identityAwsIamAuthDAL: Pick; + identityAwsAuthDAL: Pick; identityOrgMembershipDAL: Pick; identityDAL: Pick; licenseService: Pick; permissionService: Pick; }; -export type TIdentityAwsIamAuthServiceFactory = ReturnType; +export type TIdentityAwsAuthServiceFactory = ReturnType; -export const identityAwsIamAuthServiceFactory = ({ +export const identityAwsAuthServiceFactory = ({ identityAccessTokenDAL, - identityAwsIamAuthDAL, + identityAwsAuthDAL, identityOrgMembershipDAL, identityDAL, licenseService, permissionService -}: TIdentityAwsIamAuthServiceFactoryDep) => { - const login = async ({ - identityId, - iamHttpRequestMethod, - iamRequestBody, - iamRequestHeaders - }: TLoginAWSIAMAuthDTO) => { - const identityAwsIamAuth = await identityAwsIamAuthDAL.findOne({ identityId }); - if (!identityAwsIamAuth) throw new UnauthorizedError(); +}: TIdentityAwsAuthServiceFactoryDep) => { + const login = async ({ identityId, iamHttpRequestMethod, iamRequestBody, iamRequestHeaders }: TLoginAwsAuthDTO) => { + const identityAwsAuth = await identityAwsAuthDAL.findOne({ identityId }); + if (!identityAwsAuth) throw new UnauthorizedError(); - const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityAwsIamAuth.identityId }); + const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityAwsAuth.identityId }); - const headers: TAWSGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString()); + const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString()); const body: string = Buffer.from(iamRequestBody, "base64").toString(); const { @@ -68,15 +63,15 @@ export const identityAwsIamAuthServiceFactory = ({ } }: { data: TGetCallerIdentityResponse } = await axios({ method: iamHttpRequestMethod, - url: identityAwsIamAuth.stsEndpoint, + url: identityAwsAuth.stsEndpoint, headers, data: body }); - if (identityAwsIamAuth.allowedAccountIds) { + if (identityAwsAuth.allowedAccountIds) { // validate if Account is in the list of allowed Account IDs - const isAccountAllowed = identityAwsIamAuth.allowedAccountIds + const isAccountAllowed = identityAwsAuth.allowedAccountIds .split(",") .map((accountId) => accountId.trim()) .some((accountId) => accountId === Account); @@ -84,10 +79,10 @@ export const identityAwsIamAuthServiceFactory = ({ if (!isAccountAllowed) throw new UnauthorizedError(); } - if (identityAwsIamAuth.allowedPrincipalArns) { + if (identityAwsAuth.allowedPrincipalArns) { // validate if Arn is in the list of allowed Principal ARNs - const isArnAllowed = identityAwsIamAuth.allowedPrincipalArns + const isArnAllowed = identityAwsAuth.allowedPrincipalArns .split(",") .map((principalArn) => principalArn.trim()) .some((principalArn) => { @@ -100,15 +95,15 @@ export const identityAwsIamAuthServiceFactory = ({ if (!isArnAllowed) throw new UnauthorizedError(); } - const identityAccessToken = await identityAwsIamAuthDAL.transaction(async (tx) => { + const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => { const newToken = await identityAccessTokenDAL.create( { - identityId: identityAwsIamAuth.identityId, + identityId: identityAwsAuth.identityId, isAccessTokenRevoked: false, - accessTokenTTL: identityAwsIamAuth.accessTokenTTL, - accessTokenMaxTTL: identityAwsIamAuth.accessTokenMaxTTL, + accessTokenTTL: identityAwsAuth.accessTokenTTL, + accessTokenMaxTTL: identityAwsAuth.accessTokenMaxTTL, accessTokenNumUses: 0, - accessTokenNumUsesLimit: identityAwsIamAuth.accessTokenNumUsesLimit + accessTokenNumUsesLimit: identityAwsAuth.accessTokenNumUsesLimit }, tx ); @@ -118,7 +113,7 @@ export const identityAwsIamAuthServiceFactory = ({ const appCfg = getConfig(); const accessToken = jwt.sign( { - identityId: identityAwsIamAuth.identityId, + identityId: identityAwsAuth.identityId, identityAccessTokenId: identityAccessToken.id, authTokenType: AuthTokenType.IDENTITY_ACCESS_TOKEN } as TIdentityAccessTokenJwtPayload, @@ -131,10 +126,10 @@ export const identityAwsIamAuthServiceFactory = ({ } ); - return { accessToken, identityAwsIamAuth, identityAccessToken, identityMembershipOrg }; + return { accessToken, identityAwsAuth, identityAccessToken, identityMembershipOrg }; }; - const attachAwsIamAuth = async ({ + const attachAwsAuth = async ({ identityId, stsEndpoint, allowedPrincipalArns, @@ -147,12 +142,12 @@ export const identityAwsIamAuthServiceFactory = ({ actorAuthMethod, actor, actorOrgId - }: TAttachAWSIAMAuthDTO) => { + }: TAttachAwsAuthDTO) => { const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); if (identityMembershipOrg.identity.authMethod) throw new BadRequestError({ - message: "Failed to add AWS IAM Auth to already configured identity" + message: "Failed to add AWS Auth to already configured identity" }); if (accessTokenMaxTTL > 0 && accessTokenTTL > accessTokenMaxTTL) { @@ -186,10 +181,11 @@ export const identityAwsIamAuthServiceFactory = ({ return extractIPDetails(accessTokenTrustedIp.ipAddress); }); - const identityAwsIamAuth = await identityAwsIamAuthDAL.transaction(async (tx) => { - const doc = await identityAwsIamAuthDAL.create( + const identityAwsAuth = await identityAwsAuthDAL.transaction(async (tx) => { + const doc = await identityAwsAuthDAL.create( { identityId: identityMembershipOrg.identityId, + type: "iam", stsEndpoint, allowedPrincipalArns, allowedAccountIds, @@ -203,16 +199,16 @@ export const identityAwsIamAuthServiceFactory = ({ await identityDAL.updateById( identityMembershipOrg.identityId, { - authMethod: IdentityAuthMethod.AWS_IAM_AUTH + authMethod: IdentityAuthMethod.AWS_AUTH }, tx ); return doc; }); - return { ...identityAwsIamAuth, orgId: identityMembershipOrg.orgId }; + return { ...identityAwsAuth, orgId: identityMembershipOrg.orgId }; }; - const updateAwsIamAuth = async ({ + const updateAwsAuth = async ({ identityId, stsEndpoint, allowedPrincipalArns, @@ -225,20 +221,19 @@ export const identityAwsIamAuthServiceFactory = ({ actorAuthMethod, actor, actorOrgId - }: TUpdateAWSIAMAuthDTO) => { + }: TUpdateAwsAuthDTO) => { const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); - if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_IAM_AUTH) + if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_AUTH) throw new BadRequestError({ - message: "Failed to update AWS IAM Auth" + message: "Failed to update AWS Auth" }); - const identityAwsIamAuth = await identityAwsIamAuthDAL.findOne({ identityId }); + const identityAwsAuth = await identityAwsAuthDAL.findOne({ identityId }); if ( - (accessTokenMaxTTL || identityAwsIamAuth.accessTokenMaxTTL) > 0 && - (accessTokenTTL || identityAwsIamAuth.accessTokenMaxTTL) > - (accessTokenMaxTTL || identityAwsIamAuth.accessTokenMaxTTL) + (accessTokenMaxTTL || identityAwsAuth.accessTokenMaxTTL) > 0 && + (accessTokenTTL || identityAwsAuth.accessTokenMaxTTL) > (accessTokenMaxTTL || identityAwsAuth.accessTokenMaxTTL) ) { throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" }); } @@ -270,7 +265,7 @@ export const identityAwsIamAuthServiceFactory = ({ return extractIPDetails(accessTokenTrustedIp.ipAddress); }); - const updatedAwsIamAuth = await identityAwsIamAuthDAL.updateById(identityAwsIamAuth.id, { + const updatedAwsAuth = await identityAwsAuthDAL.updateById(identityAwsAuth.id, { stsEndpoint, allowedPrincipalArns, allowedAccountIds, @@ -282,18 +277,18 @@ export const identityAwsIamAuthServiceFactory = ({ : undefined }); - return { ...updatedAwsIamAuth, orgId: identityMembershipOrg.orgId }; + return { ...updatedAwsAuth, orgId: identityMembershipOrg.orgId }; }; - const getAwsIamAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAWSIAMAuthDTO) => { + const getAwsAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAwsAuthDTO) => { const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); - if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_IAM_AUTH) + if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_AUTH) throw new BadRequestError({ - message: "The identity does not have AWS IAM Auth attached" + message: "The identity does not have AWS Auth attached" }); - const awsIamIdentityAuth = await identityAwsIamAuthDAL.findOne({ identityId }); + const awsIdentityAuth = await identityAwsAuthDAL.findOne({ identityId }); const { permission } = await permissionService.getOrgPermission( actor, @@ -303,13 +298,13 @@ export const identityAwsIamAuthServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); - return { ...awsIamIdentityAuth, orgId: identityMembershipOrg.orgId }; + return { ...awsIdentityAuth, orgId: identityMembershipOrg.orgId }; }; return { login, - attachAwsIamAuth, - updateAwsIamAuth, - getAwsIamAuth + attachAwsAuth, + updateAwsAuth, + getAwsAuth }; }; diff --git a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-types.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-types.ts similarity index 86% rename from backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-types.ts rename to backend/src/services/identity-aws-auth/identity-aws-auth-types.ts index 19f27f430..e45783ae1 100644 --- a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-types.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-types.ts @@ -1,13 +1,13 @@ import { TProjectPermission } from "@app/lib/types"; -export type TLoginAWSIAMAuthDTO = { +export type TLoginAwsAuthDTO = { identityId: string; iamHttpRequestMethod: string; iamRequestBody: string; iamRequestHeaders: string; }; -export type TAttachAWSIAMAuthDTO = { +export type TAttachAwsAuthDTO = { identityId: string; stsEndpoint: string; allowedPrincipalArns: string; @@ -18,7 +18,7 @@ export type TAttachAWSIAMAuthDTO = { accessTokenTrustedIps: { ipAddress: string }[]; } & Omit; -export type TUpdateAWSIAMAuthDTO = { +export type TUpdateAwsAuthDTO = { identityId: string; stsEndpoint?: string; allowedPrincipalArns?: string; @@ -29,11 +29,11 @@ export type TUpdateAWSIAMAuthDTO = { accessTokenTrustedIps?: { ipAddress: string }[]; } & Omit; -export type TGetAWSIAMAuthDTO = { +export type TGetAwsAuthDTO = { identityId: string; } & Omit; -export type TAWSGetCallerIdentityHeaders = { +export type TAwsGetCallerIdentityHeaders = { "Content-Type": string; Host: string; "X-Amz-Date": string; diff --git a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-validators.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts similarity index 100% rename from backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-validators.ts rename to backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts diff --git a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-dal.ts b/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-dal.ts deleted file mode 100644 index 584ac775f..000000000 --- a/backend/src/services/identity-aws-iam-auth/identity-aws-iam-auth-dal.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { TDbClient } from "@app/db"; -import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; - -export type TIdentityAwsIamAuthDALFactory = ReturnType; - -export const identityAwsIamAuthDALFactory = (db: TDbClient) => { - const awsIamAuthOrm = ormify(db, TableName.IdentityAwsIamAuth); - - return awsIamAuthOrm; -}; diff --git a/backend/src/services/identity-ua/identity-ua-service.ts b/backend/src/services/identity-ua/identity-ua-service.ts index 54a074073..5e940871b 100644 --- a/backend/src/services/identity-ua/identity-ua-service.ts +++ b/backend/src/services/identity-ua/identity-ua-service.ts @@ -52,7 +52,7 @@ export const identityUaServiceFactory = ({ }: TIdentityUaServiceFactoryDep) => { const login = async (clientId: string, clientSecret: string, ip: string) => { const identityUa = await identityUaDAL.findOne({ clientId }); - if (!identityUa) throw new UnauthorizedError(); + if (!identityUa) throw new UnauthorizedError({ message: "Invalid credentials" }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityUa.identityId }); @@ -68,7 +68,7 @@ export const identityUaServiceFactory = ({ const validClientSecretInfo = clientSecrtInfo.find(({ clientSecretHash }) => bcrypt.compareSync(clientSecret, clientSecretHash) ); - if (!validClientSecretInfo) throw new UnauthorizedError(); + if (!validClientSecretInfo) throw new UnauthorizedError({ message: "Invalid credentials" }); const { clientSecretTTL, clientSecretNumUses, clientSecretNumUsesLimit } = validClientSecretInfo; if (Number(clientSecretTTL) > 0) { diff --git a/backend/src/services/integration-auth/integration-sync-secret.ts b/backend/src/services/integration-auth/integration-sync-secret.ts index 168159847..4e1dbd7ae 100644 --- a/backend/src/services/integration-auth/integration-sync-secret.ts +++ b/backend/src/services/integration-auth/integration-sync-secret.ts @@ -517,20 +517,22 @@ const syncSecretsAWSParameterStore = async ({ }) ); - // Identify secrets to delete - await Promise.all( - Object.keys(awsParameterStoreSecretsObj).map(async (key) => { - if (!(key in secrets)) { - // case: - // -> delete secret - await ssm - .deleteParameter({ - Name: awsParameterStoreSecretsObj[key].Name as string - }) - .promise(); - } - }) - ); + if (!metadata.shouldDisableDelete) { + // Identify secrets to delete + await Promise.all( + Object.keys(awsParameterStoreSecretsObj).map(async (key) => { + if (!(key in secrets)) { + // case: + // -> delete secret + await ssm + .deleteParameter({ + Name: awsParameterStoreSecretsObj[key].Name as string + }) + .promise(); + } + }) + ); + } }; /** diff --git a/backend/src/services/integration/integration-types.ts b/backend/src/services/integration/integration-types.ts index 56ea46350..1913dd31f 100644 --- a/backend/src/services/integration/integration-types.ts +++ b/backend/src/services/integration/integration-types.ts @@ -27,6 +27,7 @@ export type TCreateIntegrationDTO = { value: string; }[]; kmsKeyId?: string; + shouldDisableDelete?: boolean; }; } & Omit; diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index d7ee1ce93..60ddc5230 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -546,6 +546,10 @@ export const orgServiceFactory = ({ code }); + await userDAL.updateById(user.id, { + isEmailVerified: true + }); + if (user.isAccepted) { // this means user has already completed signup process // isAccepted is set true when keys are exchanged diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index 3f647d8a9..feb8c01d5 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -972,7 +972,8 @@ export const secretServiceFactory = ({ path, actor, environment, - projectId, + projectId: workspaceId, + projectSlug, actorId, actorOrgId, actorAuthMethod, @@ -980,6 +981,8 @@ export const secretServiceFactory = ({ includeImports, version }: TGetASecretRawDTO) => { + const projectId = workspaceId || (await projectDAL.findProjectBySlug(projectSlug as string, actorOrgId)).id; + const botKey = await projectBotService.getBotKey(projectId); if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); diff --git a/backend/src/services/secret/secret-types.ts b/backend/src/services/secret/secret-types.ts index df0af5b5d..9f2addc89 100644 --- a/backend/src/services/secret/secret-types.ts +++ b/backend/src/services/secret/secret-types.ts @@ -152,7 +152,9 @@ export type TGetASecretRawDTO = { type: "shared" | "personal"; includeImports?: boolean; version?: number; -} & TProjectPermission; + projectSlug?: string; + projectId?: string; +} & Omit; export type TCreateSecretRawDTO = TProjectPermission & { secretPath: string; diff --git a/docs/documentation/getting-started/introduction.mdx b/docs/documentation/getting-started/introduction.mdx index 144691ac4..06455092d 100644 --- a/docs/documentation/getting-started/introduction.mdx +++ b/docs/documentation/getting-started/introduction.mdx @@ -51,7 +51,7 @@ As a result, the 3 main concepts that are important to understand are: - **[Identities](/documentation/platform/identities/overview)**: users or machines with a set permissions assigned to them. - **[Clients](/integrations/platforms/kubernetes)**: Infisical-developed tools for managing secrets in various infrastructure components (e.g., [Kubernetes Operator](/integrations/platforms/kubernetes), [Infisical Agent](/integrations/platforms/infisical-agent), [CLI](/cli/usage), [SDKs](/sdks/overview), [API](/api-reference/overview/introduction), [Web Dashboard](/documentation/platform/organization)). -- **[Authentication Methods](/documentation/platform/identities/universal-auth)**: ways for Identities to authenticate inside different clients (e.g., SAML SSO for Web Dashboard, Universal Auth for Infisical Agent, AWS IAM Auth etc.). +- **[Authentication Methods](/documentation/platform/identities/universal-auth)**: ways for Identities to authenticate inside different clients (e.g., SAML SSO for Web Dashboard, Universal Auth for Infisical Agent, AWS Auth etc.). ## How to get started with Infisical? diff --git a/docs/documentation/platform/identities/aws-iam-auth.mdx b/docs/documentation/platform/identities/aws-auth.mdx similarity index 88% rename from docs/documentation/platform/identities/aws-iam-auth.mdx rename to docs/documentation/platform/identities/aws-auth.mdx index 510aa0d01..cf76ffce7 100644 --- a/docs/documentation/platform/identities/aws-iam-auth.mdx +++ b/docs/documentation/platform/identities/aws-auth.mdx @@ -1,34 +1,60 @@ --- -title: AWS IAM Auth +title: AWS Auth description: "Learn how to authenticate with Infisical for EC2 instances, Lambda functions, and other IAM principals." --- -**AWS IAM Auth** is an AWS-native authentication method for IAM principals like EC2 instances or Lambda functions to access Infisical. +**AWS Auth** is an AWS-native authentication method for IAM principals like EC2 instances or Lambda functions to access Infisical. + +## Diagram + +The following sequence digram illustrates the AWS Auth workflow for authenticating AWS IAM principals with Infisical. + +```mermaid +sequenceDiagram + participant Client as Client + participant Infis as Infisical + participant AWS as AWS STS + + Note over Client,Client: Step 1: Sign GetCallerIdentityQuery + + Note over Client,Infis: Step 2: Login Operation + Client->>Infis: Send signed query details /api/v1/auth/aws-auth/login + + Note over Infis,AWS: Step 3: Query verification + Infis->>AWS: Forward signed GetCallerIdentity query + AWS-->>Infis: Return IAM user/role details + + Note over Infis: Step 4: Identity Property Validation + Infis->>Client: Return short-lived access token + + Note over Client,Infis: Step 4: Access Infisical API with Token + Client->>Infis: Make authenticated requests using the short-lived access token +``` ## Concept -At a high-level, Infisical authenticates an IAM principal by verifying its identity and checking that it meets specific requirements (e.g. it is an allowed IAM principal ARN) at the `/api/v1/auth/aws-iam-auth/login` endpoint. If successful, +At a high-level, Infisical authenticates an IAM principal by verifying its identity and checking that it meets specific requirements (e.g. it is an allowed IAM principal ARN) at the `/api/v1/auth/aws-auth/login` endpoint. If successful, then Infisical returns a short-lived access token that can be used to make authenticated requests to the Infisical API. -In AWS IAM Auth, an IAM principal signs a `GetCallerIdentity` query using the [AWS Signature v4 algorithm](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html); this is done using the credentials from the AWS environment where the IAM principal is running. +In AWS Auth, an IAM principal signs a `GetCallerIdentity` query using the [AWS Signature v4 algorithm](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html); this is done using the credentials from the AWS environment where the IAM principal is running. The query data including the request method, request body, and request headers are sent to Infisical afterwhich Infisical forwards the signed query to AWS STS API via the [sts:GetCallerIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html) method to verify and obtain the identity of the IAM principal. Once obtained, the identity information is verified against specified requirements such as if the associated IAM principal ARN is allowed to authenticate with Infisical. If all is well, Infisical returns a short-lived access token that can be used to make authenticated requests to the Infisical API. We recommend using one of Infisical's clients like SDKs or the Infisical Agent -to authenticate with Infisical using AWS IAM Auth as they handle the +to authenticate with Infisical using AWS Auth as they handle the authentication process including the signed `GetCallerIdentity` query construction for you. Also, note that Infisical needs network-level access to send requests to the AWS STS API -as part of the AWS IAM Auth workflow. +as part of the AWS Auth workflow. ## Workflow In the following steps, we explore how to create and use identities for your workloads and applications on AWS to -access the Infisical API using the AWS IAM authentication method. +access the Infisical API using the AWS Auth authentication method. @@ -45,9 +71,9 @@ access the Infisical API using the AWS IAM authentication method. - Name (required): A friendly name for the identity. - Role (required): A role from the **Organization Roles** tab for the identity to assume. The organization role assigned will determine what organization level resources this identity can have access to. - Once you've created an identity, you'll be prompted to configure the authentication method for it. Here, select **AWS IAM Auth**. + Once you've created an identity, you'll be prompted to configure the authentication method for it. Here, select **AWS Auth**. - ![identities create iam auth method](/images/platform/identities/identities-org-create-aws-iam-auth-method.png) + ![identities create aws auth method](/images/platform/identities/identities-org-create-aws-auth-method.png) Here's some more guidance on each field: @@ -71,7 +97,7 @@ access the Infisical API using the AWS IAM authentication method. ![identities project create](/images/platform/identities/identities-project-create.png) - To access the Infisical API as the identity, you need to construct a signed `GetCallerIdentity` query using the [AWS Signature v4 algorithm](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html) and make a request to the `/api/v1/auth/aws-iam-auth/login` endpoint containing the query data + To access the Infisical API as the identity, you need to construct a signed `GetCallerIdentity` query using the [AWS Signature v4 algorithm](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html) and make a request to the `/api/v1/auth/aws-auth/login` endpoint containing the query data in exchange for an access token. We provide a few code examples below of how you can authenticate with Infisical from inside a Lambda function, EC2 instance, etc. and obtain an access token to access the [Infisical API](/api-reference/overview/introduction). @@ -119,7 +145,7 @@ access the Infisical API using the AWS IAM authentication method. const identityId = ""; const { data } = await axios.post( - `${infisicalUrl}/api/v1/auth/aws-iam-auth/login`, + `${infisicalUrl}/api/v1/auth/aws-auth/login`, { identityId, iamHttpRequestMethod: "POST", @@ -191,7 +217,7 @@ access the Infisical API using the AWS IAM authentication method. const infisicalUrl = "https://app.infisical.com"; // or your self-hosted Infisical URL const identityId = ""; - const { data } = await axios.post(`${infisicalUrl}/api/v1/auth/aws-iam-auth/login`, { + const { data } = await axios.post(`${infisicalUrl}/api/v1/auth/aws-auth/login`, { identityId, iamHttpRequestMethod: "POST", iamRequestUrl: Buffer.from(iamRequestURL).toString("base64"), @@ -239,7 +265,7 @@ access the Infisical API using the AWS IAM authentication method. #### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/auth/aws-iam-auth/login' \ + curl --location --request POST 'https://app.infisical.com/api/v1/auth/aws-auth/login' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'identityId=...' \ --data-urlencode 'iamHttpRequestMethod=...' \ @@ -263,7 +289,7 @@ access the Infisical API using the AWS IAM authentication method. - We recommend using one of Infisical's clients like SDKs or the Infisical Agent to authenticate with Infisical using AWS IAM Auth as they handle the authentication process including the signed `GetCallerIdentity` query construction for you. + We recommend using one of Infisical's clients like SDKs or the Infisical Agent to authenticate with Infisical using AWS Auth as they handle the authentication process including the signed `GetCallerIdentity` query construction for you. diff --git a/docs/documentation/platform/identities/machine-identities.mdx b/docs/documentation/platform/identities/machine-identities.mdx index cd8ab2cbe..35ede887e 100644 --- a/docs/documentation/platform/identities/machine-identities.mdx +++ b/docs/documentation/platform/identities/machine-identities.mdx @@ -7,7 +7,7 @@ description: "Learn how to use Machine Identities to programmatically interact w An Infisical machine identity is an entity that represents a workload or application that require access to various resources in Infisical. This is conceptually similar to an IAM user in AWS or service account in Google Cloud Platform (GCP). -Each identity must authenticate with the Infisical API using a supported authentication method like [Universal Auth](/documentation/platform/identities/universal-auth), [AWS IAM Auth](/documentation/platform/identities/aws-iam-auth), or [GCP IAM Auth](/documentation/platform/identities/gcp-auth) to get back a short-lived access token to be used in subsequent requests. +Each identity must authenticate with the Infisical API using a supported authentication method like [Universal Auth](/documentation/platform/identities/universal-auth), [AWS Auth](/documentation/platform/identities/aws-auth), or [GCP Auth](/documentation/platform/identities/gcp-auth) to get back a short-lived access token to be used in subsequent requests. ![organization identities](/images/platform/organization/organization-machine-identities.png) @@ -38,8 +38,8 @@ Machine Identity support for the rest of the clients is planned to be released i To interact with various resources in Infisical, Machine Identities are able to authenticate using: - [Universal Auth](/documentation/platform/identities/universal-auth): A platform-agnostic authentication method that can be configured on an identity suitable to authenticate from any platform/environment. -- [AWS IAM Auth](/documentation/platform/identities/aws-iam-auth): An AWS-native authentication method for IAM principals like EC2 instances or Lambda functions to authenticate with Infisical. -- [GCP IAM Auth](/documentation/platform/identities/gcp-auth): A GCP-native authentication method for IAM service accounts to authenticate with Infisical. +- [AWS Auth](/documentation/platform/identities/aws-auth): An AWS-native authentication method for IAM principals like EC2 instances or Lambda functions to authenticate with Infisical. +- [GCP Auth](/documentation/platform/identities/gcp-auth): A GCP-native authentication method for IAM service accounts and GCE instances to authenticate with Infisical. ## FAQ diff --git a/docs/documentation/platform/identities/universal-auth.mdx b/docs/documentation/platform/identities/universal-auth.mdx index cd40a9e64..bad96c0e3 100644 --- a/docs/documentation/platform/identities/universal-auth.mdx +++ b/docs/documentation/platform/identities/universal-auth.mdx @@ -5,6 +5,25 @@ description: "Learn how to authenticate to Infisical from any platform or enviro **Universal Auth** is a platform-agnostic authentication method that can be configured for a [machine identity](/documentation/platform/identities/machine-identities) suitable to authenticate from any platform/environment. +## Diagram + +The following sequence digram illustrates the Universal Auth workflow for authenticating clients with Infisical. + +```mermaid +sequenceDiagram + participant Client as Client + participant Infis as Infisical + + Note over Client,Infis: Step 1: Login Operation + Client->>Infis: Send Client ID and Client Secret + + Note over Infis: Step 2: Client ID and Client Secret validation + Infis->>Client: Return short-lived access token + + Note over Client,Infis: Step 3: Access Infisical API with Token + Client->>Infis: Make authenticated requests using the short-lived access token +``` + ## Concept In this method, Infisical authenticates an identity by verifying the credentials issued for it at the `/api/v1/auth/universal-auth/login` endpoint. If successful, @@ -12,7 +31,7 @@ then Infisical returns a short-lived access token that can be used to make authe In Universal Auth, an identity is given a **Client ID** and one or more **Client Secret(s)**. Together, a **Client ID** and **Client Secret** can be exchanged for a short-lived access token to authenticate with the Infisical API. -## Workflow +## Guide In the following steps, we explore how to create and use identities for your workloads and applications to access the Infisical API using the Universal Auth authentication method. diff --git a/docs/images/platform/identities/identities-org-create-aws-iam-auth-method.png b/docs/images/platform/identities/identities-org-create-aws-auth-method.png similarity index 100% rename from docs/images/platform/identities/identities-org-create-aws-iam-auth-method.png rename to docs/images/platform/identities/identities-org-create-aws-auth-method.png diff --git a/docs/integrations/platforms/kubernetes.mdx b/docs/integrations/platforms/kubernetes.mdx index d1cff4e75..3d1b72331 100644 --- a/docs/integrations/platforms/kubernetes.mdx +++ b/docs/integrations/platforms/kubernetes.mdx @@ -77,6 +77,8 @@ spec: projectSlug: envSlug: # "dev", "staging", "prod", etc.. secretsPath: "" # Root is "/" + recursive: true # Fetch all secrets from the specified path and all sub-directories. Default is false. + credentialsRef: secretName: universal-auth-credentials secretNamespace: default @@ -89,6 +91,7 @@ spec: secretsScope: envSlug: secretsPath: # Root is "/" + recursive: true # Fetch all secrets from the specified path and all sub-directories. Default is false. managedSecretReference: secretName: managed-secret diff --git a/docs/mint.json b/docs/mint.json index 916a9ca2f..4a106a79c 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -153,8 +153,8 @@ "documentation/platform/auth-methods/email-password", "documentation/platform/token", "documentation/platform/identities/universal-auth", - "documentation/platform/identities/aws-iam-auth", "documentation/platform/identities/gcp-auth", + "documentation/platform/identities/aws-auth", "documentation/platform/mfa", { "group": "SSO", diff --git a/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx b/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx index ed97ad8dd..9dfb5ff62 100644 --- a/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx +++ b/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx @@ -31,6 +31,7 @@ export const SecretPathInput = ({ const [inputValue, setInputValue] = useState(propValue ?? ""); const [secretPath, setSecretPath] = useState("/"); const [suggestions, setSuggestions] = useState([]); + const [isInputFocused, setIsInputFocus] = useState(false); const [highlightedIndex, setHighlightedIndex] = useState(-1); const debouncedInputValue = useDebounce(inputValue, 200); @@ -55,7 +56,9 @@ export const SecretPathInput = ({ ) { setSecretPath(debouncedInputValue); } + }, [debouncedInputValue]); + useEffect(() => { // filter suggestions based on matching const searchFragment = debouncedInputValue.split("/").pop() || ""; const filteredSuggestions = folders @@ -65,7 +68,7 @@ export const SecretPathInput = ({ .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); setSuggestions(filteredSuggestions); - }, [debouncedInputValue]); + }, [debouncedInputValue, folders]); const handleSuggestionSelect = (selectedIndex: number) => { if (!suggestions[selectedIndex]) { @@ -75,7 +78,7 @@ export const SecretPathInput = ({ const validPaths = inputValue.split("/"); validPaths.pop(); - const newValue = `${validPaths.join("/")}/${suggestions[selectedIndex]}`; + const newValue = `${validPaths.join("/")}/${suggestions[selectedIndex]}/`; onChange?.(newValue); setInputValue(newValue); setSecretPath(newValue); @@ -108,7 +111,7 @@ export const SecretPathInput = ({ return ( 0 && inputValue.length > 1} + open={suggestions.length > 0 && isInputFocused} onOpenChange={() => { setHighlightedIndex(-1); }} @@ -119,6 +122,8 @@ export const SecretPathInput = ({ type="text" autoComplete="off" onKeyDown={handleKeyDown} + onFocus={() => setIsInputFocus(true)} + onBlur={() => setIsInputFocus(false)} value={inputValue} onChange={handleInputChange} className={containerClassName} @@ -150,8 +155,9 @@ export const SecretPathInput = ({ key={`secret-reference-secret-${i + 1}`} >
diff --git a/frontend/src/hooks/api/identities/constants.tsx b/frontend/src/hooks/api/identities/constants.tsx index 798a13b88..d2669a308 100644 --- a/frontend/src/hooks/api/identities/constants.tsx +++ b/frontend/src/hooks/api/identities/constants.tsx @@ -3,5 +3,5 @@ import { IdentityAuthMethod } from "./enums"; export const identityAuthToNameMap: { [I in IdentityAuthMethod]: string } = { [IdentityAuthMethod.UNIVERSAL_AUTH]: "Universal Auth", [IdentityAuthMethod.GCP_AUTH]: "GCP Auth", - [IdentityAuthMethod.AWS_IAM_AUTH]: "AWS IAM Auth" + [IdentityAuthMethod.AWS_AUTH]: "AWS Auth" }; diff --git a/frontend/src/hooks/api/identities/enums.tsx b/frontend/src/hooks/api/identities/enums.tsx index be50c72ad..a67776c87 100644 --- a/frontend/src/hooks/api/identities/enums.tsx +++ b/frontend/src/hooks/api/identities/enums.tsx @@ -1,5 +1,5 @@ export enum IdentityAuthMethod { UNIVERSAL_AUTH = "universal-auth", GCP_AUTH = "gcp-auth", - AWS_IAM_AUTH = "aws-iam-auth" + AWS_AUTH = "aws-auth" } diff --git a/frontend/src/hooks/api/identities/index.tsx b/frontend/src/hooks/api/identities/index.tsx index bd7347f88..d59e096c0 100644 --- a/frontend/src/hooks/api/identities/index.tsx +++ b/frontend/src/hooks/api/identities/index.tsx @@ -1,7 +1,7 @@ export { identityAuthToNameMap } from "./constants"; export { IdentityAuthMethod } from "./enums"; export { - useAddIdentityAwsIamAuth, + useAddIdentityAwsAuth, useAddIdentityGcpAuth, useAddIdentityUniversalAuth, useCreateIdentity, @@ -9,12 +9,11 @@ export { useDeleteIdentity, useRevokeIdentityUniversalAuthClientSecret, useUpdateIdentity, - useUpdateIdentityAwsIamAuth, + useUpdateIdentityAwsAuth, useUpdateIdentityGcpAuth, - useUpdateIdentityUniversalAuth -} from "./mutations"; + useUpdateIdentityUniversalAuth} from "./mutations"; export { - useGetIdentityAwsIamAuth, + useGetIdentityAwsAuth, useGetIdentityGcpAuth, useGetIdentityUniversalAuth, useGetIdentityUniversalAuthClientSecrets diff --git a/frontend/src/hooks/api/identities/mutations.tsx b/frontend/src/hooks/api/identities/mutations.tsx index e2cdc8841..527f74f16 100644 --- a/frontend/src/hooks/api/identities/mutations.tsx +++ b/frontend/src/hooks/api/identities/mutations.tsx @@ -5,7 +5,7 @@ import { apiRequest } from "@app/config/request"; import { organizationKeys } from "../organization/queries"; import { identitiesKeys } from "./queries"; import { - AddIdentityAwsIamAuthDTO, + AddIdentityAwsAuthDTO, AddIdentityGcpAuthDTO, AddIdentityUniversalAuthDTO, ClientSecretData, @@ -15,10 +15,10 @@ import { DeleteIdentityDTO, DeleteIdentityUniversalAuthClientSecretDTO, Identity, - IdentityAwsIamAuth, + IdentityAwsAuth, IdentityGcpAuth, IdentityUniversalAuth, - UpdateIdentityAwsIamAuthDTO, + UpdateIdentityAwsAuthDTO, UpdateIdentityDTO, UpdateIdentityGcpAuthDTO, UpdateIdentityUniversalAuthDTO @@ -256,9 +256,9 @@ export const useUpdateIdentityGcpAuth = () => { }); }; -export const useAddIdentityAwsIamAuth = () => { +export const useAddIdentityAwsAuth = () => { const queryClient = useQueryClient(); - return useMutation({ + return useMutation({ mutationFn: async ({ identityId, stsEndpoint, @@ -270,9 +270,9 @@ export const useAddIdentityAwsIamAuth = () => { accessTokenTrustedIps }) => { const { - data: { identityAwsIamAuth } - } = await apiRequest.post<{ identityAwsIamAuth: IdentityAwsIamAuth }>( - `/api/v1/auth/aws-iam-auth/identities/${identityId}`, + data: { identityAwsAuth } + } = await apiRequest.post<{ identityAwsAuth: IdentityAwsAuth }>( + `/api/v1/auth/aws-auth/identities/${identityId}`, { stsEndpoint, allowedPrincipalArns, @@ -284,7 +284,7 @@ export const useAddIdentityAwsIamAuth = () => { } ); - return identityAwsIamAuth; + return identityAwsAuth; }, onSuccess: (_, { organizationId }) => { queryClient.invalidateQueries(organizationKeys.getOrgIdentityMemberships(organizationId)); @@ -292,9 +292,9 @@ export const useAddIdentityAwsIamAuth = () => { }); }; -export const useUpdateIdentityAwsIamAuth = () => { +export const useUpdateIdentityAwsAuth = () => { const queryClient = useQueryClient(); - return useMutation({ + return useMutation({ mutationFn: async ({ identityId, stsEndpoint, @@ -306,9 +306,9 @@ export const useUpdateIdentityAwsIamAuth = () => { accessTokenTrustedIps }) => { const { - data: { identityAwsIamAuth } - } = await apiRequest.patch<{ identityAwsIamAuth: IdentityAwsIamAuth }>( - `/api/v1/auth/aws-iam-auth/identities/${identityId}`, + data: { identityAwsAuth } + } = await apiRequest.patch<{ identityAwsAuth: IdentityAwsAuth }>( + `/api/v1/auth/aws-auth/identities/${identityId}`, { stsEndpoint, allowedPrincipalArns, @@ -320,7 +320,7 @@ export const useUpdateIdentityAwsIamAuth = () => { } ); - return identityAwsIamAuth; + return identityAwsAuth; }, onSuccess: (_, { organizationId }) => { queryClient.invalidateQueries(organizationKeys.getOrgIdentityMemberships(organizationId)); diff --git a/frontend/src/hooks/api/identities/queries.tsx b/frontend/src/hooks/api/identities/queries.tsx index 62f139f5f..2996f275f 100644 --- a/frontend/src/hooks/api/identities/queries.tsx +++ b/frontend/src/hooks/api/identities/queries.tsx @@ -2,12 +2,7 @@ import { useQuery } from "@tanstack/react-query"; import { apiRequest } from "@app/config/request"; -import { - ClientSecretData, - IdentityAwsIamAuth, - IdentityGcpAuth, - IdentityUniversalAuth -} from "./types"; +import { ClientSecretData, IdentityAwsAuth, IdentityGcpAuth, IdentityUniversalAuth } from "./types"; export const identitiesKeys = { getIdentityUniversalAuth: (identityId: string) => @@ -15,7 +10,7 @@ export const identitiesKeys = { getIdentityUniversalAuthClientSecrets: (identityId: string) => [{ identityId }, "identity-universal-auth-client-secrets"] as const, getIdentityGcpAuth: (identityId: string) => [{ identityId }, "identity-gcp-auth"] as const, - getIdentityAwsIamAuth: (identityId: string) => [{ identityId }, "identity-aws-iam-auth"] as const + getIdentityAwsAuth: (identityId: string) => [{ identityId }, "identity-aws-auth"] as const }; export const useGetIdentityUniversalAuth = (identityId: string) => { @@ -63,17 +58,17 @@ export const useGetIdentityGcpAuth = (identityId: string) => { }); }; -export const useGetIdentityAwsIamAuth = (identityId: string) => { +export const useGetIdentityAwsAuth = (identityId: string) => { return useQuery({ enabled: Boolean(identityId), - queryKey: identitiesKeys.getIdentityAwsIamAuth(identityId), + queryKey: identitiesKeys.getIdentityAwsAuth(identityId), queryFn: async () => { const { - data: { identityAwsIamAuth } - } = await apiRequest.get<{ identityAwsIamAuth: IdentityAwsIamAuth }>( - `/api/v1/auth/aws-iam-auth/identities/${identityId}` + data: { identityAwsAuth } + } = await apiRequest.get<{ identityAwsAuth: IdentityAwsAuth }>( + `/api/v1/auth/aws-auth/identities/${identityId}` ); - return identityAwsIamAuth; + return identityAwsAuth; } }); }; diff --git a/frontend/src/hooks/api/identities/types.ts b/frontend/src/hooks/api/identities/types.ts index 6cdb05a8c..a63096562 100644 --- a/frontend/src/hooks/api/identities/types.ts +++ b/frontend/src/hooks/api/identities/types.ts @@ -158,8 +158,9 @@ export type UpdateIdentityGcpAuthDTO = { }[]; }; -export type IdentityAwsIamAuth = { +export type IdentityAwsAuth = { identityId: string; + type: "iam"; stsEndpoint: string; allowedPrincipalArns: string; allowedAccountIds: string; @@ -169,7 +170,7 @@ export type IdentityAwsIamAuth = { accessTokenTrustedIps: IdentityTrustedIp[]; }; -export type AddIdentityAwsIamAuthDTO = { +export type AddIdentityAwsAuthDTO = { organizationId: string; identityId: string; stsEndpoint: string; @@ -183,7 +184,7 @@ export type AddIdentityAwsIamAuthDTO = { }[]; }; -export type UpdateIdentityAwsIamAuthDTO = { +export type UpdateIdentityAwsAuthDTO = { organizationId: string; identityId: string; stsEndpoint?: string; diff --git a/frontend/src/hooks/api/integrations/queries.tsx b/frontend/src/hooks/api/integrations/queries.tsx index b855dbf73..2d4c8a313 100644 --- a/frontend/src/hooks/api/integrations/queries.tsx +++ b/frontend/src/hooks/api/integrations/queries.tsx @@ -68,6 +68,7 @@ export const useCreateIntegration = () => { value: string; }[]; kmsKeyId?: string; + shouldDisableDelete?: boolean; }; }) => { const { diff --git a/frontend/src/hooks/api/secretFolders/queries.tsx b/frontend/src/hooks/api/secretFolders/queries.tsx index 71c63f3eb..d2882c551 100644 --- a/frontend/src/hooks/api/secretFolders/queries.tsx +++ b/frontend/src/hooks/api/secretFolders/queries.tsx @@ -79,7 +79,7 @@ export const useGetFoldersByEnv = ({ }); }); return [...names]; - }, [(folders || []).map((folder) => folder.data)]); + }, [...(folders || []).map((folder) => folder.data)]); const isFolderPresentInEnv = useCallback( (name: string, env: string) => { @@ -91,7 +91,7 @@ export const useGetFoldersByEnv = ({ } return false; }, - [(folders || []).map((folder) => folder.data)] + [...(folders || []).map((folder) => folder.data)] ); const getFolderByNameAndEnv = useCallback( diff --git a/frontend/src/pages/integrations/aws-parameter-store/create.tsx b/frontend/src/pages/integrations/aws-parameter-store/create.tsx index cc80d2f29..ee9bf30b9 100644 --- a/frontend/src/pages/integrations/aws-parameter-store/create.tsx +++ b/frontend/src/pages/integrations/aws-parameter-store/create.tsx @@ -89,6 +89,7 @@ export default function AWSParameterStoreCreateIntegrationPage() { const [isLoading, setIsLoading] = useState(false); const [shouldTag, setShouldTag] = useState(false); + const [shouldDisableDelete, setShouldDisableDelete] = useState(false); const [tagKey, setTagKey] = useState(""); const [tagValue, setTagValue] = useState(""); const [kmsKeyId, setKmsKeyId] = useState(""); @@ -144,7 +145,8 @@ export default function AWSParameterStoreCreateIntegrationPage() { ] } : {}), - ...(kmsKeyId && { kmsKeyId }) + ...(kmsKeyId && { kmsKeyId }), + ...(shouldDisableDelete && { shouldDisableDelete }) } }); @@ -273,6 +275,15 @@ export default function AWSParameterStoreCreateIntegrationPage() { exit={{ opacity: 0, translateX: 30 }} >
+ setShouldDisableDelete(!shouldDisableDelete)} + isChecked={shouldDisableDelete} + > + Disable deleting secrets in AWS Parameter Store + +
+
setShouldTag(!shouldTag)} diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx index 994672ee1..74c4c7f6d 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx @@ -14,7 +14,7 @@ import { import { IdentityAuthMethod } from "@app/hooks/api/identities"; import { UsePopUpState } from "@app/hooks/usePopUp"; -import { IdentityAwsIamAuthForm } from "./IdentityAwsIamAuthForm"; +import { IdentityAwsAuthForm } from "./IdentityAwsAuthForm"; import { IdentityGcpAuthForm } from "./IdentityGcpAuthForm"; import { IdentityUniversalAuthForm } from "./IdentityUniversalAuthForm"; @@ -29,8 +29,8 @@ type Props = { const identityAuthMethods = [ { label: "Universal Auth", value: IdentityAuthMethod.UNIVERSAL_AUTH }, - { label: "AWS IAM Auth", value: IdentityAuthMethod.AWS_IAM_AUTH }, - { label: "GCP Auth", value: IdentityAuthMethod.GCP_AUTH } + { label: "GCP Auth", value: IdentityAuthMethod.GCP_AUTH }, + { label: "AWS Auth", value: IdentityAuthMethod.AWS_AUTH } ]; const schema = yup @@ -68,9 +68,9 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog const renderIdentityAuthForm = () => { switch (identityAuthMethodData?.authMethod ?? authMethod) { - case IdentityAuthMethod.AWS_IAM_AUTH: { + case IdentityAuthMethod.AWS_AUTH: { return ( - secretsPath: # Root is "/" + recursive: true # Wether or not to use recursive mode (Fetches all secrets in an environment from a given secret path, and all folders inside the path) / defaults to false universalAuth: secretsScope: projectSlug: envSlug: # "dev", "staging", "prod", etc.. secretsPath: "" # Root is "/" + recursive: true # Wether or not to use recursive mode (Fetches all secrets in an environment from a given secret path, and all folders inside the path) / defaults to false credentialsRef: secretName: universal-auth-credentials diff --git a/k8-operator/controllers/infisicalsecret_helper.go b/k8-operator/controllers/infisicalsecret_helper.go index 4ef378fe2..c14f724eb 100644 --- a/k8-operator/controllers/infisicalsecret_helper.go +++ b/k8-operator/controllers/infisicalsecret_helper.go @@ -269,7 +269,7 @@ func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context } else if infisicalMachineIdentityCreds.ClientId != "" && infisicalMachineIdentityCreds.ClientSecret != "" { authStrategy = AuthStrategy.UNIVERSAL_MACHINE_IDENTITY } else { - return fmt.Errorf("no authentication method provided. You must provide either a valid service token or a service account details to fetch secrets") + return fmt.Errorf("no authentication method provided. You must provide either a valid service token or a service account details to fetch secrets\n") } r.SetInfisicalTokenLoadCondition(ctx, &infisicalSecret, err) @@ -312,8 +312,9 @@ func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context } else if authStrategy == AuthStrategy.SERVICE_TOKEN { // Service Tokens (deprecated) envSlug := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.EnvSlug secretsPath := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.SecretsPath + recursive := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.Recursive - plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceToken(infisicalToken, secretVersionBasedOnETag, envSlug, secretsPath) + plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceToken(infisicalToken, secretVersionBasedOnETag, envSlug, secretsPath, recursive) if err != nil { return fmt.Errorf("\nfailed to get secrets because [err=%v]", err) } diff --git a/k8-operator/packages/api/api.go b/k8-operator/packages/api/api.go index 05a58e8cb..233925dda 100644 --- a/k8-operator/packages/api/api.go +++ b/k8-operator/packages/api/api.go @@ -66,6 +66,10 @@ func CallGetSecretsV3(httpClient *resty.Client, request GetEncryptedSecretsV3Req httpRequest.SetQueryParam("secretPath", request.SecretPath) } + if request.Recursive { + httpRequest.SetQueryParam("recursive", "true") + } + response, err := httpRequest.Get(fmt.Sprintf("%v/v3/secrets", API_HOST_URL)) if err != nil { @@ -148,19 +152,23 @@ func CallUniversalMachineIdentityRefreshAccessToken(request MachineIdentityUnive func CallGetDecryptedSecretsV3(httpClient *resty.Client, request GetDecryptedSecretsV3Request) (GetDecryptedSecretsV3Response, error) { var decryptedSecretsResponse GetDecryptedSecretsV3Response - response, err := httpClient. + req := httpClient. R(). SetResult(&decryptedSecretsResponse). SetHeader("User-Agent", USER_AGENT_NAME). SetQueryParam("secretPath", request.SecretPath). SetQueryParam("workspaceSlug", request.ProjectSlug). - SetQueryParam("environment", request.Environment). - Get(fmt.Sprintf("%v/v3/secrets/raw", API_HOST_URL)) + SetQueryParam("environment", request.Environment) + + if request.Recursive { + req.SetQueryParam("recursive", "true") + } + + response, err := req.Get(fmt.Sprintf("%v/v3/secrets/raw", API_HOST_URL)) if err != nil { return GetDecryptedSecretsV3Response{}, fmt.Errorf("CallGetDecryptedSecretsV3: Unable to complete api request [err=%s]", err) } - if response.IsError() { return GetDecryptedSecretsV3Response{}, fmt.Errorf("CallGetDecryptedSecretsV3: Unsuccessful response: [response=%s]", response) } diff --git a/k8-operator/packages/api/models.go b/k8-operator/packages/api/models.go index ff4ea3e10..ccb8d0d00 100644 --- a/k8-operator/packages/api/models.go +++ b/k8-operator/packages/api/models.go @@ -31,6 +31,7 @@ type GetEncryptedWorkspaceKeyResponse struct { type GetEncryptedSecretsV3Request struct { Environment string `json:"environment"` WorkspaceId string `json:"workspaceId"` + Recursive bool `json:"recursive"` SecretPath string `json:"secretPath"` IncludeImport bool `json:"include_imports"` ETag string `json:"etag,omitempty"` @@ -100,6 +101,7 @@ type GetDecryptedSecretsV3Request struct { ProjectSlug string `json:"workspaceSlug"` Environment string `json:"environment"` SecretPath string `json:"secretPath"` + Recursive bool `json:"recursive"` ETag string `json:"etag,omitempty"` } diff --git a/k8-operator/packages/util/secrets.go b/k8-operator/packages/util/secrets.go index a8c4a4cc5..290e1340c 100644 --- a/k8-operator/packages/util/secrets.go +++ b/k8-operator/packages/util/secrets.go @@ -60,6 +60,7 @@ func GetPlainTextSecretsViaUniversalAuth(accessToken string, etag string, secret secretsResponse, err := api.CallGetDecryptedSecretsV3(httpClient, api.GetDecryptedSecretsV3Request{ ProjectSlug: secretScope.ProjectSlug, Environment: secretScope.EnvSlug, + Recursive: secretScope.Recursive, SecretPath: secretScope.SecretsPath, ETag: etag, }) @@ -85,7 +86,7 @@ func GetPlainTextSecretsViaUniversalAuth(accessToken string, etag string, secret }, nil } -func GetPlainTextSecretsViaServiceToken(fullServiceToken string, etag string, envSlug string, secretPath string) ([]model.SingleEnvironmentVariable, model.RequestUpdateUpdateDetails, error) { +func GetPlainTextSecretsViaServiceToken(fullServiceToken string, etag string, envSlug string, secretPath string, recursive bool) ([]model.SingleEnvironmentVariable, model.RequestUpdateUpdateDetails, error) { serviceTokenParts := strings.SplitN(fullServiceToken, ".", 4) if len(serviceTokenParts) < 4 { return nil, model.RequestUpdateUpdateDetails{}, fmt.Errorf("invalid service token entered. Please double check your service token and try again") @@ -106,6 +107,7 @@ func GetPlainTextSecretsViaServiceToken(fullServiceToken string, etag string, en encryptedSecretsResponse, err := api.CallGetSecretsV3(httpClient, api.GetEncryptedSecretsV3Request{ WorkspaceId: serviceTokenDetails.Workspace, Environment: envSlug, + Recursive: recursive, ETag: etag, SecretPath: secretPath, }) @@ -376,7 +378,7 @@ func ExpandSecrets(secrets []model.SingleEnvironmentVariable, infisicalToken str if crossRefSec, ok := crossEnvRefSecs[uniqKey]; !ok { // if not in cross reference cache, fetch it from server - refSecs, _, err := GetPlainTextSecretsViaServiceToken(infisicalToken, "", env, secPath) + refSecs, _, err := GetPlainTextSecretsViaServiceToken(infisicalToken, "", env, secPath, false) if err != nil { fmt.Printf("Could not fetch secrets in environment: %s secret-path: %s", env, secPath) // HandleError(err, fmt.Sprintf("Could not fetch secrets in environment: %s secret-path: %s", env, secPath), "If you are using a service token to fetch secrets, please ensure it is valid") diff --git a/pg-migrator/.gitignore b/pg-migrator/.gitignore deleted file mode 100644 index 65eef93d6..000000000 --- a/pg-migrator/.gitignore +++ /dev/null @@ -1 +0,0 @@ -db diff --git a/pg-migrator/package-lock.json b/pg-migrator/package-lock.json deleted file mode 100644 index 5db0d9368..000000000 --- a/pg-migrator/package-lock.json +++ /dev/null @@ -1,1487 +0,0 @@ -{ - "name": "pg-migrator", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "pg-migrator", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@casl/ability": "^6.5.0", - "@sindresorhus/slugify": "^2.2.1", - "dotenv": "^16.3.1", - "knex": "^3.1.0", - "level": "^8.0.0", - "mongoose": "^8.0.4", - "nanoid": "^5.0.4", - "pg": "^8.11.3", - "prompt-sync": "^4.2.0", - "uuid": "^9.0.1", - "zod": "^3.22.4" - }, - "devDependencies": { - "@types/node": "^20.11.0", - "@types/prompt-sync": "^4.2.3", - "@types/uuid": "^9.0.7", - "tsx": "^4.7.0", - "typescript": "^5.3.3" - } - }, - "node_modules/@casl/ability": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.5.0.tgz", - "integrity": "sha512-3guc94ugr5ylZQIpJTLz0CDfwNi0mxKVECj1vJUPAvs+Lwunh/dcuUjwzc4MHM9D8JOYX0XUZMEPedpB3vIbOw==", - "dependencies": { - "@ucast/mongo2js": "^1.3.0" - }, - "funding": { - "url": "https://github.com/stalniy/casl/blob/master/BACKERS.md" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", - "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", - "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", - "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", - "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", - "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", - "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", - "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", - "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", - "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", - "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", - "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", - "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", - "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", - "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", - "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", - "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", - "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", - "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", - "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", - "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", - "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", - "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", - "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@mongodb-js/saslprep": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.3.tgz", - "integrity": "sha512-SyCxhJfmK6MoLNV5SbDpNdUy9SDv5H7y9/9rl3KpnwgTHWuNNMc87zWqbcIZXNWY+aUjxLGLEcvHoLagG4tWCg==", - "dependencies": { - "sparse-bitfield": "^3.0.3" - } - }, - "node_modules/@sindresorhus/slugify": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", - "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==", - "dependencies": { - "@sindresorhus/transliterate": "^1.0.0", - "escape-string-regexp": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@sindresorhus/transliterate": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz", - "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==", - "dependencies": { - "escape-string-regexp": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@types/node": { - "version": "20.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", - "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/prompt-sync": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@types/prompt-sync/-/prompt-sync-4.2.3.tgz", - "integrity": "sha512-Ox77gCSx0YyeakGt/qfOZUSFNSSi+sh3ABoGOiCwiO2KODx492BJnUm9oIXS+AHJtqp12iM4RduY6viTJ9bYwA==", - "dev": true - }, - "node_modules/@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", - "dev": true - }, - "node_modules/@types/webidl-conversions": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" - }, - "node_modules/@types/whatwg-url": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", - "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", - "dependencies": { - "@types/node": "*", - "@types/webidl-conversions": "*" - } - }, - "node_modules/@ucast/core": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.2.tgz", - "integrity": "sha512-ons5CwXZ/51wrUPfoduC+cO7AS1/wRb0ybpQJ9RrssossDxVy4t49QxWoWgfBDvVKsz9VXzBk9z0wqTdZ+Cq8g==" - }, - "node_modules/@ucast/js": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@ucast/js/-/js-3.0.3.tgz", - "integrity": "sha512-jBBqt57T5WagkAjqfCIIE5UYVdaXYgGkOFYv2+kjq2AVpZ2RIbwCo/TujJpDlwTVluUI+WpnRpoGU2tSGlEvFQ==", - "dependencies": { - "@ucast/core": "^1.0.0" - } - }, - "node_modules/@ucast/mongo": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@ucast/mongo/-/mongo-2.4.3.tgz", - "integrity": "sha512-XcI8LclrHWP83H+7H2anGCEeDq0n+12FU2mXCTz6/Tva9/9ddK/iacvvhCyW6cijAAOILmt0tWplRyRhVyZLsA==", - "dependencies": { - "@ucast/core": "^1.4.1" - } - }, - "node_modules/@ucast/mongo2js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@ucast/mongo2js/-/mongo2js-1.3.4.tgz", - "integrity": "sha512-ahazOr1HtelA5AC1KZ9x0UwPMqqimvfmtSm/PRRSeKKeE5G2SCqTgwiNzO7i9jS8zA3dzXpKVPpXMkcYLnyItA==", - "dependencies": { - "@ucast/core": "^1.6.1", - "@ucast/js": "^3.0.0", - "@ucast/mongo": "^2.4.0" - } - }, - "node_modules/abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dependencies": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, - "node_modules/bson": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", - "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", - "engines": { - "node": ">=16.20.1" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-writer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/classic-level": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", - "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", - "hasInstallScript": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "^2.2.2", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" - }, - "node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "engines": { - "node": ">=14" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/esbuild": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", - "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.11", - "@esbuild/android-arm": "0.19.11", - "@esbuild/android-arm64": "0.19.11", - "@esbuild/android-x64": "0.19.11", - "@esbuild/darwin-arm64": "0.19.11", - "@esbuild/darwin-x64": "0.19.11", - "@esbuild/freebsd-arm64": "0.19.11", - "@esbuild/freebsd-x64": "0.19.11", - "@esbuild/linux-arm": "0.19.11", - "@esbuild/linux-arm64": "0.19.11", - "@esbuild/linux-ia32": "0.19.11", - "@esbuild/linux-loong64": "0.19.11", - "@esbuild/linux-mips64el": "0.19.11", - "@esbuild/linux-ppc64": "0.19.11", - "@esbuild/linux-riscv64": "0.19.11", - "@esbuild/linux-s390x": "0.19.11", - "@esbuild/linux-x64": "0.19.11", - "@esbuild/netbsd-x64": "0.19.11", - "@esbuild/openbsd-x64": "0.19.11", - "@esbuild/sunos-x64": "0.19.11", - "@esbuild/win32-arm64": "0.19.11", - "@esbuild/win32-ia32": "0.19.11", - "@esbuild/win32-x64": "0.19.11" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/getopts": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", - "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/kareem": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", - "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/knex": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz", - "integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==", - "dependencies": { - "colorette": "2.0.19", - "commander": "^10.0.0", - "debug": "4.3.4", - "escalade": "^3.1.1", - "esm": "^3.2.25", - "get-package-type": "^0.1.0", - "getopts": "2.3.0", - "interpret": "^2.2.0", - "lodash": "^4.17.21", - "pg-connection-string": "2.6.2", - "rechoir": "^0.8.0", - "resolve-from": "^5.0.0", - "tarn": "^3.0.2", - "tildify": "2.0.0" - }, - "bin": { - "knex": "bin/cli.js" - }, - "engines": { - "node": ">=16" - }, - "peerDependenciesMeta": { - "better-sqlite3": { - "optional": true - }, - "mysql": { - "optional": true - }, - "mysql2": { - "optional": true - }, - "pg": { - "optional": true - }, - "pg-native": { - "optional": true - }, - "sqlite3": { - "optional": true - }, - "tedious": { - "optional": true - } - } - }, - "node_modules/level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dependencies": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/level" - } - }, - "node_modules/level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dependencies": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" - }, - "node_modules/module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/mongodb": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz", - "integrity": "sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA==", - "dependencies": { - "@mongodb-js/saslprep": "^1.1.0", - "bson": "^6.2.0", - "mongodb-connection-string-url": "^2.6.0" - }, - "engines": { - "node": ">=16.20.1" - }, - "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", - "gcp-metadata": "^5.2.0", - "kerberos": "^2.0.1", - "mongodb-client-encryption": ">=6.0.0 <7", - "snappy": "^7.2.2", - "socks": "^2.7.1" - }, - "peerDependenciesMeta": { - "@aws-sdk/credential-providers": { - "optional": true - }, - "@mongodb-js/zstd": { - "optional": true - }, - "gcp-metadata": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "snappy": { - "optional": true - }, - "socks": { - "optional": true - } - } - }, - "node_modules/mongodb-connection-string-url": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", - "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", - "dependencies": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" - } - }, - "node_modules/mongoose": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.0.4.tgz", - "integrity": "sha512-wN9qvdevX3+922VnLT7CpaZRT3jmVCBOK2QMHMGeScQxDRnFMPpkuI9StEPpZo/3x8t+kbzH7F8RMPsyNwyM4w==", - "dependencies": { - "bson": "^6.2.0", - "kareem": "2.5.1", - "mongodb": "6.2.0", - "mpath": "0.9.0", - "mquery": "5.0.0", - "ms": "2.1.3", - "sift": "16.0.1" - }, - "engines": { - "node": ">=16.20.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "node_modules/mongoose/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/mpath": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", - "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mquery": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", - "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", - "dependencies": { - "debug": "4.x" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nanoid": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.4.tgz", - "integrity": "sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^18 || >=20" - } - }, - "node_modules/napi-macros": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", - "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==" - }, - "node_modules/node-gyp-build": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", - "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/packet-reader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/pg": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", - "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", - "dependencies": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "^2.6.2", - "pg-pool": "^3.6.1", - "pg-protocol": "^1.6.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - }, - "engines": { - "node": ">= 8.0.0" - }, - "optionalDependencies": { - "pg-cloudflare": "^1.1.1" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", - "optional": true - }, - "node_modules/pg-connection-string": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-pool": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", - "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "dependencies": { - "split2": "^4.1.0" - } - }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prompt-sync": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", - "integrity": "sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==", - "dependencies": { - "strip-ansi": "^5.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/sift": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", - "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" - }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tarn": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", - "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/tildify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", - "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", - "dev": true, - "dependencies": { - "esbuild": "~0.19.10", - "get-tsconfig": "^4.7.2" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/zod": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", - "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/pg-migrator/package.json b/pg-migrator/package.json deleted file mode 100644 index 4ea100d8a..000000000 --- a/pg-migrator/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "pg-migrator", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "migration": "tsx src/index.ts", - "rollback": "tsx src/rollback.ts", - "migrate:audit-log": "tsx src/audit-log-migrator.ts" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@types/node": "^20.11.0", - "@types/prompt-sync": "^4.2.3", - "@types/uuid": "^9.0.7", - "tsx": "^4.7.0", - "typescript": "^5.3.3" - }, - "dependencies": { - "@casl/ability": "^6.5.0", - "@sindresorhus/slugify": "^2.2.1", - "dotenv": "^16.3.1", - "knex": "^3.1.0", - "level": "^8.0.0", - "mongoose": "^8.0.4", - "nanoid": "^5.0.4", - "pg": "^8.11.3", - "prompt-sync": "^4.2.0", - "uuid": "^9.0.1", - "zod": "^3.22.4" - } -} diff --git a/pg-migrator/src/@types/knex.d.ts b/pg-migrator/src/@types/knex.d.ts deleted file mode 100644 index 059a14d16..000000000 --- a/pg-migrator/src/@types/knex.d.ts +++ /dev/null @@ -1,451 +0,0 @@ -import { Knex } from "knex"; - -import { - TableName, - TApiKeys, - TApiKeysInsert, - TApiKeysUpdate, - TAuditLogs, - TAuditLogsInsert, - TAuditLogsUpdate, - TAuthTokens, - TAuthTokenSessions, - TAuthTokenSessionsInsert, - TAuthTokenSessionsUpdate, - TAuthTokensInsert, - TAuthTokensUpdate, - TBackupPrivateKey, - TBackupPrivateKeyInsert, - TBackupPrivateKeyUpdate, - TGitAppInstallSessions, - TGitAppInstallSessionsInsert, - TGitAppInstallSessionsUpdate, - TGitAppOrg, - TGitAppOrgInsert, - TGitAppOrgUpdate, - TIdentities, - TIdentitiesInsert, - TIdentitiesUpdate, - TIdentityAccessTokens, - TIdentityAccessTokensInsert, - TIdentityAccessTokensUpdate, - TIdentityOrgMemberships, - TIdentityOrgMembershipsInsert, - TIdentityOrgMembershipsUpdate, - TIdentityProjectMemberships, - TIdentityProjectMembershipsInsert, - TIdentityProjectMembershipsUpdate, - TIdentityUaClientSecrets, - TIdentityUaClientSecretsInsert, - TIdentityUaClientSecretsUpdate, - TIdentityUniversalAuths, - TIdentityUniversalAuthsInsert, - TIdentityUniversalAuthsUpdate, - TIncidentContacts, - TIncidentContactsInsert, - TIncidentContactsUpdate, - TIntegrationAuths, - TIntegrationAuthsInsert, - TIntegrationAuthsUpdate, - TIntegrations, - TIntegrationsInsert, - TIntegrationsUpdate, - TOrganizations, - TOrganizationsInsert, - TOrganizationsUpdate, - TOrgBots, - TOrgBotsInsert, - TOrgBotsUpdate, - TOrgMemberships, - TOrgMembershipsInsert, - TOrgMembershipsUpdate, - TOrgRoles, - TOrgRolesInsert, - TOrgRolesUpdate, - TProjectBots, - TProjectBotsInsert, - TProjectBotsUpdate, - TProjectEnvironments, - TProjectEnvironmentsInsert, - TProjectEnvironmentsUpdate, - TProjectKeys, - TProjectKeysInsert, - TProjectKeysUpdate, - TProjectMemberships, - TProjectMembershipsInsert, - TProjectMembershipsUpdate, - TProjectRoles, - TProjectRolesInsert, - TProjectRolesUpdate, - TProjects, - TProjectsInsert, - TProjectsUpdate, - TSamlConfigs, - TSamlConfigsInsert, - TSamlConfigsUpdate, - TSecretApprovalPolicies, - TSecretApprovalPoliciesApprovers, - TSecretApprovalPoliciesApproversInsert, - TSecretApprovalPoliciesApproversUpdate, - TSecretApprovalPoliciesInsert, - TSecretApprovalPoliciesUpdate, - TSecretApprovalRequests, - TSecretApprovalRequestSecretTags, - TSecretApprovalRequestSecretTagsInsert, - TSecretApprovalRequestSecretTagsUpdate, - TSecretApprovalRequestsInsert, - TSecretApprovalRequestsReviewers, - TSecretApprovalRequestsReviewersInsert, - TSecretApprovalRequestsReviewersUpdate, - TSecretApprovalRequestsSecrets, - TSecretApprovalRequestsSecretsInsert, - TSecretApprovalRequestsSecretsUpdate, - TSecretApprovalRequestsUpdate, - TSecretBlindIndexes, - TSecretBlindIndexesInsert, - TSecretBlindIndexesUpdate, - TSecretFolders, - TSecretFoldersInsert, - TSecretFoldersUpdate, - TSecretFolderVersions, - TSecretFolderVersionsInsert, - TSecretFolderVersionsUpdate, - TSecretImports, - TSecretImportsInsert, - TSecretImportsUpdate, - TSecretRotationOutputs, - TSecretRotationOutputsInsert, - TSecretRotationOutputsUpdate, - TSecretRotations, - TSecretRotationsInsert, - TSecretRotationsUpdate, - TSecrets, - TSecretScanningGitRisks, - TSecretScanningGitRisksInsert, - TSecretScanningGitRisksUpdate, - TSecretsInsert, - TSecretSnapshotFolders, - TSecretSnapshotFoldersInsert, - TSecretSnapshotFoldersUpdate, - TSecretSnapshots, - TSecretSnapshotSecrets, - TSecretSnapshotSecretsInsert, - TSecretSnapshotSecretsUpdate, - TSecretSnapshotsInsert, - TSecretSnapshotsUpdate, - TSecretsUpdate, - TSecretTagJunction, - TSecretTagJunctionInsert, - TSecretTagJunctionUpdate, - TSecretTags, - TSecretTagsInsert, - TSecretTagsUpdate, - TSecretVersions, - TSecretVersionsInsert, - TSecretVersionsUpdate, - TSecretVersionTagJunction, - TSecretVersionTagJunctionInsert, - TSecretVersionTagJunctionUpdate, - TServiceTokens, - TServiceTokensInsert, - TServiceTokensUpdate, - TSuperAdmin, - TSuperAdminInsert, - TSuperAdminUpdate, - TTrustedIps, - TTrustedIpsInsert, - TTrustedIpsUpdate, - TUserActions, - TUserActionsInsert, - TUserActionsUpdate, - TUserEncryptionKeys, - TUserEncryptionKeysInsert, - TUserEncryptionKeysUpdate, - TUsers, - TUsersInsert, - TUsersUpdate, - TWebhooks, - TWebhooksInsert, - TWebhooksUpdate, -} from "../schemas"; - -declare module "knex/types/tables" { - interface Tables { - [TableName.Users]: Knex.CompositeTableType< - TUsers, - TUsersInsert, - TUsersUpdate - >; - [TableName.UserEncryptionKey]: Knex.CompositeTableType< - TUserEncryptionKeys, - TUserEncryptionKeysInsert, - TUserEncryptionKeysUpdate - >; - [TableName.AuthTokens]: Knex.CompositeTableType< - TAuthTokens, - TAuthTokensInsert, - TAuthTokensUpdate - >; - [TableName.AuthTokenSession]: Knex.CompositeTableType< - TAuthTokenSessions, - TAuthTokenSessionsInsert, - TAuthTokenSessionsUpdate - >; - [TableName.BackupPrivateKey]: Knex.CompositeTableType< - TBackupPrivateKey, - TBackupPrivateKeyInsert, - TBackupPrivateKeyUpdate - >; - [TableName.Organization]: Knex.CompositeTableType< - TOrganizations, - TOrganizationsInsert, - TOrganizationsUpdate - >; - [TableName.OrgMembership]: Knex.CompositeTableType< - TOrgMemberships, - TOrgMembershipsInsert, - TOrgMembershipsUpdate - >; - [TableName.OrgRoles]: Knex.CompositeTableType< - TOrgRoles, - TOrgRolesInsert, - TOrgRolesUpdate - >; - [TableName.IncidentContact]: Knex.CompositeTableType< - TIncidentContacts, - TIncidentContactsInsert, - TIncidentContactsUpdate - >; - [TableName.UserAction]: Knex.CompositeTableType< - TUserActions, - TUserActionsInsert, - TUserActionsUpdate - >; - [TableName.SuperAdmin]: Knex.CompositeTableType< - TSuperAdmin, - TSuperAdminInsert, - TSuperAdminUpdate - >; - [TableName.ApiKey]: Knex.CompositeTableType< - TApiKeys, - TApiKeysInsert, - TApiKeysUpdate - >; - [TableName.Project]: Knex.CompositeTableType< - TProjects, - TProjectsInsert, - TProjectsUpdate - >; - [TableName.ProjectMembership]: Knex.CompositeTableType< - TProjectMemberships, - TProjectMembershipsInsert, - TProjectMembershipsUpdate - >; - [TableName.Environment]: Knex.CompositeTableType< - TProjectEnvironments, - TProjectEnvironmentsInsert, - TProjectEnvironmentsUpdate - >; - [TableName.ProjectBot]: Knex.CompositeTableType< - TProjectBots, - TProjectBotsInsert, - TProjectBotsUpdate - >; - [TableName.ProjectRoles]: Knex.CompositeTableType< - TProjectRoles, - TProjectRolesInsert, - TProjectRolesUpdate - >; - [TableName.ProjectKeys]: Knex.CompositeTableType< - TProjectKeys, - TProjectKeysInsert, - TProjectKeysUpdate - >; - [TableName.Secret]: Knex.CompositeTableType< - TSecrets, - TSecretsInsert, - TSecretsUpdate - >; - [TableName.SecretBlindIndex]: Knex.CompositeTableType< - TSecretBlindIndexes, - TSecretBlindIndexesInsert, - TSecretBlindIndexesUpdate - >; - [TableName.SecretVersion]: Knex.CompositeTableType< - TSecretVersions, - TSecretVersionsInsert, - TSecretVersionsUpdate - >; - [TableName.SecretFolder]: Knex.CompositeTableType< - TSecretFolders, - TSecretFoldersInsert, - TSecretFoldersUpdate - >; - [TableName.SecretFolderVersion]: Knex.CompositeTableType< - TSecretFolderVersions, - TSecretFolderVersionsInsert, - TSecretFolderVersionsUpdate - >; - [TableName.SecretTag]: Knex.CompositeTableType< - TSecretTags, - TSecretTagsInsert, - TSecretTagsUpdate - >; - [TableName.SecretImport]: Knex.CompositeTableType< - TSecretImports, - TSecretImportsInsert, - TSecretImportsUpdate - >; - [TableName.Integration]: Knex.CompositeTableType< - TIntegrations, - TIntegrationsInsert, - TIntegrationsUpdate - >; - [TableName.Webhook]: Knex.CompositeTableType< - TWebhooks, - TWebhooksInsert, - TWebhooksUpdate - >; - [TableName.ServiceToken]: Knex.CompositeTableType< - TServiceTokens, - TServiceTokensInsert, - TServiceTokensUpdate - >; - [TableName.IntegrationAuth]: Knex.CompositeTableType< - TIntegrationAuths, - TIntegrationAuthsInsert, - TIntegrationAuthsUpdate - >; - [TableName.Identity]: Knex.CompositeTableType< - TIdentities, - TIdentitiesInsert, - TIdentitiesUpdate - >; - [TableName.IdentityUniversalAuth]: Knex.CompositeTableType< - TIdentityUniversalAuths, - TIdentityUniversalAuthsInsert, - TIdentityUniversalAuthsUpdate - >; - [TableName.IdentityUaClientSecret]: Knex.CompositeTableType< - TIdentityUaClientSecrets, - TIdentityUaClientSecretsInsert, - TIdentityUaClientSecretsUpdate - >; - [TableName.IdentityAccessToken]: Knex.CompositeTableType< - TIdentityAccessTokens, - TIdentityAccessTokensInsert, - TIdentityAccessTokensUpdate - >; - [TableName.IdentityOrgMembership]: Knex.CompositeTableType< - TIdentityOrgMemberships, - TIdentityOrgMembershipsInsert, - TIdentityOrgMembershipsUpdate - >; - [TableName.IdentityProjectMembership]: Knex.CompositeTableType< - TIdentityProjectMemberships, - TIdentityProjectMembershipsInsert, - TIdentityProjectMembershipsUpdate - >; - [TableName.SecretApprovalPolicy]: Knex.CompositeTableType< - TSecretApprovalPolicies, - TSecretApprovalPoliciesInsert, - TSecretApprovalPoliciesUpdate - >; - [TableName.SecretApprovalPolicyApprover]: Knex.CompositeTableType< - TSecretApprovalPoliciesApprovers, - TSecretApprovalPoliciesApproversInsert, - TSecretApprovalPoliciesApproversUpdate - >; - [TableName.SecretApprovalRequest]: Knex.CompositeTableType< - TSecretApprovalRequests, - TSecretApprovalRequestsInsert, - TSecretApprovalRequestsUpdate - >; - [TableName.SecretApprovalRequestReviewer]: Knex.CompositeTableType< - TSecretApprovalRequestsReviewers, - TSecretApprovalRequestsReviewersInsert, - TSecretApprovalRequestsReviewersUpdate - >; - [TableName.SecretApprovalRequestSecret]: Knex.CompositeTableType< - TSecretApprovalRequestsSecrets, - TSecretApprovalRequestsSecretsInsert, - TSecretApprovalRequestsSecretsUpdate - >; - [TableName.SecretApprovalRequestSecretTag]: Knex.CompositeTableType< - TSecretApprovalRequestSecretTags, - TSecretApprovalRequestSecretTagsInsert, - TSecretApprovalRequestSecretTagsUpdate - >; - [TableName.SecretRotation]: Knex.CompositeTableType< - TSecretRotations, - TSecretRotationsInsert, - TSecretRotationsUpdate - >; - [TableName.SecretRotationOutput]: Knex.CompositeTableType< - TSecretRotationOutputs, - TSecretRotationOutputsInsert, - TSecretRotationOutputsUpdate - >; - [TableName.Snapshot]: Knex.CompositeTableType< - TSecretSnapshots, - TSecretSnapshotsInsert, - TSecretSnapshotsUpdate - >; - [TableName.SnapshotSecret]: Knex.CompositeTableType< - TSecretSnapshotSecrets, - TSecretSnapshotSecretsInsert, - TSecretSnapshotSecretsUpdate - >; - [TableName.SnapshotFolder]: Knex.CompositeTableType< - TSecretSnapshotFolders, - TSecretSnapshotFoldersInsert, - TSecretSnapshotFoldersUpdate - >; - [TableName.SamlConfig]: Knex.CompositeTableType< - TSamlConfigs, - TSamlConfigsInsert, - TSamlConfigsUpdate - >; - [TableName.OrgBot]: Knex.CompositeTableType< - TOrgBots, - TOrgBotsInsert, - TOrgBotsUpdate - >; - [TableName.AuditLog]: Knex.CompositeTableType< - TAuditLogs, - TAuditLogsInsert, - TAuditLogsUpdate - >; - [TableName.GitAppInstallSession]: Knex.CompositeTableType< - TGitAppInstallSessions, - TGitAppInstallSessionsInsert, - TGitAppInstallSessionsUpdate - >; - [TableName.GitAppOrg]: Knex.CompositeTableType< - TGitAppOrg, - TGitAppOrgInsert, - TGitAppOrgUpdate - >; - [TableName.SecretScanningGitRisk]: Knex.CompositeTableType< - TSecretScanningGitRisks, - TSecretScanningGitRisksInsert, - TSecretScanningGitRisksUpdate - >; - [TableName.TrustedIps]: Knex.CompositeTableType< - TTrustedIps, - TTrustedIpsInsert, - TTrustedIpsUpdate - >; - // Junction tables - [TableName.JnSecretTag]: Knex.CompositeTableType< - TSecretTagJunction, - TSecretTagJunctionInsert, - TSecretTagJunctionUpdate - >; - [TableName.SecretVersionTag]: Knex.CompositeTableType< - TSecretVersionTagJunction, - TSecretVersionTagJunctionInsert, - TSecretVersionTagJunctionUpdate - >; - } -} diff --git a/pg-migrator/src/audit-log-migrator.ts b/pg-migrator/src/audit-log-migrator.ts deleted file mode 100644 index becb60427..000000000 --- a/pg-migrator/src/audit-log-migrator.ts +++ /dev/null @@ -1,1284 +0,0 @@ -import { Level } from "level"; -import { TableName } from "./schemas"; -import dotenv from "dotenv"; -import PromptSync from "prompt-sync"; -import mongoose from "mongoose"; -import knex from "knex"; -import path from "path"; -import { v4 as uuidV4 } from "uuid"; -import { getFolderKv, migrateCollection, truncateAndSlugify } from "."; -import { ActorType, AuditLog } from "./models"; - -export type TCreateAuditLogDTO = { - event: Event; - actor: UserActor | IdentityActor | ServiceActor; - orgId?: string; - projectId?: string; -} & BaseAuthData; - -interface BaseAuthData { - ipAddress?: string; - userAgent?: string; - userAgentType?: UserAgentType; -} - -export enum UserAgentType { - WEB = "web", - CLI = "cli", - K8_OPERATOR = "k8-operator", - TERRAFORM = "terraform", - OTHER = "other", - PYTHON_SDK = "InfisicalPythonSDK", - NODE_SDK = "InfisicalNodeSDK", -} - -export enum EventType { - GET_SECRETS = "get-secrets", - GET_SECRET = "get-secret", - REVEAL_SECRET = "reveal-secret", - CREATE_SECRET = "create-secret", - CREATE_SECRETS = "create-secrets", - UPDATE_SECRET = "update-secret", - UPDATE_SECRETS = "update-secrets", - DELETE_SECRET = "delete-secret", - DELETE_SECRETS = "delete-secrets", - GET_WORKSPACE_KEY = "get-workspace-key", - AUTHORIZE_INTEGRATION = "authorize-integration", - UNAUTHORIZE_INTEGRATION = "unauthorize-integration", - CREATE_INTEGRATION = "create-integration", - DELETE_INTEGRATION = "delete-integration", - ADD_TRUSTED_IP = "add-trusted-ip", - UPDATE_TRUSTED_IP = "update-trusted-ip", - DELETE_TRUSTED_IP = "delete-trusted-ip", - CREATE_SERVICE_TOKEN = "create-service-token", // v2 - DELETE_SERVICE_TOKEN = "delete-service-token", // v2 - CREATE_IDENTITY = "create-identity", - UPDATE_IDENTITY = "update-identity", - DELETE_IDENTITY = "delete-identity", - LOGIN_IDENTITY_UNIVERSAL_AUTH = "login-identity-universal-auth", - ADD_IDENTITY_UNIVERSAL_AUTH = "add-identity-universal-auth", - UPDATE_IDENTITY_UNIVERSAL_AUTH = "update-identity-universal-auth", - GET_IDENTITY_UNIVERSAL_AUTH = "get-identity-universal-auth", - CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "create-identity-universal-auth-client-secret", - REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "revoke-identity-universal-auth-client-secret", - GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS = "get-identity-universal-auth-client-secret", - CREATE_ENVIRONMENT = "create-environment", - UPDATE_ENVIRONMENT = "update-environment", - DELETE_ENVIRONMENT = "delete-environment", - ADD_WORKSPACE_MEMBER = "add-workspace-member", - ADD_BATCH_WORKSPACE_MEMBER = "add-workspace-members", - REMOVE_WORKSPACE_MEMBER = "remove-workspace-member", - CREATE_FOLDER = "create-folder", - UPDATE_FOLDER = "update-folder", - DELETE_FOLDER = "delete-folder", - CREATE_WEBHOOK = "create-webhook", - UPDATE_WEBHOOK_STATUS = "update-webhook-status", - DELETE_WEBHOOK = "delete-webhook", - GET_SECRET_IMPORTS = "get-secret-imports", - CREATE_SECRET_IMPORT = "create-secret-import", - UPDATE_SECRET_IMPORT = "update-secret-import", - DELETE_SECRET_IMPORT = "delete-secret-import", - UPDATE_USER_WORKSPACE_ROLE = "update-user-workspace-role", - UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS = "update-user-workspace-denied-permissions", - SECRET_APPROVAL_MERGED = "secret-approval-merged", - SECRET_APPROVAL_REQUEST = "secret-approval-request", - SECRET_APPROVAL_CLOSED = "secret-approval-closed", - SECRET_APPROVAL_REOPENED = "secret-approval-reopened", -} - -interface UserActorMetadata { - userId: string; - email: string; -} - -interface ServiceActorMetadata { - serviceId: string; - name: string; -} - -interface IdentityActorMetadata { - identityId: string; - name: string; -} - -export interface UserActor { - type: ActorType.USER; - metadata: UserActorMetadata; -} - -export interface ServiceActor { - type: ActorType.SERVICE; - metadata: ServiceActorMetadata; -} - -export interface IdentityActor { - type: ActorType.IDENTITY; - metadata: IdentityActorMetadata; -} - -export type Actor = UserActor | ServiceActor | IdentityActor; - -interface GetSecretsEvent { - type: EventType.GET_SECRETS; - metadata: { - environment: string; - secretPath: string; - numberOfSecrets: number; - }; -} - -interface GetSecretEvent { - type: EventType.GET_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface CreateSecretEvent { - type: EventType.CREATE_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface CreateSecretBatchEvent { - type: EventType.CREATE_SECRETS; - metadata: { - environment: string; - secretPath: string; - secrets: Array<{ - secretId: string; - secretKey: string; - secretVersion: number; - }>; - }; -} - -interface UpdateSecretEvent { - type: EventType.UPDATE_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface UpdateSecretBatchEvent { - type: EventType.UPDATE_SECRETS; - metadata: { - environment: string; - secretPath: string; - secrets: Array<{ - secretId: string; - secretKey: string; - secretVersion: number; - }>; - }; -} - -interface DeleteSecretEvent { - type: EventType.DELETE_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface DeleteSecretBatchEvent { - type: EventType.DELETE_SECRETS; - metadata: { - environment: string; - secretPath: string; - secrets: Array<{ - secretId: string; - secretKey: string; - secretVersion: number; - }>; - }; -} - -interface GetWorkspaceKeyEvent { - type: EventType.GET_WORKSPACE_KEY; - metadata: { - keyId: string; - }; -} - -interface AuthorizeIntegrationEvent { - type: EventType.AUTHORIZE_INTEGRATION; - metadata: { - integration: string; - }; -} - -interface UnauthorizeIntegrationEvent { - type: EventType.UNAUTHORIZE_INTEGRATION; - metadata: { - integration: string; - }; -} - -interface CreateIntegrationEvent { - type: EventType.CREATE_INTEGRATION; - metadata: { - integrationId: string; - integration: string; // TODO: fix type - environment: string; - secretPath: string; - url?: string; - app?: string; - appId?: string; - targetEnvironment?: string; - targetEnvironmentId?: string; - targetService?: string; - targetServiceId?: string; - path?: string; - region?: string; - }; -} - -interface DeleteIntegrationEvent { - type: EventType.DELETE_INTEGRATION; - metadata: { - integrationId: string; - integration: string; // TODO: fix type - environment: string; - secretPath: string; - url?: string; - app?: string; - appId?: string; - targetEnvironment?: string; - targetEnvironmentId?: string; - targetService?: string; - targetServiceId?: string; - path?: string; - region?: string; - }; -} - -interface AddTrustedIPEvent { - type: EventType.ADD_TRUSTED_IP; - metadata: { - trustedIpId: string; - ipAddress: string; - prefix?: number; - }; -} - -interface UpdateTrustedIPEvent { - type: EventType.UPDATE_TRUSTED_IP; - metadata: { - trustedIpId: string; - ipAddress: string; - prefix?: number; - }; -} - -interface DeleteTrustedIPEvent { - type: EventType.DELETE_TRUSTED_IP; - metadata: { - trustedIpId: string; - ipAddress: string; - prefix?: number; - }; -} - -interface CreateServiceTokenEvent { - type: EventType.CREATE_SERVICE_TOKEN; - metadata: { - name: string; - scopes: Array<{ - environment: string; - secretPath: string; - }>; - }; -} - -interface DeleteServiceTokenEvent { - type: EventType.DELETE_SERVICE_TOKEN; - metadata: { - name: string; - scopes: Array<{ - environment: string; - secretPath: string; - }>; - }; -} - -interface CreateIdentityEvent { - // note: currently not logging org-role - type: EventType.CREATE_IDENTITY; - metadata: { - identityId: string; - name: string; - }; -} - -interface UpdateIdentityEvent { - type: EventType.UPDATE_IDENTITY; - metadata: { - identityId: string; - name?: string; - }; -} - -interface DeleteIdentityEvent { - type: EventType.DELETE_IDENTITY; - metadata: { - identityId: string; - }; -} - -interface LoginIdentityUniversalAuthEvent { - type: EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH; - metadata: { - identityId: string; - identityUniversalAuthId: string; - clientSecretId: string; - identityAccessTokenId: string; - }; -} -export enum IPType { - IPV4 = "ipv4", - IPV6 = "ipv6", -} - -export interface TIdentityTrustedIp { - ipAddress: string; - type: IPType; - prefix: number; -} - -interface AddIdentityUniversalAuthEvent { - type: EventType.ADD_IDENTITY_UNIVERSAL_AUTH; - metadata: { - identityId: string; - clientSecretTrustedIps: Array; - accessTokenTTL: number; - accessTokenMaxTTL: number; - accessTokenNumUsesLimit: number; - accessTokenTrustedIps: Array; - }; -} - -interface UpdateIdentityUniversalAuthEvent { - type: EventType.UPDATE_IDENTITY_UNIVERSAL_AUTH; - metadata: { - identityId: string; - clientSecretTrustedIps?: Array; - accessTokenTTL?: number; - accessTokenMaxTTL?: number; - accessTokenNumUsesLimit?: number; - accessTokenTrustedIps?: Array; - }; -} - -interface GetIdentityUniversalAuthEvent { - type: EventType.GET_IDENTITY_UNIVERSAL_AUTH; - metadata: { - identityId: string; - }; -} - -interface CreateIdentityUniversalAuthClientSecretEvent { - type: EventType.CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET; - metadata: { - identityId: string; - clientSecretId: string; - }; -} - -interface GetIdentityUniversalAuthClientSecretsEvent { - type: EventType.GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS; - metadata: { - identityId: string; - }; -} - -interface RevokeIdentityUniversalAuthClientSecretEvent { - type: EventType.REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET; - metadata: { - identityId: string; - clientSecretId: string; - }; -} - -interface CreateEnvironmentEvent { - type: EventType.CREATE_ENVIRONMENT; - metadata: { - name: string; - slug: string; - }; -} - -interface UpdateEnvironmentEvent { - type: EventType.UPDATE_ENVIRONMENT; - metadata: { - oldName: string; - newName: string; - oldSlug: string; - newSlug: string; - oldPos: number; - newPos: number; - }; -} - -interface DeleteEnvironmentEvent { - type: EventType.DELETE_ENVIRONMENT; - metadata: { - name: string; - slug: string; - }; -} - -interface AddWorkspaceMemberEvent { - type: EventType.ADD_WORKSPACE_MEMBER; - metadata: { - userId: string; - email: string; - }; -} - -interface AddBatchWorkspaceMemberEvent { - type: EventType.ADD_BATCH_WORKSPACE_MEMBER; - metadata: Array<{ - userId: string; - email: string; - }>; -} - -interface RemoveWorkspaceMemberEvent { - type: EventType.REMOVE_WORKSPACE_MEMBER; - metadata: { - userId: string; - email: string; - }; -} - -interface CreateFolderEvent { - type: EventType.CREATE_FOLDER; - metadata: { - environment: string; - folderId: string; - folderName: string; - folderPath: string; - }; -} - -interface UpdateFolderEvent { - type: EventType.UPDATE_FOLDER; - metadata: { - environment: string; - folderId: string; - oldFolderName: string; - newFolderName: string; - folderPath: string; - }; -} - -interface DeleteFolderEvent { - type: EventType.DELETE_FOLDER; - metadata: { - environment: string; - folderId: string; - folderName: string; - folderPath: string; - }; -} - -interface CreateWebhookEvent { - type: EventType.CREATE_WEBHOOK; - metadata: { - webhookId: string; - environment: string; - secretPath: string; - webhookUrl: string; - isDisabled: boolean; - }; -} - -interface UpdateWebhookStatusEvent { - type: EventType.UPDATE_WEBHOOK_STATUS; - metadata: { - webhookId: string; - environment: string; - secretPath: string; - webhookUrl: string; - isDisabled: boolean; - }; -} - -interface DeleteWebhookEvent { - type: EventType.DELETE_WEBHOOK; - metadata: { - webhookId: string; - environment: string; - secretPath: string; - webhookUrl: string; - isDisabled: boolean; - }; -} - -interface GetSecretImportsEvent { - type: EventType.GET_SECRET_IMPORTS; - metadata: { - environment: string; - folderId: string; - numberOfImports: number; - }; -} - -interface CreateSecretImportEvent { - type: EventType.CREATE_SECRET_IMPORT; - metadata: { - secretImportId: string; - folderId: string; - importFromEnvironment: string; - importFromSecretPath: string; - importToEnvironment: string; - importToSecretPath: string; - }; -} - -interface UpdateSecretImportEvent { - type: EventType.UPDATE_SECRET_IMPORT; - metadata: { - secretImportId: string; - folderId: string; - importToEnvironment: string; - importToSecretPath: string; - position: number; - orderBefore?: { - environment: string; - secretPath: string; - }[]; - orderAfter?: { - environment: string; - secretPath: string; - }[]; - }; -} - -interface DeleteSecretImportEvent { - type: EventType.DELETE_SECRET_IMPORT; - metadata: { - secretImportId: string; - folderId: string; - importFromEnvironment: string; - importFromSecretPath: string; - importToEnvironment: string; - importToSecretPath: string; - }; -} - -interface UpdateUserRole { - type: EventType.UPDATE_USER_WORKSPACE_ROLE; - metadata: { - userId: string; - email: string; - oldRole: string; - newRole: string; - }; -} - -interface UpdateUserDeniedPermissions { - type: EventType.UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS; - metadata: { - userId: string; - email: string; - deniedPermissions: { - environmentSlug: string; - ability: string; - }[]; - }; -} -interface SecretApprovalMerge { - type: EventType.SECRET_APPROVAL_MERGED; - metadata: { - mergedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -interface SecretApprovalClosed { - type: EventType.SECRET_APPROVAL_CLOSED; - metadata: { - closedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -interface SecretApprovalReopened { - type: EventType.SECRET_APPROVAL_REOPENED; - metadata: { - reopenedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -interface SecretApprovalRequest { - type: EventType.SECRET_APPROVAL_REQUEST; - metadata: { - committedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -export type Event = - | GetSecretsEvent - | GetSecretEvent - | CreateSecretEvent - | CreateSecretBatchEvent - | UpdateSecretEvent - | UpdateSecretBatchEvent - | DeleteSecretEvent - | DeleteSecretBatchEvent - | GetWorkspaceKeyEvent - | AuthorizeIntegrationEvent - | UnauthorizeIntegrationEvent - | CreateIntegrationEvent - | DeleteIntegrationEvent - | AddTrustedIPEvent - | UpdateTrustedIPEvent - | DeleteTrustedIPEvent - | CreateServiceTokenEvent - | DeleteServiceTokenEvent - | CreateIdentityEvent - | UpdateIdentityEvent - | DeleteIdentityEvent - | LoginIdentityUniversalAuthEvent - | AddIdentityUniversalAuthEvent - | UpdateIdentityUniversalAuthEvent - | GetIdentityUniversalAuthEvent - | CreateIdentityUniversalAuthClientSecretEvent - | GetIdentityUniversalAuthClientSecretsEvent - | RevokeIdentityUniversalAuthClientSecretEvent - | CreateEnvironmentEvent - | UpdateEnvironmentEvent - | DeleteEnvironmentEvent - | AddWorkspaceMemberEvent - | AddBatchWorkspaceMemberEvent - | RemoveWorkspaceMemberEvent - | CreateFolderEvent - | UpdateFolderEvent - | DeleteFolderEvent - | CreateWebhookEvent - | UpdateWebhookStatusEvent - | DeleteWebhookEvent - | GetSecretImportsEvent - | CreateSecretImportEvent - | UpdateSecretImportEvent - | DeleteSecretImportEvent - | UpdateUserRole - | UpdateUserDeniedPermissions - | SecretApprovalMerge - | SecretApprovalClosed - | SecretApprovalRequest; - -const kdb = new Level("./db", { valueEncoding: "json" }); - -const projectKv = kdb.sublevel(TableName.Project); -const secKv = kdb.sublevel(TableName.Secret); -const userKv = kdb.sublevel(TableName.Users); -const orgKv = kdb.sublevel(TableName.Organization); -const identityKv = kdb.sublevel(TableName.Identity); -const secretApprovalRequestKv = kdb.sublevel(TableName.SecretApprovalRequest); -const projectMembKv = kdb.sublevel(TableName.ProjectMembership); -const projectKeyKv = kdb.sublevel(TableName.ProjectKeys); -const integrationKv = kdb.sublevel(TableName.Integration); -const trustedIpKv = kdb.sublevel(TableName.TrustedIps); -const identityUaKv = kdb.sublevel(TableName.IdentityUniversalAuth); -const identityUaClientSecKv = kdb.sublevel(TableName.IdentityUaClientSecret); -const identityAccessTokenKv = kdb.sublevel(TableName.IdentityAccessToken); -const webhookKv = kdb.sublevel(TableName.Webhook); - -// add these to the main migrator -// this will be empty -const secretImportKv = kdb.sublevel(TableName.SecretImport); - -const getKeyWithFallack = (sublevel: typeof projectKeyKv, key: string) => - sublevel.get(key).catch(() => key); - -const main = async () => { - try { - dotenv.config(); - const prompt = PromptSync({ sigint: true }); - - let mongodb_url = process.env.MONGO_DB_URL; - if (!mongodb_url) { - mongodb_url = prompt("Type the mongodb url: "); - } - console.log("Checking mongoose connection..."); - await mongoose.connect(mongodb_url); - console.log("Connected successfully to mongo"); - - let postgres_url = process.env.POSTGRES_DB_URL; - if (!postgres_url) { - postgres_url = prompt("Type the postgres url: "); - } - console.log("Checking postgres connection..."); - const db = knex({ - client: "pg", - connection: postgres_url, - migrations: { - directory: path.join(__dirname, "../../backend/src/db/migrations"), - extension: "ts", - tableName: "infisical_migrations", - }, - }); - console.log("Connected successfully to postgres"); - await db.raw("select 1+1 as result"); - - if (process.env.START_FRESH === "true") { - console.log("Starting rolling back to latest, comment this out later"); - await db.migrate.rollback({}, true); - await kdb.clear(); - console.log("Rolling back completed"); - - console.log("Executing migration"); - await db.migrate.latest(); - console.log("Completed migration"); - } - - await migrateCollection({ - db, - mongooseCollection: AuditLog, - postgresTableName: TableName.AuditLog, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - const orgId = await orgKv - .get(doc.organization.toString()) - .catch(() => null); - if (!orgId) return; - - const projectId = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectId) return; - - const eventFields = { - id, - actor: doc.actor.type, - actorMetadata: doc.actor.metadata, - orgId, - eventType: doc.event.type, - expiresAt: doc.expiresAt, - ipAddress: doc.ipAddress, - projectId, - userAgent: doc.userAgent, - userAgentType: doc.userAgentType, - createdAt: (doc as any).createdAt, - updatedAt: (doc as any).updatedAt, - }; - - switch (doc.event.type) { - case EventType.GET_SECRET: { - const event = doc.event.metadata; - if (!event.environment) return; - - const secretId = await secKv.get(event.secretId).catch(() => null); - if (!secretId) return; - const pgEvent = { ...event, secretId }; - return { ...eventFields, eventMetadata: pgEvent }; - } - case EventType.GET_SECRETS: { - const event = doc.event.metadata; - return { ...eventFields, eventMetadata: event }; - } - case EventType.CREATE_SECRET: { - const event = doc.event.metadata; - const secretId = await secKv.get(event.secretId).catch(() => null); - if (!secretId) return; - const pgEvent = { ...event, secretId }; - return { ...eventFields, eventMetadata: pgEvent }; - } - case EventType.CREATE_SECRETS: { - const event = doc.event.metadata; - const secrets = await Promise.all( - event.secrets.flatMap(async (el) => { - const secretId = await secKv.get(el.secretId).catch(() => null); - if (!secretId) return []; - return { ...el, secretId }; - }), - ); - return { ...eventFields, eventMetadata: { ...event, secrets } }; - } - case EventType.UPDATE_SECRET: { - const event = doc.event.metadata; - const secretId = await secKv.get(event.secretId).catch(() => null); - if (!secretId) return; - const pgEvent = { ...event, secretId }; - return { ...eventFields, eventMetadata: pgEvent }; - } - case EventType.UPDATE_SECRETS: { - const event = doc.event.metadata; - const secrets = await Promise.all( - event.secrets.flatMap(async (el) => { - const secretId = await secKv.get(el.secretId).catch(() => null); - if (!secretId) return []; - return { ...el, secretId }; - }), - ); - return { ...eventFields, eventMetadata: { ...event, secrets } }; - } - case EventType.DELETE_SECRET: { - const event = doc.event.metadata; - const secretId = await secKv.get(event.secretId).catch(() => null); - if (!secretId) return; - const pgEvent = { ...event, secretId }; - return { ...eventFields, eventMetadata: pgEvent }; - } - case EventType.DELETE_SECRETS: { - const event = doc.event.metadata; - const secrets = await Promise.all( - event.secrets.flatMap(async (el) => { - const secretId = await secKv.get(el.secretId).catch(() => null); - if (!secretId) return []; - return { ...el, secretId }; - }), - ); - return { ...eventFields, eventMetadata: { ...event, secrets } }; - } - case EventType.GET_WORKSPACE_KEY: { - const event = doc.event.metadata; - const keyId = await projectKeyKv.get(event.keyId).catch(() => null); - if (!keyId) return; - return { ...eventFields, eventMetadata: { keyId } }; - } - case EventType.AUTHORIZE_INTEGRATION: { - const event = doc.event.metadata; - return { ...eventFields, eventMetadata: event }; - } - case EventType.UNAUTHORIZE_INTEGRATION: { - const event = doc.event.metadata; - return { ...eventFields, eventMetadata: event }; - } - case EventType.CREATE_INTEGRATION: { - const event = doc.event.metadata; - const integrationId = await integrationKv - .get(event.integrationId) - .catch(() => event.integrationId); - return { - ...eventFields, - eventMetadata: { ...event, integrationId }, - }; - } - case EventType.DELETE_INTEGRATION: { - const event = doc.event.metadata; - const integrationId = await integrationKv - .get(event.integrationId) - .catch(() => event.integrationId); - return { - ...eventFields, - eventMetadata: { ...event, integrationId }, - }; - } - case EventType.ADD_TRUSTED_IP: { - const event = doc.event.metadata; - const trustedIpId = await trustedIpKv - .get(event.trustedIpId) - .catch(() => event.trustedIpId); - return { - ...eventFields, - eventMetadata: { ...event, trustedIpId }, - }; - } - case EventType.UPDATE_TRUSTED_IP: { - const event = doc.event.metadata; - const trustedIpId = await trustedIpKv - .get(event.trustedIpId) - .catch(() => event.trustedIpId); - return { - ...eventFields, - eventMetadata: { ...event, trustedIpId }, - }; - } - case EventType.DELETE_TRUSTED_IP: { - const event = doc.event.metadata; - const trustedIpId = await trustedIpKv - .get(event.trustedIpId) - .catch(() => event.trustedIpId); - if (!trustedIpId) return; - return { - ...eventFields, - eventMetadata: { ...event, trustedIpId }, - }; - } - case EventType.CREATE_SERVICE_TOKEN: { - const event = doc.event.metadata; - return { - ...eventFields, - eventMetadata: event, - }; - } - case EventType.DELETE_SERVICE_TOKEN: { - const event = doc.event.metadata; - return { - ...eventFields, - eventMetadata: event, - }; - } - case EventType.CREATE_IDENTITY: { - const event = doc.event.metadata; - const trustedIpId = await identityKv - .get(event.identityId) - .catch(() => event.identityId); - return { - ...eventFields, - eventMetadata: { ...event, trustedIpId }, - }; - } - case EventType.UPDATE_IDENTITY: { - const event = doc.event.metadata; - const trustedIpId = await identityKv - .get(event.identityId) - .catch(() => event.identityId); - return { - ...eventFields, - eventMetadata: { ...event, trustedIpId }, - }; - } - case EventType.DELETE_IDENTITY: { - const event = doc.event.metadata; - const trustedIpId = await identityKv - .get(event.identityId) - .catch(() => event.identityId); - return { - ...eventFields, - eventMetadata: { ...event, trustedIpId }, - }; - } - case EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH: { - const event = doc.event.metadata; - const identityId = await getKeyWithFallack( - identityKv, - event.identityId, - ); - const identityAccessTokenId = await getKeyWithFallack( - identityAccessTokenKv, - event.identityAccessTokenId, - ); - const identityUniversalAuthId = await getKeyWithFallack( - identityUaKv, - event.identityUniversalAuthId, - ); - const clientSecretId = await getKeyWithFallack( - identityUaClientSecKv, - event.clientSecretId, - ); - return { - ...eventFields, - eventMetadata: { - identityId, - identityAccessTokenId, - identityUniversalAuthId, - clientSecretId, - }, - }; - } - case EventType.ADD_IDENTITY_UNIVERSAL_AUTH: { - const event = doc.event.metadata; - const identityId = await getKeyWithFallack( - identityKv, - event.identityId, - ); - return { - ...eventFields, - eventMetadata: { - ...event, - identityId, - }, - }; - } - case EventType.UPDATE_IDENTITY_UNIVERSAL_AUTH: { - const event = doc.event.metadata; - const identityId = await getKeyWithFallack( - identityKv, - event.identityId, - ); - return { - ...eventFields, - eventMetadata: { - ...event, - identityId, - }, - }; - } - case EventType.GET_IDENTITY_UNIVERSAL_AUTH: { - const event = doc.event.metadata; - const identityId = await getKeyWithFallack( - identityKv, - event.identityId, - ); - return { - ...eventFields, - eventMetadata: { - identityId, - }, - }; - } - case EventType.CREATE_ENVIRONMENT: { - const event = doc.event.metadata; - return { - ...eventFields, - eventMetadata: event, - }; - } - case EventType.UPDATE_ENVIRONMENT: { - const event = doc.event.metadata; - return { - ...eventFields, - eventMetadata: event, - }; - } - case EventType.DELETE_ENVIRONMENT: { - const event = doc.event.metadata; - return { - ...eventFields, - eventMetadata: event, - }; - } - case EventType.ADD_WORKSPACE_MEMBER: { - const event = doc.event.metadata; - const userId = await getKeyWithFallack(userKv, event.userId); - return { ...eventFields, eventMetadata: { ...event, userId } }; - } - case EventType.ADD_BATCH_WORKSPACE_MEMBER: { - const event = doc.event.metadata; - const pgEvent = await Promise.all( - event.flatMap(async ({ userId, email }) => ({ - userId: await getKeyWithFallack(userKv, userId), - email, - })), - ); - return { ...eventFields, eventMetadata: pgEvent }; - } - case EventType.REMOVE_WORKSPACE_MEMBER: { - const event = doc.event.metadata; - const userId = await getKeyWithFallack(userKv, event.userId); - return { ...eventFields, eventMetadata: { ...event, userId } }; - } - case EventType.CREATE_FOLDER: { - const event = doc.event.metadata; - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(event.environment), - ); - const folderId = await getKeyWithFallack( - folderKv as any, - event.folderId, - ); - return { ...eventFields, eventMetadata: { ...event, folderId } }; - } - case EventType.UPDATE_FOLDER: { - const event = doc.event.metadata; - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(event.environment), - ); - const folderId = await getKeyWithFallack( - folderKv as any, - event.folderId, - ); - return { ...eventFields, eventMetadata: { ...event, folderId } }; - } - case EventType.DELETE_FOLDER: { - const event = doc.event.metadata; - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(event.environment), - ); - const folderId = await getKeyWithFallack( - folderKv as any, - event.folderId, - ); - return { ...eventFields, eventMetadata: { ...event, folderId } }; - } - case EventType.CREATE_WEBHOOK: { - const event = doc.event.metadata; - const webhookId = await getKeyWithFallack( - webhookKv, - event.webhookId, - ); - return { ...eventFields, eventMetadata: { ...event, webhookId } }; - } - case EventType.UPDATE_WEBHOOK_STATUS: { - const event = doc.event.metadata; - const webhookId = await getKeyWithFallack( - webhookKv, - event.webhookId, - ); - return { ...eventFields, eventMetadata: { ...event, webhookId } }; - } - case EventType.DELETE_WEBHOOK: { - const event = doc.event.metadata; - const webhookId = await getKeyWithFallack( - webhookKv, - event.webhookId, - ); - return { ...eventFields, eventMetadata: { ...event, webhookId } }; - } - case EventType.CREATE_SECRET_IMPORT: { - const event = doc.event.metadata; - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(event.importToEnvironment), - ); - const folderId = await getKeyWithFallack( - folderKv as any, - event.folderId, - ); - const secretImportId = await getKeyWithFallack( - secretImportKv, - event.secretImportId, - ); - return { - ...eventFields, - eventMetadata: { ...event, folderId, secretImportId }, - }; - } - case EventType.UPDATE_SECRET_IMPORT: { - const event = doc.event.metadata; - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(event.importToEnvironment), - ); - const folderId = await getKeyWithFallack( - folderKv as any, - event.folderId, - ); - const secretImportId = await getKeyWithFallack( - secretImportKv, - event.secretImportId, - ); - return { - ...eventFields, - eventMetadata: { ...event, folderId, secretImportId }, - }; - } - case EventType.DELETE_SECRET_IMPORT: { - const event = doc.event.metadata; - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(event.importToEnvironment), - ); - const folderId = await getKeyWithFallack( - folderKv as any, - event.folderId, - ); - const secretImportId = await getKeyWithFallack( - secretImportKv, - event.secretImportId, - ); - return { - ...eventFields, - eventMetadata: { ...event, folderId, secretImportId }, - }; - } - case EventType.UPDATE_USER_WORKSPACE_ROLE: { - const event = doc.event.metadata; - const userId = await getKeyWithFallack(userKv, event.userId); - return { - ...eventFields, - eventMetadata: { ...event, userId }, - }; - } - case EventType.UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS: { - const event = doc.event.metadata; - const userId = await getKeyWithFallack(userKv, event.userId); - return { - ...eventFields, - eventMetadata: { ...event, userId }, - }; - } - case EventType.SECRET_APPROVAL_MERGED: { - const event = doc.event.metadata; - const secretApprovalRequestId = await getKeyWithFallack( - secretApprovalRequestKv, - event.secretApprovalRequestId, - ); - const mergedBy = await getKeyWithFallack( - projectMembKv, - event.mergedBy, - ); - return { - ...eventFields, - eventMetadata: { ...event, secretApprovalRequestId, mergedBy }, - }; - } - case EventType.SECRET_APPROVAL_REQUEST: { - const event = doc.event.metadata; - const secretApprovalRequestId = await getKeyWithFallack( - secretApprovalRequestKv, - event.secretApprovalRequestId, - ); - const committedBy = await getKeyWithFallack( - projectMembKv, - event.committedBy, - ); - return { - ...eventFields, - eventMetadata: { ...event, secretApprovalRequestId, committedBy }, - }; - } - case EventType.SECRET_APPROVAL_CLOSED: { - const event = doc.event.metadata; - const secretApprovalRequestId = await getKeyWithFallack( - secretApprovalRequestKv, - event.secretApprovalRequestId, - ); - const closedBy = await getKeyWithFallack( - projectMembKv, - event.closedBy, - ); - return { - ...eventFields, - eventMetadata: { ...event, secretApprovalRequestId, closedBy }, - }; - } - case EventType.SECRET_APPROVAL_REOPENED: { - const event = doc.event.metadata; - const secretApprovalRequestId = await getKeyWithFallack( - secretApprovalRequestKv, - event.secretApprovalRequestId, - ); - const reopenedBy = await getKeyWithFallack( - projectMembKv, - event.reopenedBy, - ); - return { - ...eventFields, - eventMetadata: { ...event, secretApprovalRequestId, reopenedBy }, - }; - } - default: { - throw new Error("Unknown field"); - } - } - }, - }); - } catch (error) { - console.error(error); - } - process.exit(0); -}; - -main(); diff --git a/pg-migrator/src/folder.ts b/pg-migrator/src/folder.ts deleted file mode 100644 index ac03d9923..000000000 --- a/pg-migrator/src/folder.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { TFolderSchema } from "./models"; - -export const folderBfsTraversal = async ( - root: TFolderSchema, - callback: ( - data: TFolderSchema & { parentId: string | null }, - ) => void | Promise, -) => { - const queue = [root]; - while (queue.length) { - const folder = queue.pop() as TFolderSchema & { parentId: null }; - callback(folder); - queue.push( - ...folder.children.map((el) => ({ - ...el, - parentId: folder.id, - })), - ); - } -}; - -export const flattenFolders = (folders: TFolderSchema) => { - const flattened: { - id: string; - parentId: string | null; - name: string; - version: number; - }[] = []; - - if(!folders) return [] - - folderBfsTraversal(folders, ({ name, version, parentId, id }) => { - flattened.push({ name, version, parentId, id }); - }); - return flattened; -}; diff --git a/pg-migrator/src/index.ts b/pg-migrator/src/index.ts deleted file mode 100644 index ada5931c6..000000000 --- a/pg-migrator/src/index.ts +++ /dev/null @@ -1,2512 +0,0 @@ -import promptSync from "prompt-sync"; -import mongoose, { Model } from "mongoose"; -import dotenv from "dotenv"; -import knex, { Knex } from "knex"; -import path from "path"; -import { Level } from "level"; -import { packRules } from "@casl/ability/extra"; -import slugify from "@sindresorhus/slugify"; - -import { - APIKeyData, - BackupPrivateKey, - Bot, - BotKey, - BotOrg, - CommitType, - Folder, - FolderVersion, - GitAppInstallationSession, - GitAppOrganizationInstallation, - GitRisks, - Identity, - IdentityAccessToken, - IdentityMembership, - IdentityMembershipOrg, - IdentityUniversalAuth, - IdentityUniversalAuthClientSecret, - IncidentContactOrg, - Integration, - IntegrationAuth, - Key, - Membership, - MembershipOrg, - Organization, - Role, - SSOConfig, - Secret, - SecretApprovalPolicy, - SecretApprovalRequest, - SecretBlindIndexData, - SecretImport, - SecretSnapshot, - SecretVersion, - ServiceTokenData, - Tag, - TrustedIP, - User, - UserAction, - Webhook, - Workspace, -} from "./models"; -import { TableName } from "./schemas"; -import { v4 as uuidV4 } from "uuid"; -import { Tables } from "knex/types/tables"; -import { ServerConfig } from "./models/serverConfig"; -import { flattenFolders } from "./folder"; -import { SecretRotation } from "./models/secretRotation"; - -import { customAlphabet } from "nanoid"; - -const SLUG_ALPHABETS = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -export const alphaNumericNanoId = customAlphabet(SLUG_ALPHABETS, 10); - -enum SecretEncryptionAlgo { - AES_256_GCM = "aes-256-gcm", -} - -const ENV_SLUG_LENGTH = 500; - -enum SecretKeyEncoding { - UTF8 = "utf8", - BASE64 = "base64", - HEX = "hex", -} - -const kdb = new Level("./db", { valueEncoding: "json" }); -const getFolderVersionKey = (folderId: string, version: number) => - `${folderId}:${version}`; - -const projectKv = kdb.sublevel(TableName.Project); -const envPKv = kdb.sublevel(TableName.Environment); - -export const getEnvId = (workspace: string, environment: string) => { - const envKv = envPKv.sublevel(workspace); - return envKv.get(environment); -}; -export const getFolderKv = (workspace: string, environment: string) => { - const envKv = envPKv.sublevel(workspace); - return envKv.sublevel(environment); -}; - -const checkIfFolderIsDangling = async ( - projectId: string, - env_slug: string, - folderId: string, -) => { - const kv = getFolderKv(projectId, truncateAndSlugify(env_slug)); - const result = await kv.get(`${folderId}:dead`).catch(() => null); - return Boolean(result); -}; - -const migrationCheckPointsKv = kdb.sublevel("CHECK-POINTS"); - -export const truncateAndSlugify = (slug: string): string => { - return slugify(slug.slice(0, ENV_SLUG_LENGTH)); -}; - -/** - * Sorts an array of items into groups. The return value is a map where the keys are - * the group ids the given getGroupId function produced and the value is an array of - * each item in that group. - */ -export const groupBy = ( - array: readonly T[], - getGroupId: (item: T) => Key, -): Record => - array.reduce( - (acc, item) => { - const groupId = getGroupId(item); - if (!acc[groupId]) acc[groupId] = []; - acc[groupId].push(item); - return acc; - }, - {} as Record, - ); - -export const migrateCollection = async < - T extends {}, - K extends keyof Tables, - R extends (keyof Tables[K]["base"])[] = [], ->({ - db, - postPgProcessing, - preProcessing, - mongooseCollection, - postgresTableName, - returnKeys, - filter, -}: { - db: Knex; - returnKeys: R; - postPgProcessing?: ( - preData: T[], - data: Pick[], - ) => void | Promise; - preProcessing: ( - data: T, - ) => - | Tables[K]["base"] - | Tables[K]["base"][] - | Promise - | undefined; - postgresTableName: K; - mongooseCollection: Model; - filter?: Record; -}) => { - // check ones that have already been migrated - const migrationCheckPointsKvRes = await migrationCheckPointsKv - .get(`${postgresTableName}-${mongooseCollection.modelName}`) - .catch(() => null); - - if (migrationCheckPointsKvRes) { - console.log( - `Skipping Postgres table '${postgresTableName}' because of check point`, - ); - return; - } - - const mongooseDoc: T[] = []; - const pgDoc: Tables[K]["base"][] = []; // pre processed data ready to be inserted into PSQL - - console.log( - "Starting migration of ", - mongooseCollection.modelName, - " Postgres table name:", - postgresTableName, - ); - const totalMongoCount = - postgresTableName === TableName.AuditLog - ? await mongooseCollection.estimatedDocumentCount() // this is because audit log is too big - : await mongooseCollection.countDocuments(); - - console.log("Total documents", totalMongoCount); - console.log("Total batches", Math.ceil(totalMongoCount / 1000)); - let batch = 1; - - for await (const doc of mongooseCollection - .find(filter || {}) - .cursor({ batchSize: 100 })) { - mongooseDoc.push(doc); - const preProcessedData = await preProcessing( - doc.toObject({ virtuals: true }), - ); - if (preProcessedData) { - if (Array.isArray(preProcessedData)) { - pgDoc.push( - ...(preProcessedData.filter(Boolean) as Tables[K]["base"][]), - ); - } else { - pgDoc.push(preProcessedData); - } - } - if (mongooseDoc.length >= 1000) { - console.log("Batch No.:", batch); - if (!pgDoc.length) - console.log("Skipping this batch due to empty pre processor", batch); - if (pgDoc.length) { - const newUserIds = await db.transaction(async (tx) => { - return (await tx - .batchInsert(postgresTableName, pgDoc as any) - .returning(returnKeys as any)) as Pick< - Tables[K]["base"], - R[number] - >[]; - }); - await postPgProcessing?.(mongooseDoc, newUserIds); - } - batch += 1; - mongooseDoc.splice(0, mongooseDoc.length); - pgDoc.splice(0, pgDoc.length); - } - } - if (mongooseDoc.length) { - console.log("Batch No.:", batch); - if (!pgDoc.length) - console.log("Skipping this batch due to empty pre processor", batch); - if (pgDoc.length) { - const newUserIds = await db.transaction(async (tx) => { - return (await tx - .batchInsert(postgresTableName, pgDoc as any) - .returning(returnKeys as any)) as Pick< - Tables[K]["base"], - R[number] - >[]; - }); - await postPgProcessing?.(mongooseDoc, newUserIds); - } - batch += 1; - mongooseDoc.splice(0, mongooseDoc.length); - pgDoc.splice(0, pgDoc.length); - } - - migrationCheckPointsKv.put( - `${postgresTableName}-${mongooseCollection.modelName}`, - "done", - ); - - console.log( - "Finished migration of ", - mongooseCollection.modelName, - " Postgres table name:", - postgresTableName, - ); -}; - -const main = async () => { - try { - dotenv.config(); - - // process.env.MONGO_DB_URL = "mongodb://root:example@localhost:27017/test?authSource=admin" - - // process.env.POSTGRES_DB_URL = "postgres://infisical:infisical@localhost/infisical?sslmode=disable" - - process.env.START_FRESH = "true"; - const prompt = promptSync({ sigint: true }); - - let mongodb_url = process.env.MONGO_DB_URL; - if (!mongodb_url) { - mongodb_url = prompt("Type the mongodb url: "); - } - console.log("Checking mongoose connection..."); - await mongoose.connect(mongodb_url); - console.log("Connected successfully to mongo"); - - let postgres_url = process.env.POSTGRES_DB_URL; - if (!postgres_url) { - postgres_url = prompt("Type the postgres url: "); - } - - console.log("Checking postgres connection..."); - const db = knex({ - client: "pg", - connection: postgres_url, - migrations: { - directory: path.join(__dirname, "../../backend/src/db/migrations"), - extension: "ts", - tableName: "infisical_migrations", - }, - }); - console.log("Connected successfully to postgres"); - await db.raw("select 1+1 as result"); - - if (process.env.START_FRESH === "true") { - await migrationCheckPointsKv.clear(); - - console.log("Starting rolling back to latest, comment this out later"); - await db.migrate.rollback({}, true); - await kdb.clear(); - console.log("Rolling back completed"); - - console.log("Executing migration"); - await db.migrate.latest(); - console.log("Completed migration"); - } - - const userKv = kdb.sublevel(TableName.Users); - await migrateCollection({ - db, - mongooseCollection: User, - postgresTableName: TableName.Users, - returnKeys: ["id", "email"], - preProcessing: async (doc) => { - if (["64058e0ea5c55c6a8203fed7", "64155f5d75c91bf4e176eb85", "6434ff80b82e04f17008aa13"].includes(doc._id.toString())) { - console.log("Skipping duplicate user") - return - } - - const id = uuidV4(); - await userKv.put(doc.id.toString(), id); - - return { - id, - firstName: doc.firstName, - email: doc.email, - devices: JSON.stringify(doc.devices), - lastName: doc.lastName, - isAccepted: Boolean(doc.publicKey), - superAdmin: doc.superAdmin, - authMethods: doc.authMethods, - isMfaEnabled: doc.isMfaEnabled, - createdAt: new Date(doc.createdAt), - updatedAt: new Date(doc.updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: User, - postgresTableName: TableName.UserEncryptionKey, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - if (!doc.publicKey || !doc.encryptedPrivateKey || !doc.iv) return; - const userId = await userKv.get(doc.id.toString()).catch(() => null); - if (!userId) return; - - return { - id, - iv: doc.iv, - tag: doc.tag as string, - salt: doc.salt as string, - verifier: doc.verifier as string, - publicKey: doc.publicKey, - userId, - protectedKey: doc.protectedKey as string, - protectedKeyIV: doc.protectedKeyIV as string, - protectedKeyTag: doc.protectedKeyTag as string, - encryptedPrivateKey: doc.encryptedPrivateKey as string, - encryptionVersion: doc.encryptionVersion as number, - // for change password - clientPublicKey: null, - serverPrivateKey: null, - }; - }, - }); - // skipping user auth token and token sessions - // lets reset and ask users to login - - await migrateCollection({ - db, - mongooseCollection: BackupPrivateKey, - postgresTableName: TableName.BackupPrivateKey, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const userId = await userKv.get(doc.user.toString()).catch(() => null); - if (!userId) return; - - return { - id, - encryptedPrivateKey: doc.encryptedPrivateKey, - userId, - verifier: doc.verifier, - salt: doc.salt, - tag: doc.tag, - iv: doc.iv, - algorithm: SecretEncryptionAlgo.AES_256_GCM, - keyEncoding: SecretKeyEncoding.UTF8, - createdAt: new Date(doc.createdAt), - updatedAt: new Date(doc.updatedAt), - }; - }, - }); - - const orgKv = kdb.sublevel(TableName.Organization); - await migrateCollection({ - db, - mongooseCollection: Organization, - postgresTableName: TableName.Organization, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - await orgKv.put(doc._id.toString(), id); - return { - id, - name: doc.name, - slug: slugify(`${doc.name}-${alphaNumericNanoId(4)}`), - customerId: doc.customerId, - createdAt: new Date(doc.createdAt), - updatedAt: new Date(doc.updatedAt), - }; - }, - }); - - const orgRoleKv = kdb.sublevel(TableName.OrgRoles); - await migrateCollection({ - db, - filter: { isOrgRole: true }, - mongooseCollection: Role, - postgresTableName: TableName.OrgRoles, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - await orgRoleKv.put(doc._id.toString(), id); - return { - id, - name: doc.name, - orgId, - description: doc.description, - slug: truncateAndSlugify(doc.slug), - permissions: doc.permissions - ? JSON.stringify(packRules(doc.permissions as any)) - : null, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: MembershipOrg, - postgresTableName: TableName.OrgMembership, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - const userId = doc?.user - ? await userKv.get(doc.user.toString()).catch(() => null) - : null; - if (!userId) return; - - const roleId = doc.customRole - ? await orgRoleKv.get(doc.customRole.toString()) - : null; - - return { - id, - role: doc.role, - orgId, - roleId, - userId, - status: doc.status, - inviteEmail: doc.inviteEmail, - createdAt: new Date(doc.createdAt), - updatedAt: new Date(doc.updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: IncidentContactOrg, - postgresTableName: TableName.IncidentContact, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - return { - id, - email: doc.email, - orgId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: UserAction, - postgresTableName: TableName.UserAction, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const userId = await userKv.get(doc.user.toString()).catch(() => null); - if (!userId) return; - - return { - id, - userId, - action: doc.action, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: ServerConfig, - postgresTableName: TableName.SuperAdmin, - returnKeys: ["id"], - preProcessing: async (doc) => { - return { - id: "00000000-0000-0000-0000-000000000000", - allowSignUp: doc.allowSignUp, - initialized: doc.initialized, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: APIKeyData, - postgresTableName: TableName.ApiKey, - returnKeys: ["id"], - preProcessing: async (doc) => { - const userId = await userKv.get(doc.user.toString()).catch(() => null); - if (!userId) return; - - // expired tokens can be removed - if (new Date(doc.expiresAt) < new Date()) return; - return { - id: doc._id.toString(), - userId, - name: doc.name, - lastUsed: doc.lastUsed, - secretHash: doc.secretHash, - expiresAt: doc.expiresAt, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: Workspace, - postgresTableName: TableName.Project, - returnKeys: ["id"], - preProcessing: async (doc) => { - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - await projectKv.put(doc._id.toString(), doc._id.toString()); - - // expired tokens can be removed - // cannot use this uuid for the org id - return { - id: doc._id.toString(), - name: doc.name.slice(0, 60), - slug: slugify(`${doc.name.slice(0, 60)}-${alphaNumericNanoId(4)}`), - orgId, - autoCapitalization: doc.autoCapitalization, - createdAt: new Date(), - updatedAt: new Date(), - }; - }, - }); - - console.log( - "Migrating environments from Mongo Project -> Pg Environment Table", - ); - const envPKv = kdb.sublevel(TableName.Environment); - - const getEnvId = async (workspace: string, environment: string) => { - const envKv = envPKv.sublevel(workspace); - return envKv.get(environment); - }; - const getFolderKv = (workspace: string, environment: string) => { - const envKv = envPKv.sublevel(workspace); - return envKv.sublevel(environment); - }; - - await migrateCollection({ - db, - mongooseCollection: Workspace, - postgresTableName: TableName.Environment, - returnKeys: ["id"], - preProcessing: async (doc) => { - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - const projectKvRes = await projectKv - .get(doc._id.toString()) - .catch(() => null); - if (!projectKvRes) return; - - // to we scope environments into each project then map each slug with respective id - const envKv = envPKv.sublevel(doc._id.toString()); - - // expired tokens can be removed - // cannot use this uuid for the org id - return Promise.all( - doc.environments.map(async (env, index) => { - const id = uuidV4(); - await envKv.put(truncateAndSlugify(env.slug), id); - return { - id, - name: env.name, - slug: truncateAndSlugify(env.slug), - position: index + 1, - projectId: doc._id.toString(), - createdAt: new Date(), - updatedAt: new Date(), - }; - }), - ); - }, - }); - - console.log("Creating root folders for all environments"); - await migrateCollection({ - db, - mongooseCollection: Workspace, - postgresTableName: TableName.SecretFolder, - returnKeys: ["id"], - preProcessing: async (doc) => { - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - let results = []; - for (const env of doc.environments) { - const id = uuidV4(); - - // case: we forgot to clean up folders that belong to deleted env slugs - const isEnvFound = await getEnvId( - doc._id.toString(), - truncateAndSlugify(env.slug), - ).catch(() => null); - - if (!isEnvFound) continue; - - const envId = await getEnvId( - doc._id.toString(), - truncateAndSlugify(env.slug), - ); - - const folderKv = getFolderKv( - doc._id.toString(), - truncateAndSlugify(env.slug), - ); - - await folderKv.put("root", id); - results.push({ - id, - name: "root", - envId, - version: 1, - createdAt: new Date(), - updatedAt: new Date(), - }); - } - - return results; - }, - }); - - const projectKeyKv = kdb.sublevel(TableName.ProjectKeys); - await migrateCollection({ - db, - mongooseCollection: Key, - postgresTableName: TableName.ProjectKeys, - returnKeys: ["id"], - preProcessing: async (doc) => { - // expired tokens can be removed - // cannot use this uuid for the org id - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const id = uuidV4(); - await projectKeyKv.put(doc._id.toString(), id); - - const senderId = await userKv - .get(doc.sender.toString()) - .catch(() => null); - if (!senderId) return; - - const receiverId = await userKv - .get(doc.receiver.toString()) - .catch(() => null); - if (!receiverId) return; - - return { - id, - projectId: doc.workspace.toString(), - senderId, - nonce: doc.nonce, - encryptedKey: doc.encryptedKey, - receiverId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - console.log("Migrating roles from Mongo Project -> Pg Project Role Table"); - const projectRoleKv = kdb.sublevel(TableName.ProjectRoles); - await migrateCollection({ - db, - filter: { isOrgRole: false }, - mongooseCollection: Role, - postgresTableName: TableName.ProjectRoles, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - await projectRoleKv.put(doc._id.toString(), id); - return { - id, - name: doc.name, - projectId: doc.workspace.toString(), - description: doc.description, - slug: truncateAndSlugify(doc.slug), - permissions: doc.permissions - ? JSON.stringify(packRules(doc.permissions as any)) - : null, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const projectMembKv = kdb.sublevel(TableName.ProjectMembership); - await migrateCollection({ - db, - mongooseCollection: Membership, - postgresTableName: TableName.ProjectMembership, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const userId = await userKv.get(doc.user.toString()).catch(() => null); - if (!userId) return; - - const roleId = doc.customRole - ? await projectRoleKv.get(doc.customRole.toString()) - : null; - await projectMembKv.put(doc._id.toString(), id); - - return { - id, - role: doc.role, - roleId, - projectId: doc.workspace.toString(), - userId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: Folder, - postgresTableName: TableName.SecretFolder, - returnKeys: ["id"], - preProcessing: async (doc) => { - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - // case: we forgot to clean up folders that belong to deleted env slugs - const isEnvFound = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ).catch(() => null); - - if (!isEnvFound) return; - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - const folders = flattenFolders(doc.nodes); - if (!folders) return; - - const pgFolder = []; - for (const folder of folders) { - if (folder.id !== "root") { - const { name, version } = folder; - const id = uuidV4(); - await folderKv.put(folder.id, id); - const parentId = folder?.parentId - ? await folderKv.get(folder?.parentId).catch((e) => { - console.log("parent folder not found==>", folder); - throw e; - }) - : null; - - pgFolder.push({ - name, - version, - id, - parentId, - envId, - createdAt: (doc as any).createdAt, - updatedAt: (doc as any).updatedAt, - }); - } - } - - return pgFolder; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: FolderVersion, - postgresTableName: TableName.SecretFolderVersion, - returnKeys: ["id"], - preProcessing: async (doc) => { - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - // looping through env, we can come across envs that do not exist in the present state. - // This is because some folder snap shots were taken when that env slug exists but the same env slug was later deleted - let envId: string; - try { - const isEnvFound = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ).catch(() => null); - if (!isEnvFound) return; - - envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - } catch (e) { - return; - } - - const rootFolders = (doc?.nodes?.children || []).map( - ({ name, version, id }) => ({ - name, - version, - id, - }), - ); - - const pgFolder = await Promise.all( - rootFolders.map(async (folder) => { - const { name, version } = folder; - const id = uuidV4(); - - await folderKv.put(getFolderVersionKey(folder.id, version), id); - - // we are looking for each folder in folder versions and some we might not see - // because folderKv is ony keeps track of folders that are present in dashboard. So those we don't find, we'll add to same kv but add prefix `dead`. - // This way, we can handle dead ones we encounter in the future - const folderId = await folderKv.get(folder.id).catch(async () => { - const newFolderId = uuidV4(); - await folderKv.put(`${folder.id}:dead`, id); // we are adding dead folders that are not present in dashboard - return newFolderId; - }); - - return { - name, - version, - id, - folderId, - envId, - createdAt: (doc as any).createdAt, - updatedAt: (doc as any).updatedAt, - }; - }), - ); - - return pgFolder; - }, - }); - - const secretImportKv = kdb.sublevel(TableName.SecretImport); - await migrateCollection({ - db, - mongooseCollection: SecretImport, - postgresTableName: TableName.SecretImport, - returnKeys: ["id"], - preProcessing: async (doc) => { - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const envKv = envPKv.sublevel(doc.workspace.toString()); - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - if ( - await checkIfFolderIsDangling( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - doc.folderId, - ) - ) { - return; - } - - // case: when import is created for a given folder and later the folder is deleted AND the import with that folder ref is not deleted THEN this folder won't exist?? :( - const folderId = await folderKv.get(doc.folderId).catch(() => null); - - if (!folderId) return; - - return Promise.all( - doc.imports - .map(async ({ environment, secretPath }, index) => { - const id = uuidV4(); - // case: when import is created but later the env slug is deleted HOWEVER the import with that env slug was not deleted :( - const importEnv = await envKv - .get(truncateAndSlugify(environment)) - .catch(() => null); - if (!importEnv) return; - - return { - id, - folderId, - position: index + 1, - version: 1, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - importEnv, - importPath: secretPath, - }; - }) - .filter(Boolean), - ); - }, - }); - - const tagKv = kdb.sublevel(TableName.SecretTag); - await migrateCollection({ - db, - mongooseCollection: Tag, - postgresTableName: TableName.SecretTag, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - await tagKv.put(doc._id.toString(), id); - - // skip tags that have slugs that are empty - if (doc.slug.length < 1) { - return; - } - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const createdBy = await userKv - .get(doc.user.toString()) - .catch(() => null); - if (!createdBy) return; - - return { - id, - name: doc.name, - slug: truncateAndSlugify(doc.slug), - color: doc.tagColor, - projectId: doc.workspace.toString(), - createdBy: createdBy || null, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: SecretBlindIndexData, - postgresTableName: TableName.SecretBlindIndex, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - return { - id, - projectId: doc.workspace.toString(), - saltIV: doc.saltIV, - saltTag: doc.saltTag, - algorithm: doc.algorithm, - keyEncoding: doc.keyEncoding, - encryptedSaltCipherText: doc.encryptedSaltCiphertext, - createdAt: new Date(), - updatedAt: new Date(), - }; - }, - }); - - const secKv = kdb.sublevel(TableName.Secret); - await migrateCollection({ - db, - mongooseCollection: Secret, - postgresTableName: TableName.Secret, - returnKeys: ["id"], - preProcessing: async (doc) => { - // when env slug is empty - if (doc.environment.length < 1) { - return; - } - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - // case: we forgot to clean up secrets that belong to deleted env slugs - const isEnvFound = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ).catch(() => null); - if (!isEnvFound) return; - - if ( - await checkIfFolderIsDangling( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - doc.folder as string, - ) - ) { - return; - } - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - // Case: if folder id doesn't exist and the root of the folder also doesn;t exist, THEN put the secret at the ROOT - // case: after deleting a folder, we don't clean up the secrets that link to that folder - const folderId = await folderKv - .get(doc.folder || "root") - .catch(() => null); - - // case: when environments are renamed, there used to be a TIMEE when the related folder's slugs weren't updated with it... :( - if (!folderId) return; - - // issue with personal - const userId = doc.user - ? await userKv.get(doc.user.toString()).catch(() => null) - : null; - - if (doc.type === "personal" && !userId) return; - - const id = uuidV4(); - await secKv.put(doc._id.toString(), id); - - return { - id, - keyEncoding: doc.keyEncoding, - algorithm: doc.algorithm, - folderId, - type: doc.type, - version: doc.version, - secretReminderRepeatDays: doc.secretReminderRepeatDays, - userId, - metadata: doc.metadata, - secretKeyIV: doc.secretKeyIV, - secretKeyTag: doc.secretKeyTag, - secretKeyCiphertext: doc.secretKeyCiphertext, - secretValueIV: doc.secretValueIV, - secretValueTag: doc.secretValueTag, - secretValueCiphertext: doc.secretValueCiphertext, - secretBlindIndex: doc.secretBlindIndex, - secretCommentIV: doc.secretCommentIV, - secretCommentTag: doc.secretCommentTag, - secretCommentCiphertext: doc.secretCommentCiphertext, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - console.log( - "Migrating secret tags from Mongo Secret.tags -> Pg SecretTag table", - ); - await migrateCollection({ - db, - mongooseCollection: Secret, - postgresTableName: TableName.JnSecretTag, - returnKeys: ["id"], - preProcessing: async (doc) => { - return Promise.all( - (doc.tags || [])?.map(async (tagId) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - // case: we forgot to clean up secrets that belong to deleted env slugs - const isEnvFound = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ).catch(() => null); - if (!isEnvFound) return; - - if ( - await checkIfFolderIsDangling( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - doc.folder as string, - ) - ) { - return; - } - - // const userId = doc.user - // ? await userKv.get(doc.user.toString()).catch(() => null) - // : null; - // if (!userId) return; - - const secretId = await secKv.get(doc._id.toString()).catch((e) => { - throw e; - }); - const secretTagId = await tagKv.get(tagId).catch((e) => { - throw e; - }); - return { - id, - [`${TableName.Secret}Id`]: secretId, - [`${TableName.SecretTag}Id`]: secretTagId, - // createdAt: new Date((doc as any).createdAt), - // updatedAt: new Date((doc as any).updatedAt), - }; - }), - ); - }, - }); - - const secVerKv = kdb.sublevel(TableName.SecretVersion); - await migrateCollection({ - db, - mongooseCollection: SecretVersion, - postgresTableName: TableName.SecretVersion, - returnKeys: ["id"], - preProcessing: async (doc) => { - // when env slug is empty - if (doc.environment.length < 1) { - return; - } - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - // case: we forgot to clean up secrets that belong to deleted env slugs - const isEnvFound = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ).catch(() => null); - if (!isEnvFound) return; - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - if ( - await checkIfFolderIsDangling( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - doc.folder as string, - ) - ) { - return; - } - - // Case: if folder id doesn't exist and the root of the folder also doesn;t exist, THEN put the secret at the ROOT - const folderId = await folderKv - .get(doc.folder || "root") - .catch(async () => { - console.log( - "secret location unknown, moving secret to root of env_slug/project", - ); - return await folderKv.get("root"); - }); - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - const userId = doc.user - ? await userKv.get(doc.user.toString()).catch(() => null) - : null; - if (!userId && doc.type === "personal") return; - - const id = uuidV4(); - await secVerKv.put(doc._id.toString(), id); - const secretId = await secKv - .get(doc.secret.toString()) - .catch(async (e) => { - const newId = uuidV4(); - await secKv.put(`${doc.secret.toString()}:dead`, newId); - return newId; - }); - - // comment and reminder are not saved in secret version of mongo - return { - id, - keyEncoding: doc.keyEncoding, - algorithm: doc.algorithm, - folderId, - envId, - type: doc.type, - version: doc.version, - userId, - secretId, - secretKeyIV: doc.secretKeyIV, - secretKeyTag: doc.secretKeyTag, - secretKeyCiphertext: doc.secretKeyCiphertext, - secretValueIV: doc.secretValueIV, - secretValueTag: doc.secretValueTag, - secretValueCiphertext: doc.secretValueCiphertext, - secretBlindIndex: doc.secretBlindIndex, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const projectBotKv = kdb.sublevel(TableName.ProjectBot); - await migrateCollection({ - db, - mongooseCollection: Bot, - postgresTableName: TableName.ProjectBot, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - // if we try to process two bots for the same workspace, then skip - if ( - await projectBotKv.get(doc.workspace.toString()).catch(() => null) - ) { - return; - } - - await projectBotKv.put(doc.workspace.toString(), id); - - // case: skip bots that are inactive (skipped specifically because 6388653a200193a667c7e3f3 has two records, one active one not) - let bot = await Bot.findOne({ - workspace: doc.workspace, - $or: [{ isActive: true }, { isActive: false }], - }) - .sort({ isActive: -1 }) - .lean(); - - // case: when no bots are found for this project, skip - if (!bot) return; - - const botKey = await BotKey.findOne({ bot: bot?._id }); - - const senderId = botKey?.sender - ? await userKv.get(botKey.sender.toString()).catch(() => null) - : null; - - if (!senderId) return; - - return { - id, - algorithm: bot.algorithm, - keyEncoding: bot.keyEncoding, - projectId: bot.workspace.toString(), - name: bot.name, - iv: bot.iv, - tag: bot.tag, - senderId, - isActive: bot.isActive, - publicKey: bot.publicKey, - encryptedProjectKey: botKey?.encryptedKey || null, - encryptedProjectKeyNonce: botKey?.nonce || null, - encryptedPrivateKey: bot.encryptedPrivateKey, - createdAt: new Date((bot as any).createdAt), - updatedAt: new Date((bot as any).updatedAt), - }; - }, - }); - - const integrationAuthKv = kdb.sublevel(TableName.IntegrationAuth); - await migrateCollection({ - db, - mongooseCollection: IntegrationAuth, - postgresTableName: TableName.IntegrationAuth, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - await integrationAuthKv.put(doc._id.toString(), id); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - return { - id, - projectId: doc.workspace.toString(), - keyEncoding: doc.keyEncoding || SecretKeyEncoding.UTF8, - algorithm: doc.algorithm || SecretEncryptionAlgo.AES_256_GCM, - metadata: doc.metadata, - url: doc.url, - teamId: doc.teamId, - accessIV: doc.accessIV, - accessTag: doc.accessTag, - accessCiphertext: doc.accessCiphertext, - accountId: doc.accountId, - namespace: doc.namespace, - refreshIV: doc.refreshIV, - refreshTag: doc.refreshTag, - refreshCiphertext: doc.refreshCiphertext, - integration: doc.integration, - accessIdIV: doc.accessIdIV, - accessIdTag: doc.accessIdTag, - accessIdCiphertext: doc.accessIdCiphertext, - accessExpiresAt: doc.accessExpiresAt, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const integrationKv = kdb.sublevel(TableName.Integration); - await migrateCollection({ - db, - mongooseCollection: Integration, - postgresTableName: TableName.Integration, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - const integrationAuthId = await integrationAuthKv.get( - doc.integrationAuth.toString(), - ); - await integrationKv.put(doc._id.toString(), id); - - return { - id, - integration: doc.integration, - url: doc.url, - metadata: doc.metadata, - isActive: doc.isActive, - secretPath: doc.secretPath, - integrationAuthId, - app: doc.app, - envId, - path: doc.path, - appId: doc.appId, - owner: doc.owner, - scope: doc.scope, - region: doc.region, - targetService: doc.targetService, - targetServiceId: doc.targetServiceId, - targetEnvironment: doc.targetEnvironment, - targetEnvironmentId: doc.targetEnvironmentId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: ServiceTokenData, - postgresTableName: TableName.ServiceToken, - returnKeys: ["id"], - preProcessing: async (doc) => { - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const userId = await userKv.get(doc.user.toString()).catch(() => null); - if (!userId) return; - - return { - id: doc._id.toString(), - projectId: doc.workspace.toString(), - name: doc.name, - createdBy: userId, - iv: doc.iv, - tag: doc.tag, - scopes: JSON.stringify(doc.scopes), - lastUsed: doc.lastUsed, - secretHash: doc.secretHash, - expiresAt: doc.expiresAt, - permissions: doc.permissions, - encryptedKey: doc.encryptedKey, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const webhookKv = kdb.sublevel(TableName.Webhook); - await migrateCollection({ - db, - mongooseCollection: Webhook, - postgresTableName: TableName.Webhook, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - await webhookKv.put(doc._id.toString(), id); - return { - id, - iv: doc.iv, - envId, - secretPath: doc.secretPath, - url: doc.url, - algorithm: doc.algorithm || SecretEncryptionAlgo.AES_256_GCM, - keyEncoding: doc.keyEncoding || SecretKeyEncoding.UTF8, - tag: doc.tag, - isDisabled: doc.isDisabled, - lastStatus: doc.lastStatus, - encryptedSecretKey: doc.encryptedSecretKey, - lastRunErrorMessage: doc.lastRunErrorMessage, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const identityKv = kdb.sublevel(TableName.Identity); - await migrateCollection({ - db, - mongooseCollection: Identity, - postgresTableName: TableName.Identity, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - await identityKv.put(doc._id.toString(), id); - return { - id, - name: doc.name, - authMethod: doc.authMethod, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const identityUaKv = kdb.sublevel(TableName.IdentityUniversalAuth); - await migrateCollection({ - db, - mongooseCollection: IdentityUniversalAuth, - postgresTableName: TableName.IdentityUniversalAuth, - returnKeys: ["id"], - preProcessing: async (doc) => { - // dangling identity - if (!await identityKv.get(doc.identity.toString()).catch(() => null)) { - return - } - - const id = uuidV4(); - const identityId = await identityKv.get(doc.identity.toString()); - await identityUaKv.put(doc._id.toString(), id); - return { - id, - identityId, - clientId: doc.clientId, - accessTokenTTL: doc.accessTokenTTL, - accessTokenMaxTTL: doc.accessTokenMaxTTL, - accessTokenTrustedIps: JSON.stringify( - doc.accessTokenTrustedIps || [], - ), - accessTokenNumUsesLimit: doc.accessTokenNumUsesLimit, - clientSecretTrustedIps: JSON.stringify( - doc.clientSecretTrustedIps || [], - ), - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const identityUaClientSecKv = kdb.sublevel( - TableName.IdentityUaClientSecret, - ); - await migrateCollection({ - db, - mongooseCollection: IdentityUniversalAuthClientSecret, - postgresTableName: TableName.IdentityUaClientSecret, - returnKeys: ["id"], - preProcessing: async (doc) => { - // dangling identity - if (!await identityKv.get(doc.identity.toString()).catch(() => null)) { - return - } - - const identityUAId = await identityUaKv.get( - doc.identityUniversalAuth.toString(), - ); - await identityUaClientSecKv.put(doc._id.toString(), doc._id.toString()); - return { - id: doc._id.toString(), - identityUAId, - description: doc.description, - clientSecretTTL: doc.clientSecretTTL, - clientSecretHash: doc.clientSecretHash, - clientSecretPrefix: doc.clientSecretPrefix, - clientSecretNumUses: doc.clientSecretNumUses, - isClientSecretRevoked: doc.isClientSecretRevoked, - clientSecretLastUsedAt: doc.clientSecretLastUsedAt, - clientSecretNumUsesLimit: doc.clientSecretNumUsesLimit, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const identityAccessTokenKv = kdb.sublevel(TableName.IdentityAccessToken); - await migrateCollection({ - db, - mongooseCollection: IdentityAccessToken, - postgresTableName: TableName.IdentityAccessToken, - returnKeys: ["id"], - preProcessing: async (doc) => { - // dangling identity - if (!await identityKv.get(doc.identity.toString()).catch(() => null)) { - return - } - - await identityAccessTokenKv.put(doc._id.toString(), doc._id.toString()); - const identityUAClientSecretId = doc?.identityUniversalAuthClientSecret - ? await identityUaClientSecKv.get( - doc.identityUniversalAuthClientSecret.toString(), - ) - : null; - const identityId = await identityKv.get(doc.identity.toString()); - return { - id: doc._id.toString(), - accessTokenNumUsesLimit: doc.accessTokenNumUsesLimit, - accessTokenMaxTTL: doc.accessTokenMaxTTL, - accessTokenTTL: doc.accessTokenTTL, - identityId, - accessTokenNumUses: doc.accessTokenNumUses, - isAccessTokenRevoked: doc.isAccessTokenRevoked, - accessTokenLastUsedAt: doc.accessTokenLastUsedAt, - accessTokenLastRenewedAt: doc.accessTokenLastRenewedAt, - identityUAClientSecretId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: IdentityMembershipOrg, - postgresTableName: TableName.IdentityOrgMembership, - returnKeys: ["id"], - preProcessing: async (doc) => { - // dangling identity - if (!await identityKv.get(doc.identity.toString()).catch(() => null)) { - return - } - - const id = uuidV4(); - - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - const identityId = await identityKv.get(doc.identity.toString()); - const roleId = doc.customRole - ? await orgRoleKv.get(doc.customRole.toString()) - : null; - - return { - id, - role: doc.role, - orgId, - identityId, - roleId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: IdentityMembership, - postgresTableName: TableName.IdentityProjectMembership, - returnKeys: ["id"], - preProcessing: async (doc) => { - // dangling identity - if (!await identityKv.get(doc.identity.toString()).catch(() => null)) { - return - } - - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const identityId = await identityKv.get(doc.identity.toString()); - const roleId = doc.customRole - ? await projectRoleKv.get(doc.customRole.toString()) - : null; - - return { - id, - role: doc.role, - identityId, - projectId: doc.workspace.toString(), - roleId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const sapKv = kdb.sublevel(TableName.SecretApprovalPolicy); - await migrateCollection({ - db, - mongooseCollection: SecretApprovalPolicy, - postgresTableName: TableName.SecretApprovalPolicy, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - await sapKv.put(doc._id.toString(), id); - - return { - id, - name: doc.name, - envId, - approvals: doc.approvals, - secretPath: doc.secretPath, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - console.log( - "Migration secret approval policy approvers -> Pg sap approvers table", - ); - await migrateCollection({ - db, - mongooseCollection: SecretApprovalPolicy, - postgresTableName: TableName.SecretApprovalPolicyApprover, - returnKeys: ["id"], - preProcessing: async (doc) => { - const policyId = await sapKv.get(doc._id.toString()); - - return Promise.all( - doc.approvers.map(async (membId) => { - const id = uuidV4(); - const approverId = await projectMembKv.get(membId.toString()); - return { - id, - policyId, - approverId, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }), - ); - }, - }); - - const secRotationKv = kdb.sublevel(TableName.SecretRotation); - await migrateCollection({ - db, - mongooseCollection: SecretRotation, - postgresTableName: TableName.SecretRotation, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - await secRotationKv.put(doc._id.toString(), id); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - return { - id, - envId, - keyEncoding: doc.keyEncoding, - algorithm: doc.algorithm, - secretPath: doc.secretPath, - status: doc.status, - interval: doc.interval, - provider: doc.provider, - encryptedData: doc.encryptedData, - encryptedDataIV: doc.encryptedDataIV, - encryptedDataTag: doc.encryptedDataTag, - lastRotatedAt: doc.lastRotatedAt ? new Date(doc.lastRotatedAt) : null, - statusMessage: doc.statusMessage, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - console.log( - "Migration secret rotation outputs from mongo to postgres secret rotation output table", - ); - await migrateCollection({ - db, - mongooseCollection: SecretRotation, - postgresTableName: TableName.SecretRotationOutput, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - const rotationId = await secRotationKv.get(doc._id.toString()); - - return Promise.all( - doc.outputs.map(async ({ key, secret }) => { - const secretId = await secKv - .get(secret.toString()) - .catch(() => null); - if (!secretId) return; - - return { - id, - key, - secretId, - rotationId, - }; - }), - ); - }, - }); - - const ssoConfigKv = kdb.sublevel(TableName.SamlConfig); - await migrateCollection({ - db, - mongooseCollection: SSOConfig, - postgresTableName: TableName.SamlConfig, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - // case: when a org has two SSO configs, one with encryptedEntryPoint defined should be taken. Others skipped - if (!doc.encryptedEntryPoint) { - return; - } - - await ssoConfigKv.put(orgId.toString(), "true"); - - return { - id, - isActive: doc.isActive, - orgId, - certIV: doc.certIV, - certTag: doc.certTag, - issuerIV: doc.issuerIV, - issuerTag: doc.issuerTag, - authProvider: doc.authProvider, - entryPointIV: doc.entryPointIV, - entryPointTag: doc.entryPointTag, - encryptedEntryPoint: doc.encryptedEntryPoint, - encryptedCert: doc.encryptedCert, - encryptedIssuer: doc.encryptedIssuer, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const botOrgsProcessed = kdb.sublevel(TableName.OrgBot); - await migrateCollection({ - db, - mongooseCollection: BotOrg, - postgresTableName: TableName.OrgBot, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - // case: race condition where there are multiple org bots, we only take one - const botOrgsProcessedRes = await botOrgsProcessed - .get(orgId) - .catch(() => null); - if (botOrgsProcessedRes) { - return; - } - - const ssoConfigRes = await ssoConfigKv.get(orgId).catch(() => null); - if (!ssoConfigRes) { - return; - } - - await botOrgsProcessed.put(orgId, "true"); - - return { - id, - orgId, - name: doc.name, - encryptedPrivateKey: doc.encryptedPrivateKey, - publicKey: doc.publicKey, - privateKeyIV: doc.privateKeyIV, - privateKeyTag: doc.privateKeyTag, - symmetricKeyIV: doc.symmetricKeyIV, - symmetricKeyTag: doc.symmetricKeyTag, - privateKeyAlgorithm: doc.privateKeyAlgorithm, - encryptedSymmetricKey: doc.encryptedSymmetricKey, - privateKeyKeyEncoding: doc.privateKeyKeyEncoding, - symmetricKeyAlgorithm: doc.symmetricKeyAlgorithm, - symmetricKeyKeyEncoding: doc.symmetricKeyKeyEncoding, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: GitAppInstallationSession, - postgresTableName: TableName.GitAppInstallSession, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const orgId = doc?.organization - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - const userId = await userKv.get(doc.user.toString()).catch(() => null); - if (!userId) return; - - return { - id, - orgId, - userId, - sessionId: doc.sessionId, - createdAt: (doc as any)?.createdAt - ? new Date((doc as any).createdAt) - : new Date(), - updatedAt: (doc as any)?.updatedAt - ? new Date((doc as any).updatedAt) - : new Date(), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: GitAppOrganizationInstallation, - postgresTableName: TableName.GitAppOrg, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const orgId = doc?.organizationId.toString() - ? await orgKv.get(doc.organizationId.toString()).catch(() => null) - : null; - if (!orgId) return; - - const userId = await userKv.get(doc.user.toString()).catch(() => null); - if (!userId) return; - - return { - id, - orgId, - userId, - installationId: doc.installationId, - createdAt: (doc as any)?.createdAt - ? new Date((doc as any).createdAt) - : new Date(), - updatedAt: (doc as any)?.updatedAt - ? new Date((doc as any).updatedAt) - : new Date(), - }; - }, - }); - - await migrateCollection({ - db, - mongooseCollection: GitRisks, - postgresTableName: TableName.SecretScanningGitRisk, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const orgId = doc?.organization.toString() - ? await orgKv.get(doc.organization.toString()).catch(() => null) - : null; - if (!orgId) return; - - return { - id, - orgId, - installationId: doc.installationId, - status: doc.status, - tags: doc.tags, - date: doc.date, - file: doc.file, - email: doc.email, - author: doc.author, - commit: doc.commit, - ruleID: doc.ruleID, - endLine: doc.endLine, - entropy: doc.entropy, - message: doc.message, - endColumn: doc.endColumn, - riskOwner: doc.riskOwner, - startLine: doc.startLine, - isResolved: doc.isResolved, - pusherName: doc.pusher?.name, - description: doc.description, - fingerprint: doc.fingerprint, - fingerPrintWithoutCommitId: doc.fingerPrintWithoutCommitId, - pusherEmail: doc.pusher?.email, - startColumn: doc.startColumn, - symlinkFile: doc.symlinkFile, - repositoryId: doc.repositoryId, - repositoryLink: doc.repositoryLink, - isFalsePositive: doc.isFalsePositive, - repositoryFullName: doc.repositoryFullName, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const trustedIpKv = kdb.sublevel(TableName.TrustedIps); - await migrateCollection({ - db, - mongooseCollection: TrustedIP, - postgresTableName: TableName.TrustedIps, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - await trustedIpKv.put(doc._id.toString(), id); - - return { - id, - projectId: doc.workspace.toString(), - type: doc.type, - prefix: doc.prefix, - comment: doc.comment, - ipAddress: doc.ipAddress, - isActive: doc.isActive, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - const snapKv = kdb.sublevel(TableName.Snapshot); - await migrateCollection({ - db, - mongooseCollection: SecretSnapshot, - postgresTableName: TableName.Snapshot, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - await snapKv.put(doc._id.toString(), id); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const envKv = envPKv.sublevel(doc.workspace.toString()); - - // case: env was deleted but still links snapshot, so we don't need it - if ( - !(await envKv - .get(truncateAndSlugify(doc.environment)) - .catch(() => null)) - ) { - return; - } - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - if ( - await checkIfFolderIsDangling( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - doc.folderId, - ) - ) { - return; - } - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - // const folderKv = getFolderKv(doc.workspace.toString(), truncateAndSlugify(doc.environment)); - const folderId = await folderKv.get(doc.folderId).catch(async () => { - // this folder may not exist now in tree then create a new id and assign it - const newId = uuidV4(); - await folderKv.put(doc.folderId, newId); - return newId; - }); - - return { - id, - envId, - folderId, - createdAt: (doc as any).createdAt, - updatedAt: (doc as any).updatedAt, - }; - }, - }); - - console.log("Migrating secret snapshot secrets"); - await migrateCollection({ - db, - mongooseCollection: SecretSnapshot, - postgresTableName: TableName.SnapshotSecret, - returnKeys: ["id"], - preProcessing: async (doc) => { - const snapshotId = await snapKv.get(doc._id.toString()); - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - const envKv = envPKv.sublevel(doc.workspace.toString()); - - // case: env was deleted but still links snapshot, so we don't need it - if ( - !(await envKv - .get(truncateAndSlugify(doc.environment)) - .catch(() => null)) - ) { - return; - } - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - return Promise.all( - doc.secretVersions - .map(async (secVer) => { - const id = uuidV4(); - - // case: for secret versions that have been discarded, skip creating a snapshot for it - const secretVersionId = await secVerKv - .get(secVer.toString()) - .catch(() => null); - if (!secretVersionId) return; - - return { - id, - envId, - snapshotId, - secretVersionId, - createdAt: (doc as any).createdAt, - updatedAt: (doc as any).updatedAt, - }; - }) - .filter(Boolean), - ); - }, - }); - - console.log("Migrating secret snapshot folders"); - await migrateCollection({ - db, - mongooseCollection: SecretSnapshot, - postgresTableName: TableName.SnapshotFolder, - returnKeys: ["id"], - preProcessing: async (doc) => { - const snapshotId = await snapKv.get(doc._id.toString()); - - if (!doc.folderVersion) return; - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - // case: we forgot to clean up secrets that belong to deleted env slugs - const isEnvFound = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ).catch(() => null); - if (!isEnvFound) return; - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - if ( - await checkIfFolderIsDangling( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - doc.folderId, - ) - ) { - return; - } - - const envId = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - const folderVersion = await FolderVersion.findById(doc.folderVersion); - - if (!folderVersion) return; - - return Promise.all( - folderVersion.nodes.children.map(async (folderVer) => { - const id = uuidV4(); - const folderVersionId = await folderKv.get( - getFolderVersionKey(folderVer.id, folderVer.version), - ); - return { - id, - envId, - snapshotId, - folderVersionId, - createdAt: (doc as any).createdAt, - updatedAt: (doc as any).updatedAt, - }; - }), - ); - }, - }); - - const sarKv = kdb.sublevel(TableName.SecretApprovalRequest); - await migrateCollection({ - db, - mongooseCollection: SecretApprovalRequest, - postgresTableName: TableName.SecretApprovalRequest, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - - // case: when the policy has been deleted, the request should also be deleted - const policyId = await sapKv - .get(doc.policy.toString()) - .catch(() => null); - if (!policyId) return; - - const projectKvRes = await projectKv - .get(doc.workspace.toString()) - .catch(() => null); - if (!projectKvRes) return; - - // case: we forgot to clean up secrets that belong to deleted env slugs - const isEnvFound = await getEnvId( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ).catch(() => null); - if (!isEnvFound) return; - - const folderKv = getFolderKv( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - ); - - if ( - await checkIfFolderIsDangling( - doc.workspace.toString(), - truncateAndSlugify(doc.environment), - doc.folderId, - ) - ) { - return; - } - - // Case: if folder id doesn't exist and the root of the folder also doesn't exist, THEN put the secret at the ROOT - const folderId = await folderKv - .get(doc.folderId || "root") - .catch(async () => { - return await folderKv.get("root"); - }); - - // case: when the committer has been removed from Infisical, we should delete all of their requests (past and preset). - const committerId = await projectMembKv - .get(doc.committer.toString()) - .catch(() => null); - if (!committerId) return; - - await sarKv.put(doc._id.toString(), id); - - const statusChangeBy = doc.statusChangeBy - ? await projectMembKv - .get(doc.statusChangeBy.toString()) - .catch(() => null) - : null; - return { - id, - policyId, - hasMerged: doc.hasMerged, - status: doc.status, - conflicts: JSON.stringify(doc.conflicts), - slug: truncateAndSlugify(doc.slug), - folderId, - committerId, - statusChangeBy, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }, - }); - - console.log( - "Migrating Mongo Secret approval request reviewers -> Pg Secret Approval Request reviewers table", - ); - await migrateCollection({ - db, - mongooseCollection: SecretApprovalRequest, - postgresTableName: TableName.SecretApprovalRequestReviewer, - returnKeys: ["id"], - preProcessing: async (doc) => { - const id = uuidV4(); - const requestId = await sarKv.get(doc._id.toString()).catch(() => null); - if (!requestId) return; - - return Promise.all( - doc.reviewers.map(async ({ status, member }) => { - return { - id, - status, - requestId, - member: await projectMembKv.get(member.toString()), - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - }), - ); - }, - }); - - console.log( - "Migrating Mongo Secret approval request secrets -> Pg Secret Approval Request secrets table", - ); - await migrateCollection({ - db, - mongooseCollection: SecretApprovalRequest, - postgresTableName: TableName.SecretApprovalRequestSecret, - returnKeys: ["id"], - preProcessing: async (doc) => { - const requestId = await sarKv.get(doc._id.toString()).catch(() => null); - if (!requestId) return; - - return Promise.all( - doc.commits.map(async (commit) => { - const id = uuidV4(); - - if (commit.op === CommitType.CREATE) { - if (!commit.newVersion.secretBlindIndex) return; - - return { - id, - op: CommitType.CREATE, - requestId, - secretBlindIndex: commit?.newVersion?.secretBlindIndex as string, - keyEncoding: commit.newVersion.keyEncoding as string, - algorithm: commit.newVersion.algorithm as string, - version: commit.newVersion.version, - secretKeyIV: commit.newVersion.secretKeyIV, - secretKeyTag: commit.newVersion.secretKeyTag, - secretKeyCiphertext: commit.newVersion.secretKeyCiphertext, - secretValueIV: commit.newVersion.secretValueIV, - secretValueTag: commit.newVersion.secretValueTag, - secretValueCiphertext: commit.newVersion.secretValueCiphertext, - secretCommentIV: commit.newVersion.secretCommentIV, - secretCommentTag: commit.newVersion.secretCommentTag, - secretCommentCiphertext: - commit.newVersion.secretCommentCiphertext, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - } - if (commit.op === CommitType.UPDATE) { - const id = uuidV4(); - - const secretId = await secKv - .get(commit.secret.toString()) - .catch(() => null); - if (!secretId) return; - - const secret = await Secret.findById(commit.secret); - if (!secret) return; - - if (!secret?.secretBlindIndex) return; - - const secretVersion = await secVerKv.get(commit.secretVersion._id.toString()) - - return { - id, - op: CommitType.UPDATE, - requestId, - secretId, - secretBlindIndex: - commit.newVersion.secretBlindIndex || secret.secretBlindIndex, - keyEncoding: - (commit.newVersion.keyEncoding as string) || - secret.keyEncoding, - algorithm: - (commit.newVersion.algorithm as string) || secret.algorithm, - version: commit.newVersion.version || secret.version, - secretKeyIV: - commit.newVersion.secretKeyIV || secret.secretKeyIV, - secretKeyTag: - commit.newVersion.secretKeyTag || secret.secretKeyTag, - secretKeyCiphertext: - commit.newVersion.secretKeyCiphertext || - secret.secretKeyCiphertext, - secretValueIV: - commit.newVersion.secretValueIV || secret.secretValueIV, - secretValueTag: - commit.newVersion.secretValueTag || secret.secretValueTag, - secretValueCiphertext: - commit.newVersion.secretValueCiphertext || - secret.secretValueCiphertext, - secretCommentIV: - commit.newVersion.secretCommentIV || secret.secretCommentIV, - secretCommentTag: - commit.newVersion.secretCommentTag || secret.secretCommentTag, - secretCommentCiphertext: - commit.newVersion.secretCommentCiphertext || - secret.secretCommentCiphertext, - secretVersion, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - } - if (commit.op === CommitType.DELETE) { - const id = uuidV4(); - - const secretId = await secKv - .get(commit.secret.toString()) - .catch(() => null); - if (!secretId) return; - - const secret = await Secret.findById(commit.secret); - if (!secret) return; - - if (!secret?.secretBlindIndex) return; - - const secretVersion = await secVerKv.get(commit.secretVersion._id.toString()) - - return { - id, - op: CommitType.DELETE, - requestId, - secretId, - secretBlindIndex: secret.secretBlindIndex, - keyEncoding: secret.keyEncoding, - algorithm: secret.algorithm, - version: secret.version, - secretKeyIV: secret.secretKeyIV, - secretKeyTag: secret.secretKeyTag, - secretKeyCiphertext: secret.secretKeyCiphertext, - secretValueIV: secret.secretValueIV, - secretValueTag: secret.secretValueTag, - secretValueCiphertext: secret.secretValueCiphertext, - secretCommentIV: secret.secretCommentIV, - secretCommentTag: secret.secretCommentTag, - secretCommentCiphertext: secret.secretCommentCiphertext, - secretVersion, - createdAt: new Date((doc as any).createdAt), - updatedAt: new Date((doc as any).updatedAt), - }; - } - }), - ); - }, - }); - - console.log("MIGRATION SCRIPT COMPLETED SUCCESSFULLY"); - process.exit(1); - } catch (error) { - console.error(error); - process.exit(1); - } -}; - -main(); diff --git a/pg-migrator/src/migrations/20231128072457_user.ts b/pg-migrator/src/migrations/20231128072457_user.ts deleted file mode 100644 index f0572824e..000000000 --- a/pg-migrator/src/migrations/20231128072457_user.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { - createOnUpdateTrigger, - createUpdateAtTriggerFunction, - dropOnUpdateTrigger, - dropUpdatedAtTriggerFunction -} from "../utils"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.Users); - if (!isTablePresent) { - await knex.schema.createTable(TableName.Users, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("email").notNullable(); - t.specificType("authMethods", "text[]"); - t.boolean("superAdmin").defaultTo(false); - t.string("firstName"); - t.string("lastName"); - t.boolean("isAccepted").defaultTo(false); - t.boolean("isMfaEnabled").defaultTo(false); - t.specificType("mfaMethods", "text[]"); - t.jsonb("devices"); - t.timestamps(true, true, true); - }); - } - // this is a one time function - await createUpdateAtTriggerFunction(knex); - await createOnUpdateTrigger(knex, TableName.Users); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.Users); - await dropOnUpdateTrigger(knex, TableName.Users); - await dropUpdatedAtTriggerFunction(knex); -} diff --git a/pg-migrator/src/migrations/20231128092347_user-encryption-key.ts b/pg-migrator/src/migrations/20231128092347_user-encryption-key.ts deleted file mode 100644 index 2ac292e88..000000000 --- a/pg-migrator/src/migrations/20231128092347_user-encryption-key.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.UserEncryptionKey); - if (!isTablePresent) { - await knex.schema.createTable(TableName.UserEncryptionKey, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.text("clientPublicKey"); - t.text("serverPrivateKey"); - t.integer("encryptionVersion").defaultTo(2); - t.text("protectedKey"); - t.text("protectedKeyIV"); - t.text("protectedKeyTag"); - t.text("publicKey").notNullable(); - t.text("encryptedPrivateKey").notNullable(); - t.text("iv").notNullable(); - t.text("tag").notNullable(); - t.text("salt").notNullable(); - t.text("verifier").notNullable(); - // one to one relationship - t.uuid("userId").notNullable().unique(); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - }); - } -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.UserEncryptionKey); -} diff --git a/pg-migrator/src/migrations/20231129072939_auth-token.ts b/pg-migrator/src/migrations/20231129072939_auth-token.ts deleted file mode 100644 index ed23ebe9d..000000000 --- a/pg-migrator/src/migrations/20231129072939_auth-token.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.AuthTokens); - if (!isTablePresent) { - await knex.schema.createTable(TableName.AuthTokens, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("type").notNullable(); - t.string("phoneNumber"); - t.string("tokenHash").notNullable(); - t.integer("triesLeft"); - t.datetime("expiresAt").notNullable(); - // does not need update trigger we will do it manually - t.timestamps(true, true, true); - t.uuid("userId"); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - }); - } -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.AuthTokens); -} diff --git a/pg-migrator/src/migrations/20231130072734_auth-token-session.ts b/pg-migrator/src/migrations/20231130072734_auth-token-session.ts deleted file mode 100644 index 9d5b98910..000000000 --- a/pg-migrator/src/migrations/20231130072734_auth-token-session.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.AuthTokenSession); - if (!isTablePresent) { - await knex.schema.createTable(TableName.AuthTokenSession, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("ip").notNullable(); - t.string("userAgent"); - t.integer("refreshVersion").notNullable().defaultTo(1); - t.integer("accessVersion").notNullable().defaultTo(1); - t.datetime("lastUsed").notNullable(); - // does not need update trigger we will do it manually - t.timestamps(true, true, true); - t.uuid("userId").notNullable(); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - }); - } - // this is a one time function - await createOnUpdateTrigger(knex, TableName.AuthTokenSession); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.AuthTokenSession); - await dropOnUpdateTrigger(knex, TableName.AuthTokenSession); -} diff --git a/pg-migrator/src/migrations/20231201151432_backup-key.ts b/pg-migrator/src/migrations/20231201151432_backup-key.ts deleted file mode 100644 index 0c5dd2286..000000000 --- a/pg-migrator/src/migrations/20231201151432_backup-key.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; - -export async function up(knex: Knex): Promise { - const doesTableExist = await knex.schema.hasTable(TableName.BackupPrivateKey); - if (!doesTableExist) { - await knex.schema.createTable(TableName.BackupPrivateKey, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.text("encryptedPrivateKey").notNullable(); - t.text("iv").notNullable(); - t.text("tag").notNullable(); - t.string("algorithm").notNullable(); - t.string("keyEncoding").notNullable(); - t.text("salt").notNullable(); - t.text("verifier").notNullable(); - t.timestamps(true, true, true); - t.uuid("userId").notNullable().unique(); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - }); - } -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.BackupPrivateKey); -} diff --git a/pg-migrator/src/migrations/20231204092737_organization.ts b/pg-migrator/src/migrations/20231204092737_organization.ts deleted file mode 100644 index 8928b086a..000000000 --- a/pg-migrator/src/migrations/20231204092737_organization.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.Organization); - if (!isTablePresent) { - await knex.schema.createTable(TableName.Organization, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("customerId"); - t.string("slug").notNullable(); - // does not need update trigger we will do it manually - t.unique("slug"); - t.timestamps(true, true, true); - }); - await knex.schema.alterTable(TableName.AuthTokens, (t) => { - t.uuid("orgId"); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - }); - } - // this is a one time function - await createOnUpdateTrigger(knex, TableName.Organization); -} - -export async function down(knex: Knex): Promise { - if (await knex.schema.hasColumn(TableName.AuthTokens, "orgId")) { - await knex.schema.alterTable(TableName.AuthTokens, (t) => { - t.dropColumn("orgId"); - }); - } - await knex.schema.dropTableIfExists(TableName.Organization); - await dropOnUpdateTrigger(knex, TableName.Organization); -} diff --git a/pg-migrator/src/migrations/20231204092747_org-membership.ts b/pg-migrator/src/migrations/20231204092747_org-membership.ts deleted file mode 100644 index 2b166d3e5..000000000 --- a/pg-migrator/src/migrations/20231204092747_org-membership.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { OrgMembershipStatus } from "../schemas/models"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - const isOrgRolePresent = await knex.schema.hasTable(TableName.OrgRoles); - if (!isOrgRolePresent) { - await knex.schema.createTable(TableName.OrgRoles, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("description"); - t.string("slug").notNullable(); - t.jsonb("permissions").notNullable(); - // does not need update trigger we will do it manually - t.timestamps(true, true, true); - t.uuid("orgId").notNullable(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - }); - } - - const isOrgTablePresent = await knex.schema.hasTable(TableName.OrgMembership); - if (!isOrgTablePresent) { - await knex.schema.createTable(TableName.OrgMembership, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("role").notNullable(); - t.string("status").notNullable().defaultTo(OrgMembershipStatus.Invited); - t.string("inviteEmail"); - // does not need update trigger we will do it manually - t.timestamps(true, true, true); - t.uuid("userId"); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - t.uuid("orgId").notNullable(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.uuid("roleId"); - t.foreign("roleId").references("id").inTable(TableName.OrgRoles); - }); - } - // this is a one time function - await createOnUpdateTrigger(knex, TableName.OrgMembership); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.OrgMembership); - await knex.schema.dropTableIfExists(TableName.OrgRoles); - await dropOnUpdateTrigger(knex, TableName.OrgMembership); -} diff --git a/pg-migrator/src/migrations/20231205151331_incident-contact.ts b/pg-migrator/src/migrations/20231205151331_incident-contact.ts deleted file mode 100644 index a0c1a3c27..000000000 --- a/pg-migrator/src/migrations/20231205151331_incident-contact.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.IncidentContact); - if (!isTablePresent) { - await knex.schema.createTable(TableName.IncidentContact, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("email").notNullable(); - // does not need update trigger we will do it manually - t.timestamps(true, true, true); - t.uuid("orgId").notNullable(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - }); - } - // this is a one time function - await createOnUpdateTrigger(knex, TableName.IncidentContact); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.IncidentContact); - await dropOnUpdateTrigger(knex, TableName.IncidentContact); -} diff --git a/pg-migrator/src/migrations/20231207055643_user-action.ts b/pg-migrator/src/migrations/20231207055643_user-action.ts deleted file mode 100644 index c3b54839c..000000000 --- a/pg-migrator/src/migrations/20231207055643_user-action.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.UserAction); - if (!isTablePresent) { - await knex.schema.createTable(TableName.UserAction, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("action").notNullable(); - t.timestamps(true, true, true); - t.uuid("userId").notNullable(); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - }); - } -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.UserAction); -} diff --git a/pg-migrator/src/migrations/20231207055701_super-admin.ts b/pg-migrator/src/migrations/20231207055701_super-admin.ts deleted file mode 100644 index 6d5f7f32d..000000000 --- a/pg-migrator/src/migrations/20231207055701_super-admin.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.SuperAdmin); - if (!isTablePresent) { - await knex.schema.createTable(TableName.SuperAdmin, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.boolean("initialized").defaultTo(false); - t.boolean("allowSignUp").defaultTo(true); - t.timestamps(true, true, true); - }); - } - // this is a one time function - await createOnUpdateTrigger(knex, TableName.SuperAdmin); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SuperAdmin); - await dropOnUpdateTrigger(knex, TableName.SuperAdmin); -} diff --git a/pg-migrator/src/migrations/20231207105059_api-key.ts b/pg-migrator/src/migrations/20231207105059_api-key.ts deleted file mode 100644 index 4758973da..000000000 --- a/pg-migrator/src/migrations/20231207105059_api-key.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - const isTablePresent = await knex.schema.hasTable(TableName.ApiKey); - if (!isTablePresent) { - await knex.schema.createTable(TableName.ApiKey, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.datetime("lastUsed"); - t.datetime("expiresAt"); - t.string("secretHash").notNullable(); - t.timestamps(true, true, true); - t.uuid("userId").notNullable(); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - }); - } - await createOnUpdateTrigger(knex, TableName.ApiKey); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.ApiKey); - await dropOnUpdateTrigger(knex, TableName.ApiKey); -} diff --git a/pg-migrator/src/migrations/20231212110939_project.ts b/pg-migrator/src/migrations/20231212110939_project.ts deleted file mode 100644 index b2764dc1f..000000000 --- a/pg-migrator/src/migrations/20231212110939_project.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.Project))) { - await knex.schema.createTable(TableName.Project, (t) => { - t.string("id", 36).primary().defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("slug").notNullable(); - t.boolean("autoCapitalization").defaultTo(true); - t.uuid("orgId").notNullable(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.timestamps(true, true, true); - t.unique(["orgId", "slug"]); - }); - } - await createOnUpdateTrigger(knex, TableName.Project); - // environments - if (!(await knex.schema.hasTable(TableName.Environment))) { - await knex.schema.createTable(TableName.Environment, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("slug").notNullable(); - t.integer("position").notNullable(); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - // this will ensure ever env has its position - t.unique(["projectId", "position"], { - indexName: "env_pos_composite_uniqe", - deferrable: "deferred" - }); - t.timestamps(true, true, true); - }); - } - // project key - if (!(await knex.schema.hasTable(TableName.ProjectKeys))) { - await knex.schema.createTable(TableName.ProjectKeys, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.text("encryptedKey").notNullable(); - t.text("nonce").notNullable(); - t.uuid("receiverId").notNullable(); - t.foreign("receiverId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - t.uuid("senderId"); - // if sender is deleted just don't do anything to this record - t.foreign("senderId").references("id").inTable(TableName.Users).onDelete("SET NULL"); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.ProjectKeys); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.Environment); - await knex.schema.dropTableIfExists(TableName.ProjectKeys); - await knex.schema.dropTableIfExists(TableName.Project); - await dropOnUpdateTrigger(knex, TableName.ProjectKeys); - await dropOnUpdateTrigger(knex, TableName.Project); -} diff --git a/pg-migrator/src/migrations/20231212110946_project-membership.ts b/pg-migrator/src/migrations/20231212110946_project-membership.ts deleted file mode 100644 index ad7cdb8a5..000000000 --- a/pg-migrator/src/migrations/20231212110946_project-membership.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.ProjectRoles))) { - await knex.schema.createTable(TableName.ProjectRoles, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("description"); - t.string("slug").notNullable(); - t.jsonb("permissions").notNullable(); - // does not need update trigger we will do it manually - t.timestamps(true, true, true); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - }); - } - - if (!(await knex.schema.hasTable(TableName.ProjectMembership))) { - await knex.schema.createTable(TableName.ProjectMembership, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("role").notNullable(); - // does not need update trigger we will do it manually - t.timestamps(true, true, true); - t.uuid("userId").notNullable(); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - // until role is changed/removed the role should not deleted - t.uuid("roleId"); - t.foreign("roleId").references("id").inTable(TableName.ProjectRoles); - }); - } - await createOnUpdateTrigger(knex, TableName.ProjectMembership); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.ProjectMembership); - await knex.schema.dropTableIfExists(TableName.ProjectRoles); - await dropOnUpdateTrigger(knex, TableName.ProjectMembership); -} diff --git a/pg-migrator/src/migrations/20231218092441_secret-folder.ts b/pg-migrator/src/migrations/20231218092441_secret-folder.ts deleted file mode 100644 index ba67e295b..000000000 --- a/pg-migrator/src/migrations/20231218092441_secret-folder.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretFolder))) { - await knex.schema.createTable(TableName.SecretFolder, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.integer("version").defaultTo(1); - t.timestamps(true, true, true); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - t.uuid("parentId"); - t.foreign("parentId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretFolder); - - if (!(await knex.schema.hasTable(TableName.SecretFolderVersion))) { - await knex.schema.createTable(TableName.SecretFolderVersion, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.integer("version").defaultTo(1); - t.timestamps(true, true, true); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - t.uuid("folderId").notNullable(); - // t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("SET NULL"); - }); - } - - await createOnUpdateTrigger(knex, TableName.SecretFolderVersion); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretFolderVersion); - await knex.schema.dropTableIfExists(TableName.SecretFolder); - await dropOnUpdateTrigger(knex, TableName.SecretFolder); - await dropOnUpdateTrigger(knex, TableName.SecretFolderVersion); -} diff --git a/pg-migrator/src/migrations/20231218092508_secret-import.ts b/pg-migrator/src/migrations/20231218092508_secret-import.ts deleted file mode 100644 index 12aa80c74..000000000 --- a/pg-migrator/src/migrations/20231218092508_secret-import.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretImport))) { - await knex.schema.createTable(TableName.SecretImport, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.integer("version").defaultTo(1); - t.string("importPath").notNullable(); - t.uuid("importEnv").notNullable(); - t.foreign("importEnv").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - t.integer("position").notNullable(); - t.timestamps(true, true, true); - t.uuid("folderId").notNullable(); - t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); - t.unique(["folderId", "position"], { - indexName: "import_pos_composite_uniqe", - deferrable: "deferred" - }); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretImport); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretImport); - await dropOnUpdateTrigger(knex, TableName.SecretImport); -} diff --git a/pg-migrator/src/migrations/20231218092517_secret-tag.ts b/pg-migrator/src/migrations/20231218092517_secret-tag.ts deleted file mode 100644 index 051f39d76..000000000 --- a/pg-migrator/src/migrations/20231218092517_secret-tag.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretTag))) { - await knex.schema.createTable(TableName.SecretTag, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("slug").notNullable(); - t.string("color"); - t.timestamps(true, true, true); - t.uuid("createdBy"); - t.foreign("createdBy").references("id").inTable(TableName.Users).onDelete("SET NULL"); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretTag); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretTag); - await dropOnUpdateTrigger(knex, TableName.SecretTag); -} diff --git a/pg-migrator/src/migrations/20231218103423_secret.ts b/pg-migrator/src/migrations/20231218103423_secret.ts deleted file mode 100644 index c955ee50f..000000000 --- a/pg-migrator/src/migrations/20231218103423_secret.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Knex } from "knex"; - -import { - SecretEncryptionAlgo, - SecretKeyEncoding, - SecretType, - TableName, -} from "../schemas"; -import { - createJunctionTable, - createOnUpdateTrigger, - dropOnUpdateTrigger, -} from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretBlindIndex))) { - await knex.schema.createTable(TableName.SecretBlindIndex, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.text("encryptedSaltCipherText").notNullable(); - t.text("saltIV").notNullable(); - t.text("saltTag").notNullable(); - t.string("algorithm") - .notNullable() - .defaultTo(SecretEncryptionAlgo.AES_256_GCM); - t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); - t.string("projectId").notNullable().unique(); - t.foreign("projectId") - .references("id") - .inTable(TableName.Project) - .onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretBlindIndex); - - if (!(await knex.schema.hasTable(TableName.Secret))) { - await knex.schema.createTable(TableName.Secret, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.integer("version").defaultTo(1).notNullable(); - t.string("type").notNullable().defaultTo(SecretType.Shared); - // t.text("secretKeyHash").notNullable(); - // t.text("secretValueHash"); - // t.text("secretCommentHash"); - // this is required but for backward compatiability we are making it nullable - t.text("secretBlindIndex"); - t.text("secretKeyCiphertext").notNullable(); - t.text("secretKeyIV").notNullable(); - t.text("secretKeyTag").notNullable(); - t.text("secretValueCiphertext").notNullable(); - t.text("secretValueIV").notNullable(); // symmetric encryption - t.text("secretValueTag").notNullable(); - t.text("secretCommentCiphertext"); - t.text("secretCommentIV"); - t.text("secretCommentTag"); - t.string("secretReminderNote"); - t.integer("secretReminderRepeatDays"); - t.boolean("skipMultilineEncoding").defaultTo(false); - t.string("algorithm") - .notNullable() - .defaultTo(SecretEncryptionAlgo.AES_256_GCM); - t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); - t.jsonb("metadata"); - t.uuid("userId"); - t.foreign("userId") - .references("id") - .inTable(TableName.Users) - .onDelete("CASCADE"); - t.uuid("folderId").notNullable(); - t.foreign("folderId") - .references("id") - .inTable(TableName.SecretFolder) - .onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.Secret); - // many to many relation between tags - await createJunctionTable( - knex, - TableName.JnSecretTag, - TableName.Secret, - TableName.SecretTag, - ); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretBlindIndex); - await dropOnUpdateTrigger(knex, TableName.SecretBlindIndex); - - await knex.schema.dropTableIfExists(TableName.JnSecretTag); - await knex.schema.dropTableIfExists(TableName.Secret); - await dropOnUpdateTrigger(knex, TableName.Secret); -} diff --git a/pg-migrator/src/migrations/20231220052508_secret-version.ts b/pg-migrator/src/migrations/20231220052508_secret-version.ts deleted file mode 100644 index 0bcee295b..000000000 --- a/pg-migrator/src/migrations/20231220052508_secret-version.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Knex } from "knex"; - -import { SecretEncryptionAlgo, SecretKeyEncoding, SecretType, TableName } from "../schemas"; -import { createJunctionTable, createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretVersion))) { - await knex.schema.createTable(TableName.SecretVersion, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.integer("version").defaultTo(1).notNullable(); - t.string("type").notNullable().defaultTo(SecretType.Shared); - t.text("secretBlindIndex"); - t.text("secretKeyCiphertext").notNullable(); - t.text("secretKeyIV").notNullable(); - t.text("secretKeyTag").notNullable(); - t.text("secretValueCiphertext").notNullable(); - t.text("secretValueIV").notNullable(); // symmetric encryption - t.text("secretValueTag").notNullable(); - t.text("secretCommentCiphertext"); - t.text("secretCommentIV"); - t.text("secretCommentTag"); - t.string("secretReminderNote"); - t.integer("secretReminderRepeatDays"); - t.boolean("skipMultilineEncoding").defaultTo(false); - t.string("algorithm").notNullable().defaultTo(SecretEncryptionAlgo.AES_256_GCM); - t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); - t.jsonb("metadata"); - // to avoid orphan rows - t.uuid("envId"); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - t.uuid("secretId").notNullable(); - t.uuid("folderId").notNullable(); - // t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("SET NULL"); - t.uuid("userId"); - t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretVersion); - // many to many relation between tags - await createJunctionTable( - knex, - TableName.SecretVersionTag, - TableName.SecretVersion, - TableName.SecretTag - ); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretVersionTag); - await knex.schema.dropTableIfExists(TableName.SecretVersion); - await dropOnUpdateTrigger(knex, TableName.SecretVersion); -} diff --git a/pg-migrator/src/migrations/20231222092113_project-bot.ts b/pg-migrator/src/migrations/20231222092113_project-bot.ts deleted file mode 100644 index 98c67c8b6..000000000 --- a/pg-migrator/src/migrations/20231222092113_project-bot.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.ProjectBot))) { - await knex.schema.createTable(TableName.ProjectBot, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.boolean("isActive").defaultTo(false).notNullable(); - t.text("encryptedPrivateKey").notNullable(); - t.text("publicKey").notNullable(); - t.text("iv").notNullable(); - t.text("tag").notNullable(); - t.string("algorithm").notNullable(); - t.string("keyEncoding").notNullable(); - t.text("encryptedProjectKey"); - t.text("encryptedProjectKeyNonce"); - // one to one relationship - t.string("projectId").notNullable().unique(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - t.uuid("senderId"); - t.foreign("senderId").references("id").inTable(TableName.Users).onDelete("SET NULL"); - t.timestamps(true, true, true); - }); - } - - await createOnUpdateTrigger(knex, TableName.ProjectBot); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.ProjectBot); - await dropOnUpdateTrigger(knex, TableName.ProjectBot); -} diff --git a/pg-migrator/src/migrations/20231222172455_integration.ts b/pg-migrator/src/migrations/20231222172455_integration.ts deleted file mode 100644 index 4ef34cab1..000000000 --- a/pg-migrator/src/migrations/20231222172455_integration.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.IntegrationAuth))) { - await knex.schema.createTable(TableName.IntegrationAuth, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("integration").notNullable(); - t.string("teamId"); // vercel-specific - t.string("url"); // for self hosted - t.string("namespace"); // hashicorp specific - t.string("accountId"); // netlify - t.text("refreshCiphertext"); - t.string("refreshIV"); - t.string("refreshTag"); - t.string("accessIdCiphertext"); - t.string("accessIdIV"); - t.string("accessIdTag"); - t.text("accessCiphertext"); - t.string("accessIV"); - t.string("accessTag"); - t.datetime("accessExpiresAt"); - t.jsonb("metadata"); - t.string("algorithm").notNullable(); - t.string("keyEncoding").notNullable(); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.IntegrationAuth); - - if (!(await knex.schema.hasTable(TableName.Integration))) { - await knex.schema.createTable(TableName.Integration, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.boolean("isActive").notNullable(); - t.string("url"); // self hosted - t.string("app"); // name of app in provider - t.string("appId"); - t.string("targetEnvironment"); - t.string("targetEnvironmentId"); - t.string("targetService"); // railway - qovery specific - t.string("targetServiceId"); - t.string("owner"); // github specific - t.string("path"); // aws parameter store / vercel preview branch - t.string("region"); // aws - t.string("scope"); // qovery specific scope - t.string("integration").notNullable(); - t.jsonb("metadata"); - t.uuid("integrationAuthId").notNullable(); - t.foreign("integrationAuthId") - .references("id") - .inTable(TableName.IntegrationAuth) - .onDelete("CASCADE"); - t.uuid("envId").notNullable(); - t.string("secretPath").defaultTo("/").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.Integration); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.Integration); - await knex.schema.dropTableIfExists(TableName.IntegrationAuth); - await dropOnUpdateTrigger(knex, TableName.IntegrationAuth); - await dropOnUpdateTrigger(knex, TableName.Integration); -} diff --git a/pg-migrator/src/migrations/20231225072545_service-token.ts b/pg-migrator/src/migrations/20231225072545_service-token.ts deleted file mode 100644 index 0dd20af82..000000000 --- a/pg-migrator/src/migrations/20231225072545_service-token.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.ServiceToken))) { - await knex.schema.createTable(TableName.ServiceToken, (t) => { - t.string("id", 36).primary().defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.jsonb("scopes").notNullable(); - t.specificType("permissions", "text[]").notNullable(); - t.datetime("lastUsed"); - t.datetime("expiresAt"); - t.text("secretHash").notNullable(); - t.text("encryptedKey"); - t.text("iv"); - t.text("tag"); - t.timestamps(true, true, true); - // user is old one - t.string("createdBy").notNullable(); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - }); - } - await createOnUpdateTrigger(knex, TableName.ServiceToken); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.ServiceToken); - await dropOnUpdateTrigger(knex, TableName.ServiceToken); -} diff --git a/pg-migrator/src/migrations/20231225072552_webhook.ts b/pg-migrator/src/migrations/20231225072552_webhook.ts deleted file mode 100644 index f12f489e8..000000000 --- a/pg-migrator/src/migrations/20231225072552_webhook.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.Webhook))) { - await knex.schema.createTable(TableName.Webhook, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("secretPath").notNullable().defaultTo("/"); - t.string("url").notNullable(); - t.string("lastStatus"); - t.text("lastRunErrorMessage"); - t.boolean("isDisabled").defaultTo(false).notNullable(); - // webhook signature - t.text("encryptedSecretKey"); - t.text("iv"); - t.text("tag"); - t.string("algorithm"); - t.string("keyEncoding"); - t.timestamps(true, true, true); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - }); - } - await createOnUpdateTrigger(knex, TableName.Webhook); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.Webhook); - await dropOnUpdateTrigger(knex, TableName.Webhook); -} diff --git a/pg-migrator/src/migrations/20231228074856_identity.ts b/pg-migrator/src/migrations/20231228074856_identity.ts deleted file mode 100644 index 56f5c6752..000000000 --- a/pg-migrator/src/migrations/20231228074856_identity.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.Identity))) { - await knex.schema.createTable(TableName.Identity, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("authMethod"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.Identity); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.Identity); - await dropOnUpdateTrigger(knex, TableName.Identity); -} diff --git a/pg-migrator/src/migrations/20231228074908_identity-universal-auth.ts b/pg-migrator/src/migrations/20231228074908_identity-universal-auth.ts deleted file mode 100644 index 3d648a797..000000000 --- a/pg-migrator/src/migrations/20231228074908_identity-universal-auth.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.IdentityUniversalAuth))) { - await knex.schema.createTable(TableName.IdentityUniversalAuth, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("clientId").notNullable(); - t.bigint("accessTokenTTL").defaultTo(7200).notNullable(); - t.bigint("accessTokenMaxTTL").defaultTo(7200).notNullable(); - t.bigint("accessTokenNumUsesLimit").defaultTo(0).notNullable(); - t.jsonb("clientSecretTrustedIps").notNullable(); - t.jsonb("accessTokenTrustedIps").notNullable(); - t.timestamps(true, true, true); - t.uuid("identityId").notNullable().unique(); - t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); - }); - } - if (!(await knex.schema.hasTable(TableName.IdentityUaClientSecret))) { - await knex.schema.createTable(TableName.IdentityUaClientSecret, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("description").notNullable(); - t.string("clientSecretPrefix").notNullable(); - t.string("clientSecretHash").notNullable(); - t.datetime("clientSecretLastUsedAt"); - t.bigint("clientSecretNumUses").defaultTo(0).notNullable(); - t.bigint("clientSecretNumUsesLimit").defaultTo(0).notNullable(); - t.bigint("clientSecretTTL").defaultTo(0).notNullable(); - t.boolean("isClientSecretRevoked").defaultTo(false).notNullable(); - t.timestamps(true, true, true); - t.uuid("identityUAId").notNullable(); - t.foreign("identityUAId") - .references("id") - .inTable(TableName.IdentityUniversalAuth) - .onDelete("CASCADE"); - }); - } - await createOnUpdateTrigger(knex, TableName.IdentityUniversalAuth); - await createOnUpdateTrigger(knex, TableName.IdentityUaClientSecret); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.IdentityUaClientSecret); - await knex.schema.dropTableIfExists(TableName.IdentityUniversalAuth); - await dropOnUpdateTrigger(knex, TableName.IdentityUaClientSecret); - await dropOnUpdateTrigger(knex, TableName.IdentityUniversalAuth); -} diff --git a/pg-migrator/src/migrations/20231228075011_identity-access-token.ts b/pg-migrator/src/migrations/20231228075011_identity-access-token.ts deleted file mode 100644 index fccbe2730..000000000 --- a/pg-migrator/src/migrations/20231228075011_identity-access-token.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.IdentityAccessToken))) { - await knex.schema.createTable(TableName.IdentityAccessToken, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.integer("accessTokenTTL").defaultTo(2592000).notNullable(); // 30 days second - t.integer("accessTokenMaxTTL").defaultTo(2592000).notNullable(); - t.integer("accessTokenNumUses").defaultTo(0).notNullable(); - t.integer("accessTokenNumUsesLimit").defaultTo(0).notNullable(); - t.datetime("accessTokenLastUsedAt"); - t.datetime("accessTokenLastRenewedAt"); - t.boolean("isAccessTokenRevoked").defaultTo(false).notNullable(); - t.uuid("identityUAClientSecretId"); - t.foreign("identityUAClientSecretId") - .references("id") - .inTable(TableName.IdentityUaClientSecret) - .onDelete("CASCADE"); - t.uuid("identityId").notNullable(); - t.foreign("identityId") - .references("id") - .inTable(TableName.Identity) - .onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - - await createOnUpdateTrigger(knex, TableName.IdentityAccessToken); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.IdentityAccessToken); - await dropOnUpdateTrigger(knex, TableName.IdentityAccessToken); -} diff --git a/pg-migrator/src/migrations/20231228075023_identity-membership.ts b/pg-migrator/src/migrations/20231228075023_identity-membership.ts deleted file mode 100644 index 288c11be3..000000000 --- a/pg-migrator/src/migrations/20231228075023_identity-membership.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.IdentityOrgMembership))) { - await knex.schema.createTable(TableName.IdentityOrgMembership, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("role").notNullable(); - t.uuid("roleId"); - t.foreign("roleId").references("id").inTable(TableName.OrgRoles); - t.uuid("orgId").notNullable(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.timestamps(true, true, true); - t.uuid("identityId").notNullable(); - t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); - }); - } - await createOnUpdateTrigger(knex, TableName.IdentityOrgMembership); - - if (!(await knex.schema.hasTable(TableName.IdentityProjectMembership))) { - await knex.schema.createTable(TableName.IdentityProjectMembership, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("role").notNullable(); - t.uuid("roleId"); - t.foreign("roleId").references("id").inTable(TableName.ProjectRoles); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - t.uuid("identityId").notNullable(); - t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.IdentityProjectMembership); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.IdentityOrgMembership); - await knex.schema.dropTableIfExists(TableName.IdentityProjectMembership); - - await dropOnUpdateTrigger(knex, TableName.IdentityProjectMembership); - await dropOnUpdateTrigger(knex, TableName.IdentityOrgMembership); -} diff --git a/pg-migrator/src/migrations/20240101054849_secret-approval-policy.ts b/pg-migrator/src/migrations/20240101054849_secret-approval-policy.ts deleted file mode 100644 index 7fde0d314..000000000 --- a/pg-migrator/src/migrations/20240101054849_secret-approval-policy.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretApprovalPolicy))) { - await knex.schema.createTable(TableName.SecretApprovalPolicy, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.string("secretPath"); - t.integer("approvals").defaultTo(1).notNullable(); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretApprovalPolicy); - - if (!(await knex.schema.hasTable(TableName.SecretApprovalPolicyApprover))) { - await knex.schema.createTable(TableName.SecretApprovalPolicyApprover, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.uuid("approverId").notNullable(); - t.foreign("approverId") - .references("id") - .inTable(TableName.ProjectMembership) - .onDelete("CASCADE"); - t.uuid("policyId").notNullable(); - t.foreign("policyId") - .references("id") - .inTable(TableName.SecretApprovalPolicy) - .onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - - await createOnUpdateTrigger(knex, TableName.SecretApprovalPolicyApprover); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretApprovalPolicyApprover); - await knex.schema.dropTableIfExists(TableName.SecretApprovalPolicy); - await dropOnUpdateTrigger(knex, TableName.SecretApprovalPolicyApprover); - await dropOnUpdateTrigger(knex, TableName.SecretApprovalPolicy); -} diff --git a/pg-migrator/src/migrations/20240101104907_secret-approval-request.ts b/pg-migrator/src/migrations/20240101104907_secret-approval-request.ts deleted file mode 100644 index 21a9e944e..000000000 --- a/pg-migrator/src/migrations/20240101104907_secret-approval-request.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Knex } from "knex"; - -import { SecretEncryptionAlgo, SecretKeyEncoding, TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretApprovalRequest))) { - await knex.schema.createTable(TableName.SecretApprovalRequest, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.uuid("policyId").notNullable(); - t.boolean("hasMerged").defaultTo(false).notNullable(); - t.string("status").defaultTo("open").notNullable(); - t.jsonb("conflicts"); - t.foreign("policyId") - .references("id") - .inTable(TableName.SecretApprovalPolicy) - .onDelete("CASCADE"); - t.string("slug").notNullable(); - t.uuid("folderId").notNullable(); - t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); - t.uuid("statusChangeBy"); - t.foreign("statusChangeBy") - .references("id") - .inTable(TableName.ProjectMembership) - .onDelete("SET NULL"); - t.uuid("committerId").notNullable(); - t.foreign("committerId") - .references("id") - .inTable(TableName.ProjectMembership) - .onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretApprovalRequest); - - if (!(await knex.schema.hasTable(TableName.SecretApprovalRequestReviewer))) { - await knex.schema.createTable(TableName.SecretApprovalRequestReviewer, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.uuid("member").notNullable(); - t.foreign("member").references("id").inTable(TableName.ProjectMembership).onDelete("CASCADE"); - t.string("status").notNullable(); - t.uuid("requestId").notNullable(); - t.foreign("requestId") - .references("id") - .inTable(TableName.SecretApprovalRequest) - .onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretApprovalRequestReviewer); - - if (!(await knex.schema.hasTable(TableName.SecretApprovalRequestSecret))) { - await knex.schema.createTable(TableName.SecretApprovalRequestSecret, (t) => { - // everything related to secret - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.integer("version").defaultTo(1); - t.text("secretBlindIndex"); - t.text("secretKeyCiphertext").notNullable(); - t.text("secretKeyIV").notNullable(); - t.text("secretKeyTag").notNullable(); - t.text("secretValueCiphertext").notNullable(); - t.text("secretValueIV").notNullable(); // symmetric encryption - t.text("secretValueTag").notNullable(); - t.text("secretCommentCiphertext"); - t.text("secretCommentIV"); - t.text("secretCommentTag"); - t.string("secretReminderNote"); - t.integer("secretReminderRepeatDays"); - t.boolean("skipMultilineEncoding").defaultTo(false); - t.string("algorithm").notNullable().defaultTo(SecretEncryptionAlgo.AES_256_GCM); - t.string("keyEncoding").notNullable().defaultTo(SecretKeyEncoding.UTF8); - t.jsonb("metadata"); - t.timestamps(true, true, true); - // commit details - t.uuid("requestId").notNullable(); - t.foreign("requestId") - .references("id") - .inTable(TableName.SecretApprovalRequest) - .onDelete("CASCADE"); - t.string("op").notNullable(); - t.uuid("secretId"); - t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("SET NULL"); - t.uuid("secretVersion"); - t.foreign("secretVersion") - .references("id") - .inTable(TableName.SecretVersion) - .onDelete("SET NULL"); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretApprovalRequestSecret); - - if (!(await knex.schema.hasTable(TableName.SecretApprovalRequestSecretTag))) { - await knex.schema.createTable(TableName.SecretApprovalRequestSecretTag, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.uuid("secretId").notNullable(); - t.foreign("secretId") - .references("id") - .inTable(TableName.SecretApprovalRequestSecret) - .onDelete("CASCADE"); - t.uuid("tagId").notNullable(); - t.foreign("tagId").references("id").inTable(TableName.SecretTag).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretApprovalRequestSecretTag); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretApprovalRequestSecretTag); - await knex.schema.dropTableIfExists(TableName.SecretApprovalRequestSecret); - await knex.schema.dropTableIfExists(TableName.SecretApprovalRequestReviewer); - await knex.schema.dropTableIfExists(TableName.SecretApprovalRequest); - - await dropOnUpdateTrigger(knex, TableName.SecretApprovalRequestSecretTag); - await dropOnUpdateTrigger(knex, TableName.SecretApprovalRequestSecret); - await dropOnUpdateTrigger(knex, TableName.SecretApprovalRequestReviewer); - await dropOnUpdateTrigger(knex, TableName.SecretApprovalRequest); -} diff --git a/pg-migrator/src/migrations/20240102152111_secret-rotation.ts b/pg-migrator/src/migrations/20240102152111_secret-rotation.ts deleted file mode 100644 index f7009488a..000000000 --- a/pg-migrator/src/migrations/20240102152111_secret-rotation.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SecretRotation))) { - await knex.schema.createTable(TableName.SecretRotation, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("provider").notNullable(); - t.string("secretPath").notNullable(); - t.integer("interval").notNullable(); - t.datetime("lastRotatedAt"); - t.string("status"); - t.text("statusMessage"); - t.text("encryptedData"); - t.text("encryptedDataIV"); - t.text("encryptedDataTag"); - t.string("algorithm"); - t.string("keyEncoding"); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.SecretRotation); - - if (!(await knex.schema.hasTable(TableName.SecretRotationOutput))) { - await knex.schema.createTable(TableName.SecretRotationOutput, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("key").notNullable(); - t.uuid("secretId").notNullable(); - t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("CASCADE"); - t.uuid("rotationId").notNullable(); - t.foreign("rotationId") - .references("id") - .inTable(TableName.SecretRotation) - .onDelete("CASCADE"); - }); - } -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretRotationOutput); - await knex.schema.dropTableIfExists(TableName.SecretRotation); - await dropOnUpdateTrigger(knex, TableName.SecretRotation); -} diff --git a/pg-migrator/src/migrations/20240104140641_secret-snapshot.ts b/pg-migrator/src/migrations/20240104140641_secret-snapshot.ts deleted file mode 100644 index 01b1e24fb..000000000 --- a/pg-migrator/src/migrations/20240104140641_secret-snapshot.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.Snapshot))) { - await knex.schema.createTable(TableName.Snapshot, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - // this is not a relation kept like that - // this ensure snapshot are not lost when folder gets deleted and rolled back - t.uuid("folderId").notNullable(); - t.uuid("parentFolderId"); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.Snapshot); - - if (!(await knex.schema.hasTable(TableName.SnapshotSecret))) { - await knex.schema.createTable(TableName.SnapshotSecret, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - // not a relation kept like that to keep it when rolled back - t.uuid("secretVersionId").notNullable(); - t.foreign("secretVersionId") - .references("id") - .inTable(TableName.SecretVersion) - .onDelete("CASCADE"); - t.uuid("snapshotId").notNullable(); - t.foreign("snapshotId").references("id").inTable(TableName.Snapshot).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - - if (!(await knex.schema.hasTable(TableName.SnapshotFolder))) { - await knex.schema.createTable(TableName.SnapshotFolder, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.uuid("envId").notNullable(); - t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); - // not a relation kept like that to keep it when rolled back - t.uuid("folderVersionId").notNullable(); - t.foreign("folderVersionId") - .references("id") - .inTable(TableName.SecretFolderVersion) - .onDelete("CASCADE"); - t.uuid("snapshotId").notNullable(); - t.foreign("snapshotId").references("id").inTable(TableName.Snapshot).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SnapshotSecret); - await knex.schema.dropTableIfExists(TableName.SnapshotFolder); - await knex.schema.dropTableIfExists(TableName.Snapshot); - await dropOnUpdateTrigger(knex, TableName.Snapshot); -} diff --git a/pg-migrator/src/migrations/20240107153439_saml-config.ts b/pg-migrator/src/migrations/20240107153439_saml-config.ts deleted file mode 100644 index 76070dc68..000000000 --- a/pg-migrator/src/migrations/20240107153439_saml-config.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.SamlConfig))) { - await knex.schema.createTable(TableName.SamlConfig, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("authProvider").notNullable(); - t.boolean("isActive").notNullable(); - t.string("encryptedEntryPoint"); - t.string("entryPointIV"); - t.string("entryPointTag"); - t.string("encryptedIssuer"); - t.string("issuerTag"); - t.string("issuerIV"); - t.text("encryptedCert"); - t.string("certIV"); - t.string("certTag"); - t.timestamps(true, true, true); - t.uuid("orgId").notNullable().unique(); - t.foreign("orgId").references("id").inTable(TableName.Organization); - }); - } - - await createOnUpdateTrigger(knex, TableName.SamlConfig); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SamlConfig); - await dropOnUpdateTrigger(knex, TableName.SamlConfig); -} diff --git a/pg-migrator/src/migrations/20240107163155_org-bot.ts b/pg-migrator/src/migrations/20240107163155_org-bot.ts deleted file mode 100644 index 6e4365f9d..000000000 --- a/pg-migrator/src/migrations/20240107163155_org-bot.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.OrgBot))) { - await knex.schema.createTable(TableName.OrgBot, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("name").notNullable(); - t.text("publicKey").notNullable(); - t.text("encryptedSymmetricKey").notNullable(); - t.text("symmetricKeyIV").notNullable(); - t.text("symmetricKeyTag").notNullable(); - t.string("symmetricKeyAlgorithm").notNullable(); - t.string("symmetricKeyKeyEncoding").notNullable(); - t.text("encryptedPrivateKey").notNullable(); - t.text("privateKeyIV").notNullable(); - t.text("privateKeyTag").notNullable(); - t.string("privateKeyAlgorithm").notNullable(); - t.string("privateKeyKeyEncoding").notNullable(); - // one to one relationship - t.uuid("orgId").notNullable().unique(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - - await createOnUpdateTrigger(knex, TableName.OrgBot); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.OrgBot); - await dropOnUpdateTrigger(knex, TableName.OrgBot); -} diff --git a/pg-migrator/src/migrations/20240108134148_audit-log.ts b/pg-migrator/src/migrations/20240108134148_audit-log.ts deleted file mode 100644 index 9eb74f03d..000000000 --- a/pg-migrator/src/migrations/20240108134148_audit-log.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.AuditLog))) { - await knex.schema.createTable(TableName.AuditLog, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("actor").notNullable(); - t.jsonb("actorMetadata").notNullable(); - t.string("ipAddress"); - t.string("eventType").notNullable(); - t.jsonb("eventMetadata"); - t.string("userAgent"); - t.string("userAgentType"); - t.datetime("expiresAt"); - t.timestamps(true, true, true); - // no trigger needed as this collection is append only - t.uuid("orgId"); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.string("projectId"); - t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); - }); - } -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.AuditLog); -} diff --git a/pg-migrator/src/migrations/20240111051011_secret-scanning.ts b/pg-migrator/src/migrations/20240111051011_secret-scanning.ts deleted file mode 100644 index af011d558..000000000 --- a/pg-migrator/src/migrations/20240111051011_secret-scanning.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.GitAppInstallSession))) { - await knex.schema.createTable(TableName.GitAppInstallSession, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("sessionId").notNullable().unique(); - t.uuid("userId"); - // one to one relationship - t.uuid("orgId").notNullable().unique(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - createOnUpdateTrigger(knex, TableName.GitAppInstallSession); - - if (!(await knex.schema.hasTable(TableName.GitAppOrg))) { - await knex.schema.createTable(TableName.GitAppOrg, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("installationId").notNullable().unique(); - t.uuid("userId").notNullable(); - // one to one relationship - t.uuid("orgId").notNullable().unique(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - createOnUpdateTrigger(knex, TableName.GitAppOrg); - - if (!(await knex.schema.hasTable(TableName.SecretScanningGitRisk))) { - await knex.schema.createTable(TableName.SecretScanningGitRisk, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("description"); - t.string("startLine"); - t.string("endLine"); - t.string("startColumn"); - t.string("endColumn"); - t.string("file"); - t.string("symlinkFile"); - t.string("commit"); - t.string("entropy"); - t.string("author"); - t.string("email"); - t.string("date"); - t.text("message"); - t.specificType("tags", "text[]"); - t.string("ruleID"); - t.string("fingerprint").unique(); - t.string("fingerPrintWithoutCommitId"); - t.boolean("isFalsePositive").defaultTo(false); - t.boolean("isResolved").defaultTo(false); - t.string("riskOwner"); - t.string("installationId").notNullable(); - t.string("repositoryId"); - t.string("repositoryLink"); - t.string("repositoryFullName"); - t.string("pusherName"); - t.string("pusherEmail"); - t.string("status"); - // one to one relationship - t.uuid("orgId").notNullable(); - t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); - t.timestamps(true, true, true); - }); - } - createOnUpdateTrigger(knex, TableName.SecretScanningGitRisk); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.SecretScanningGitRisk); - await knex.schema.dropTableIfExists(TableName.GitAppOrg); - await knex.schema.dropTableIfExists(TableName.GitAppInstallSession); - await dropOnUpdateTrigger(knex, TableName.SecretScanningGitRisk); - await dropOnUpdateTrigger(knex, TableName.GitAppOrg); - await dropOnUpdateTrigger(knex, TableName.GitAppInstallSession); -} diff --git a/pg-migrator/src/migrations/20240113103743_trusted-ip.ts b/pg-migrator/src/migrations/20240113103743_trusted-ip.ts deleted file mode 100644 index 2924f0668..000000000 --- a/pg-migrator/src/migrations/20240113103743_trusted-ip.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "../schemas"; -import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; - -export async function up(knex: Knex): Promise { - if (!(await knex.schema.hasTable(TableName.TrustedIps))) { - await knex.schema.createTable(TableName.TrustedIps, (t) => { - t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - t.string("ipAddress").notNullable(); - t.string("type").notNullable(); - t.integer("prefix"); - t.boolean("isActive").defaultTo(true); - t.string("comment"); - t.string("projectId").notNullable(); - t.foreign("projectId").references("id").inTable(TableName.Project); - t.timestamps(true, true, true); - }); - } - await createOnUpdateTrigger(knex, TableName.TrustedIps); -} - -export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists(TableName.TrustedIps); - await dropOnUpdateTrigger(knex, TableName.TrustedIps); -} diff --git a/pg-migrator/src/models/apiKeyData.ts b/pg-migrator/src/models/apiKeyData.ts deleted file mode 100644 index ac6a09358..000000000 --- a/pg-migrator/src/models/apiKeyData.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IAPIKeyData { - _id: Types.ObjectId; - name: string; - user: Types.ObjectId; - lastUsed: Date; - expiresAt: Date; - secretHash: string; -} - -const apiKeyDataSchema = new Schema( - { - name: { - type: String, - required: true, - }, - user: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - lastUsed: { - type: Date, - }, - expiresAt: { - type: Date, - }, - secretHash: { - type: String, - required: true, - }, - }, - { - timestamps: true, - }, -); - -export const APIKeyData = model("APIKeyData", apiKeyDataSchema); diff --git a/pg-migrator/src/models/apiKeyDataV2.ts b/pg-migrator/src/models/apiKeyDataV2.ts deleted file mode 100644 index 6775a0878..000000000 --- a/pg-migrator/src/models/apiKeyDataV2.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export interface IAPIKeyDataV2 extends Document { - _id: Types.ObjectId; - name: string; - user: Types.ObjectId; - lastUsed?: Date - usageCount: number; - expiresAt?: Date; -} - -const apiKeyDataV2Schema = new Schema( - { - name: { - type: String, - required: true - }, - user: { - type: Schema.Types.ObjectId, - ref: "User", - required: true - }, - lastUsed: { - type: Date, - required: false - }, - usageCount: { - type: Number, - default: 0, - required: true - } - }, - { - timestamps: true - } -); - -export const APIKeyDataV2 = model("APIKeyDataV2", apiKeyDataV2Schema); \ No newline at end of file diff --git a/pg-migrator/src/models/auditLog/auditLog.ts b/pg-migrator/src/models/auditLog/auditLog.ts deleted file mode 100644 index cceabb9f4..000000000 --- a/pg-migrator/src/models/auditLog/auditLog.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Schema, Types, model } from "mongoose"; -import { ActorType, EventType, UserAgentType } from "./enums"; -import { Actor, Event } from "./types"; - -export interface IAuditLog { - actor: Actor; - organization: Types.ObjectId; - workspace: Types.ObjectId; - ipAddress: string; - event: Event; - userAgent: string; - userAgentType: UserAgentType; - expiresAt?: Date; -} - -const auditLogSchema = new Schema( - { - actor: { - type: { - type: String, - enum: ActorType, - required: true, - }, - metadata: { - type: Schema.Types.Mixed, - }, - }, - organization: { - type: Schema.Types.ObjectId, - required: false, - }, - workspace: { - type: Schema.Types.ObjectId, - required: false, - index: true, - }, - ipAddress: { - type: String, - required: true, - }, - event: { - type: { - type: String, - enum: EventType, - required: true, - }, - metadata: { - type: Schema.Types.Mixed, - }, - }, - userAgent: { - type: String, - required: true, - }, - userAgentType: { - type: String, - enum: UserAgentType, - required: true, - }, - expiresAt: { - type: Date, - expires: 0, - }, - }, - { - timestamps: true, - }, -); - -export const AuditLog = model("AuditLog", auditLogSchema); diff --git a/pg-migrator/src/models/auditLog/enums.ts b/pg-migrator/src/models/auditLog/enums.ts deleted file mode 100644 index ad0051bbc..000000000 --- a/pg-migrator/src/models/auditLog/enums.ts +++ /dev/null @@ -1,69 +0,0 @@ -export enum ActorType { // would extend to AWS, Azure, ... - USER = "user", // userIdentity - SERVICE = "service", - IDENTITY = "identity" -} - -export enum UserAgentType { - WEB = "web", - CLI = "cli", - K8_OPERATOR = "k8-operator", - TERRAFORM = "terraform", - OTHER = "other", - PYTHON_SDK = "InfisicalPythonSDK", - NODE_SDK = "InfisicalNodeSDK" -} - -export enum EventType { - GET_SECRETS = "get-secrets", - GET_SECRET = "get-secret", - REVEAL_SECRET = "reveal-secret", - CREATE_SECRET = "create-secret", - CREATE_SECRETS = "create-secrets", - UPDATE_SECRET = "update-secret", - UPDATE_SECRETS = "update-secrets", - DELETE_SECRET = "delete-secret", - DELETE_SECRETS = "delete-secrets", - GET_WORKSPACE_KEY = "get-workspace-key", - AUTHORIZE_INTEGRATION = "authorize-integration", - UNAUTHORIZE_INTEGRATION = "unauthorize-integration", - CREATE_INTEGRATION = "create-integration", - DELETE_INTEGRATION = "delete-integration", - ADD_TRUSTED_IP = "add-trusted-ip", - UPDATE_TRUSTED_IP = "update-trusted-ip", - DELETE_TRUSTED_IP = "delete-trusted-ip", - CREATE_SERVICE_TOKEN = "create-service-token", // v2 - DELETE_SERVICE_TOKEN = "delete-service-token", // v2 - CREATE_IDENTITY = "create-identity", - UPDATE_IDENTITY = "update-identity", - DELETE_IDENTITY = "delete-identity", - LOGIN_IDENTITY_UNIVERSAL_AUTH = "login-identity-universal-auth", - ADD_IDENTITY_UNIVERSAL_AUTH = "add-identity-universal-auth", - UPDATE_IDENTITY_UNIVERSAL_AUTH = "update-identity-universal-auth", - GET_IDENTITY_UNIVERSAL_AUTH = "get-identity-universal-auth", - CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "create-identity-universal-auth-client-secret", - REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "revoke-identity-universal-auth-client-secret", - GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS = "get-identity-universal-auth-client-secret", - CREATE_ENVIRONMENT = "create-environment", - UPDATE_ENVIRONMENT = "update-environment", - DELETE_ENVIRONMENT = "delete-environment", - ADD_WORKSPACE_MEMBER = "add-workspace-member", - ADD_BATCH_WORKSPACE_MEMBER = "add-workspace-members", - REMOVE_WORKSPACE_MEMBER = "remove-workspace-member", - CREATE_FOLDER = "create-folder", - UPDATE_FOLDER = "update-folder", - DELETE_FOLDER = "delete-folder", - CREATE_WEBHOOK = "create-webhook", - UPDATE_WEBHOOK_STATUS = "update-webhook-status", - DELETE_WEBHOOK = "delete-webhook", - GET_SECRET_IMPORTS = "get-secret-imports", - CREATE_SECRET_IMPORT = "create-secret-import", - UPDATE_SECRET_IMPORT = "update-secret-import", - DELETE_SECRET_IMPORT = "delete-secret-import", - UPDATE_USER_WORKSPACE_ROLE = "update-user-workspace-role", - UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS = "update-user-workspace-denied-permissions", - SECRET_APPROVAL_MERGED = "secret-approval-merged", - SECRET_APPROVAL_REQUEST = "secret-approval-request", - SECRET_APPROVAL_CLOSED = "secret-approval-closed", - SECRET_APPROVAL_REOPENED = "secret-approval-reopened" -} diff --git a/pg-migrator/src/models/auditLog/index.ts b/pg-migrator/src/models/auditLog/index.ts deleted file mode 100644 index 37b86b5d1..000000000 --- a/pg-migrator/src/models/auditLog/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./auditLog"; -export * from "./enums"; -export * from "./types"; \ No newline at end of file diff --git a/pg-migrator/src/models/auditLog/types.ts b/pg-migrator/src/models/auditLog/types.ts deleted file mode 100644 index a4e470414..000000000 --- a/pg-migrator/src/models/auditLog/types.ts +++ /dev/null @@ -1,585 +0,0 @@ -import { ActorType, EventType } from "./enums"; -import { IIdentityTrustedIp } from "../../../models"; - -interface UserActorMetadata { - userId: string; - email: string; -} - -interface ServiceActorMetadata { - serviceId: string; - name: string; -} - -interface IdentityActorMetadata { - identityId: string; - name: string; -} - -export interface UserActor { - type: ActorType.USER; - metadata: UserActorMetadata; -} - -export interface ServiceActor { - type: ActorType.SERVICE; - metadata: ServiceActorMetadata; -} - -export interface IdentityActor { - type: ActorType.IDENTITY; - metadata: IdentityActorMetadata; -} - -export type Actor = UserActor | ServiceActor | IdentityActor; - -interface GetSecretsEvent { - type: EventType.GET_SECRETS; - metadata: { - environment: string; - secretPath: string; - numberOfSecrets: number; - }; -} - -interface GetSecretEvent { - type: EventType.GET_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface CreateSecretEvent { - type: EventType.CREATE_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface CreateSecretBatchEvent { - type: EventType.CREATE_SECRETS; - metadata: { - environment: string; - secretPath: string; - secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>; - }; -} - -interface UpdateSecretEvent { - type: EventType.UPDATE_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface UpdateSecretBatchEvent { - type: EventType.UPDATE_SECRETS; - metadata: { - environment: string; - secretPath: string; - secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>; - }; -} - -interface DeleteSecretEvent { - type: EventType.DELETE_SECRET; - metadata: { - environment: string; - secretPath: string; - secretId: string; - secretKey: string; - secretVersion: number; - }; -} - -interface DeleteSecretBatchEvent { - type: EventType.DELETE_SECRETS; - metadata: { - environment: string; - secretPath: string; - secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>; - }; -} - -interface GetWorkspaceKeyEvent { - type: EventType.GET_WORKSPACE_KEY; - metadata: { - keyId: string; - }; -} - -interface AuthorizeIntegrationEvent { - type: EventType.AUTHORIZE_INTEGRATION; - metadata: { - integration: string; - }; -} - -interface UnauthorizeIntegrationEvent { - type: EventType.UNAUTHORIZE_INTEGRATION; - metadata: { - integration: string; - }; -} - -interface CreateIntegrationEvent { - type: EventType.CREATE_INTEGRATION; - metadata: { - integrationId: string; - integration: string; // TODO: fix type - environment: string; - secretPath: string; - url?: string; - app?: string; - appId?: string; - targetEnvironment?: string; - targetEnvironmentId?: string; - targetService?: string; - targetServiceId?: string; - path?: string; - region?: string; - }; -} - -interface DeleteIntegrationEvent { - type: EventType.DELETE_INTEGRATION; - metadata: { - integrationId: string; - integration: string; // TODO: fix type - environment: string; - secretPath: string; - url?: string; - app?: string; - appId?: string; - targetEnvironment?: string; - targetEnvironmentId?: string; - targetService?: string; - targetServiceId?: string; - path?: string; - region?: string; - }; -} - -interface AddTrustedIPEvent { - type: EventType.ADD_TRUSTED_IP; - metadata: { - trustedIpId: string; - ipAddress: string; - prefix?: number; - }; -} - -interface UpdateTrustedIPEvent { - type: EventType.UPDATE_TRUSTED_IP; - metadata: { - trustedIpId: string; - ipAddress: string; - prefix?: number; - }; -} - -interface DeleteTrustedIPEvent { - type: EventType.DELETE_TRUSTED_IP; - metadata: { - trustedIpId: string; - ipAddress: string; - prefix?: number; - }; -} - -interface CreateServiceTokenEvent { - type: EventType.CREATE_SERVICE_TOKEN; - metadata: { - name: string; - scopes: Array<{ - environment: string; - secretPath: string; - }>; - }; -} - -interface DeleteServiceTokenEvent { - type: EventType.DELETE_SERVICE_TOKEN; - metadata: { - name: string; - scopes: Array<{ - environment: string; - secretPath: string; - }>; - }; -} - -interface CreateIdentityEvent { // note: currently not logging org-role - type: EventType.CREATE_IDENTITY; - metadata: { - identityId: string; - name: string; - }; -} - -interface UpdateIdentityEvent { - type: EventType.UPDATE_IDENTITY; - metadata: { - identityId: string; - name?: string; - }; -} - -interface DeleteIdentityEvent { - type: EventType.DELETE_IDENTITY; - metadata: { - identityId: string; - }; -} - -interface LoginIdentityUniversalAuthEvent { - type: EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH ; - metadata: { - identityId: string; - identityUniversalAuthId: string; - clientSecretId: string; - identityAccessTokenId: string; - }; -} - -interface AddIdentityUniversalAuthEvent { - type: EventType.ADD_IDENTITY_UNIVERSAL_AUTH; - metadata: { - identityId: string; - clientSecretTrustedIps: Array; - accessTokenTTL: number; - accessTokenMaxTTL: number; - accessTokenNumUsesLimit: number; - accessTokenTrustedIps: Array; - }; -} - -interface UpdateIdentityUniversalAuthEvent { - type: EventType.UPDATE_IDENTITY_UNIVERSAL_AUTH; - metadata: { - identityId: string; - clientSecretTrustedIps?: Array; - accessTokenTTL?: number; - accessTokenMaxTTL?: number; - accessTokenNumUsesLimit?: number; - accessTokenTrustedIps?: Array; - }; -} - -interface GetIdentityUniversalAuthEvent { - type: EventType.GET_IDENTITY_UNIVERSAL_AUTH; - metadata: { - identityId: string; - }; -} - -interface CreateIdentityUniversalAuthClientSecretEvent { - type: EventType.CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET ; - metadata: { - identityId: string; - clientSecretId: string; - }; -} - -interface GetIdentityUniversalAuthClientSecretsEvent { - type: EventType.GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS; - metadata: { - identityId: string; - }; -} - - -interface RevokeIdentityUniversalAuthClientSecretEvent { - type: EventType.REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET ; - metadata: { - identityId: string; - clientSecretId: string; - }; -} - -interface CreateEnvironmentEvent { - type: EventType.CREATE_ENVIRONMENT; - metadata: { - name: string; - slug: string; - }; -} - -interface UpdateEnvironmentEvent { - type: EventType.UPDATE_ENVIRONMENT; - metadata: { - oldName: string; - newName: string; - oldSlug: string; - newSlug: string; - }; -} - -interface DeleteEnvironmentEvent { - type: EventType.DELETE_ENVIRONMENT; - metadata: { - name: string; - slug: string; - }; -} - -interface AddWorkspaceMemberEvent { - type: EventType.ADD_WORKSPACE_MEMBER; - metadata: { - userId: string; - email: string; - }; -} - -interface AddBatchWorkspaceMemberEvent { - type: EventType.ADD_BATCH_WORKSPACE_MEMBER; - metadata: Array<{ - userId: string; - email: string; - }>; -} - -interface RemoveWorkspaceMemberEvent { - type: EventType.REMOVE_WORKSPACE_MEMBER; - metadata: { - userId: string; - email: string; - }; -} - -interface CreateFolderEvent { - type: EventType.CREATE_FOLDER; - metadata: { - environment: string; - folderId: string; - folderName: string; - folderPath: string; - }; -} - -interface UpdateFolderEvent { - type: EventType.UPDATE_FOLDER; - metadata: { - environment: string; - folderId: string; - oldFolderName: string; - newFolderName: string; - folderPath: string; - }; -} - -interface DeleteFolderEvent { - type: EventType.DELETE_FOLDER; - metadata: { - environment: string; - folderId: string; - folderName: string; - folderPath: string; - }; -} - -interface CreateWebhookEvent { - type: EventType.CREATE_WEBHOOK; - metadata: { - webhookId: string; - environment: string; - secretPath: string; - webhookUrl: string; - isDisabled: boolean; - }; -} - -interface UpdateWebhookStatusEvent { - type: EventType.UPDATE_WEBHOOK_STATUS; - metadata: { - webhookId: string; - environment: string; - secretPath: string; - webhookUrl: string; - isDisabled: boolean; - }; -} - -interface DeleteWebhookEvent { - type: EventType.DELETE_WEBHOOK; - metadata: { - webhookId: string; - environment: string; - secretPath: string; - webhookUrl: string; - isDisabled: boolean; - }; -} - -interface GetSecretImportsEvent { - type: EventType.GET_SECRET_IMPORTS; - metadata: { - environment: string; - secretImportId: string; - folderId: string; - numberOfImports: number; - }; -} - -interface CreateSecretImportEvent { - type: EventType.CREATE_SECRET_IMPORT; - metadata: { - secretImportId: string; - folderId: string; - importFromEnvironment: string; - importFromSecretPath: string; - importToEnvironment: string; - importToSecretPath: string; - }; -} - -interface UpdateSecretImportEvent { - type: EventType.UPDATE_SECRET_IMPORT; - metadata: { - secretImportId: string; - folderId: string; - importToEnvironment: string; - importToSecretPath: string; - orderBefore: { - environment: string; - secretPath: string; - }[]; - orderAfter: { - environment: string; - secretPath: string; - }[]; - }; -} - -interface DeleteSecretImportEvent { - type: EventType.DELETE_SECRET_IMPORT; - metadata: { - secretImportId: string; - folderId: string; - importFromEnvironment: string; - importFromSecretPath: string; - importToEnvironment: string; - importToSecretPath: string; - }; -} - -interface UpdateUserRole { - type: EventType.UPDATE_USER_WORKSPACE_ROLE; - metadata: { - userId: string; - email: string; - oldRole: string; - newRole: string; - }; -} - -interface UpdateUserDeniedPermissions { - type: EventType.UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS; - metadata: { - userId: string; - email: string; - deniedPermissions: { - environmentSlug: string; - ability: string; - }[]; - }; -} -interface SecretApprovalMerge { - type: EventType.SECRET_APPROVAL_MERGED; - metadata: { - mergedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -interface SecretApprovalClosed { - type: EventType.SECRET_APPROVAL_CLOSED; - metadata: { - closedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -interface SecretApprovalReopened { - type: EventType.SECRET_APPROVAL_REOPENED; - metadata: { - reopenedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -interface SecretApprovalRequest { - type: EventType.SECRET_APPROVAL_REQUEST; - metadata: { - committedBy: string; - secretApprovalRequestSlug: string; - secretApprovalRequestId: string; - }; -} - -export type Event = - | GetSecretsEvent - | GetSecretEvent - | CreateSecretEvent - | CreateSecretBatchEvent - | UpdateSecretEvent - | UpdateSecretBatchEvent - | DeleteSecretEvent - | DeleteSecretBatchEvent - | GetWorkspaceKeyEvent - | AuthorizeIntegrationEvent - | UnauthorizeIntegrationEvent - | CreateIntegrationEvent - | DeleteIntegrationEvent - | AddTrustedIPEvent - | UpdateTrustedIPEvent - | DeleteTrustedIPEvent - | CreateServiceTokenEvent - | DeleteServiceTokenEvent - | CreateIdentityEvent - | UpdateIdentityEvent - | DeleteIdentityEvent - | LoginIdentityUniversalAuthEvent - | AddIdentityUniversalAuthEvent - | UpdateIdentityUniversalAuthEvent - | GetIdentityUniversalAuthEvent - | CreateIdentityUniversalAuthClientSecretEvent - | GetIdentityUniversalAuthClientSecretsEvent - | RevokeIdentityUniversalAuthClientSecretEvent - | CreateEnvironmentEvent - | UpdateEnvironmentEvent - | DeleteEnvironmentEvent - | AddWorkspaceMemberEvent - | AddBatchWorkspaceMemberEvent - | RemoveWorkspaceMemberEvent - | CreateFolderEvent - | UpdateFolderEvent - | DeleteFolderEvent - | CreateWebhookEvent - | UpdateWebhookStatusEvent - | DeleteWebhookEvent - | GetSecretImportsEvent - | CreateSecretImportEvent - | UpdateSecretImportEvent - | DeleteSecretImportEvent - | UpdateUserRole - | UpdateUserDeniedPermissions - | SecretApprovalMerge - | SecretApprovalClosed - | SecretApprovalRequest - | SecretApprovalReopened; diff --git a/pg-migrator/src/models/backupPrivateKey.ts b/pg-migrator/src/models/backupPrivateKey.ts deleted file mode 100644 index 47e4b8909..000000000 --- a/pg-migrator/src/models/backupPrivateKey.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IBackupPrivateKey { - _id: Types.ObjectId; - user: Types.ObjectId; - encryptedPrivateKey: string; - iv: string; - tag: string; - salt: string; - algorithm: string; - keyEncoding: "base64" | "utf8"; - verifier: string; - createdAt: string; - updatedAt: string; -} - -const backupPrivateKeySchema = new Schema( - { - user: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - encryptedPrivateKey: { - type: String, - - required: true, - }, - iv: { - type: String, - - required: true, - }, - tag: { - type: String, - - required: true, - }, - algorithm: { - // the encryption algorithm used - type: String, - required: true, - }, - keyEncoding: { - type: String, - required: true, - }, - salt: { - type: String, - - required: true, - }, - verifier: { - type: String, - - required: true, - }, - }, - { - timestamps: true, - }, -); - -export const BackupPrivateKey = model( - "BackupPrivateKey", - backupPrivateKeySchema, -); diff --git a/pg-migrator/src/models/bot.ts b/pg-migrator/src/models/bot.ts deleted file mode 100644 index 1d024191c..000000000 --- a/pg-migrator/src/models/bot.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IBot { - _id: Types.ObjectId; - name: string; - workspace: Types.ObjectId; - isActive: boolean; - publicKey: string; - encryptedPrivateKey: string; - iv: string; - tag: string; - algorithm: "aes-256-gcm"; - keyEncoding: "base64" | "utf8"; -} - -const botSchema = new Schema( - { - name: { - type: String, - required: true, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - isActive: { - type: Boolean, - required: true, - default: false, - }, - publicKey: { - type: String, - required: true, - }, - encryptedPrivateKey: { - type: String, - required: true, - - }, - iv: { - type: String, - required: true, - - }, - tag: { - type: String, - required: true, - - }, - algorithm: { - // the encryption algorithm used - type: String, - required: true, - - }, - keyEncoding: { - type: String, - required: true, - - }, - }, - { - timestamps: true, - }, -); - -export const Bot = model("Bot", botSchema); diff --git a/pg-migrator/src/models/botKey.ts b/pg-migrator/src/models/botKey.ts deleted file mode 100644 index 02a6d6ea9..000000000 --- a/pg-migrator/src/models/botKey.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IBotKey { - _id: Types.ObjectId; - encryptedKey: string; - nonce: string; - sender: Types.ObjectId; - bot: Types.ObjectId; - workspace: Types.ObjectId; -} - -const botKeySchema = new Schema( - { - encryptedKey: { - type: String, - required: true, - }, - nonce: { - type: String, - required: true, - }, - sender: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - bot: { - type: Schema.Types.ObjectId, - ref: "Bot", - required: true, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - }, - { - timestamps: true, - } -); - -export const BotKey = model("BotKey", botKeySchema); \ No newline at end of file diff --git a/pg-migrator/src/models/botOrg.ts b/pg-migrator/src/models/botOrg.ts deleted file mode 100644 index 9da98e6c9..000000000 --- a/pg-migrator/src/models/botOrg.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IBotOrg { - _id: Types.ObjectId; - name: string; - organization: Types.ObjectId; - publicKey: string; - encryptedSymmetricKey: string; - symmetricKeyIV: string; - symmetricKeyTag: string; - symmetricKeyAlgorithm: "aes-256-gcm"; - symmetricKeyKeyEncoding: "base64" | "utf8"; - encryptedPrivateKey: string; - privateKeyIV: string; - privateKeyTag: string; - privateKeyAlgorithm: "aes-256-gcm"; - privateKeyKeyEncoding: "base64" | "utf8"; -} - -const botOrgSchema = new Schema( - { - name: { - type: String, - required: true, - }, - organization: { - type: Schema.Types.ObjectId, - ref: "Organization", - required: true, - }, - publicKey: { - type: String, - required: true, - }, - encryptedSymmetricKey: { - type: String, - required: true, - }, - symmetricKeyIV: { - type: String, - required: true, - }, - symmetricKeyTag: { - type: String, - required: true, - }, - symmetricKeyAlgorithm: { - type: String, - required: true, - }, - symmetricKeyKeyEncoding: { - type: String, - required: true, - }, - encryptedPrivateKey: { - type: String, - required: true, - }, - privateKeyIV: { - type: String, - required: true, - }, - privateKeyTag: { - type: String, - required: true, - }, - privateKeyAlgorithm: { - type: String, - required: true, - }, - privateKeyKeyEncoding: { - type: String, - required: true, - }, - }, - { - timestamps: true, - }, -); - -export const BotOrg = model("BotOrg", botOrgSchema); diff --git a/pg-migrator/src/models/folder.ts b/pg-migrator/src/models/folder.ts deleted file mode 100644 index b3016822d..000000000 --- a/pg-migrator/src/models/folder.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export type TFolderRootSchema = { - _id: Types.ObjectId; - workspace: Types.ObjectId; - environment: string; - nodes: TFolderSchema; -}; - -export type TFolderSchema = { - id: string; - name: string; - version: number; - children: TFolderSchema[]; -}; - -const folderSchema = new Schema({ - id: { - required: true, - type: String, - }, - version: { - required: true, - type: Number, - default: 1, - }, - name: { - required: true, - type: String, - default: "root", - }, -}); - -folderSchema.add({ children: [folderSchema] }); - -const folderRootSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - environment: { - type: String, - required: true, - }, - nodes: folderSchema, - }, - { - timestamps: true, - } -); - -export const Folder = model("Folder", folderRootSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/folderVersion.ts b/pg-migrator/src/models/folderVersion.ts deleted file mode 100644 index dbcebcb92..000000000 --- a/pg-migrator/src/models/folderVersion.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export type TFolderRootVersionSchema = { - _id: Types.ObjectId; - workspace: Types.ObjectId; - environment: string; - nodes: TFolderVersionSchema; -}; - -export type TFolderVersionSchema = { - id: string; - name: string; - version: number; - children: TFolderVersionSchema[]; -}; - -const folderVersionSchema = new Schema({ - id: { - required: true, - type: String, - default: "root", - }, - name: { - required: true, - type: String, - default: "root", - }, - version: { - required: true, - type: Number, - default: 1, - }, -}); - -folderVersionSchema.add({ children: [folderVersionSchema] }); - -const folderRootVersionSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - environment: { - type: String, - required: true, - }, - nodes: folderVersionSchema, - }, - { - timestamps: true, - } -); - -export const FolderVersion = model( - "FolderVersion", - folderRootVersionSchema -); \ No newline at end of file diff --git a/pg-migrator/src/models/gitAppInstallationSession.ts b/pg-migrator/src/models/gitAppInstallationSession.ts deleted file mode 100644 index 0cdf8df3c..000000000 --- a/pg-migrator/src/models/gitAppInstallationSession.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -type GitAppInstallationSession = { - id: string; - sessionId: string; - organization: Types.ObjectId; - user: Types.ObjectId; -} - -const gitAppInstallationSession = new Schema({ - id: { - required: true, - type: String, - }, - sessionId: { - type: String, - required: true, - unique: true - }, - organization: { - type: Schema.Types.ObjectId, - required: true, - unique: true - }, - user: { - type: Schema.Types.ObjectId, - ref: "User" - } -}); - - -export const GitAppInstallationSession = model("git_app_installation_session", gitAppInstallationSession); \ No newline at end of file diff --git a/pg-migrator/src/models/gitAppOrganizationInstallation.ts b/pg-migrator/src/models/gitAppOrganizationInstallation.ts deleted file mode 100644 index 4ce55b0cb..000000000 --- a/pg-migrator/src/models/gitAppOrganizationInstallation.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Schema, model } from "mongoose"; - -type Installation = { - installationId: string - organizationId: string - user: Schema.Types.ObjectId -}; - - -const gitAppOrganizationInstallation = new Schema({ - installationId: { - type: String, - required: true, - unique: true - }, - organizationId: { - type: String, - required: true, - unique: true - }, - user: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - } -}); - - -export const GitAppOrganizationInstallation = model("git_app_organization_installation", gitAppOrganizationInstallation); \ No newline at end of file diff --git a/pg-migrator/src/models/gitRisks.ts b/pg-migrator/src/models/gitRisks.ts deleted file mode 100644 index 8d3f59208..000000000 --- a/pg-migrator/src/models/gitRisks.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { Schema, model } from "mongoose"; - -export const STATUS_RESOLVED_FALSE_POSITIVE = "RESOLVED_FALSE_POSITIVE"; -export const STATUS_RESOLVED_REVOKED = "RESOLVED_REVOKED"; -export const STATUS_RESOLVED_NOT_REVOKED = "RESOLVED_NOT_REVOKED"; -export const STATUS_UNRESOLVED = "UNRESOLVED"; - -export type IGitRisks = { - id: string; - description: string; - startLine: string; - endLine: string; - startColumn: string; - endColumn: string; - match: string; - secret: string; - file: string; - symlinkFile: string; - commit: string; - entropy: string; - author: string; - email: string; - date: string; - message: string; - tags: string[]; - ruleID: string; - fingerprint: string; - fingerPrintWithoutCommitId: string - - isFalsePositive: boolean; // New field for marking risks as false positives - isResolved: boolean; // New field for marking risks as resolved - riskOwner: string | null; // New field for setting a risk owner (nullable string) - installationId: string, - repositoryId: string, - repositoryLink: string - repositoryFullName: string - status: string - pusher: { - name: string, - email: string - }, - organization: Schema.Types.ObjectId, -} - -const gitRisks = new Schema({ - id: { - type: String, - }, - description: { - type: String, - }, - startLine: { - type: String, - }, - endLine: { - type: String, - }, - startColumn: { - type: String, - }, - endColumn: { - type: String, - }, - file: { - type: String, - }, - symlinkFile: { - type: String, - }, - commit: { - type: String, - }, - entropy: { - type: String, - }, - author: { - type: String, - }, - email: { - type: String, - }, - date: { - type: String, - }, - message: { - type: String, - }, - tags: { - type: [String], - }, - ruleID: { - type: String, - }, - fingerprint: { - type: String, - unique: true - }, - fingerPrintWithoutCommitId: { - type: String, - }, - isFalsePositive: { - type: Boolean, - default: false - }, - isResolved: { - type: Boolean, - default: false - }, - riskOwner: { - type: String, - default: null - }, - installationId: { - type: String, - require: true - }, - repositoryId: { - type: String - }, - repositoryLink: { - type: String - }, - repositoryFullName: { - type: String - }, - pusher: { - name: { - type: String - }, - email: { - type: String - }, - }, - organization: { - type: Schema.Types.ObjectId, - ref: "Organization", - }, - status: { - type: String, - enum: [ - STATUS_RESOLVED_FALSE_POSITIVE, - STATUS_RESOLVED_REVOKED, - STATUS_RESOLVED_NOT_REVOKED, - STATUS_UNRESOLVED - ], - default: STATUS_UNRESOLVED - } -}, { timestamps: true }); - -export const GitRisks = model("GitRisks", gitRisks); \ No newline at end of file diff --git a/pg-migrator/src/models/identity.ts b/pg-migrator/src/models/identity.ts deleted file mode 100644 index ec4948e1b..000000000 --- a/pg-migrator/src/models/identity.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; -import { IPType } from "../ee/models"; - -export interface IIdentityTrustedIp { - ipAddress: string; - type: IPType; - prefix: number; -} - -export enum IdentityAuthMethod { - UNIVERSAL_AUTH = "universal-auth" -} - -export interface IIdentity extends Document { - _id: Types.ObjectId; - name: string; - authMethod?: IdentityAuthMethod; -} - -const identitySchema = new Schema( - { - name: { - type: String, - required: true - }, - authMethod: { - type: String, - enum: IdentityAuthMethod, - required: false, - }, - - }, - { - timestamps: true - } -); - -export const Identity = model("Identity", identitySchema); diff --git a/pg-migrator/src/models/identityAccessToken.ts b/pg-migrator/src/models/identityAccessToken.ts deleted file mode 100644 index d65c6cbce..000000000 --- a/pg-migrator/src/models/identityAccessToken.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; -import { IIdentityTrustedIp } from "./identity"; - -export interface IIdentityAccessToken extends Document { - _id: Types.ObjectId; - identity: Types.ObjectId; - identityUniversalAuthClientSecret?: Types.ObjectId; - accessTokenLastUsedAt?: Date; - accessTokenLastRenewedAt?: Date; - accessTokenNumUses: number; - accessTokenNumUsesLimit: number; - accessTokenTTL: number; - accessTokenMaxTTL: number; - accessTokenTrustedIps: Array; - isAccessTokenRevoked: boolean; - updatedAt: Date; - createdAt: Date; -} - -const identityAccessTokenSchema = new Schema( - { - identity: { - type: Schema.Types.ObjectId, - ref: "Identity", - required: false, - }, - identityUniversalAuthClientSecret: { - type: Schema.Types.ObjectId, - ref: "IdentityUniversalAuthClientSecret", - required: false, - }, - accessTokenLastUsedAt: { - type: Date, - required: false, - }, - accessTokenLastRenewedAt: { - type: Date, - required: false, - }, - accessTokenNumUses: { - // number of times access token has been used - type: Number, - default: 0, - required: true, - }, - accessTokenNumUsesLimit: { - // number of times access token can be used for - type: Number, - default: 0, // default: used as many times as needed - required: true, - }, - accessTokenTTL: { - // seconds - // incremental lifetime - type: Number, - default: 2592000, // 30 days - required: true, - }, - accessTokenMaxTTL: { - // seconds - // max lifetime - type: Number, - default: 2592000, // 30 days - required: true, - }, - accessTokenTrustedIps: { - type: [ - { - ipAddress: { - type: String, - required: true, - }, - type: { - type: String, - required: true, - }, - prefix: { - type: Number, - required: false, - }, - }, - ], - default: [], - required: true, - }, - isAccessTokenRevoked: { - type: Boolean, - default: false, - required: true, - }, - }, - { - timestamps: true, - }, -); - -export const IdentityAccessToken = model( - "IdentityAccessToken", - identityAccessTokenSchema, -); diff --git a/pg-migrator/src/models/identityMembership.ts b/pg-migrator/src/models/identityMembership.ts deleted file mode 100644 index 4c4a12eba..000000000 --- a/pg-migrator/src/models/identityMembership.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IIdentityMembership { - _id: Types.ObjectId; - identity: Types.ObjectId; - workspace: Types.ObjectId; - role: "admin" | "member" | "viewer" | "no-access" | "custom"; - customRole: Types.ObjectId; -} - -const identityMembershipSchema = new Schema( - { - identity: { - type: Schema.Types.ObjectId, - ref: "Identity", - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - index: true, - }, - role: { - type: String, - required: true, - }, - customRole: { - type: Schema.Types.ObjectId, - ref: "Role", - }, - }, - { - timestamps: true, - }, -); - -export const IdentityMembership = model( - "IdentityMembership", - identityMembershipSchema, -); diff --git a/pg-migrator/src/models/identityMembershipOrg.ts b/pg-migrator/src/models/identityMembershipOrg.ts deleted file mode 100644 index 87699467f..000000000 --- a/pg-migrator/src/models/identityMembershipOrg.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IIdentityMembershipOrg { - _id: Types.ObjectId; - identity: Types.ObjectId; - organization: Types.ObjectId; - role: "admin" | "member" | "no-access" | "custom"; - customRole: Types.ObjectId; -} - -const identityMembershipOrgSchema = new Schema( - { - identity: { - type: Schema.Types.ObjectId, - ref: "Identity", - }, - organization: { - type: Schema.Types.ObjectId, - ref: "Organization", - }, - role: { - type: String, - required: true, - }, - customRole: { - type: Schema.Types.ObjectId, - ref: "Role", - }, - }, - { - timestamps: true, - }, -); - -export const IdentityMembershipOrg = model( - "IdentityMembershipOrg", - identityMembershipOrgSchema, -); diff --git a/pg-migrator/src/models/identityUniversalAuth.ts b/pg-migrator/src/models/identityUniversalAuth.ts deleted file mode 100644 index 18b14775a..000000000 --- a/pg-migrator/src/models/identityUniversalAuth.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export interface IIdentityUniversalAuth extends Document { - _id: Types.ObjectId; - identity: Types.ObjectId; - clientId: string; - clientSecretTrustedIps: Array<{}>; - accessTokenTTL: number; - accessTokenMaxTTL: number; - accessTokenNumUsesLimit: number; - accessTokenTrustedIps: Array<{}>; -} - -const identityUniversalAuthSchema = new Schema( - { - identity: { - type: Schema.Types.ObjectId, - ref: "Identity", - required: true, - }, - clientId: { - type: String, - required: true, - }, - clientSecretTrustedIps: { - type: [ - { - ipAddress: { - type: String, - required: true, - }, - type: { - type: String, - required: true, - }, - prefix: { - type: Number, - required: false, - }, - }, - ], - default: [ - { - ipAddress: "0.0.0.0", - prefix: 0, - }, - ], - required: true, - }, - accessTokenTTL: { - // seconds - // incremental lifetime - type: Number, - default: 7200, - required: true, - }, - accessTokenMaxTTL: { - // seconds - // max lifetime - type: Number, - default: 7200, - required: true, - }, - accessTokenNumUsesLimit: { - // number of times access token can be used for - type: Number, - default: 0, // default: used as many times as needed - required: true, - }, - accessTokenTrustedIps: { - type: [ - { - ipAddress: { - type: String, - required: true, - }, - type: { - type: String, - required: true, - }, - prefix: { - type: Number, - required: false, - }, - }, - ], - default: [], - required: true, - }, - }, - { - timestamps: true, - }, -); - -export const IdentityUniversalAuth = model( - "IdentityUniversalAuth", - identityUniversalAuthSchema, -); diff --git a/pg-migrator/src/models/identityUniversalAuthClientSecret.ts b/pg-migrator/src/models/identityUniversalAuthClientSecret.ts deleted file mode 100644 index af9cc08a4..000000000 --- a/pg-migrator/src/models/identityUniversalAuthClientSecret.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export interface IIdentityUniversalAuthClientSecret extends Document { - _id: Types.ObjectId; - identity: Types.ObjectId; - identityUniversalAuth : Types.ObjectId; - description: string; - clientSecretPrefix: string; - clientSecretHash: string; - clientSecretLastUsedAt?: Date; - clientSecretNumUses: number; - clientSecretNumUsesLimit: number; - clientSecretTTL: number; - updatedAt: Date; - createdAt: Date; - isClientSecretRevoked: boolean; -} - -const identityUniversalAuthClientSecretSchema = new Schema( - { - identity: { - type: Schema.Types.ObjectId, - ref: "Identity", - required: true - }, - identityUniversalAuth: { - type: Schema.Types.ObjectId, - ref: "IdentityUniversalAuth", - required: true - }, - description: { - type: String, - required: true - }, - clientSecretPrefix: { - type: String, - required: true - }, - clientSecretHash: { - type: String, - required: true - }, - clientSecretLastUsedAt: { - type: Date, - required: false - }, - clientSecretNumUses: { - // number of times client secret has been used - // in login operation - type: Number, - default: 0, - required: true - }, - clientSecretNumUsesLimit: { - // number of times client secret can be used for - // a login operation - type: Number, - default: 0, // default: used as many times as needed - required: true - }, - clientSecretTTL: { - type: Number, - default: 0, // default: does not expire - required: true - }, - isClientSecretRevoked: { - type: Boolean, - default: false, - required: true - } - }, - { - timestamps: true - } -); - -identityUniversalAuthClientSecretSchema.index( - { identityUniversalAuth: 1, isClientSecretRevoked: 1 } -); - -export const IdentityUniversalAuthClientSecret = model("IdentityUniversalAuthClientSecret", identityUniversalAuthClientSecretSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/incidentContactOrg.ts b/pg-migrator/src/models/incidentContactOrg.ts deleted file mode 100644 index 905b9263f..000000000 --- a/pg-migrator/src/models/incidentContactOrg.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IIncidentContactOrg { - _id: Types.ObjectId; - email: string; - organization: Types.ObjectId; -} - -const incidentContactOrgSchema = new Schema( - { - email: { - type: String, - required: true, - }, - organization: { - type: Schema.Types.ObjectId, - ref: "Organization", - required: true, - }, - }, - { - timestamps: true, - } -); - -export const IncidentContactOrg = model( - "IncidentContactOrg", - incidentContactOrgSchema -); \ No newline at end of file diff --git a/pg-migrator/src/models/index.ts b/pg-migrator/src/models/index.ts deleted file mode 100644 index 2489e30f5..000000000 --- a/pg-migrator/src/models/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -export * from "./backupPrivateKey"; -export * from "./bot"; -export * from "./botOrg"; -export * from "./botKey"; -export * from "./incidentContactOrg"; -export * from "./integration/integration"; -export * from "./integrationAuth"; -export * from "./key"; -export * from "./membership"; -export * from "./membershipOrg"; -export * from "./organization"; -export * from "./secret"; -export * from "./tag"; -export * from "./folder"; -export * from "./secretImports"; -export * from "./secretBlindIndexData"; -export * from "./serviceToken"; // TODO: deprecate -export * from "./tokenData"; -export * from "./user"; -export * from "./userAction"; -export * from "./workspace"; -export * from "./serviceTokenData"; // TODO: deprecate - -// new -export * from "./identity"; -export * from "./identityMembership"; -export * from "./identityMembershipOrg"; -export * from "./identityUniversalAuth"; -export * from "./identityUniversalAuthClientSecret"; -export * from "./identityAccessToken"; - -export * from "./apiKeyData"; // TODO: deprecate -export * from "./apiKeyDataV2"; -export * from "./loginSRPDetail"; -export * from "./tokenVersion"; -export * from "./webhooks"; - -export * from "./secretSnapshot"; -export * from "./secretVersion"; -export * from "./folderVersion"; -export * from "./role"; -export * from "./ssoConfig"; -export * from "./trustedIp"; -export * from "./auditLog"; -export * from "./gitRisks"; -export * from "./gitAppOrganizationInstallation"; -export * from "./gitAppInstallationSession"; -export * from "./secretApprovalPolicy"; -export * from "./secretApprovalRequest"; diff --git a/pg-migrator/src/models/integration/index.ts b/pg-migrator/src/models/integration/index.ts deleted file mode 100644 index 2ed44cd28..000000000 --- a/pg-migrator/src/models/integration/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./integration"; \ No newline at end of file diff --git a/pg-migrator/src/models/integration/integration.ts b/pg-migrator/src/models/integration/integration.ts deleted file mode 100644 index 40578138d..000000000 --- a/pg-migrator/src/models/integration/integration.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { Schema, Types, model } from "mongoose"; -import { Metadata } from "./types"; - -export interface IIntegration { - _id: Types.ObjectId; - workspace: Types.ObjectId; - environment: string; - isActive: boolean; - url: string; - app: string; - appId: string; - owner: string; - targetEnvironment: string; - targetEnvironmentId: string; - targetService: string; - targetServiceId: string; - path: string; - region: string; - scope: string; - secretPath: string; - integration: - | "azure-key-vault" - | "aws-parameter-store" - | "aws-secret-manager" - | "heroku" - | "vercel" - | "netlify" - | "github" - | "gitlab" - | "render" - | "railway" - | "flyio" - | "circleci" - | "laravel-forge" - | "travisci" - | "supabase" - | "checkly" - | "qovery" - | "terraform-cloud" - | "teamcity" - | "hashicorp-vault" - | "cloudflare-pages" - | "cloudflare-workers" - | "bitbucket" - | "codefresh" - | "digital-ocean-app-platform" - | "cloud-66" - | "northflank" - | "windmill" - | "gcp-secret-manager" - | "hasura-cloud"; - integrationAuth: Types.ObjectId; - metadata: Metadata; -} - -const integrationSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - environment: { - type: String, - required: true, - }, - isActive: { - type: Boolean, - required: true, - }, - url: { - // for custom self-hosted integrations (e.g. self-hosted GitHub enterprise) - type: String, - default: null, - }, - app: { - // name of app in provider - type: String, - default: null, - }, - appId: { - // id of app in provider - type: String, - default: null, - }, - targetEnvironment: { - // target environment - type: String, - default: null, - }, - targetEnvironmentId: { - type: String, - default: null, - }, - targetService: { - // railway-specific service - // qovery-specific project - type: String, - default: null, - }, - targetServiceId: { - // railway-specific service - // qovery specific project - type: String, - default: null, - }, - owner: { - // github-specific repo owner-login - type: String, - default: null, - }, - path: { - // aws-parameter-store-specific path - // (also) vercel preview-branch - type: String, - default: null, - }, - region: { - // aws-parameter-store-specific path - type: String, - default: null, - }, - scope: { - // qovery-specific scope - type: String, - default: null, - }, - integration: { - type: String, - required: true, - }, - integrationAuth: { - type: Schema.Types.ObjectId, - ref: "IntegrationAuth", - required: true, - }, - secretPath: { - type: String, - required: true, - default: "/", - }, - metadata: { - type: Schema.Types.Mixed, - default: {}, - }, - }, - { - timestamps: true, - }, -); - -export const Integration = model( - "Integration", - integrationSchema, -); diff --git a/pg-migrator/src/models/integration/types.ts b/pg-migrator/src/models/integration/types.ts deleted file mode 100644 index 635182cd2..000000000 --- a/pg-migrator/src/models/integration/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -export type Metadata = { - secretPrefix?: string; - secretSuffix?: string; - secretGCPLabel?: { - labelName: string; - labelValue: string; - } - secretAWSTag?: { - key: string; - value: string; - }[] - kmsKeyId?: string; -} \ No newline at end of file diff --git a/pg-migrator/src/models/integrationAuth/index.ts b/pg-migrator/src/models/integrationAuth/index.ts deleted file mode 100644 index 157095bd2..000000000 --- a/pg-migrator/src/models/integrationAuth/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./integrationAuth"; \ No newline at end of file diff --git a/pg-migrator/src/models/integrationAuth/integrationAuth.ts b/pg-migrator/src/models/integrationAuth/integrationAuth.ts deleted file mode 100644 index 1c2e6d450..000000000 --- a/pg-migrator/src/models/integrationAuth/integrationAuth.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; -import { IntegrationAuthMetadata } from "./types"; - -export interface IIntegrationAuth extends Document { - _id: Types.ObjectId; - workspace: Types.ObjectId; - integration: - | "heroku" - | "vercel" - | "netlify" - | "github" - | "gitlab" - | "render" - | "railway" - | "flyio" - | "azure-key-vault" - | "laravel-forge" - | "circleci" - | "travisci" - | "supabase" - | "aws-parameter-store" - | "aws-secret-manager" - | "checkly" - | "qovery" - | "cloudflare-pages" - | "cloudflare-workers" - | "codefresh" - | "digital-ocean-app-platform" - | "bitbucket" - | "cloud-66" - | "terraform-cloud" - | "teamcity" - | "northflank" - | "windmill" - | "gcp-secret-manager" - | "hasura-cloud"; - teamId: string; - accountId: string; - url: string; - namespace: string; - refreshCiphertext?: string; - refreshIV?: string; - refreshTag?: string; - accessIdCiphertext?: string; - accessIdIV?: string; - accessIdTag?: string; - accessCiphertext?: string; - accessIV?: string; - accessTag?: string; - algorithm?: "aes-256-gcm"; - keyEncoding?: "utf8" | "base64"; - accessExpiresAt?: Date; - metadata?: IntegrationAuthMetadata; -} - -const integrationAuthSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - integration: { - type: String, - required: true, - }, - teamId: { - // vercel-specific integration param - type: String, - }, - url: { - // for any self-hosted integrations (e.g. self-hosted hashicorp-vault) - type: String, - }, - namespace: { - // hashicorp-vault-specific integration param - type: String, - }, - accountId: { - // netlify-specific integration param - type: String, - }, - refreshCiphertext: { - type: String, - - }, - refreshIV: { - type: String, - - }, - refreshTag: { - type: String, - - }, - accessIdCiphertext: { - type: String, - - }, - accessIdIV: { - type: String, - - }, - accessIdTag: { - type: String, - - }, - accessCiphertext: { - type: String, - - }, - accessIV: { - type: String, - - }, - accessTag: { - type: String, - - }, - accessExpiresAt: { - type: Date, - - }, - algorithm: { - // the encryption algorithm used - type: String, - required: true, - }, - keyEncoding: { - type: String, - required: true, - }, - metadata: { - type: Schema.Types.Mixed, - }, - }, - { - timestamps: true, - }, -); - -export const IntegrationAuth = model( - "IntegrationAuth", - integrationAuthSchema, -); diff --git a/pg-migrator/src/models/integrationAuth/types.ts b/pg-migrator/src/models/integrationAuth/types.ts deleted file mode 100644 index d29869e3b..000000000 --- a/pg-migrator/src/models/integrationAuth/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -interface GCPIntegrationAuthMetadata { - authMethod: "oauth2" | "serviceAccount" -} - -export type IntegrationAuthMetadata = GCPIntegrationAuthMetadata; \ No newline at end of file diff --git a/pg-migrator/src/models/key.ts b/pg-migrator/src/models/key.ts deleted file mode 100644 index d0d6f80f7..000000000 --- a/pg-migrator/src/models/key.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IKey { - _id: Types.ObjectId; - encryptedKey: string; - nonce: string; - sender: Types.ObjectId; - receiver: Types.ObjectId; - workspace: Types.ObjectId; -} - -const keySchema = new Schema( - { - encryptedKey: { - type: String, - required: true, - }, - nonce: { - type: String, - required: true, - }, - sender: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - receiver: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - }, - { - timestamps: true, - }, -); - -export const Key = model("Key", keySchema); diff --git a/pg-migrator/src/models/loginSRPDetail.ts b/pg-migrator/src/models/loginSRPDetail.ts deleted file mode 100644 index 26f897270..000000000 --- a/pg-migrator/src/models/loginSRPDetail.ts +++ /dev/null @@ -1,27 +0,0 @@ -import mongoose, { Schema, Types, model } from "mongoose"; - -export interface ILoginSRPDetail { - _id: Types.ObjectId; - clientPublicKey: string; - email: string; - serverBInt: mongoose.Schema.Types.Buffer; - userId: string; - expireAt: Date; -} - -const loginSRPDetailSchema = new Schema( - { - clientPublicKey: { - type: String, - required: true, - }, - email: { - type: String, - unique: true, - }, - serverBInt: { type: mongoose.Schema.Types.Buffer }, - expireAt: { type: Date }, - } -); - -export const LoginSRPDetail = model("LoginSRPDetail", loginSRPDetailSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/membership.ts b/pg-migrator/src/models/membership.ts deleted file mode 100644 index eb2787082..000000000 --- a/pg-migrator/src/models/membership.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IMembershipPermission { - environmentSlug: string; - ability: string; -} - -export interface IMembership { - _id: Types.ObjectId; - user: Types.ObjectId; - inviteEmail?: string; - workspace: Types.ObjectId; - role: "admin" | "member" | "viewer" | "no-access" | "custom"; - customRole: Types.ObjectId; - deniedPermissions: IMembershipPermission[]; -} - -const membershipSchema = new Schema( - { - user: { - type: Schema.Types.ObjectId, - ref: "User", - }, - inviteEmail: { - type: String, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - deniedPermissions: { - type: [ - { - environmentSlug: String, - ability: { - type: String, - enum: ["read", "write"], - }, - }, - ], - default: [], - }, - role: { - type: String, - required: true, - }, - customRole: { - type: Schema.Types.ObjectId, - ref: "Role", - }, - }, - { - timestamps: true, - }, -); - -export const Membership = model("Membership", membershipSchema); diff --git a/pg-migrator/src/models/membershipOrg.ts b/pg-migrator/src/models/membershipOrg.ts deleted file mode 100644 index 2f02fc28a..000000000 --- a/pg-migrator/src/models/membershipOrg.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export interface IMembershipOrg extends Document { - _id: Types.ObjectId; - user: Types.ObjectId; - inviteEmail: string; - organization: Types.ObjectId; - role: "admin" | "member" | "no-access" | "custom"; - customRole: Types.ObjectId; - status: "invited" | "accepted"; - createdAt: string; - updatedAt: string; -} - -const membershipOrgSchema = new Schema( - { - user: { - type: Schema.Types.ObjectId, - ref: "User", - }, - inviteEmail: { - type: String, - }, - organization: { - type: Schema.Types.ObjectId, - ref: "Organization", - }, - role: { - type: String, - required: true, - }, - status: { - type: String, - required: true, - }, - customRole: { - type: Schema.Types.ObjectId, - ref: "Role", - }, - }, - { - timestamps: true, - }, -); - -export const MembershipOrg = model( - "MembershipOrg", - membershipOrgSchema, -); diff --git a/pg-migrator/src/models/organization.ts b/pg-migrator/src/models/organization.ts deleted file mode 100644 index 31a27411b..000000000 --- a/pg-migrator/src/models/organization.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IOrganization { - _id: Types.ObjectId; - name: string; - customerId?: string; - createdAt: string; - updatedAt: string; -} - -const organizationSchema = new Schema( - { - name: { - type: String, - required: true, - }, - customerId: { - type: String, - }, - }, - { - timestamps: true, - }, -); - -export const Organization = model( - "Organization", - organizationSchema, -); diff --git a/pg-migrator/src/models/role.ts b/pg-migrator/src/models/role.ts deleted file mode 100644 index 536363312..000000000 --- a/pg-migrator/src/models/role.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IRole { - _id: Types.ObjectId; - name: string; - description: string; - slug: string; - permissions: Array; - workspace: Types.ObjectId; - organization: Types.ObjectId; - isOrgRole: boolean; - createdAt: string; - updatedAt: string; -} - -const roleSchema = new Schema( - { - name: { - type: String, - required: true, - }, - organization: { - type: Schema.Types.ObjectId, - ref: "Organization", - required: true, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - }, - isOrgRole: { - type: Boolean, - required: true, - - }, - description: { - type: String, - }, - slug: { - type: String, - required: true, - }, - permissions: { - type: Array, - required: true, - }, - }, - { - timestamps: true, - }, -); - -roleSchema.index({ organization: 1, workspace: 1 }); - -export const Role = model("Role", roleSchema); diff --git a/pg-migrator/src/models/secret.ts b/pg-migrator/src/models/secret.ts deleted file mode 100644 index 1dbb6a84e..000000000 --- a/pg-migrator/src/models/secret.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface ISecret { - _id: Types.ObjectId; - version: number; - workspace: Types.ObjectId; - type: string; - user?: Types.ObjectId; - environment: string; - secretBlindIndex?: string; - secretKeyCiphertext: string; - secretKeyIV: string; - secretKeyTag: string; - secretKeyHash: string; - secretValueCiphertext: string; - secretValueIV: string; - secretValueTag: string; - secretValueHash: string; - secretCommentCiphertext?: string; - secretCommentIV?: string; - secretCommentTag?: string; - secretCommentHash?: string; - - // ? NOTE: This works great for workspace-level reminders. - // ? If we want to do it on a user-basis, we should ideally have a seperate model for reminders. - secretReminderRepeatDays?: number | null; - secretReminderNote?: string | null; - - skipMultilineEncoding?: boolean; - algorithm: "aes-256-gcm"; - keyEncoding: "utf8" | "base64"; - tags?: string[]; - folder?: string; - metadata?: { - [key: string]: string; - }; -} - -const secretSchema = new Schema( - { - version: { - type: Number, - required: true, - default: 1, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - type: { - type: String, - required: true, - }, - user: { - // user associated with the personal secret - type: Schema.Types.ObjectId, - ref: "User", - }, - tags: { - ref: "Tag", - type: [Schema.Types.ObjectId], - default: [], - }, - environment: { - type: String, - required: true, - }, - secretBlindIndex: { - type: String, - - }, - secretKeyCiphertext: { - type: String, - required: true, - }, - secretKeyIV: { - type: String, // symmetric - required: true, - }, - secretKeyTag: { - type: String, // symmetric - required: true, - }, - secretKeyHash: { - type: String, - }, - secretValueCiphertext: { - type: String, - required: true, - }, - secretValueIV: { - type: String, // symmetric - required: true, - }, - secretValueTag: { - type: String, // symmetric - required: true, - }, - secretValueHash: { - type: String, - }, - secretCommentCiphertext: { - type: String, - required: false, - }, - secretCommentIV: { - type: String, // symmetric - required: false, - }, - secretCommentTag: { - type: String, // symmetric - required: false, - }, - secretCommentHash: { - type: String, - required: false, - }, - - secretReminderRepeatDays: { - type: Number, - required: false, - default: null, - }, - secretReminderNote: { - type: String, - required: false, - default: null, - }, - - skipMultilineEncoding: { - type: Boolean, - required: false, - }, - - algorithm: { - // the encryption algorithm used - type: String, - required: true, - }, - keyEncoding: { - type: String, - required: true, - }, - folder: { - type: String, - default: "root", - }, - metadata: { - type: Schema.Types.Mixed, - }, - }, - { - timestamps: true, - }, -); - -secretSchema.index({ tags: 1 }, { background: true }); - -export const Secret = model("Secret", secretSchema); diff --git a/pg-migrator/src/models/secretApprovalPolicy.ts b/pg-migrator/src/models/secretApprovalPolicy.ts deleted file mode 100644 index 376b541c7..000000000 --- a/pg-migrator/src/models/secretApprovalPolicy.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface ISecretApprovalPolicy { - _id: Types.ObjectId; - workspace: Types.ObjectId; - name: string; - environment: string; - secretPath?: string; - approvers: Types.ObjectId[]; - approvals: number; -} - -const secretApprovalPolicySchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true - }, - approvers: [ - { - // user associated with the personal secret - type: Schema.Types.ObjectId, - ref: "Membership" - } - ], - name: { - type: String - }, - environment: { - type: String, - required: true - }, - secretPath: { - type: String, - required: false - }, - approvals: { - type: Number, - default: 1 - } - }, - { - timestamps: true - } -); - -export const SecretApprovalPolicy = model( - "SecretApprovalPolicy", - secretApprovalPolicySchema -); diff --git a/pg-migrator/src/models/secretApprovalRequest.ts b/pg-migrator/src/models/secretApprovalRequest.ts deleted file mode 100644 index 983163d1a..000000000 --- a/pg-migrator/src/models/secretApprovalRequest.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export enum ApprovalStatus { - PENDING = "pending", - APPROVED = "approved", - REJECTED = "rejected", -} - -export enum CommitType { - DELETE = "delete", - UPDATE = "update", - CREATE = "create", -} - -export interface ISecretApprovalSecChange { - _id: Types.ObjectId; - version: number; - secretBlindIndex?: string; - secretKeyCiphertext: string; - secretKeyIV: string; - secretKeyTag: string; - secretValueCiphertext: string; - secretValueIV: string; - secretValueTag: string; - secretCommentIV?: string; - secretCommentTag?: string; - secretCommentCiphertext?: string; - skipMultilineEncoding?: boolean; - algorithm?: "aes-256-gcm"; - keyEncoding?: "utf8" | "base64"; - tags?: string[]; -} - -export type ISecretCommits = Array< - | { - newVersion: ISecretApprovalSecChange; - op: CommitType.CREATE; - } - | { - // secret is recorded to get the latest version, we can keep ref to secret for pulling change as it will also get changed - // on merge - secretVersion: J; - secret: T; - newVersion: Partial> & { - _id: Types.ObjectId; - }; - op: CommitType.UPDATE; - } - | { - secret: T; - secretVersion: J; - op: CommitType.DELETE; - } ->; -export interface ISecretApprovalRequest { - _id: Types.ObjectId; - committer: Types.ObjectId; - slug: string; - statusChangeBy: Types.ObjectId; - reviewers: { - member: Types.ObjectId; - status: ApprovalStatus; - }[]; - workspace: Types.ObjectId; - environment: string; - folderId: string; - hasMerged: boolean; - status: "open" | "close"; - policy: Types.ObjectId; - commits: ISecretCommits; - conflicts: Array<{ secretId: string; op: CommitType }>; -} - -const secretApprovalSecretChangeSchema = new Schema({ - version: { - type: Number, - default: 1, - required: true, - }, - secretBlindIndex: { - type: String, - - }, - secretKeyCiphertext: { - type: String, - required: true, - }, - secretKeyIV: { - type: String, // symmetric - required: true, - }, - secretKeyTag: { - type: String, // symmetric - required: true, - }, - secretValueCiphertext: { - type: String, - required: true, - }, - secretValueIV: { - type: String, // symmetric - required: true, - }, - secretValueTag: { - type: String, // symmetric - required: true, - }, - skipMultilineEncoding: { - type: Boolean, - required: false, - }, - algorithm: { - // the encryption algorithm used - type: String, - required: true, - }, - keyEncoding: { - type: String, - required: true, - }, - tags: { - ref: "Tag", - type: [Schema.Types.ObjectId], - default: [], - }, -}); - -const secretApprovalRequestSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - environment: { - type: String, - required: true, - }, - folderId: { - type: String, - required: true, - default: "root", - }, - slug: { - type: String, - }, - reviewers: { - type: [ - { - member: { - // user associated with the personal secret - type: Schema.Types.ObjectId, - ref: "Membership", - }, - status: { - type: String, - enum: ApprovalStatus, - default: ApprovalStatus.PENDING, - }, - }, - ], - default: [], - }, - policy: { type: Schema.Types.ObjectId, ref: "SecretApprovalPolicy" }, - hasMerged: { type: Boolean, default: false }, - status: { type: String, enum: ["close", "open"], default: "open" }, - committer: { type: Schema.Types.ObjectId, ref: "Membership" }, - statusChangeBy: { type: Schema.Types.ObjectId, ref: "Membership" }, - commits: [ - { - secret: { type: Types.ObjectId, ref: "Secret" }, - newVersion: secretApprovalSecretChangeSchema, - secretVersion: { type: Types.ObjectId, ref: "SecretVersion" }, - op: { type: String, enum: [CommitType], required: true }, - }, - ], - conflicts: { - type: [ - { - secretId: { type: String, required: true }, - op: { type: String, enum: [CommitType], required: true }, - }, - ], - default: [], - }, - }, - { - timestamps: true, - }, -); - -export const SecretApprovalRequest = model( - "SecretApprovalRequest", - secretApprovalRequestSchema, -); diff --git a/pg-migrator/src/models/secretBlindIndexData.ts b/pg-migrator/src/models/secretBlindIndexData.ts deleted file mode 100644 index e1eea4c3b..000000000 --- a/pg-migrator/src/models/secretBlindIndexData.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export interface ISecretBlindIndexData extends Document { - _id: Types.ObjectId; - workspace: Types.ObjectId; - encryptedSaltCiphertext: string; - saltIV: string; - saltTag: string; - algorithm: "aes-256-gcm"; - keyEncoding: "base64" | "utf8"; -} - -const secretBlindIndexDataSchema = new Schema({ - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - encryptedSaltCiphertext: { - // TODO: make these - type: String, - required: true, - }, - saltIV: { - type: String, - required: true, - }, - saltTag: { - type: String, - required: true, - }, - algorithm: { - type: String, - required: true, - - }, - keyEncoding: { - type: String, - required: true, - - }, -}); - -secretBlindIndexDataSchema.index({ workspace: 1 }); - -export const SecretBlindIndexData = model( - "SecretBlindIndexData", - secretBlindIndexDataSchema, -); diff --git a/pg-migrator/src/models/secretImports.ts b/pg-migrator/src/models/secretImports.ts deleted file mode 100644 index 79046a489..000000000 --- a/pg-migrator/src/models/secretImports.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface ISecretImports { - _id: Types.ObjectId; - workspace: Types.ObjectId; - environment: string; - folderId: string; - imports: Array<{ - environment: string; - secretPath: string; - }>; -} - -const secretImportSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true - }, - environment: { - type: String, - required: true - }, - folderId: { - type: String, - required: true, - default: "root" - }, - imports: { - type: [ - { - environment: { - type: String, - required: true - }, - secretPath: { - type: String, - required: true - } - } - ], - default: [] - } - }, - { - timestamps: true - } -); - -export const SecretImport = model("SecretImports", secretImportSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/secretRotation.ts b/pg-migrator/src/models/secretRotation.ts deleted file mode 100644 index 238cef536..000000000 --- a/pg-migrator/src/models/secretRotation.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Document, Schema, model, Types } from "mongoose"; - -export interface ISecretRotation extends Document { - _id: Types.ObjectId; - name: string; - interval: number; - provider: string; - customProvider: Types.ObjectId; - workspace: Types.ObjectId; - environment: string; - secretPath: string; - outputs: Array<{ - key: string; - secret: Types.ObjectId; - }>; - status?: "success" | "failed"; - lastRotatedAt?: string; - statusMessage?: string; - encryptedData: string; - encryptedDataIV: string; - encryptedDataTag: string; - algorithm: string; - keyEncoding: string; -} -const secretRotationSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - }, - provider: { - type: String, - required: true, - }, - customProvider: { - type: Schema.Types.ObjectId, - ref: "SecretRotationProvider", - }, - environment: { - type: String, - required: true, - }, - secretPath: { - type: String, - required: true, - }, - interval: { - type: Number, - required: true, - }, - lastRotatedAt: { - type: String, - }, - status: { - type: String, - enum: ["success", "failed"], - }, - statusMessage: { - type: String, - }, - // encrypted data on input keys and secrets got - encryptedData: { - type: String, - select: false, - }, - encryptedDataIV: { - type: String, - select: false, - }, - encryptedDataTag: { - type: String, - select: false, - }, - algorithm: { - // the encryption algorithm used - type: String, - required: true, - select: false, - }, - keyEncoding: { - type: String, - required: true, - select: false, - }, - outputs: [ - { - key: { - type: String, - required: true, - }, - secret: { - type: Schema.Types.ObjectId, - ref: "Secret", - }, - }, - ], - }, - { - timestamps: true, - }, -); - -export const SecretRotation = model( - "SecretRotation", - secretRotationSchema, -); diff --git a/pg-migrator/src/models/secretSnapshot.ts b/pg-migrator/src/models/secretSnapshot.ts deleted file mode 100644 index 132329f4a..000000000 --- a/pg-migrator/src/models/secretSnapshot.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface ISecretSnapshot { - id: string; - _id: string; - workspace: Types.ObjectId; - environment: string; - folderId: string | "root"; - version: number; - secretVersions: Types.ObjectId[]; - folderVersion: Types.ObjectId; -} - -const secretSnapshotSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - environment: { - type: String, - required: true, - }, - folderId: { - type: String, - default: "root", - }, - version: { - type: Number, - default: 1, - required: true, - }, - secretVersions: [ - { - type: Schema.Types.ObjectId, - ref: "SecretVersion", - required: true, - }, - ], - folderVersion: { - type: Schema.Types.ObjectId, - ref: "FolderVersion", - }, - }, - { - timestamps: true, - }, -); - -export const SecretSnapshot = model( - "SecretSnapshot", - secretSnapshotSchema, -); diff --git a/pg-migrator/src/models/secretVersion.ts b/pg-migrator/src/models/secretVersion.ts deleted file mode 100644 index 6922216d1..000000000 --- a/pg-migrator/src/models/secretVersion.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface ISecretVersion { - _id: Types.ObjectId; - secret: Types.ObjectId; - version: number; - workspace: Types.ObjectId; // new - type: string; // new - user?: Types.ObjectId; // new - environment: string; // new - isDeleted: boolean; - secretBlindIndex?: string; - secretKeyCiphertext: string; - secretKeyIV: string; - secretKeyTag: string; - secretValueCiphertext: string; - secretValueIV: string; - secretValueTag: string; - skipMultilineEncoding?: boolean; - algorithm: "aes-256-gcm"; - keyEncoding: "utf8" | "base64"; - createdAt: string; - folder?: string; - tags?: string[]; -} - -const secretVersionSchema = new Schema( - { - secret: { - // could be deleted - type: Schema.Types.ObjectId, - ref: "Secret", - required: true, - }, - version: { - type: Number, - default: 1, - required: true, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - type: { - type: String, - required: true, - }, - user: { - // user associated with the personal secret - type: Schema.Types.ObjectId, - ref: "User", - }, - environment: { - type: String, - required: true, - }, - isDeleted: { - // consider removing field - type: Boolean, - default: false, - required: true, - }, - secretBlindIndex: { - type: String, - - }, - secretKeyCiphertext: { - type: String, - required: true, - }, - secretKeyIV: { - type: String, // symmetric - required: true, - }, - secretKeyTag: { - type: String, // symmetric - required: true, - }, - secretValueCiphertext: { - type: String, - required: true, - }, - secretValueIV: { - type: String, // symmetric - required: true, - }, - secretValueTag: { - type: String, // symmetric - required: true, - }, - skipMultilineEncoding: { - type: Boolean, - required: false, - }, - algorithm: { - // the encryption algorithm used - type: String, - required: true, - }, - keyEncoding: { - type: String, - required: true, - }, - folder: { - type: String, - required: true, - }, - tags: { - ref: "Tag", - type: [Schema.Types.ObjectId], - default: [], - }, - }, - { - timestamps: true, - }, -); - -export const SecretVersion = model( - "SecretVersion", - secretVersionSchema, -); diff --git a/pg-migrator/src/models/serverConfig.ts b/pg-migrator/src/models/serverConfig.ts deleted file mode 100644 index 13e469bd5..000000000 --- a/pg-migrator/src/models/serverConfig.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IServerConfig { - _id: Types.ObjectId; - initialized: boolean; - allowSignUp: boolean; -} - -const serverConfigSchema = new Schema( - { - initialized: { - type: Boolean, - default: false - }, - allowSignUp: { - type: Boolean, - default: true - } - }, - { - timestamps: true - } -); - -export const ServerConfig = model("ServerConfig", serverConfigSchema); diff --git a/pg-migrator/src/models/serviceToken.ts b/pg-migrator/src/models/serviceToken.ts deleted file mode 100644 index 0e943b177..000000000 --- a/pg-migrator/src/models/serviceToken.ts +++ /dev/null @@ -1,60 +0,0 @@ -// TODO: deprecate -import { Schema, Types, model } from "mongoose"; -export interface IServiceToken { - _id: Types.ObjectId; - name: string; - user: Types.ObjectId; - workspace: Types.ObjectId; - environment: string; - expiresAt: Date; - publicKey: string; - encryptedKey: string; - nonce: string; -} - -const serviceTokenSchema = new Schema( - { - name: { - type: String, - required: true, - }, - user: { - // token issuer - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - environment: { - type: String, - required: true, - }, - expiresAt: { - type: Date, - }, - publicKey: { - type: String, - required: true, - select: true, - }, - encryptedKey: { - type: String, - required: true, - select: true, - }, - nonce: { - type: String, - required: true, - select: true, - }, - }, - { - timestamps: true, - } -); - -export const ServiceToken = model("ServiceToken", serviceTokenSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/serviceTokenData.ts b/pg-migrator/src/models/serviceTokenData.ts deleted file mode 100644 index a8357d689..000000000 --- a/pg-migrator/src/models/serviceTokenData.ts +++ /dev/null @@ -1,93 +0,0 @@ -// TODO: deprecate -import { Document, Schema, Types, model } from "mongoose"; - -export interface IServiceTokenData extends Document { - _id: Types.ObjectId; - name: string; - workspace: Types.ObjectId; - scopes: Array<{ - environment: string; - secretPath: string; - }>; - user: Types.ObjectId; - serviceAccount: Types.ObjectId; - lastUsed: Date; - expiresAt: Date; - secretHash: string; - encryptedKey: string; - iv: string; - tag: string; - permissions: string[]; -} - -const serviceTokenDataSchema = new Schema( - { - name: { - type: String, - required: true - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true - }, - scopes: { - type: [ - { - environment: { - type: String, - required: true - }, - secretPath: { - type: String, - default: "/", - required: true - } - } - ], - required: true - }, - user: { - type: Schema.Types.ObjectId, - ref: "User", - required: true - }, - serviceAccount: { - type: Schema.Types.ObjectId, - ref: "ServiceAccount" - }, - lastUsed: { - type: Date - }, - expiresAt: { - type: Date - }, - secretHash: { - type: String, - required: true, - - }, - encryptedKey: { - type: String, - - }, - iv: { - type: String, - - }, - tag: { - type: String, - - }, - permissions: { - type: [String], - enum: ["read", "write"], - default: ["read"] - } - }, - { - timestamps: true - } -); - -export const ServiceTokenData = model("ServiceTokenData", serviceTokenDataSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/ssoConfig.ts b/pg-migrator/src/models/ssoConfig.ts deleted file mode 100644 index b591b8817..000000000 --- a/pg-migrator/src/models/ssoConfig.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export enum AuthProvider { - OKTA_SAML = "okta-saml", - AZURE_SAML = "azure-saml", - JUMPCLOUD_SAML = "jumpcloud-saml" -} - -export interface ISSOConfig { - organization: Types.ObjectId; - authProvider: AuthProvider; - isActive: boolean; - encryptedEntryPoint: string; - entryPointIV: string; - entryPointTag: string; - encryptedIssuer: string; - issuerIV: string; - issuerTag: string; - encryptedCert: string; - certIV: string; - certTag: string; -} - -const ssoConfigSchema = new Schema( - { - organization: { - type: Schema.Types.ObjectId, - ref: "Organization" - }, - authProvider: { - type: String, - enum: AuthProvider, - required: true - }, - isActive: { - type: Boolean, - required: true - }, - encryptedEntryPoint: { - type: String - }, - entryPointIV: { - type: String - }, - entryPointTag: { - type: String - }, - encryptedIssuer: { - type: String - }, - issuerIV: { - type: String - }, - issuerTag: { - type: String - }, - encryptedCert: { - type: String - }, - certIV: { - type: String - }, - certTag: { - type: String - } - }, - { - timestamps: true - } -); - -export const SSOConfig = model("SSOConfig", ssoConfigSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/tag.ts b/pg-migrator/src/models/tag.ts deleted file mode 100644 index a5f0bd307..000000000 --- a/pg-migrator/src/models/tag.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface ITag { - _id: Types.ObjectId; - name: string; - tagColor: string; - slug: string; - user: Types.ObjectId; - workspace: Types.ObjectId; -} - -const tagSchema = new Schema( - { - name: { - type: String, - required: true, - trim: true, - }, - tagColor: { - type: String, - required: false, - trim: true, - }, - slug: { - type: String, - required: true, - trim: true, - lowercase: true, - validate: [ - function (value: any) { - return value.indexOf(" ") === -1; - }, - "slug cannot contain spaces", - ], - }, - user: { - type: Schema.Types.ObjectId, - ref: "User", - }, - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - }, - }, - { - timestamps: true, - } -); - -tagSchema.index({ slug: 1, workspace: 1 }, { unique: true }) -tagSchema.index({ workspace: 1 }) - -export const Tag = model("Tag", tagSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/token.ts b/pg-migrator/src/models/token.ts deleted file mode 100644 index 62d342b0a..000000000 --- a/pg-migrator/src/models/token.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Schema, model } from "mongoose"; - -export interface IToken { - email: string; - token: string; - createdAt: Date; - ttl: number; -} - -const tokenSchema = new Schema({ - email: { - type: String, - required: true, - }, - token: { - type: String, - required: true, - }, - createdAt: { - type: Date, - default: Date.now, - }, - ttl: { - type: Number, - }, -}); - -tokenSchema.index({ email: 1 }); - -export const Token = model("Token", tokenSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/tokenData.ts b/pg-migrator/src/models/tokenData.ts deleted file mode 100644 index 80c6016c1..000000000 --- a/pg-migrator/src/models/tokenData.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface ITokenData { - type: string; - email?: string; - phoneNumber?: string; - organization?: Types.ObjectId; - tokenHash: string; - triesLeft?: number; - expiresAt: Date; - createdAt: Date; - updatedAt: Date; -} - -const tokenDataSchema = new Schema({ - type: { - type: String, - enum: [ - "emailConfirmation", - "emailMfa", - "organizationInvitation", - "passwordReset", - ], - required: true, - }, - email: { - type: String, - }, - phoneNumber: { - type: String, - }, - organization: { // organizationInvitation-specific field - type: Schema.Types.ObjectId, - ref: "Organization", - }, - tokenHash: { - type: String, - - required: true, - }, - triesLeft: { - type: Number, - }, - expiresAt: { - type: Date, - expires: 0, - required: true, - }, -}, { - timestamps: true, -}); - -export const TokenData = model("TokenData", tokenDataSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/tokenVersion.ts b/pg-migrator/src/models/tokenVersion.ts deleted file mode 100644 index b162e019e..000000000 --- a/pg-migrator/src/models/tokenVersion.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export interface ITokenVersion extends Document { - user: Types.ObjectId; - ip: string; - userAgent: string; - refreshVersion: number; - accessVersion: number; - lastUsed: Date; -} - -const tokenVersionSchema = new Schema( - { - user: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - ip: { - type: String, - required: true, - }, - userAgent: { - type: String, - required: true, - }, - refreshVersion: { - type: Number, - required: true, - }, - accessVersion: { - type: Number, - required: true, - }, - lastUsed: { - type: Date, - required: true, - }, - }, - { - timestamps: true, - } -); - -export const TokenVersion = model("TokenVersion", tokenVersionSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/trustedIp.ts b/pg-migrator/src/models/trustedIp.ts deleted file mode 100644 index 85616be11..000000000 --- a/pg-migrator/src/models/trustedIp.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export enum IPType { - IPV4 = "ipv4", - IPV6 = "ipv6" -} - -export interface ITrustedIP { - _id: Types.ObjectId; - workspace: Types.ObjectId; - ipAddress: string; - type: "ipv4" | "ipv6", // either IPv4/IPv6 address or network IPv4/IPv6 address - isActive: boolean; - comment: string; - prefix?: number; // CIDR -} - -const trustedIpSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true - }, - ipAddress: { - type: String, - required: true - }, - type: { - type: String, - enum: [ - IPType.IPV4, - IPType.IPV6 - ], - required: true - }, - prefix: { - type: Number, - required: false - }, - isActive: { - type: Boolean, - required: true - }, - comment: { - type: String - } - }, - { - timestamps: true - } -); - -export const TrustedIP = model("TrustedIP", trustedIpSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/user.ts b/pg-migrator/src/models/user.ts deleted file mode 100644 index 08ce2bb46..000000000 --- a/pg-migrator/src/models/user.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export enum AuthMethod { - EMAIL = "email", - GOOGLE = "google", - GITHUB = "github", - GITLAB = "gitlab", - OKTA_SAML = "okta-saml", - AZURE_SAML = "azure-saml", - JUMPCLOUD_SAML = "jumpcloud-saml", -} - -export interface IUser extends Document { - _id: Types.ObjectId; - authProvider?: AuthMethod; - authMethods: AuthMethod[]; - email: string; - superAdmin?: boolean; - firstName?: string; - lastName?: string; - encryptionVersion: number; - protectedKey: string; - protectedKeyIV: string; - protectedKeyTag: string; - publicKey?: string; - encryptedPrivateKey?: string; - iv?: string; - tag?: string; - salt?: string; - verifier?: string; - isMfaEnabled: boolean; - mfaMethods: boolean; - devices: { - ip: string; - userAgent: string; - }[]; - createdAt: string; - updatedAt: string; -} - -const userSchema = new Schema( - { - authProvider: { - // TODO field: deprecate - type: String, - enum: AuthMethod, - }, - authMethods: { - type: [ - { - type: String, - enum: AuthMethod, - }, - ], - default: [AuthMethod.EMAIL], - required: true, - }, - email: { - type: String, - required: true, - unique: true, - }, - firstName: { - type: String, - }, - lastName: { - type: String, - }, - encryptionVersion: { - type: Number, - - default: 1, // to resolve backward-compatibility issues - }, - protectedKey: { - // introduced as part of encryption version 2 - type: String, - - }, - protectedKeyIV: { - // introduced as part of encryption version 2 - type: String, - - }, - protectedKeyTag: { - // introduced as part of encryption version 2 - type: String, - - }, - publicKey: { - type: String, - - }, - encryptedPrivateKey: { - type: String, - - }, - superAdmin: { - type: Boolean, - }, - iv: { - // iv of [encryptedPrivateKey] - type: String, - - }, - tag: { - // tag of [encryptedPrivateKey] - type: String, - - }, - salt: { - type: String, - - }, - verifier: { - type: String, - - }, - isMfaEnabled: { - type: Boolean, - default: false, - }, - mfaMethods: [ - { - type: String, - }, - ], - devices: { - type: [ - { - ip: String, - userAgent: String, - }, - ], - default: [], - - }, - }, - { - timestamps: true, - }, -); - -export const User = model("User", userSchema); diff --git a/pg-migrator/src/models/userAction.ts b/pg-migrator/src/models/userAction.ts deleted file mode 100644 index 68fae22be..000000000 --- a/pg-migrator/src/models/userAction.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IUserAction { - _id: Types.ObjectId; - user: Types.ObjectId; - action: string; -} - -const userActionSchema = new Schema( - { - user: { - type: Schema.Types.ObjectId, - ref: "User", - required: true, - }, - action: { - type: String, - required: true, - }, - }, - { - timestamps: true, - } -); - -export const UserAction = model("UserAction", userActionSchema); \ No newline at end of file diff --git a/pg-migrator/src/models/webhooks.ts b/pg-migrator/src/models/webhooks.ts deleted file mode 100644 index db3eadf1e..000000000 --- a/pg-migrator/src/models/webhooks.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Document, Schema, Types, model } from "mongoose"; - -export interface IWebhook extends Document { - _id: Types.ObjectId; - workspace: Types.ObjectId; - environment: string; - secretPath: string; - url: string; - lastStatus: "success" | "failed"; - lastRunErrorMessage?: string; - isDisabled: boolean; - encryptedSecretKey: string; - iv: string; - tag: string; - algorithm: "aes-256-gcm"; - keyEncoding: "base64" | "utf8"; -} - -const WebhookSchema = new Schema( - { - workspace: { - type: Schema.Types.ObjectId, - ref: "Workspace", - required: true, - }, - environment: { - type: String, - required: true, - }, - secretPath: { - type: String, - required: true, - default: "/", - }, - url: { - type: String, - required: true, - }, - lastStatus: { - type: String, - enum: ["success", "failed"], - }, - lastRunErrorMessage: { - type: String, - }, - isDisabled: { - type: Boolean, - default: false, - }, - // used for webhook signature - encryptedSecretKey: { - type: String, - - }, - iv: { - type: String, - - }, - tag: { - type: String, - - }, - algorithm: { - // the encryption algorithm used - type: String, - - }, - keyEncoding: { - type: String, - - }, - }, - { - timestamps: true, - }, -); - -export const Webhook = model("Webhook", WebhookSchema); diff --git a/pg-migrator/src/models/workspace.ts b/pg-migrator/src/models/workspace.ts deleted file mode 100644 index 9d7a19fcc..000000000 --- a/pg-migrator/src/models/workspace.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Schema, Types, model } from "mongoose"; - -export interface IWorkspace { - _id: Types.ObjectId; - name: string; - organization: Types.ObjectId; - environments: Array<{ - name: string; - slug: string; - }>; - autoCapitalization: boolean; -} - -const workspaceSchema = new Schema({ - name: { - type: String, - required: true, - }, - autoCapitalization: { - type: Boolean, - default: true, - }, - organization: { - type: Schema.Types.ObjectId, - ref: "Organization", - required: true, - }, - environments: { - type: [ - { - name: String, - slug: String, - }, - ], - default: [ - { - name: "Development", - slug: "dev", - }, - { - name: "Staging", - slug: "staging", - }, - { - name: "Production", - slug: "prod", - }, - ], - }, -}); - -export const Workspace = model("Workspace", workspaceSchema); \ No newline at end of file diff --git a/pg-migrator/src/rollback.ts b/pg-migrator/src/rollback.ts deleted file mode 100644 index 8d12bbddc..000000000 --- a/pg-migrator/src/rollback.ts +++ /dev/null @@ -1,29 +0,0 @@ -import dotenv from "dotenv"; -import knex from "knex"; -import { Level } from "level"; -import path from "path"; - -const main = async () => { - dotenv.config(); - let postgres_url = process.env.POSTGRES_DB_URL; - - console.log("Checking postgres connection..."); - const db = knex({ - client: "pg", - connection: postgres_url, - migrations: { - directory: path.join(__dirname, "./migrations"), - extension: "ts", - tableName: "infisical_migrations", - }, - }); - console.log("Good to go with postgres"); - const kdb = new Level("./db", { valueEncoding: "json" }); - console.log("Starting rolling back to latest"); - await db.migrate.rollback({}, true); - console.log("Rolling back completed"); - kdb.clear(); - process.exit(0); -}; - -main(); diff --git a/pg-migrator/src/schemas/api-keys.ts b/pg-migrator/src/schemas/api-keys.ts deleted file mode 100644 index c3f384a5a..000000000 --- a/pg-migrator/src/schemas/api-keys.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ApiKeysSchema = z.object({ - id: z.string(), - name: z.string(), - lastUsed: z.date().nullable().optional(), - expiresAt: z.date().nullable().optional(), - secretHash: z.string(), - createdAt: z.date(), - updatedAt: z.date(), - userId: z.string().uuid(), -}); - -export type TApiKeys = z.infer; -export type TApiKeysInsert = Omit; -export type TApiKeysUpdate = Partial>; diff --git a/pg-migrator/src/schemas/audit-logs.ts b/pg-migrator/src/schemas/audit-logs.ts deleted file mode 100644 index 90c389b94..000000000 --- a/pg-migrator/src/schemas/audit-logs.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const AuditLogsSchema = z.object({ - id: z.string().uuid(), - actor: z.string(), - actorMetadata: z.unknown(), - ipAddress: z.string().nullable().optional(), - eventType: z.string(), - eventMetadata: z.unknown().nullable().optional(), - userAgent: z.string().nullable().optional(), - userAgentType: z.string().nullable().optional(), - expiresAt: z.date().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - orgId: z.string().uuid().nullable().optional(), - projectId: z.string().nullable().optional(), -}); - -export type TAuditLogs = z.infer; -export type TAuditLogsInsert = Omit; -export type TAuditLogsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/auth-token-sessions.ts b/pg-migrator/src/schemas/auth-token-sessions.ts deleted file mode 100644 index 9dbf8e09f..000000000 --- a/pg-migrator/src/schemas/auth-token-sessions.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const AuthTokenSessionsSchema = z.object({ - id: z.string().uuid(), - ip: z.string(), - userAgent: z.string().nullable().optional(), - refreshVersion: z.number().default(1), - accessVersion: z.number().default(1), - lastUsed: z.date(), - createdAt: z.date(), - updatedAt: z.date(), - userId: z.string().uuid(), -}); - -export type TAuthTokenSessions = z.infer; -export type TAuthTokenSessionsInsert = Omit; -export type TAuthTokenSessionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/auth-tokens.ts b/pg-migrator/src/schemas/auth-tokens.ts deleted file mode 100644 index 4a612b11d..000000000 --- a/pg-migrator/src/schemas/auth-tokens.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const AuthTokensSchema = z.object({ - id: z.string().uuid(), - type: z.string(), - phoneNumber: z.string().nullable().optional(), - tokenHash: z.string(), - triesLeft: z.number().nullable().optional(), - expiresAt: z.date(), - createdAt: z.date(), - updatedAt: z.date(), - userId: z.string().uuid().nullable().optional(), - orgId: z.string().uuid().nullable().optional(), -}); - -export type TAuthTokens = z.infer; -export type TAuthTokensInsert = Omit; -export type TAuthTokensUpdate = Partial>; diff --git a/pg-migrator/src/schemas/backup-private-key.ts b/pg-migrator/src/schemas/backup-private-key.ts deleted file mode 100644 index 9b6e787b1..000000000 --- a/pg-migrator/src/schemas/backup-private-key.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const BackupPrivateKeySchema = z.object({ - id: z.string().uuid(), - encryptedPrivateKey: z.string(), - iv: z.string(), - tag: z.string(), - algorithm: z.string(), - keyEncoding: z.string(), - salt: z.string(), - verifier: z.string(), - createdAt: z.date(), - updatedAt: z.date(), - userId: z.string().uuid(), -}); - -export type TBackupPrivateKey = z.infer; -export type TBackupPrivateKeyInsert = Omit; -export type TBackupPrivateKeyUpdate = Partial>; diff --git a/pg-migrator/src/schemas/git-app-install-sessions.ts b/pg-migrator/src/schemas/git-app-install-sessions.ts deleted file mode 100644 index 16f62eab7..000000000 --- a/pg-migrator/src/schemas/git-app-install-sessions.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const GitAppInstallSessionsSchema = z.object({ - id: z.string().uuid(), - sessionId: z.string(), - userId: z.string().uuid().nullable().optional(), - orgId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TGitAppInstallSessions = z.infer; -export type TGitAppInstallSessionsInsert = Omit; -export type TGitAppInstallSessionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/git-app-org.ts b/pg-migrator/src/schemas/git-app-org.ts deleted file mode 100644 index f5226811d..000000000 --- a/pg-migrator/src/schemas/git-app-org.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const GitAppOrgSchema = z.object({ - id: z.string().uuid(), - installationId: z.string(), - userId: z.string().uuid(), - orgId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TGitAppOrg = z.infer; -export type TGitAppOrgInsert = Omit; -export type TGitAppOrgUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identities.ts b/pg-migrator/src/schemas/identities.ts deleted file mode 100644 index b8ff6c36f..000000000 --- a/pg-migrator/src/schemas/identities.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IdentitiesSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - authMethod: z.string().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TIdentities = z.infer; -export type TIdentitiesInsert = Omit; -export type TIdentitiesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-access-tokens.ts b/pg-migrator/src/schemas/identity-access-tokens.ts deleted file mode 100644 index aa86e0356..000000000 --- a/pg-migrator/src/schemas/identity-access-tokens.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IdentityAccessTokensSchema = z.object({ - id: z.string().uuid(), - accessTokenTTL: z.number().default(2592000), - accessTokenMaxTTL: z.number().default(2592000), - accessTokenNumUses: z.number().default(0), - accessTokenNumUsesLimit: z.number().default(0), - accessTokenLastUsedAt: z.date().nullable().optional(), - accessTokenLastRenewedAt: z.date().nullable().optional(), - isAccessTokenRevoked: z.boolean().default(false), - identityUAClientSecretId: z.string().nullable().optional(), - identityId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TIdentityAccessTokens = z.infer; -export type TIdentityAccessTokensInsert = Omit< - TIdentityAccessTokens, - TImmutableDBKeys ->; -export type TIdentityAccessTokensUpdate = Partial< - Omit ->; diff --git a/pg-migrator/src/schemas/identity-org-memberships.ts b/pg-migrator/src/schemas/identity-org-memberships.ts deleted file mode 100644 index c5c9a0f61..000000000 --- a/pg-migrator/src/schemas/identity-org-memberships.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IdentityOrgMembershipsSchema = z.object({ - id: z.string().uuid(), - role: z.string(), - roleId: z.string().uuid().nullable().optional(), - orgId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), - identityId: z.string().uuid(), -}); - -export type TIdentityOrgMemberships = z.infer; -export type TIdentityOrgMembershipsInsert = Omit; -export type TIdentityOrgMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-project-memberships.ts b/pg-migrator/src/schemas/identity-project-memberships.ts deleted file mode 100644 index 9a57952a4..000000000 --- a/pg-migrator/src/schemas/identity-project-memberships.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IdentityProjectMembershipsSchema = z.object({ - id: z.string().uuid(), - role: z.string(), - roleId: z.string().uuid().nullable().optional(), - projectId: z.string(), - identityId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TIdentityProjectMemberships = z.infer; -export type TIdentityProjectMembershipsInsert = Omit; -export type TIdentityProjectMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/identity-ua-client-secrets.ts b/pg-migrator/src/schemas/identity-ua-client-secrets.ts deleted file mode 100644 index a7b7cb9a8..000000000 --- a/pg-migrator/src/schemas/identity-ua-client-secrets.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IdentityUaClientSecretsSchema = z.object({ - id: z.string(), - description: z.string(), - clientSecretPrefix: z.string(), - clientSecretHash: z.string(), - clientSecretLastUsedAt: z.date().nullable().optional(), - clientSecretNumUses: z.number().default(0), - clientSecretNumUsesLimit: z.number().default(0), - clientSecretTTL: z.number().default(0), - isClientSecretRevoked: z.boolean().default(false), - createdAt: z.date(), - updatedAt: z.date(), - identityUAId: z.string().uuid(), -}); - -export type TIdentityUaClientSecrets = z.infer< - typeof IdentityUaClientSecretsSchema ->; -export type TIdentityUaClientSecretsInsert = Omit< - TIdentityUaClientSecrets, - TImmutableDBKeys ->; -export type TIdentityUaClientSecretsUpdate = Partial< - Omit ->; diff --git a/pg-migrator/src/schemas/identity-universal-auths.ts b/pg-migrator/src/schemas/identity-universal-auths.ts deleted file mode 100644 index 82b9fb23e..000000000 --- a/pg-migrator/src/schemas/identity-universal-auths.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IdentityUniversalAuthsSchema = z.object({ - id: z.string().uuid(), - clientId: z.string(), - accessTokenTTL: z.number().default(7200), - accessTokenMaxTTL: z.number().default(7200), - accessTokenNumUsesLimit: z.number().default(0), - clientSecretTrustedIps: z.unknown(), - accessTokenTrustedIps: z.unknown(), - createdAt: z.date(), - updatedAt: z.date(), - identityId: z.string().uuid(), -}); - -export type TIdentityUniversalAuths = z.infer; -export type TIdentityUniversalAuthsInsert = Omit; -export type TIdentityUniversalAuthsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/incident-contacts.ts b/pg-migrator/src/schemas/incident-contacts.ts deleted file mode 100644 index c1492e0fa..000000000 --- a/pg-migrator/src/schemas/incident-contacts.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IncidentContactsSchema = z.object({ - id: z.string().uuid(), - email: z.string(), - createdAt: z.date(), - updatedAt: z.date(), - orgId: z.string().uuid(), -}); - -export type TIncidentContacts = z.infer; -export type TIncidentContactsInsert = Omit; -export type TIncidentContactsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/index.ts b/pg-migrator/src/schemas/index.ts deleted file mode 100644 index fe02658f9..000000000 --- a/pg-migrator/src/schemas/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -export * from "./api-keys"; -export * from "./audit-logs"; -export * from "./auth-token-sessions"; -export * from "./auth-tokens"; -export * from "./backup-private-key"; -export * from "./git-app-install-sessions"; -export * from "./git-app-org"; -export * from "./identities"; -export * from "./identity-access-tokens"; -export * from "./identity-org-memberships"; -export * from "./identity-project-memberships"; -export * from "./identity-ua-client-secrets"; -export * from "./identity-universal-auths"; -export * from "./incident-contacts"; -export * from "./integration-auths"; -export * from "./integrations"; -export * from "./models"; -export * from "./org-bots"; -export * from "./org-memberships"; -export * from "./org-roles"; -export * from "./organizations"; -export * from "./project-bots"; -export * from "./project-environments"; -export * from "./project-keys"; -export * from "./project-memberships"; -export * from "./project-roles"; -export * from "./projects"; -export * from "./secret-approval-request-secret-tags"; -export * from "./secret-approval-requests-secrets"; -export * from "./saml-configs"; -export * from "./secret-approval-policies-approvers"; -export * from "./secret-approval-requests-reviewers"; -export * from "./secret-approval-policies"; -export * from "./secret-approval-requests"; -export * from "./secret-blind-indexes"; -export * from "./secret-folder-versions"; -export * from "./secret-folders"; -export * from "./secret-imports"; -export * from "./secret-rotation-outputs"; -export * from "./secret-rotations"; -export * from "./secret-scanning-git-risks"; -export * from "./secret-snapshot-folders"; -export * from "./secret-snapshot-secrets"; -export * from "./secret-snapshots"; -export * from "./secret-tag-junction"; -export * from "./secret-tags"; -export * from "./secret-versions"; -export * from "./secrets"; -export * from "./service-tokens"; -export * from "./super-admin"; -export * from "./trusted-ips"; -export * from "./user-actions"; -export * from "./user-encryption-keys"; -export * from "./users"; -export * from "./webhooks"; -export * from "./secret-version-tag-junction"; diff --git a/pg-migrator/src/schemas/integration-auths.ts b/pg-migrator/src/schemas/integration-auths.ts deleted file mode 100644 index d2983658c..000000000 --- a/pg-migrator/src/schemas/integration-auths.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IntegrationAuthsSchema = z.object({ - id: z.string().uuid(), - integration: z.string(), - teamId: z.string().nullable().optional(), - url: z.string().nullable().optional(), - namespace: z.string().nullable().optional(), - accountId: z.string().nullable().optional(), - refreshCiphertext: z.string().nullable().optional(), - refreshIV: z.string().nullable().optional(), - refreshTag: z.string().nullable().optional(), - accessIdCiphertext: z.string().nullable().optional(), - accessIdIV: z.string().nullable().optional(), - accessIdTag: z.string().nullable().optional(), - accessCiphertext: z.string().nullable().optional(), - accessIV: z.string().nullable().optional(), - accessTag: z.string().nullable().optional(), - accessExpiresAt: z.date().nullable().optional(), - metadata: z.unknown().nullable().optional(), - algorithm: z.string(), - keyEncoding: z.string(), - projectId: z.string(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TIntegrationAuths = z.infer; -export type TIntegrationAuthsInsert = Omit; -export type TIntegrationAuthsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/integrations.ts b/pg-migrator/src/schemas/integrations.ts deleted file mode 100644 index b2163dc4d..000000000 --- a/pg-migrator/src/schemas/integrations.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const IntegrationsSchema = z.object({ - id: z.string().uuid(), - isActive: z.boolean(), - url: z.string().nullable().optional(), - app: z.string().nullable().optional(), - appId: z.string().nullable().optional(), - targetEnvironment: z.string().nullable().optional(), - targetEnvironmentId: z.string().nullable().optional(), - targetService: z.string().nullable().optional(), - targetServiceId: z.string().nullable().optional(), - owner: z.string().nullable().optional(), - path: z.string().nullable().optional(), - region: z.string().nullable().optional(), - scope: z.string().nullable().optional(), - integration: z.string(), - metadata: z.unknown().nullable().optional(), - integrationAuthId: z.string().uuid(), - envId: z.string().uuid(), - secretPath: z.string().default('/'), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TIntegrations = z.infer; -export type TIntegrationsInsert = Omit; -export type TIntegrationsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/models.ts b/pg-migrator/src/schemas/models.ts deleted file mode 100644 index eba69f621..000000000 --- a/pg-migrator/src/schemas/models.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { z } from "zod"; - -export enum TableName { - Users = "users", - UserEncryptionKey = "user_encryption_keys", - AuthTokens = "auth_tokens", - AuthTokenSession = "auth_token_sessions", - BackupPrivateKey = "backup_private_key", - Organization = "organizations", - OrgMembership = "org_memberships", - OrgRoles = "org_roles", - OrgBot = "org_bots", - IncidentContact = "incident_contacts", - UserAction = "user_actions", - SuperAdmin = "super_admin", - ApiKey = "api_keys", - Project = "projects", - ProjectBot = "project_bots", - Environment = "project_environments", - ProjectMembership = "project_memberships", - ProjectRoles = "project_roles", - ProjectKeys = "project_keys", - Secret = "secrets", - SecretBlindIndex = "secret_blind_indexes", - SecretVersion = "secret_versions", - SecretFolder = "secret_folders", - SecretFolderVersion = "secret_folder_versions", - SecretImport = "secret_imports", - Snapshot = "secret_snapshots", - SnapshotSecret = "secret_snapshot_secrets", - SnapshotFolder = "secret_snapshot_folders", - SecretTag = "secret_tags", - Integration = "integrations", - IntegrationAuth = "integration_auths", - ServiceToken = "service_tokens", - Webhook = "webhooks", - Identity = "identities", - IdentityAccessToken = "identity_access_tokens", - IdentityUniversalAuth = "identity_universal_auths", - IdentityUaClientSecret = "identity_ua_client_secrets", - IdentityOrgMembership = "identity_org_memberships", - IdentityProjectMembership = "identity_project_memberships", - SecretApprovalPolicy = "secret_approval_policies", - SecretApprovalPolicyApprover = "secret_approval_policies_approvers", - SecretApprovalRequest = "secret_approval_requests", - SecretApprovalRequestReviewer = "secret_approval_requests_reviewers", - SecretApprovalRequestSecret = "secret_approval_requests_secrets", - SecretApprovalRequestSecretTag = "secret_approval_request_secret_tags", - SecretRotation = "secret_rotations", - SecretRotationOutput = "secret_rotation_outputs", - SamlConfig = "saml_configs", - AuditLog = "audit_logs", - GitAppInstallSession = "git_app_install_sessions", - GitAppOrg = "git_app_org", - SecretScanningGitRisk = "secret_scanning_git_risks", - TrustedIps = "trusted_ips", - // junction tables with tags - JnSecretTag = "secret_tag_junction", - SecretVersionTag = "secret_version_tag_junction", -} - -export type TImmutableDBKeys = "id" | "createdAt" | "updatedAt"; - -export const UserDeviceSchema = z - .object({ - ip: z.string(), - userAgent: z.string(), - }) - .array() - .default([]); - -export const ServiceTokenScopes = z - .object({ - environment: z.string(), - secretPath: z.string().default("/"), - }) - .array(); - -export enum OrgMembershipRole { - Admin = "admin", - Member = "member", - NoAccess = "no-access", - Custom = "custom", -} - -export enum OrgMembershipStatus { - Invited = "invited", - Accepted = "accepted", -} - -export enum ProjectMembershipRole { - Admin = "admin", - Member = "member", - Custom = "custom", - Viewer = "viewer", - NoAccess = "no-access", -} - -export enum SecretEncryptionAlgo { - AES_256_GCM = "aes-256-gcm", -} - -export enum SecretKeyEncoding { - UTF8 = "utf8", - BASE64 = "base64", - HEX = "hex", -} - -export enum SecretType { - Shared = "shared", - Personal = "personal", -} - -export enum IdentityAuthMethod { - Univeral = "universal", -} diff --git a/pg-migrator/src/schemas/org-bots.ts b/pg-migrator/src/schemas/org-bots.ts deleted file mode 100644 index 400ab19c8..000000000 --- a/pg-migrator/src/schemas/org-bots.ts +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const OrgBotsSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - publicKey: z.string(), - encryptedSymmetricKey: z.string(), - symmetricKeyIV: z.string(), - symmetricKeyTag: z.string(), - symmetricKeyAlgorithm: z.string(), - symmetricKeyKeyEncoding: z.string(), - encryptedPrivateKey: z.string(), - privateKeyIV: z.string(), - privateKeyTag: z.string(), - privateKeyAlgorithm: z.string(), - privateKeyKeyEncoding: z.string(), - orgId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TOrgBots = z.infer; -export type TOrgBotsInsert = Omit; -export type TOrgBotsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/org-memberships.ts b/pg-migrator/src/schemas/org-memberships.ts deleted file mode 100644 index 932c84d00..000000000 --- a/pg-migrator/src/schemas/org-memberships.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const OrgMembershipsSchema = z.object({ - id: z.string().uuid(), - role: z.string(), - status: z.string().default('invited'), - inviteEmail: z.string().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - userId: z.string().uuid().nullable().optional(), - orgId: z.string().uuid(), - roleId: z.string().uuid().nullable().optional(), -}); - -export type TOrgMemberships = z.infer; -export type TOrgMembershipsInsert = Omit; -export type TOrgMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/org-roles.ts b/pg-migrator/src/schemas/org-roles.ts deleted file mode 100644 index 9718cdb26..000000000 --- a/pg-migrator/src/schemas/org-roles.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const OrgRolesSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - description: z.string().nullable().optional(), - slug: z.string(), - permissions: z.unknown(), - createdAt: z.date(), - updatedAt: z.date(), - orgId: z.string().uuid(), -}); - -export type TOrgRoles = z.infer; -export type TOrgRolesInsert = Omit; -export type TOrgRolesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/organizations.ts b/pg-migrator/src/schemas/organizations.ts deleted file mode 100644 index 0aa214a00..000000000 --- a/pg-migrator/src/schemas/organizations.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const OrganizationsSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - slug: z.string(), - customerId: z.string().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TOrganizations = z.infer; -export type TOrganizationsInsert = Omit; -export type TOrganizationsUpdate = Partial< - Omit ->; diff --git a/pg-migrator/src/schemas/project-bots.ts b/pg-migrator/src/schemas/project-bots.ts deleted file mode 100644 index 90ced9b3e..000000000 --- a/pg-migrator/src/schemas/project-bots.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ProjectBotsSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - isActive: z.boolean().default(false), - encryptedPrivateKey: z.string(), - publicKey: z.string(), - iv: z.string(), - tag: z.string(), - algorithm: z.string(), - keyEncoding: z.string(), - encryptedProjectKey: z.string().nullable().optional(), - encryptedProjectKeyNonce: z.string().nullable().optional(), - projectId: z.string(), - senderId: z.string().uuid().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TProjectBots = z.infer; -export type TProjectBotsInsert = Omit; -export type TProjectBotsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-environments.ts b/pg-migrator/src/schemas/project-environments.ts deleted file mode 100644 index aa3e392c7..000000000 --- a/pg-migrator/src/schemas/project-environments.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ProjectEnvironmentsSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - slug: z.string(), - position: z.number(), - projectId: z.string(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TProjectEnvironments = z.infer; -export type TProjectEnvironmentsInsert = Omit; -export type TProjectEnvironmentsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-keys.ts b/pg-migrator/src/schemas/project-keys.ts deleted file mode 100644 index 64e33d574..000000000 --- a/pg-migrator/src/schemas/project-keys.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ProjectKeysSchema = z.object({ - id: z.string().uuid(), - encryptedKey: z.string(), - nonce: z.string(), - receiverId: z.string().uuid(), - senderId: z.string().uuid().nullable().optional(), - projectId: z.string(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TProjectKeys = z.infer; -export type TProjectKeysInsert = Omit; -export type TProjectKeysUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-memberships.ts b/pg-migrator/src/schemas/project-memberships.ts deleted file mode 100644 index c98befb38..000000000 --- a/pg-migrator/src/schemas/project-memberships.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ProjectMembershipsSchema = z.object({ - id: z.string().uuid(), - role: z.string(), - createdAt: z.date(), - updatedAt: z.date(), - userId: z.string().uuid(), - projectId: z.string(), - roleId: z.string().uuid().nullable().optional(), -}); - -export type TProjectMemberships = z.infer; -export type TProjectMembershipsInsert = Omit; -export type TProjectMembershipsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/project-roles.ts b/pg-migrator/src/schemas/project-roles.ts deleted file mode 100644 index 190dd1cec..000000000 --- a/pg-migrator/src/schemas/project-roles.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ProjectRolesSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - description: z.string().nullable().optional(), - slug: z.string(), - permissions: z.unknown(), - createdAt: z.date(), - updatedAt: z.date(), - projectId: z.string(), -}); - -export type TProjectRoles = z.infer; -export type TProjectRolesInsert = Omit; -export type TProjectRolesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/projects.ts b/pg-migrator/src/schemas/projects.ts deleted file mode 100644 index 005e4bbde..000000000 --- a/pg-migrator/src/schemas/projects.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ProjectsSchema = z.object({ - id: z.string(), - name: z.string(), - slug: z.string(), - autoCapitalization: z.boolean().default(true).nullable().optional(), - orgId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TProjects = z.infer; -export type TProjectsInsert = Omit; -export type TProjectsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/saml-configs.ts b/pg-migrator/src/schemas/saml-configs.ts deleted file mode 100644 index 392fb2bef..000000000 --- a/pg-migrator/src/schemas/saml-configs.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SamlConfigsSchema = z.object({ - id: z.string().uuid(), - authProvider: z.string(), - isActive: z.boolean(), - encryptedEntryPoint: z.string().nullable().optional(), - entryPointIV: z.string().nullable().optional(), - entryPointTag: z.string().nullable().optional(), - encryptedIssuer: z.string().nullable().optional(), - issuerTag: z.string().nullable().optional(), - issuerIV: z.string().nullable().optional(), - encryptedCert: z.string().nullable().optional(), - certIV: z.string().nullable().optional(), - certTag: z.string().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - orgId: z.string().uuid(), -}); - -export type TSamlConfigs = z.infer; -export type TSamlConfigsInsert = Omit; -export type TSamlConfigsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-policies-approvers.ts b/pg-migrator/src/schemas/secret-approval-policies-approvers.ts deleted file mode 100644 index c6fb75f06..000000000 --- a/pg-migrator/src/schemas/secret-approval-policies-approvers.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretApprovalPoliciesApproversSchema = z.object({ - id: z.string().uuid(), - approverId: z.string().uuid(), - policyId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretApprovalPoliciesApprovers = z.infer; -export type TSecretApprovalPoliciesApproversInsert = Omit; -export type TSecretApprovalPoliciesApproversUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-policies.ts b/pg-migrator/src/schemas/secret-approval-policies.ts deleted file mode 100644 index ec859bb4e..000000000 --- a/pg-migrator/src/schemas/secret-approval-policies.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretApprovalPoliciesSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - secretPath: z.string().nullable().optional(), - approvals: z.number().default(1), - envId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretApprovalPolicies = z.infer; -export type TSecretApprovalPoliciesInsert = Omit; -export type TSecretApprovalPoliciesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-request-secret-tags.ts b/pg-migrator/src/schemas/secret-approval-request-secret-tags.ts deleted file mode 100644 index 47e11e6a9..000000000 --- a/pg-migrator/src/schemas/secret-approval-request-secret-tags.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretApprovalRequestSecretTagsSchema = z.object({ - id: z.string().uuid(), - secretId: z.string().uuid(), - tagId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretApprovalRequestSecretTags = z.infer; -export type TSecretApprovalRequestSecretTagsInsert = Omit; -export type TSecretApprovalRequestSecretTagsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-requests-reviewers.ts b/pg-migrator/src/schemas/secret-approval-requests-reviewers.ts deleted file mode 100644 index 4ed9b50a1..000000000 --- a/pg-migrator/src/schemas/secret-approval-requests-reviewers.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretApprovalRequestsReviewersSchema = z.object({ - id: z.string().uuid(), - member: z.string().uuid(), - status: z.string(), - requestId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretApprovalRequestsReviewers = z.infer; -export type TSecretApprovalRequestsReviewersInsert = Omit; -export type TSecretApprovalRequestsReviewersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-requests-secrets.ts b/pg-migrator/src/schemas/secret-approval-requests-secrets.ts deleted file mode 100644 index 2fe6c6692..000000000 --- a/pg-migrator/src/schemas/secret-approval-requests-secrets.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretApprovalRequestsSecretsSchema = z.object({ - id: z.string().uuid(), - version: z.number().default(1).nullable().optional(), - secretBlindIndex: z.string(), - secretKeyCiphertext: z.string(), - secretKeyIV: z.string(), - secretKeyTag: z.string(), - secretValueCiphertext: z.string(), - secretValueIV: z.string(), - secretValueTag: z.string(), - secretCommentCiphertext: z.string().nullable().optional(), - secretCommentIV: z.string().nullable().optional(), - secretCommentTag: z.string().nullable().optional(), - secretReminderNote: z.string().nullable().optional(), - secretReminderRepeatDays: z.number().nullable().optional(), - skipMultilineEncoding: z.boolean().default(false).nullable().optional(), - algorithm: z.string().default('aes-256-gcm'), - keyEncoding: z.string().default('utf8'), - metadata: z.unknown().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - requestId: z.string().uuid(), - op: z.string(), - secretId: z.string().uuid().nullable().optional(), - secretVersion: z.string().uuid().nullable().optional(), -}); - -export type TSecretApprovalRequestsSecrets = z.infer; -export type TSecretApprovalRequestsSecretsInsert = Omit; -export type TSecretApprovalRequestsSecretsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-approval-requests.ts b/pg-migrator/src/schemas/secret-approval-requests.ts deleted file mode 100644 index 7d5f2f443..000000000 --- a/pg-migrator/src/schemas/secret-approval-requests.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretApprovalRequestsSchema = z.object({ - id: z.string().uuid(), - policyId: z.string().uuid(), - hasMerged: z.boolean().default(false), - status: z.string().default('open'), - conflicts: z.unknown().nullable().optional(), - slug: z.string(), - folderId: z.string().uuid(), - statusChangeBy: z.string().uuid().nullable().optional(), - committerId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretApprovalRequests = z.infer; -export type TSecretApprovalRequestsInsert = Omit; -export type TSecretApprovalRequestsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-blind-indexes.ts b/pg-migrator/src/schemas/secret-blind-indexes.ts deleted file mode 100644 index 17eacb473..000000000 --- a/pg-migrator/src/schemas/secret-blind-indexes.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretBlindIndexesSchema = z.object({ - id: z.string().uuid(), - encryptedSaltCipherText: z.string(), - saltIV: z.string(), - saltTag: z.string(), - algorithm: z.string().default('aes-256-gcm'), - keyEncoding: z.string().default('utf8'), - projectId: z.string(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretBlindIndexes = z.infer; -export type TSecretBlindIndexesInsert = Omit; -export type TSecretBlindIndexesUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-folder-versions.ts b/pg-migrator/src/schemas/secret-folder-versions.ts deleted file mode 100644 index 895f81ebc..000000000 --- a/pg-migrator/src/schemas/secret-folder-versions.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretFolderVersionsSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - version: z.number().default(1).nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - envId: z.string().uuid(), - folderId: z.string().uuid(), -}); - -export type TSecretFolderVersions = z.infer; -export type TSecretFolderVersionsInsert = Omit; -export type TSecretFolderVersionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-folders.ts b/pg-migrator/src/schemas/secret-folders.ts deleted file mode 100644 index aa437c753..000000000 --- a/pg-migrator/src/schemas/secret-folders.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretFoldersSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - version: z.number().default(1).nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - envId: z.string().uuid(), - parentId: z.string().uuid().nullable().optional(), -}); - -export type TSecretFolders = z.infer; -export type TSecretFoldersInsert = Omit; -export type TSecretFoldersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-imports.ts b/pg-migrator/src/schemas/secret-imports.ts deleted file mode 100644 index 109d41ec2..000000000 --- a/pg-migrator/src/schemas/secret-imports.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretImportsSchema = z.object({ - id: z.string().uuid(), - version: z.number().default(1).nullable().optional(), - importPath: z.string(), - importEnv: z.string().uuid(), - position: z.number(), - createdAt: z.date(), - updatedAt: z.date(), - folderId: z.string().uuid(), -}); - -export type TSecretImports = z.infer; -export type TSecretImportsInsert = Omit; -export type TSecretImportsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-rotation-outputs.ts b/pg-migrator/src/schemas/secret-rotation-outputs.ts deleted file mode 100644 index b98338c75..000000000 --- a/pg-migrator/src/schemas/secret-rotation-outputs.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretRotationOutputsSchema = z.object({ - id: z.string().uuid(), - key: z.string(), - secretId: z.string().uuid(), - rotationId: z.string().uuid(), -}); - -export type TSecretRotationOutputs = z.infer; -export type TSecretRotationOutputsInsert = Omit; -export type TSecretRotationOutputsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-rotations.ts b/pg-migrator/src/schemas/secret-rotations.ts deleted file mode 100644 index 6e2bf6547..000000000 --- a/pg-migrator/src/schemas/secret-rotations.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretRotationsSchema = z.object({ - id: z.string().uuid(), - provider: z.string(), - secretPath: z.string(), - interval: z.number(), - lastRotatedAt: z.date().nullable().optional(), - status: z.string().nullable().optional(), - statusMessage: z.string().nullable().optional(), - encryptedData: z.string().nullable().optional(), - encryptedDataIV: z.string().nullable().optional(), - encryptedDataTag: z.string().nullable().optional(), - algorithm: z.string().nullable().optional(), - keyEncoding: z.string().nullable().optional(), - envId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretRotations = z.infer; -export type TSecretRotationsInsert = Omit; -export type TSecretRotationsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-scanning-git-risks.ts b/pg-migrator/src/schemas/secret-scanning-git-risks.ts deleted file mode 100644 index 0951d3ba5..000000000 --- a/pg-migrator/src/schemas/secret-scanning-git-risks.ts +++ /dev/null @@ -1,46 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretScanningGitRisksSchema = z.object({ - id: z.string().uuid(), - description: z.string().nullable().optional(), - startLine: z.string().nullable().optional(), - endLine: z.string().nullable().optional(), - startColumn: z.string().nullable().optional(), - endColumn: z.string().nullable().optional(), - file: z.string().nullable().optional(), - symlinkFile: z.string().nullable().optional(), - commit: z.string().nullable().optional(), - entropy: z.string().nullable().optional(), - author: z.string().nullable().optional(), - email: z.string().nullable().optional(), - date: z.string().nullable().optional(), - message: z.string().nullable().optional(), - tags: z.string().array().nullable().optional(), - ruleID: z.string().nullable().optional(), - fingerprint: z.string().nullable().optional(), - fingerPrintWithoutCommitId: z.string().nullable().optional(), - isFalsePositive: z.boolean().default(false).nullable().optional(), - isResolved: z.boolean().default(false).nullable().optional(), - riskOwner: z.string().nullable().optional(), - installationId: z.string(), - repositoryId: z.string().nullable().optional(), - repositoryLink: z.string().nullable().optional(), - repositoryFullName: z.string().nullable().optional(), - pusherName: z.string().nullable().optional(), - pusherEmail: z.string().nullable().optional(), - status: z.string().nullable().optional(), - orgId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretScanningGitRisks = z.infer; -export type TSecretScanningGitRisksInsert = Omit; -export type TSecretScanningGitRisksUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-snapshot-folders.ts b/pg-migrator/src/schemas/secret-snapshot-folders.ts deleted file mode 100644 index 5f3b1a88c..000000000 --- a/pg-migrator/src/schemas/secret-snapshot-folders.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretSnapshotFoldersSchema = z.object({ - id: z.string().uuid(), - envId: z.string().uuid(), - folderVersionId: z.string().uuid(), - snapshotId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretSnapshotFolders = z.infer; -export type TSecretSnapshotFoldersInsert = Omit; -export type TSecretSnapshotFoldersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-snapshot-secrets.ts b/pg-migrator/src/schemas/secret-snapshot-secrets.ts deleted file mode 100644 index f8a69a695..000000000 --- a/pg-migrator/src/schemas/secret-snapshot-secrets.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretSnapshotSecretsSchema = z.object({ - id: z.string().uuid(), - envId: z.string().uuid(), - secretVersionId: z.string().uuid(), - snapshotId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretSnapshotSecrets = z.infer; -export type TSecretSnapshotSecretsInsert = Omit; -export type TSecretSnapshotSecretsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-snapshots.ts b/pg-migrator/src/schemas/secret-snapshots.ts deleted file mode 100644 index ef9e0b7d0..000000000 --- a/pg-migrator/src/schemas/secret-snapshots.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretSnapshotsSchema = z.object({ - id: z.string().uuid(), - envId: z.string().uuid(), - folderId: z.string().uuid(), - parentFolderId: z.string().uuid().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretSnapshots = z.infer; -export type TSecretSnapshotsInsert = Omit; -export type TSecretSnapshotsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-tag-junction.ts b/pg-migrator/src/schemas/secret-tag-junction.ts deleted file mode 100644 index 467ef7b15..000000000 --- a/pg-migrator/src/schemas/secret-tag-junction.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretTagJunctionSchema = z.object({ - id: z.string().uuid(), - secretsId: z.string().uuid(), - secret_tagsId: z.string().uuid(), -}); - -export type TSecretTagJunction = z.infer; -export type TSecretTagJunctionInsert = Omit; -export type TSecretTagJunctionUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-tags.ts b/pg-migrator/src/schemas/secret-tags.ts deleted file mode 100644 index 78f03dedd..000000000 --- a/pg-migrator/src/schemas/secret-tags.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretTagsSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - slug: z.string(), - color: z.string().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - createdBy: z.string().uuid().nullable().optional(), - projectId: z.string(), -}); - -export type TSecretTags = z.infer; -export type TSecretTagsInsert = Omit; -export type TSecretTagsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-version-tag-junction.ts b/pg-migrator/src/schemas/secret-version-tag-junction.ts deleted file mode 100644 index 11b3f0032..000000000 --- a/pg-migrator/src/schemas/secret-version-tag-junction.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretVersionTagJunctionSchema = z.object({ - id: z.string().uuid(), - secret_versionsId: z.string().uuid(), - secret_tagsId: z.string().uuid(), -}); - -export type TSecretVersionTagJunction = z.infer; -export type TSecretVersionTagJunctionInsert = Omit; -export type TSecretVersionTagJunctionUpdate = Partial>; diff --git a/pg-migrator/src/schemas/secret-versions.ts b/pg-migrator/src/schemas/secret-versions.ts deleted file mode 100644 index aff51bd83..000000000 --- a/pg-migrator/src/schemas/secret-versions.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretVersionsSchema = z.object({ - id: z.string().uuid(), - version: z.number().default(1), - type: z.string().default("shared"), - secretBlindIndex: z.string().nullable().optional(), - secretKeyCiphertext: z.string(), - secretKeyIV: z.string(), - secretKeyTag: z.string(), - secretValueCiphertext: z.string(), - secretValueIV: z.string(), - secretValueTag: z.string(), - secretCommentCiphertext: z.string().nullable().optional(), - secretCommentIV: z.string().nullable().optional(), - secretCommentTag: z.string().nullable().optional(), - secretReminderNote: z.string().nullable().optional(), - secretReminderRepeatDays: z.number().nullable().optional(), - skipMultilineEncoding: z.boolean().default(false).nullable().optional(), - algorithm: z.string().default("aes-256-gcm"), - keyEncoding: z.string().default("utf8"), - metadata: z.unknown().nullable().optional(), - envId: z.string().uuid().nullable().optional(), - secretId: z.string().uuid(), - folderId: z.string().uuid(), - userId: z.string().uuid().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecretVersions = z.infer; -export type TSecretVersionsInsert = Omit; -export type TSecretVersionsUpdate = Partial< - Omit ->; diff --git a/pg-migrator/src/schemas/secrets.ts b/pg-migrator/src/schemas/secrets.ts deleted file mode 100644 index 646f9d070..000000000 --- a/pg-migrator/src/schemas/secrets.ts +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SecretsSchema = z.object({ - id: z.string().uuid(), - version: z.number().default(1), - type: z.string().default("shared"), - secretBlindIndex: z.string().nullable().optional(), - secretKeyCiphertext: z.string(), - secretKeyIV: z.string(), - secretKeyTag: z.string(), - secretValueCiphertext: z.string(), - secretValueIV: z.string(), - secretValueTag: z.string(), - secretCommentCiphertext: z.string().nullable().optional(), - secretCommentIV: z.string().nullable().optional(), - secretCommentTag: z.string().nullable().optional(), - secretReminderNote: z.string().nullable().optional(), - secretReminderRepeatDays: z.number().nullable().optional(), - skipMultilineEncoding: z.boolean().default(false).nullable().optional(), - algorithm: z.string().default("aes-256-gcm"), - keyEncoding: z.string().default("utf8"), - metadata: z.unknown().nullable().optional(), - userId: z.string().uuid().nullable().optional(), - folderId: z.string().uuid(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSecrets = z.infer; -export type TSecretsInsert = Omit; -export type TSecretsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/service-tokens.ts b/pg-migrator/src/schemas/service-tokens.ts deleted file mode 100644 index 29b0cd49f..000000000 --- a/pg-migrator/src/schemas/service-tokens.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const ServiceTokensSchema = z.object({ - id: z.string().uuid(), - name: z.string(), - scopes: z.unknown(), - permissions: z.string().array(), - lastUsed: z.date().nullable().optional(), - expiresAt: z.date().nullable().optional(), - secretHash: z.string(), - encryptedKey: z.string().nullable().optional(), - iv: z.string().nullable().optional(), - tag: z.string().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - createdBy: z.string(), - projectId: z.string(), -}); - -export type TServiceTokens = z.infer; -export type TServiceTokensInsert = Omit; -export type TServiceTokensUpdate = Partial>; diff --git a/pg-migrator/src/schemas/super-admin.ts b/pg-migrator/src/schemas/super-admin.ts deleted file mode 100644 index f998cf325..000000000 --- a/pg-migrator/src/schemas/super-admin.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const SuperAdminSchema = z.object({ - id: z.string().uuid(), - initialized: z.boolean().default(false).nullable().optional(), - allowSignUp: z.boolean().default(true).nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TSuperAdmin = z.infer; -export type TSuperAdminInsert = Omit; -export type TSuperAdminUpdate = Partial>; diff --git a/pg-migrator/src/schemas/trusted-ips.ts b/pg-migrator/src/schemas/trusted-ips.ts deleted file mode 100644 index c3311340d..000000000 --- a/pg-migrator/src/schemas/trusted-ips.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const TrustedIpsSchema = z.object({ - id: z.string().uuid(), - ipAddress: z.string(), - type: z.string(), - prefix: z.number().nullable().optional(), - isActive: z.boolean().default(true).nullable().optional(), - comment: z.string().nullable().optional(), - projectId: z.string(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TTrustedIps = z.infer; -export type TTrustedIpsInsert = Omit; -export type TTrustedIpsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/user-actions.ts b/pg-migrator/src/schemas/user-actions.ts deleted file mode 100644 index a3a07d699..000000000 --- a/pg-migrator/src/schemas/user-actions.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const UserActionsSchema = z.object({ - id: z.string().uuid(), - action: z.string(), - createdAt: z.date(), - updatedAt: z.date(), - userId: z.string().uuid(), -}); - -export type TUserActions = z.infer; -export type TUserActionsInsert = Omit; -export type TUserActionsUpdate = Partial>; diff --git a/pg-migrator/src/schemas/user-encryption-keys.ts b/pg-migrator/src/schemas/user-encryption-keys.ts deleted file mode 100644 index 0fde37ae7..000000000 --- a/pg-migrator/src/schemas/user-encryption-keys.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const UserEncryptionKeysSchema = z.object({ - id: z.string().uuid(), - clientPublicKey: z.string().nullable().optional(), - serverPrivateKey: z.string().nullable().optional(), - encryptionVersion: z.number().default(2).nullable().optional(), - protectedKey: z.string(), - protectedKeyIV: z.string(), - protectedKeyTag: z.string(), - publicKey: z.string(), - encryptedPrivateKey: z.string(), - iv: z.string(), - tag: z.string(), - salt: z.string(), - verifier: z.string(), - userId: z.string().uuid(), -}); - -export type TUserEncryptionKeys = z.infer; -export type TUserEncryptionKeysInsert = Omit; -export type TUserEncryptionKeysUpdate = Partial>; diff --git a/pg-migrator/src/schemas/users.ts b/pg-migrator/src/schemas/users.ts deleted file mode 100644 index b9689883d..000000000 --- a/pg-migrator/src/schemas/users.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const UsersSchema = z.object({ - id: z.string().uuid(), - email: z.string(), - authMethods: z.string().array().nullable().optional(), - superAdmin: z.boolean().default(false).nullable().optional(), - firstName: z.string().nullable().optional(), - lastName: z.string().nullable().optional(), - isAccepted: z.boolean().default(false).nullable().optional(), - isMfaEnabled: z.boolean().default(false).nullable().optional(), - mfaMethods: z.string().array().nullable().optional(), - devices: z.unknown().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), -}); - -export type TUsers = z.infer; -export type TUsersInsert = Omit; -export type TUsersUpdate = Partial>; diff --git a/pg-migrator/src/schemas/webhooks.ts b/pg-migrator/src/schemas/webhooks.ts deleted file mode 100644 index 2b7e36cab..000000000 --- a/pg-migrator/src/schemas/webhooks.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by automation script, DO NOT EDIT. -// Automated by pulling database and generating zod schema -// To update. Just run npm run generate:schema -// Written by akhilmhdh. - -import { z } from "zod"; - -import { TImmutableDBKeys } from "./models"; - -export const WebhooksSchema = z.object({ - id: z.string().uuid(), - secretPath: z.string().default('/'), - url: z.string(), - lastStatus: z.string().nullable().optional(), - lastRunErrorMessage: z.string().nullable().optional(), - isDisabled: z.boolean().default(false), - encryptedSecretKey: z.string().nullable().optional(), - iv: z.string().nullable().optional(), - tag: z.string().nullable().optional(), - algorithm: z.string().nullable().optional(), - keyEncoding: z.string().nullable().optional(), - createdAt: z.date(), - updatedAt: z.date(), - envId: z.string().uuid(), -}); - -export type TWebhooks = z.infer; -export type TWebhooksInsert = Omit; -export type TWebhooksUpdate = Partial>; diff --git a/pg-migrator/src/utils.ts b/pg-migrator/src/utils.ts deleted file mode 100644 index b59ae8bbe..000000000 --- a/pg-migrator/src/utils.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Knex } from "knex"; - -import { TableName } from "./schemas"; - -export const createJunctionTable = ( - knex: Knex, - tableName: TableName, - table1Name: TableName, - table2Name: TableName, -) => - knex.schema.createTable(tableName, (table) => { - table.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); - table.uuid(`${table1Name}Id`).unsigned().notNullable(); // Foreign key for table1 - table.uuid(`${table2Name}Id`).unsigned().notNullable(); // Foreign key for table2 - table - .foreign(`${table1Name}Id`) - .references("id") - .inTable(table1Name) - .onDelete("CASCADE"); - table - .foreign(`${table2Name}Id`) - .references("id") - .inTable(table2Name) - .onDelete("CASCADE"); - }); - -// one time logic -// this is a postgres function log to set updateAt to present time whenever row gets updated -export const createUpdateAtTriggerFunction = (knex: Knex) => - knex.raw(` -CREATE OR REPLACE FUNCTION on_update_timestamp() RETURNS TRIGGER AS $$ BEGIN NEW."updatedAt" = NOW(); -RETURN NEW; -END; -$$ LANGUAGE plpgsql; -`); - -export const dropUpdatedAtTriggerFunction = (knex: Knex) => - knex.raw(` -DROP FUNCTION IF EXISTS on_update_timestamp() CASCADE; -`); - -// we would be using this to apply updatedAt where ever we wanta -// remember to set `timestamps(true,true,true)` before this on schema -export const createOnUpdateTrigger = (knex: Knex, tableName: string) => - knex.raw(` -CREATE TRIGGER "${tableName}_updatedAt" -BEFORE UPDATE ON ${tableName} -FOR EACH ROW -EXECUTE PROCEDURE on_update_timestamp(); -`); - -export const dropOnUpdateTrigger = (knex: Knex, tableName: string) => - knex.raw(`DROP TRIGGER IF EXISTS "${tableName}_updatedAt" ON ${tableName}`); diff --git a/pg-migrator/tsconfig.json b/pg-migrator/tsconfig.json deleted file mode 100644 index f17360603..000000000 --- a/pg-migrator/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "lib": ["es6"], - "typeRoots": ["./node_modules/@types", "./src/@types", "./node_modules"], - "allowJs": true, - "outDir": "build", - "rootDir": "src", - "strict": true, - "noImplicitAny": true, - "esModuleInterop": true, - "resolveJsonModule": true - } -}