Compare commits

...

129 Commits

Author SHA1 Message Date
37169d0e20 Update secret-approval-request-service.ts 2024-03-15 17:05:07 +01:00
ca39901601 Fix: Select org when using init 2024-03-15 17:03:21 +01:00
44cae9d52e add small helpful comment 2024-03-15 17:03:21 +01:00
6b81eb5aa6 Feat: CLI support for scoped JWT tokens 2024-03-15 17:03:21 +01:00
be6012d03f Feat: Scoped JWT to organization, Add authMethod to services 2024-03-15 17:03:21 +01:00
dff0318cc2 Merge pull request #1556 from Infisical/daniel/org-scoped-jwt
Feat: Scoped JWT tokens
2024-03-15 16:57:32 +01:00
eba7b6a3ce Fix: Email signup and switching organization 2024-03-15 16:53:01 +01:00
ff44807605 Fix: Rebase error 2024-03-15 16:53:01 +01:00
bfb4e1ac14 parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345579 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345572 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345563 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345551 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345540 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345533 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345529 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345522 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345503 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345496 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345489 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345357 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345061 +0100

parent 10a292bca563efbe5972d7ffc33ee4b96a868e42
author Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1709970985 +0100
committer Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> 1710345029 +0100

Feat: Org Scoped JWT Tokens

Add link button

Fix: Avoid invalidating all queries on logout to prevent UI glitch

Update _app.tsx

Feat: Scoped JWT to organization, add authMethod to request

Feat: Scoped JWT to organization, Add authMethod to services

Feat: Scoped JWT to organization, require organization on all requests by default on JWT requests

Update index.ts

Feat: Scoped JWT to organization

Chore: Move SAML org check to permission service

Feat: Scoped JWT to organization, actorAuthMethod to create project DTO

Fix: Invalidate after selecting organization

Chore: Optional 'invalidate' option for create org hook

Fix: Creating dummy workspaces

Fix: Select org after creation

Feat: Org Scoped JWT's, remove inline service

Fix: ActorType unresolved

Fix: Better type checking

Feat: Org scoped JWT's

Fix: Add missing actor org ID

Fix: Add missing actor org ID

Fix: Return access token

Update auth-type.ts

Fix: Add actor org ID

Chore: Remove unused code

Fix: Add missing actor org ID to permission check

Fix: Add missing actor auth method to permission checks

Fix: Include actor org id

Chore: Remove redundant lint comment

Fix: Add missing actorOrgId to service handlers

Fix: Rebase fixes

Fix: Rebase LDAP fixes

Chore: Export Cli login interface

Update queries.tsx

Feat: Org scoped JWT's CLI support

Update inject-permission.ts

Fix: MFA

Remove log

Fix: Admin signup, select organization

Improvement: Use select organization hook

Update permission-service.ts

Fix: Make API keys compatible with old endpoints

Update inject-permission.ts

Chore: Better error messages

Update index.ts

Fix: Signup not redirecting to backup PDF page due to error

Select org on signup

Type improvements

Chore: Removed code that spans out of scope

Fix: Better types

Chore: Move comment

Chore: Change order

Fix: Code readability

Fix: Code readability

Update auth-token-service.ts

Chore: Remove old comments

Fix: Cleanup

Chore: Minor code cleanup

Fix: Add auth method and organization ID to test JWT

Fix: Get org ID in getOrgIdentityPermission DAL operation
2024-03-15 16:53:01 +01:00
5c2d61432e Fix: Get org ID in getOrgIdentityPermission DAL operation 2024-03-15 16:53:01 +01:00
7ea0730621 Fix: Add auth method and organization ID to test JWT 2024-03-15 16:53:01 +01:00
d9d5ba055e Chore: Minor code cleanup 2024-03-15 16:53:01 +01:00
8d318881b8 Fix: Cleanup 2024-03-15 16:53:01 +01:00
2b7d1a2e36 Chore: Remove old comments 2024-03-15 16:53:01 +01:00
5d3b04be29 Update auth-token-service.ts 2024-03-15 16:53:01 +01:00
42f10b2bfd Fix: Code readability 2024-03-15 16:53:01 +01:00
80470e96e5 Fix: Code readability 2024-03-15 16:53:01 +01:00
8cc5c766e3 Chore: Change order 2024-03-15 16:53:01 +01:00
a1fe0e9676 Chore: Move comment 2024-03-15 16:53:01 +01:00
e1bbe17526 Fix: Better types 2024-03-15 16:53:01 +01:00
9475755d40 Chore: Removed code that spans out of scope 2024-03-15 16:53:01 +01:00
30ba304382 Type improvements 2024-03-15 16:53:01 +01:00
974e6e56b4 Select org on signup 2024-03-15 16:53:01 +01:00
b7bbc513e5 Fix: Signup not redirecting to backup PDF page due to error 2024-03-15 16:53:01 +01:00
f6956130bb Update index.ts 2024-03-15 16:53:01 +01:00
01f373798f Chore: Better error messages 2024-03-15 16:53:01 +01:00
fe82231574 Update inject-permission.ts 2024-03-15 16:53:01 +01:00
d6eee8a7b3 Fix: Re-add API key support 2024-03-15 16:53:01 +01:00
88827d5060 Fix: Make API keys compatible with old endpoints 2024-03-15 16:53:01 +01:00
9b0299ff9c Update permission-service.ts 2024-03-15 16:53:01 +01:00
f9e59cf35e Update permission-service.ts 2024-03-15 16:53:01 +01:00
afc92d6ec0 Improvement: Use select organization hook 2024-03-15 16:53:01 +01:00
74479fb950 Fix: member invites, select org 2024-03-15 16:53:00 +01:00
06eef21e1c Fix: Admin signup, select organization 2024-03-15 16:53:00 +01:00
e687de0a97 Fix: Org scoped JWT's, MFA support 2024-03-15 16:53:00 +01:00
7192abfc4c Remove log 2024-03-15 16:53:00 +01:00
c7744ca371 Fix: MFA 2024-03-15 16:53:00 +01:00
ed45daf34b Update inject-permission.ts 2024-03-15 16:53:00 +01:00
3baeddc426 Feat: Org scoped JWT's CLI support 2024-03-15 16:53:00 +01:00
1e0995e5fc Feat: Org scoped JWT's CLI support 2024-03-15 16:53:00 +01:00
9c724ff064 Feat: Org scoped JWT's CLI support 2024-03-15 16:53:00 +01:00
5950369101 Feat: Org scoped JWT's, CLI support 2024-03-15 16:53:00 +01:00
add15bacd3 Update queries.tsx 2024-03-15 16:53:00 +01:00
a6aa370349 Chore: Export Cli login interface 2024-03-15 16:53:00 +01:00
a50391889a Fix: Rebase LDAP fixes 2024-03-15 16:53:00 +01:00
fb4b35fa09 Fix: Rebase fixes 2024-03-15 16:53:00 +01:00
4dafe14d90 Fix: Better type checking 2024-03-15 16:53:00 +01:00
8c1745f73e Fix: Add missing actorOrgId to service handlers 2024-03-15 16:52:52 +01:00
c829dcf4a3 Fix: Don't allow org select screen when token already has an organization ID 2024-03-15 16:52:52 +01:00
973bfe2407 Chore: Remove redundant lint comment 2024-03-15 16:52:52 +01:00
e2a3dc4a0a Fix: Include actor org id 2024-03-15 16:52:52 +01:00
f4df97b968 Fix: Add missing actor auth method to permission checks 2024-03-15 16:52:52 +01:00
278666ca96 Fix: Add missing actor org ID to permission check 2024-03-15 16:52:52 +01:00
e2f72de2d8 Chore: Remove unused code 2024-03-15 16:52:52 +01:00
a24b8a858c Fix: Add actor org ID 2024-03-15 16:52:52 +01:00
2b7f7e82c7 Update auth-type.ts 2024-03-15 16:52:52 +01:00
9b0cea23c7 Fix: Return access token 2024-03-15 16:52:52 +01:00
49f6d6f77b Fix: Add missing actor org ID 2024-03-15 16:52:52 +01:00
611704d0d4 Fix: Add missing actor org ID 2024-03-15 16:52:52 +01:00
e6143dc21f Feat: Org scoped JWT's 2024-03-15 16:52:52 +01:00
28caafa248 Fix: Better type checking 2024-03-15 16:52:52 +01:00
41df9880ce Fix: ActorType unresolved 2024-03-15 16:52:52 +01:00
c3ea73e461 Feat: Org Scoped JWT's, service handler 2024-03-15 16:52:52 +01:00
19841bbf7d Feat: Org Scoped JWT's, remove inline service 2024-03-15 16:52:51 +01:00
748ffb4008 Fix: Select org after creation 2024-03-15 16:52:51 +01:00
75338f7c81 Fix: Formatting and support for selecting org (line 109-122) 2024-03-15 16:52:51 +01:00
f1fe4f5b5a Fix: Creating dummy workspaces 2024-03-15 16:52:51 +01:00
53f83b6883 Fix: Selecting SAML enforced organization 2024-03-15 16:52:51 +01:00
67e45c086f Chore: Optional 'invalidate' option for create org hook 2024-03-15 16:52:51 +01:00
7bf57e6d46 Fix: Invalidate after selecting organization 2024-03-15 16:52:51 +01:00
a7d62848f9 Fix: Creating dummy workspaces 2024-03-15 16:52:51 +01:00
9a6d0d2048 Feat: Scoped JWT to organization, actorAuthMethod to create project DTO 2024-03-15 16:52:51 +01:00
5bb7e9163a Feat: Scoped JWT to organization, add actorAuthMethod to DTO's 2024-03-15 16:52:51 +01:00
41af790073 Feat: Scoped JWT to organization, add actorAuthMethod to services 2024-03-15 16:52:51 +01:00
3e0d4ce6cf Feat: Scoped JWT to organization, add actorAuthMethod to services 2024-03-15 16:52:51 +01:00
0d22320d61 Feat: Scoped JWT to organization 2024-03-15 16:52:51 +01:00
fafdff7de1 Chore: Move SAML org check to permission service 2024-03-15 16:52:51 +01:00
bbe245477b Feat: Scoped JWT to organization 2024-03-15 16:52:51 +01:00
ea9659ba64 Update index.ts 2024-03-15 16:52:51 +01:00
4246a07c1a Feat: Scoped JWT to organization, require organization on all requests by default on JWT requests 2024-03-15 16:52:51 +01:00
d410b85fe1 Feat: Scoped JWT to organization, add actorAuthMethod to Permission types 2024-03-15 16:52:51 +01:00
d1adc4cfad Feat: Scoped JWT to organization, Add actorAuthMethod to DTO 2024-03-15 16:52:51 +01:00
2e4a7c5e7f Feat: Scoped JWT to organization 2024-03-15 16:52:51 +01:00
bf05366c5f Feat: Scoped JWT to organization, Add authMethod to services 2024-03-15 16:52:51 +01:00
ba51ede553 Feat: Scoped JWT to organization, SAML helper functions 2024-03-15 16:52:51 +01:00
4d1b0790d4 Feat: Scoped JWT to organization, add authMethod to request 2024-03-15 16:52:51 +01:00
76dd1d9fca Feat: Scoped JWT to organization, include authMethod on all service calls 2024-03-15 16:52:51 +01:00
2c7237411e Feat: Navigate to select org 2024-03-15 16:52:36 +01:00
78f9981139 Formatting and navigating to select org 2024-03-15 16:52:36 +01:00
fcd810ee07 Navigate to select org instead of dashboard 2024-03-15 16:52:36 +01:00
e4084facaa Update _app.tsx 2024-03-15 16:52:36 +01:00
ebbee48adf Feat: Select organization on login 2024-03-15 16:52:36 +01:00
5b09212f27 Fix: Avoid invalidating all queries on logout to prevent UI glitch 2024-03-15 16:52:36 +01:00
17a458cc26 Add link button 2024-03-15 16:52:36 +01:00
96f381d61b Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
df39add05a Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
da50807919 Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
8652e09546 Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
6826f9058e Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
5d932c021f Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
c74566cefd Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
9daf73d71c Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
2ca3e05f37 Feat: Org Scoped JWT Tokens 2024-03-15 16:52:36 +01:00
ebc03c20ce Fix: Removed legacy create project code 2024-03-15 16:47:56 +01:00
29cc94f756 Update project-types.ts 2024-03-13 09:17:29 +01:00
69e8b3d242 Fix: Rebase errors 2024-03-13 09:17:29 +01:00
5d18abc67f Update inject-identity.ts 2024-03-13 09:17:29 +01:00
233e12189a Fix: Remove orgId from service token 2024-03-13 09:17:29 +01:00
cbdbc8790e Fix: Remove org ID from JWT 2024-03-13 09:17:29 +01:00
7975e86161 feat: fix project query by slug (now accepts an org ID) 2024-03-13 09:17:29 +01:00
d767995b45 feat: standardize org ID's on auth requests 2024-03-13 09:17:29 +01:00
98762e53f1 Slug projects and filter type 2024-03-13 09:17:29 +01:00
acee2314f4 Draft 2024-03-13 09:17:29 +01:00
2f23381a80 Fix: Change org ID to org slug 2024-03-13 09:17:29 +01:00
2d5006eeb1 Fix: Change org ID to org slug 2024-03-13 09:17:29 +01:00
82083f5df8 Fix: Non-existant variable being passed to Posthog 2024-03-13 09:17:29 +01:00
ddc4cf5a74 Feat: List secrets by project slug 2024-03-13 09:17:29 +01:00
ff4b7ba52e Update inject-identity.ts 2024-03-13 09:17:29 +01:00
e2bf3546a0 Update inject-identity.ts 2024-03-13 09:17:29 +01:00
da710c65db Fix: Remove orgId from service token 2024-03-13 09:17:29 +01:00
f3ca2c2ba4 Update index.ts 2024-03-13 09:17:29 +01:00
e3aa23a317 Feat: Create project via org slug instead of org ID 2024-03-13 09:17:29 +01:00
815a497ac9 nit: update error message 2024-03-13 09:17:29 +01:00
0134ffde5e Fix: Remove org ID from JWT 2024-03-13 09:17:29 +01:00
48444b4df9 feat: fix project query by slug (now accepts an org ID) 2024-03-13 09:17:29 +01:00
d0a61ffdba feat: standardize org ID's on auth requests 2024-03-13 09:17:29 +01:00
f6dbce3603 Remove API key auth mode 2024-03-13 09:17:29 +01:00
b09398ac75 Slug projects and filter type 2024-03-13 09:17:29 +01:00
7ef22b2715 Draft 2024-03-13 09:17:29 +01:00
126 changed files with 3156 additions and 947 deletions

View File

@ -10,7 +10,7 @@ import { seedData1 } from "@app/db/seed-data";
import { initEnvConfig } from "@app/lib/config/env"; import { initEnvConfig } from "@app/lib/config/env";
import { initLogger } from "@app/lib/logger"; import { initLogger } from "@app/lib/logger";
import { main } from "@app/server/app"; import { main } from "@app/server/app";
import { AuthTokenType } from "@app/services/auth/auth-type"; import { AuthMethod, AuthTokenType } from "@app/services/auth/auth-type";
import { mockQueue } from "./mocks/queue"; import { mockQueue } from "./mocks/queue";
import { mockSmtpServer } from "./mocks/smtp"; import { mockSmtpServer } from "./mocks/smtp";
@ -52,6 +52,8 @@ export default {
authTokenType: AuthTokenType.ACCESS_TOKEN, authTokenType: AuthTokenType.ACCESS_TOKEN,
userId: seedData1.id, userId: seedData1.id,
tokenVersionId: seedData1.token.id, tokenVersionId: seedData1.token.id,
authMethod: AuthMethod.EMAIL,
organizationId: seedData1.organization.id,
accessVersion: 1 accessVersion: 1
}, },
cfg.AUTH_SECRET, cfg.AUTH_SECRET,

View File

@ -19,7 +19,7 @@ import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service";
import { TAuthLoginFactory } from "@app/services/auth/auth-login-service"; import { TAuthLoginFactory } from "@app/services/auth/auth-login-service";
import { TAuthPasswordFactory } from "@app/services/auth/auth-password-service"; import { TAuthPasswordFactory } from "@app/services/auth/auth-password-service";
import { TAuthSignupFactory } from "@app/services/auth/auth-signup-service"; import { TAuthSignupFactory } from "@app/services/auth/auth-signup-service";
import { ActorType } from "@app/services/auth/auth-type"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
import { TIdentityServiceFactory } from "@app/services/identity/identity-service"; import { TIdentityServiceFactory } from "@app/services/identity/identity-service";
import { TIdentityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service"; import { TIdentityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service";
@ -59,6 +59,7 @@ declare module "fastify" {
// identity injection. depending on which kinda of token the information is filled in auth // identity injection. depending on which kinda of token the information is filled in auth
auth: TAuthMode; auth: TAuthMode;
permission: { permission: {
authMethod: ActorAuthMethod;
type: ActorType; type: ActorType;
id: string; id: string;
orgId?: string; orgId?: string;

View File

@ -122,6 +122,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.query.organizationId, orgId: req.query.organizationId,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });
return ldap; return ldap;
@ -151,6 +152,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.body.organizationId, orgId: req.body.organizationId,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body ...req.body
}); });
@ -184,6 +186,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.body.organizationId, orgId: req.body.organizationId,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body ...req.body
}); });

View File

