mirror of
https://github.com/Infisical/infisical.git
synced 2025-07-28 02:53:22 +00:00
Compare commits
134 Commits
infisical/
...
daniel/fix
Author | SHA1 | Date | |
---|---|---|---|
|
eaccb3ddbc | ||
|
ad482fb24e | ||
|
94cf3c5ae2 | ||
|
9b781d3af8 | ||
|
f38d64cc90 | ||
|
6c738f7ad1 | ||
|
afb818e41a | ||
|
c0d679dbd4 | ||
|
7046542ace | ||
|
cdf90bf9a5 | ||
|
ecfb3ec95b | ||
|
5c58a4d1a3 | ||
|
03a91b2c59 | ||
|
751361bd54 | ||
|
b4b88daf36 | ||
|
6546740bd9 | ||
|
b32558c66f | ||
|
effd30857e | ||
|
60998c8944 | ||
|
3c4d9fd4a9 | ||
|
ad70c783e8 | ||
|
7347362738 | ||
|
4b7f2e808b | ||
|
57f9d13189 | ||
|
bd2e8ac922 | ||
|
79694750af | ||
|
03db367a4e | ||
|
b0fb848a92 | ||
|
4fdfcd50dc | ||
|
e707f0d235 | ||
|
27f4225c44 | ||
|
28a9d8e739 | ||
|
a1321e4749 | ||
|
d4db01bbde | ||
|
39634b8aae | ||
|
4815ff13ee | ||
|
fb503756d9 | ||
|
069b0cd6fb | ||
|
ed23bd40d2 | ||
|
82181f078a | ||
|
48a97fb39d | ||
|
eeaee4409c | ||
|
a9a5e92358 | ||
|
8d457bb0bf | ||
|
5878a221f8 | ||
|
fdbf59cd78 | ||
|
2cc2a91812 | ||
|
92828b5295 | ||
|
50c0fae557 | ||
|
4e2f2281f9 | ||
|
70e083bae0 | ||
|
6a943e275a | ||
|
526dc6141b | ||
|
dcab9dcdda | ||
|
1b0591def8 | ||
|
4b4305bddc | ||
|
22d89d791c | ||
|
fcaff76afa | ||
|
ae9eb20189 | ||
|
3905d16a7c | ||
|
ecafdb0d01 | ||
|
3f8ce42682 | ||
|
3ecfb3f9d2 | ||
|
9011394c34 | ||
|
c0096ca64c | ||
|
8bc952388c | ||
|
eef29cd2d4 | ||
|
6ef873f3a0 | ||
|
fe99c12c0d | ||
|
8313245ae1 | ||
|
332b0e2cc3 | ||
|
8bc9a5fed6 | ||
|
55e75bbbef | ||
|
61ff732ec0 | ||
|
609b224ca9 | ||
|
c23e16105b | ||
|
c10f4ece51 | ||
|
fc7015de83 | ||
|
bcdb1b11bc | ||
|
01d850f7e8 | ||
|
2d1b60a520 | ||
|
8de2302d98 | ||
|
0529b50ad7 | ||
|
c74fe0ca73 | ||
|
d5f8526a84 | ||
|
c1aa5c840c | ||
|
782ae7a41d | ||
|
d355956daf | ||
|
dc146d0883 | ||
|
24dd79b566 | ||
|
410476ecb5 | ||
|
f1c41be7d4 | ||
|
f138973ac7 | ||
|
5b9c0438a2 | ||
|
11399d73dc | ||
|
38ed39c2f8 | ||
|
4e3827780f | ||
|
644cdf5a67 | ||
|
0d6ea0d69e | ||
|
237979a1c6 | ||
|
4a566cf83f | ||
|
654b8ab5ca | ||
|
ac0780266b | ||
|
7a253ddcc7 | ||
|
b65677a708 | ||
|
c1eb97ee53 | ||
|
937e48dbc5 | ||
|
b3d4787e21 | ||
|
72d46efba5 | ||
|
b6eb08167f | ||
|
582472e4cc | ||
|
3b3b76548b | ||
|
f8416ad891 | ||
|
31e49672d5 | ||
|
9248bdf463 | ||
|
87c061ae9b | ||
|
e9fa631c8f | ||
|
44f087991c | ||
|
cff15b64c4 | ||
|
136f5a6052 | ||
|
59f662f8a8 | ||
|
b68b3840d4 | ||
|
06dd55888e | ||
|
7711994018 | ||
|
cb27cfdd84 | ||
|
4b3e4f6a1e | ||
|
560f8d4a9b | ||
|
7e8f9ec9e4 | ||
|
7bf1f4708a | ||
|
bcbb49ed1b | ||
|
5855cc660a | ||
|
6fe3a8bd67 | ||
|
6c6fae3793 | ||
|
202efce10d |
1
.env.migration.example
Normal file
1
.env.migration.example
Normal file
@@ -0,0 +1 @@
|
||||
DB_CONNECTION_URI=
|
6
.github/pull_request_template.md
vendored
6
.github/pull_request_template.md
vendored
@@ -1,6 +1,6 @@
|
||||
# Description 📣
|
||||
|
||||
<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->
|
||||
<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. Here's how we expect a pull request to be : https://infisical.com/docs/contributing/getting-started/pull-requests -->
|
||||
|
||||
## Type ✨
|
||||
|
||||
@@ -19,4 +19,6 @@
|
||||
|
||||
---
|
||||
|
||||
- [ ] I have read the [contributing guide](https://infisical.com/docs/contributing/overview), agreed and acknowledged the [code of conduct](https://infisical.com/docs/contributing/code-of-conduct). 📝
|
||||
- [ ] I have read the [contributing guide](https://infisical.com/docs/contributing/getting-started/overview), agreed and acknowledged the [code of conduct](https://infisical.com/docs/contributing/getting-started/code-of-conduct). 📝
|
||||
|
||||
<!-- If you have any questions regarding contribution, here's the FAQ : https://infisical.com/docs/contributing/getting-started/faq -->
|
8
.github/values.yaml
vendored
8
.github/values.yaml
vendored
@@ -19,11 +19,11 @@ infisical:
|
||||
## @param backend.name Backend name
|
||||
##
|
||||
name: infisical
|
||||
replicaCount: 2
|
||||
replicaCount: 3
|
||||
image:
|
||||
repository: infisical/infisical
|
||||
tag: "latest-postgres"
|
||||
pullPolicy: IfNotPresent
|
||||
repository: infisical/staging_infisical
|
||||
tag: "latest"
|
||||
pullPolicy: Always
|
||||
|
||||
deploymentAnnotations:
|
||||
secrets.infisical.com/auto-reload: "true"
|
||||
|
55
.github/workflows/check-api-for-breaking-changes.yml
vendored
Normal file
55
.github/workflows/check-api-for-breaking-changes.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
name: "Check API For Breaking Changes"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- "backend/src/server/routes/**"
|
||||
|
||||
jobs:
|
||||
check-be-api-changes:
|
||||
name: Check API Changes
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v3
|
||||
# - name: Setup Node 20
|
||||
# uses: actions/setup-node@v3
|
||||
# with:
|
||||
# node-version: "20"
|
||||
# uncomment this when testing locally using nektos/act
|
||||
- uses: KengoTODA/actions-setup-docker-compose@v1
|
||||
if: ${{ env.ACT }}
|
||||
name: Install `docker-compose` for local simulations
|
||||
with:
|
||||
version: "2.14.2"
|
||||
- name: 📦Build the latest image
|
||||
run: docker build --tag infisical-api .
|
||||
working-directory: backend
|
||||
- name: Start postgres and redis
|
||||
run: touch .env && docker-compose -f docker-compose.pg.yml up -d db redis
|
||||
- name: Start the server
|
||||
run: |
|
||||
echo "SECRET_SCANNING_GIT_APP_ID=793712" >> .env
|
||||
echo "SECRET_SCANNING_PRIVATE_KEY=some-random" >> .env
|
||||
echo "SECRET_SCANNING_WEBHOOK_SECRET=some-random" >> .env
|
||||
docker run --name infisical-api -d -p 4000:4000 -e DB_CONNECTION_URI=$DB_CONNECTION_URI -e REDIS_URL=$REDIS_URL -e JWT_AUTH_SECRET=$JWT_AUTH_SECRET --env-file .env --entrypoint '/bin/sh' infisical-api -c "npm run migration:latest && ls && node dist/main.mjs"
|
||||
env:
|
||||
REDIS_URL: redis://172.17.0.1:6379
|
||||
DB_CONNECTION_URI: postgres://infisical:infisical@172.17.0.1:5432/infisical?sslmode=disable
|
||||
JWT_AUTH_SECRET: something-random
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.21.5'
|
||||
- name: Wait for containers to be stable
|
||||
run: timeout 60s sh -c 'until docker ps | grep infisical-api | grep -q healthy; do echo "Waiting for container to be healthy..."; sleep 2; done'
|
||||
- name: Install openapi-diff
|
||||
run: go install github.com/tufin/oasdiff@latest
|
||||
- name: Running OpenAPI Spec diff action
|
||||
run: oasdiff breaking https://app.infisical.com/api/docs/json http://localhost:4000/api/docs/json --fail-on ERR
|
||||
- name: cleanup
|
||||
run: |
|
||||
docker-compose -f "docker-compose.pg.yml" down
|
||||
docker stop infisical-api
|
||||
docker remove infisical-api
|
43
.github/workflows/check-be-pull-request.yml
vendored
43
.github/workflows/check-be-pull-request.yml
vendored
@@ -1,43 +0,0 @@
|
||||
name: "Check Backend Pull Request"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- "backend/**"
|
||||
- "!backend/README.md"
|
||||
- "!backend/.*"
|
||||
- "backend/.eslintrc.js"
|
||||
|
||||
jobs:
|
||||
check-be-pr:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: ☁️ Checkout source
|
||||
uses: actions/checkout@v3
|
||||
- name: 🔧 Setup Node 16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
cache: "npm"
|
||||
cache-dependency-path: backend/package-lock.json
|
||||
- name: 📦 Install dependencies
|
||||
run: npm ci --only-production
|
||||
working-directory: backend
|
||||
# - name: 🧪 Run tests
|
||||
# run: npm run test:ci
|
||||
# working-directory: backend
|
||||
# - name: 📁 Upload test results
|
||||
# uses: actions/upload-artifact@v3
|
||||
# if: always()
|
||||
# with:
|
||||
# name: be-test-results
|
||||
# path: |
|
||||
# ./backend/reports
|
||||
# ./backend/coverage
|
||||
- name: 🏗️ Run build
|
||||
run: npm run build
|
||||
working-directory: backend
|
35
.github/workflows/check-be-ts-and-lint.yml
vendored
Normal file
35
.github/workflows/check-be-ts-and-lint.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: "Check Backend PR types and lint"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- "backend/**"
|
||||
- "!backend/README.md"
|
||||
- "!backend/.*"
|
||||
- "backend/.eslintrc.js"
|
||||
|
||||
jobs:
|
||||
check-be-pr:
|
||||
name: Check TS and Lint
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: ☁️ Checkout source
|
||||
uses: actions/checkout@v3
|
||||
- name: 🔧 Setup Node 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "npm"
|
||||
cache-dependency-path: backend/package-lock.json
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
working-directory: backend
|
||||
- name: Run type check
|
||||
run: npm run type:check
|
||||
working-directory: backend
|
||||
- name: Run lint check
|
||||
run: npm run lint
|
||||
working-directory: backend
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,7 +6,7 @@ node_modules
|
||||
.env.gamma
|
||||
.env.prod
|
||||
.env.infisical
|
||||
|
||||
.env.migration
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
|
@@ -104,7 +104,6 @@ ENV NEXT_PUBLIC_INTERCOM_ID=$INTERCOM_ID \
|
||||
WORKDIR /
|
||||
|
||||
COPY --from=backend-runner /app /backend
|
||||
COPY --from=backend-runner /app/dist/services/smtp/templates /backend/dist/templates
|
||||
|
||||
COPY --from=frontend-runner /app ./backend/frontend-build
|
||||
|
||||
|
30
README.md
30
README.md
@@ -33,7 +33,7 @@
|
||||
<img src="https://img.shields.io/github/commit-activity/m/infisical/infisical" alt="git commit activity" />
|
||||
</a>
|
||||
<a href="https://cloudsmith.io/~infisical/repos/">
|
||||
<img src="https://img.shields.io/badge/Downloads-2.58M-orange" alt="Cloudsmith downloads" />
|
||||
<img src="https://img.shields.io/badge/Downloads-6.95M-orange" alt="Cloudsmith downloads" />
|
||||
</a>
|
||||
<a href="https://infisical.com/slack">
|
||||
<img src="https://img.shields.io/badge/chat-on%20Slack-blueviolet" alt="Slack community channel" />
|
||||
@@ -53,17 +53,19 @@ We're on a mission to make secret management more accessible to everyone, not ju
|
||||
|
||||
## Features
|
||||
|
||||
- **[User-friendly dashboard](https://infisical.com/docs/documentation/platform/project)** to manage secrets across projects and environments (e.g. development, production, etc.)
|
||||
- **[Client SDKs](https://infisical.com/docs/sdks/overview)** to fetch secrets for your apps and infrastructure on demand
|
||||
- **[Infisical CLI](https://infisical.com/docs/cli/overview)** to fetch and inject secrets into any framework in local development
|
||||
- **[Native integrations](https://infisical.com/docs/integrations/overview)** with platforms like GitHub, Vercel, Netlify, and more
|
||||
- [**Automatic Kubernetes deployment secret reloads**](https://infisical.com/docs/documentation/getting-started/kubernetes)
|
||||
- **[Complete control over your data](https://infisical.com/docs/self-hosting/overview)** - host it yourself on any infrastructure
|
||||
- **[Secret versioning](https://infisical.com/docs/documentation/platform/secret-versioning)** and **[Point-in-Time Recovery]()** to version every secret and project state
|
||||
- **[Audit logs](https://infisical.com/docs/documentation/platform/audit-logs)** to record every action taken in a project
|
||||
- **Role-based Access Controls** per environment
|
||||
- [**Simple on-premise deployments** to AWS, Digital Ocean, and more](https://infisical.com/docs/self-hosting/overview)
|
||||
- [**Secret Scanning and Leak Prevention**](https://infisical.com/docs/cli/scanning-overview)
|
||||
- **[User-friendly dashboard](https://infisical.com/docs/documentation/platform/project)** to manage secrets across projects and environments (e.g. development, production, etc.).
|
||||
- **[Client SDKs](https://infisical.com/docs/sdks/overview)** to fetch secrets for your apps and infrastructure on demand.
|
||||
- **[Infisical CLI](https://infisical.com/docs/cli/overview)** to fetch and inject secrets into any framework in local development and CI/CD.
|
||||
- **[Infisical API](https://infisical.com/docs/api-reference/overview/introduction)** to perform CRUD operation on secrets, users, projects, and any other resource in Infisical.
|
||||
- **[Native integrations](https://infisical.com/docs/integrations/overview)** with platforms like [GitHub](https://infisical.com/docs/integrations/cicd/githubactions), [Vercel](https://infisical.com/docs/integrations/cloud/vercel), [AWS](https://infisical.com/docs/integrations/cloud/aws-secret-manager), and tools like [Terraform](https://infisical.com/docs/integrations/frameworks/terraform), [Ansible](https://infisical.com/docs/integrations/platforms/ansible), and more.
|
||||
- **[Infisical Kubernetes operator](https://infisical.com/docs/documentation/getting-started/kubernetes)** to managed secrets in k8s, automatically reload deployments, and more.
|
||||
- **[Infisical Agent](https://infisical.com/docs/infisical-agent/overview)** to inject secrets into your applications without modifying any code logic.
|
||||
- **[Self-hosting and on-prem](https://infisical.com/docs/self-hosting/overview)** to get complete control over your data.
|
||||
- **[Secret versioning](https://infisical.com/docs/documentation/platform/secret-versioning)** and **[Point-in-Time Recovery](https://infisical.com/docs/documentation/platform/pit-recovery)** to version every secret and project state.
|
||||
- **[Audit logs](https://infisical.com/docs/documentation/platform/audit-logs)** to record every action taken in a project.
|
||||
- **[Role-based Access Controls](https://infisical.com/docs/documentation/platform/role-based-access-controls)** to create permission sets on any resource in Infisica and assign those to user or machine identities.
|
||||
- **[Simple on-premise deployments](https://infisical.com/docs/self-hosting/overview)** to AWS, Digital Ocean, and more.
|
||||
- **[Secret Scanning and Leak Prevention](https://infisical.com/docs/cli/scanning-overview)** to prevent secrets from leaking to git.
|
||||
|
||||
And much more.
|
||||
|
||||
@@ -115,9 +117,9 @@ Lean about Infisical's code scanning feature [here](https://infisical.com/docs/c
|
||||
|
||||
This repo available under the [MIT expat license](https://github.com/Infisical/infisical/blob/main/LICENSE), with the exception of the `ee` directory which will contain premium enterprise features requiring a Infisical license.
|
||||
|
||||
If you are interested in managed Infisical Cloud of self-hosted Enterprise Offering, take a look at [our website](https://infisical.com/) or [book a meeting with us](https://cal.com/vmatsiiako/infisical-demo):
|
||||
If you are interested in managed Infisical Cloud of self-hosted Enterprise Offering, take a look at [our website](https://infisical.com/) or [book a meeting with us](https://infisical.cal.com/vlad/infisical-demo):
|
||||
|
||||
<a href="https://cal.com/vmatsiiako/infisical-demo"><img alt="Schedule a meeting" src="https://cal.com/book-with-cal-dark.svg" /></a>
|
||||
<a href="[https://infisical.cal.com/vlad/infisical-demo](https://infisical.cal.com/vlad/infisical-demo)"><img alt="Schedule a meeting" src="https://cal.com/book-with-cal-dark.svg" /></a>
|
||||
|
||||
## Security
|
||||
|
||||
|
@@ -1,27 +1,39 @@
|
||||
/* eslint-env node */
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true
|
||||
es6: true,
|
||||
node: true
|
||||
},
|
||||
extends: ["airbnb-base", "airbnb-typescript/base", "prettier"],
|
||||
plugins: ["prettier", "simple-import-sort", "import"],
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-type-checked",
|
||||
"airbnb-base",
|
||||
"airbnb-typescript/base",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier"
|
||||
],
|
||||
plugins: ["@typescript-eslint", "simple-import-sort", "import"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
project: true,
|
||||
sourceType: "module",
|
||||
project: "./tsconfig.json",
|
||||
tsconfigRootDir: __dirname
|
||||
},
|
||||
root: true,
|
||||
rules: {
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-unsafe-enum-comparison": "off",
|
||||
"no-void": "off",
|
||||
"consistent-return": "off", // my style
|
||||
"import/order": "off", // for simple-import-order
|
||||
"import/prefer-default-export": "off", // why
|
||||
"no-restricted-syntax": "off",
|
||||
// importing rules
|
||||
"simple-import-sort/exports": "error",
|
||||
"import/first": "error",
|
||||
"import/newline-after-import": "error",
|
||||
"import/no-duplicates": "error",
|
||||
"simple-import-sort/exports": "error",
|
||||
"simple-import-sort/imports": [
|
||||
"warn",
|
||||
{
|
||||
@@ -45,12 +57,5 @@ module.exports = {
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
settings: {
|
||||
"import/resolver": {
|
||||
typescript: {
|
||||
project: ["./tsconfig.json"]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"singleQuote": false,
|
||||
"printWidth": 100,
|
||||
"printWidth": 120,
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"semi": true
|
||||
}
|
||||
}
|
||||
|
@@ -16,9 +16,11 @@ export const mockQueue = (): TQueueServiceFactory => {
|
||||
queues[name] = jobFn;
|
||||
workers[name] = jobFn;
|
||||
},
|
||||
listen: async (name, event) => {
|
||||
listen: (name, event) => {
|
||||
events[name] = event;
|
||||
},
|
||||
clearQueue: async () => {},
|
||||
stopJobById: async () => {},
|
||||
stopRepeatableJobByJobId: async () => true
|
||||
};
|
||||
};
|
||||
|
724
backend/package-lock.json
generated
724
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -2,12 +2,12 @@
|
||||
"name": "backend",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"main": "./dist/main.mjs",
|
||||
"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 && cp -R ./src/lib/validator/disposable_emails.txt ./dist && cp -R ./src/services/smtp/templates ./dist",
|
||||
"build": "tsup",
|
||||
"start": "node dist/main.mjs",
|
||||
"type:check": "tsc --noEmit",
|
||||
"lint:fix": "eslint --fix --ext js,ts ./src",
|
||||
@@ -44,11 +44,13 @@
|
||||
"@types/pg": "^8.10.9",
|
||||
"@types/picomatch": "^2.3.3",
|
||||
"@types/prompt-sync": "^4.2.3",
|
||||
"@types/resolve": "^1.20.6",
|
||||
"@types/uuid": "^9.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||
"@typescript-eslint/parser": "^6.13.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.20.0",
|
||||
"@typescript-eslint/parser": "^6.20.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
@@ -59,6 +61,7 @@
|
||||
"prompt-sync": "^4.2.0",
|
||||
"rimraf": "^5.0.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsc-alias": "^1.8.8",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"tsup": "^8.0.1",
|
||||
"tsx": "^4.4.0",
|
||||
@@ -71,6 +74,7 @@
|
||||
"@casl/ability": "^6.5.0",
|
||||
"@fastify/cookie": "^9.2.0",
|
||||
"@fastify/cors": "^8.4.1",
|
||||
"@fastify/etag": "^5.1.0",
|
||||
"@fastify/formbody": "^7.4.0",
|
||||
"@fastify/helmet": "^11.1.1",
|
||||
"@fastify/passport": "^2.4.0",
|
||||
@@ -92,7 +96,6 @@
|
||||
"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",
|
||||
@@ -107,7 +110,6 @@
|
||||
"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",
|
||||
@@ -123,4 +125,4 @@
|
||||
"zod": "^3.22.4",
|
||||
"zod-to-json-schema": "^3.22.0"
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,13 +3,9 @@ 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
|
||||
path: path.join(__dirname, "../../.env.migration")
|
||||
});
|
||||
|
||||
const db = knex({
|
||||
@@ -94,17 +90,7 @@ const main = async () => {
|
||||
.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);
|
||||
@@ -124,16 +110,16 @@ const main = async () => {
|
||||
if (colInfo.nullable) {
|
||||
ztype = ztype.concat(".nullable().optional()");
|
||||
}
|
||||
schema = schema.concat(`${!schema ? "\n" : ""} ${columnName}: ${ztype},\n`);
|
||||
schema = schema.concat(
|
||||
`${!schema ? "\n" : ""} ${columnName}: ${ztype}${colNum === columnNames.length - 1 ? "" : ","}\n`
|
||||
);
|
||||
}
|
||||
|
||||
const dashcase = tableName.split("_").join("-");
|
||||
const pascalCase = tableName
|
||||
.split("_")
|
||||
.reduce(
|
||||
(prev, curr) => prev + `${curr.at(0)?.toUpperCase()}${curr.slice(1).toLowerCase()}`,
|
||||
""
|
||||
);
|
||||
.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.
|
||||
@@ -152,15 +138,6 @@ 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);
|
||||
|
7
backend/src/@types/fastify-zod.d.ts
vendored
7
backend/src/@types/fastify-zod.d.ts
vendored
@@ -1,9 +1,4 @@
|
||||
import {
|
||||
FastifyInstance,
|
||||
RawReplyDefaultExpression,
|
||||
RawRequestDefaultExpression,
|
||||
RawServerDefault
|
||||
} from "fastify";
|
||||
import { FastifyInstance, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerDefault } from "fastify";
|
||||
import { Logger } from "pino";
|
||||
|
||||
import { ZodTypeProvider } from "@app/server/plugins/fastify-zod";
|
||||
|
2
backend/src/@types/fastify.d.ts
vendored
2
backend/src/@types/fastify.d.ts
vendored
@@ -51,6 +51,7 @@ declare module "fastify" {
|
||||
// used for mfa session authentication
|
||||
mfa: {
|
||||
userId: string;
|
||||
orgId?: string;
|
||||
user: TUsers;
|
||||
};
|
||||
// identity injection. depending on which kinda of token the information is filled in auth
|
||||
@@ -58,6 +59,7 @@ declare module "fastify" {
|
||||
permission: {
|
||||
type: ActorType;
|
||||
id: string;
|
||||
orgId?: string;
|
||||
};
|
||||
// passport data
|
||||
passportUser: {
|
||||
|
108
backend/src/@types/knex.d.ts
vendored
108
backend/src/@types/knex.d.ts
vendored
@@ -177,11 +177,7 @@ declare module "knex/types/tables" {
|
||||
TUserEncryptionKeysInsert,
|
||||
TUserEncryptionKeysUpdate
|
||||
>;
|
||||
[TableName.AuthTokens]: Knex.CompositeTableType<
|
||||
TAuthTokens,
|
||||
TAuthTokensInsert,
|
||||
TAuthTokensUpdate
|
||||
>;
|
||||
[TableName.AuthTokens]: Knex.CompositeTableType<TAuthTokens, TAuthTokensInsert, TAuthTokensUpdate>;
|
||||
[TableName.AuthTokenSession]: Knex.CompositeTableType<
|
||||
TAuthTokenSessions,
|
||||
TAuthTokenSessionsInsert,
|
||||
@@ -192,32 +188,16 @@ declare module "knex/types/tables" {
|
||||
TBackupPrivateKeyInsert,
|
||||
TBackupPrivateKeyUpdate
|
||||
>;
|
||||
[TableName.Organization]: Knex.CompositeTableType<
|
||||
TOrganizations,
|
||||
TOrganizationsInsert,
|
||||
TOrganizationsUpdate
|
||||
>;
|
||||
[TableName.OrgMembership]: Knex.CompositeTableType<
|
||||
TOrgMemberships,
|
||||
TOrgMembershipsInsert,
|
||||
TOrgMembershipsUpdate
|
||||
>;
|
||||
[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.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<
|
||||
@@ -230,73 +210,33 @@ declare module "knex/types/tables" {
|
||||
TProjectEnvironmentsInsert,
|
||||
TProjectEnvironmentsUpdate
|
||||
>;
|
||||
[TableName.ProjectBot]: Knex.CompositeTableType<
|
||||
TProjectBots,
|
||||
TProjectBotsInsert,
|
||||
TProjectBotsUpdate
|
||||
>;
|
||||
[TableName.ProjectRoles]: Knex.CompositeTableType<
|
||||
TProjectRoles,
|
||||
TProjectRolesInsert,
|
||||
TProjectRolesUpdate
|
||||
>;
|
||||
[TableName.ProjectKeys]: Knex.CompositeTableType<
|
||||
TProjectKeys,
|
||||
TProjectKeysInsert,
|
||||
TProjectKeysUpdate
|
||||
>;
|
||||
[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.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.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.ServiceToken]: Knex.CompositeTableType<TServiceTokens, TServiceTokensInsert, TServiceTokensUpdate>;
|
||||
[TableName.IntegrationAuth]: Knex.CompositeTableType<
|
||||
TIntegrationAuths,
|
||||
TIntegrationAuthsInsert,
|
||||
TIntegrationAuthsUpdate
|
||||
>;
|
||||
[TableName.Identity]: Knex.CompositeTableType<
|
||||
TIdentities,
|
||||
TIdentitiesInsert,
|
||||
TIdentitiesUpdate
|
||||
>;
|
||||
[TableName.Identity]: Knex.CompositeTableType<TIdentities, TIdentitiesInsert, TIdentitiesUpdate>;
|
||||
[TableName.IdentityUniversalAuth]: Knex.CompositeTableType<
|
||||
TIdentityUniversalAuths,
|
||||
TIdentityUniversalAuthsInsert,
|
||||
@@ -362,11 +302,7 @@ declare module "knex/types/tables" {
|
||||
TSecretRotationOutputsInsert,
|
||||
TSecretRotationOutputsUpdate
|
||||
>;
|
||||
[TableName.Snapshot]: Knex.CompositeTableType<
|
||||
TSecretSnapshots,
|
||||
TSecretSnapshotsInsert,
|
||||
TSecretSnapshotsUpdate
|
||||
>;
|
||||
[TableName.Snapshot]: Knex.CompositeTableType<TSecretSnapshots, TSecretSnapshotsInsert, TSecretSnapshotsUpdate>;
|
||||
[TableName.SnapshotSecret]: Knex.CompositeTableType<
|
||||
TSecretSnapshotSecrets,
|
||||
TSecretSnapshotSecretsInsert,
|
||||
@@ -377,11 +313,7 @@ declare module "knex/types/tables" {
|
||||
TSecretSnapshotFoldersInsert,
|
||||
TSecretSnapshotFoldersUpdate
|
||||
>;
|
||||
[TableName.SamlConfig]: Knex.CompositeTableType<
|
||||
TSamlConfigs,
|
||||
TSamlConfigsInsert,
|
||||
TSamlConfigsUpdate
|
||||
>;
|
||||
[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<
|
||||
@@ -395,11 +327,7 @@ declare module "knex/types/tables" {
|
||||
TSecretScanningGitRisksInsert,
|
||||
TSecretScanningGitRisksUpdate
|
||||
>;
|
||||
[TableName.TrustedIps]: Knex.CompositeTableType<
|
||||
TTrustedIps,
|
||||
TTrustedIpsInsert,
|
||||
TTrustedIpsUpdate
|
||||
>;
|
||||
[TableName.TrustedIps]: Knex.CompositeTableType<TTrustedIps, TTrustedIpsInsert, TTrustedIpsUpdate>;
|
||||
// Junction tables
|
||||
[TableName.JnSecretTag]: Knex.CompositeTableType<
|
||||
TSecretTagJunction,
|
||||
|
@@ -1,10 +1,18 @@
|
||||
import knex from "knex";
|
||||
|
||||
export type TDbClient = ReturnType<typeof initDbConnection>;
|
||||
export const initDbConnection = (dbConnectionUri: string) => {
|
||||
export const initDbConnection = ({ dbConnectionUri, dbRootCert }: { dbConnectionUri: string; dbRootCert?: string }) => {
|
||||
const db = knex({
|
||||
client: "pg",
|
||||
connection: dbConnectionUri
|
||||
connection: {
|
||||
connectionString: dbConnectionUri,
|
||||
ssl: dbRootCert
|
||||
? {
|
||||
rejectUnauthorized: true,
|
||||
ca: Buffer.from(dbRootCert, "base64").toString("ascii")
|
||||
}
|
||||
: false
|
||||
}
|
||||
});
|
||||
|
||||
return db;
|
||||
|
@@ -5,9 +5,9 @@ import dotenv from "dotenv";
|
||||
import type { Knex } from "knex";
|
||||
import path from "path";
|
||||
|
||||
// Update with your config settings.
|
||||
// Update with your config settings. .
|
||||
dotenv.config({
|
||||
path: path.join(__dirname, "../../.env"),
|
||||
path: path.join(__dirname, "../../../.env.migration"),
|
||||
debug: true
|
||||
});
|
||||
export default {
|
||||
|
@@ -38,12 +38,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
}
|
||||
await createOnUpdateTrigger(knex, TableName.SecretVersion);
|
||||
// many to many relation between tags
|
||||
await createJunctionTable(
|
||||
knex,
|
||||
TableName.SecretVersionTag,
|
||||
TableName.SecretVersion,
|
||||
TableName.SecretTag
|
||||
);
|
||||
await createJunctionTable(knex, TableName.SecretVersionTag, TableName.SecretVersion, TableName.SecretTag);
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
|
@@ -50,10 +50,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
t.string("integration").notNullable();
|
||||
t.jsonb("metadata");
|
||||
t.uuid("integrationAuthId").notNullable();
|
||||
t.foreign("integrationAuthId")
|
||||
.references("id")
|
||||
.inTable(TableName.IntegrationAuth)
|
||||
.onDelete("CASCADE");
|
||||
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");
|
||||
|
@@ -31,10 +31,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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");
|
||||
t.foreign("identityUAId").references("id").inTable(TableName.IdentityUniversalAuth).onDelete("CASCADE");
|
||||
});
|
||||
}
|
||||
await createOnUpdateTrigger(knex, TableName.IdentityUniversalAuth);
|
||||
|
@@ -19,7 +19,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
.references("id")
|
||||
.inTable(TableName.IdentityUaClientSecret)
|
||||
.onDelete("CASCADE");
|
||||
t.uuid("identityId").notNullable();
|
||||
t.uuid("identityId").notNullable();
|
||||
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
|
||||
t.timestamps(true, true, true);
|
||||
});
|
||||
|
@@ -21,15 +21,9 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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.foreign("approverId").references("id").inTable(TableName.ProjectMembership).onDelete("CASCADE");
|
||||
t.uuid("policyId").notNullable();
|
||||
t.foreign("policyId")
|
||||
.references("id")
|
||||
.inTable(TableName.SecretApprovalPolicy)
|
||||
.onDelete("CASCADE");
|
||||
t.foreign("policyId").references("id").inTable(TableName.SecretApprovalPolicy).onDelete("CASCADE");
|
||||
t.timestamps(true, true, true);
|
||||
});
|
||||
}
|
||||
|
@@ -11,23 +11,14 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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.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.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.foreign("committerId").references("id").inTable(TableName.ProjectMembership).onDelete("CASCADE");
|
||||
t.timestamps(true, true, true);
|
||||
});
|
||||
}
|
||||
@@ -40,10 +31,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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.foreign("requestId").references("id").inTable(TableName.SecretApprovalRequest).onDelete("CASCADE");
|
||||
t.timestamps(true, true, true);
|
||||
});
|
||||
}
|
||||
@@ -73,18 +61,12 @@ export async function up(knex: Knex): Promise<void> {
|
||||
t.timestamps(true, true, true);
|
||||
// commit details
|
||||
t.uuid("requestId").notNullable();
|
||||
t.foreign("requestId")
|
||||
.references("id")
|
||||
.inTable(TableName.SecretApprovalRequest)
|
||||
.onDelete("CASCADE");
|
||||
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");
|
||||
t.foreign("secretVersion").references("id").inTable(TableName.SecretVersion).onDelete("SET NULL");
|
||||
});
|
||||
}
|
||||
await createOnUpdateTrigger(knex, TableName.SecretApprovalRequestSecret);
|
||||
@@ -93,10 +75,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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.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);
|
||||
|
@@ -32,10 +32,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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");
|
||||
t.foreign("rotationId").references("id").inTable(TableName.SecretRotation).onDelete("CASCADE");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -25,10 +25,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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.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);
|
||||
@@ -42,10 +39,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
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.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);
|
||||
|
@@ -15,7 +15,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
t.timestamps(true, true, true);
|
||||
});
|
||||
}
|
||||
createOnUpdateTrigger(knex, TableName.GitAppInstallSession);
|
||||
await createOnUpdateTrigger(knex, TableName.GitAppInstallSession);
|
||||
|
||||
if (!(await knex.schema.hasTable(TableName.GitAppOrg))) {
|
||||
await knex.schema.createTable(TableName.GitAppOrg, (t) => {
|
||||
@@ -28,7 +28,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
t.timestamps(true, true, true);
|
||||
});
|
||||
}
|
||||
createOnUpdateTrigger(knex, TableName.GitAppOrg);
|
||||
await createOnUpdateTrigger(knex, TableName.GitAppOrg);
|
||||
|
||||
if (!(await knex.schema.hasTable(TableName.SecretScanningGitRisk))) {
|
||||
await knex.schema.createTable(TableName.SecretScanningGitRisk, (t) => {
|
||||
@@ -66,7 +66,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
t.timestamps(true, true, true);
|
||||
});
|
||||
}
|
||||
createOnUpdateTrigger(knex, TableName.SecretScanningGitRisk);
|
||||
await createOnUpdateTrigger(knex, TableName.SecretScanningGitRisk);
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
|
25
backend/src/db/migrations/20240204171758_org-based-auth.ts
Normal file
25
backend/src/db/migrations/20240204171758_org-based-auth.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { TableName } from "../schemas";
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable(TableName.Organization, (t) => {
|
||||
t.boolean("authEnforced").defaultTo(false);
|
||||
t.index("slug");
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(TableName.SamlConfig, (t) => {
|
||||
t.datetime("lastUsed");
|
||||
});
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable(TableName.Organization, (t) => {
|
||||
t.dropColumn("authEnforced");
|
||||
t.dropIndex("slug");
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(TableName.SamlConfig, (t) => {
|
||||
t.dropColumn("lastUsed");
|
||||
});
|
||||
}
|
@@ -15,7 +15,7 @@ export const ApiKeysSchema = z.object({
|
||||
secretHash: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
userId: z.string().uuid(),
|
||||
userId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TApiKeys = z.infer<typeof ApiKeysSchema>;
|
||||
|
@@ -20,7 +20,7 @@ export const AuditLogsSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
orgId: z.string().uuid().nullable().optional(),
|
||||
projectId: z.string().nullable().optional(),
|
||||
projectId: z.string().nullable().optional()
|
||||
});
|
||||
|
||||
export type TAuditLogs = z.infer<typeof AuditLogsSchema>;
|
||||
|
@@ -16,7 +16,7 @@ export const AuthTokenSessionsSchema = z.object({
|
||||
lastUsed: z.date(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
userId: z.string().uuid(),
|
||||
userId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TAuthTokenSessions = z.infer<typeof AuthTokenSessionsSchema>;
|
||||
|
@@ -17,7 +17,7 @@ export const AuthTokensSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
userId: z.string().uuid().nullable().optional(),
|
||||
orgId: z.string().uuid().nullable().optional(),
|
||||
orgId: z.string().uuid().nullable().optional()
|
||||
});
|
||||
|
||||
export type TAuthTokens = z.infer<typeof AuthTokensSchema>;
|
||||
|
@@ -18,7 +18,7 @@ export const BackupPrivateKeySchema = z.object({
|
||||
verifier: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
userId: z.string().uuid(),
|
||||
userId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TBackupPrivateKey = z.infer<typeof BackupPrivateKeySchema>;
|
||||
|
@@ -13,7 +13,7 @@ export const GitAppInstallSessionsSchema = z.object({
|
||||
userId: z.string().uuid().nullable().optional(),
|
||||
orgId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TGitAppInstallSessions = z.infer<typeof GitAppInstallSessionsSchema>;
|
||||
|
@@ -13,7 +13,7 @@ export const GitAppOrgSchema = z.object({
|
||||
userId: z.string().uuid(),
|
||||
orgId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TGitAppOrg = z.infer<typeof GitAppOrgSchema>;
|
||||
|
@@ -12,7 +12,7 @@ export const IdentitiesSchema = z.object({
|
||||
name: z.string(),
|
||||
authMethod: z.string().nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TIdentities = z.infer<typeof IdentitiesSchema>;
|
||||
|
@@ -19,7 +19,7 @@ export const IdentityAccessTokensSchema = z.object({
|
||||
identityUAClientSecretId: z.string().nullable().optional(),
|
||||
identityId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TIdentityAccessTokens = z.infer<typeof IdentityAccessTokensSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const IdentityOrgMembershipsSchema = z.object({
|
||||
orgId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
identityId: z.string().uuid(),
|
||||
identityId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TIdentityOrgMemberships = z.infer<typeof IdentityOrgMembershipsSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const IdentityProjectMembershipsSchema = z.object({
|
||||
projectId: z.string(),
|
||||
identityId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TIdentityProjectMemberships = z.infer<typeof IdentityProjectMembershipsSchema>;
|
||||
|
@@ -19,7 +19,7 @@ export const IdentityUaClientSecretsSchema = z.object({
|
||||
isClientSecretRevoked: z.boolean().default(false),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
identityUAId: z.string().uuid(),
|
||||
identityUAId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TIdentityUaClientSecrets = z.infer<typeof IdentityUaClientSecretsSchema>;
|
||||
|
@@ -17,7 +17,7 @@ export const IdentityUniversalAuthsSchema = z.object({
|
||||
accessTokenTrustedIps: z.unknown(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
identityId: z.string().uuid(),
|
||||
identityId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TIdentityUniversalAuths = z.infer<typeof IdentityUniversalAuthsSchema>;
|
||||
|
@@ -12,7 +12,7 @@ export const IncidentContactsSchema = z.object({
|
||||
email: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
orgId: z.string().uuid(),
|
||||
orgId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TIncidentContacts = z.infer<typeof IncidentContactsSchema>;
|
||||
|
@@ -29,7 +29,7 @@ export const IntegrationAuthsSchema = z.object({
|
||||
keyEncoding: z.string(),
|
||||
projectId: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TIntegrationAuths = z.infer<typeof IntegrationAuthsSchema>;
|
||||
|
@@ -25,9 +25,9 @@ export const IntegrationsSchema = z.object({
|
||||
metadata: z.unknown().nullable().optional(),
|
||||
integrationAuthId: z.string().uuid(),
|
||||
envId: z.string().uuid(),
|
||||
secretPath: z.string().default('/'),
|
||||
secretPath: z.string().default("/"),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TIntegrations = z.infer<typeof IntegrationsSchema>;
|
||||
|
@@ -23,7 +23,7 @@ export const OrgBotsSchema = z.object({
|
||||
privateKeyKeyEncoding: z.string(),
|
||||
orgId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TOrgBots = z.infer<typeof OrgBotsSchema>;
|
||||
|
@@ -10,13 +10,13 @@ import { TImmutableDBKeys } from "./models";
|
||||
export const OrgMembershipsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
role: z.string(),
|
||||
status: z.string().default('invited'),
|
||||
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(),
|
||||
roleId: z.string().uuid().nullable().optional()
|
||||
});
|
||||
|
||||
export type TOrgMemberships = z.infer<typeof OrgMembershipsSchema>;
|
||||
|
@@ -15,7 +15,7 @@ export const OrgRolesSchema = z.object({
|
||||
permissions: z.unknown(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
orgId: z.string().uuid(),
|
||||
orgId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TOrgRoles = z.infer<typeof OrgRolesSchema>;
|
||||
|
@@ -14,6 +14,7 @@ export const OrganizationsSchema = z.object({
|
||||
slug: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
authEnforced: z.boolean().default(false).nullable().optional()
|
||||
});
|
||||
|
||||
export type TOrganizations = z.infer<typeof OrganizationsSchema>;
|
||||
|
@@ -22,7 +22,7 @@ export const ProjectBotsSchema = z.object({
|
||||
projectId: z.string(),
|
||||
senderId: z.string().uuid().nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TProjectBots = z.infer<typeof ProjectBotsSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const ProjectEnvironmentsSchema = z.object({
|
||||
position: z.number(),
|
||||
projectId: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TProjectEnvironments = z.infer<typeof ProjectEnvironmentsSchema>;
|
||||
|
@@ -15,7 +15,7 @@ export const ProjectKeysSchema = z.object({
|
||||
senderId: z.string().uuid().nullable().optional(),
|
||||
projectId: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TProjectKeys = z.infer<typeof ProjectKeysSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const ProjectMembershipsSchema = z.object({
|
||||
updatedAt: z.date(),
|
||||
userId: z.string().uuid(),
|
||||
projectId: z.string(),
|
||||
roleId: z.string().uuid().nullable().optional(),
|
||||
roleId: z.string().uuid().nullable().optional()
|
||||
});
|
||||
|
||||
export type TProjectMemberships = z.infer<typeof ProjectMembershipsSchema>;
|
||||
|
@@ -15,7 +15,7 @@ export const ProjectRolesSchema = z.object({
|
||||
permissions: z.unknown(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
projectId: z.string(),
|
||||
projectId: z.string()
|
||||
});
|
||||
|
||||
export type TProjectRoles = z.infer<typeof ProjectRolesSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const ProjectsSchema = z.object({
|
||||
autoCapitalization: z.boolean().default(true).nullable().optional(),
|
||||
orgId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TProjects = z.infer<typeof ProjectsSchema>;
|
||||
|
@@ -23,6 +23,7 @@ export const SamlConfigsSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
orgId: z.string().uuid(),
|
||||
lastUsed: z.date().nullable().optional()
|
||||
});
|
||||
|
||||
export type TSamlConfigs = z.infer<typeof SamlConfigsSchema>;
|
||||
|
@@ -12,7 +12,7 @@ export const SecretApprovalPoliciesApproversSchema = z.object({
|
||||
approverId: z.string().uuid(),
|
||||
policyId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretApprovalPoliciesApprovers = z.infer<typeof SecretApprovalPoliciesApproversSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const SecretApprovalPoliciesSchema = z.object({
|
||||
approvals: z.number().default(1),
|
||||
envId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretApprovalPolicies = z.infer<typeof SecretApprovalPoliciesSchema>;
|
||||
|
@@ -12,7 +12,7 @@ export const SecretApprovalRequestSecretTagsSchema = z.object({
|
||||
secretId: z.string().uuid(),
|
||||
tagId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretApprovalRequestSecretTags = z.infer<typeof SecretApprovalRequestSecretTagsSchema>;
|
||||
|
@@ -13,7 +13,7 @@ export const SecretApprovalRequestsReviewersSchema = z.object({
|
||||
status: z.string(),
|
||||
requestId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretApprovalRequestsReviewers = z.infer<typeof SecretApprovalRequestsReviewersSchema>;
|
||||
|
@@ -23,15 +23,15 @@ export const SecretApprovalRequestsSecretsSchema = z.object({
|
||||
secretReminderNote: z.string().nullable().optional(),
|
||||
secretReminderRepeatDays: z.number().nullable().optional(),
|
||||
skipMultilineEncoding: z.boolean().default(false).nullable().optional(),
|
||||
algorithm: z.string().default('aes-256-gcm'),
|
||||
keyEncoding: z.string().default('utf8'),
|
||||
algorithm: z.string().default("aes-256-gcm"),
|
||||
keyEncoding: z.string().default("utf8"),
|
||||
metadata: z.unknown().nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
requestId: z.string().uuid(),
|
||||
op: z.string(),
|
||||
secretId: z.string().uuid().nullable().optional(),
|
||||
secretVersion: z.string().uuid().nullable().optional(),
|
||||
secretVersion: z.string().uuid().nullable().optional()
|
||||
});
|
||||
|
||||
export type TSecretApprovalRequestsSecrets = z.infer<typeof SecretApprovalRequestsSecretsSchema>;
|
||||
|
@@ -11,14 +11,14 @@ export const SecretApprovalRequestsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
policyId: z.string().uuid(),
|
||||
hasMerged: z.boolean().default(false),
|
||||
status: z.string().default('open'),
|
||||
status: z.string().default("open"),
|
||||
conflicts: z.unknown().nullable().optional(),
|
||||
slug: z.string(),
|
||||
folderId: z.string().uuid(),
|
||||
statusChangeBy: z.string().uuid().nullable().optional(),
|
||||
committerId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretApprovalRequests = z.infer<typeof SecretApprovalRequestsSchema>;
|
||||
|
@@ -12,11 +12,11 @@ export const SecretBlindIndexesSchema = z.object({
|
||||
encryptedSaltCipherText: z.string(),
|
||||
saltIV: z.string(),
|
||||
saltTag: z.string(),
|
||||
algorithm: z.string().default('aes-256-gcm'),
|
||||
keyEncoding: z.string().default('utf8'),
|
||||
algorithm: z.string().default("aes-256-gcm"),
|
||||
keyEncoding: z.string().default("utf8"),
|
||||
projectId: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretBlindIndexes = z.infer<typeof SecretBlindIndexesSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const SecretFolderVersionsSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
envId: z.string().uuid(),
|
||||
folderId: z.string().uuid(),
|
||||
folderId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TSecretFolderVersions = z.infer<typeof SecretFolderVersionsSchema>;
|
||||
|
@@ -14,7 +14,7 @@ export const SecretFoldersSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
envId: z.string().uuid(),
|
||||
parentId: z.string().uuid().nullable().optional(),
|
||||
parentId: z.string().uuid().nullable().optional()
|
||||
});
|
||||
|
||||
export type TSecretFolders = z.infer<typeof SecretFoldersSchema>;
|
||||
|
@@ -15,7 +15,7 @@ export const SecretImportsSchema = z.object({
|
||||
position: z.number(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
folderId: z.string().uuid(),
|
||||
folderId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TSecretImports = z.infer<typeof SecretImportsSchema>;
|
||||
|
@@ -11,7 +11,7 @@ export const SecretRotationOutputsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
key: z.string(),
|
||||
secretId: z.string().uuid(),
|
||||
rotationId: z.string().uuid(),
|
||||
rotationId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TSecretRotationOutputs = z.infer<typeof SecretRotationOutputsSchema>;
|
||||
|
@@ -22,7 +22,7 @@ export const SecretRotationsSchema = z.object({
|
||||
keyEncoding: z.string().nullable().optional(),
|
||||
envId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretRotations = z.infer<typeof SecretRotationsSchema>;
|
||||
|
@@ -38,7 +38,7 @@ export const SecretScanningGitRisksSchema = z.object({
|
||||
status: z.string().nullable().optional(),
|
||||
orgId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretScanningGitRisks = z.infer<typeof SecretScanningGitRisksSchema>;
|
||||
|
@@ -13,7 +13,7 @@ export const SecretSnapshotFoldersSchema = z.object({
|
||||
folderVersionId: z.string().uuid(),
|
||||
snapshotId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretSnapshotFolders = z.infer<typeof SecretSnapshotFoldersSchema>;
|
||||
|
@@ -13,7 +13,7 @@ export const SecretSnapshotSecretsSchema = z.object({
|
||||
secretVersionId: z.string().uuid(),
|
||||
snapshotId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretSnapshotSecrets = z.infer<typeof SecretSnapshotSecretsSchema>;
|
||||
|
@@ -13,7 +13,7 @@ export const SecretSnapshotsSchema = z.object({
|
||||
folderId: z.string().uuid(),
|
||||
parentFolderId: z.string().uuid().nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSecretSnapshots = z.infer<typeof SecretSnapshotsSchema>;
|
||||
|
@@ -10,7 +10,7 @@ import { TImmutableDBKeys } from "./models";
|
||||
export const SecretTagJunctionSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
secretsId: z.string().uuid(),
|
||||
secret_tagsId: z.string().uuid(),
|
||||
secret_tagsId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TSecretTagJunction = z.infer<typeof SecretTagJunctionSchema>;
|
||||
|
@@ -15,7 +15,7 @@ export const SecretTagsSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
createdBy: z.string().uuid().nullable().optional(),
|
||||
projectId: z.string(),
|
||||
projectId: z.string()
|
||||
});
|
||||
|
||||
export type TSecretTags = z.infer<typeof SecretTagsSchema>;
|
||||
|
@@ -10,7 +10,7 @@ import { TImmutableDBKeys } from "./models";
|
||||
export const SecretVersionTagJunctionSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
secret_versionsId: z.string().uuid(),
|
||||
secret_tagsId: z.string().uuid(),
|
||||
secret_tagsId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TSecretVersionTagJunction = z.infer<typeof SecretVersionTagJunctionSchema>;
|
||||
|
@@ -21,7 +21,7 @@ export const ServiceTokensSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
createdBy: z.string(),
|
||||
projectId: z.string(),
|
||||
projectId: z.string()
|
||||
});
|
||||
|
||||
export type TServiceTokens = z.infer<typeof ServiceTokensSchema>;
|
||||
|
@@ -12,7 +12,7 @@ export const SuperAdminSchema = z.object({
|
||||
initialized: z.boolean().default(false).nullable().optional(),
|
||||
allowSignUp: z.boolean().default(true).nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TSuperAdmin = z.infer<typeof SuperAdminSchema>;
|
||||
|
@@ -16,7 +16,7 @@ export const TrustedIpsSchema = z.object({
|
||||
comment: z.string().nullable().optional(),
|
||||
projectId: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TTrustedIps = z.infer<typeof TrustedIpsSchema>;
|
||||
|
@@ -12,7 +12,7 @@ export const UserActionsSchema = z.object({
|
||||
action: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
userId: z.string().uuid(),
|
||||
userId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TUserActions = z.infer<typeof UserActionsSchema>;
|
||||
|
@@ -21,7 +21,7 @@ export const UserEncryptionKeysSchema = z.object({
|
||||
tag: z.string(),
|
||||
salt: z.string(),
|
||||
verifier: z.string(),
|
||||
userId: z.string().uuid(),
|
||||
userId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TUserEncryptionKeys = z.infer<typeof UserEncryptionKeysSchema>;
|
||||
|
@@ -19,7 +19,7 @@ export const UsersSchema = z.object({
|
||||
mfaMethods: z.string().array().nullable().optional(),
|
||||
devices: z.unknown().nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export type TUsers = z.infer<typeof UsersSchema>;
|
||||
|
@@ -9,7 +9,7 @@ import { TImmutableDBKeys } from "./models";
|
||||
|
||||
export const WebhooksSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
secretPath: z.string().default('/'),
|
||||
secretPath: z.string().default("/"),
|
||||
url: z.string(),
|
||||
lastStatus: z.string().nullable().optional(),
|
||||
lastRunErrorMessage: z.string().nullable().optional(),
|
||||
@@ -21,7 +21,7 @@ export const WebhooksSchema = z.object({
|
||||
keyEncoding: z.string().nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
envId: z.string().uuid(),
|
||||
envId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TWebhooks = z.infer<typeof WebhooksSchema>;
|
||||
|
@@ -48,14 +48,12 @@ export const generateUserSrpKeys = async (password: string) => {
|
||||
await new Promise((resolve) => {
|
||||
client.init({ username: seedData1.email, password: seedData1.password }, () => resolve(null));
|
||||
});
|
||||
const { salt, verifier } = await new Promise<{ salt: string; verifier: string }>(
|
||||
(resolve, reject) => {
|
||||
client.createVerifier((err, res) => {
|
||||
if (err) return reject(err);
|
||||
return resolve(res);
|
||||
});
|
||||
}
|
||||
);
|
||||
const { salt, verifier } = await new Promise<{ salt: string; verifier: string }>((resolve, reject) => {
|
||||
client.createVerifier((err, res) => {
|
||||
if (err) return reject(err);
|
||||
return resolve(res);
|
||||
});
|
||||
});
|
||||
const derivedKey = await argon2.hash(password, {
|
||||
salt: Buffer.from(salt),
|
||||
memoryCost: 65536,
|
||||
|
@@ -14,7 +14,7 @@ export async function seed(knex: Knex): Promise<void> {
|
||||
const [user] = await knex(TableName.Users)
|
||||
.insert([
|
||||
{
|
||||
// @ts-ignore to calculate predefined
|
||||
// @ts-expect-error exluded type id needs to be inserted here to keep it testable
|
||||
id: seedData1.id,
|
||||
email: seedData1.email,
|
||||
superAdmin: true,
|
||||
@@ -48,7 +48,7 @@ export async function seed(knex: Knex): Promise<void> {
|
||||
]);
|
||||
|
||||
await knex(TableName.AuthTokenSession).insert({
|
||||
// @ts-ignore
|
||||
// @ts-expect-error exluded type id needs to be inserted here to keep it testable
|
||||
id: seedData1.token.id,
|
||||
userId: seedData1.id,
|
||||
ip: "151.196.220.213",
|
||||
|
@@ -14,7 +14,7 @@ export async function seed(knex: Knex): Promise<void> {
|
||||
const [org] = await knex(TableName.Organization)
|
||||
.insert([
|
||||
{
|
||||
// @ts-ignore because we need that id for api calls
|
||||
// @ts-expect-error exluded type id needs to be inserted here to keep it testable
|
||||
id: seedData1.organization.id,
|
||||
name: "infisical",
|
||||
slug: "infisical",
|
||||
|
@@ -20,7 +20,7 @@ export async function seed(knex: Knex): Promise<void> {
|
||||
name: seedData1.project.name,
|
||||
orgId: seedData1.organization.id,
|
||||
slug: "first-project",
|
||||
// @ts-ignore pre calc id
|
||||
// @ts-expect-error exluded type id needs to be inserted here to keep it testable
|
||||
id: seedData1.project.id
|
||||
})
|
||||
.returning("*");
|
||||
@@ -45,7 +45,5 @@ export async function seed(knex: Knex): Promise<void> {
|
||||
}))
|
||||
)
|
||||
.returning("*");
|
||||
await knex(TableName.SecretFolder).insert(
|
||||
envs.map(({ id }) => ({ name: "root", envId: id, parentId: null }))
|
||||
);
|
||||
await knex(TableName.SecretFolder).insert(envs.map(({ id }) => ({ name: "root", envId: id, parentId: null })));
|
||||
}
|
||||
|
@@ -2,12 +2,7 @@ import { Knex } from "knex";
|
||||
|
||||
import { TableName } from "./schemas";
|
||||
|
||||
export const createJunctionTable = (
|
||||
knex: Knex,
|
||||
tableName: TableName,
|
||||
table1Name: TableName,
|
||||
table2Name: TableName
|
||||
) =>
|
||||
export const createJunctionTable = (knex: Knex, tableName: TableName, table1Name: TableName, table2Name: TableName) =>
|
||||
knex.schema.createTable(tableName, (table) => {
|
||||
table.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
|
||||
table.uuid(`${table1Name}Id`).unsigned().notNullable(); // Foreign key for table1
|
||||
|
@@ -1,3 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
// TODO(akhilmhdh): Fix this when licence service gets it type
|
||||
import { z } from "zod";
|
||||
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
@@ -19,6 +22,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgPlansTableByBillCycle({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
billingCycle: req.query.billingCycle
|
||||
});
|
||||
@@ -40,6 +44,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const plan = await server.services.license.getOrgPlan({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return { plan };
|
||||
@@ -82,6 +87,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.startOrgTrial({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
success_url: req.body.success_url
|
||||
});
|
||||
@@ -103,6 +109,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.createOrganizationPortalSession({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
@@ -123,6 +130,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgBillingInfo({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
@@ -143,6 +151,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgPlanTable({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
@@ -163,6 +172,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgBillingDetails({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
@@ -187,6 +197,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.updateOrgBillingDetails({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
name: req.body.name,
|
||||
email: req.body.email
|
||||
@@ -209,6 +220,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgPmtMethods({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
@@ -233,6 +245,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.addOrgPmtMethods({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
success_url: req.body.success_url,
|
||||
cancel_url: req.body.cancel_url
|
||||
@@ -258,6 +271,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.delOrgPmtMethods({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
pmtMethodId: req.params.pmtMethodId
|
||||
});
|
||||
@@ -281,6 +295,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgTaxIds({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
@@ -307,6 +322,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.addOrgTaxId({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
type: req.body.type,
|
||||
value: req.body.value
|
||||
@@ -332,6 +348,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.delOrgTaxId({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
taxId: req.params.taxId
|
||||
});
|
||||
@@ -355,6 +372,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgTaxInvoices({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
@@ -377,6 +395,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
|
||||
const data = await server.services.license.getOrgLicenses({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return data;
|
||||
|
@@ -26,11 +26,11 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
|
||||
const role = await server.services.orgRole.createRole(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.body
|
||||
req.body,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { role };
|
||||
}
|
||||
@@ -58,12 +58,12 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
|
||||
const role = await server.services.orgRole.updateRole(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.params.roleId,
|
||||
req.body
|
||||
req.body,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { role };
|
||||
}
|
||||
@@ -85,11 +85,11 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
|
||||
const role = await server.services.orgRole.deleteRole(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.params.roleId
|
||||
req.params.roleId,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { role };
|
||||
}
|
||||
@@ -114,10 +114,10 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
|
||||
const roles = await server.services.orgRole.listRoles(
|
||||
req.permission.id,
|
||||
req.params.organizationId
|
||||
req.params.organizationId,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { data: { roles } };
|
||||
}
|
||||
@@ -139,10 +139,10 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
|
||||
const { permissions, membership } = await server.services.orgRole.getUserPermission(
|
||||
req.permission.id,
|
||||
req.params.organizationId
|
||||
req.params.organizationId,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { permissions, membership };
|
||||
}
|
||||
|
@@ -30,7 +30,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
req.permission.type,
|
||||
req.permission.id,
|
||||
req.params.projectId,
|
||||
req.body
|
||||
req.body,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { role };
|
||||
}
|
||||
@@ -63,7 +64,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
req.permission.id,
|
||||
req.params.projectId,
|
||||
req.params.roleId,
|
||||
req.body
|
||||
req.body,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { role };
|
||||
}
|
||||
@@ -89,7 +91,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
req.permission.type,
|
||||
req.permission.id,
|
||||
req.params.projectId,
|
||||
req.params.roleId
|
||||
req.params.roleId,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { role };
|
||||
}
|
||||
@@ -117,7 +120,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
const roles = await server.services.projectRole.listRoles(
|
||||
req.permission.type,
|
||||
req.permission.id,
|
||||
req.params.projectId
|
||||
req.params.projectId,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { data: { roles } };
|
||||
}
|
||||
@@ -141,10 +145,10 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
|
||||
const { permissions, membership } = await server.services.projectRole.getUserPermission(
|
||||
req.permission.id,
|
||||
req.params.projectId
|
||||
req.params.projectId,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { data: { permissions, membership } };
|
||||
}
|
||||
|
@@ -11,6 +11,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
method: "GET",
|
||||
url: "/:workspaceId/secret-snapshots",
|
||||
schema: {
|
||||
description: "Return project secret snapshots ids",
|
||||
security: [
|
||||
{
|
||||
apiKeyAuth: [],
|
||||
bearerAuth: []
|
||||
}
|
||||
],
|
||||
params: z.object({
|
||||
workspaceId: z.string().trim()
|
||||
}),
|
||||
@@ -31,6 +38,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
const secretSnapshots = await server.services.snapshot.listSnapshots({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.params.workspaceId,
|
||||
...req.query
|
||||
});
|
||||
@@ -60,6 +68,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
const count = await server.services.snapshot.projectSecretSnapshotCount({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.params.workspaceId,
|
||||
environment: req.query.environment,
|
||||
path: req.query.path
|
||||
@@ -72,6 +81,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
method: "GET",
|
||||
url: "/:workspaceId/audit-logs",
|
||||
schema: {
|
||||
description: "Return audit logs",
|
||||
security: [
|
||||
{
|
||||
bearerAuth: [],
|
||||
apiKeyAuth: []
|
||||
}
|
||||
],
|
||||
params: z.object({
|
||||
workspaceId: z.string().trim()
|
||||
}),
|
||||
@@ -112,6 +128,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
handler: async (req) => {
|
||||
const auditLogs = await server.services.auditLog.listProjectAuditLogs({
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.params.workspaceId,
|
||||
...req.query,
|
||||
auditLogActor: req.query.actor,
|
||||
|
@@ -1,3 +1,11 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
// All the any rules are disabled because passport typesense with fastify is really poor
|
||||
|
||||
import { Authenticator } from "@fastify/passport";
|
||||
import fastifySession from "@fastify/session";
|
||||
import { MultiSamlStrategy } from "@node-saml/passport-saml";
|
||||
@@ -5,13 +13,12 @@ import { FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { SamlConfigsSchema } from "@app/db/schemas";
|
||||
import { SamlProviders } from "@app/ee/services/saml-config/saml-config-types";
|
||||
import { SamlProviders, TGetSamlCfgDTO } from "@app/ee/services/saml-config/saml-config-types";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { getServerCfg } from "@app/services/super-admin/super-admin-service";
|
||||
|
||||
type TSAMLConfig = {
|
||||
callbackUrl: string;
|
||||
@@ -20,6 +27,7 @@ type TSAMLConfig = {
|
||||
cert: string;
|
||||
audience: string;
|
||||
wantAuthnResponseSigned?: boolean;
|
||||
disableRequestedAuthnContext?: boolean;
|
||||
};
|
||||
|
||||
export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
@@ -33,19 +41,33 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
new MultiSamlStrategy(
|
||||
{
|
||||
passReqToCallback: true,
|
||||
// eslint-disable-next-line
|
||||
getSamlOptions: async (req, done) => {
|
||||
try {
|
||||
const { ssoIdentifier } = req.params;
|
||||
if (!ssoIdentifier) throw new BadRequestError({ message: "Missing sso identitier" });
|
||||
const { samlConfigId, orgSlug } = req.params;
|
||||
|
||||
const ssoConfig = await server.services.saml.getSaml({
|
||||
type: "ssoId",
|
||||
id: ssoIdentifier
|
||||
});
|
||||
if (!ssoConfig) throw new BadRequestError({ message: "SSO config not found" });
|
||||
let ssoLookupDetails: TGetSamlCfgDTO;
|
||||
|
||||
if (orgSlug) {
|
||||
ssoLookupDetails = {
|
||||
type: "orgSlug",
|
||||
orgSlug
|
||||
};
|
||||
} else if (samlConfigId) {
|
||||
ssoLookupDetails = {
|
||||
type: "ssoId",
|
||||
id: samlConfigId
|
||||
};
|
||||
} else {
|
||||
throw new BadRequestError({ message: "Missing sso identitier or org slug" });
|
||||
}
|
||||
|
||||
const ssoConfig = await server.services.saml.getSaml(ssoLookupDetails);
|
||||
if (!ssoConfig || !ssoConfig.isActive)
|
||||
throw new BadRequestError({ message: "Failed to authenticate with SAML SSO" });
|
||||
|
||||
const samlConfig: TSAMLConfig = {
|
||||
callbackUrl: `${appCfg.SITE_URL}/api/v1/sso/saml2/${ssoIdentifier}`,
|
||||
callbackUrl: `${appCfg.SITE_URL}/api/v1/sso/saml2/${ssoConfig.id}`,
|
||||
entryPoint: ssoConfig.entryPoint,
|
||||
issuer: ssoConfig.issuer,
|
||||
cert: ssoConfig.cert,
|
||||
@@ -55,7 +77,8 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
samlConfig.wantAuthnResponseSigned = false;
|
||||
}
|
||||
if (ssoConfig.authProvider === SamlProviders.AZURE_SAML) {
|
||||
if (req.body.RelayState && JSON.parse(req.body.RelayState).spIntiaited) {
|
||||
samlConfig.disableRequestedAuthnContext = true;
|
||||
if (req.body?.RelayState && JSON.parse(req.body.RelayState).spInitiated) {
|
||||
samlConfig.audience = `spn:${ssoConfig.issuer}`;
|
||||
}
|
||||
}
|
||||
@@ -67,14 +90,14 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line
|
||||
async (req, profile, cb) => {
|
||||
try {
|
||||
const serverCfg = getServerCfg();
|
||||
if (!profile) throw new BadRequestError({ message: "Missing profile" });
|
||||
const { firstName } = profile;
|
||||
const email = profile?.email ?? profile?.emailAddress as string // emailRippling is added because in Rippling the field `email` reserved
|
||||
|
||||
if (!email || !firstName){
|
||||
const email = profile?.email ?? (profile?.emailAddress as string); // emailRippling is added because in Rippling the field `email` reserved
|
||||
|
||||
if (!email || !firstName) {
|
||||
throw new BadRequestError({ message: "Invalid request. Missing email or first name" });
|
||||
}
|
||||
|
||||
@@ -82,7 +105,6 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
email,
|
||||
firstName: profile.firstName as string,
|
||||
lastName: profile.lastName as string,
|
||||
isSignupAllowed: Boolean(serverCfg.allowSignUp),
|
||||
relayState: (req.body as { RelayState?: string }).RelayState,
|
||||
authProvider: (req as unknown as FastifyRequest).ssoConfig?.authProvider as string,
|
||||
orgId: (req as unknown as FastifyRequest).ssoConfig?.orgId as string
|
||||
@@ -98,11 +120,11 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
);
|
||||
|
||||
server.route({
|
||||
url: "/redirect/saml2/:ssoIdentifier",
|
||||
url: "/redirect/saml2/organizations/:orgSlug",
|
||||
method: "GET",
|
||||
schema: {
|
||||
params: z.object({
|
||||
ssoIdentifier: z.string().trim()
|
||||
orgSlug: z.string().trim()
|
||||
}),
|
||||
querystring: z.object({
|
||||
callback_port: z.string().optional()
|
||||
@@ -124,11 +146,37 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
});
|
||||
|
||||
server.route({
|
||||
url: "/saml2/:ssoIdentifier",
|
||||
url: "/redirect/saml2/:samlConfigId",
|
||||
method: "GET",
|
||||
schema: {
|
||||
params: z.object({
|
||||
samlConfigId: z.string().trim()
|
||||
}),
|
||||
querystring: z.object({
|
||||
callback_port: z.string().optional()
|
||||
})
|
||||
},
|
||||
preValidation: (req, res) =>
|
||||
(
|
||||
passport.authenticate("saml", {
|
||||
failureRedirect: "/",
|
||||
additionalParams: {
|
||||
RelayState: JSON.stringify({
|
||||
spInitiated: true,
|
||||
callbackPort: req.query.callback_port ?? ""
|
||||
})
|
||||
}
|
||||
} as any) as any
|
||||
)(req, res),
|
||||
handler: () => {}
|
||||
});
|
||||
|
||||
server.route({
|
||||
url: "/saml2/:samlConfigId",
|
||||
method: "POST",
|
||||
schema: {
|
||||
params: z.object({
|
||||
ssoIdentifier: z.string().trim()
|
||||
samlConfigId: z.string().trim()
|
||||
})
|
||||
},
|
||||
preValidation: passport.authenticate("saml", {
|
||||
@@ -140,15 +188,11 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
handler: (req, res) => {
|
||||
if (req.passportUser.isUserCompleted) {
|
||||
return res.redirect(
|
||||
`${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent(
|
||||
req.passportUser.providerAuthToken
|
||||
)}`
|
||||
`${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}`
|
||||
);
|
||||
}
|
||||
return res.redirect(
|
||||
`${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent(
|
||||
req.passportUser.providerAuthToken
|
||||
)}`
|
||||
`${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}`
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -171,7 +215,8 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
isActive: z.boolean(),
|
||||
entryPoint: z.string(),
|
||||
issuer: z.string(),
|
||||
cert: z.string()
|
||||
cert: z.string(),
|
||||
lastUsed: z.date().nullable().optional()
|
||||
})
|
||||
.optional()
|
||||
}
|
||||
@@ -180,6 +225,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
const saml = await server.services.saml.getSaml({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.query.organizationId,
|
||||
type: "org"
|
||||
});
|
||||
@@ -208,6 +254,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
const saml = await server.services.saml.createSamlCfg({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.body.organizationId,
|
||||
...req.body
|
||||
});
|
||||
@@ -238,6 +285,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
|
||||
const saml = await server.services.saml.updateSamlCfg({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.body.organizationId,
|
||||
...req.body
|
||||
});
|
||||
|
@@ -34,6 +34,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
||||
const approval = await server.services.secretApprovalPolicy.createSecretApprovalPolicy({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.body.workspaceId,
|
||||
...req.body,
|
||||
name: req.body.name ?? `${req.body.environment}-${nanoid(3)}`
|
||||
@@ -71,6 +72,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
||||
const approval = await server.services.secretApprovalPolicy.updateSecretApprovalPolicy({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.body,
|
||||
secretPolicyId: req.params.sapId
|
||||
});
|
||||
@@ -96,6 +98,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
||||
const approval = await server.services.secretApprovalPolicy.deleteSecretApprovalPolicy({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
secretPolicyId: req.params.sapId
|
||||
});
|
||||
return { approval };
|
||||
@@ -111,7 +114,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
approvals: sapPubSchema.merge(z.object({approvers:z.string().array()})).array()
|
||||
approvals: sapPubSchema.merge(z.object({ approvers: z.string().array() })).array()
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -120,6 +123,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
||||
const approvals = await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.query.workspaceId
|
||||
});
|
||||
return { approvals };
|
||||
@@ -137,7 +141,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
policy: sapPubSchema.merge(z.object({approvers:z.string().array()})).optional()
|
||||
policy: sapPubSchema.merge(z.object({ approvers: z.string().array() })).optional()
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -146,6 +150,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
||||
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.query.workspaceId,
|
||||
...req.query
|
||||
});
|
||||
|
@@ -9,10 +9,7 @@ import {
|
||||
SecretVersionsSchema
|
||||
} from "@app/db/schemas";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import {
|
||||
ApprovalStatus,
|
||||
RequestState
|
||||
} from "@app/ee/services/secret-approval-request/secret-approval-request-types";
|
||||
import { ApprovalStatus, RequestState } from "@app/ee/services/secret-approval-request/secret-approval-request-types";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
@@ -41,9 +38,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
approvers: z.string().array(),
|
||||
secretPath: z.string().optional().nullable()
|
||||
}),
|
||||
commits: z
|
||||
.object({ op: z.string(), secretId: z.string().nullable().optional() })
|
||||
.array(),
|
||||
commits: z.object({ op: z.string(), secretId: z.string().nullable().optional() }).array(),
|
||||
environment: z.string(),
|
||||
reviewers: z.object({ member: z.string(), status: z.string() }).array(),
|
||||
approvers: z.string().array()
|
||||
@@ -57,6 +52,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
const approvals = await server.services.secretApprovalRequest.getSecretApprovals({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.query,
|
||||
projectId: req.query.workspaceId
|
||||
});
|
||||
@@ -85,6 +81,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
const approvals = await server.services.secretApprovalRequest.requestCount({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.query.workspaceId
|
||||
});
|
||||
return { approvals };
|
||||
@@ -109,6 +106,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
const { approval } = await server.services.secretApprovalRequest.mergeSecretApprovalRequest({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
approvalId: req.params.id
|
||||
});
|
||||
return { approval };
|
||||
@@ -136,6 +134,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
const review = await server.services.secretApprovalRequest.reviewApproval({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
approvalId: req.params.id,
|
||||
status: req.body.status
|
||||
});
|
||||
@@ -164,6 +163,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
const approval = await server.services.secretApprovalRequest.updateApprovalStatus({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
approvalId: req.params.id,
|
||||
status: req.body.status
|
||||
});
|
||||
@@ -174,11 +174,12 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: isClosing ? EventType.SECRET_APPROVAL_CLOSED : EventType.SECRET_APPROVAL_REOPENED,
|
||||
// eslint-disable-next-line
|
||||
metadata: {
|
||||
[isClosing ? ("closedBy" as const) : ("reopenedBy" as const)]:
|
||||
approval.statusChangeBy as string,
|
||||
[isClosing ? ("closedBy" as const) : ("reopenedBy" as const)]: approval.statusChangeBy as string,
|
||||
secretApprovalRequestId: approval.id,
|
||||
secretApprovalRequestSlug: approval.slug
|
||||
// eslint-disable-next-line
|
||||
} as any
|
||||
// akhilmhdh: had to apply any to avoid ts issue with this
|
||||
}
|
||||
@@ -270,6 +271,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
const approval = await server.services.secretApprovalRequest.getSecretApprovalDetails({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.params.id
|
||||
});
|
||||
return { approval };
|
||||
|
@@ -30,6 +30,7 @@ export const registerSecretRotationProviderRouter = async (server: FastifyZodPro
|
||||
const providers = await server.services.secretRotation.getProviderTemplates({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.params.workspaceId
|
||||
});
|
||||
return providers;
|
||||
|
@@ -40,6 +40,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
|
||||
const secretRotation = await server.services.secretRotation.createRotation({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.body,
|
||||
projectId: req.body.workspaceId
|
||||
});
|
||||
@@ -73,6 +74,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
|
||||
const secretRotation = await server.services.secretRotation.restartById({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
rotationId: req.body.id
|
||||
});
|
||||
return { secretRotation };
|
||||
@@ -123,6 +125,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
|
||||
const secretRotations = await server.services.secretRotation.getByProjectId({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.query.workspaceId
|
||||
});
|
||||
return { secretRotations };
|
||||
@@ -155,6 +158,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
|
||||
const secretRotation = await server.services.secretRotation.deleteById({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
rotationId: req.params.id
|
||||
});
|
||||
return { secretRotation };
|
||||
|
@@ -22,6 +22,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
|
||||
const session = await server.services.secretScanning.createInstallationSession({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.body.organizationId
|
||||
});
|
||||
return session;
|
||||
@@ -45,6 +46,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
|
||||
const { installatedApp } = await server.services.secretScanning.linkInstallationToOrg({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.body
|
||||
});
|
||||
return installatedApp;
|
||||
@@ -62,12 +64,12 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const appInstallationCompleted =
|
||||
await server.services.secretScanning.getOrgInstallationStatus({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
const appInstallationCompleted = await server.services.secretScanning.getOrgInstallationStatus({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return { appInstallationCompleted };
|
||||
}
|
||||
});
|
||||
@@ -86,6 +88,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
|
||||
const { risks } = await server.services.secretScanning.getRisksByOrg({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId
|
||||
});
|
||||
return { risks };
|
||||
@@ -107,6 +110,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
|
||||
const { risk } = await server.services.secretScanning.updateRiskStatus({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.organizationId,
|
||||
riskId: req.params.riskId,
|
||||
...req.body
|
||||
|
@@ -27,6 +27,7 @@ export const registerSecretVersionRouter = async (server: FastifyZodProvider) =>
|
||||
const secretVersions = await server.services.secret.getSecretVersions({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
limit: req.query.limit,
|
||||
offset: req.query.offset,
|
||||
secretId: req.params.secretId
|
||||
|
@@ -46,6 +46,7 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
|
||||
const secretSnapshot = await server.services.snapshot.getSnapshotData({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.params.secretSnapshotId
|
||||
});
|
||||
return { secretSnapshot };
|
||||
@@ -56,6 +57,13 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
|
||||
method: "POST",
|
||||
url: "/:secretSnapshotId/rollback",
|
||||
schema: {
|
||||
description: "Roll back project secrets to those captured in a secret snapshot version.",
|
||||
security: [
|
||||
{
|
||||
apiKeyAuth: [],
|
||||
bearerAuth: []
|
||||
}
|
||||
],
|
||||
params: z.object({
|
||||
secretSnapshotId: z.string().trim()
|
||||
}),
|
||||
@@ -70,6 +78,7 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
|
||||
const secretSnapshot = await server.services.snapshot.rollbackSnapshot({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.params.secretSnapshotId
|
||||
});
|
||||
return { secretSnapshot };
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user