mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 14:26:25 +00:00
Merge pull request #1332 from akhilmhdh/feat/infisical-pg
Hello world from PG
This commit is contained in:
@@ -0,0 +1,57 @@
|
|||||||
|
name: Release standalone postgres version
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "infisical/v*.*.*-postgres"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
infisical-standalone:
|
||||||
|
name: Build infisical standalone image postgres
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Extract version from tag
|
||||||
|
id: extract_version
|
||||||
|
run: echo "::set-output name=version::${GITHUB_REF_NAME#infisical/}"
|
||||||
|
- name: ☁️ Checkout source
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: 📦 Install dependencies to test all dependencies
|
||||||
|
run: npm ci --only-production
|
||||||
|
working-directory: backend
|
||||||
|
- name: version output
|
||||||
|
run: |
|
||||||
|
echo "Output Value: ${{ steps.version.outputs.major }}"
|
||||||
|
echo "Output Value: ${{ steps.version.outputs.minor }}"
|
||||||
|
echo "Output Value: ${{ steps.version.outputs.patch }}"
|
||||||
|
echo "Output Value: ${{ steps.version.outputs.version }}"
|
||||||
|
echo "Output Value: ${{ steps.version.outputs.version_type }}"
|
||||||
|
echo "Output Value: ${{ steps.version.outputs.increment }}"
|
||||||
|
- name: Save commit hashes for tag
|
||||||
|
id: commit
|
||||||
|
uses: pr-mpt/actions-commit-hash@v2
|
||||||
|
- name: 🐋 Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64
|
||||||
|
file: Dockerfile.standalone-infisical
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
akhilmhdh/destruction:latest
|
||||||
|
akhilmhdh/destruction:${{ steps.commit.outputs.short }}
|
||||||
|
akhilmhdh/destruction:${{ steps.extract_version.outputs.version }}
|
||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
# backend
|
# backend
|
||||||
node_modules
|
node_modules
|
||||||
.env
|
.env
|
||||||
|
.env.test
|
||||||
.env.dev
|
.env.dev
|
||||||
.env.gamma
|
.env.gamma
|
||||||
.env.prod
|
.env.prod
|
||||||
@@ -61,4 +62,4 @@ yarn-error.log*
|
|||||||
# Editor specific
|
# Editor specific
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
|
||||||
frontend-build
|
frontend-build
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ ARG POSTHOG_HOST=https://app.posthog.com
|
|||||||
ARG POSTHOG_API_KEY=posthog-api-key
|
ARG POSTHOG_API_KEY=posthog-api-key
|
||||||
ARG INTERCOM_ID=intercom-id
|
ARG INTERCOM_ID=intercom-id
|
||||||
|
|
||||||
FROM node:16-alpine AS base
|
FROM node:20-alpine AS base
|
||||||
|
|
||||||
FROM base AS frontend-dependencies
|
FROM base AS frontend-dependencies
|
||||||
|
|
||||||
@@ -68,11 +68,12 @@ RUN addgroup --system --gid 1001 nodejs \
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY backend/package*.json ./
|
COPY backend-pg/package*.json ./
|
||||||
RUN npm ci --only-production
|
RUN npm ci --only-production
|
||||||
|
|
||||||
COPY /backend .
|
COPY /backend-pg .
|
||||||
COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh
|
COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh
|
||||||
|
RUN npm i -D tsconfig-paths
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Production stage
|
# Production stage
|
||||||
@@ -80,7 +81,7 @@ FROM base AS backend-runner
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY backend/package*.json ./
|
COPY backend-pg/package*.json ./
|
||||||
RUN npm ci --only-production
|
RUN npm ci --only-production
|
||||||
|
|
||||||
COPY --from=backend-build /app .
|
COPY --from=backend-build /app .
|
||||||
@@ -102,16 +103,19 @@ ENV NEXT_PUBLIC_INTERCOM_ID=$INTERCOM_ID \
|
|||||||
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|
||||||
COPY --from=backend-runner /app /backend
|
COPY --from=backend-runner /app /backend-pg
|
||||||
|
COPY --from=backend-runner /app/dist/services/smtp/templates /backend-pg/dist/templates
|
||||||
|
|
||||||
|
COPY --from=frontend-runner /app ./backend-pg/frontend-build
|
||||||
|
|
||||||
COPY --from=frontend-runner /app ./backend/frontend-build
|
|
||||||
|
|
||||||
ENV PORT 8080
|
ENV PORT 8080
|
||||||
|
ENV HOST=0.0.0.0
|
||||||
ENV HTTPS_ENABLED false
|
ENV HTTPS_ENABLED false
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
ENV STANDALONE_BUILD true
|
ENV STANDALONE_BUILD true
|
||||||
|
ENV STANDALONE_MODE true
|
||||||
WORKDIR /backend
|
WORKDIR /backend-pg
|
||||||
|
|
||||||
ENV TELEMETRY_ENABLED true
|
ENV TELEMETRY_ENABLED true
|
||||||
|
|
||||||
@@ -119,10 +123,8 @@ HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \
|
|||||||
CMD node healthcheck.js
|
CMD node healthcheck.js
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
EXPOSE 443
|
||||||
|
|
||||||
USER non-root-user
|
USER non-root-user
|
||||||
|
|
||||||
CMD ["./standalone-entrypoint.sh"]
|
CMD ["./standalone-entrypoint.sh"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ push:
|
|||||||
up-dev:
|
up-dev:
|
||||||
docker-compose -f docker-compose.dev.yml up --build
|
docker-compose -f docker-compose.dev.yml up --build
|
||||||
|
|
||||||
|
up-pg-dev:
|
||||||
|
docker compose -f docker-compose.pg.yml up --build
|
||||||
|
|
||||||
i-dev:
|
i-dev:
|
||||||
infisical run -- docker-compose -f docker-compose.dev.yml up --build
|
infisical run -- docker-compose -f docker-compose.dev.yml up --build
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
node_modules
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
docker-compose.*
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
vitest-environment-infisical.ts
|
||||||
|
vitest.config.ts
|
||||||
|
.eslintrc.js
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2021: true
|
||||||
|
},
|
||||||
|
extends: ["airbnb-base", "airbnb-typescript/base", "prettier"],
|
||||||
|
plugins: ["prettier", "simple-import-sort", "import"],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
sourceType: "module",
|
||||||
|
project: "./tsconfig.json",
|
||||||
|
tsconfigRootDir: __dirname
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// "@typescript-eslint/no-empty-function": "off",
|
||||||
|
"consistent-return": "off", // my style
|
||||||
|
"import/order": "off", // for simple-import-order
|
||||||
|
"import/prefer-default-export": "off", // why
|
||||||
|
"no-restricted-syntax": "off",
|
||||||
|
"import/first": "error",
|
||||||
|
"import/newline-after-import": "error",
|
||||||
|
"import/no-duplicates": "error",
|
||||||
|
"simple-import-sort/exports": "error",
|
||||||
|
"simple-import-sort/imports": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
groups: [
|
||||||
|
// Side effect imports.
|
||||||
|
["^\\u0000"],
|
||||||
|
// Node.js builtins prefixed with `node:`.
|
||||||
|
["^node:"],
|
||||||
|
// Packages.
|
||||||
|
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
|
||||||
|
["^@?\\w"],
|
||||||
|
["^@app"],
|
||||||
|
["@lib"],
|
||||||
|
["@server"],
|
||||||
|
// Absolute imports and other imports such as Vue-style `@/foo`.
|
||||||
|
// Anything not matched in another group.
|
||||||
|
["^"],
|
||||||
|
// Relative imports.
|
||||||
|
// Anything that starts with a dot.
|
||||||
|
["^\\."]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
"import/resolver": {
|
||||||
|
typescript: {
|
||||||
|
project: ["./tsconfig.json"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
dist
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": false,
|
||||||
|
"printWidth": 100,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"semi": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Build stage
|
||||||
|
FROM node:20-alpine AS build
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci --only-production
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV npm_config_cache /home/node/.npm
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci --only-production && npm cache clean --force
|
||||||
|
|
||||||
|
COPY --from=build /app .
|
||||||
|
|
||||||
|
RUN apk add --no-cache bash curl && curl -1sLf \
|
||||||
|
'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.alpine.sh' | bash \
|
||||||
|
&& apk add infisical=0.8.1 && apk add --no-cache git
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \
|
||||||
|
CMD node healthcheck.js
|
||||||
|
|
||||||
|
EXPOSE 4000
|
||||||
|
|
||||||
|
CMD ["npm", "start"]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
RUN apk add --no-cache bash curl && curl -1sLf \
|
||||||
|
'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.alpine.sh' | bash \
|
||||||
|
&& apk add infisical=0.8.1 && apk add --no-cache git
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json package.json
|
||||||
|
COPY package-lock.json package-lock.json
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
ENV HOST=0.0.0.0
|
||||||
|
|
||||||
|
CMD ["npm", "run", "dev:docker"]
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { TQueueServiceFactory } from "@app/queue";
|
||||||
|
|
||||||
|
export const mockQueue = (): TQueueServiceFactory => {
|
||||||
|
const queues: Record<string, unknown> = {};
|
||||||
|
const workers: Record<string, unknown> = {};
|
||||||
|
const job: Record<string, unknown> = {};
|
||||||
|
const events: Record<string, unknown> = {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
queue: async (name, jobData) => {
|
||||||
|
job[name] = jobData;
|
||||||
|
},
|
||||||
|
shutdown: async () => undefined,
|
||||||
|
stopRepeatableJob: async () => true,
|
||||||
|
start: (name, jobFn) => {
|
||||||
|
queues[name] = jobFn;
|
||||||
|
workers[name] = jobFn;
|
||||||
|
},
|
||||||
|
listen: async (name, event) => {
|
||||||
|
events[name] = event;
|
||||||
|
},
|
||||||
|
stopRepeatableJobByJobId: async () => true
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { TSmtpSendMail, TSmtpService } from "@app/services/smtp/smtp-service";
|
||||||
|
|
||||||
|
export const mockSmtpServer = (): TSmtpService => {
|
||||||
|
const storage: TSmtpSendMail[] = [];
|
||||||
|
return {
|
||||||
|
sendMail: async (data) => {
|
||||||
|
storage.push(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { seedData1 } from "@app/db/seed-data";
|
||||||
|
import jsrp from "jsrp";
|
||||||
|
|
||||||
|
describe("Login V1 Router", async () => {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const client = new jsrp.client();
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
client.init({ username: seedData1.email, password: seedData1.password }, () => resolve(null));
|
||||||
|
});
|
||||||
|
let clientProof: string;
|
||||||
|
|
||||||
|
test("Login first phase", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "POST",
|
||||||
|
url: "/api/v3/auth/login1",
|
||||||
|
body: {
|
||||||
|
email: "[email protected]",
|
||||||
|
clientPublicKey: client.getPublicKey()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("serverPublicKey");
|
||||||
|
expect(payload).toHaveProperty("salt");
|
||||||
|
client.setSalt(payload.salt);
|
||||||
|
client.setServerPublicKey(payload.serverPublicKey);
|
||||||
|
clientProof = client.getProof(); // called M1
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Login second phase", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "POST",
|
||||||
|
url: "/api/v3/auth/login2",
|
||||||
|
body: {
|
||||||
|
email: seedData1.email,
|
||||||
|
clientProof
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("mfaEnabled");
|
||||||
|
expect(payload).toHaveProperty("token");
|
||||||
|
expect(payload.mfaEnabled).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { seedData1 } from "@app/db/seed-data";
|
||||||
|
|
||||||
|
describe("Org V1 Router", async () => {
|
||||||
|
test("GET Org list", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: "/api/v1/organization",
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("organizations");
|
||||||
|
expect(payload).toEqual({
|
||||||
|
organizations: [expect.objectContaining({ name: seedData1.organization.name })]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
import { seedData1 } from "@app/db/seed-data";
|
||||||
|
import { DEFAULT_PROJECT_ENVS } from "@app/db/seeds/3-project";
|
||||||
|
|
||||||
|
describe("Project Environment Router", async () => {
|
||||||
|
test("Get default environments", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/workspace/${seedData1.project.id}`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("workspace");
|
||||||
|
// check for default environments
|
||||||
|
expect(payload).toEqual({
|
||||||
|
workspace: expect.objectContaining({
|
||||||
|
name: seedData1.project.name,
|
||||||
|
id: seedData1.project.id,
|
||||||
|
slug: seedData1.project.slug,
|
||||||
|
environments: expect.arrayContaining([
|
||||||
|
expect.objectContaining(DEFAULT_PROJECT_ENVS[0]),
|
||||||
|
expect.objectContaining(DEFAULT_PROJECT_ENVS[1]),
|
||||||
|
expect.objectContaining(DEFAULT_PROJECT_ENVS[2])
|
||||||
|
])
|
||||||
|
})
|
||||||
|
});
|
||||||
|
// ensure only two default environments exist
|
||||||
|
expect(payload.workspace.environments.length).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockProjectEnv = { name: "temp", slug: "temp", id: "" }; // id will be filled in create op
|
||||||
|
test("Create environment", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "POST",
|
||||||
|
url: `/api/v1/workspace/${seedData1.project.id}/environments`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
name: mockProjectEnv.name,
|
||||||
|
slug: mockProjectEnv.slug
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("environment");
|
||||||
|
expect(payload.environment).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: mockProjectEnv.name,
|
||||||
|
slug: mockProjectEnv.slug,
|
||||||
|
projectId: seedData1.project.id,
|
||||||
|
position: DEFAULT_PROJECT_ENVS.length + 1,
|
||||||
|
createdAt: expect.any(String),
|
||||||
|
updatedAt: expect.any(String)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
mockProjectEnv.id = payload.environment.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Update environment", async () => {
|
||||||
|
const updatedName = { name: "temp#2", slug: "temp2" };
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "PATCH",
|
||||||
|
url: `/api/v1/workspace/${seedData1.project.id}/environments/${mockProjectEnv.id}`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
name: updatedName.name,
|
||||||
|
slug: updatedName.slug,
|
||||||
|
position: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("environment");
|
||||||
|
expect(payload.environment).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: updatedName.name,
|
||||||
|
slug: updatedName.slug,
|
||||||
|
projectId: seedData1.project.id,
|
||||||
|
position: 1,
|
||||||
|
createdAt: expect.any(String),
|
||||||
|
updatedAt: expect.any(String)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
mockProjectEnv.name = updatedName.name;
|
||||||
|
mockProjectEnv.slug = updatedName.slug;
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Delete environment", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "DELETE",
|
||||||
|
url: `/api/v1/workspace/${seedData1.project.id}/environments/${mockProjectEnv.id}`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("environment");
|
||||||
|
expect(payload.environment).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: mockProjectEnv.name,
|
||||||
|
slug: mockProjectEnv.slug,
|
||||||
|
position: 1,
|
||||||
|
createdAt: expect.any(String),
|
||||||
|
updatedAt: expect.any(String)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// after all these opreations the list of environment should be still same
|
||||||
|
test("Default list of environment", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/workspace/${seedData1.project.id}`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("workspace");
|
||||||
|
// check for default environments
|
||||||
|
expect(payload).toEqual({
|
||||||
|
workspace: expect.objectContaining({
|
||||||
|
name: seedData1.project.name,
|
||||||
|
id: seedData1.project.id,
|
||||||
|
slug: seedData1.project.slug,
|
||||||
|
environments: expect.arrayContaining([
|
||||||
|
expect.objectContaining(DEFAULT_PROJECT_ENVS[0]),
|
||||||
|
expect.objectContaining(DEFAULT_PROJECT_ENVS[1]),
|
||||||
|
expect.objectContaining(DEFAULT_PROJECT_ENVS[2])
|
||||||
|
])
|
||||||
|
})
|
||||||
|
});
|
||||||
|
// ensure only two default environments exist
|
||||||
|
expect(payload.workspace.environments.length).toBe(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
import { seedData1 } from "@app/db/seed-data";
|
||||||
|
|
||||||
|
describe("Secret Folder Router", async () => {
|
||||||
|
test.each([
|
||||||
|
{ name: "folder1", path: "/" }, // one in root
|
||||||
|
{ name: "folder1", path: "/level1/level2" }, // then create a deep one creating intermediate ones
|
||||||
|
{ name: "folder2", path: "/" },
|
||||||
|
{ name: "folder1", path: "/level1/level2" } // this should not create folder return same thing
|
||||||
|
])("Create folder $name in $path", async ({ name, path }) => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "POST",
|
||||||
|
url: `/api/v1/folders`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
name,
|
||||||
|
path
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("folder");
|
||||||
|
// check for default environments
|
||||||
|
expect(payload).toEqual({
|
||||||
|
folder: expect.objectContaining({
|
||||||
|
name,
|
||||||
|
id: expect.any(String)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
expected: {
|
||||||
|
folders: [{ name: "folder1" }, { name: "level1" }, { name: "folder2" }],
|
||||||
|
length: 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ path: "/level1/level2", expected: { folders: [{ name: "folder1" }], length: 1 } }
|
||||||
|
])("Get folders $path", async ({ path, expected }) => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/folders`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("folders");
|
||||||
|
expect(payload.folders.length).toBe(expected.length);
|
||||||
|
expect(payload).toEqual({ folders: expected.folders.map((el) => expect.objectContaining(el)) });
|
||||||
|
});
|
||||||
|
|
||||||
|
let toBeDeleteFolderId = "";
|
||||||
|
test("Update a deep folder", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "PATCH",
|
||||||
|
url: `/api/v1/folders/folder1`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
name: "folder-updated",
|
||||||
|
path: "/level1/level2"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("folder");
|
||||||
|
expect(payload.folder).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: "folder-updated"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
toBeDeleteFolderId = payload.folder.id;
|
||||||
|
|
||||||
|
const resUpdatedFolders = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/folders`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/level1/level2"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resUpdatedFolders.statusCode).toBe(200);
|
||||||
|
const updatedFolderList = JSON.parse(resUpdatedFolders.payload);
|
||||||
|
expect(updatedFolderList).toHaveProperty("folders");
|
||||||
|
expect(updatedFolderList.folders.length).toEqual(1);
|
||||||
|
expect(updatedFolderList.folders[0].name).toEqual("folder-updated");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Delete a deep folder", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "DELETE",
|
||||||
|
url: `/api/v1/folders/${toBeDeleteFolderId}`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/level1/level2"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("folder");
|
||||||
|
expect(payload.folder).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: "folder-updated"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const resUpdatedFolders = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/folders`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/level1/level2"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resUpdatedFolders.statusCode).toBe(200);
|
||||||
|
const updatedFolderList = JSON.parse(resUpdatedFolders.payload);
|
||||||
|
expect(updatedFolderList).toHaveProperty("folders");
|
||||||
|
expect(updatedFolderList.folders.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
import { seedData1 } from "@app/db/seed-data";
|
||||||
|
|
||||||
|
describe("Secret Folder Router", async () => {
|
||||||
|
test.each([
|
||||||
|
{ importEnv: "dev", importPath: "/" }, // one in root
|
||||||
|
{ importEnv: "staging", importPath: "/" } // then create a deep one creating intermediate ones
|
||||||
|
])("Create secret import $importEnv with path $importPath", async ({ importPath, importEnv }) => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "POST",
|
||||||
|
url: `/api/v1/secret-imports`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/",
|
||||||
|
import: {
|
||||||
|
environment: importEnv,
|
||||||
|
path: importPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("secretImport");
|
||||||
|
// check for default environments
|
||||||
|
expect(payload.secretImport).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
importPath: expect.any(String),
|
||||||
|
importEnv: expect.objectContaining({
|
||||||
|
name: expect.any(String),
|
||||||
|
slug: expect.any(String),
|
||||||
|
id: expect.any(String)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
let testSecretImportId = "";
|
||||||
|
test("Get secret imports", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/secret-imports`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("secretImports");
|
||||||
|
expect(payload.secretImports.length).toBe(2);
|
||||||
|
testSecretImportId = payload.secretImports[0].id;
|
||||||
|
expect(payload.secretImports).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
importPath: expect.any(String),
|
||||||
|
importEnv: expect.objectContaining({
|
||||||
|
name: expect.any(String),
|
||||||
|
slug: expect.any(String),
|
||||||
|
id: expect.any(String)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Update secret import position", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "PATCH",
|
||||||
|
url: `/api/v1/secret-imports/${testSecretImportId}`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/",
|
||||||
|
import: {
|
||||||
|
position: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("secretImport");
|
||||||
|
// check for default environments
|
||||||
|
expect(payload.secretImport).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
importPath: expect.any(String),
|
||||||
|
position: 2,
|
||||||
|
importEnv: expect.objectContaining({
|
||||||
|
name: expect.any(String),
|
||||||
|
slug: expect.any(String),
|
||||||
|
id: expect.any(String)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const secretImportsListRes = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/secret-imports`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(secretImportsListRes.statusCode).toBe(200);
|
||||||
|
const secretImportList = JSON.parse(secretImportsListRes.payload);
|
||||||
|
expect(secretImportList).toHaveProperty("secretImports");
|
||||||
|
expect(secretImportList.secretImports[1].id).toEqual(testSecretImportId);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Delete secret import position", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "DELETE",
|
||||||
|
url: `/api/v1/secret-imports/${testSecretImportId}`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
const payload = JSON.parse(res.payload);
|
||||||
|
expect(payload).toHaveProperty("secretImport");
|
||||||
|
// check for default environments
|
||||||
|
expect(payload.secretImport).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
importPath: expect.any(String),
|
||||||
|
importEnv: expect.objectContaining({
|
||||||
|
name: expect.any(String),
|
||||||
|
slug: expect.any(String),
|
||||||
|
id: expect.any(String)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const secretImportsListRes = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api/v1/secret-imports`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${jwtAuthToken}`
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
workspaceId: seedData1.project.id,
|
||||||
|
environment: seedData1.environment.slug,
|
||||||
|
path: "/"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(secretImportsListRes.statusCode).toBe(200);
|
||||||
|
const secretImportList = JSON.parse(secretImportsListRes.payload);
|
||||||
|
expect(secretImportList).toHaveProperty("secretImports");
|
||||||
|
expect(secretImportList.secretImports.length).toEqual(1);
|
||||||
|
expect(secretImportList.secretImports[0].position).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
describe("Status V1 Router", async () => {
|
||||||
|
test("Simple check", async () => {
|
||||||
|
const res = await testServer.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: "/api/status"
|
||||||
|
});
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// import { main } from "@app/server/app";
|
||||||
|
import { initEnvConfig } from "@app/lib/config/env";
|
||||||
|
import dotenv from "dotenv";
|
||||||
|
import knex from "knex";
|
||||||
|
import path from "path";
|
||||||
|
import { mockSmtpServer } from "./mocks/smtp";
|
||||||
|
import { initLogger } from "@app/lib/logger";
|
||||||
|
import jwt from "jsonwebtoken";
|
||||||
|
|
||||||
|
import "ts-node/register";
|
||||||
|
import { main } from "@app/server/app";
|
||||||
|
import { mockQueue } from "./mocks/queue";
|
||||||
|
import { AuthTokenType } from "@app/services/auth/auth-type";
|
||||||
|
import { seedData1 } from "@app/db/seed-data";
|
||||||
|
|
||||||
|
dotenv.config({ path: path.join(__dirname, "../.env.test") });
|
||||||
|
export default {
|
||||||
|
name: "knex-env",
|
||||||
|
transformMode: "ssr",
|
||||||
|
async setup() {
|
||||||
|
const db = knex({
|
||||||
|
client: "pg",
|
||||||
|
connection: process.env.DB_CONNECTION_URI,
|
||||||
|
migrations: {
|
||||||
|
directory: path.join(__dirname, "../src/db/migrations"),
|
||||||
|
extension: "ts",
|
||||||
|
tableName: "infisical_migrations"
|
||||||
|
},
|
||||||
|
seeds: {
|
||||||
|
directory: path.join(__dirname, "../src/db/seeds"),
|
||||||
|
extension: "ts"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await db.migrate.latest();
|
||||||
|
await db.seed.run();
|
||||||
|
const smtp = mockSmtpServer();
|
||||||
|
const queue = mockQueue();
|
||||||
|
const logger = await initLogger();
|
||||||
|
const cfg = initEnvConfig(logger);
|
||||||
|
const server = await main({ db, smtp, logger, queue });
|
||||||
|
// @ts-expect-error type
|
||||||
|
globalThis.testServer = server;
|
||||||
|
// @ts-expect-error type
|
||||||
|
globalThis.jwtAuthToken = jwt.sign(
|
||||||
|
{
|
||||||
|
authTokenType: AuthTokenType.ACCESS_TOKEN,
|
||||||
|
userId: seedData1.id,
|
||||||
|
tokenVersionId: seedData1.token.id,
|
||||||
|
accessVersion: 1
|
||||||
|
},
|
||||||
|
cfg.AUTH_SECRET,
|
||||||
|
{ expiresIn: cfg.JWT_AUTH_LIFETIME }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
await db.destroy();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
// custom setup
|
||||||
|
return {
|
||||||
|
async teardown() {
|
||||||
|
// @ts-expect-error type
|
||||||
|
await globalThis.testServer.close();
|
||||||
|
// @ts-expect-error type
|
||||||
|
delete globalThis.testServer;
|
||||||
|
// @ts-expect-error type
|
||||||
|
delete globalThis.jwtToken;
|
||||||
|
// called after all tests with this env have been run
|
||||||
|
await db.migrate.rollback({}, true);
|
||||||
|
await db.destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"watch": ["src"],
|
||||||
|
"ext": ".ts,.js",
|
||||||
|
"ignore": [],
|
||||||
|
"exec": "tsx ./src/main.ts | pino-pretty --colorize --colorizeObjects --singleLine"
|
||||||
|
}
|
||||||
Generated
+14066
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,125 @@
|
|||||||
|
{
|
||||||
|
"name": "backend-pg",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"dev": "tsx watch --clear-screen=false ./src/main.ts | pino-pretty --colorize --colorizeObjects --singleLine",
|
||||||
|
"dev:docker": "nodemon",
|
||||||
|
"build": "rimraf dist && tsup",
|
||||||
|
"start": "node dist/main.mjs",
|
||||||
|
"type:check": "tsc --noEmit",
|
||||||
|
"lint:fix": "eslint --fix --ext js,ts ./src",
|
||||||
|
"lint": "eslint 'src/**/*.ts'",
|
||||||
|
"test:e2e": "vitest run -c vitest.e2e.config.ts",
|
||||||
|
"test:e2e-watch": "vitest -c vitest.e2e.config.ts",
|
||||||
|
"test:e2e-coverage": "vitest run --coverage -c vitest.e2e.config.ts",
|
||||||
|
"generate:component": "tsx ./scripts/create-backend-file.ts",
|
||||||
|
"generate:schema": "tsx ./scripts/generate-schema-types.ts",
|
||||||
|
"migration:new": "tsx ./scripts/create-migration.ts",
|
||||||
|
"migration:up": "knex --knexfile ./src/db/knexfile.ts --client pg migrate:up",
|
||||||
|
"migration:down": "knex --knexfile ./src/db/knexfile.ts --client pg migrate:down",
|
||||||
|
"migration:list": "knex --knexfile ./src/db/knexfile.ts --client pg migrate:list",
|
||||||
|
"migration:latest": "knex --knexfile ./src/db/knexfile.ts --client pg migrate:latest",
|
||||||
|
"migration:rollback": "knex --knexfile ./src/db/knexfile.ts migrate:rollback",
|
||||||
|
"seed:new": "tsx ./scripts/create-seed-file.ts",
|
||||||
|
"seed:run": "knex --knexfile ./src/db/knexfile.ts --client pg seed:run",
|
||||||
|
"db:reset": "npm run migration:rollback -- --all && npm run migration:latest && npm run seed:run"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bcrypt": "^5.0.2",
|
||||||
|
"@types/jmespath": "^0.15.2",
|
||||||
|
"@types/jsonwebtoken": "^9.0.5",
|
||||||
|
"@types/jsrp": "^0.2.6",
|
||||||
|
"@types/libsodium-wrappers": "^0.7.13",
|
||||||
|
"@types/lodash.isequal": "^4.5.8",
|
||||||
|
"@types/node": "^20.9.5",
|
||||||
|
"@types/nodemailer": "^6.4.14",
|
||||||
|
"@types/passport-github": "^1.1.12",
|
||||||
|
"@types/passport-google-oauth20": "^2.0.14",
|
||||||
|
"@types/pg": "^8.10.9",
|
||||||
|
"@types/picomatch": "^2.3.3",
|
||||||
|
"@types/prompt-sync": "^4.2.3",
|
||||||
|
"@types/uuid": "^9.0.7",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||||
|
"@typescript-eslint/parser": "^6.13.2",
|
||||||
|
"eslint": "^8.55.0",
|
||||||
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-import-resolver-typescript": "^3.6.1",
|
||||||
|
"eslint-plugin-import": "^2.29.0",
|
||||||
|
"eslint-plugin-prettier": "^5.0.1",
|
||||||
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||||
|
"nodemon": "^3.0.2",
|
||||||
|
"pino-pretty": "^10.2.3",
|
||||||
|
"prompt-sync": "^4.2.0",
|
||||||
|
"rimraf": "^5.0.5",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
|
"tsconfig-paths": "^4.2.0",
|
||||||
|
"tsup": "^8.0.1",
|
||||||
|
"tsx": "^4.4.0",
|
||||||
|
"typescript": "^5.3.2",
|
||||||
|
"vite-tsconfig-paths": "^4.2.2",
|
||||||
|
"vitest": "^1.0.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@aws-sdk/client-secrets-manager": "^3.485.0",
|
||||||
|
"@casl/ability": "^6.5.0",
|
||||||
|
"@fastify/cookie": "^9.2.0",
|
||||||
|
"@fastify/cors": "^8.4.1",
|
||||||
|
"@fastify/formbody": "^7.4.0",
|
||||||
|
"@fastify/helmet": "^11.1.1",
|
||||||
|
"@fastify/passport": "^2.4.0",
|
||||||
|
"@fastify/rate-limit": "^9.0.0",
|
||||||
|
"@fastify/session": "^10.7.0",
|
||||||
|
"@fastify/swagger": "^8.12.0",
|
||||||
|
"@fastify/swagger-ui": "^1.10.1",
|
||||||
|
"@node-saml/passport-saml": "^4.0.4",
|
||||||
|
"@octokit/rest": "^20.0.2",
|
||||||
|
"@octokit/webhooks-types": "^7.3.1",
|
||||||
|
"@sindresorhus/slugify": "^2.2.1",
|
||||||
|
"@ucast/mongo2js": "^1.3.4",
|
||||||
|
"ajv": "^8.12.0",
|
||||||
|
"argon2": "^0.31.2",
|
||||||
|
"aws-sdk": "^2.1532.0",
|
||||||
|
"axios": "^1.6.2",
|
||||||
|
"axios-retry": "^4.0.0",
|
||||||
|
"bcrypt": "^5.1.1",
|
||||||
|
"bullmq": "^5.1.1",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||||
|
"fastify": "^4.24.3",
|
||||||
|
"fastify-plugin": "^4.5.1",
|
||||||
|
"handlebars": "^4.7.8",
|
||||||
|
"ioredis": "^5.3.2",
|
||||||
|
"jmespath": "^0.16.0",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"jsrp": "^0.2.4",
|
||||||
|
"knex": "^3.0.1",
|
||||||
|
"libsodium-wrappers": "^0.7.13",
|
||||||
|
"lodash.isequal": "^4.5.0",
|
||||||
|
"mysql2": "^3.6.5",
|
||||||
|
"nanoid": "^5.0.4",
|
||||||
|
"node-cache": "^5.1.2",
|
||||||
|
"nodemailer": "^6.9.7",
|
||||||
|
"ora": "^7.0.1",
|
||||||
|
"passport-github": "^1.1.0",
|
||||||
|
"passport-gitlab2": "^5.0.0",
|
||||||
|
"passport-google-oauth20": "^2.0.0",
|
||||||
|
"pg": "^8.11.3",
|
||||||
|
"picomatch": "^3.0.1",
|
||||||
|
"pino": "^8.16.2",
|
||||||
|
"posthog-node": "^3.6.0",
|
||||||
|
"probot": "^12.3.3",
|
||||||
|
"smee-client": "^2.0.0",
|
||||||
|
"tweetnacl": "^1.0.3",
|
||||||
|
"tweetnacl-util": "^0.15.1",
|
||||||
|
"uuid": "^9.0.1",
|
||||||
|
"zod": "^3.22.4",
|
||||||
|
"zod-to-json-schema": "^3.22.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
import { mkdirSync, writeFileSync } from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import promptSync from "prompt-sync";
|
||||||
|
|
||||||
|
const prompt = promptSync({
|
||||||
|
sigint: true
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
Component List
|
||||||
|
--------------
|
||||||
|
1. Service component
|
||||||
|
2. DAL component
|
||||||
|
3. Router component
|
||||||
|
`);
|
||||||
|
const componentType = parseInt(prompt("Select a component: "), 10);
|
||||||
|
|
||||||
|
if (componentType === 1) {
|
||||||
|
const componentName = prompt("Enter service name: ");
|
||||||
|
const dir = path.join(__dirname, `../src/services/${componentName}`);
|
||||||
|
const pascalCase = componentName
|
||||||
|
.split("-")
|
||||||
|
.map((el) => `${el[0].toUpperCase()}${el.slice(1)}`)
|
||||||
|
.join("");
|
||||||
|
const camelCase = componentName
|
||||||
|
.split("-")
|
||||||
|
.map((el, index) => (index === 0 ? el : `${el[0].toUpperCase()}${el.slice(1)}`))
|
||||||
|
.join("");
|
||||||
|
const dalTypeName = `T${pascalCase}DALFactory`;
|
||||||
|
const dalName = `${camelCase}DALFactory`;
|
||||||
|
const serviceTypeName = `T${pascalCase}ServiceFactory`;
|
||||||
|
const serviceName = `${camelCase}ServiceFactory`;
|
||||||
|
|
||||||
|
mkdirSync(dir);
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
path.join(dir, `${componentName}-dal.ts`),
|
||||||
|
`import { TDbClient } from "@app/db";
|
||||||
|
import { TableName } from "@app/db/schemas";
|
||||||
|
|
||||||
|
export type ${dalTypeName} = ReturnType<typeof ${dalName}>;
|
||||||
|
|
||||||
|
export const ${dalName} = (db: TDbClient) => {
|
||||||
|
|
||||||
|
return { };
|
||||||
|
};
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
path.join(dir, `${componentName}-service.ts`),
|
||||||
|
`import { ${dalTypeName} } from "./${componentName}-dal";
|
||||||
|
|
||||||
|
type ${serviceTypeName}Dep = {
|
||||||
|
${camelCase}DAL: ${dalTypeName};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ${serviceTypeName} = ReturnType<typeof ${serviceName}>;
|
||||||
|
|
||||||
|
export const ${serviceName} = ({ ${camelCase}DAL }: ${serviceTypeName}Dep) => {
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
`
|
||||||
|
);
|
||||||
|
writeFileSync(path.join(dir, `${componentName}-types.ts`), "");
|
||||||
|
} else if (componentType === 2) {
|
||||||
|
const componentName = prompt("Enter service name: ");
|
||||||
|
const componentPath = prompt("Path wrt service folder: ");
|
||||||
|
const pascalCase = componentName
|
||||||
|
.split("-")
|
||||||
|
.map((el) => `${el[0].toUpperCase()}${el.slice(1)}`)
|
||||||
|
.join("");
|
||||||
|
const camelCase = componentName
|
||||||
|
.split("-")
|
||||||
|
.map((el, index) => (index === 0 ? el : `${el[0].toUpperCase()}${el.slice(1)}`))
|
||||||
|
.join("");
|
||||||
|
const dalTypeName = `T${pascalCase}DALFactory`;
|
||||||
|
const dalName = `${camelCase}DALFactory`;
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
path.join(__dirname, "../src/services", componentPath, `${componentName}-dal.ts`),
|
||||||
|
`import { TDbClient } from "@app/db";
|
||||||
|
import { TableName } from "@app/db/schemas";
|
||||||
|
|
||||||
|
export type ${dalTypeName} = ReturnType<typeof ${dalName}>;
|
||||||
|
|
||||||
|
export const ${dalName} = (db: TDbClient) => {
|
||||||
|
|
||||||
|
return { };
|
||||||
|
};
|
||||||
|
`
|
||||||
|
);
|
||||||
|
} else if (componentType === 3) {
|
||||||
|
const name = prompt("Enter router name: ");
|
||||||
|
const version = prompt("Version number: ");
|
||||||
|
const pascalCase = name
|
||||||
|
.split("-")
|
||||||
|
.map((el) => `${el[0].toUpperCase()}${el.slice(1)}`)
|
||||||
|
.join("");
|
||||||
|
writeFileSync(
|
||||||
|
path.join(__dirname, `../src/server/routes/v${Number(version)}/${name}-router.ts`),
|
||||||
|
`import { z } from "zod";
|
||||||
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
|
export const register${pascalCase}Router = async (server: FastifyZodProvider) => {
|
||||||
|
server.route({
|
||||||
|
url: "/",
|
||||||
|
method: "GET",
|
||||||
|
schema: {
|
||||||
|
params: z.object({}),
|
||||||
|
response: {
|
||||||
|
200: z.object({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
import { execSync } from "child_process";
|
||||||
|
import path from "path";
|
||||||
|
import promptSync from "prompt-sync";
|
||||||
|
|
||||||
|
const prompt = promptSync({ sigint: true });
|
||||||
|
|
||||||
|
const migrationName = prompt("Enter name for migration: ");
|
||||||
|
|
||||||
|
execSync(
|
||||||
|
`npx knex migrate:make --knexfile ${path.join(
|
||||||
|
__dirname,
|
||||||
|
"../src/db/knexfile.ts"
|
||||||
|
)} -x ts ${migrationName}`,
|
||||||
|
{ stdio: "inherit" }
|
||||||
|
);
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
import { execSync } from "child_process";
|
||||||
|
import { readdirSync } from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import promptSync from "prompt-sync";
|
||||||
|
|
||||||
|
const prompt = promptSync({ sigint: true });
|
||||||
|
|
||||||
|
const migrationName = prompt("Enter name for seedfile: ");
|
||||||
|
const fileCounter = readdirSync(path.join(__dirname, "../src/db/seed")).length || 1;
|
||||||
|
execSync(
|
||||||
|
`npx knex seed:make --knexfile ${path.join(
|
||||||
|
__dirname,
|
||||||
|
"../src/db/knexfile.ts"
|
||||||
|
)} -x ts ${fileCounter}-${migrationName}`,
|
||||||
|
{ stdio: "inherit" }
|
||||||
|
);
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
import dotenv from "dotenv";
|
||||||
|
import path from "path";
|
||||||
|
import knex from "knex";
|
||||||
|
import { writeFileSync } from "fs";
|
||||||
|
import promptSync from "prompt-sync";
|
||||||
|
|
||||||
|
const prompt = promptSync({ sigint: true });
|
||||||
|
|
||||||
|
dotenv.config({
|
||||||
|
path: path.join(__dirname, "../.env"),
|
||||||
|
debug: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const db = knex({
|
||||||
|
client: "pg",
|
||||||
|
connection: process.env.DB_CONNECTION_URI
|
||||||
|
});
|
||||||
|
|
||||||
|
const getZodPrimitiveType = (type: string) => {
|
||||||
|
switch (type) {
|
||||||
|
case "uuid":
|
||||||
|
return "z.string().uuid()";
|
||||||
|
case "character varying":
|
||||||
|
return "z.string()";
|
||||||
|
case "ARRAY":
|
||||||
|
return "z.string().array()";
|
||||||
|
case "boolean":
|
||||||
|
return "z.boolean()";
|
||||||
|
case "jsonb":
|
||||||
|
return "z.unknown()";
|
||||||
|
case "json":
|
||||||
|
return "z.unknown()";
|
||||||
|
case "timestamp with time zone":
|
||||||
|
return "z.date()";
|
||||||
|
case "integer":
|
||||||
|
return "z.number()";
|
||||||
|
case "bigint":
|
||||||
|
return "z.coerce.number()";
|
||||||
|
case "text":
|
||||||
|
return "z.string()";
|
||||||
|
default:
|
||||||
|
throw new Error(`Invalid type: ${type}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getZodDefaultValue = (type: unknown, value: string | number | boolean | Object) => {
|
||||||
|
if (!value || value === "null") return;
|
||||||
|
switch (type) {
|
||||||
|
case "uuid":
|
||||||
|
return;
|
||||||
|
case "character varying": {
|
||||||
|
if (value === "gen_random_uuid()") return;
|
||||||
|
if (typeof value === "string" && value.includes("::")) {
|
||||||
|
return `.default(${value.split("::")[0]})`;
|
||||||
|
}
|
||||||
|
return `.default(${value})`;
|
||||||
|
}
|
||||||
|
case "ARRAY":
|
||||||
|
return `.default(${value})`;
|
||||||
|
case "boolean":
|
||||||
|
return `.default(${value})`;
|
||||||
|
case "jsonb":
|
||||||
|
return "z.string()";
|
||||||
|
case "json":
|
||||||
|
return "z.string()";
|
||||||
|
case "timestamp with time zone": {
|
||||||
|
if (value === "CURRENT_TIMESTAMP") return;
|
||||||
|
return "z.string().datetime()";
|
||||||
|
}
|
||||||
|
case "integer": {
|
||||||
|
if ((value as string).includes("nextval")) return;
|
||||||
|
return `.default(${value})`;
|
||||||
|
}
|
||||||
|
case "bigint": {
|
||||||
|
if ((value as string).includes("nextval")) return;
|
||||||
|
return `.default(${parseInt((value as string).split("::")[0].slice(1, -1), 10)})`;
|
||||||
|
}
|
||||||
|
case "text":
|
||||||
|
if (typeof value === "string" && value.includes("::")) {
|
||||||
|
return `.default(${value.split("::")[0]})`;
|
||||||
|
}
|
||||||
|
return `.default(${value})`;
|
||||||
|
default:
|
||||||
|
throw new Error(`Invalid type: ${type}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
const tables = (
|
||||||
|
await db("information_schema.tables")
|
||||||
|
.whereRaw("table_schema = current_schema()")
|
||||||
|
.select<{ tableName: string }[]>("table_name as tableName")
|
||||||
|
.orderBy("table_name")
|
||||||
|
).filter((el) => !el.tableName.includes("_migrations"));
|
||||||
|
|
||||||
|
console.log("Select a table to generate schema");
|
||||||
|
console.table(tables);
|
||||||
|
console.log("all: all tables");
|
||||||
|
const selectedTables = prompt("Type table numbers comma seperated: ");
|
||||||
|
const tableNumbers =
|
||||||
|
selectedTables !== "all" ? selectedTables.split(",").map((el) => Number(el)) : [];
|
||||||
|
|
||||||
|
for (let i = 0; i < tables.length; i += 1) {
|
||||||
|
// skip if not desired table
|
||||||
|
if (selectedTables !== "all" && !tableNumbers.includes(i)) continue;
|
||||||
|
|
||||||
|
const { tableName } = tables[i];
|
||||||
|
const columns = await db(tableName).columnInfo();
|
||||||
|
const columnNames = Object.keys(columns);
|
||||||
|
|
||||||
|
let schema = "";
|
||||||
|
for (let colNum = 0; colNum < columnNames.length; colNum++) {
|
||||||
|
const columnName = columnNames[colNum];
|
||||||
|
const colInfo = columns[columnName];
|
||||||
|
let ztype = getZodPrimitiveType(colInfo.type);
|
||||||
|
if (colInfo.defaultValue) {
|
||||||
|
const { defaultValue } = colInfo;
|
||||||
|
const zSchema = getZodDefaultValue(colInfo.type, defaultValue);
|
||||||
|
if (zSchema) {
|
||||||
|
ztype = ztype.concat(zSchema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (colInfo.nullable) {
|
||||||
|
ztype = ztype.concat(".nullable().optional()");
|
||||||
|
}
|
||||||
|
schema = schema.concat(`${!schema ? "\n" : ""} ${columnName}: ${ztype},\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dashcase = tableName.split("_").join("-");
|
||||||
|
const pascalCase = tableName
|
||||||
|
.split("_")
|
||||||
|
.reduce(
|
||||||
|
(prev, curr) => prev + `${curr.at(0)?.toUpperCase()}${curr.slice(1).toLowerCase()}`,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
writeFileSync(
|
||||||
|
path.join(__dirname, "../src/db/schemas", `${dashcase}.ts`),
|
||||||
|
`// 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 ${pascalCase}Schema = z.object({${schema}});
|
||||||
|
|
||||||
|
export type T${pascalCase} = z.infer<typeof ${pascalCase}Schema>;
|
||||||
|
export type T${pascalCase}Insert = Omit<T${pascalCase}, TImmutableDBKeys>;
|
||||||
|
export type T${pascalCase}Update = Partial<Omit<T${pascalCase}, TImmutableDBKeys>>;
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
// const file = readFileSync(path.join(__dirname, "../src/db/schemas/index.ts"), "utf8");
|
||||||
|
// if (!file.includes(`export * from "./${dashcase};"`)) {
|
||||||
|
// appendFileSync(
|
||||||
|
// path.join(__dirname, "../src/db/schemas/index.ts"),
|
||||||
|
// `\nexport * from "./${dashcase}";`,
|
||||||
|
// "utf8"
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
process.exit(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
main();
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
import {
|
||||||
|
FastifyInstance,
|
||||||
|
RawReplyDefaultExpression,
|
||||||
|
RawRequestDefaultExpression,
|
||||||
|
RawServerDefault
|
||||||
|
} from "fastify";
|
||||||
|
import { Logger } from "pino";
|
||||||
|
|
||||||
|
import { ZodTypeProvider } from "@app/server/plugins/fastify-zod";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
type FastifyZodProvider = FastifyInstance<
|
||||||
|
RawServerDefault,
|
||||||
|
RawRequestDefaultExpression<RawServerDefault>,
|
||||||
|
RawReplyDefaultExpression<RawServerDefault>,
|
||||||
|
Readonly<Logger>,
|
||||||
|
ZodTypeProvider
|
||||||
|
>;
|
||||||
|
|
||||||
|
// used only for testing
|
||||||
|
const testServer: FastifyZodProvider;
|
||||||
|
const jwtAuthToken: string;
|
||||||
|
}
|
||||||
Vendored
+119
@@ -0,0 +1,119 @@
|
|||||||
|
import "fastify";
|
||||||
|
|
||||||
|
import { TUsers } from "@app/db/schemas";
|
||||||
|
import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service";
|
||||||
|
import { TCreateAuditLogDTO } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||||
|
import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service";
|
||||||
|
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
|
||||||
|
import { TSecretApprovalRequestServiceFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-service";
|
||||||
|
import { TSecretRotationServiceFactory } from "@app/ee/services/secret-rotation/secret-rotation-service";
|
||||||
|
import { TSecretScanningServiceFactory } from "@app/ee/services/secret-scanning/secret-scanning-service";
|
||||||
|
import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service";
|
||||||
|
import { TTrustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-service";
|
||||||
|
import { TAuthMode } from "@app/server/plugins/auth/inject-identity";
|
||||||
|
import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service";
|
||||||
|
import { TAuthLoginFactory } from "@app/services/auth/auth-login-service";
|
||||||
|
import { TAuthPasswordFactory } from "@app/services/auth/auth-password-service";
|
||||||
|
import { TAuthSignupFactory } from "@app/services/auth/auth-signup-service";
|
||||||
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
|
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
|
||||||
|
import { TIdentityServiceFactory } from "@app/services/identity/identity-service";
|
||||||
|
import { TIdentityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service";
|
||||||
|
import { TIdentityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
|
||||||
|
import { TIdentityUaServiceFactory } from "@app/services/identity-ua/identity-ua-service";
|
||||||
|
import { TIntegrationServiceFactory } from "@app/services/integration/integration-service";
|
||||||
|
import { TIntegrationAuthServiceFactory } from "@app/services/integration-auth/integration-auth-service";
|
||||||
|
import { TOrgRoleServiceFactory } from "@app/services/org/org-role-service";
|
||||||
|
import { TOrgServiceFactory } from "@app/services/org/org-service";
|
||||||
|
import { TProjectServiceFactory } from "@app/services/project/project-service";
|
||||||
|
import { TProjectBotServiceFactory } from "@app/services/project-bot/project-bot-service";
|
||||||
|
import { TProjectEnvServiceFactory } from "@app/services/project-env/project-env-service";
|
||||||
|
import { TProjectKeyServiceFactory } from "@app/services/project-key/project-key-service";
|
||||||
|
import { TProjectMembershipServiceFactory } from "@app/services/project-membership/project-membership-service";
|
||||||
|
import { TProjectRoleServiceFactory } from "@app/services/project-role/project-role-service";
|
||||||
|
import { TSecretServiceFactory } from "@app/services/secret/secret-service";
|
||||||
|
import { TSecretBlindIndexServiceFactory } from "@app/services/secret-blind-index/secret-blind-index-service";
|
||||||
|
import { TSecretFolderServiceFactory } from "@app/services/secret-folder/secret-folder-service";
|
||||||
|
import { TSecretImportServiceFactory } from "@app/services/secret-import/secret-import-service";
|
||||||
|
import { TSecretTagServiceFactory } from "@app/services/secret-tag/secret-tag-service";
|
||||||
|
import { TServiceTokenServiceFactory } from "@app/services/service-token/service-token-service";
|
||||||
|
import { TSuperAdminServiceFactory } from "@app/services/super-admin/super-admin-service";
|
||||||
|
import { TTelemetryServiceFactory } from "@app/services/telemetry/telemetry-service";
|
||||||
|
import { TUserDALFactory } from "@app/services/user/user-dal";
|
||||||
|
import { TUserServiceFactory } from "@app/services/user/user-service";
|
||||||
|
import { TWebhookServiceFactory } from "@app/services/webhook/webhook-service";
|
||||||
|
|
||||||
|
declare module "fastify" {
|
||||||
|
interface FastifyRequest {
|
||||||
|
realIp: string;
|
||||||
|
// used for mfa session authentication
|
||||||
|
mfa: {
|
||||||
|
userId: string;
|
||||||
|
user: TUsers;
|
||||||
|
};
|
||||||
|
// identity injection. depending on which kinda of token the information is filled in auth
|
||||||
|
auth: TAuthMode;
|
||||||
|
permission: {
|
||||||
|
type: ActorType;
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
// passport data
|
||||||
|
passportUser: {
|
||||||
|
isUserCompleted: string;
|
||||||
|
providerAuthToken: string;
|
||||||
|
};
|
||||||
|
auditLogInfo: Pick<TCreateAuditLogDTO, "userAgent" | "userAgentType" | "ipAddress" | "actor">;
|
||||||
|
ssoConfig: Awaited<ReturnType<TSamlConfigServiceFactory["getSaml"]>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FastifyInstance {
|
||||||
|
services: {
|
||||||
|
login: TAuthLoginFactory;
|
||||||
|
password: TAuthPasswordFactory;
|
||||||
|
signup: TAuthSignupFactory;
|
||||||
|
authToken: TAuthTokenServiceFactory;
|
||||||
|
permission: TPermissionServiceFactory;
|
||||||
|
org: TOrgServiceFactory;
|
||||||
|
orgRole: TOrgRoleServiceFactory;
|
||||||
|
superAdmin: TSuperAdminServiceFactory;
|
||||||
|
user: TUserServiceFactory;
|
||||||
|
apiKey: TApiKeyServiceFactory;
|
||||||
|
project: TProjectServiceFactory;
|
||||||
|
projectMembership: TProjectMembershipServiceFactory;
|
||||||
|
projectEnv: TProjectEnvServiceFactory;
|
||||||
|
projectKey: TProjectKeyServiceFactory;
|
||||||
|
projectRole: TProjectRoleServiceFactory;
|
||||||
|
secret: TSecretServiceFactory;
|
||||||
|
secretTag: TSecretTagServiceFactory;
|
||||||
|
secretImport: TSecretImportServiceFactory;
|
||||||
|
projectBot: TProjectBotServiceFactory;
|
||||||
|
folder: TSecretFolderServiceFactory;
|
||||||
|
integration: TIntegrationServiceFactory;
|
||||||
|
integrationAuth: TIntegrationAuthServiceFactory;
|
||||||
|
webhook: TWebhookServiceFactory;
|
||||||
|
serviceToken: TServiceTokenServiceFactory;
|
||||||
|
identity: TIdentityServiceFactory;
|
||||||
|
identityAccessToken: TIdentityAccessTokenServiceFactory;
|
||||||
|
identityProject: TIdentityProjectServiceFactory;
|
||||||
|
identityUa: TIdentityUaServiceFactory;
|
||||||
|
secretApprovalPolicy: TSecretApprovalPolicyServiceFactory;
|
||||||
|
secretApprovalRequest: TSecretApprovalRequestServiceFactory;
|
||||||
|
secretRotation: TSecretRotationServiceFactory;
|
||||||
|
snapshot: TSecretSnapshotServiceFactory;
|
||||||
|
saml: TSamlConfigServiceFactory;
|
||||||
|
auditLog: TAuditLogServiceFactory;
|
||||||
|
secretScanning: TSecretScanningServiceFactory;
|
||||||
|
license: TLicenseServiceFactory;
|
||||||
|
trustedIp: TTrustedIpServiceFactory;
|
||||||
|
secretBlindIndex: TSecretBlindIndexServiceFactory;
|
||||||
|
telemetry: TTelemetryServiceFactory;
|
||||||
|
};
|
||||||
|
// this is exclusive use for middlewares in which we need to inject data
|
||||||
|
// everywhere else access using service layer
|
||||||
|
store: {
|
||||||
|
user: Pick<TUserDALFactory, "findById">;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+415
@@ -0,0 +1,415 @@
|
|||||||
|
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 "@app/db/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
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
declare module "passport-gitlab2";
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
import Redis from "ioredis";
|
||||||
|
|
||||||
|
export const initRedisConnection = (redisUrl: string) => {
|
||||||
|
const redis = new Redis(redisUrl);
|
||||||
|
return redis;
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export type { TDbClient } from "./instance";
|
||||||
|
export { initDbConnection } from "./instance";
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import knex from "knex";
|
||||||
|
|
||||||
|
export type TDbClient = ReturnType<typeof initDbConnection>;
|
||||||
|
export const initDbConnection = (dbConnectionUri: string) => {
|
||||||
|
const db = knex({
|
||||||
|
client: "pg",
|
||||||
|
connection: dbConnectionUri
|
||||||
|
});
|
||||||
|
|
||||||
|
return db;
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// eslint-disable-next-line
|
||||||
|
import "ts-node/register";
|
||||||
|
|
||||||
|
import dotenv from "dotenv";
|
||||||
|
import type { Knex } from "knex";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
// Update with your config settings.
|
||||||
|
dotenv.config({
|
||||||
|
path: path.join(__dirname, "../../.env"),
|
||||||
|
debug: true
|
||||||
|
});
|
||||||
|
export default {
|
||||||
|
development: {
|
||||||
|
client: "postgres",
|
||||||
|
connection: process.env.DB_CONNECTION_URI,
|
||||||
|
pool: {
|
||||||
|
min: 2,
|
||||||
|
max: 10
|
||||||
|
},
|
||||||
|
seeds: {
|
||||||
|
directory: "./seeds"
|
||||||
|
},
|
||||||
|
migrations: {
|
||||||
|
tableName: "infisical_migrations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
production: {
|
||||||
|
client: "postgres",
|
||||||
|
connection: process.env.DB_CONNECTION_URI,
|
||||||
|
pool: {
|
||||||
|
min: 2,
|
||||||
|
max: 10
|
||||||
|
},
|
||||||
|
migrations: {
|
||||||
|
tableName: "infisical_migrations"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as Knex.Config;
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import {
|
||||||
|
createOnUpdateTrigger,
|
||||||
|
createUpdateAtTriggerFunction,
|
||||||
|
dropOnUpdateTrigger,
|
||||||
|
dropUpdatedAtTriggerFunction
|
||||||
|
} from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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").unique().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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.Users);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.Users);
|
||||||
|
await dropUpdatedAtTriggerFunction(knex);
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.UserEncryptionKey);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.AuthTokens);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.AuthTokenSession);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.AuthTokenSession);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.BackupPrivateKey);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
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<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.OrgMembership);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.OrgRoles);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.OrgMembership);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IncidentContact);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IncidentContact);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.UserAction);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SuperAdmin);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SuperAdmin);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
const isTablePresent = await knex.schema.hasTable(TableName.ApiKey);
|
||||||
|
if (!isTablePresent) {
|
||||||
|
await knex.schema.createTable(TableName.ApiKey, (t) => {
|
||||||
|
t.string("id", 36).primary().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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.ApiKey);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.ApiKey);
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.ProjectMembership);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.ProjectRoles);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.ProjectMembership);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretFolderVersion);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretFolder);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretFolder);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretFolderVersion);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretImport);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretImport);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretTag);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretTag);
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { SecretEncryptionAlgo, SecretKeyEncoding, SecretType, TableName } from "../schemas";
|
||||||
|
import { createJunctionTable, createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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");
|
||||||
|
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.index("secretBlindIndex");
|
||||||
|
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<void> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { SecretEncryptionAlgo, SecretKeyEncoding, SecretType, TableName } from "../schemas";
|
||||||
|
import { createJunctionTable, createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretVersionTag);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretVersion);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretVersion);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.ProjectBot);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.ProjectBot);
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.Integration);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IntegrationAuth);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IntegrationAuth);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.Integration);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.ServiceToken);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.ServiceToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.Webhook);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.Webhook);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.Identity);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.Identity);
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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.bigInteger("accessTokenTTL").defaultTo(7200).notNullable();
|
||||||
|
t.bigInteger("accessTokenMaxTTL").defaultTo(7200).notNullable();
|
||||||
|
t.bigInteger("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.string("id", 36).primary().defaultTo(knex.fn.uuid());
|
||||||
|
t.string("description").notNullable();
|
||||||
|
t.string("clientSecretPrefix").notNullable();
|
||||||
|
t.string("clientSecretHash").notNullable();
|
||||||
|
t.datetime("clientSecretLastUsedAt");
|
||||||
|
t.bigInteger("clientSecretNumUses").defaultTo(0).notNullable();
|
||||||
|
t.bigInteger("clientSecretNumUsesLimit").defaultTo(0).notNullable();
|
||||||
|
t.bigInteger("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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IdentityUaClientSecret);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IdentityUniversalAuth);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IdentityUaClientSecret);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IdentityUniversalAuth);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
if (!(await knex.schema.hasTable(TableName.IdentityAccessToken))) {
|
||||||
|
await knex.schema.createTable(TableName.IdentityAccessToken, (t) => {
|
||||||
|
t.string("id", 36).primary().defaultTo(knex.fn.uuid());
|
||||||
|
t.bigInteger("accessTokenTTL").defaultTo(2592000).notNullable(); // 30 days second
|
||||||
|
t.bigInteger("accessTokenMaxTTL").defaultTo(2592000).notNullable();
|
||||||
|
t.bigInteger("accessTokenNumUses").defaultTo(0).notNullable();
|
||||||
|
t.bigInteger("accessTokenNumUsesLimit").defaultTo(0).notNullable();
|
||||||
|
t.datetime("accessTokenLastUsedAt");
|
||||||
|
t.datetime("accessTokenLastRenewedAt");
|
||||||
|
t.boolean("isAccessTokenRevoked").defaultTo(false).notNullable();
|
||||||
|
t.string("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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IdentityAccessToken);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IdentityAccessToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IdentityOrgMembership);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IdentityProjectMembership);
|
||||||
|
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IdentityProjectMembership);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IdentityOrgMembership);
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretApprovalPolicyApprover);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretApprovalPolicy);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretApprovalPolicyApprover);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretApprovalPolicy);
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { SecretEncryptionAlgo, SecretKeyEncoding, TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretRotationOutput);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SecretRotation);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SecretRotation);
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SnapshotSecret);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SnapshotFolder);
|
||||||
|
await knex.schema.dropTableIfExists(TableName.Snapshot);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.Snapshot);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.SamlConfig);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.SamlConfig);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.OrgBot);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.OrgBot);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.AuditLog);
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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<void> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
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).onDelete("CASCADE");
|
||||||
|
t.timestamps(true, true, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await createOnUpdateTrigger(knex, TableName.TrustedIps);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex: Knex): Promise<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.TrustedIps);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.TrustedIps);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// 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<typeof ApiKeysSchema>;
|
||||||
|
export type TApiKeysInsert = Omit<TApiKeys, TImmutableDBKeys>;
|
||||||
|
export type TApiKeysUpdate = Partial<Omit<TApiKeys, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// 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<typeof AuditLogsSchema>;
|
||||||
|
export type TAuditLogsInsert = Omit<TAuditLogs, TImmutableDBKeys>;
|
||||||
|
export type TAuditLogsUpdate = Partial<Omit<TAuditLogs, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// 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<typeof AuthTokenSessionsSchema>;
|
||||||
|
export type TAuthTokenSessionsInsert = Omit<TAuthTokenSessions, TImmutableDBKeys>;
|
||||||
|
export type TAuthTokenSessionsUpdate = Partial<Omit<TAuthTokenSessions, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// 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<typeof AuthTokensSchema>;
|
||||||
|
export type TAuthTokensInsert = Omit<TAuthTokens, TImmutableDBKeys>;
|
||||||
|
export type TAuthTokensUpdate = Partial<Omit<TAuthTokens, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// 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<typeof BackupPrivateKeySchema>;
|
||||||
|
export type TBackupPrivateKeyInsert = Omit<TBackupPrivateKey, TImmutableDBKeys>;
|
||||||
|
export type TBackupPrivateKeyUpdate = Partial<Omit<TBackupPrivateKey, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// 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<typeof GitAppInstallSessionsSchema>;
|
||||||
|
export type TGitAppInstallSessionsInsert = Omit<TGitAppInstallSessions, TImmutableDBKeys>;
|
||||||
|
export type TGitAppInstallSessionsUpdate = Partial<Omit<TGitAppInstallSessions, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// 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<typeof GitAppOrgSchema>;
|
||||||
|
export type TGitAppOrgInsert = Omit<TGitAppOrg, TImmutableDBKeys>;
|
||||||
|
export type TGitAppOrgUpdate = Partial<Omit<TGitAppOrg, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// 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<typeof IdentitiesSchema>;
|
||||||
|
export type TIdentitiesInsert = Omit<TIdentities, TImmutableDBKeys>;
|
||||||
|
export type TIdentitiesUpdate = Partial<Omit<TIdentities, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// 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.coerce.number().default(2592000),
|
||||||
|
accessTokenMaxTTL: z.coerce.number().default(2592000),
|
||||||
|
accessTokenNumUses: z.coerce.number().default(0),
|
||||||
|
accessTokenNumUsesLimit: z.coerce.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<typeof IdentityAccessTokensSchema>;
|
||||||
|
export type TIdentityAccessTokensInsert = Omit<TIdentityAccessTokens, TImmutableDBKeys>;
|
||||||
|
export type TIdentityAccessTokensUpdate = Partial<Omit<TIdentityAccessTokens, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// 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<typeof IdentityOrgMembershipsSchema>;
|
||||||
|
export type TIdentityOrgMembershipsInsert = Omit<TIdentityOrgMemberships, TImmutableDBKeys>;
|
||||||
|
export type TIdentityOrgMembershipsUpdate = Partial<Omit<TIdentityOrgMemberships, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// 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<typeof IdentityProjectMembershipsSchema>;
|
||||||
|
export type TIdentityProjectMembershipsInsert = Omit<TIdentityProjectMemberships, TImmutableDBKeys>;
|
||||||
|
export type TIdentityProjectMembershipsUpdate = Partial<Omit<TIdentityProjectMemberships, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// 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.coerce.number().default(0),
|
||||||
|
clientSecretNumUsesLimit: z.coerce.number().default(0),
|
||||||
|
clientSecretTTL: z.coerce.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<TIdentityUaClientSecrets, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// 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.coerce.number().default(7200),
|
||||||
|
accessTokenMaxTTL: z.coerce.number().default(7200),
|
||||||
|
accessTokenNumUsesLimit: z.coerce.number().default(0),
|
||||||
|
clientSecretTrustedIps: z.unknown(),
|
||||||
|
accessTokenTrustedIps: z.unknown(),
|
||||||
|
createdAt: z.date(),
|
||||||
|
updatedAt: z.date(),
|
||||||
|
identityId: z.string().uuid(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TIdentityUniversalAuths = z.infer<typeof IdentityUniversalAuthsSchema>;
|
||||||
|
export type TIdentityUniversalAuthsInsert = Omit<TIdentityUniversalAuths, TImmutableDBKeys>;
|
||||||
|
export type TIdentityUniversalAuthsUpdate = Partial<Omit<TIdentityUniversalAuths, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// 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<typeof IncidentContactsSchema>;
|
||||||
|
export type TIncidentContactsInsert = Omit<TIncidentContacts, TImmutableDBKeys>;
|
||||||
|
export type TIncidentContactsUpdate = Partial<Omit<TIncidentContacts, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
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 "./saml-configs";
|
||||||
|
export * from "./secret-approval-policies";
|
||||||
|
export * from "./secret-approval-policies-approvers";
|
||||||
|
export * from "./secret-approval-request-secret-tags";
|
||||||
|
export * from "./secret-approval-requests";
|
||||||
|
export * from "./secret-approval-requests-reviewers";
|
||||||
|
export * from "./secret-approval-requests-secrets";
|
||||||
|
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-version-tag-junction";
|
||||||
|
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";
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// 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<typeof IntegrationAuthsSchema>;
|
||||||
|
export type TIntegrationAuthsInsert = Omit<TIntegrationAuths, TImmutableDBKeys>;
|
||||||
|
export type TIntegrationAuthsUpdate = Partial<Omit<TIntegrationAuths, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// 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<typeof IntegrationsSchema>;
|
||||||
|
export type TIntegrationsInsert = Omit<TIntegrations, TImmutableDBKeys>;
|
||||||
|
export type TIntegrationsUpdate = Partial<Omit<TIntegrations, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
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-auth"
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// 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<typeof OrgBotsSchema>;
|
||||||
|
export type TOrgBotsInsert = Omit<TOrgBots, TImmutableDBKeys>;
|
||||||
|
export type TOrgBotsUpdate = Partial<Omit<TOrgBots, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// 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<typeof OrgMembershipsSchema>;
|
||||||
|
export type TOrgMembershipsInsert = Omit<TOrgMemberships, TImmutableDBKeys>;
|
||||||
|
export type TOrgMembershipsUpdate = Partial<Omit<TOrgMemberships, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// 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<typeof OrgRolesSchema>;
|
||||||
|
export type TOrgRolesInsert = Omit<TOrgRoles, TImmutableDBKeys>;
|
||||||
|
export type TOrgRolesUpdate = Partial<Omit<TOrgRoles, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// 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(),
|
||||||
|
customerId: z.string().nullable().optional(),
|
||||||
|
slug: z.string(),
|
||||||
|
createdAt: z.date(),
|
||||||
|
updatedAt: z.date()
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TOrganizations = z.infer<typeof OrganizationsSchema>;
|
||||||
|
export type TOrganizationsInsert = Omit<TOrganizations, TImmutableDBKeys>;
|
||||||
|
export type TOrganizationsUpdate = Partial<Omit<TOrganizations, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// 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<typeof ProjectBotsSchema>;
|
||||||
|
export type TProjectBotsInsert = Omit<TProjectBots, TImmutableDBKeys>;
|
||||||
|
export type TProjectBotsUpdate = Partial<Omit<TProjectBots, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// 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<typeof ProjectEnvironmentsSchema>;
|
||||||
|
export type TProjectEnvironmentsInsert = Omit<TProjectEnvironments, TImmutableDBKeys>;
|
||||||
|
export type TProjectEnvironmentsUpdate = Partial<Omit<TProjectEnvironments, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// 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<typeof ProjectKeysSchema>;
|
||||||
|
export type TProjectKeysInsert = Omit<TProjectKeys, TImmutableDBKeys>;
|
||||||
|
export type TProjectKeysUpdate = Partial<Omit<TProjectKeys, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// 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<typeof ProjectMembershipsSchema>;
|
||||||
|
export type TProjectMembershipsInsert = Omit<TProjectMemberships, TImmutableDBKeys>;
|
||||||
|
export type TProjectMembershipsUpdate = Partial<Omit<TProjectMemberships, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// 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<typeof ProjectRolesSchema>;
|
||||||
|
export type TProjectRolesInsert = Omit<TProjectRoles, TImmutableDBKeys>;
|
||||||
|
export type TProjectRolesUpdate = Partial<Omit<TProjectRoles, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// 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<typeof ProjectsSchema>;
|
||||||
|
export type TProjectsInsert = Omit<TProjects, TImmutableDBKeys>;
|
||||||
|
export type TProjectsUpdate = Partial<Omit<TProjects, TImmutableDBKeys>>;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// 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<typeof SamlConfigsSchema>;
|
||||||
|
export type TSamlConfigsInsert = Omit<TSamlConfigs, TImmutableDBKeys>;
|
||||||
|
export type TSamlConfigsUpdate = Partial<Omit<TSamlConfigs, TImmutableDBKeys>>;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user