@ -24,6 +24,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId, orgId: req.params.organizationId,
actorAuthMethod: req.permission.authMethod,
billingCycle: req.query.billingCycle billingCycle: req.query.billingCycle
}); });
return data; return data;
@ -45,6 +46,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return { plan }; return { plan };
@ -66,6 +68,8 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
const data = await server.services.license.getOrgPlan({ const data = await server.services.license.getOrgPlan({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return data; return data;
@ -89,6 +93,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId, orgId: req.params.organizationId,
actorAuthMethod: req.permission.authMethod,
success_url: req.body.success_url success_url: req.body.success_url
}); });
return data; return data;
@ -110,6 +115,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return data; return data;
@ -131,6 +137,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return data; return data;
@ -152,6 +159,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return data; return data;
@ -173,6 +181,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return data; return data;
@ -198,6 +207,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId, orgId: req.params.organizationId,
name: req.body.name, name: req.body.name,
email: req.body.email email: req.body.email
@ -221,6 +231,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return data; return data;
@ -246,6 +257,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId, orgId: req.params.organizationId,
success_url: req.body.success_url, success_url: req.body.success_url,
cancel_url: req.body.cancel_url cancel_url: req.body.cancel_url
@ -271,6 +283,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
const data = await server.services.license.delOrgPmtMethods({ const data = await server.services.license.delOrgPmtMethods({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId, orgId: req.params.organizationId,
pmtMethodId: req.params.pmtMethodId pmtMethodId: req.params.pmtMethodId
@ -295,6 +308,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
const data = await server.services.license.getOrgTaxIds({ const data = await server.services.license.getOrgTaxIds({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
@ -322,6 +336,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
const data = await server.services.license.addOrgTaxId({ const data = await server.services.license.addOrgTaxId({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId, orgId: req.params.organizationId,
type: req.body.type, type: req.body.type,
@ -348,6 +363,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
const data = await server.services.license.delOrgTaxId({ const data = await server.services.license.delOrgTaxId({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId, orgId: req.params.organizationId,
taxId: req.params.taxId taxId: req.params.taxId
@ -373,7 +389,8 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId orgId: req.params.organizationId,
actorAuthMethod: req.permission.authMethod
}); });
return data; return data;
} }
@ -396,6 +413,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
return data; return data;

View File

@ -41,6 +41,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.body, req.body,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { role }; return { role };
@ -84,6 +85,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
req.params.organizationId, req.params.organizationId,
req.params.roleId, req.params.roleId,
req.body, req.body,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { role }; return { role };
@ -110,6 +112,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.params.roleId, req.params.roleId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { role }; return { role };
@ -138,6 +141,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
const roles = await server.services.orgRole.listRoles( const roles = await server.services.orgRole.listRoles(
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { data: { roles } }; return { data: { roles } };
@ -163,6 +167,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
const { permissions, membership } = await server.services.orgRole.getUserPermission( const { permissions, membership } = await server.services.orgRole.getUserPermission(
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { permissions, membership }; return { permissions, membership };

View File

@ -31,6 +31,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
req.permission.id, req.permission.id,
req.params.projectId, req.params.projectId,
req.body, req.body,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { role }; return { role };
@ -65,6 +66,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
req.params.projectId, req.params.projectId,
req.params.roleId, req.params.roleId,
req.body, req.body,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { role }; return { role };
@ -92,6 +94,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
req.permission.id, req.permission.id,
req.params.projectId, req.params.projectId,
req.params.roleId, req.params.roleId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { role }; return { role };
@ -121,6 +124,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
req.permission.type, req.permission.type,
req.permission.id, req.permission.id,
req.params.projectId, req.params.projectId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { data: { roles } }; return { data: { roles } };
@ -148,6 +152,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
const { permissions, membership } = await server.services.projectRole.getUserPermission( const { permissions, membership } = await server.services.projectRole.getUserPermission(
req.permission.id, req.permission.id,
req.params.projectId, req.params.projectId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { data: { permissions, membership } }; return { data: { permissions, membership } };

View File

@ -37,6 +37,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
handler: async (req) => { handler: async (req) => {
const secretSnapshots = await server.services.snapshot.listSnapshots({ const secretSnapshots = await server.services.snapshot.listSnapshots({
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
@ -68,6 +69,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
const count = await server.services.snapshot.projectSecretSnapshotCount({ const count = await server.services.snapshot.projectSecretSnapshotCount({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
environment: req.query.environment, environment: req.query.environment,
@ -129,6 +131,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
const auditLogs = await server.services.auditLog.listProjectAuditLogs({ const auditLogs = await server.services.auditLog.listProjectAuditLogs({
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
...req.query, ...req.query,
auditLogActor: req.query.actor, auditLogActor: req.query.actor,

View File

@ -231,6 +231,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.query.organizationId, orgId: req.query.organizationId,
type: "org" type: "org"
}); });
@ -259,6 +260,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
const saml = await server.services.saml.createSamlCfg({ const saml = await server.services.saml.createSamlCfg({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.body.organizationId, orgId: req.body.organizationId,
...req.body ...req.body
@ -290,6 +292,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
const saml = await server.services.saml.updateSamlCfg({ const saml = await server.services.saml.updateSamlCfg({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.body.organizationId, orgId: req.body.organizationId,
...req.body ...req.body

View File

@ -39,6 +39,7 @@ export const registerScimRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.body.organizationId, orgId: req.body.organizationId,
actorAuthMethod: req.permission.authMethod,
description: req.body.description, description: req.body.description,
ttlDays: req.body.ttlDays ttlDays: req.body.ttlDays
}); });
@ -65,6 +66,7 @@ export const registerScimRouter = async (server: FastifyZodProvider) => {
const scimTokens = await server.services.scim.listScimTokens({ const scimTokens = await server.services.scim.listScimTokens({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.query.organizationId orgId: req.query.organizationId
}); });
@ -92,6 +94,7 @@ export const registerScimRouter = async (server: FastifyZodProvider) => {
scimTokenId: req.params.scimTokenId, scimTokenId: req.params.scimTokenId,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });

View File

@ -34,6 +34,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
const approval = await server.services.secretApprovalPolicy.createSecretApprovalPolicy({ const approval = await server.services.secretApprovalPolicy.createSecretApprovalPolicy({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
...req.body, ...req.body,
@ -72,6 +73,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
const approval = await server.services.secretApprovalPolicy.updateSecretApprovalPolicy({ const approval = await server.services.secretApprovalPolicy.updateSecretApprovalPolicy({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
secretPolicyId: req.params.sapId secretPolicyId: req.params.sapId
@ -98,6 +100,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
const approval = await server.services.secretApprovalPolicy.deleteSecretApprovalPolicy({ const approval = await server.services.secretApprovalPolicy.deleteSecretApprovalPolicy({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPolicyId: req.params.sapId secretPolicyId: req.params.sapId
}); });
@ -123,6 +126,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
const approvals = await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({ const approvals = await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.query.workspaceId projectId: req.query.workspaceId
}); });
@ -150,6 +154,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({ const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.query.workspaceId, projectId: req.query.workspaceId,
...req.query ...req.query

View File

@ -52,6 +52,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
const approvals = await server.services.secretApprovalRequest.getSecretApprovals({ const approvals = await server.services.secretApprovalRequest.getSecretApprovals({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.query, ...req.query,
projectId: req.query.workspaceId projectId: req.query.workspaceId
@ -81,6 +82,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
const approvals = await server.services.secretApprovalRequest.requestCount({ const approvals = await server.services.secretApprovalRequest.requestCount({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.query.workspaceId projectId: req.query.workspaceId
}); });
@ -106,6 +108,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
const { approval } = await server.services.secretApprovalRequest.mergeSecretApprovalRequest({ const { approval } = await server.services.secretApprovalRequest.mergeSecretApprovalRequest({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
approvalId: req.params.id approvalId: req.params.id
}); });
@ -134,6 +137,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
const review = await server.services.secretApprovalRequest.reviewApproval({ const review = await server.services.secretApprovalRequest.reviewApproval({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
approvalId: req.params.id, approvalId: req.params.id,
status: req.body.status status: req.body.status
@ -163,6 +167,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
const approval = await server.services.secretApprovalRequest.updateApprovalStatus({ const approval = await server.services.secretApprovalRequest.updateApprovalStatus({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
approvalId: req.params.id, approvalId: req.params.id,
status: req.body.status status: req.body.status
@ -271,6 +276,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
const approval = await server.services.secretApprovalRequest.getSecretApprovalDetails({ const approval = await server.services.secretApprovalRequest.getSecretApprovalDetails({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.id id: req.params.id
}); });

View File

@ -30,6 +30,7 @@ export const registerSecretRotationProviderRouter = async (server: FastifyZodPro
const providers = await server.services.secretRotation.getProviderTemplates({ const providers = await server.services.secretRotation.getProviderTemplates({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId projectId: req.params.workspaceId
}); });

View File

@ -39,6 +39,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
handler: async (req) => { handler: async (req) => {
const secretRotation = await server.services.secretRotation.createRotation({ const secretRotation = await server.services.secretRotation.createRotation({
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
@ -74,6 +75,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
const secretRotation = await server.services.secretRotation.restartById({ const secretRotation = await server.services.secretRotation.restartById({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
rotationId: req.body.id rotationId: req.body.id
}); });
@ -125,6 +127,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
const secretRotations = await server.services.secretRotation.getByProjectId({ const secretRotations = await server.services.secretRotation.getByProjectId({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.query.workspaceId projectId: req.query.workspaceId
}); });
@ -158,6 +161,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
const secretRotation = await server.services.secretRotation.deleteById({ const secretRotation = await server.services.secretRotation.deleteById({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
rotationId: req.params.id rotationId: req.params.id
}); });

View File

@ -22,6 +22,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
const session = await server.services.secretScanning.createInstallationSession({ const session = await server.services.secretScanning.createInstallationSession({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.body.organizationId orgId: req.body.organizationId
}); });
@ -46,6 +47,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
const { installatedApp } = await server.services.secretScanning.linkInstallationToOrg({ const { installatedApp } = await server.services.secretScanning.linkInstallationToOrg({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body ...req.body
}); });
@ -67,6 +69,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
const appInstallationCompleted = await server.services.secretScanning.getOrgInstallationStatus({ const appInstallationCompleted = await server.services.secretScanning.getOrgInstallationStatus({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
@ -88,6 +91,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
const { risks } = await server.services.secretScanning.getRisksByOrg({ const { risks } = await server.services.secretScanning.getRisksByOrg({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
@ -110,6 +114,7 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
const { risk } = await server.services.secretScanning.updateRiskStatus({ const { risk } = await server.services.secretScanning.updateRiskStatus({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.organizationId, orgId: req.params.organizationId,
riskId: req.params.riskId, riskId: req.params.riskId,

View File

@ -27,6 +27,7 @@ export const registerSecretVersionRouter = async (server: FastifyZodProvider) =>
const secretVersions = await server.services.secret.getSecretVersions({ const secretVersions = await server.services.secret.getSecretVersions({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
limit: req.query.limit, limit: req.query.limit,
offset: req.query.offset, offset: req.query.offset,

View File

@ -46,6 +46,7 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
const secretSnapshot = await server.services.snapshot.getSnapshotData({ const secretSnapshot = await server.services.snapshot.getSnapshotData({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.secretSnapshotId id: req.params.secretSnapshotId
}); });
@ -78,6 +79,7 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
const secretSnapshot = await server.services.snapshot.rollbackSnapshot({ const secretSnapshot = await server.services.snapshot.rollbackSnapshot({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.secretSnapshotId id: req.params.secretSnapshotId
}); });

View File

@ -22,6 +22,7 @@ export const registerTrustedIpRouter = async (server: FastifyZodProvider) => {
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { handler: async (req) => {
const trustedIps = await server.services.trustedIp.listIpsByProjectId({ const trustedIps = await server.services.trustedIp.listIpsByProjectId({
actorAuthMethod: req.permission.authMethod,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
@ -52,6 +53,7 @@ export const registerTrustedIpRouter = async (server: FastifyZodProvider) => {
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { handler: async (req) => {
const { trustedIp, project } = await server.services.trustedIp.addProjectIp({ const { trustedIp, project } = await server.services.trustedIp.addProjectIp({
actorAuthMethod: req.permission.authMethod,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
@ -99,6 +101,7 @@ export const registerTrustedIpRouter = async (server: FastifyZodProvider) => {
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
trustedIpId: req.params.trustedIpId, trustedIpId: req.params.trustedIpId,
...req.body ...req.body
@ -140,6 +143,7 @@ export const registerTrustedIpRouter = async (server: FastifyZodProvider) => {
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
trustedIpId: req.params.trustedIpId trustedIpId: req.params.trustedIpId
}); });

View File

@ -31,10 +31,17 @@ export const auditLogServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
auditLogActor auditLogActor
}: TListProjectAuditLogDTO) => { }: TListProjectAuditLogDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs);
const auditLogs = await auditLogDAL.find({ const auditLogs = await auditLogDAL.find({
startDate, startDate,

View File

@ -55,6 +55,7 @@ export const ldapConfigServiceFactory = ({
actorId, actorId,
orgId, orgId,
actorOrgId, actorOrgId,
actorAuthMethod,
isActive, isActive,
url, url,
bindDN, bindDN,
@ -62,7 +63,7 @@ export const ldapConfigServiceFactory = ({
searchBase, searchBase,
caCert caCert
}: TCreateLdapCfgDTO) => { }: TCreateLdapCfgDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Ldap); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Ldap);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
@ -149,13 +150,14 @@ export const ldapConfigServiceFactory = ({
orgId, orgId,
actorOrgId, actorOrgId,
isActive, isActive,
actorAuthMethod,
url, url,
bindDN, bindDN,
bindPass, bindPass,
searchBase, searchBase,
caCert caCert
}: TUpdateLdapCfgDTO) => { }: TUpdateLdapCfgDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Ldap); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Ldap);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
@ -274,8 +276,14 @@ export const ldapConfigServiceFactory = ({
}; };
}; };
const getLdapCfgWithPermissionCheck = async ({ actor, actorId, orgId, actorOrgId }: TOrgPermission) => { const getLdapCfgWithPermissionCheck = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); actor,
actorId,
orgId,
actorAuthMethod,
actorOrgId
}: TOrgPermission) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Ldap); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Ldap);
return getLdapCfg({ return getLdapCfg({
orgId orgId

View File

@ -192,9 +192,10 @@ export const licenseServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
billingCycle billingCycle
}: TOrgPlansTableDTO) => { }: TOrgPlansTableDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const { data } = await licenseServerCloudApi.request.get( const { data } = await licenseServerCloudApi.request.get(
`/api/license-server/v1/cloud-products?billing-cycle=${billingCycle}` `/api/license-server/v1/cloud-products?billing-cycle=${billingCycle}`
@ -202,15 +203,22 @@ export const licenseServiceFactory = ({
return data; return data;
}; };
const getOrgPlan = async ({ orgId, actor, actorId, actorOrgId, projectId }: TOrgPlanDTO) => { const getOrgPlan = async ({ orgId, actor, actorId, actorOrgId, actorAuthMethod, projectId }: TOrgPlanDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const plan = await getPlan(orgId, projectId); const plan = await getPlan(orgId, projectId);
return plan; return plan;
}; };
const startOrgTrial = async ({ orgId, actorId, actor, actorOrgId, success_url }: TStartOrgTrialDTO) => { const startOrgTrial = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); orgId,
actorId,
actor,
actorOrgId,
actorAuthMethod,
success_url
}: TStartOrgTrialDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing);
@ -231,8 +239,14 @@ export const licenseServiceFactory = ({
return { url }; return { url };
}; };
const createOrganizationPortalSession = async ({ orgId, actorId, actor, actorOrgId }: TCreateOrgPortalSession) => { const createOrganizationPortalSession = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); orgId,
actorId,
actor,
actorAuthMethod,
actorOrgId
}: TCreateOrgPortalSession) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing);
@ -278,8 +292,8 @@ export const licenseServiceFactory = ({
return { url }; return { url };
}; };
const getOrgBillingInfo = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgBillInfoDTO) => { const getOrgBillingInfo = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -295,8 +309,8 @@ export const licenseServiceFactory = ({
}; };
// returns org current plan feature table // returns org current plan feature table
const getOrgPlanTable = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgBillInfoDTO) => { const getOrgPlanTable = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -311,8 +325,8 @@ export const licenseServiceFactory = ({
return data; return data;
}; };
const getOrgBillingDetails = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgBillInfoDTO) => { const getOrgBillingDetails = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -332,11 +346,12 @@ export const licenseServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
orgId, orgId,
name, name,
email email
}: TUpdateOrgBillingDetailsDTO) => { }: TUpdateOrgBillingDetailsDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -355,8 +370,8 @@ export const licenseServiceFactory = ({
return data; return data;
}; };
const getOrgPmtMethods = async ({ orgId, actor, actorId, actorOrgId }: TOrgPmtMethodsDTO) => { const getOrgPmtMethods = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgPmtMethodsDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -378,11 +393,12 @@ export const licenseServiceFactory = ({
orgId, orgId,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
success_url, success_url,
cancel_url cancel_url
}: TAddOrgPmtMethodDTO) => { }: TAddOrgPmtMethodDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -403,8 +419,15 @@ export const licenseServiceFactory = ({
return { url }; return { url };
}; };
const delOrgPmtMethods = async ({ actorId, actor, actorOrgId, orgId, pmtMethodId }: TDelOrgPmtMethodDTO) => { const delOrgPmtMethods = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); actorId,
actor,
actorAuthMethod,
actorOrgId,
orgId,
pmtMethodId
}: TDelOrgPmtMethodDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -420,8 +443,8 @@ export const licenseServiceFactory = ({
return data; return data;
}; };
const getOrgTaxIds = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgTaxIdDTO) => { const getOrgTaxIds = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgTaxIdDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -438,8 +461,8 @@ export const licenseServiceFactory = ({
return taxIds; return taxIds;
}; };
const addOrgTaxId = async ({ actorId, actor, actorOrgId, orgId, type, value }: TAddOrgTaxIdDTO) => { const addOrgTaxId = async ({ actorId, actor, actorAuthMethod, actorOrgId, orgId, type, value }: TAddOrgTaxIdDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -459,8 +482,8 @@ export const licenseServiceFactory = ({
return data; return data;
}; };
const delOrgTaxId = async ({ orgId, actor, actorId, actorOrgId, taxId }: TDelOrgTaxIdDTO) => { const delOrgTaxId = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId, taxId }: TDelOrgTaxIdDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -476,8 +499,8 @@ export const licenseServiceFactory = ({
return data; return data;
}; };
const getOrgTaxInvoices = async ({ actorId, actor, actorOrgId, orgId }: TOrgInvoiceDTO) => { const getOrgTaxInvoices = async ({ actorId, actor, actorOrgId, actorAuthMethod, orgId }: TOrgInvoiceDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);
@ -493,8 +516,8 @@ export const licenseServiceFactory = ({
return invoices; return invoices;
}; };
const getOrgLicenses = async ({ orgId, actor, actorId, actorOrgId }: TOrgLicensesDTO) => { const getOrgLicenses = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgLicensesDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId); const organization = await orgDAL.findOrgById(orgId);

View File

@ -129,11 +129,18 @@ export const permissionDALFactory = (db: TDbClient) => {
`${TableName.IdentityProjectMembershipRole}.customRoleId`, `${TableName.IdentityProjectMembershipRole}.customRoleId`,
`${TableName.ProjectRoles}.id` `${TableName.ProjectRoles}.id`
) )
.join(
// Join the Project table to later select orgId
TableName.Project,
`${TableName.IdentityProjectMembership}.projectId`,
`${TableName.Project}.id`
)
.where("identityId", identityId) .where("identityId", identityId)
.where(`${TableName.IdentityProjectMembership}.projectId`, projectId) .where(`${TableName.IdentityProjectMembership}.projectId`, projectId)
.select(selectAllTableCols(TableName.IdentityProjectMembershipRole)) .select(selectAllTableCols(TableName.IdentityProjectMembershipRole))
.select( .select(
db.ref("id").withSchema(TableName.IdentityProjectMembership).as("membershipId"), db.ref("id").withSchema(TableName.IdentityProjectMembership).as("membershipId"),
db.ref("orgId").withSchema(TableName.Project).as("orgId"), // Now you can select orgId from Project
db.ref("role").withSchema(TableName.IdentityProjectMembership).as("oldRoleField"), db.ref("role").withSchema(TableName.IdentityProjectMembership).as("oldRoleField"),
db.ref("createdAt").withSchema(TableName.IdentityProjectMembership).as("membershipCreatedAt"), db.ref("createdAt").withSchema(TableName.IdentityProjectMembership).as("membershipCreatedAt"),
db.ref("updatedAt").withSchema(TableName.IdentityProjectMembership).as("membershipUpdatedAt"), db.ref("updatedAt").withSchema(TableName.IdentityProjectMembership).as("membershipUpdatedAt"),
@ -144,16 +151,16 @@ export const permissionDALFactory = (db: TDbClient) => {
const permission = sqlNestRelationships({ const permission = sqlNestRelationships({
data: docs, data: docs,
key: "membershipId", key: "membershipId",
parentMapper: ({ membershipId, membershipCreatedAt, membershipUpdatedAt, oldRoleField }) => ({ parentMapper: ({ membershipId, membershipCreatedAt, membershipUpdatedAt, oldRoleField, orgId }) => ({
id: membershipId, id: membershipId,
identityId, identityId,
projectId, projectId,
role: oldRoleField, role: oldRoleField,
createdAt: membershipCreatedAt, createdAt: membershipCreatedAt,
updatedAt: membershipUpdatedAt, updatedAt: membershipUpdatedAt,
orgId,
// just a prefilled value // just a prefilled value
orgAuthEnforced: false, orgAuthEnforced: false
orgId: ""
}), }),
childrenMapper: [ childrenMapper: [
{ {

View File

@ -0,0 +1,23 @@
import { TOrganizations } from "@app/db/schemas";
import { UnauthorizedError } from "@app/lib/errors";
import { ActorAuthMethod, AuthMethod } from "@app/services/auth/auth-type";
function isAuthMethodSaml(actorAuthMethod: ActorAuthMethod) {
if (!actorAuthMethod) return false;
return [AuthMethod.AZURE_SAML, AuthMethod.OKTA_SAML, AuthMethod.JUMPCLOUD_SAML, AuthMethod.GOOGLE_SAML].includes(
actorAuthMethod
);
}
function validateOrgSAML(actorAuthMethod: ActorAuthMethod, isSamlEnforced: TOrganizations["authEnforced"]) {
if (actorAuthMethod === undefined) {
throw new UnauthorizedError({ name: "No auth method defined" });
}
if (isSamlEnforced && actorAuthMethod !== null && !isAuthMethodSaml(actorAuthMethod)) {
throw new UnauthorizedError({ name: "Cannot access org-scoped resource" });
}
}
export { isAuthMethodSaml, validateOrgSAML };

View File

@ -11,13 +11,15 @@ import {
} from "@app/db/schemas"; } from "@app/db/schemas";
import { conditionsMatcher } from "@app/lib/casl"; import { conditionsMatcher } from "@app/lib/casl";
import { BadRequestError, UnauthorizedError } from "@app/lib/errors"; import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { ActorType } from "@app/services/auth/auth-type"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
import { TOrgRoleDALFactory } from "@app/services/org/org-role-dal"; import { TOrgRoleDALFactory } from "@app/services/org/org-role-dal";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TProjectRoleDALFactory } from "@app/services/project-role/project-role-dal"; import { TProjectRoleDALFactory } from "@app/services/project-role/project-role-dal";
import { TServiceTokenDALFactory } from "@app/services/service-token/service-token-dal"; import { TServiceTokenDALFactory } from "@app/services/service-token/service-token-dal";
import { orgAdminPermissions, orgMemberPermissions, orgNoAccessPermissions, OrgPermissionSet } from "./org-permission"; import { orgAdminPermissions, orgMemberPermissions, orgNoAccessPermissions, OrgPermissionSet } from "./org-permission";
import { TPermissionDALFactory } from "./permission-dal"; import { TPermissionDALFactory } from "./permission-dal";
import { validateOrgSAML } from "./permission-fns";
import { TBuildProjectPermissionDTO } from "./permission-types"; import { TBuildProjectPermissionDTO } from "./permission-types";
import { import {
buildServiceTokenProjectPermission, buildServiceTokenProjectPermission,
@ -32,6 +34,7 @@ type TPermissionServiceFactoryDep = {
orgRoleDAL: Pick<TOrgRoleDALFactory, "findOne">; orgRoleDAL: Pick<TOrgRoleDALFactory, "findOne">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "findOne">; projectRoleDAL: Pick<TProjectRoleDALFactory, "findOne">;
serviceTokenDAL: Pick<TServiceTokenDALFactory, "findById">; serviceTokenDAL: Pick<TServiceTokenDALFactory, "findById">;
projectDAL: Pick<TProjectDALFactory, "findById">;
permissionDAL: TPermissionDALFactory; permissionDAL: TPermissionDALFactory;
}; };
@ -41,7 +44,8 @@ export const permissionServiceFactory = ({
permissionDAL, permissionDAL,
orgRoleDAL, orgRoleDAL,
projectRoleDAL, projectRoleDAL,
serviceTokenDAL serviceTokenDAL,
projectDAL
}: TPermissionServiceFactoryDep) => { }: TPermissionServiceFactoryDep) => {
const buildOrgPermission = (role: string, permission?: unknown) => { const buildOrgPermission = (role: string, permission?: unknown) => {
switch (role) { switch (role) {
@ -98,16 +102,30 @@ export const permissionServiceFactory = ({
/* /*
* Get user permission in an organization * Get user permission in an organization
* */ */
const getUserOrgPermission = async (userId: string, orgId: string, userOrgId?: string) => { const getUserOrgPermission = async (
userId: string,
orgId: string,
authMethod: ActorAuthMethod,
userOrgId?: string
) => {
const membership = await permissionDAL.getOrgPermission(userId, orgId); const membership = await permissionDAL.getOrgPermission(userId, orgId);
if (!membership) throw new UnauthorizedError({ name: "User not in org" }); if (!membership) throw new UnauthorizedError({ name: "User not in org" });
if (membership.role === OrgMembershipRole.Custom && !membership.permissions) { if (membership.role === OrgMembershipRole.Custom && !membership.permissions) {
throw new BadRequestError({ name: "Custom permission not found" }); throw new BadRequestError({ name: "Custom permission not found" });
} }
if (membership.orgAuthEnforced && membership.orgId !== userOrgId) {
throw new BadRequestError({ name: "Cannot access org-scoped resource" }); // If the org ID is API_KEY, the request is being made with an API Key.
// Since we can't scope API keys to an organization, we'll need to do an arbitrary check to see if the user is a member of the organization.
// Extra: This means that when users are using API keys to make requests, they can't use slug-based routes.
// Slug-based routes depend on the organization ID being present on the request, since project slugs aren't globally unique, and we need a way to filter by organization.
if (userOrgId !== "API_KEY" && membership.orgId !== userOrgId) {
throw new UnauthorizedError({ name: "You are not logged into this organization" });
} }
validateOrgSAML(authMethod, membership.orgAuthEnforced);
return { permission: buildOrgPermission(membership.role, membership.permissions), membership }; return { permission: buildOrgPermission(membership.role, membership.permissions), membership };
}; };
@ -120,10 +138,16 @@ export const permissionServiceFactory = ({
return { permission: buildOrgPermission(membership.role, membership.permissions), membership }; return { permission: buildOrgPermission(membership.role, membership.permissions), membership };
}; };
const getOrgPermission = async (type: ActorType, id: string, orgId: string, actorOrgId?: string) => { const getOrgPermission = async (
type: ActorType,
id: string,
orgId: string,
authMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
switch (type) { switch (type) {
case ActorType.USER: case ActorType.USER:
return getUserOrgPermission(id, orgId, actorOrgId); return getUserOrgPermission(id, orgId, authMethod, actorOrgId);
case ActorType.IDENTITY: case ActorType.IDENTITY:
return getIdentityOrgPermission(id, orgId); return getIdentityOrgPermission(id, orgId);
default: default:
@ -153,34 +177,39 @@ export const permissionServiceFactory = ({
const getUserProjectPermission = async ( const getUserProjectPermission = async (
userId: string, userId: string,
projectId: string, projectId: string,
authMethod: ActorAuthMethod,
userOrgId?: string userOrgId?: string
): Promise<TProjectPermissionRT<ActorType.USER>> => { ): Promise<TProjectPermissionRT<ActorType.USER>> => {
const userProjectPermission = await permissionDAL.getProjectPermission(userId, projectId); const membership = await permissionDAL.getProjectPermission(userId, projectId);
if (!userProjectPermission) throw new UnauthorizedError({ name: "User not in project" }); if (!membership) throw new UnauthorizedError({ name: "User not in project" });
if ( if (membership.roles.some(({ role, permissions }) => role === ProjectMembershipRole.Custom && !permissions)) {
userProjectPermission.roles.some(({ role, permissions }) => role === ProjectMembershipRole.Custom && !permissions)
) {
throw new BadRequestError({ name: "Custom permission not found" }); throw new BadRequestError({ name: "Custom permission not found" });
} }
if (userProjectPermission.orgAuthEnforced && userProjectPermission.orgId !== userOrgId) { // If the org ID is API_KEY, the request is being made with an API Key.
throw new BadRequestError({ name: "Cannot access org-scoped resource" }); // Since we can't scope API keys to an organization, we'll need to do an arbitrary check to see if the user is a member of the organization.
// Extra: This means that when users are using API keys to make requests, they can't use slug-based routes.
// Slug-based routes depend on the organization ID being present on the request, since project slugs aren't globally unique, and we need a way to filter by organization.
if (userOrgId !== "API_KEY" && membership.orgId !== userOrgId) {
throw new UnauthorizedError({ name: "You are not logged into this organization" });
} }
validateOrgSAML(authMethod, membership.orgAuthEnforced);
return { return {
permission: buildProjectPermission(userProjectPermission.roles), permission: buildProjectPermission(membership.roles),
membership: userProjectPermission, membership,
hasRole: (role: string) => hasRole: (role: string) =>
userProjectPermission.roles.findIndex( membership.roles.findIndex(({ role: slug, customRoleSlug }) => role === slug || slug === customRoleSlug) !== -1
({ role: slug, customRoleSlug }) => role === slug || slug === customRoleSlug
) !== -1
}; };
}; };
const getIdentityProjectPermission = async ( const getIdentityProjectPermission = async (
identityId: string, identityId: string,
projectId: string projectId: string,
identityOrgId: string | undefined
): Promise<TProjectPermissionRT<ActorType.IDENTITY>> => { ): Promise<TProjectPermissionRT<ActorType.IDENTITY>> => {
const identityProjectPermission = await permissionDAL.getProjectIdentityPermission(identityId, projectId); const identityProjectPermission = await permissionDAL.getProjectIdentityPermission(identityId, projectId);
if (!identityProjectPermission) throw new UnauthorizedError({ name: "Identity not in project" }); if (!identityProjectPermission) throw new UnauthorizedError({ name: "Identity not in project" });
@ -193,6 +222,10 @@ export const permissionServiceFactory = ({
throw new BadRequestError({ name: "Custom permission not found" }); throw new BadRequestError({ name: "Custom permission not found" });
} }
if (identityProjectPermission.orgId !== identityOrgId) {
throw new UnauthorizedError({ name: "You are not a member of this organization" });
}
return { return {
permission: buildProjectPermission(identityProjectPermission.roles), permission: buildProjectPermission(identityProjectPermission.roles),
membership: identityProjectPermission, membership: identityProjectPermission,
@ -203,14 +236,32 @@ export const permissionServiceFactory = ({
}; };
}; };
const getServiceTokenProjectPermission = async (serviceTokenId: string, projectId: string) => { const getServiceTokenProjectPermission = async (
serviceTokenId: string,
projectId: string,
actorOrgId: string | undefined
) => {
const serviceToken = await serviceTokenDAL.findById(serviceTokenId); const serviceToken = await serviceTokenDAL.findById(serviceTokenId);
if (!serviceToken) throw new BadRequestError({ message: "Service token not found" }); if (!serviceToken) throw new BadRequestError({ message: "Service token not found" });
const serviceTokenProject = await projectDAL.findById(serviceToken.projectId);
if (!serviceTokenProject) throw new BadRequestError({ message: "Service token not linked to a project" });
if (serviceTokenProject.orgId !== actorOrgId) {
throw new UnauthorizedError({ message: "Service token not a part of this organization" });
}
if (serviceToken.projectId !== projectId) if (serviceToken.projectId !== projectId)
throw new UnauthorizedError({ throw new UnauthorizedError({
message: "Failed to find service authorization for given project" message: "Failed to find service authorization for given project"
}); });
if (serviceTokenProject.orgId !== actorOrgId)
throw new UnauthorizedError({
message: "Failed to find service authorization for given project"
});
const scopes = ServiceTokenScopes.parse(serviceToken.scopes || []); const scopes = ServiceTokenScopes.parse(serviceToken.scopes || []);
return { return {
permission: buildServiceTokenProjectPermission(scopes, serviceToken.permissions), permission: buildServiceTokenProjectPermission(scopes, serviceToken.permissions),
@ -238,15 +289,16 @@ export const permissionServiceFactory = ({
type: T, type: T,
id: string, id: string,
projectId: string, projectId: string,
actorOrgId?: string actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
): Promise<TProjectPermissionRT<T>> => { ): Promise<TProjectPermissionRT<T>> => {
switch (type) { switch (type) {
case ActorType.USER: case ActorType.USER:
return getUserProjectPermission(id, projectId, actorOrgId) as Promise<TProjectPermissionRT<T>>; return getUserProjectPermission(id, projectId, actorAuthMethod, actorOrgId) as Promise<TProjectPermissionRT<T>>;
case ActorType.SERVICE: case ActorType.SERVICE:
return getServiceTokenProjectPermission(id, projectId) as Promise<TProjectPermissionRT<T>>; return getServiceTokenProjectPermission(id, projectId, actorOrgId) as Promise<TProjectPermissionRT<T>>;
case ActorType.IDENTITY: case ActorType.IDENTITY:
return getIdentityProjectPermission(id, projectId) as Promise<TProjectPermissionRT<T>>; return getIdentityProjectPermission(id, projectId, actorOrgId) as Promise<TProjectPermissionRT<T>>;
default: default:
throw new UnauthorizedError({ throw new UnauthorizedError({
message: "Permission not defined", message: "Permission not defined",

View File

@ -55,6 +55,7 @@ export const samlConfigServiceFactory = ({
const createSamlCfg = async ({ const createSamlCfg = async ({
cert, cert,
actor, actor,
actorAuthMethod,
actorOrgId, actorOrgId,
orgId, orgId,
issuer, issuer,
@ -63,7 +64,7 @@ export const samlConfigServiceFactory = ({
entryPoint, entryPoint,
authProvider authProvider
}: TCreateSamlCfgDTO) => { }: TCreateSamlCfgDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Sso); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Sso);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
@ -146,6 +147,7 @@ export const samlConfigServiceFactory = ({
orgId, orgId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
cert, cert,
actorId, actorId,
issuer, issuer,
@ -153,7 +155,7 @@ export const samlConfigServiceFactory = ({
entryPoint, entryPoint,
authProvider authProvider
}: TUpdateSamlCfgDTO) => { }: TUpdateSamlCfgDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
if (!plan.samlSSO) if (!plan.samlSSO)
@ -238,6 +240,7 @@ export const samlConfigServiceFactory = ({
dto.actor, dto.actor,
dto.actorId, dto.actorId,
ssoConfig.orgId, ssoConfig.orgId,
dto.actorAuthMethod,
dto.actorOrgId dto.actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Sso); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Sso);

View File

@ -1,5 +1,5 @@
import { TOrgPermission } from "@app/lib/types"; import { TOrgPermission } from "@app/lib/types";
import { ActorType } from "@app/services/auth/auth-type"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
export enum SamlProviders { export enum SamlProviders {
OKTA_SAML = "okta-saml", OKTA_SAML = "okta-saml",
@ -26,7 +26,14 @@ export type TUpdateSamlCfgDTO = Partial<{
TOrgPermission; TOrgPermission;
export type TGetSamlCfgDTO = export type TGetSamlCfgDTO =
| { type: "org"; orgId: string; actor: ActorType; actorId: string; actorOrgId?: string } | {
type: "org";
orgId: string;
actor: ActorType;
actorId: string;
actorAuthMethod: ActorAuthMethod;
actorOrgId: string | undefined;
}
| { | {
type: "orgSlug"; type: "orgSlug";
orgSlug: string; orgSlug: string;

View File

@ -56,8 +56,16 @@ export const scimServiceFactory = ({
permissionService, permissionService,
smtpService smtpService
}: TScimServiceFactoryDep) => { }: TScimServiceFactoryDep) => {
const createScimToken = async ({ actor, actorId, actorOrgId, orgId, description, ttlDays }: TCreateScimTokenDTO) => { const createScimToken = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
orgId,
description,
ttlDays
}: TCreateScimTokenDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Scim); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Scim);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
@ -85,8 +93,8 @@ export const scimServiceFactory = ({
return { scimToken }; return { scimToken };
}; };
const listScimTokens = async ({ actor, actorId, actorOrgId, orgId }: TOrgPermission) => { const listScimTokens = async ({ actor, actorId, actorOrgId, actorAuthMethod, orgId }: TOrgPermission) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Scim); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Scim);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
@ -99,11 +107,17 @@ export const scimServiceFactory = ({
return scimTokens; return scimTokens;
}; };
const deleteScimToken = async ({ scimTokenId, actor, actorId, actorOrgId }: TDeleteScimTokenDTO) => { const deleteScimToken = async ({ scimTokenId, actor, actorId, actorAuthMethod, actorOrgId }: TDeleteScimTokenDTO) => {
let scimToken = await scimDAL.findById(scimTokenId); let scimToken = await scimDAL.findById(scimTokenId);
if (!scimToken) throw new BadRequestError({ message: "Failed to find SCIM token to delete" }); if (!scimToken) throw new BadRequestError({ message: "Failed to find SCIM token to delete" });
const { permission } = await permissionService.getOrgPermission(actor, actorId, scimToken.orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(
actor,
actorId,
scimToken.orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Scim); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Scim);
const plan = await licenseService.getPlan(scimToken.orgId); const plan = await licenseService.getPlan(scimToken.orgId);

View File

@ -45,6 +45,7 @@ export const secretApprovalPolicyServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
approvals, approvals,
approvers, approvers,
projectId, projectId,
@ -54,7 +55,13 @@ export const secretApprovalPolicyServiceFactory = ({
if (approvals > approvers.length) if (approvals > approvers.length)
throw new BadRequestError({ message: "Approvals cannot be greater than approvers" }); throw new BadRequestError({ message: "Approvals cannot be greater than approvers" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
ProjectPermissionSub.SecretApproval ProjectPermissionSub.SecretApproval
@ -98,6 +105,7 @@ export const secretApprovalPolicyServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
approvals, approvals,
secretPolicyId secretPolicyId
}: TUpdateSapDTO) => { }: TUpdateSapDTO) => {
@ -108,6 +116,7 @@ export const secretApprovalPolicyServiceFactory = ({
actor, actor,
actorId, actorId,
secretApprovalPolicy.projectId, secretApprovalPolicy.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
@ -152,7 +161,13 @@ export const secretApprovalPolicyServiceFactory = ({
}; };
}; };
const deleteSecretApprovalPolicy = async ({ secretPolicyId, actor, actorId, actorOrgId }: TDeleteSapDTO) => { const deleteSecretApprovalPolicy = async ({
secretPolicyId,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TDeleteSapDTO) => {
const sapPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId); const sapPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId);
if (!sapPolicy) throw new BadRequestError({ message: "Secret approval policy not found" }); if (!sapPolicy) throw new BadRequestError({ message: "Secret approval policy not found" });
@ -160,6 +175,7 @@ export const secretApprovalPolicyServiceFactory = ({
actor, actor,
actorId, actorId,
sapPolicy.projectId, sapPolicy.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
@ -171,8 +187,20 @@ export const secretApprovalPolicyServiceFactory = ({
return sapPolicy; return sapPolicy;
}; };
const getSecretApprovalPolicyByProjectId = async ({ actorId, actor, actorOrgId, projectId }: TListSapDTO) => { const getSecretApprovalPolicyByProjectId = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TListSapDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
const sapPolicies = await secretApprovalPolicyDAL.find({ projectId }); const sapPolicies = await secretApprovalPolicyDAL.find({ projectId });
@ -201,10 +229,17 @@ export const secretApprovalPolicyServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
secretPath secretPath
}: TGetBoardSapDTO) => { }: TGetBoardSapDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { secretPath, environment }) subject(ProjectPermissionSub.Secrets, { secretPath, environment })

View File

@ -82,13 +82,14 @@ export const secretApprovalRequestServiceFactory = ({
secretVersionDAL, secretVersionDAL,
secretQueueService secretQueueService
}: TSecretApprovalRequestServiceFactoryDep) => { }: TSecretApprovalRequestServiceFactoryDep) => {
const requestCount = async ({ projectId, actor, actorId, actorOrgId }: TApprovalRequestCountDTO) => { const requestCount = async ({ projectId, actor, actorId, actorOrgId, actorAuthMethod }: TApprovalRequestCountDTO) => {
if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" });
const { membership } = await permissionService.getProjectPermission( const { membership } = await permissionService.getProjectPermission(
actor as ActorType.USER, actor as ActorType.USER,
actorId, actorId,
projectId, projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
@ -100,6 +101,7 @@ export const secretApprovalRequestServiceFactory = ({
projectId, projectId,
actorId, actorId,
actor, actor,
actorAuthMethod,
actorOrgId, actorOrgId,
status, status,
environment, environment,
@ -109,7 +111,13 @@ export const secretApprovalRequestServiceFactory = ({
}: TListApprovalsDTO) => { }: TListApprovalsDTO) => {
if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" });
const { membership } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { membership } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
const approvals = await secretApprovalRequestDAL.findByProjectId({ const approvals = await secretApprovalRequestDAL.findByProjectId({
projectId, projectId,
committer, committer,
@ -122,7 +130,13 @@ export const secretApprovalRequestServiceFactory = ({
return approvals; return approvals;
}; };
const getSecretApprovalDetails = async ({ actor, actorId, actorOrgId, id }: TSecretApprovalDetailsDTO) => { const getSecretApprovalDetails = async ({
actor,
actorId,
actorOrgId,
actorAuthMethod,
id
}: TSecretApprovalDetailsDTO) => {
if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" });
const secretApprovalRequest = await secretApprovalRequestDAL.findById(id); const secretApprovalRequest = await secretApprovalRequestDAL.findById(id);
@ -133,6 +147,7 @@ export const secretApprovalRequestServiceFactory = ({
actor, actor,
actorId, actorId,
secretApprovalRequest.projectId, secretApprovalRequest.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
if ( if (
@ -150,7 +165,14 @@ export const secretApprovalRequestServiceFactory = ({
return { ...secretApprovalRequest, secretPath: secretPath?.[0]?.path || "/", commits: secrets }; return { ...secretApprovalRequest, secretPath: secretPath?.[0]?.path || "/", commits: secrets };
}; };
const reviewApproval = async ({ approvalId, actor, status, actorId, actorOrgId }: TReviewRequestDTO) => { const reviewApproval = async ({
approvalId,
actor,
status,
actorId,
actorAuthMethod,
actorOrgId
}: TReviewRequestDTO) => {
const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId);
if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" });
if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" }); if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" });
@ -160,6 +182,7 @@ export const secretApprovalRequestServiceFactory = ({
ActorType.USER, ActorType.USER,
actorId, actorId,
secretApprovalRequest.projectId, secretApprovalRequest.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
if ( if (
@ -192,7 +215,14 @@ export const secretApprovalRequestServiceFactory = ({
return reviewStatus; return reviewStatus;
}; };
const updateApprovalStatus = async ({ actorId, status, approvalId, actor, actorOrgId }: TStatusChangeDTO) => { const updateApprovalStatus = async ({
actorId,
status,
approvalId,
actor,
actorOrgId,
actorAuthMethod
}: TStatusChangeDTO) => {
const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId);
if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" });
if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" }); if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" });
@ -202,6 +232,7 @@ export const secretApprovalRequestServiceFactory = ({
ActorType.USER, ActorType.USER,
actorId, actorId,
secretApprovalRequest.projectId, secretApprovalRequest.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
if ( if (
@ -229,7 +260,8 @@ export const secretApprovalRequestServiceFactory = ({
approvalId, approvalId,
actor, actor,
actorId, actorId,
actorOrgId actorOrgId,
actorAuthMethod
}: TMergeSecretApprovalRequestDTO) => { }: TMergeSecretApprovalRequestDTO) => {
const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId);
if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" });
@ -240,8 +272,10 @@ export const secretApprovalRequestServiceFactory = ({
ActorType.USER, ActorType.USER,
actorId, actorId,
projectId, projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
if ( if (
!hasRole(ProjectMembershipRole.Admin) && !hasRole(ProjectMembershipRole.Admin) &&
secretApprovalRequest.committerId !== membership.id && secretApprovalRequest.committerId !== membership.id &&
@ -438,6 +472,7 @@ export const secretApprovalRequestServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
policy, policy,
projectId, projectId,
secretPath, secretPath,
@ -449,6 +484,7 @@ export const secretApprovalRequestServiceFactory = ({
actor, actor,
actorId, actorId,
projectId, projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(

View File

@ -39,8 +39,20 @@ export const secretRotationServiceFactory = ({
folderDAL, folderDAL,
secretDAL secretDAL
}: TSecretRotationServiceFactoryDep) => { }: TSecretRotationServiceFactoryDep) => {
const getProviderTemplates = async ({ actor, actorId, actorOrgId, projectId }: TProjectPermission) => { const getProviderTemplates = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
projectId
}: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation);
return { return {
@ -54,6 +66,7 @@ export const secretRotationServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
inputs, inputs,
outputs, outputs,
interval, interval,
@ -61,7 +74,13 @@ export const secretRotationServiceFactory = ({
secretPath, secretPath,
environment environment
}: TCreateSecretRotationDTO) => { }: TCreateSecretRotationDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
ProjectPermissionSub.SecretRotation ProjectPermissionSub.SecretRotation
@ -139,14 +158,20 @@ export const secretRotationServiceFactory = ({
return secretRotation; return secretRotation;
}; };
const getByProjectId = async ({ actorId, projectId, actor, actorOrgId }: TListByProjectIdDTO) => { const getByProjectId = async ({ actorId, projectId, actor, actorOrgId, actorAuthMethod }: TListByProjectIdDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation);
const doc = await secretRotationDAL.find({ projectId }); const doc = await secretRotationDAL.find({ projectId });
return doc; return doc;
}; };
const restartById = async ({ actor, actorId, actorOrgId, rotationId }: TRestartDTO) => { const restartById = async ({ actor, actorId, actorOrgId, actorAuthMethod, rotationId }: TRestartDTO) => {
const doc = await secretRotationDAL.findById(rotationId); const doc = await secretRotationDAL.findById(rotationId);
if (!doc) throw new BadRequestError({ message: "Rotation not found" }); if (!doc) throw new BadRequestError({ message: "Rotation not found" });
@ -157,18 +182,30 @@ export const secretRotationServiceFactory = ({
message: "Failed to add secret rotation due to plan restriction. Upgrade plan to add secret rotation." message: "Failed to add secret rotation due to plan restriction. Upgrade plan to add secret rotation."
}); });
const { permission } = await permissionService.getProjectPermission(actor, actorId, doc.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
doc.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretRotation); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretRotation);
await secretRotationQueue.removeFromQueue(doc.id, doc.interval); await secretRotationQueue.removeFromQueue(doc.id, doc.interval);
await secretRotationQueue.addToQueue(doc.id, doc.interval); await secretRotationQueue.addToQueue(doc.id, doc.interval);
return doc; return doc;
}; };
const deleteById = async ({ actor, actorId, actorOrgId, rotationId }: TDeleteDTO) => { const deleteById = async ({ actor, actorId, actorOrgId, actorAuthMethod, rotationId }: TDeleteDTO) => {
const doc = await secretRotationDAL.findById(rotationId); const doc = await secretRotationDAL.findById(rotationId);
if (!doc) throw new BadRequestError({ message: "Rotation not found" }); if (!doc) throw new BadRequestError({ message: "Rotation not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, doc.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
doc.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete, ProjectPermissionActions.Delete,
ProjectPermissionSub.SecretRotation ProjectPermissionSub.SecretRotation

View File

@ -39,8 +39,14 @@ export const secretScanningServiceFactory = ({
permissionService, permissionService,
secretScanningQueue secretScanningQueue
}: TSecretScanningServiceFactoryDep) => { }: TSecretScanningServiceFactoryDep) => {
const createInstallationSession = async ({ actor, orgId, actorId, actorOrgId }: TInstallAppSessionDTO) => { const createInstallationSession = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); actor,
orgId,
actorId,
actorAuthMethod,
actorOrgId
}: TInstallAppSessionDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning);
const sessionId = crypto.randomBytes(16).toString("hex"); const sessionId = crypto.randomBytes(16).toString("hex");
@ -53,12 +59,19 @@ export const secretScanningServiceFactory = ({
actorId, actorId,
installationId, installationId,
actor, actor,
actorAuthMethod,
actorOrgId actorOrgId
}: TLinkInstallSessionDTO) => { }: TLinkInstallSessionDTO) => {
const session = await gitAppInstallSessionDAL.findOne({ sessionId }); const session = await gitAppInstallSessionDAL.findOne({ sessionId });
if (!session) throw new UnauthorizedError({ message: "Session not found" }); if (!session) throw new UnauthorizedError({ message: "Session not found" });
const { permission } = await permissionService.getOrgPermission(actor, actorId, session.orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(
actor,
actorId,
session.orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning);
const installatedApp = await gitAppOrgDAL.transaction(async (tx) => { const installatedApp = await gitAppOrgDAL.transaction(async (tx) => {
await gitAppInstallSessionDAL.deleteById(session.id, tx); await gitAppInstallSessionDAL.deleteById(session.id, tx);
@ -89,23 +102,37 @@ export const secretScanningServiceFactory = ({
return { installatedApp }; return { installatedApp };
}; };
const getOrgInstallationStatus = async ({ actorId, orgId, actor, actorOrgId }: TGetOrgInstallStatusDTO) => { const getOrgInstallationStatus = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); actorId,
orgId,
actor,
actorAuthMethod,
actorOrgId
}: TGetOrgInstallStatusDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning);
const appInstallation = await gitAppOrgDAL.findOne({ orgId }); const appInstallation = await gitAppOrgDAL.findOne({ orgId });
return Boolean(appInstallation); return Boolean(appInstallation);
}; };
const getRisksByOrg = async ({ actor, orgId, actorId, actorOrgId }: TGetOrgRisksDTO) => { const getRisksByOrg = async ({ actor, orgId, actorId, actorAuthMethod, actorOrgId }: TGetOrgRisksDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning);
const risks = await secretScanningDAL.find({ orgId }, { sort: [["createdAt", "desc"]] }); const risks = await secretScanningDAL.find({ orgId }, { sort: [["createdAt", "desc"]] });
return { risks }; return { risks };
}; };
const updateRiskStatus = async ({ actorId, orgId, actor, actorOrgId, riskId, status }: TUpdateRiskStatusDTO) => { const updateRiskStatus = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); actorId,
orgId,
actor,
actorOrgId,
actorAuthMethod,
riskId,
status
}: TUpdateRiskStatusDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.SecretScanning); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.SecretScanning);
const isRiskResolved = Boolean( const isRiskResolved = Boolean(

View File

@ -59,9 +59,16 @@ export const secretSnapshotServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
path path
}: TProjectSnapshotCountDTO) => { }: TProjectSnapshotCountDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
const folder = await folderDAL.findBySecretPath(projectId, environment, path); const folder = await folderDAL.findBySecretPath(projectId, environment, path);
@ -77,11 +84,18 @@ export const secretSnapshotServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
path, path,
limit = 20, limit = 20,
offset = 0 offset = 0
}: TProjectSnapshotListDTO) => { }: TProjectSnapshotListDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
const folder = await folderDAL.findBySecretPath(projectId, environment, path); const folder = await folderDAL.findBySecretPath(projectId, environment, path);
@ -91,10 +105,16 @@ export const secretSnapshotServiceFactory = ({
return snapshots; return snapshots;
}; };
const getSnapshotData = async ({ actorId, actor, actorOrgId, id }: TGetSnapshotDataDTO) => { const getSnapshotData = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TGetSnapshotDataDTO) => {
const snapshot = await snapshotDAL.findSecretSnapshotDataById(id); const snapshot = await snapshotDAL.findSecretSnapshotDataById(id);
if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" }); if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, snapshot.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
snapshot.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
return snapshot; return snapshot;
}; };
@ -145,11 +165,23 @@ export const secretSnapshotServiceFactory = ({
} }
}; };
const rollbackSnapshot = async ({ id: snapshotId, actor, actorId, actorOrgId }: TRollbackSnapshotDTO) => { const rollbackSnapshot = async ({
id: snapshotId,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TRollbackSnapshotDTO) => {
const snapshot = await snapshotDAL.findById(snapshotId); const snapshot = await snapshotDAL.findById(snapshotId);
if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" }); if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, snapshot.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
snapshot.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
ProjectPermissionSub.SecretRollback ProjectPermissionSub.SecretRollback

View File

@ -26,8 +26,14 @@ export const trustedIpServiceFactory = ({
licenseService, licenseService,
projectDAL projectDAL
}: TTrustedIpServiceFactoryDep) => { }: TTrustedIpServiceFactoryDep) => {
const listIpsByProjectId = async ({ projectId, actor, actorId, actorOrgId }: TProjectPermission) => { const listIpsByProjectId = async ({ projectId, actor, actorId, actorAuthMethod, actorOrgId }: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList);
const trustedIps = await trustedIpDAL.find({ const trustedIps = await trustedIpDAL.find({
projectId projectId
@ -38,13 +44,20 @@ export const trustedIpServiceFactory = ({
const addProjectIp = async ({ const addProjectIp = async ({
projectId, projectId,
actorId, actorId,
actorAuthMethod,
actor, actor,
actorOrgId, actorOrgId,
ipAddress: ip, ipAddress: ip,
comment, comment,
isActive isActive
}: TCreateIpDTO) => { }: TCreateIpDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
const project = await projectDAL.findById(projectId); const project = await projectDAL.findById(projectId);
@ -78,11 +91,18 @@ export const trustedIpServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
ipAddress: ip, ipAddress: ip,
comment, comment,
trustedIpId trustedIpId
}: TUpdateIpDTO) => { }: TUpdateIpDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
const project = await projectDAL.findById(projectId); const project = await projectDAL.findById(projectId);
@ -113,8 +133,21 @@ export const trustedIpServiceFactory = ({
return { trustedIp, project }; // for audit log return { trustedIp, project }; // for audit log
}; };
const deleteProjectIp = async ({ projectId, actorId, actor, actorOrgId, trustedIpId }: TDeleteIpDTO) => { const deleteProjectIp = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); projectId,
actorId,
actor,
actorOrgId,
actorAuthMethod,
trustedIpId
}: TDeleteIpDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
const project = await projectDAL.findById(projectId); const project = await projectDAL.findById(projectId);

View File

@ -1,17 +1,19 @@
import { ActorType } from "@app/services/auth/auth-type"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
export type TOrgPermission = { export type TOrgPermission = {
actor: ActorType; actor: ActorType;
actorId: string; actorId: string;
orgId: string; orgId: string;
actorOrgId?: string; actorAuthMethod: ActorAuthMethod;
actorOrgId: string | undefined;
}; };
export type TProjectPermission = { export type TProjectPermission = {
actor: ActorType; actor: ActorType;
actorId: string; actorId: string;
projectId: string; projectId: string;
actorOrgId?: string; actorAuthMethod: ActorAuthMethod;
actorOrgId: string | undefined;
}; };
export type RequiredKeys<T> = { export type RequiredKeys<T> = {

View File

@ -6,42 +6,49 @@ import { TServiceTokens, TUsers } from "@app/db/schemas";
import { TScimTokenJwtPayload } from "@app/ee/services/scim/scim-types"; import { TScimTokenJwtPayload } from "@app/ee/services/scim/scim-types";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { UnauthorizedError } from "@app/lib/errors"; import { UnauthorizedError } from "@app/lib/errors";
import { ActorType, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type"; import { ActorType, AuthMethod, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type";
import { TIdentityAccessTokenJwtPayload } from "@app/services/identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "@app/services/identity-access-token/identity-access-token-types";
export type TAuthMode = export type TAuthMode =
| { | {
orgId?: string;
authMode: AuthMode.JWT; authMode: AuthMode.JWT;
actor: ActorType.USER; actor: ActorType.USER;
userId: string; userId: string;
tokenVersionId: string; // the session id of token used tokenVersionId: string; // the session id of token used
user: TUsers; user: TUsers;
orgId?: string;
authMethod: AuthMethod;
} }
| { | {
authMode: AuthMode.API_KEY; authMode: AuthMode.API_KEY;
authMethod: null;
actor: ActorType.USER; actor: ActorType.USER;
userId: string; userId: string;
user: TUsers; user: TUsers;
orgId?: string; orgId: string;
} }
| { | {
authMode: AuthMode.SERVICE_TOKEN; authMode: AuthMode.SERVICE_TOKEN;
serviceToken: TServiceTokens & { createdByEmail: string }; serviceToken: TServiceTokens & { createdByEmail: string };
actor: ActorType.SERVICE; actor: ActorType.SERVICE;
serviceTokenId: string; serviceTokenId: string;
orgId: string;
authMethod: null;
} }
| { | {
authMode: AuthMode.IDENTITY_ACCESS_TOKEN; authMode: AuthMode.IDENTITY_ACCESS_TOKEN;
actor: ActorType.IDENTITY; actor: ActorType.IDENTITY;
identityId: string; identityId: string;
identityName: string; identityName: string;
orgId: string;
authMethod: null;
} }
| { | {
authMode: AuthMode.SCIM_TOKEN; authMode: AuthMode.SCIM_TOKEN;
actor: ActorType.SCIM_CLIENT; actor: ActorType.SCIM_CLIENT;
scimTokenId: string; scimTokenId: string;
orgId: string; orgId: string;
authMethod: null;
}; };
const extractAuth = async (req: FastifyRequest, jwtSecret: string) => { const extractAuth = async (req: FastifyRequest, jwtSecret: string) => {
@ -50,6 +57,7 @@ const extractAuth = async (req: FastifyRequest, jwtSecret: string) => {
return { authMode: AuthMode.API_KEY, token: apiKey, actor: ActorType.USER } as const; return { authMode: AuthMode.API_KEY, token: apiKey, actor: ActorType.USER } as const;
} }
const authHeader = req.headers?.authorization; const authHeader = req.headers?.authorization;
if (!authHeader) return { authMode: null, token: null }; if (!authHeader) return { authMode: null, token: null };
const authTokenValue = authHeader.slice(7); // slice of after Bearer const authTokenValue = authHeader.slice(7); // slice of after Bearer
@ -71,6 +79,7 @@ const extractAuth = async (req: FastifyRequest, jwtSecret: string) => {
actor: ActorType.USER actor: ActorType.USER
} as const; } as const;
case AuthTokenType.API_KEY: case AuthTokenType.API_KEY:
// throw new Error("API Key auth is no longer supported.");
return { authMode: AuthMode.API_KEY, token: decodedToken, actor: ActorType.USER } as const; return { authMode: AuthMode.API_KEY, token: decodedToken, actor: ActorType.USER } as const;
case AuthTokenType.IDENTITY_ACCESS_TOKEN: case AuthTokenType.IDENTITY_ACCESS_TOKEN:
return { return {
@ -89,17 +98,30 @@ const extractAuth = async (req: FastifyRequest, jwtSecret: string) => {
} }
}; };
// ! Important: You can only 100% count on the `req.permission.orgId` field being present when the auth method is Identity Access Token (Machine Identity).
export const injectIdentity = fp(async (server: FastifyZodProvider) => { export const injectIdentity = fp(async (server: FastifyZodProvider) => {
server.decorateRequest("auth", null); server.decorateRequest("auth", null);
server.addHook("onRequest", async (req) => { server.addHook("onRequest", async (req) => {
const appCfg = getConfig(); const appCfg = getConfig();
const { authMode, token, actor } = await extractAuth(req, appCfg.AUTH_SECRET); const { authMode, token, actor } = await extractAuth(req, appCfg.AUTH_SECRET);
if (req.url.includes("/api/v3/auth/")) {
return;
}
if (!authMode) return; if (!authMode) return;
switch (authMode) { switch (authMode) {
case AuthMode.JWT: { case AuthMode.JWT: {
const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token); const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token);
req.auth = { authMode: AuthMode.JWT, user, userId: user.id, tokenVersionId, actor, orgId }; req.auth = {
authMode: AuthMode.JWT,
user,
userId: user.id,
tokenVersionId,
actor,
orgId,
authMethod: token.authMethod
};
break; break;
} }
case AuthMode.IDENTITY_ACCESS_TOKEN: { case AuthMode.IDENTITY_ACCESS_TOKEN: {
@ -107,29 +129,40 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
req.auth = { req.auth = {
authMode: AuthMode.IDENTITY_ACCESS_TOKEN, authMode: AuthMode.IDENTITY_ACCESS_TOKEN,
actor, actor,
orgId: identity.orgId,
identityId: identity.identityId, identityId: identity.identityId,
identityName: identity.name identityName: identity.name,
authMethod: null
}; };
break; break;
} }
case AuthMode.SERVICE_TOKEN: { case AuthMode.SERVICE_TOKEN: {
const serviceToken = await server.services.serviceToken.fnValidateServiceToken(token); const serviceToken = await server.services.serviceToken.fnValidateServiceToken(token);
req.auth = { req.auth = {
orgId: serviceToken.orgId,
authMode: AuthMode.SERVICE_TOKEN as const, authMode: AuthMode.SERVICE_TOKEN as const,
serviceToken, serviceToken,
serviceTokenId: serviceToken.id, serviceTokenId: serviceToken.id,
actor actor,
authMethod: null
}; };
break; break;
} }
case AuthMode.API_KEY: { case AuthMode.API_KEY: {
const user = await server.services.apiKey.fnValidateApiKey(token as string); const user = await server.services.apiKey.fnValidateApiKey(token as string);
req.auth = { authMode: AuthMode.API_KEY as const, userId: user.id, actor, user }; req.auth = {
authMode: AuthMode.API_KEY as const,
userId: user.id,
actor,
user,
orgId: "API_KEY", // We set the orgId to an arbitrary value, since we can't link an API key to a specific org. We have to deprecate API keys soon!
authMethod: null
};
break; break;
} }
case AuthMode.SCIM_TOKEN: { case AuthMode.SCIM_TOKEN: {
const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token); const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token);
req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId }; req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId, authMethod: null };
break; break;
} }
default: default:

View File

@ -9,13 +9,33 @@ export const injectPermission = fp(async (server) => {
if (!req.auth) return; if (!req.auth) return;
if (req.auth.actor === ActorType.USER) { if (req.auth.actor === ActorType.USER) {
req.permission = { type: ActorType.USER, id: req.auth.userId, orgId: req.auth?.orgId }; req.permission = {
type: ActorType.USER,
id: req.auth.userId,
orgId: req.auth.orgId, // if the req.auth.authMode is AuthMode.API_KEY, the orgId will be "API_KEY"
authMethod: req.auth.authMethod // if the req.auth.authMode is AuthMode.API_KEY, the authMethod will be null
};
} else if (req.auth.actor === ActorType.IDENTITY) { } else if (req.auth.actor === ActorType.IDENTITY) {
req.permission = { type: ActorType.IDENTITY, id: req.auth.identityId }; req.permission = {
type: ActorType.IDENTITY,
id: req.auth.identityId,
orgId: req.auth.orgId,
authMethod: null
};
} else if (req.auth.actor === ActorType.SERVICE) { } else if (req.auth.actor === ActorType.SERVICE) {
req.permission = { type: ActorType.SERVICE, id: req.auth.serviceTokenId }; req.permission = {
type: ActorType.SERVICE,
id: req.auth.serviceTokenId,
orgId: req.auth.orgId,
authMethod: null
};
} else if (req.auth.actor === ActorType.SCIM_CLIENT) { } else if (req.auth.actor === ActorType.SCIM_CLIENT) {
req.permission = { type: ActorType.SCIM_CLIENT, id: req.auth.scimTokenId, orgId: req.auth.orgId }; req.permission = {
type: ActorType.SCIM_CLIENT,
id: req.auth.scimTokenId,
orgId: req.auth.orgId,
authMethod: null
};
} }
}); });
}); });

View File

@ -3,15 +3,26 @@ import { FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify";
import { UnauthorizedError } from "@app/lib/errors"; import { UnauthorizedError } from "@app/lib/errors";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
interface TAuthOptions {
requireOrg: boolean;
}
export const verifyAuth = export const verifyAuth =
<T extends FastifyRequest>(authStrats: AuthMode[]) => <T extends FastifyRequest>(authStrategies: AuthMode[], options: TAuthOptions = { requireOrg: true }) =>
(req: T, _res: FastifyReply, done: HookHandlerDoneFunction) => { (req: T, _res: FastifyReply, done: HookHandlerDoneFunction) => {
if (!Array.isArray(authStrats)) throw new Error("Auth strategy must be array"); if (!Array.isArray(authStrategies)) throw new Error("Auth strategy must be array");
if (!req.auth) throw new UnauthorizedError({ name: "Unauthorized access", message: "Token missing" }); if (!req.auth) throw new UnauthorizedError({ name: "Unauthorized access", message: "Token missing" });
const isAccessAllowed = authStrats.some((strat) => strat === req.auth.authMode); const isAccessAllowed = authStrategies.some((strategy) => strategy === req.auth.authMode);
if (!isAccessAllowed) { if (!isAccessAllowed) {
throw new UnauthorizedError({ name: `${req.url} Unauthorized Access` }); throw new UnauthorizedError({ name: `${req.url} Unauthorized Access` });
} }
// New optional option. There are some routes which do not require an organization ID to be present on the request.
// An example of this is the /v1 auth routes.
if (req.auth.authMode === AuthMode.JWT && options.requireOrg === true && !req.permission.orgId) {
throw new UnauthorizedError({ name: `${req.url} Unauthorized Access, no organization found in request` });
}
done(); done();
}; };

View File

@ -201,7 +201,8 @@ export const registerRoutes = async (
permissionDAL, permissionDAL,
orgRoleDAL, orgRoleDAL,
projectRoleDAL, projectRoleDAL,
serviceTokenDAL serviceTokenDAL,
projectDAL
}); });
const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL, keyStore }); const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL, keyStore });
const trustedIpService = trustedIpServiceFactory({ const trustedIpService = trustedIpServiceFactory({
@ -266,7 +267,7 @@ export const registerRoutes = async (
const tokenService = tokenServiceFactory({ tokenDAL: authTokenDAL, userDAL }); const tokenService = tokenServiceFactory({ tokenDAL: authTokenDAL, userDAL });
const userService = userServiceFactory({ userDAL }); const userService = userServiceFactory({ userDAL });
const loginService = authLoginServiceFactory({ userDAL, smtpService, tokenService }); const loginService = authLoginServiceFactory({ userDAL, smtpService, tokenService, orgDAL, tokenDAL: authTokenDAL });
const passwordService = authPaswordServiceFactory({ const passwordService = authPaswordServiceFactory({
tokenService, tokenService,
smtpService, smtpService,
@ -372,6 +373,7 @@ export const registerRoutes = async (
projectKeyDAL, projectKeyDAL,
userDAL, userDAL,
projectEnvDAL, projectEnvDAL,
orgDAL,
orgService, orgService,
projectMembershipDAL, projectMembershipDAL,
folderDAL, folderDAL,
@ -517,7 +519,8 @@ export const registerRoutes = async (
projectEnvDAL, projectEnvDAL,
serviceTokenDAL, serviceTokenDAL,
userDAL, userDAL,
permissionService permissionService,
projectDAL
}); });
const identityService = identityServiceFactory({ const identityService = identityServiceFactory({
@ -525,7 +528,10 @@ export const registerRoutes = async (
identityDAL, identityDAL,
identityOrgMembershipDAL identityOrgMembershipDAL
}); });
const identityAccessTokenService = identityAccessTokenServiceFactory({ identityAccessTokenDAL }); const identityAccessTokenService = identityAccessTokenServiceFactory({
identityAccessTokenDAL,
identityOrgMembershipDAL
});
const identityProjectService = identityProjectServiceFactory({ const identityProjectService = identityProjectServiceFactory({
permissionService, permissionService,
projectDAL, projectDAL,

View File

@ -21,7 +21,7 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => {
}) })
} }
}, },
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT], { requireOrg: false }),
handler: async (req, res) => { handler: async (req, res) => {
const appCfg = getConfig(); const appCfg = getConfig();
if (req.auth.authMode === AuthMode.JWT) { if (req.auth.authMode === AuthMode.JWT) {
@ -85,6 +85,7 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => {
const token = jwt.sign( const token = jwt.sign(
{ {
authMethod: decodedToken.authMethod,
authTokenType: AuthTokenType.ACCESS_TOKEN, authTokenType: AuthTokenType.ACCESS_TOKEN,
userId: decodedToken.userId, userId: decodedToken.userId,
tokenVersionId: tokenVersion.id, tokenVersionId: tokenVersion.id,

View File

@ -30,6 +30,7 @@ export const registerProjectBotRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
projectId: req.params.projectId projectId: req.params.projectId
}); });
return { bot }; return { bot };
@ -70,6 +71,7 @@ export const registerProjectBotRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
botId: req.params.botId, botId: req.params.botId,
botKey: req.body.botKey, botKey: req.body.botKey,
isActive: req.body.isActive isActive: req.body.isActive

View File

@ -34,6 +34,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
const identity = await server.services.identity.createIdentity({ const identity = await server.services.identity.createIdentity({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
orgId: req.body.organizationId orgId: req.body.organizationId
@ -94,6 +95,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
const identity = await server.services.identity.updateIdentity({ const identity = await server.services.identity.updateIdentity({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.identityId, id: req.params.identityId,
...req.body ...req.body
@ -139,6 +141,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
const identity = await server.services.identity.deleteIdentity({ const identity = await server.services.identity.deleteIdentity({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.identityId id: req.params.identityId
}); });

View File

@ -121,6 +121,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
...req.body, ...req.body,
identityId: req.params.identityId identityId: req.params.identityId
}); });
@ -194,6 +195,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
...req.body, ...req.body,
identityId: req.params.identityId identityId: req.params.identityId
}); });
@ -242,6 +244,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
const identityUniversalAuth = await server.services.identityUa.getIdentityUa({ const identityUniversalAuth = await server.services.identityUa.getIdentityUa({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
identityId: req.params.identityId identityId: req.params.identityId
}); });
@ -291,6 +294,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
const { clientSecret, clientSecretData, orgId } = await server.services.identityUa.createUaClientSecret({ const { clientSecret, clientSecretData, orgId } = await server.services.identityUa.createUaClientSecret({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
identityId: req.params.identityId, identityId: req.params.identityId,
...req.body ...req.body
@ -336,6 +340,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
const { clientSecrets: clientSecretData, orgId } = await server.services.identityUa.getUaClientSecrets({ const { clientSecrets: clientSecretData, orgId } = await server.services.identityUa.getUaClientSecrets({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
identityId: req.params.identityId identityId: req.params.identityId
}); });
@ -379,6 +384,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
const clientSecretData = await server.services.identityUa.revokeUaClientSecret({ const clientSecretData = await server.services.identityUa.revokeUaClientSecret({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
identityId: req.params.identityId, identityId: req.params.identityId,
clientSecretId: req.params.clientSecretId clientSecretId: req.params.clientSecretId

View File

@ -53,6 +53,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const integrationAuth = await server.services.integrationAuth.getIntegrationAuth({ const integrationAuth = await server.services.integrationAuth.getIntegrationAuth({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId id: req.params.integrationAuthId
}); });
@ -80,6 +81,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
integration: req.query.integration, integration: req.query.integration,
projectId: req.query.projectId projectId: req.query.projectId
}); });
@ -117,6 +119,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const integrationAuth = await server.services.integrationAuth.deleteIntegrationAuthById({ const integrationAuth = await server.services.integrationAuth.deleteIntegrationAuthById({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId id: req.params.integrationAuthId
}); });
@ -157,6 +160,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const integrationAuth = await server.services.integrationAuth.oauthExchange({ const integrationAuth = await server.services.integrationAuth.oauthExchange({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
...req.body ...req.body
@ -200,6 +204,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const integrationAuth = await server.services.integrationAuth.saveIntegrationToken({ const integrationAuth = await server.services.integrationAuth.saveIntegrationToken({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
...req.body ...req.body
@ -247,6 +252,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const apps = await server.services.integrationAuth.getIntegrationApps({ const apps = await server.services.integrationAuth.getIntegrationApps({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
...req.query ...req.query
@ -278,6 +284,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const teams = await server.services.integrationAuth.getIntegrationAuthTeams({ const teams = await server.services.integrationAuth.getIntegrationAuthTeams({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId id: req.params.integrationAuthId
}); });
@ -306,6 +313,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const branches = await server.services.integrationAuth.getVercelBranches({ const branches = await server.services.integrationAuth.getVercelBranches({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
appId: req.query.appId appId: req.query.appId
@ -335,6 +343,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const groups = await server.services.integrationAuth.getChecklyGroups({ const groups = await server.services.integrationAuth.getChecklyGroups({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
accountId: req.query.accountId accountId: req.query.accountId
@ -361,6 +370,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const orgs = await server.services.integrationAuth.getQoveryOrgs({ const orgs = await server.services.integrationAuth.getQoveryOrgs({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId id: req.params.integrationAuthId
}); });
@ -389,6 +399,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const projects = await server.services.integrationAuth.getQoveryProjects({ const projects = await server.services.integrationAuth.getQoveryProjects({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
orgId: req.query.orgId orgId: req.query.orgId
@ -418,6 +429,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const environments = await server.services.integrationAuth.getQoveryEnvs({ const environments = await server.services.integrationAuth.getQoveryEnvs({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
projectId: req.query.projectId projectId: req.query.projectId
@ -447,6 +459,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const apps = await server.services.integrationAuth.getQoveryApps({ const apps = await server.services.integrationAuth.getQoveryApps({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
environmentId: req.query.environmentId environmentId: req.query.environmentId
@ -476,6 +489,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const containers = await server.services.integrationAuth.getQoveryContainers({ const containers = await server.services.integrationAuth.getQoveryContainers({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
environmentId: req.query.environmentId environmentId: req.query.environmentId
@ -505,6 +519,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const jobs = await server.services.integrationAuth.getQoveryJobs({ const jobs = await server.services.integrationAuth.getQoveryJobs({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
environmentId: req.query.environmentId environmentId: req.query.environmentId
@ -537,6 +552,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const pipelines = await server.services.integrationAuth.getHerokuPipelines({ const pipelines = await server.services.integrationAuth.getHerokuPipelines({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId id: req.params.integrationAuthId
}); });
@ -565,6 +581,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const environments = await server.services.integrationAuth.getRailwayEnvironments({ const environments = await server.services.integrationAuth.getRailwayEnvironments({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
appId: req.query.appId appId: req.query.appId
@ -594,6 +611,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const services = await server.services.integrationAuth.getRailwayServices({ const services = await server.services.integrationAuth.getRailwayServices({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
appId: req.query.appId appId: req.query.appId
@ -630,6 +648,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const workspaces = await server.services.integrationAuth.getBitbucketWorkspaces({ const workspaces = await server.services.integrationAuth.getBitbucketWorkspaces({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId id: req.params.integrationAuthId
}); });
@ -663,6 +682,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const secretGroups = await server.services.integrationAuth.getNorthFlankSecretGroups({ const secretGroups = await server.services.integrationAuth.getNorthFlankSecretGroups({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
appId: req.query.appId appId: req.query.appId
@ -697,6 +717,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
const buildConfigs = await server.services.integrationAuth.getTeamcityBuildConfigs({ const buildConfigs = await server.services.integrationAuth.getTeamcityBuildConfigs({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationAuthId, id: req.params.integrationAuthId,
appId: req.query.appId appId: req.query.appId

View File

@ -53,6 +53,7 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
const { integration, integrationAuth } = await server.services.integration.createIntegration({ const { integration, integrationAuth } = await server.services.integration.createIntegration({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body ...req.body
}); });
@ -123,6 +124,7 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
const integration = await server.services.integration.updateIntegration({ const integration = await server.services.integration.updateIntegration({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationId, id: req.params.integrationId,
...req.body ...req.body
@ -148,6 +150,7 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
handler: async (req) => { handler: async (req) => {
const integration = await server.services.integration.deleteIntegration({ const integration = await server.services.integration.deleteIntegration({
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.integrationId id: req.params.integrationId

View File

@ -29,6 +29,7 @@ export const registerInviteOrgRouter = async (server: FastifyZodProvider) => {
orgId: req.body.organizationId, orgId: req.body.organizationId,
userId: req.permission.id, userId: req.permission.id,
inviteeEmail: req.body.inviteeEmail, inviteeEmail: req.body.inviteeEmail,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });

View File

@ -15,7 +15,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
}) })
} }
}, },
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT], { requireOrg: false }),
handler: async (req) => { handler: async (req) => {
const organizations = await server.services.org.findAllOrganizationOfUser(req.permission.id); const organizations = await server.services.org.findAllOrganizationOfUser(req.permission.id);
return { organizations }; return { organizations };
@ -40,6 +40,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
const organization = await server.services.org.findOrganizationById( const organization = await server.services.org.findOrganizationById(
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { organization }; return { organization };
@ -76,6 +77,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
const users = await server.services.org.findAllOrgMembers( const users = await server.services.org.findAllOrgMembers(
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { users }; return { users };
@ -111,6 +113,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId, orgId: req.params.organizationId,
data: req.body data: req.body
}); });
@ -138,6 +141,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
const incidentContactsOrg = await req.server.services.org.findIncidentContacts( const incidentContactsOrg = await req.server.services.org.findIncidentContacts(
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { incidentContactsOrg }; return { incidentContactsOrg };
@ -162,6 +166,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.body.email, req.body.email,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { incidentContactsOrg }; return { incidentContactsOrg };
@ -185,6 +190,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.params.incidentContactId, req.params.incidentContactId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { incidentContactsOrg }; return { incidentContactsOrg };

View File

@ -38,6 +38,7 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
...req.body ...req.body
}); });
@ -94,6 +95,7 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
const { environment, old } = await server.services.projectEnv.updateEnvironment({ const { environment, old } = await server.services.projectEnv.updateEnvironment({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
id: req.params.id, id: req.params.id,
@ -152,6 +154,7 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
const environment = await server.services.projectEnv.deleteEnvironment({ const environment = await server.services.projectEnv.deleteEnvironment({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
id: req.params.id id: req.params.id

View File

@ -30,6 +30,7 @@ export const registerProjectKeyRouter = async (server: FastifyZodProvider) => {
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
nonce: req.body.key.nonce, nonce: req.body.key.nonce,
receiverId: req.body.key.userId, receiverId: req.body.key.userId,

View File

@ -65,6 +65,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
const memberships = await server.services.projectMembership.getProjectMemberships({ const memberships = await server.services.projectMembership.getProjectMemberships({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId projectId: req.params.workspaceId
}); });
@ -101,6 +102,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
const data = await server.services.projectMembership.addUsersToProject({ const data = await server.services.projectMembership.addUsersToProject({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
members: req.body.members members: req.body.members
@ -168,6 +170,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
const roles = await server.services.projectMembership.updateProjectMembership({ const roles = await server.services.projectMembership.updateProjectMembership({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
membershipId: req.params.membershipId, membershipId: req.params.membershipId,
@ -217,6 +220,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
const membership = await server.services.projectMembership.deleteProjectMembership({ const membership = await server.services.projectMembership.deleteProjectMembership({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
membershipId: req.params.membershipId membershipId: req.params.membershipId

View File

@ -9,6 +9,7 @@ import {
} from "@app/db/schemas"; } from "@app/db/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectFilterType } from "@app/services/project/project-types";
import { integrationAuthPubSchema } from "../sanitizedSchemas"; import { integrationAuthPubSchema } from "../sanitizedSchemas";
import { sanitizedServiceTokenSchema } from "../v2/service-token-router"; import { sanitizedServiceTokenSchema } from "../v2/service-token-router";
@ -44,6 +45,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
const publicKeys = await server.services.projectKey.getProjectPublicKeys({ const publicKeys = await server.services.projectKey.getProjectPublicKeys({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId projectId: req.params.workspaceId
}); });
@ -96,6 +98,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
const users = await server.services.projectMembership.getProjectMemberships({ const users = await server.services.projectMembership.getProjectMemberships({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });
@ -136,37 +139,14 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
onRequest: verifyAuth([AuthMode.JWT, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const workspace = await server.services.project.getAProject({ const workspace = await server.services.project.getAProject({
filter: {
type: ProjectFilterType.ID,
projectId: req.params.workspaceId
},
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId
projectId: req.params.workspaceId
});
return { workspace };
}
});
server.route({
url: "/",
method: "POST",
schema: {
body: z.object({
workspaceName: z.string().trim(),
organizationId: z.string().trim()
}),
response: {
200: z.object({
workspace: projectWithEnv
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const workspace = await server.services.project.createProject({
actorId: req.permission.id,
actor: req.permission.type,
orgId: req.body.organizationId,
actorOrgId: req.permission.orgId,
workspaceName: req.body.workspaceName
}); });
return { workspace }; return { workspace };
} }
@ -188,10 +168,14 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const workspace = await server.services.project.deleteProject({ const workspace = await server.services.project.deleteProject({
filter: {
type: ProjectFilterType.ID,
projectId: req.params.workspaceId
},
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId
projectId: req.params.workspaceId
}); });
return { workspace }; return { workspace };
} }
@ -219,6 +203,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
const workspace = await server.services.project.updateName({ const workspace = await server.services.project.updateName({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
name: req.body.name name: req.body.name
@ -247,17 +232,21 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}) })
} }
}, },
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const workspace = await server.services.project.updateProject({ const workspace = await server.services.project.updateProject({
actorId: req.permission.id, filter: {
actor: req.permission.type, type: ProjectFilterType.ID,
actorOrgId: req.permission.orgId, projectId: req.params.workspaceId
projectId: req.params.workspaceId, },
update: { update: {
name: req.body.name, name: req.body.name,
autoCapitalization: req.body.autoCapitalization autoCapitalization: req.body.autoCapitalization
} },
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id,
actor: req.permission.type,
actorOrgId: req.permission.orgId
}); });
return { return {
workspace workspace
@ -287,6 +276,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
const workspace = await server.services.project.toggleAutoCapitalization({ const workspace = await server.services.project.toggleAutoCapitalization({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
autoCapitalization: req.body.autoCapitalization autoCapitalization: req.body.autoCapitalization
@ -323,6 +313,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
handler: async (req) => { handler: async (req) => {
const integrations = await server.services.integration.listIntegrationByProject({ const integrations = await server.services.integration.listIntegrationByProject({
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId projectId: req.params.workspaceId
@ -348,6 +339,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
handler: async (req) => { handler: async (req) => {
const authorizations = await server.services.integrationAuth.listIntegrationAuthByProjectId({ const authorizations = await server.services.integrationAuth.listIntegrationAuthByProjectId({
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId projectId: req.params.workspaceId
@ -373,6 +365,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
handler: async (req) => { handler: async (req) => {
const serviceTokenData = await server.services.serviceToken.getProjectServiceTokens({ const serviceTokenData = await server.services.serviceToken.getProjectServiceTokens({
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId projectId: req.params.workspaceId

View File

@ -38,6 +38,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
const folder = await server.services.folder.createFolder({ const folder = await server.services.folder.createFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
@ -95,6 +96,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
const { folder, old } = await server.services.folder.updateFolder({ const { folder, old } = await server.services.folder.updateFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
@ -152,6 +154,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
const folder = await server.services.folder.deleteFolder({ const folder = await server.services.folder.deleteFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
@ -205,6 +208,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
const folders = await server.services.folder.getFolders({ const folders = await server.services.folder.getFolders({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.query, ...req.query,
projectId: req.query.workspaceId, projectId: req.query.workspaceId,

View File

@ -43,6 +43,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
const secretImport = await server.services.secretImport.createImport({ const secretImport = await server.services.secretImport.createImport({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
@ -112,6 +113,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
const secretImport = await server.services.secretImport.updateImport({ const secretImport = await server.services.secretImport.updateImport({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.secretImportId, id: req.params.secretImportId,
...req.body, ...req.body,
@ -173,6 +175,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
const secretImport = await server.services.secretImport.deleteImport({ const secretImport = await server.services.secretImport.deleteImport({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.secretImportId, id: req.params.secretImportId,
...req.body, ...req.body,
@ -232,6 +235,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
const secretImports = await server.services.secretImport.getImports({ const secretImports = await server.services.secretImport.getImports({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.query, ...req.query,
projectId: req.query.workspaceId projectId: req.query.workspaceId
@ -285,6 +289,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
const importedSecrets = await server.services.secretImport.getSecretsFromImports({ const importedSecrets = await server.services.secretImport.getSecretsFromImports({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.query, ...req.query,
projectId: req.query.workspaceId projectId: req.query.workspaceId

View File

@ -23,6 +23,7 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
const workspaceTags = await server.services.secretTag.getProjectTags({ const workspaceTags = await server.services.secretTag.getProjectTags({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.projectId projectId: req.params.projectId
}); });
@ -53,6 +54,7 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
const workspaceTag = await server.services.secretTag.createTag({ const workspaceTag = await server.services.secretTag.createTag({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.projectId, projectId: req.params.projectId,
...req.body ...req.body
@ -80,6 +82,7 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => {
const workspaceTag = await server.services.secretTag.deleteTag({ const workspaceTag = await server.services.secretTag.deleteTag({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.tagId id: req.params.tagId
}); });

View File

@ -15,7 +15,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => {
}) })
} }
}, },
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT], { requireOrg: false }),
handler: async (req) => { handler: async (req) => {
const user = await server.services.user.getMe(req.permission.id); const user = await server.services.user.getMe(req.permission.id);
return { user }; return { user };

View File

@ -47,6 +47,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
const webhook = await server.services.webhook.createWebhook({ const webhook = await server.services.webhook.createWebhook({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
...req.body ...req.body
@ -93,6 +94,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
const webhook = await server.services.webhook.updateWebhook({ const webhook = await server.services.webhook.updateWebhook({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.webhookId, id: req.params.webhookId,
isDisabled: req.body.isDisabled isDisabled: req.body.isDisabled
@ -130,6 +132,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
const webhook = await server.services.webhook.deleteWebhook({ const webhook = await server.services.webhook.deleteWebhook({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.webhookId id: req.params.webhookId
}); });
@ -172,6 +175,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
const webhook = await server.services.webhook.testWebhook({ const webhook = await server.services.webhook.testWebhook({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.webhookId id: req.params.webhookId
}); });
@ -204,6 +208,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
const webhooks = await server.services.webhook.listWebhooks({ const webhooks = await server.services.webhook.listWebhooks({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.query, ...req.query,
projectId: req.query.workspaceId projectId: req.query.workspaceId

View File

@ -41,6 +41,7 @@ export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => {
const identityMemberships = await server.services.identity.listOrgIdentities({ const identityMemberships = await server.services.identity.listOrgIdentities({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
orgId: req.params.orgId orgId: req.params.orgId
}); });

View File

@ -34,6 +34,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
const identityMembership = await server.services.identityProject.createProjectIdentity({ const identityMembership = await server.services.identityProject.createProjectIdentity({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
identityId: req.params.identityId, identityId: req.params.identityId,
projectId: req.params.projectId, projectId: req.params.projectId,
@ -87,6 +88,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
const roles = await server.services.identityProject.updateProjectIdentity({ const roles = await server.services.identityProject.updateProjectIdentity({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
identityId: req.params.identityId, identityId: req.params.identityId,
projectId: req.params.projectId, projectId: req.params.projectId,
@ -121,6 +123,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
const identityMembership = await server.services.identityProject.deleteProjectIdentity({ const identityMembership = await server.services.identityProject.deleteProjectIdentity({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
identityId: req.params.identityId, identityId: req.params.identityId,
projectId: req.params.projectId projectId: req.params.projectId
@ -175,6 +178,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
const identityMemberships = await server.services.identityProject.listProjectIdentities({ const identityMemberships = await server.services.identityProject.listProjectIdentities({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.projectId projectId: req.params.projectId
}); });

View File

@ -68,11 +68,14 @@ export const registerMfaRouter = async (server: FastifyZodProvider) => {
}, },
handler: async (req, res) => { handler: async (req, res) => {
const userAgent = req.headers["user-agent"]; const userAgent = req.headers["user-agent"];
const mfaJwtToken = req.headers.authorization?.replace("Bearer ", "");
if (!userAgent) throw new Error("user agent header is required"); if (!userAgent) throw new Error("user agent header is required");
if (!mfaJwtToken) throw new Error("authorization header is required");
const appCfg = getConfig(); const appCfg = getConfig();
const { user, token } = await server.services.login.verifyMfaToken({ const { user, token } = await server.services.login.verifyMfaToken({
userAgent, userAgent,
mfaJwtToken,
ip: req.realIp, ip: req.realIp,
userId: req.mfa.userId, userId: req.mfa.userId,
orgId: req.mfa.orgId, orgId: req.mfa.orgId,

View File

@ -44,6 +44,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
const users = await server.services.org.findAllOrgMembers( const users = await server.services.org.findAllOrgMembers(
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { users }; return { users };
@ -88,6 +89,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId orgId: req.params.organizationId
}); });
@ -123,6 +125,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
const membership = await server.services.org.updateOrgMembership({ const membership = await server.services.org.updateOrgMembership({
userId: req.permission.id, userId: req.permission.id,
role: req.body.role, role: req.body.role,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId, orgId: req.params.organizationId,
membershipId: req.params.membershipId, membershipId: req.params.membershipId,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
@ -155,6 +158,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
const membership = await server.services.org.deleteOrgMembership({ const membership = await server.services.org.deleteOrgMembership({
userId: req.permission.id, userId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
orgId: req.params.organizationId, orgId: req.params.organizationId,
membershipId: req.params.membershipId, membershipId: req.params.membershipId,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
@ -176,7 +180,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
}) })
} }
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY], { requireOrg: false }),
handler: async (req) => { handler: async (req) => {
if (req.auth.actor !== ActorType.USER) return; if (req.auth.actor !== ActorType.USER) return;
@ -210,6 +214,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
const organization = await server.services.org.deleteOrganizationById( const organization = await server.services.org.deleteOrganizationById(
req.permission.id, req.permission.id,
req.params.organizationId, req.params.organizationId,
req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
return { organization }; return { organization };

View File

@ -27,7 +27,9 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
handler: async (req) => { handler: async (req) => {
const memberships = await server.services.projectMembership.addUsersToProjectNonE2EE({ const memberships = await server.services.projectMembership.addUsersToProjectNonE2EE({
projectId: req.params.projectId, projectId: req.params.projectId,
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actor: req.permission.type, actor: req.permission.type,
emails: req.body.emails, emails: req.body.emails,
usernames: req.body.usernames usernames: req.body.usernames
@ -73,6 +75,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
const memberships = await server.services.projectMembership.deleteProjectMemberships({ const memberships = await server.services.projectMembership.deleteProjectMemberships({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.projectId, projectId: req.params.projectId,
emails: req.body.emails, emails: req.body.emails,

View File

@ -7,6 +7,7 @@ import { authRateLimit } from "@app/server/config/rateLimiter";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectFilterType } from "@app/services/project/project-types";
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
const projectWithEnv = ProjectsSchema.merge( const projectWithEnv = ProjectsSchema.merge(
@ -16,6 +17,14 @@ const projectWithEnv = ProjectsSchema.merge(
}) })
); );
const slugSchema = z
.string()
.min(5)
.max(36)
.refine((v) => slugify(v) === v, {
message: "Slug must be at least 5 character but no more than 36"
});
export const registerProjectRouter = async (server: FastifyZodProvider) => { export const registerProjectRouter = async (server: FastifyZodProvider) => {
/* Get project key */ /* Get project key */
server.route({ server.route({
@ -46,6 +55,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
const key = await server.services.projectKey.getLatestProjectKey({ const key = await server.services.projectKey.getLatestProjectKey({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId projectId: req.params.workspaceId
}); });
@ -73,7 +83,6 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
params: z.object({ params: z.object({
projectId: z.string().trim() projectId: z.string().trim()
}), }),
body: z.object({ body: z.object({
userPrivateKey: z.string().trim() userPrivateKey: z.string().trim()
}), }),
@ -81,11 +90,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
200: z.void() 200: z.void()
} }
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { handler: async (req) => {
await server.services.project.upgradeProject({ await server.services.project.upgradeProject({
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
projectId: req.params.projectId, projectId: req.params.projectId,
userPrivateKey: req.body.userPrivateKey userPrivateKey: req.body.userPrivateKey
}); });
@ -106,9 +117,11 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}) })
} }
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { handler: async (req) => {
const status = await server.services.project.getProjectUpgradeStatus({ const status = await server.services.project.getProjectUpgradeStatus({
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId, projectId: req.params.projectId,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id actorId: req.permission.id
@ -127,16 +140,11 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}, },
schema: { schema: {
body: z.object({ body: z.object({
projectName: z.string().trim(), projectName: z.string().trim().describe("Name of the project you're creating"),
slug: z slug: slugSchema
.string() .optional()
.min(5) .describe("An optional slug for the project. If not provided, it will be auto-generated"),
.max(36) organizationSlug: z.string().trim().describe("The slug of the organization to create the project in")
.refine((v) => slugify(v) === v, {
message: "Slug must be a valid slug"
})
.optional(),
organizationId: z.string().trim()
}), }),
response: { response: {
200: z.object({ 200: z.object({
@ -144,12 +152,14 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}) })
} }
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const project = await server.services.project.createProject({ const project = await server.services.project.createProject({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
orgId: req.body.organizationId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
orgSlug: req.body.organizationSlug,
workspaceName: req.body.projectName, workspaceName: req.body.projectName,
slug: req.body.slug slug: req.body.slug
}); });
@ -158,7 +168,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
event: PostHogEventTypes.ProjectCreated, event: PostHogEventTypes.ProjectCreated,
distinctId: getTelemetryDistinctId(req), distinctId: getTelemetryDistinctId(req),
properties: { properties: {
orgId: req.body.organizationId, orgId: project.orgId,
name: project.name, name: project.name,
...req.auditLogInfo ...req.auditLogInfo
} }
@ -167,4 +177,104 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
return { project }; return { project };
} }
}); });
/* Delete a project by slug */
server.route({
method: "DELETE",
url: "/:slug",
schema: {
params: z.object({
slug: slugSchema.describe("The slug of the project to delete.")
}),
response: {
200: ProjectsSchema
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const project = await server.services.project.deleteProject({
filter: {
type: ProjectFilterType.SLUG,
slug: req.params.slug,
orgId: req.permission.orgId
},
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
actor: req.permission.type
});
return project;
}
});
/* Get a project by slug */
server.route({
method: "GET",
url: "/:slug",
schema: {
params: z.object({
slug: slugSchema.describe("The slug of the project to get.")
}),
response: {
200: projectWithEnv
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const project = await server.services.project.getAProject({
filter: {
slug: req.params.slug,
orgId: req.permission.orgId,
type: ProjectFilterType.SLUG
},
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type
});
return project;
}
});
/* Update a project by slug */
server.route({
method: "PATCH",
url: "/:slug",
schema: {
params: z.object({
slug: slugSchema.describe("The slug of the project to update.")
}),
body: z.object({
name: z.string().trim().optional().describe("The new name of the project."),
autoCapitalization: z.boolean().optional().describe("The new auto-capitalization setting.")
}),
response: {
200: ProjectsSchema
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const project = await server.services.project.updateProject({
filter: {
type: ProjectFilterType.SLUG,
slug: req.params.slug,
orgId: req.permission.orgId
},
update: {
name: req.body.name,
autoCapitalization: req.body.autoCapitalization
},
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
actorOrgId: req.permission.orgId
});
return project;
}
});
}; };

View File

@ -46,6 +46,8 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) =>
handler: async (req) => { handler: async (req) => {
const { serviceToken, user } = await server.services.serviceToken.getServiceToken({ const { serviceToken, user } = await server.services.serviceToken.getServiceToken({
actorId: req.permission.id, actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
actor: req.permission.type actor: req.permission.type
}); });
@ -98,6 +100,7 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) =>
const { serviceToken, token } = await server.services.serviceToken.createServiceToken({ const { serviceToken, token } = await server.services.serviceToken.createServiceToken({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body, ...req.body,
projectId: req.body.workspaceId projectId: req.body.workspaceId
@ -136,6 +139,7 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) =>
const serviceTokenData = await server.services.serviceToken.deleteServiceToken({ const serviceTokenData = await server.services.serviceToken.deleteServiceToken({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
id: req.params.serviceTokenId id: req.params.serviceTokenId
}); });

View File

@ -60,7 +60,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => {
}) })
} }
}, },
preHandler: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), preHandler: verifyAuth([AuthMode.JWT, AuthMode.API_KEY], { requireOrg: false }),
handler: async (req) => { handler: async (req) => {
const user = await server.services.user.updateAuthMethods(req.permission.id, req.body.authMethods); const user = await server.services.user.updateAuthMethods(req.permission.id, req.body.authMethods);
return { user }; return { user };

View File

@ -34,6 +34,42 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
} }
}); });
server.route({
method: "POST",
url: "/select-organization",
config: {
rateLimit: authRateLimit
},
schema: {
body: z.object({
organizationId: z.string().trim()
}),
response: {
200: z.object({
token: z.string()
})
}
},
handler: async (req, res) => {
const cfg = getConfig();
const tokens = await server.services.login.selectOrganization({
userAgent: req.headers["user-agent"],
authJwtToken: req.headers.authorization,
organizationId: req.body.organizationId,
ipAddress: req.realIp
});
void res.setCookie("jid", tokens.refresh, {
httpOnly: true,
path: "/",
sameSite: "strict",
secure: cfg.HTTPS_ENABLED
});
return { token: tokens.access };
}
});
server.route({ server.route({
method: "POST", method: "POST",
url: "/login2", url: "/login2",

View File

@ -20,6 +20,7 @@ export const registerSecretBlindIndexRouter = async (server: FastifyZodProvider)
handler: async (req) => { handler: async (req) => {
const count = await server.services.secretBlindIndex.getSecretBlindIndexStatus({ const count = await server.services.secretBlindIndex.getSecretBlindIndexStatus({
projectId: req.params.projectId, projectId: req.params.projectId,
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
@ -52,6 +53,7 @@ export const registerSecretBlindIndexRouter = async (server: FastifyZodProvider)
handler: async (req) => { handler: async (req) => {
const secrets = await server.services.secretBlindIndex.getProjectSecrets({ const secrets = await server.services.secretBlindIndex.getProjectSecrets({
projectId: req.params.projectId, projectId: req.params.projectId,
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
@ -86,6 +88,7 @@ export const registerSecretBlindIndexRouter = async (server: FastifyZodProvider)
await server.services.secretBlindIndex.updateProjectSecretName({ await server.services.secretBlindIndex.updateProjectSecretName({
projectId: req.params.projectId, projectId: req.params.projectId,
secretsToUpdate: req.body.secretsToUpdate, secretsToUpdate: req.body.secretsToUpdate,
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId

View File

@ -16,6 +16,7 @@ import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
import { getUserAgentType } from "@app/server/plugins/audit-log"; import { getUserAgentType } from "@app/server/plugins/audit-log";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { ActorType, AuthMode } from "@app/services/auth/auth-type"; import { ActorType, AuthMode } from "@app/services/auth/auth-type";
import { ProjectFilterType } from "@app/services/project/project-types";
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
import { secretRawSchema } from "../sanitizedSchemas"; import { secretRawSchema } from "../sanitizedSchemas";
@ -34,6 +35,13 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
], ],
querystring: z.object({ querystring: z.object({
workspaceId: z.string().trim().optional(), workspaceId: z.string().trim().optional(),
workspaceSlug: z
.string()
.trim()
.optional()
.describe(
"The slug of the workspace. This is only supported when authenticating Machine Identity's. Either the project ID or project slug has to be present in the request."
),
environment: z.string().trim().optional(), environment: z.string().trim().optional(),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash), secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
include_imports: z include_imports: z
@ -68,6 +76,22 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
environment = scope[0].environment; environment = scope[0].environment;
workspaceId = req.auth.serviceToken.projectId; workspaceId = req.auth.serviceToken.projectId;
} }
} else if (req.permission.type === ActorType.IDENTITY && req.query.workspaceSlug && !workspaceId) {
const workspace = await server.services.project.getAProject({
filter: {
type: ProjectFilterType.SLUG,
orgId: req.permission.orgId,
slug: req.query.workspaceSlug
},
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
actorOrgId: req.permission.orgId
});
if (!workspace) throw new BadRequestError({ message: `No project found with slug ${req.query.workspaceSlug}` });
workspaceId = workspace.id;
} }
if (!workspaceId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" }); if (!workspaceId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" });
@ -77,13 +101,14 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
environment, environment,
actorAuthMethod: req.permission.authMethod,
projectId: workspaceId, projectId: workspaceId,
path: secretPath, path: secretPath,
includeImports: req.query.include_imports includeImports: req.query.include_imports
}); });
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
projectId: req.query.workspaceId, projectId: workspaceId,
...req.auditLogInfo, ...req.auditLogInfo,
event: { event: {
type: EventType.GET_SECRETS, type: EventType.GET_SECRETS,
@ -160,6 +185,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secret = await server.services.secret.getSecretByNameRaw({ const secret = await server.services.secret.getSecretByNameRaw({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
environment, environment,
projectId: workspaceId, projectId: workspaceId,
@ -237,6 +263,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
environment: req.body.environment, environment: req.body.environment,
actorAuthMethod: req.permission.authMethod,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
secretPath: req.body.secretPath, secretPath: req.body.secretPath,
secretName: req.params.secretName, secretName: req.params.secretName,
@ -312,6 +339,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
environment: req.body.environment, environment: req.body.environment,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
secretPath: req.body.secretPath, secretPath: req.body.secretPath,
@ -383,6 +411,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secret = await server.services.secret.deleteSecretRaw({ const secret = await server.services.secret.deleteSecretRaw({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
environment: req.body.environment, environment: req.body.environment,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
@ -478,6 +507,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const { secrets, imports } = await server.services.secret.getSecrets({ const { secrets, imports } = await server.services.secret.getSecrets({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
environment: req.query.environment, environment: req.query.environment,
projectId: req.query.workspaceId, projectId: req.query.workspaceId,
@ -564,6 +594,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secret = await server.services.secret.getSecretByName({ const secret = await server.services.secret.getSecretByName({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
environment: req.query.environment, environment: req.query.environment,
projectId: req.query.workspaceId, projectId: req.query.workspaceId,
@ -666,6 +697,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
if (req.body.type !== SecretType.Personal && req.permission.type === ActorType.USER) { if (req.body.type !== SecretType.Personal && req.permission.type === ActorType.USER) {
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({ const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type, actor: req.permission.type,
secretPath, secretPath,
environment, environment,
@ -675,6 +708,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -718,6 +752,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secret = await server.services.secret.createSecret({ const secret = await server.services.secret.createSecret({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
path: secretPath, path: secretPath,
type, type,
@ -842,6 +877,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({ const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -851,6 +887,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -896,6 +933,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secret = await server.services.secret.updateSecret({ const secret = await server.services.secret.updateSecret({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
path: secretPath, path: secretPath,
type, type,
@ -986,6 +1024,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({ const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -995,6 +1034,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -1028,6 +1068,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secret = await server.services.secret.deleteSecret({ const secret = await server.services.secret.deleteSecret({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
path: secretPath, path: secretPath,
type, type,
@ -1110,6 +1151,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({ const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -1119,6 +1161,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -1148,6 +1191,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secrets = await server.services.secret.createManySecret({ const secrets = await server.services.secret.createManySecret({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
path: secretPath, path: secretPath,
environment, environment,
@ -1231,6 +1275,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({ const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -1240,6 +1285,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -1268,6 +1314,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secrets = await server.services.secret.updateManySecret({ const secrets = await server.services.secret.updateManySecret({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
path: secretPath, path: secretPath,
environment, environment,
@ -1340,6 +1387,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({ const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -1349,6 +1397,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
secretPath, secretPath,
environment, environment,
@ -1376,6 +1425,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const secrets = await server.services.secret.deleteManySecret({ const secrets = await server.services.secret.deleteManySecret({
actorId: req.permission.id, actorId: req.permission.id,
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
path: req.body.secretPath, path: req.body.secretPath,
environment, environment,

View File

@ -108,7 +108,8 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => {
200: z.object({ 200: z.object({
message: z.string(), message: z.string(),
user: UsersSchema, user: UsersSchema,
token: z.string() token: z.string(),
organizationId: z.string().nullish()
}) })
} }
}, },
@ -124,12 +125,13 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => {
}); });
} }
const { user, accessToken, refreshToken } = await server.services.signup.completeEmailAccountSignup({ const { user, accessToken, refreshToken, organizationId } =
...req.body, await server.services.signup.completeEmailAccountSignup({
ip: req.realIp, ...req.body,
userAgent, ip: req.realIp,
authorization: req.headers.authorization as string userAgent,
}); authorization: req.headers.authorization as string
});
if (user.email) { if (user.email) {
void server.services.telemetry.sendLoopsEvent(user.email, user.firstName || "", user.lastName || ""); void server.services.telemetry.sendLoopsEvent(user.email, user.firstName || "", user.lastName || "");
@ -152,7 +154,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => {
secure: appCfg.HTTPS_ENABLED secure: appCfg.HTTPS_ENABLED
}); });
return { message: "Successfully set up account", user, token: accessToken }; return { message: "Successfully set up account", user, token: accessToken, organizationId };
} }
}); });

View File

@ -15,10 +15,10 @@ export const validateProviderAuthToken = (providerToken: string, username?: stri
if (decodedToken.username !== username) throw new Error("Invalid auth credentials"); if (decodedToken.username !== username) throw new Error("Invalid auth credentials");
if (decodedToken.organizationId) { if (decodedToken.organizationId) {
return { orgId: decodedToken.organizationId }; return { orgId: decodedToken.organizationId, authMethod: decodedToken.authMethod };
} }
return {}; return { authMethod: decodedToken.authMethod, orgId: null };
}; };
export const validateSignUpAuthorization = (token: string, userId: string, validate = true) => { export const validateSignUpAuthorization = (token: string, userId: string, validate = true) => {

View File

@ -1,13 +1,16 @@
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import { TUsers, UserDeviceSchema } from "@app/db/schemas"; import { TUsers, UserDeviceSchema } from "@app/db/schemas";
import { isAuthMethodSaml } from "@app/ee/services/permission/permission-fns";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { generateSrpServerKey, srpCheckClientProof } from "@app/lib/crypto"; import { generateSrpServerKey, srpCheckClientProof } from "@app/lib/crypto";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { getServerCfg } from "@app/services/super-admin/super-admin-service"; import { getServerCfg } from "@app/services/super-admin/super-admin-service";
import { TTokenDALFactory } from "../auth-token/auth-token-dal";
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
import { TokenType } from "../auth-token/auth-token-types"; import { TokenType } from "../auth-token/auth-token-types";
import { TOrgDALFactory } from "../org/org-dal";
import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service"; import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service";
import { TUserDALFactory } from "../user/user-dal"; import { TUserDALFactory } from "../user/user-dal";
import { validateProviderAuthToken } from "./auth-fns"; import { validateProviderAuthToken } from "./auth-fns";
@ -17,16 +20,24 @@ import {
TOauthLoginDTO, TOauthLoginDTO,
TVerifyMfaTokenDTO TVerifyMfaTokenDTO
} from "./auth-login-type"; } from "./auth-login-type";
import { AuthMethod, AuthTokenType } from "./auth-type"; import { AuthMethod, AuthModeJwtTokenPayload, AuthModeMfaJwtTokenPayload, AuthTokenType } from "./auth-type";
type TAuthLoginServiceFactoryDep = { type TAuthLoginServiceFactoryDep = {
userDAL: TUserDALFactory; userDAL: TUserDALFactory;
orgDAL: TOrgDALFactory;
tokenService: TAuthTokenServiceFactory; tokenService: TAuthTokenServiceFactory;
smtpService: TSmtpService; smtpService: TSmtpService;
tokenDAL: TTokenDALFactory;
}; };
export type TAuthLoginFactory = ReturnType<typeof authLoginServiceFactory>; export type TAuthLoginFactory = ReturnType<typeof authLoginServiceFactory>;
export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: TAuthLoginServiceFactoryDep) => { export const authLoginServiceFactory = ({
userDAL,
tokenService,
smtpService,
orgDAL,
tokenDAL
}: TAuthLoginServiceFactoryDep) => {
/* /*
* Private * Private
* Not exported. This is to update user device list * Not exported. This is to update user device list
@ -83,12 +94,14 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
user, user,
ip, ip,
userAgent, userAgent,
organizationId organizationId,
authMethod
}: { }: {
user: TUsers; user: TUsers;
ip: string; ip: string;
userAgent: string; userAgent: string;
organizationId?: string; organizationId: string | undefined;
authMethod: AuthMethod;
}) => { }) => {
const cfg = getConfig(); const cfg = getConfig();
await updateUserDeviceSession(user, ip, userAgent); await updateUserDeviceSession(user, ip, userAgent);
@ -98,8 +111,10 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
userId: user.id userId: user.id
}); });
if (!tokenSession) throw new Error("Failed to create token"); if (!tokenSession) throw new Error("Failed to create token");
const accessToken = jwt.sign( const accessToken = jwt.sign(
{ {
authMethod,
authTokenType: AuthTokenType.ACCESS_TOKEN, authTokenType: AuthTokenType.ACCESS_TOKEN,
userId: user.id, userId: user.id,
tokenVersionId: tokenSession.id, tokenVersionId: tokenSession.id,
@ -112,6 +127,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
const refreshToken = jwt.sign( const refreshToken = jwt.sign(
{ {
authMethod,
authTokenType: AuthTokenType.REFRESH_TOKEN, authTokenType: AuthTokenType.REFRESH_TOKEN,
userId: user.id, userId: user.id,
tokenVersionId: tokenSession.id, tokenVersionId: tokenSession.id,
@ -158,9 +174,9 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
const loginExchangeClientProof = async ({ const loginExchangeClientProof = async ({
email, email,
clientProof, clientProof,
providerAuthToken,
ip, ip,
userAgent userAgent,
providerAuthToken
}: TLoginClientProofDTO) => { }: TLoginClientProofDTO) => {
const userEnc = await userDAL.findUserEncKeyByUsername({ const userEnc = await userDAL.findUserEncKeyByUsername({
username: email username: email
@ -168,14 +184,16 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
if (!userEnc) throw new Error("Failed to find user"); if (!userEnc) throw new Error("Failed to find user");
const cfg = getConfig(); const cfg = getConfig();
let organizationId; let authMethod = AuthMethod.EMAIL;
if (!userEnc.authMethods?.includes(AuthMethod.EMAIL)) { let organizationId: string | undefined;
const { orgId } = validateProviderAuthToken(providerAuthToken as string, email);
organizationId = orgId; if (providerAuthToken) {
} else if (providerAuthToken) { const decodedProviderToken = validateProviderAuthToken(providerAuthToken, email);
// SAML SSO
const { orgId } = validateProviderAuthToken(providerAuthToken, email); authMethod = decodedProviderToken.authMethod;
organizationId = orgId; if (isAuthMethodSaml(authMethod) && decodedProviderToken.orgId) {
organizationId = decodedProviderToken.orgId;
}
} }
if (!userEnc.serverPrivateKey || !userEnc.clientPublicKey) throw new Error("Failed to authenticate. Try again?"); if (!userEnc.serverPrivateKey || !userEnc.clientPublicKey) throw new Error("Failed to authenticate. Try again?");
@ -196,9 +214,9 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
if (userEnc.isMfaEnabled && userEnc.email) { if (userEnc.isMfaEnabled && userEnc.email) {
const mfaToken = jwt.sign( const mfaToken = jwt.sign(
{ {
authMethod,
authTokenType: AuthTokenType.MFA_TOKEN, authTokenType: AuthTokenType.MFA_TOKEN,
userId: userEnc.userId, userId: userEnc.userId
organizationId
}, },
cfg.AUTH_SECRET, cfg.AUTH_SECRET,
{ {
@ -221,12 +239,60 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
}, },
ip, ip,
userAgent, userAgent,
authMethod,
organizationId organizationId
}); });
return { token, isMfaEnabled: false, user: userEnc } as const; return { token, isMfaEnabled: false, user: userEnc } as const;
}; };
const selectOrganization = async ({
userAgent,
authJwtToken,
ipAddress,
organizationId
}: {
userAgent: string | undefined;
authJwtToken: string | undefined;
ipAddress: string;
organizationId: string;
}) => {
const cfg = getConfig();
if (!authJwtToken) throw new UnauthorizedError({ name: "Authorization header is required" });
if (!userAgent) throw new UnauthorizedError({ name: "user agent header is required" });
// eslint-disable-next-line no-param-reassign
authJwtToken = authJwtToken.replace("Bearer ", ""); // remove bearer from token
// The decoded JWT token, which contains the auth method.
const decodedToken = jwt.verify(authJwtToken, cfg.AUTH_SECRET) as AuthModeJwtTokenPayload;
if (!decodedToken.authMethod) throw new UnauthorizedError({ name: "Auth method not found on existing token" });
const user = await userDAL.findUserEncKeyByUserId(decodedToken.userId);
if (!user) throw new BadRequestError({ message: "User not found", name: "Find user from token" });
// Check if the user actually has access to the specified organization.
const userOrgs = await orgDAL.findAllOrgsByUserId(user.id);
const hasOrganizationMembership = userOrgs.some((org) => org.id === organizationId);
if (!hasOrganizationMembership) {
throw new UnauthorizedError({ message: "User does not have access to the organization" });
}
await tokenDAL.incrementTokenSessionVersion(user.id, decodedToken.tokenVersionId);
const tokens = await generateUserTokens({
authMethod: decodedToken.authMethod,
user,
userAgent,
ip: ipAddress,
organizationId
});
return tokens;
};
/* /*
* Multi factor authentication re-send code, Get user id from token * Multi factor authentication re-send code, Get user id from token
* saved in frontend * saved in frontend
@ -244,12 +310,15 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
* Multi factor authentication verification of code * Multi factor authentication verification of code
* Third step of login in which user completes with mfa * Third step of login in which user completes with mfa
* */ * */
const verifyMfaToken = async ({ userId, mfaToken, ip, userAgent, orgId }: TVerifyMfaTokenDTO) => { const verifyMfaToken = async ({ userId, mfaToken, mfaJwtToken, ip, userAgent, orgId }: TVerifyMfaTokenDTO) => {
await tokenService.validateTokenForUser({ await tokenService.validateTokenForUser({
type: TokenType.TOKEN_EMAIL_MFA, type: TokenType.TOKEN_EMAIL_MFA,
userId, userId,
code: mfaToken code: mfaToken
}); });
const decodedToken = jwt.verify(mfaJwtToken, getConfig().AUTH_SECRET) as AuthModeMfaJwtTokenPayload;
const userEnc = await userDAL.findUserEncKeyByUserId(userId); const userEnc = await userDAL.findUserEncKeyByUserId(userId);
if (!userEnc) throw new Error("Failed to authenticate user"); if (!userEnc) throw new Error("Failed to authenticate user");
@ -260,7 +329,8 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
}, },
ip, ip,
userAgent, userAgent,
organizationId: orgId organizationId: orgId,
authMethod: decodedToken.authMethod
}); });
return { token, user: userEnc }; return { token, user: userEnc };
@ -339,6 +409,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
oauth2Login, oauth2Login,
resendMfaToken, resendMfaToken,
verifyMfaToken, verifyMfaToken,
selectOrganization,
generateUserTokens generateUserTokens
}; };
}; };

View File

@ -17,6 +17,7 @@ export type TLoginClientProofDTO = {
export type TVerifyMfaTokenDTO = { export type TVerifyMfaTokenDTO = {
userId: string; userId: string;
mfaToken: string; mfaToken: string;
mfaJwtToken: string;
ip: string; ip: string;
userAgent: string; userAgent: string;
orgId?: string; orgId?: string;

View File

@ -150,11 +150,15 @@ export const authSignupServiceFactory = ({
}); });
if (!organizationId) { if (!organizationId) {
await orgService.createOrganization({ const newOrganization = await orgService.createOrganization({
userId: user.id, userId: user.id,
userEmail: user.email ?? user.username, userEmail: user.email ?? user.username,
orgName: organizationName orgName: organizationName
}); });
if (!newOrganization) throw new Error("Failed to create organization");
organizationId = newOrganization.id;
} }
const updatedMembersips = await orgDAL.updateMembership( const updatedMembersips = await orgDAL.updateMembership(
@ -174,6 +178,7 @@ export const authSignupServiceFactory = ({
const accessToken = jwt.sign( const accessToken = jwt.sign(
{ {
authMethod: AuthMethod.EMAIL,
authTokenType: AuthTokenType.ACCESS_TOKEN, authTokenType: AuthTokenType.ACCESS_TOKEN,
userId: updateduser.info.id, userId: updateduser.info.id,
tokenVersionId: tokenSession.id, tokenVersionId: tokenSession.id,
@ -186,6 +191,7 @@ export const authSignupServiceFactory = ({
const refreshToken = jwt.sign( const refreshToken = jwt.sign(
{ {
authMethod: AuthMethod.EMAIL,
authTokenType: AuthTokenType.REFRESH_TOKEN, authTokenType: AuthTokenType.REFRESH_TOKEN,
userId: updateduser.info.id, userId: updateduser.info.id,
tokenVersionId: tokenSession.id, tokenVersionId: tokenSession.id,
@ -196,7 +202,7 @@ export const authSignupServiceFactory = ({
{ expiresIn: appCfg.JWT_REFRESH_LIFETIME } { expiresIn: appCfg.JWT_REFRESH_LIFETIME }
); );
return { user: updateduser.info, accessToken, refreshToken }; return { user: updateduser.info, accessToken, refreshToken, organizationId };
}; };
/* /*
@ -277,6 +283,7 @@ export const authSignupServiceFactory = ({
const accessToken = jwt.sign( const accessToken = jwt.sign(
{ {
authMethod: AuthMethod.EMAIL,
authTokenType: AuthTokenType.ACCESS_TOKEN, authTokenType: AuthTokenType.ACCESS_TOKEN,
userId: updateduser.info.id, userId: updateduser.info.id,
tokenVersionId: tokenSession.id, tokenVersionId: tokenSession.id,
@ -288,6 +295,7 @@ export const authSignupServiceFactory = ({
const refreshToken = jwt.sign( const refreshToken = jwt.sign(
{ {
authMethod: AuthMethod.EMAIL,
authTokenType: AuthTokenType.REFRESH_TOKEN, authTokenType: AuthTokenType.REFRESH_TOKEN,
userId: updateduser.info.id, userId: updateduser.info.id,
tokenVersionId: tokenSession.id, tokenVersionId: tokenSession.id,

View File

@ -6,6 +6,7 @@ export enum AuthMethod {
OKTA_SAML = "okta-saml", OKTA_SAML = "okta-saml",
AZURE_SAML = "azure-saml", AZURE_SAML = "azure-saml",
JUMPCLOUD_SAML = "jumpcloud-saml", JUMPCLOUD_SAML = "jumpcloud-saml",
GOOGLE_SAML = "google-saml",
LDAP = "ldap" LDAP = "ldap"
} }
@ -38,8 +39,12 @@ export enum ActorType { // would extend to AWS, Azure, ...
SCIM_CLIENT = "scimClient" SCIM_CLIENT = "scimClient"
} }
// This will be null unless the token-type is JWT
export type ActorAuthMethod = AuthMethod | null;
export type AuthModeJwtTokenPayload = { export type AuthModeJwtTokenPayload = {
authTokenType: AuthTokenType.ACCESS_TOKEN; authTokenType: AuthTokenType.ACCESS_TOKEN;
authMethod: AuthMethod;
userId: string; userId: string;
tokenVersionId: string; tokenVersionId: string;
accessVersion: number; accessVersion: number;
@ -48,12 +53,15 @@ export type AuthModeJwtTokenPayload = {
export type AuthModeMfaJwtTokenPayload = { export type AuthModeMfaJwtTokenPayload = {
authTokenType: AuthTokenType.MFA_TOKEN; authTokenType: AuthTokenType.MFA_TOKEN;
authMethod: AuthMethod;
userId: string; userId: string;
organizationId?: string; organizationId?: string;
}; };
export type AuthModeRefreshJwtTokenPayload = { export type AuthModeRefreshJwtTokenPayload = {
// authMode
authTokenType: AuthTokenType.REFRESH_TOKEN; authTokenType: AuthTokenType.REFRESH_TOKEN;
authMethod: AuthMethod;
userId: string; userId: string;
tokenVersionId: string; tokenVersionId: string;
refreshVersion: number; refreshVersion: number;
@ -63,6 +71,8 @@ export type AuthModeRefreshJwtTokenPayload = {
export type AuthModeProviderJwtTokenPayload = { export type AuthModeProviderJwtTokenPayload = {
authTokenType: AuthTokenType.PROVIDER_TOKEN; authTokenType: AuthTokenType.PROVIDER_TOKEN;
username: string; username: string;
authMethod: AuthMethod;
email: string;
organizationId?: string; organizationId?: string;
}; };

View File

@ -6,17 +6,20 @@ import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { checkIPAgainstBlocklist, TIp } from "@app/lib/ip"; import { checkIPAgainstBlocklist, TIp } from "@app/lib/ip";
import { AuthTokenType } from "../auth/auth-type"; import { AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TIdentityAccessTokenDALFactory } from "./identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "./identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload, TRenewAccessTokenDTO } from "./identity-access-token-types"; import { TIdentityAccessTokenJwtPayload, TRenewAccessTokenDTO } from "./identity-access-token-types";
type TIdentityAccessTokenServiceFactoryDep = { type TIdentityAccessTokenServiceFactoryDep = {
identityAccessTokenDAL: TIdentityAccessTokenDALFactory; identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
identityOrgMembershipDAL: TIdentityOrgDALFactory;
}; };
export type TIdentityAccessTokenServiceFactory = ReturnType<typeof identityAccessTokenServiceFactory>; export type TIdentityAccessTokenServiceFactory = ReturnType<typeof identityAccessTokenServiceFactory>;
export const identityAccessTokenServiceFactory = ({ export const identityAccessTokenServiceFactory = ({
identityAccessTokenDAL identityAccessTokenDAL,
identityOrgMembershipDAL
}: TIdentityAccessTokenServiceFactoryDep) => { }: TIdentityAccessTokenServiceFactoryDep) => {
const validateAccessTokenExp = (identityAccessToken: TIdentityAccessTokens) => { const validateAccessTokenExp = (identityAccessToken: TIdentityAccessTokens) => {
const { const {
@ -117,8 +120,16 @@ export const identityAccessTokenServiceFactory = ({
}); });
} }
const identityOrgMembership = await identityOrgMembershipDAL.findOne({
identityId: identityAccessToken.identityId
});
if (!identityOrgMembership) {
throw new UnauthorizedError({ message: "Identity does not belong to any organization" });
}
validateAccessTokenExp(identityAccessToken); validateAccessTokenExp(identityAccessToken);
return identityAccessToken; return { ...identityAccessToken, orgId: identityOrgMembership.orgId };
}; };
return { renewAccessToken, fnValidateIdentityAccessToken }; return { renewAccessToken, fnValidateIdentityAccessToken };

View File

@ -49,10 +49,17 @@ export const identityProjectServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
role role
}: TCreateProjectIdentityDTO) => { }: TCreateProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Identity);
const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId }); const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId });
@ -112,9 +119,16 @@ export const identityProjectServiceFactory = ({
roles, roles,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TUpdateProjectIdentityDTO) => { }: TUpdateProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity);
const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId }); const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId });
@ -127,6 +141,7 @@ export const identityProjectServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
projectIdentity.identityId, projectIdentity.identityId,
projectIdentity.projectId, projectIdentity.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
@ -185,6 +200,7 @@ export const identityProjectServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId projectId
}: TDeleteProjectIdentityDTO) => { }: TDeleteProjectIdentityDTO) => {
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId }); const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
@ -195,6 +211,7 @@ export const identityProjectServiceFactory = ({
actor, actor,
actorId, actorId,
identityProjectMembership.projectId, identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Identity);
@ -202,6 +219,7 @@ export const identityProjectServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityId, identityId,
identityProjectMembership.projectId, identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
@ -212,8 +230,20 @@ export const identityProjectServiceFactory = ({
return deletedIdentity; return deletedIdentity;
}; };
const listProjectIdentities = async ({ projectId, actor, actorId, actorOrgId }: TListProjectIdentityDTO) => { const listProjectIdentities = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); projectId,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TListProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Identity);
const identityMemberhips = await identityProjectDAL.findByProjectId(projectId); const identityMemberhips = await identityProjectDAL.findByProjectId(projectId);

View File

@ -144,6 +144,7 @@ export const identityUaServiceFactory = ({
accessTokenTrustedIps, accessTokenTrustedIps,
clientSecretTrustedIps, clientSecretTrustedIps,
actorId, actorId,
actorAuthMethod,
actor, actor,
actorOrgId actorOrgId
}: TAttachUaDTO) => { }: TAttachUaDTO) => {
@ -162,6 +163,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
@ -233,6 +235,7 @@ export const identityUaServiceFactory = ({
accessTokenTrustedIps, accessTokenTrustedIps,
clientSecretTrustedIps, clientSecretTrustedIps,
actorId, actorId,
actorAuthMethod,
actor, actor,
actorOrgId actorOrgId
}: TUpdateUaDTO) => { }: TUpdateUaDTO) => {
@ -256,6 +259,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
@ -308,7 +312,7 @@ export const identityUaServiceFactory = ({
return { ...updatedUaAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedUaAuth, orgId: identityMembershipOrg.orgId };
}; };
const getIdentityUa = async ({ identityId, actorId, actor, actorOrgId }: TGetUaDTO) => { const getIdentityUa = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral) if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
@ -322,6 +326,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
@ -334,6 +339,7 @@ export const identityUaServiceFactory = ({
actorOrgId, actorOrgId,
identityId, identityId,
ttl, ttl,
actorAuthMethod,
description, description,
numUsesLimit numUsesLimit
}: TCreateUaClientSecretDTO) => { }: TCreateUaClientSecretDTO) => {
@ -347,6 +353,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
@ -355,6 +362,7 @@ export const identityUaServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identityId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission); const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
@ -388,7 +396,13 @@ export const identityUaServiceFactory = ({
}; };
}; };
const getUaClientSecrets = async ({ actor, actorId, actorOrgId, identityId }: TGetUaClientSecretsDTO) => { const getUaClientSecrets = async ({
actor,
actorId,
actorOrgId,
actorAuthMethod,
identityId
}: TGetUaClientSecretsDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral) if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
@ -399,6 +413,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
@ -407,6 +422,7 @@ export const identityUaServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identityId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission); const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
@ -431,6 +447,7 @@ export const identityUaServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
clientSecretId clientSecretId
}: TRevokeUaClientSecretDTO) => { }: TRevokeUaClientSecretDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
@ -443,6 +460,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity);
@ -451,6 +469,7 @@ export const identityUaServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identityId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission); const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);

View File

@ -25,8 +25,16 @@ export const identityServiceFactory = ({
identityOrgMembershipDAL, identityOrgMembershipDAL,
permissionService permissionService
}: TIdentityServiceFactoryDep) => { }: TIdentityServiceFactoryDep) => {
const createIdentity = async ({ name, role, actor, orgId, actorId, actorOrgId }: TCreateIdentityDTO) => { const createIdentity = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); name,
role,
actor,
orgId,
actorId,
actorAuthMethod,
actorOrgId
}: TCreateIdentityDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole( const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole(
@ -54,7 +62,15 @@ export const identityServiceFactory = ({
return identity; return identity;
}; };
const updateIdentity = async ({ id, role, name, actor, actorId, actorOrgId }: TUpdateIdentityDTO) => { const updateIdentity = async ({
id,
role,
name,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TUpdateIdentityDTO) => {
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id });
if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` });
@ -62,6 +78,7 @@ export const identityServiceFactory = ({
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
@ -70,6 +87,7 @@ export const identityServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
id, id,
identityOrgMembership.orgId, identityOrgMembership.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
@ -108,7 +126,7 @@ export const identityServiceFactory = ({
return { ...identity, orgId: identityOrgMembership.orgId }; return { ...identity, orgId: identityOrgMembership.orgId };
}; };
const deleteIdentity = async ({ actorId, actor, actorOrgId, id }: TDeleteIdentityDTO) => { const deleteIdentity = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteIdentityDTO) => {
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id });
if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` });
@ -116,13 +134,16 @@ export const identityServiceFactory = ({
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity);
const { permission: identityRolePermission } = await permissionService.getOrgPermission( const { permission: identityRolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
id, id,
identityOrgMembership.orgId identityOrgMembership.orgId,
actorAuthMethod,
actorOrgId
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
if (!hasRequiredPriviledges) if (!hasRequiredPriviledges)
@ -132,8 +153,8 @@ export const identityServiceFactory = ({
return { ...deletedIdentity, orgId: identityOrgMembership.orgId }; return { ...deletedIdentity, orgId: identityOrgMembership.orgId };
}; };
const listOrgIdentities = async ({ orgId, actor, actorId, actorOrgId }: TOrgPermission) => { const listOrgIdentities = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgPermission) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
const identityMemberhips = await identityOrgMembershipDAL.findByOrgId(orgId); const identityMemberhips = await identityOrgMembershipDAL.findByOrgId(orgId);

View File

@ -61,14 +61,26 @@ export const integrationAuthServiceFactory = ({
projectBotDAL, projectBotDAL,
projectBotService projectBotService
}: TIntegrationAuthServiceFactoryDep) => { }: TIntegrationAuthServiceFactoryDep) => {
const listIntegrationAuthByProjectId = async ({ actorId, actor, actorOrgId, projectId }: TProjectPermission) => { const listIntegrationAuthByProjectId = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const authorizations = await integrationAuthDAL.find({ projectId }); const authorizations = await integrationAuthDAL.find({ projectId });
return authorizations; return authorizations;
}; };
const getIntegrationAuth = async ({ actor, id, actorId, actorOrgId }: TGetIntegrationAuthDTO) => { const getIntegrationAuth = async ({ actor, id, actorId, actorAuthMethod, actorOrgId }: TGetIntegrationAuthDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -76,6 +88,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -87,6 +100,7 @@ export const integrationAuthServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
integration, integration,
url, url,
code code
@ -94,7 +108,13 @@ export const integrationAuthServiceFactory = ({
if (!Object.values(Integrations).includes(integration as Integrations)) if (!Object.values(Integrations).includes(integration as Integrations))
throw new BadRequestError({ message: "Invalid integration" }); throw new BadRequestError({ message: "Invalid integration" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.findOne({ isActive: true, projectId }); const bot = await projectBotDAL.findOne({ isActive: true, projectId });
@ -150,6 +170,7 @@ export const integrationAuthServiceFactory = ({
url, url,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
accessId, accessId,
namespace, namespace,
accessToken accessToken
@ -157,7 +178,13 @@ export const integrationAuthServiceFactory = ({
if (!Object.values(Integrations).includes(integration as Integrations)) if (!Object.values(Integrations).includes(integration as Integrations))
throw new BadRequestError({ message: "Invalid integration" }); throw new BadRequestError({ message: "Invalid integration" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.findOne({ isActive: true, projectId }); const bot = await projectBotDAL.findOne({ isActive: true, projectId });
@ -274,6 +301,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
teamId, teamId,
id, id,
workspaceSlug workspaceSlug
@ -285,6 +313,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -302,7 +331,13 @@ export const integrationAuthServiceFactory = ({
return apps; return apps;
}; };
const getIntegrationAuthTeams = async ({ actor, actorId, actorOrgId, id }: TIntegrationAuthTeamsDTO) => { const getIntegrationAuthTeams = async ({
actor,
actorId,
actorAuthMethod,
actorOrgId,
id
}: TIntegrationAuthTeamsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -310,6 +345,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -324,7 +360,14 @@ export const integrationAuthServiceFactory = ({
return teams; return teams;
}; };
const getVercelBranches = async ({ appId, id, actor, actorId, actorOrgId }: TIntegrationAuthVercelBranchesDTO) => { const getVercelBranches = async ({
appId,
id,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TIntegrationAuthVercelBranchesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -332,6 +375,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -357,7 +401,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getChecklyGroups = async ({ actorId, actor, actorOrgId, id, accountId }: TIntegrationAuthChecklyGroupsDTO) => { const getChecklyGroups = async ({
actorId,
actor,
actorOrgId,
actorAuthMethod,
id,
accountId
}: TIntegrationAuthChecklyGroupsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -365,6 +416,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -383,7 +435,7 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getQoveryOrgs = async ({ actorId, actor, actorOrgId, id }: TIntegrationAuthQoveryOrgsDTO) => { const getQoveryOrgs = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TIntegrationAuthQoveryOrgsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -391,6 +443,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -409,7 +462,14 @@ export const integrationAuthServiceFactory = ({
return data.results.map(({ name, id: orgId }) => ({ name, orgId })); return data.results.map(({ name, id: orgId }) => ({ name, orgId }));
}; };
const getQoveryProjects = async ({ actorId, actor, actorOrgId, id, orgId }: TIntegrationAuthQoveryProjectDTO) => { const getQoveryProjects = async ({
actorId,
actor,
actorOrgId,
actorAuthMethod,
id,
orgId
}: TIntegrationAuthQoveryProjectDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -417,6 +477,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -442,6 +503,7 @@ export const integrationAuthServiceFactory = ({
id, id,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TIntegrationAuthQoveryEnvironmentsDTO) => { }: TIntegrationAuthQoveryEnvironmentsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@ -451,6 +513,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -476,7 +539,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getQoveryApps = async ({ id, actor, actorId, actorOrgId, environmentId }: TIntegrationAuthQoveryScopesDTO) => { const getQoveryApps = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -484,6 +554,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -513,6 +584,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environmentId environmentId
}: TIntegrationAuthQoveryScopesDTO) => { }: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@ -522,6 +594,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -546,7 +619,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getQoveryJobs = async ({ id, actor, actorId, actorOrgId, environmentId }: TIntegrationAuthQoveryScopesDTO) => { const getQoveryJobs = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -554,6 +634,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -578,7 +659,13 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getHerokuPipelines = async ({ id, actor, actorId, actorOrgId }: TIntegrationAuthHerokuPipelinesDTO) => { const getHerokuPipelines = async ({
id,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TIntegrationAuthHerokuPipelinesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -586,6 +673,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -610,7 +698,14 @@ export const integrationAuthServiceFactory = ({
})); }));
}; };
const getRailwayEnvironments = async ({ id, actor, actorId, actorOrgId, appId }: TIntegrationAuthRailwayEnvDTO) => { const getRailwayEnvironments = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
appId
}: TIntegrationAuthRailwayEnvDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -618,6 +713,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -670,7 +766,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getRailwayServices = async ({ id, actor, actorId, actorOrgId, appId }: TIntegrationAuthRailwayServicesDTO) => { const getRailwayServices = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
appId
}: TIntegrationAuthRailwayServicesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -678,6 +781,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -737,7 +841,13 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getBitbucketWorkspaces = async ({ actorId, actor, actorOrgId, id }: TIntegrationAuthBitbucketWorkspaceDTO) => { const getBitbucketWorkspaces = async ({
actorId,
actor,
actorOrgId,
actorAuthMethod,
id
}: TIntegrationAuthBitbucketWorkspaceDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -745,6 +855,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -756,9 +867,7 @@ export const integrationAuthServiceFactory = ({
while (hasNextPage) { while (hasNextPage) {
// eslint-disable-next-line // eslint-disable-next-line
const { data }: { data: { values: TBitbucketWorkspace[]; next: string } } = await request.get( const { data }: { data: { values: TBitbucketWorkspace[]; next: string } } = await request.get(workspaceUrl, {
workspaceUrl,
{
headers: { headers: {
Authorization: `Bearer ${accessToken}`, Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json" "Accept-Encoding": "application/json"
@ -785,6 +894,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
appId appId
}: TIntegrationAuthNorthflankSecretGroupDTO) => { }: TIntegrationAuthNorthflankSecretGroupDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@ -794,6 +904,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -851,6 +962,7 @@ export const integrationAuthServiceFactory = ({
id, id,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
actor actor
}: TGetIntegrationAuthTeamCityBuildConfigDTO) => { }: TGetIntegrationAuthTeamCityBuildConfigDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@ -860,6 +972,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@ -891,16 +1004,29 @@ export const integrationAuthServiceFactory = ({
integration, integration,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteIntegrationAuthsDTO) => { }: TDeleteIntegrationAuthsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
const integrations = await integrationAuthDAL.delete({ integration, projectId }); const integrations = await integrationAuthDAL.delete({ integration, projectId });
return integrations; return integrations;
}; };
const deleteIntegrationAuthById = async ({ id, actorId, actor, actorOrgId }: TDeleteIntegrationAuthByIdDTO) => { const deleteIntegrationAuthById = async ({
id,
actorId,
actor,
actorAuthMethod,
actorOrgId
}: TDeleteIntegrationAuthByIdDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@ -908,6 +1034,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);

View File

@ -42,6 +42,7 @@ export const integrationServiceFactory = ({
metadata, metadata,
secretPath, secretPath,
targetService, targetService,
actorAuthMethod,
targetServiceId, targetServiceId,
integrationAuthId, integrationAuthId,
sourceEnvironment, sourceEnvironment,
@ -55,6 +56,7 @@ export const integrationServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
@ -93,6 +95,7 @@ export const integrationServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
targetEnvironment, targetEnvironment,
app, app,
id, id,
@ -109,6 +112,7 @@ export const integrationServiceFactory = ({
actor, actor,
actorId, actorId,
integration.projectId, integration.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
@ -129,7 +133,7 @@ export const integrationServiceFactory = ({
return updatedIntegration; return updatedIntegration;
}; };
const deleteIntegration = async ({ actorId, id, actor, actorOrgId }: TDeleteIntegrationDTO) => { const deleteIntegration = async ({ actorId, id, actor, actorAuthMethod, actorOrgId }: TDeleteIntegrationDTO) => {
const integration = await integrationDAL.findById(id); const integration = await integrationDAL.findById(id);
if (!integration) throw new BadRequestError({ message: "Integration auth not found" }); if (!integration) throw new BadRequestError({ message: "Integration auth not found" });
@ -137,6 +141,7 @@ export const integrationServiceFactory = ({
actor, actor,
actorId, actorId,
integration.projectId, integration.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
@ -145,8 +150,20 @@ export const integrationServiceFactory = ({
return { ...integration, ...deletedIntegration }; return { ...integration, ...deletedIntegration };
}; };
const listIntegrationByProject = async ({ actor, actorId, actorOrgId, projectId }: TProjectPermission) => { const listIntegrationByProject = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
projectId
}: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const integrations = await integrationDAL.findByProjectId(projectId); const integrations = await integrationDAL.findByProjectId(projectId);

View File

@ -12,6 +12,7 @@ import {
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { ActorAuthMethod } from "../auth/auth-type";
import { TOrgRoleDALFactory } from "./org-role-dal"; import { TOrgRoleDALFactory } from "./org-role-dal";
type TOrgRoleServiceFactoryDep = { type TOrgRoleServiceFactoryDep = {
@ -26,9 +27,10 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
userId: string, userId: string,
orgId: string, orgId: string,
data: Omit<TOrgRolesInsert, "orgId">, data: Omit<TOrgRolesInsert, "orgId">,
actorOrgId?: string actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Role);
const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId }); const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId });
if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" }); if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" });
@ -45,9 +47,10 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
orgId: string, orgId: string,
roleId: string, roleId: string,
data: Omit<TOrgRolesUpdate, "orgId">, data: Omit<TOrgRolesUpdate, "orgId">,
actorOrgId?: string actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Role);
if (data?.slug) { if (data?.slug) {
const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId }); const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId });
@ -62,8 +65,14 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
return updatedRole; return updatedRole;
}; };
const deleteRole = async (userId: string, orgId: string, roleId: string, actorOrgId?: string) => { const deleteRole = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
roleId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Role);
const [deletedRole] = await orgRoleDAL.delete({ id: roleId, orgId }); const [deletedRole] = await orgRoleDAL.delete({ id: roleId, orgId });
if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" }); if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" });
@ -71,8 +80,13 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
return deletedRole; return deletedRole;
}; };
const listRoles = async (userId: string, orgId: string, actorOrgId?: string) => { const listRoles = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Role);
const customRoles = await orgRoleDAL.find({ orgId }); const customRoles = await orgRoleDAL.find({ orgId });
const roles = [ const roles = [
@ -115,8 +129,18 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
return roles; return roles;
}; };
const getUserPermission = async (userId: string, orgId: string, actorOrgId?: string) => { const getUserPermission = async (
const { permission, membership } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission, membership } = await permissionService.getUserOrgPermission(
userId,
orgId,
actorAuthMethod,
actorOrgId
);
return { permissions: packRules(permission.rules), membership }; return { permissions: packRules(permission.rules), membership };
}; };

View File

@ -18,7 +18,7 @@ import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid"; import { alphaNumericNanoId } from "@app/lib/nanoid";
import { isDisposableEmail } from "@app/lib/validator"; import { isDisposableEmail } from "@app/lib/validator";
import { ActorType, AuthMethod, AuthTokenType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType, AuthMethod, AuthTokenType } from "../auth/auth-type";
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
import { TokenType } from "../auth-token/auth-token-types"; import { TokenType } from "../auth-token/auth-token-types";
import { TProjectDALFactory } from "../project/project-dal"; import { TProjectDALFactory } from "../project/project-dal";
@ -79,8 +79,13 @@ export const orgServiceFactory = ({
/* /*
* Get organization details by the organization id * Get organization details by the organization id
* */ * */
const findOrganizationById = async (userId: string, orgId: string, actorOrgId?: string) => { const findOrganizationById = async (
await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
const org = await orgDAL.findOrgById(orgId); const org = await orgDAL.findOrgById(orgId);
if (!org) throw new BadRequestError({ name: "Org not found", message: "Organization not found" }); if (!org) throw new BadRequestError({ name: "Org not found", message: "Organization not found" });
return org; return org;
@ -95,16 +100,28 @@ export const orgServiceFactory = ({
/* /*
* Get all workspace members * Get all workspace members
* */ * */
const findAllOrgMembers = async (userId: string, orgId: string, actorOrgId?: string) => { const findAllOrgMembers = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member);
const members = await orgDAL.findAllOrgMembers(orgId); const members = await orgDAL.findAllOrgMembers(orgId);
return members; return members;
}; };
const findOrgMembersByUsername = async ({ actor, actorId, orgId, emails }: TFindOrgMembersByEmailDTO) => { const findOrgMembersByUsername = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
orgId,
emails
}: TFindOrgMembersByEmailDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member);
const members = await orgDAL.findOrgMembersByUsername(orgId, emails); const members = await orgDAL.findOrgMembersByUsername(orgId, emails);
@ -112,8 +129,8 @@ export const orgServiceFactory = ({
return members; return members;
}; };
const findAllWorkspaces = async ({ actor, actorId, actorOrgId, orgId }: TFindAllWorkspacesDTO) => { const findAllWorkspaces = async ({ actor, actorId, actorOrgId, actorAuthMethod, orgId }: TFindAllWorkspacesDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Workspace); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Workspace);
const organizationWorkspaceIds = new Set((await projectDAL.find({ orgId })).map((workspace) => workspace.id)); const organizationWorkspaceIds = new Set((await projectDAL.find({ orgId })).map((workspace) => workspace.id));
@ -193,10 +210,11 @@ export const orgServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
orgId, orgId,
data: { name, slug, authEnforced, scimEnabled } data: { name, slug, authEnforced, scimEnabled }
}: TUpdateOrgDTO) => { }: TUpdateOrgDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
@ -309,8 +327,13 @@ export const orgServiceFactory = ({
/* /*
* Delete organization by id * Delete organization by id
* */ * */
const deleteOrganizationById = async (userId: string, orgId: string, actorOrgId?: string) => { const deleteOrganizationById = async (
const { membership } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { membership } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
if ((membership.role as OrgMembershipRole) !== OrgMembershipRole.Admin) if ((membership.role as OrgMembershipRole) !== OrgMembershipRole.Admin)
throw new UnauthorizedError({ name: "Delete org by id", message: "Not an admin" }); throw new UnauthorizedError({ name: "Delete org by id", message: "Not an admin" });
@ -324,8 +347,15 @@ export const orgServiceFactory = ({
* Org membership management * Org membership management
* Not another service because it has close ties with how an org works doesn't make sense to seperate them * Not another service because it has close ties with how an org works doesn't make sense to seperate them
* */ * */
const updateOrgMembership = async ({ role, orgId, userId, membershipId, actorOrgId }: TUpdateOrgMembershipDTO) => { const updateOrgMembership = async ({
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); role,
orgId,
userId,
membershipId,
actorAuthMethod,
actorOrgId
}: TUpdateOrgMembershipDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member);
const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole); const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole);
@ -355,8 +385,14 @@ export const orgServiceFactory = ({
/* /*
* Invite user to organization * Invite user to organization
*/ */
const inviteUserToOrganization = async ({ orgId, userId, inviteeEmail, actorOrgId }: TInviteUserToOrgDTO) => { const inviteUserToOrganization = async ({
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); orgId,
userId,
inviteeEmail,
actorAuthMethod,
actorOrgId
}: TInviteUserToOrgDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Member);
const org = await orgDAL.findOrgById(orgId); const org = await orgDAL.findOrgById(orgId);
@ -515,8 +551,14 @@ export const orgServiceFactory = ({
return { token, user }; return { token, user };
}; };
const deleteOrgMembership = async ({ orgId, userId, membershipId, actorOrgId }: TDeleteOrgMembershipDTO) => { const deleteOrgMembership = async ({
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); orgId,
userId,
membershipId,
actorAuthMethod,
actorOrgId
}: TDeleteOrgMembershipDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member);
const deletedMembership = await orgDAL.transaction(async (tx) => { const deletedMembership = await orgDAL.transaction(async (tx) => {
@ -568,15 +610,26 @@ export const orgServiceFactory = ({
/* /*
* CRUD operations of incident contacts * CRUD operations of incident contacts
* */ * */
const findIncidentContacts = async (userId: string, orgId: string, actorOrgId?: string) => { const findIncidentContacts = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount);
const incidentContacts = await incidentContactDAL.findByOrgId(orgId); const incidentContacts = await incidentContactDAL.findByOrgId(orgId);
return incidentContacts; return incidentContacts;
}; };
const createIncidentContact = async (userId: string, orgId: string, email: string, actorOrgId?: string) => { const createIncidentContact = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
email: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.IncidentAccount);
const doesIncidentContactExist = await incidentContactDAL.findOne(orgId, { email }); const doesIncidentContactExist = await incidentContactDAL.findOne(orgId, { email });
if (doesIncidentContactExist) { if (doesIncidentContactExist) {
@ -590,8 +643,14 @@ export const orgServiceFactory = ({
return incidentContact; return incidentContact;
}; };
const deleteIncidentContact = async (userId: string, orgId: string, id: string, actorOrgId?: string) => { const deleteIncidentContact = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
id: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.IncidentAccount);
const incidentContact = await incidentContactDAL.deleteById(id, orgId); const incidentContact = await incidentContactDAL.deleteById(id, orgId);

View File

@ -1,26 +1,29 @@
import { TOrgPermission } from "@app/lib/types"; import { TOrgPermission } from "@app/lib/types";
import { ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
export type TUpdateOrgMembershipDTO = { export type TUpdateOrgMembershipDTO = {
userId: string; userId: string;
orgId: string; orgId: string;
membershipId: string; membershipId: string;
role: string; role: string;
actorOrgId?: string; actorOrgId: string | undefined;
actorAuthMethod: ActorAuthMethod;
}; };
export type TDeleteOrgMembershipDTO = { export type TDeleteOrgMembershipDTO = {
userId: string; userId: string;
orgId: string; orgId: string;
membershipId: string; membershipId: string;
actorOrgId?: string; actorOrgId: string | undefined;
actorAuthMethod: ActorAuthMethod;
}; };
export type TInviteUserToOrgDTO = { export type TInviteUserToOrgDTO = {
userId: string; userId: string;
orgId: string; orgId: string;
actorOrgId?: string; actorOrgId: string | undefined;
actorAuthMethod: ActorAuthMethod;
inviteeEmail: string; inviteeEmail: string;
}; };
@ -32,7 +35,9 @@ export type TVerifyUserToOrgDTO = {
export type TFindOrgMembersByEmailDTO = { export type TFindOrgMembersByEmailDTO = {
actor: ActorType; actor: ActorType;
actorOrgId: string | undefined;
actorId: string; actorId: string;
actorAuthMethod: ActorAuthMethod;
orgId: string; orgId: string;
emails: string[]; emails: string[];
}; };
@ -40,7 +45,8 @@ export type TFindOrgMembersByEmailDTO = {
export type TFindAllWorkspacesDTO = { export type TFindAllWorkspacesDTO = {
actor: ActorType; actor: ActorType;
actorId: string; actorId: string;
actorOrgId?: string; actorOrgId: string | undefined;
actorAuthMethod: ActorAuthMethod;
orgId: string; orgId: string;
}; };

View File

@ -37,10 +37,17 @@ export const projectBotServiceFactory = ({
projectId, projectId,
actorOrgId, actorOrgId,
privateKey, privateKey,
actorAuthMethod,
botKey, botKey,
publicKey publicKey
}: TFindBotByProjectIdDTO) => { }: TFindBotByProjectIdDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.transaction(async (tx) => { const bot = await projectBotDAL.transaction(async (tx) => {
@ -88,11 +95,25 @@ export const projectBotServiceFactory = ({
} }
}; };
const setBotActiveState = async ({ actor, botId, botKey, actorId, actorOrgId, isActive }: TSetActiveStateDTO) => { const setBotActiveState = async ({
actor,
botId,
botKey,
actorId,
actorOrgId,
actorAuthMethod,
isActive
}: TSetActiveStateDTO) => {
const bot = await projectBotDAL.findById(botId); const bot = await projectBotDAL.findById(botId);
if (!bot) throw new BadRequestError({ message: "Bot not found" }); if (!bot) throw new BadRequestError({ message: "Bot not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, bot.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
bot.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
const project = await projectBotDAL.findProjectByBotId(botId); const project = await projectBotDAL.findProjectByBotId(botId);

View File

@ -27,8 +27,22 @@ export const projectEnvServiceFactory = ({
projectDAL, projectDAL,
folderDAL folderDAL
}: TProjectEnvServiceFactoryDep) => { }: TProjectEnvServiceFactoryDep) => {
const createEnvironment = async ({ projectId, actorId, actor, actorOrgId, name, slug }: TCreateEnvDTO) => { const createEnvironment = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); projectId,
actorId,
actor,
actorOrgId,
actorAuthMethod,
name,
slug
}: TCreateEnvDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Environments); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Environments);
const envs = await projectEnvDAL.find({ projectId }); const envs = await projectEnvDAL.find({ projectId });
@ -65,11 +79,18 @@ export const projectEnvServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
name, name,
id, id,
position position
}: TUpdateEnvDTO) => { }: TUpdateEnvDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Environments); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Environments);
const oldEnv = await projectEnvDAL.findOne({ id, projectId }); const oldEnv = await projectEnvDAL.findOne({ id, projectId });
@ -94,8 +115,14 @@ export const projectEnvServiceFactory = ({
return { environment: env, old: oldEnv }; return { environment: env, old: oldEnv };
}; };
const deleteEnvironment = async ({ projectId, actor, actorId, actorOrgId, id }: TDeleteEnvDTO) => { const deleteEnvironment = async ({ projectId, actor, actorId, actorOrgId, actorAuthMethod, id }: TDeleteEnvDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Environments); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Environments);
const env = await projectEnvDAL.transaction(async (tx) => { const env = await projectEnvDAL.transaction(async (tx) => {

View File

@ -26,11 +26,18 @@ export const projectKeyServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
nonce, nonce,
encryptedKey encryptedKey
}: TUploadProjectKeyDTO) => { }: TUploadProjectKeyDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
const receiverMembership = await projectMembershipDAL.findOne({ const receiverMembership = await projectMembershipDAL.findOne({
@ -46,14 +53,32 @@ export const projectKeyServiceFactory = ({
await projectKeyDAL.create({ projectId, receiverId, encryptedKey, nonce, senderId: actorId }); await projectKeyDAL.create({ projectId, receiverId, encryptedKey, nonce, senderId: actorId });
}; };
const getLatestProjectKey = async ({ actorId, projectId, actor, actorOrgId }: TGetLatestProjectKeyDTO) => { const getLatestProjectKey = async ({
await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
projectId,
actor,
actorOrgId,
actorAuthMethod
}: TGetLatestProjectKeyDTO) => {
await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
const latestKey = await projectKeyDAL.findLatestProjectKey(actorId, projectId); const latestKey = await projectKeyDAL.findLatestProjectKey(actorId, projectId);
return latestKey; return latestKey;
}; };
const getProjectPublicKeys = async ({ actor, actorId, actorOrgId, projectId }: TGetLatestProjectKeyDTO) => { const getProjectPublicKeys = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
projectId
}: TGetLatestProjectKeyDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
return projectKeyDAL.findAllProjectUserPubKeys(projectId); return projectKeyDAL.findAllProjectUserPubKeys(projectId);
}; };

View File

@ -67,8 +67,20 @@ export const projectMembershipServiceFactory = ({
projectKeyDAL, projectKeyDAL,
licenseService licenseService
}: TProjectMembershipServiceFactoryDep) => { }: TProjectMembershipServiceFactoryDep) => {
const getProjectMemberships = async ({ actorId, actor, actorOrgId, projectId }: TGetProjectMembershipDTO) => { const getProjectMemberships = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TGetProjectMembershipDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
return projectMembershipDAL.findAllProjectMembers(projectId); return projectMembershipDAL.findAllProjectMembers(projectId);
@ -79,13 +91,20 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
members, members,
sendEmails = true sendEmails = true
}: TAddUsersToWorkspaceDTO) => { }: TAddUsersToWorkspaceDTO) => {
const project = await projectDAL.findById(projectId); const project = await projectDAL.findById(projectId);
if (!project) throw new BadRequestError({ message: "Project not found" }); if (!project) throw new BadRequestError({ message: "Project not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member);
const orgMembers = await orgDAL.findMembership({ const orgMembers = await orgDAL.findMembership({
orgId: project.orgId, orgId: project.orgId,
@ -145,7 +164,9 @@ export const projectMembershipServiceFactory = ({
const addUsersToProjectNonE2EE = async ({ const addUsersToProjectNonE2EE = async ({
projectId, projectId,
actorId, actorId,
actorAuthMethod,
actor, actor,
actorOrgId,
emails, emails,
usernames, usernames,
sendEmails = true sendEmails = true
@ -157,7 +178,13 @@ export const projectMembershipServiceFactory = ({
throw new BadRequestError({ message: "Please upgrade your project on your dashboard" }); throw new BadRequestError({ message: "Please upgrade your project on your dashboard" });
} }
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member);
const usernamesAndEmails = [...emails, ...usernames]; const usernamesAndEmails = [...emails, ...usernames];
@ -273,11 +300,18 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
membershipId, membershipId,
roles roles
}: TUpdateProjectMembershipDTO) => { }: TUpdateProjectMembershipDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
const membershipUser = await userDAL.findUserByProjectMembershipId(membershipId); const membershipUser = await userDAL.findUserByProjectMembershipId(membershipId);
@ -347,10 +381,17 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
membershipId membershipId
}: TDeleteProjectMembershipOldDTO) => { }: TDeleteProjectMembershipOldDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Member);
const member = await userDAL.findUserByProjectMembershipId(membershipId); const member = await userDAL.findUserByProjectMembershipId(membershipId);
@ -374,11 +415,18 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
emails, emails,
usernames usernames
}: TDeleteProjectMembershipsDTO) => { }: TDeleteProjectMembershipsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Member);
const project = await projectDAL.findById(projectId); const project = await projectDAL.findById(projectId);

View File

@ -13,7 +13,7 @@ import {
} from "@app/ee/services/permission/project-permission"; } from "@app/ee/services/permission/project-permission";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
import { TProjectRoleDALFactory } from "./project-role-dal"; import { TProjectRoleDALFactory } from "./project-role-dal";
type TProjectRoleServiceFactoryDep = { type TProjectRoleServiceFactoryDep = {
@ -29,9 +29,16 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
actorId: string, actorId: string,
projectId: string, projectId: string,
data: Omit<TProjectRolesInsert, "projectId">, data: Omit<TProjectRolesInsert, "projectId">,
actorOrgId?: string actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Role);
const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId }); const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId });
if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" }); if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" });
@ -49,9 +56,16 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
projectId: string, projectId: string,
roleId: string, roleId: string,
data: Omit<TOrgRolesUpdate, "orgId">, data: Omit<TOrgRolesUpdate, "orgId">,
actorOrgId?: string actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Role);
if (data?.slug) { if (data?.slug) {
const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId }); const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId });
@ -71,9 +85,16 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
actorId: string, actorId: string,
projectId: string, projectId: string,
roleId: string, roleId: string,
actorOrgId?: string actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Role);
const [deletedRole] = await projectRoleDAL.delete({ id: roleId, projectId }); const [deletedRole] = await projectRoleDAL.delete({ id: roleId, projectId });
if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" }); if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" });
@ -81,8 +102,20 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
return deletedRole; return deletedRole;
}; };
const listRoles = async (actor: ActorType, actorId: string, projectId: string, actorOrgId?: string) => { const listRoles = async (
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actor: ActorType,
actorId: string,
projectId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role);
const customRoles = await projectRoleDAL.find({ projectId }); const customRoles = await projectRoleDAL.find({ projectId });
const roles = [ const roles = [
@ -135,8 +168,18 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
return roles; return roles;
}; };
const getUserPermission = async (userId: string, projectId: string, actorOrgId?: string) => { const getUserPermission = async (
const { permission, membership } = await permissionService.getUserProjectPermission(userId, projectId, actorOrgId); userId: string,
projectId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined
) => {
const { permission, membership } = await permissionService.getUserProjectPermission(
userId,
projectId,
actorAuthMethod,
actorOrgId
);
return { permissions: packRules(permission.rules), membership }; return { permissions: packRules(permission.rules), membership };
}; };

View File

@ -5,6 +5,8 @@ import { ProjectsSchema, ProjectUpgradeStatus, ProjectVersion, TableName, TProje
import { BadRequestError, DatabaseError } from "@app/lib/errors"; import { BadRequestError, DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex"; import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
import { Filter, ProjectFilterType } from "./project-types";
export type TProjectDALFactory = ReturnType<typeof projectDALFactory>; export type TProjectDALFactory = ReturnType<typeof projectDALFactory>;
export const projectDALFactory = (db: TDbClient) => { export const projectDALFactory = (db: TDbClient) => {
@ -139,7 +141,7 @@ export const projectDALFactory = (db: TDbClient) => {
{ column: `${TableName.Project}.name`, order: "asc" }, { column: `${TableName.Project}.name`, order: "asc" },
{ column: `${TableName.Environment}.position`, order: "asc" } { column: `${TableName.Environment}.position`, order: "asc" }
]); ]);
return sqlNestRelationships({ const project = sqlNestRelationships({
data: workspaces, data: workspaces,
key: "id", key: "id",
parentMapper: ({ _id, ...el }) => ({ _id, ...ProjectsSchema.parse(el) }), parentMapper: ({ _id, ...el }) => ({ _id, ...ProjectsSchema.parse(el) }),
@ -155,11 +157,86 @@ export const projectDALFactory = (db: TDbClient) => {
} }
] ]
})?.[0]; })?.[0];
if (!project) {
throw new BadRequestError({ message: "Project not found" });
}
return project;
} catch (error) { } catch (error) {
throw new DatabaseError({ error, name: "Find all projects" }); throw new DatabaseError({ error, name: "Find all projects" });
} }
}; };
const findProjectBySlug = async (slug: string, orgId: string) => {
try {
const projects = await db(TableName.ProjectMembership)
.where(`${TableName.Project}.slug`, slug)
.where(`${TableName.Project}.orgId`, orgId)
.join(TableName.Project, `${TableName.ProjectMembership}.projectId`, `${TableName.Project}.id`)
.join(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`)
.select(
selectAllTableCols(TableName.Project),
db.ref("id").withSchema(TableName.Project).as("_id"),
db.ref("id").withSchema(TableName.Environment).as("envId"),
db.ref("slug").withSchema(TableName.Environment).as("envSlug"),
db.ref("name").withSchema(TableName.Environment).as("envName")
)
.orderBy([
{ column: `${TableName.Project}.name`, order: "asc" },
{ column: `${TableName.Environment}.position`, order: "asc" }
]);
const project = sqlNestRelationships({
data: projects,
key: "id",
parentMapper: ({ _id, ...el }) => ({ _id, ...ProjectsSchema.parse(el) }),
childrenMapper: [
{
key: "envId",
label: "environments" as const,
mapper: ({ envId, envSlug, envName: name }) => ({
id: envId,
slug: envSlug,
name
})
}
]
})?.[0];
if (!project) {
throw new BadRequestError({ message: "Project not found" });
}
return project;
} catch (error) {
throw new DatabaseError({ error, name: "Find project by slug" });
}
};
const findProjectByFilter = async (filter: Filter) => {
try {
if (filter.type === ProjectFilterType.ID) {
return await findProjectById(filter.projectId);
}
if (filter.type === ProjectFilterType.SLUG) {
if (!filter.orgId) {
throw new BadRequestError({
message: "Organization ID is required when querying with slugs"
});
}
return await findProjectBySlug(filter.slug, filter.orgId);
}
throw new BadRequestError({ message: "Invalid filter type" });
} catch (error) {
if (error instanceof BadRequestError) {
throw error;
}
throw new DatabaseError({ error, name: `Failed to find project by ${filter.type}` });
}
};
const checkProjectUpgradeStatus = async (projectId: string) => { const checkProjectUpgradeStatus = async (projectId: string) => {
const project = await projectOrm.findById(projectId); const project = await projectOrm.findById(projectId);
const upgradeInProgress = const upgradeInProgress =
@ -179,6 +256,8 @@ export const projectDALFactory = (db: TDbClient) => {
findAllProjectsByIdentity, findAllProjectsByIdentity,
findProjectGhostUser, findProjectGhostUser,
findProjectById, findProjectById,
findProjectByFilter,
findProjectBySlug,
checkProjectUpgradeStatus checkProjectUpgradeStatus
}; };
}; };

View File

@ -18,6 +18,7 @@ import { ActorType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal"; import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal";
import { TIdentityProjectMembershipRoleDALFactory } from "../identity-project/identity-project-membership-role-dal"; import { TIdentityProjectMembershipRoleDALFactory } from "../identity-project/identity-project-membership-role-dal";
import { TOrgDALFactory } from "../org/org-dal";
import { TOrgServiceFactory } from "../org/org-service"; import { TOrgServiceFactory } from "../org/org-service";
import { TProjectBotDALFactory } from "../project-bot/project-bot-dal"; import { TProjectBotDALFactory } from "../project-bot/project-bot-dal";
import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
@ -34,7 +35,9 @@ import {
TCreateProjectDTO, TCreateProjectDTO,
TDeleteProjectDTO, TDeleteProjectDTO,
TGetProjectDTO, TGetProjectDTO,
TToggleProjectAutoCapitalizationDTO,
TUpdateProjectDTO, TUpdateProjectDTO,
TUpdateProjectNameDTO,
TUpgradeProjectDTO TUpgradeProjectDTO
} from "./project-types"; } from "./project-types";
@ -61,6 +64,7 @@ type TProjectServiceFactoryDep = {
permissionService: TPermissionServiceFactory; permissionService: TPermissionServiceFactory;
orgService: Pick<TOrgServiceFactory, "addGhostUser">; orgService: Pick<TOrgServiceFactory, "addGhostUser">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
orgDAL: Pick<TOrgDALFactory, "findOne">;
}; };
export type TProjectServiceFactory = ReturnType<typeof projectServiceFactory>; export type TProjectServiceFactory = ReturnType<typeof projectServiceFactory>;
@ -70,6 +74,7 @@ export const projectServiceFactory = ({
projectQueue, projectQueue,
projectKeyDAL, projectKeyDAL,
permissionService, permissionService,
orgDAL,
userDAL, userDAL,
folderDAL, folderDAL,
orgService, orgService,
@ -86,11 +91,28 @@ export const projectServiceFactory = ({
/* /*
* Create workspace. Make user the admin * Create workspace. Make user the admin
* */ * */
const createProject = async ({ orgId, actor, actorId, actorOrgId, workspaceName, slug }: TCreateProjectDTO) => { const createProject = async ({
orgSlug,
actor,
actorId,
actorOrgId,
actorAuthMethod,
workspaceName,
slug: projectSlug
}: TCreateProjectDTO) => {
if (!orgSlug) {
throw new BadRequestError({
message: "Must provide organization slug to create project"
});
}
const organization = await orgDAL.findOne({ slug: orgSlug });
const { permission, membership: orgMembership } = await permissionService.getOrgPermission( const { permission, membership: orgMembership } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
orgId, organization.id,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace);
@ -98,7 +120,7 @@ export const projectServiceFactory = ({
const appCfg = getConfig(); const appCfg = getConfig();
const blindIndex = createSecretBlindIndex(appCfg.ROOT_ENCRYPTION_KEY, appCfg.ENCRYPTION_KEY); const blindIndex = createSecretBlindIndex(appCfg.ROOT_ENCRYPTION_KEY, appCfg.ENCRYPTION_KEY);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(organization.id);
if (plan.workspaceLimit !== null && plan.workspacesUsed >= plan.workspaceLimit) { if (plan.workspaceLimit !== null && plan.workspacesUsed >= plan.workspaceLimit) {
// case: limit imposed on number of workspaces allowed // case: limit imposed on number of workspaces allowed
// case: number of workspaces used exceeds the number of workspaces allowed // case: number of workspaces used exceeds the number of workspaces allowed
@ -108,13 +130,13 @@ export const projectServiceFactory = ({
} }
const results = await projectDAL.transaction(async (tx) => { const results = await projectDAL.transaction(async (tx) => {
const ghostUser = await orgService.addGhostUser(orgId, tx); const ghostUser = await orgService.addGhostUser(organization.id, tx);
const project = await projectDAL.create( const project = await projectDAL.create(
{ {
name: workspaceName, name: workspaceName,
orgId, orgId: organization.id,
slug: slug || slugify(`${workspaceName}-${alphaNumericNanoId(4)}`), slug: projectSlug || slugify(`${workspaceName}-${alphaNumericNanoId(4)}`),
version: ProjectVersion.V2 version: ProjectVersion.V2
}, },
tx tx
@ -270,7 +292,7 @@ export const projectServiceFactory = ({
// Get the role permission for the identity // Get the role permission for the identity
const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole( const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole(
ProjectMembershipRole.Admin, ProjectMembershipRole.Admin,
orgId organization.id
); );
const hasPrivilege = isAtLeastAsPrivileged(permission, rolePermission); const hasPrivilege = isAtLeastAsPrivileged(permission, rolePermission);
@ -310,20 +332,28 @@ export const projectServiceFactory = ({
return results; return results;
}; };
const deleteProject = async ({ actor, actorId, actorOrgId, projectId }: TDeleteProjectDTO) => { const deleteProject = async ({ actor, actorId, actorOrgId, actorAuthMethod, filter }: TDeleteProjectDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const project = await projectDAL.findProjectByFilter(filter);
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
project.id,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project);
const deletedProject = await projectDAL.transaction(async (tx) => { const deletedProject = await projectDAL.transaction(async (tx) => {
const project = await projectDAL.deleteById(projectId, tx); const delProject = await projectDAL.deleteById(project.id, tx);
const projectGhostUser = await projectMembershipDAL.findProjectGhostUser(projectId).catch(() => null); const projectGhostUser = await projectMembershipDAL.findProjectGhostUser(project.id).catch(() => null);
// Delete the org membership for the ghost user if it's found. // Delete the org membership for the ghost user if it's found.
if (projectGhostUser) { if (projectGhostUser) {
await userDAL.deleteById(projectGhostUser.id, tx); await userDAL.deleteById(projectGhostUser.id, tx);
} }
return project; return delProject;
}); });
return deletedProject; return deletedProject;
@ -334,16 +364,26 @@ export const projectServiceFactory = ({
return workspaces; return workspaces;
}; };
const getAProject = async ({ actorId, actorOrgId, projectId, actor }: TGetProjectDTO) => { const getAProject = async ({ actorId, actorOrgId, actorAuthMethod, filter, actor }: TGetProjectDTO) => {
await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const project = await projectDAL.findProjectByFilter(filter);
return projectDAL.findProjectById(projectId);
await permissionService.getProjectPermission(actor, actorId, project.id, actorAuthMethod, actorOrgId);
return project;
}; };
const updateProject = async ({ projectId, actor, actorId, actorOrgId, update }: TUpdateProjectDTO) => { const updateProject = async ({ actor, actorId, actorOrgId, actorAuthMethod, update, filter }: TUpdateProjectDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const project = await projectDAL.findProjectByFilter(filter);
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
project.id,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings);
const updatedProject = await projectDAL.updateById(projectId, { const updatedProject = await projectDAL.updateById(project.id, {
name: update.name, name: update.name,
autoCapitalization: update.autoCapitalization autoCapitalization: update.autoCapitalization
}); });
@ -355,25 +395,58 @@ export const projectServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
autoCapitalization autoCapitalization
}: TGetProjectDTO & { autoCapitalization: boolean }) => { }: TToggleProjectAutoCapitalizationDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings);
const updatedProject = await projectDAL.updateById(projectId, { autoCapitalization }); const updatedProject = await projectDAL.updateById(projectId, { autoCapitalization });
return updatedProject; return updatedProject;
}; };
const updateName = async ({ projectId, actor, actorId, actorOrgId, name }: TGetProjectDTO & { name: string }) => { const updateName = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); projectId,
actor,
actorId,
actorOrgId,
actorAuthMethod,
name
}: TUpdateProjectNameDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings);
const updatedProject = await projectDAL.updateById(projectId, { name }); const updatedProject = await projectDAL.updateById(projectId, { name });
return updatedProject; return updatedProject;
}; };
const upgradeProject = async ({ projectId, actor, actorId, userPrivateKey }: TUpgradeProjectDTO) => { const upgradeProject = async ({
const { permission, hasRole } = await permissionService.getProjectPermission(actor, actorId, projectId); projectId,
actor,
actorId,
actorAuthMethod,
actorOrgId,
userPrivateKey
}: TUpgradeProjectDTO) => {
const { permission, hasRole } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project);
@ -397,8 +470,20 @@ export const projectServiceFactory = ({
}); });
}; };
const getProjectUpgradeStatus = async ({ projectId, actor, actorId }: TProjectPermission) => { const getProjectUpgradeStatus = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); projectId,
actor,
actorAuthMethod,
actorOrgId,
actorId
}: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets);
const project = await projectDAL.findProjectById(projectId); const project = await projectDAL.findProjectById(projectId);

View File

@ -1,37 +1,67 @@
import { ProjectMembershipRole, TProjectKeys } from "@app/db/schemas"; import { ProjectMembershipRole, TProjectKeys } from "@app/db/schemas";
import { TProjectPermission } from "@app/lib/types"; import { TProjectPermission } from "@app/lib/types";
import { ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
export enum ProjectFilterType {
ID = "id",
SLUG = "slug"
}
export type Filter =
| {
type: ProjectFilterType.ID;
projectId: string;
}
| {
type: ProjectFilterType.SLUG;
slug: string;
orgId: string | undefined;
};
export type TCreateProjectDTO = { export type TCreateProjectDTO = {
actor: ActorType; actor: ActorType;
actorAuthMethod: ActorAuthMethod;
actorId: string; actorId: string;
actorOrgId?: string; actorOrgId?: string;
orgId: string; orgSlug: string;
workspaceName: string; workspaceName: string;
slug?: string; slug?: string;
}; };
export type TDeleteProjectDTO = { export type TDeleteProjectBySlugDTO = {
slug: string;
actor: ActorType; actor: ActorType;
actorId: string; actorId: string;
actorOrgId?: string; actorOrgId: string | undefined;
projectId: string;
}; };
export type TGetProjectDTO = { export type TGetProjectDTO = {
actor: ActorType; filter: Filter;
actorId: string; } & Omit<TProjectPermission, "projectId">;
actorOrgId?: string;
projectId: string; export type TToggleProjectAutoCapitalizationDTO = {
}; autoCapitalization: boolean;
} & TProjectPermission;
export type TUpdateProjectNameDTO = {
name: string;
} & TProjectPermission;
export type TUpdateProjectDTO = { export type TUpdateProjectDTO = {
filter: Filter;
update: { update: {
name?: string; name?: string;
autoCapitalization?: boolean; autoCapitalization?: boolean;
}; };
} & TProjectPermission; } & Omit<TProjectPermission, "projectId">;
export type TDeleteProjectDTO = {
filter: Filter;
actor: ActorType;
actorId: string;
actorOrgId: string | undefined;
} & Omit<TProjectPermission, "projectId">;
export type TUpgradeProjectDTO = { export type TUpgradeProjectDTO = {
userPrivateKey: string; userPrivateKey: string;

View File

@ -28,16 +28,29 @@ export const secretBlindIndexServiceFactory = ({
actor, actor,
projectId, projectId,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TGetProjectBlindIndexStatusDTO) => { }: TGetProjectBlindIndexStatusDTO) => {
await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId); const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId);
return Number(secretCount); return Number(secretCount);
}; };
const getProjectSecrets = async ({ projectId, actorId, actor }: TGetProjectSecretsDTO) => { const getProjectSecrets = async ({
const { hasRole } = await permissionService.getProjectPermission(actor, actorId, projectId); projectId,
actorId,
actorAuthMethod,
actorOrgId,
actor
}: TGetProjectSecretsDTO) => {
const { hasRole } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
if (!hasRole(ProjectMembershipRole.Admin)) { if (!hasRole(ProjectMembershipRole.Admin)) {
throw new UnauthorizedError({ message: "User must be admin" }); throw new UnauthorizedError({ message: "User must be admin" });
} }
@ -50,10 +63,17 @@ export const secretBlindIndexServiceFactory = ({
projectId, projectId,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
secretsToUpdate secretsToUpdate
}: TUpdateProjectSecretNameDTO) => { }: TUpdateProjectSecretNameDTO) => {
const { hasRole } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { hasRole } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
if (!hasRole(ProjectMembershipRole.Admin)) { if (!hasRole(ProjectMembershipRole.Admin)) {
throw new UnauthorizedError({ message: "User must be admin" }); throw new UnauthorizedError({ message: "User must be admin" });
} }

View File

@ -34,12 +34,19 @@ export const secretFolderServiceFactory = ({
projectId, projectId,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
name, name,
environment, environment,
path: secretPath path: secretPath
}: TCreateFolderDTO) => { }: TCreateFolderDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath }) subject(ProjectPermissionSub.Secrets, { environment, secretPath })
@ -114,12 +121,19 @@ export const secretFolderServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
name, name,
environment, environment,
path: secretPath, path: secretPath,
id id
}: TUpdateFolderDTO) => { }: TUpdateFolderDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit, ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath }) subject(ProjectPermissionSub.Secrets, { environment, secretPath })
@ -162,11 +176,18 @@ export const secretFolderServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
path: secretPath, path: secretPath,
idOrName idOrName
}: TDeleteFolderDTO) => { }: TDeleteFolderDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete, ProjectPermissionActions.Delete,
subject(ProjectPermissionSub.Secrets, { environment, secretPath }) subject(ProjectPermissionSub.Secrets, { environment, secretPath })
@ -196,12 +217,13 @@ export const secretFolderServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
path: secretPath path: secretPath
}: TGetFolderDTO) => { }: TGetFolderDTO) => {
// folder list is allowed to be read by anyone // folder list is allowed to be read by anyone
// permission to check does user has access // permission to check does user has access
await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
const env = await projectEnvDAL.findOne({ projectId, slug: environment }); const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new BadRequestError({ message: "Environment not found", name: "get folders" }); if (!env) throw new BadRequestError({ message: "Environment not found", name: "get folders" });

View File

@ -45,10 +45,17 @@ export const secretImportServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
path path
}: TCreateSecretImportDTO) => { }: TCreateSecretImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
// check if user has permission to import into destination path // check if user has permission to import into destination path
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
@ -97,10 +104,17 @@ export const secretImportServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
data, data,
id id
}: TUpdateSecretImportDTO) => { }: TUpdateSecretImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit, ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -144,9 +158,16 @@ export const secretImportServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
id id
}: TDeleteSecretImportDTO) => { }: TDeleteSecretImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete, ProjectPermissionActions.Delete,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -167,8 +188,22 @@ export const secretImportServiceFactory = ({
return secImport; return secImport;
}; };
const getImports = async ({ path, environment, projectId, actor, actorId, actorOrgId }: TGetSecretImportsDTO) => { const getImports = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); path,
environment,
projectId,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TGetSecretImportsDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -186,10 +221,17 @@ export const secretImportServiceFactory = ({
environment, environment,
projectId, projectId,
actor, actor,
actorAuthMethod,
actorId, actorId,
actorOrgId actorOrgId
}: TGetSecretsFromImportDTO) => { }: TGetSecretsFromImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })

View File

@ -15,8 +15,23 @@ type TSecretTagServiceFactoryDep = {
export type TSecretTagServiceFactory = ReturnType<typeof secretTagServiceFactory>; export type TSecretTagServiceFactory = ReturnType<typeof secretTagServiceFactory>;
export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSecretTagServiceFactoryDep) => { export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSecretTagServiceFactoryDep) => {
const createTag = async ({ name, slug, actor, color, actorId, actorOrgId, projectId }: TCreateTagDTO) => { const createTag = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); name,
slug,
actor,
color,
actorId,
actorOrgId,
actorAuthMethod,
projectId
}: TCreateTagDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Tags); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Tags);
const existingTag = await secretTagDAL.findOne({ slug, projectId }); const existingTag = await secretTagDAL.findOne({ slug, projectId });
@ -32,19 +47,31 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe
return newTag; return newTag;
}; };
const deleteTag = async ({ actorId, actor, actorOrgId, id }: TDeleteTagDTO) => { const deleteTag = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteTagDTO) => {
const tag = await secretTagDAL.findById(id); const tag = await secretTagDAL.findById(id);
if (!tag) throw new BadRequestError({ message: "Tag doesn't exist" }); if (!tag) throw new BadRequestError({ message: "Tag doesn't exist" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, tag.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
tag.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Tags); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Tags);
const deletedTag = await secretTagDAL.deleteById(tag.id); const deletedTag = await secretTagDAL.deleteById(tag.id);
return deletedTag; return deletedTag;
}; };
const getProjectTags = async ({ actor, actorId, actorOrgId, projectId }: TListProjectTagsDTO) => { const getProjectTags = async ({ actor, actorId, actorOrgId, actorAuthMethod, projectId }: TListProjectTagsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Tags);
const tags = await secretTagDAL.find({ projectId }, { sort: [["createdAt", "asc"]] }); const tags = await secretTagDAL.find({ projectId }, { sort: [["createdAt", "asc"]] });

View File

@ -145,10 +145,17 @@ export const secretServiceFactory = ({
actorId, actorId,
actorOrgId, actorOrgId,
environment, environment,
actorAuthMethod,
projectId, projectId,
...inputSecret ...inputSecret
}: TCreateSecretDTO) => { }: TCreateSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -230,10 +237,17 @@ export const secretServiceFactory = ({
actorId, actorId,
actorOrgId, actorOrgId,
environment, environment,
actorAuthMethod,
projectId, projectId,
...inputSecret ...inputSecret
}: TUpdateSecretDTO) => { }: TUpdateSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit, ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -341,11 +355,18 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
projectId, projectId,
...inputSecret ...inputSecret
}: TDeleteSecretDTO) => { }: TDeleteSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete, ProjectPermissionActions.Delete,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -401,9 +422,16 @@ export const secretServiceFactory = ({
projectId, projectId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
includeImports includeImports
}: TGetSecretsDTO) => { }: TGetSecretsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -445,6 +473,7 @@ export const secretServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
environment, environment,
path, path,
@ -453,7 +482,13 @@ export const secretServiceFactory = ({
version, version,
includeImports includeImports
}: TGetASecretDTO) => { }: TGetASecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -534,12 +569,19 @@ export const secretServiceFactory = ({
path, path,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
environment, environment,
projectId, projectId,
secrets: inputSecrets secrets: inputSecrets
}: TCreateBulkSecretDTO) => { }: TCreateBulkSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -597,11 +639,18 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
projectId, projectId,
secrets: inputSecrets secrets: inputSecrets
}: TUpdateBulkSecretDTO) => { }: TUpdateBulkSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -678,9 +727,16 @@ export const secretServiceFactory = ({
projectId, projectId,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteBulkSecretDTO) => { }: TDeleteBulkSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@ -728,6 +784,7 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
includeImports includeImports
}: TGetSecretsRawDTO) => { }: TGetSecretsRawDTO) => {
@ -740,6 +797,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
path, path,
includeImports includeImports
}); });
@ -763,6 +821,7 @@ export const secretServiceFactory = ({
projectId, projectId,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
secretName, secretName,
includeImports, includeImports,
version version
@ -773,6 +832,7 @@ export const secretServiceFactory = ({
const secret = await getSecretByName({ const secret = await getSecretByName({
actorId, actorId,
projectId, projectId,
actorAuthMethod,
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
@ -792,6 +852,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
type, type,
secretPath, secretPath,
secretValue, secretValue,
@ -813,6 +874,7 @@ export const secretServiceFactory = ({
path: secretPath, path: secretPath,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
secretKeyCiphertext: secretKeyEncrypted.ciphertext, secretKeyCiphertext: secretKeyEncrypted.ciphertext,
secretKeyIV: secretKeyEncrypted.iv, secretKeyIV: secretKeyEncrypted.iv,
@ -839,6 +901,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
type, type,
secretPath, secretPath,
secretValue, secretValue,
@ -858,6 +921,7 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
secretValueCiphertext: secretValueEncrypted.ciphertext, secretValueCiphertext: secretValueEncrypted.ciphertext,
secretValueIV: secretValueEncrypted.iv, secretValueIV: secretValueEncrypted.iv,
secretValueTag: secretValueEncrypted.tag, secretValueTag: secretValueEncrypted.tag,
@ -877,6 +941,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
type, type,
secretPath secretPath
}: TDeleteSecretRawDTO) => { }: TDeleteSecretRawDTO) => {
@ -891,7 +956,8 @@ export const secretServiceFactory = ({
path: secretPath, path: secretPath,
actor, actor,
actorId, actorId,
actorOrgId actorOrgId,
actorAuthMethod
}); });
await snapshotService.performSnapshot(secret.folderId); await snapshotService.performSnapshot(secret.folderId);
@ -904,6 +970,7 @@ export const secretServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
limit = 20, limit = 20,
offset = 0, offset = 0,
secretId secretId
@ -914,7 +981,13 @@ export const secretServiceFactory = ({
const folder = await folderDAL.findById(secret.folderId); const folder = await folderDAL.findById(secret.folderId);
if (!folder) throw new BadRequestError({ message: "Failed to find secret" }); if (!folder) throw new BadRequestError({ message: "Failed to find secret" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, folder.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
folder.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] }); const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] });

View File

@ -9,6 +9,7 @@ import { getConfig } from "@app/lib/config/env";
import { BadRequestError, UnauthorizedError } from "@app/lib/errors"; import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { ActorType } from "../auth/auth-type"; import { ActorType } from "../auth/auth-type";
import { TProjectDALFactory } from "../project/project-dal";
import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
import { TUserDALFactory } from "../user/user-dal"; import { TUserDALFactory } from "../user/user-dal";
import { TServiceTokenDALFactory } from "./service-token-dal"; import { TServiceTokenDALFactory } from "./service-token-dal";
@ -24,6 +25,7 @@ type TServiceTokenServiceFactoryDep = {
userDAL: TUserDALFactory; userDAL: TUserDALFactory;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">; permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
projectEnvDAL: Pick<TProjectEnvDALFactory, "findBySlugs">; projectEnvDAL: Pick<TProjectEnvDALFactory, "findBySlugs">;
projectDAL: Pick<TProjectDALFactory, "findById">;
}; };
export type TServiceTokenServiceFactory = ReturnType<typeof serviceTokenServiceFactory>; export type TServiceTokenServiceFactory = ReturnType<typeof serviceTokenServiceFactory>;
@ -32,7 +34,8 @@ export const serviceTokenServiceFactory = ({
serviceTokenDAL, serviceTokenDAL,
userDAL, userDAL,
permissionService, permissionService,
projectEnvDAL projectEnvDAL,
projectDAL
}: TServiceTokenServiceFactoryDep) => { }: TServiceTokenServiceFactoryDep) => {
const createServiceToken = async ({ const createServiceToken = async ({
iv, iv,
@ -40,6 +43,7 @@ export const serviceTokenServiceFactory = ({
name, name,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
scopes, scopes,
actorId, actorId,
projectId, projectId,
@ -47,7 +51,13 @@ export const serviceTokenServiceFactory = ({
permissions, permissions,
encryptedKey encryptedKey
}: TCreateServiceTokenDTO) => { }: TCreateServiceTokenDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens);
scopes.forEach(({ environment, secretPath }) => { scopes.forEach(({ environment, secretPath }) => {
@ -91,7 +101,7 @@ export const serviceTokenServiceFactory = ({
return { token, serviceToken }; return { token, serviceToken };
}; };
const deleteServiceToken = async ({ actorId, actor, actorOrgId, id }: TDeleteServiceTokenDTO) => { const deleteServiceToken = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteServiceTokenDTO) => {
const serviceToken = await serviceTokenDAL.findById(id); const serviceToken = await serviceTokenDAL.findById(id);
if (!serviceToken) throw new BadRequestError({ message: "Token not found" }); if (!serviceToken) throw new BadRequestError({ message: "Token not found" });
@ -99,6 +109,7 @@ export const serviceTokenServiceFactory = ({
actor, actor,
actorId, actorId,
serviceToken.projectId, serviceToken.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.ServiceTokens); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.ServiceTokens);
@ -119,8 +130,20 @@ export const serviceTokenServiceFactory = ({
return { serviceToken, user: serviceTokenUser }; return { serviceToken, user: serviceTokenUser };
}; };
const getProjectServiceTokens = async ({ actorId, actor, actorOrgId, projectId }: TProjectServiceTokensDTO) => { const getProjectServiceTokens = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TProjectServiceTokensDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens);
const tokens = await serviceTokenDAL.find({ projectId }, { sort: [["createdAt", "desc"]] }); const tokens = await serviceTokenDAL.find({ projectId }, { sort: [["createdAt", "desc"]] });
@ -130,7 +153,11 @@ export const serviceTokenServiceFactory = ({
const fnValidateServiceToken = async (token: string) => { const fnValidateServiceToken = async (token: string) => {
const [, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>token.split(".", 3); const [, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>token.split(".", 3);
const serviceToken = await serviceTokenDAL.findById(TOKEN_IDENTIFIER); const serviceToken = await serviceTokenDAL.findById(TOKEN_IDENTIFIER);
if (!serviceToken) throw new UnauthorizedError(); if (!serviceToken) throw new UnauthorizedError();
const project = await projectDAL.findById(serviceToken.projectId);
if (!project) throw new UnauthorizedError({ message: "Service token project not found" });
if (serviceToken.expiresAt && new Date(serviceToken.expiresAt) < new Date()) { if (serviceToken.expiresAt && new Date(serviceToken.expiresAt) < new Date()) {
await serviceTokenDAL.deleteById(serviceToken.id); await serviceTokenDAL.deleteById(serviceToken.id);
@ -142,7 +169,8 @@ export const serviceTokenServiceFactory = ({
const updatedToken = await serviceTokenDAL.updateById(serviceToken.id, { const updatedToken = await serviceTokenDAL.updateById(serviceToken.id, {
lastUsed: new Date() lastUsed: new Date()
}); });
return { ...serviceToken, lastUsed: updatedToken.lastUsed };
return { ...serviceToken, lastUsed: updatedToken.lastUsed, orgId: project.orgId };
}; };
return { return {

View File

@ -136,6 +136,7 @@ export const superAdminServiceFactory = ({
await updateServerCfg({ initialized: true }); await updateServerCfg({ initialized: true });
const token = await authService.generateUserTokens({ const token = await authService.generateUserTokens({
user: userInfo.user, user: userInfo.user,
authMethod: AuthMethod.EMAIL,
ip, ip,
userAgent, userAgent,
organizationId: undefined organizationId: undefined

View File

@ -31,13 +31,20 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
webhookUrl, webhookUrl,
environment, environment,
secretPath, secretPath,
webhookSecretKey webhookSecretKey
}: TCreateWebhookDTO) => { }: TCreateWebhookDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Webhooks);
const env = await projectEnvDAL.findOne({ projectId, slug: environment }); const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new BadRequestError({ message: "Env not found" }); if (!env) throw new BadRequestError({ message: "Env not found" });
@ -73,33 +80,51 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer
return { ...webhook, projectId, environment: env }; return { ...webhook, projectId, environment: env };
}; };
const updateWebhook = async ({ actorId, actor, actorOrgId, id, isDisabled }: TUpdateWebhookDTO) => { const updateWebhook = async ({ actorId, actor, actorOrgId, actorAuthMethod, id, isDisabled }: TUpdateWebhookDTO) => {
const webhook = await webhookDAL.findById(id); const webhook = await webhookDAL.findById(id);
if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); if (!webhook) throw new BadRequestError({ message: "Webhook not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
webhook.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Webhooks);
const updatedWebhook = await webhookDAL.updateById(id, { isDisabled }); const updatedWebhook = await webhookDAL.updateById(id, { isDisabled });
return { ...webhook, ...updatedWebhook }; return { ...webhook, ...updatedWebhook };
}; };
const deleteWebhook = async ({ id, actor, actorId, actorOrgId }: TDeleteWebhookDTO) => { const deleteWebhook = async ({ id, actor, actorId, actorAuthMethod, actorOrgId }: TDeleteWebhookDTO) => {
const webhook = await webhookDAL.findById(id); const webhook = await webhookDAL.findById(id);
if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); if (!webhook) throw new BadRequestError({ message: "Webhook not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
webhook.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Webhooks);
const deletedWebhook = await webhookDAL.deleteById(id); const deletedWebhook = await webhookDAL.deleteById(id);
return { ...webhook, ...deletedWebhook }; return { ...webhook, ...deletedWebhook };
}; };
const testWebhook = async ({ id, actor, actorId, actorOrgId }: TTestWebhookDTO) => { const testWebhook = async ({ id, actor, actorId, actorAuthMethod, actorOrgId }: TTestWebhookDTO) => {
const webhook = await webhookDAL.findById(id); const webhook = await webhookDAL.findById(id);
if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); if (!webhook) throw new BadRequestError({ message: "Webhook not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
webhook.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks);
let webhookError: string | undefined; let webhookError: string | undefined;
@ -119,8 +144,22 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer
return { ...webhook, ...updatedWebhook }; return { ...webhook, ...updatedWebhook };
}; };
const listWebhooks = async ({ actorId, actor, actorOrgId, projectId, secretPath, environment }: TListWebhookDTO) => { const listWebhooks = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId,
secretPath,
environment
}: TListWebhookDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks);
return webhookDAL.findAllWebhooks(projectId, environment, secretPath); return webhookDAL.findAllWebhooks(projectId, environment, secretPath);

View File

@ -164,6 +164,28 @@ func CallGetAllOrganizations(httpClient *resty.Client) (GetOrganizationsResponse
return orgResponse, nil return orgResponse, nil
} }
func CallSelectOrganization(httpClient *resty.Client, request SelectOrganizationRequest) (SelectOrganizationResponse, error) {
var selectOrgResponse SelectOrganizationResponse
response, err := httpClient.
R().
SetBody(request).
SetResult(&selectOrgResponse).
SetHeader("User-Agent", USER_AGENT).
Post(fmt.Sprintf("%v/v3/auth/select-organization", config.INFISICAL_URL))
if err != nil {
return SelectOrganizationResponse{}, err
}
if response.IsError() {
return SelectOrganizationResponse{}, fmt.Errorf("CallSelectOrganization: Unsuccessful response: [response=%v]", response)
}
return selectOrgResponse, nil
}
func CallGetAllWorkSpacesUserBelongsTo(httpClient *resty.Client) (GetWorkSpacesResponse, error) { func CallGetAllWorkSpacesUserBelongsTo(httpClient *resty.Client) (GetWorkSpacesResponse, error) {
var workSpacesResponse GetWorkSpacesResponse var workSpacesResponse GetWorkSpacesResponse
response, err := httpClient. response, err := httpClient.

View File

@ -135,6 +135,14 @@ type GetOrganizationsResponse struct {
} `json:"organizations"` } `json:"organizations"`
} }
type SelectOrganizationResponse struct {
Token string `json:"token"`
}
type SelectOrganizationRequest struct {
OrganizationId string `json:"organizationId"`
}
type Secret struct { type Secret struct {
SecretKeyCiphertext string `json:"secretKeyCiphertext,omitempty"` SecretKeyCiphertext string `json:"secretKeyCiphertext,omitempty"`
SecretKeyIV string `json:"secretKeyIV,omitempty"` SecretKeyIV string `json:"secretKeyIV,omitempty"`

View File

@ -74,6 +74,21 @@ var initCmd = &cobra.Command{
selectedOrganization := organizations[index] selectedOrganization := organizations[index]
tokenResponse, err := api.CallSelectOrganization(httpClient, api.SelectOrganizationRequest{OrganizationId: selectedOrganization.ID})
if err != nil {
util.HandleError(err, "Unable to select organization")
}
// set the config jwt token to the new token
userCreds.UserCredentials.JTWToken = tokenResponse.Token
err = util.StoreUserCredsInKeyRing(&userCreds.UserCredentials)
httpClient.SetAuthToken(tokenResponse.Token)
if err != nil {
util.HandleError(err, "Unable to store your user credentials")
}
workspaceResponse, err := api.CallGetAllWorkSpacesUserBelongsTo(httpClient) workspaceResponse, err := api.CallGetAllWorkSpacesUserBelongsTo(httpClient)
if err != nil { if err != nil {
util.HandleError(err, "Unable to pull projects that belong to you") util.HandleError(err, "Unable to pull projects that belong to you")

View File

@ -301,11 +301,13 @@ func cliDefaultLogin(userCredentialsToBeStored *models.UserCredentials) {
log.Debug().Msgf("[decryptedPrivateKey=%s] [email=%s] [loginTwoResponse.Token=%s]", string(decryptedPrivateKey), email, loginTwoResponse.Token) log.Debug().Msgf("[decryptedPrivateKey=%s] [email=%s] [loginTwoResponse.Token=%s]", string(decryptedPrivateKey), email, loginTwoResponse.Token)
util.PrintErrorMessageAndExit("We were unable to fetch required details to complete your login. Run with -d to see more info") util.PrintErrorMessageAndExit("We were unable to fetch required details to complete your login. Run with -d to see more info")
} }
// Login is successful so ask user to choose organization
newJwtToken := GetJwtTokenWithOrganizationId(loginTwoResponse.Token)
//updating usercredentials //updating usercredentials
userCredentialsToBeStored.Email = email userCredentialsToBeStored.Email = email
userCredentialsToBeStored.PrivateKey = string(decryptedPrivateKey) userCredentialsToBeStored.PrivateKey = string(decryptedPrivateKey)
userCredentialsToBeStored.JTWToken = loginTwoResponse.Token userCredentialsToBeStored.JTWToken = newJwtToken
} }
func init() { func init() {
@ -480,6 +482,44 @@ func getFreshUserCredentials(email string, password string) (*api.GetLoginOneV2R
return &loginOneResponseResult, &loginTwoResponseResult, nil return &loginOneResponseResult, &loginTwoResponseResult, nil
} }
func GetJwtTokenWithOrganizationId(oldJwtToken string) string {
log.Debug().Msg(fmt.Sprint("GetJwtTokenWithOrganizationId: ", "oldJwtToken", oldJwtToken))
httpClient := resty.New()
httpClient.SetAuthToken(oldJwtToken)
organizationResponse, err := api.CallGetAllOrganizations(httpClient)
if err != nil {
util.HandleError(err, "Unable to pull organizations that belong to you")
}
organizations := organizationResponse.Organizations
organizationNames := util.GetOrganizationsNameList(organizationResponse)
prompt := promptui.Select{
Label: "Which Infisical organization would you like to log into?",
Items: organizationNames,
}
index, _, err := prompt.Run()
if err != nil {
util.HandleError(err)
}
selectedOrganization := organizations[index]
selectedOrgRes, err := api.CallSelectOrganization(httpClient, api.SelectOrganizationRequest{OrganizationId: selectedOrganization.ID})
if err != nil {
util.HandleError(err)
}
return selectedOrgRes.Token
}
func userLoginMenu(currentLoggedInUserEmail string) (bool, error) { func userLoginMenu(currentLoggedInUserEmail string) (bool, error) {
label := fmt.Sprintf("Current logged in user email: %s on domain: %s", currentLoggedInUserEmail, config.INFISICAL_URL) label := fmt.Sprintf("Current logged in user email: %s on domain: %s", currentLoggedInUserEmail, config.INFISICAL_URL)

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