1
0
mirror of https://github.com/Infisical/infisical.git synced 2025-03-24 00:15:26 +00:00

Compare commits

..

63 Commits

Author SHA1 Message Date
3841394eb7 misc: migrated existing to new helper 2024-10-26 03:18:57 +08:00
3552119c7d misc: moved host validity check to helper 2024-10-25 22:49:57 +08:00
7a46725523 doc: added note for transaction 2024-10-25 22:45:06 +08:00
3bc39c6cec feat: add usage of ca 2024-10-25 21:29:47 +08:00
b5b1e57fe7 doc: sap hana 2024-10-25 21:19:22 +08:00
1a5f66fe46 feat: added support for sap hana dynamic secrets 2024-10-25 20:33:23 +08:00
45b9de63f0 Merge pull request from Infisical/daniel/fix-cleanup-job-fail
fix: `timestamp out of range` error during daily cleanup
2024-10-24 19:52:12 +04:00
114966ded4 fix: LEAST() to fix TTL's with high values causing timestamp out of range 2024-10-24 19:40:20 +04:00
71081d8e9a Merge pull request from Infisical/daniel/operator-auth-refresh
feat: automatic k8 operator token refreshing
2024-10-24 10:42:46 -04:00
dad3d50f3e Merge pull request from Infisical/daniel/fix-aws-local-login
fix(cli): aws-iam local authentication
2024-10-24 17:48:42 +04:00
e5ca5d3da2 Update test-TestUniversalAuth_SecretsGetWrongEnvironment 2024-10-24 17:45:00 +04:00
301cd54dc3 chore: bumped go sdk version 2024-10-24 17:33:51 +04:00
593bda8bc6 Merge pull request from Infisical/feat/azure-app-configuration
feat: azure app configuration integration
2024-10-24 19:37:38 +08:00
4db79edf19 misc: addressed review comments 2024-10-24 19:20:21 +08:00
e3a356cda9 updated go sdk 2024-10-24 14:47:00 +04:00
521b24debf Merge pull request from Infisical/feat/add-assume-role-support-for-aws-parameter-store
feat: add assume role support for aws parameter store
2024-10-24 02:48:29 +08:00
ca3b64bf6c Merge pull request from mtariqsajid/patch-1
jenkins integration is now available
2024-10-23 08:32:37 -04:00
b7e48fd556 feat: add assume role support for aws parameter store 2024-10-23 19:56:47 +08:00
c01ea048ce Merge pull request from scott-ray-wilson/fix-region-display
Fix: refine check of when to display region select
2024-10-22 23:58:15 -04:00
7e7d9a2bd5 fix: refine check of when to display region select 2024-10-22 20:56:10 -07:00
782e3a8985 jenkins integration is now available 2024-10-23 01:25:13 +05:00
8497ac831f Merge pull request from Infisical/feat/allow-approvers-to-bypass-secret-change-requests
feat: allow approvers to bypass secret change requests
2024-10-22 22:28:52 +04:00
e5821122d5 Merge pull request from Infisical/feat/moved-mfa-to-org-level
feat: moved mfa to org level
2024-10-22 14:14:48 -04:00
340693cfcd feat: allow approvers to bypass secret change requests 2024-10-23 01:54:40 +08:00
014b9585e0 Merge pull request from Infisical/azure-permission-docs
Add permission note for Azure Key Vault (KV) integration documentation
2024-10-22 09:48:25 -07:00
67373b0883 Add permission note for azure kv integration 2024-10-22 09:43:36 -07:00
2101040a77 misc: updated e2e 2024-10-23 00:13:10 +08:00
2e2fea304b Merge remote-tracking branch 'origin/main' into feat/moved-mfa-to-org-level 2024-10-23 00:04:09 +08:00
571709370d misc: addressed ux issues 2024-10-23 00:00:15 +08:00
e1dbe769a8 doc: added documentation for azure app configuration 2024-10-22 21:41:44 +08:00
e7e0d84c8e feat: azure app configuration integration 2024-10-22 19:41:10 +08:00
4c2ed1cc8b Merge pull request from scott-ray-wilson/fix-uw-secret-overview-overflow
Fix: cap width for tw container size on uw monitors
2024-10-22 00:48:48 -04:00
067b0f4232 fix: cap width for tw container size on uw monitors 2024-10-21 20:58:28 -07:00
6ed786e6d0 Merge pull request from Infisical/daniel/go-sdk-docs-update
docs: go SDK refreshing docs
2024-10-21 19:23:00 -04:00
d187cc3d4d Merge pull request from Infisical/daniel/error-context
feat: more contextual not found errors
2024-10-21 19:09:12 -04:00
764446a2d9 update small missing ' 2024-10-21 19:06:02 -04:00
614e4934a2 Merge pull request from scott-ray-wilson/incorrect-import-value-display-fix
Fix: Correct Secret Value Override Display on Overview Table
2024-10-21 14:18:43 -04:00
14e92f895a fix: only override secret value/id by key if same environment 2024-10-21 10:55:39 -07:00
0a38374a73 Merge pull request from Infisical/daniel/cli-snapshot-update
fix: cli snapshot test error message change
2024-10-21 21:29:34 +04:00
ec3b94a335 fix: snapshot error message change 2024-10-21 21:27:16 +04:00
ca0241bb51 improvement: improve empty table labeling for org group/users 2024-10-21 10:20:43 -07:00
7403385e7c fix: fix select all rows checkbox being checked if no folders/secrets 2024-10-21 09:45:56 -07:00
2cd1141a65 Merge pull request from scott-ray-wilson/group-tables-fixes/improvements
Fix: Group Tables/Pagination Fixes and Improvements
2024-10-21 09:39:00 -07:00
256627b2cc Update go.mdx 2024-10-21 20:38:32 +04:00
fd7e196f8b Merge pull request from Infisical/misc/export-org-data-feature
feat: add migration script to migrate org
2024-10-21 10:16:41 -04:00
212748f140 misc: added cleanup of global/instance-level resources 2024-10-21 21:19:55 +08:00
b61582a60e Merge remote-tracking branch 'origin/main' into misc/export-org-data-feature 2024-10-21 19:04:02 +08:00
9ca8da152b Update go.mdx 2024-10-21 12:08:33 +04:00
c5aa1b8664 Merge pull request from Infisical/vmatsiiako-patch-docsimage-1
Update group-mappings.mdx
2024-10-20 21:18:48 -04:00
7fb3076238 fix: added sdk context support 2024-10-19 08:40:02 +04:00
c6f66226c8 feat: more contextual not found errors 2024-10-19 05:00:14 +04:00
a0865cda2e fix: enable sdk silent mode 2024-10-19 02:59:29 +04:00
1e7b1ccf22 feat: automatic token refreshing 2024-10-19 01:38:11 +04:00
d677654311 improvement: org user groups tables search fixed and col sort added and group add users pagination fixed and search improved to include first and last name 2024-10-18 13:20:17 -07:00
5debeb421d Merge remote-tracking branch 'origin/main' into feat/moved-mfa-to-org-level 2024-10-18 20:07:59 +08:00
25b30e441a misc: added missing enforcement checks 2024-10-18 19:51:31 +08:00
8eb668cd72 misc: removed remaining mfa handling 2024-10-18 03:26:48 +08:00
bb079b3e46 misc: updated cli interactive to support mfa in org select 2024-10-18 01:59:24 +08:00
7a77dc7343 feat: added mfa popup for all select org 2024-10-17 22:29:38 +08:00
bd1ed2614e feat: added enforceMfa toggle for orgs 2024-10-17 03:02:26 +08:00
9192c5caa2 feat: created reusable mfa flow 2024-10-17 02:01:22 +08:00
8da2213bf1 misc: removed mfa from existing login 2024-10-16 22:44:04 +08:00
9f6d837a9b feat: add migration script to migrate org 2024-10-07 17:28:32 +05:30
197 changed files with 4356 additions and 1618 deletions
backend
e2e-test/routes/v1
package-lock.jsonpackage.json
scripts
src
@types
db
ee
lib/api-docs
server
services
api-key
auth-token
auth
certificate-authority
certificate-template
cmek
group-project
identity-access-token
identity-aws-auth
identity-azure-auth
identity-gcp-auth
identity-kubernetes-auth
identity-oidc-auth
identity-project
identity-token-auth
identity-ua
integration-auth
integration
kms
org-admin
org
pki-alert
pki-collection
project-bot
project-env
project-membership
project-role
project
secret-blind-index
secret-folder
secret-import
secret-sharing
secret-tag
secret-v2-bridge
secret
service-token
slack
super-admin
user
webhook
cli
docs
frontend
public/data
src
components/navigation
hooks
api
auth
dynamicSecret
groups
integrations
organization
secrets
subscriptions
index.tsuseResetPageHelper.ts
layouts/AppLayout
pages
integrations
aws-parameter-store
azure-app-configuration
login
signupinvite.tsx
views
IntegrationsPage
IntegrationDetailsPage/components
IntegrationPage.utils.tsx
components/IntegrationsSection
Login
Org/MembersPage/components
OrgGroupsTab/components/OrgGroupsSection
OrgIdentityTab/components/IdentitySection
OrgMembersTab/components/OrgMembersSection
Project
KmsPage/components
MembersPage/components/IdentityTab
SecretApprovalPage/components/SecretApprovalRequest/components
SecretMainPage
SecretOverviewPage
SecretOverviewPage.tsx
components/SecretOverviewTableRow
Settings/OrgSettingsPage/components/OrgAuthTab
Signup/components/UserInfoSSOStep
helm-charts/secrets-operator
k8-operator

@ -39,8 +39,6 @@ describe("Login V1 Router", async () => {
});
expect(res.statusCode).toBe(200);
const payload = JSON.parse(res.payload);
expect(payload).toHaveProperty("mfaEnabled");
expect(payload).toHaveProperty("token");
expect(payload.mfaEnabled).toBeFalsy();
});
});

@ -56,6 +56,7 @@
"google-auth-library": "^9.9.0",
"googleapis": "^137.1.0",
"handlebars": "^4.7.8",
"hdb": "^0.19.10",
"ioredis": "^5.3.2",
"jmespath": "^0.16.0",
"jsonwebtoken": "^9.0.2",
@ -12196,6 +12197,28 @@
"node": ">= 0.4"
}
},
"node_modules/hdb": {
"version": "0.19.10",
"resolved": "https://registry.npmjs.org/hdb/-/hdb-0.19.10.tgz",
"integrity": "sha512-er0oyute1aMjf6v41JU7z1a6Zo8lqj3muC7C4Uoi81Xf4WNdjPb424wUnXIhaf4HS8H9ARDyWrMGJTvPU2jjPw==",
"dependencies": {
"iconv-lite": "^0.4.18"
},
"engines": {
"node": ">= 0.12"
}
},
"node_modules/hdb/node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/helmet": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz",

@ -58,6 +58,7 @@
"migration:latest": "npm run auditlog-migration:latest && knex --knexfile ./src/db/knexfile.ts --client pg migrate:latest",
"migration:status": "npm run auditlog-migration:status && knex --knexfile ./src/db/knexfile.ts --client pg migrate:status",
"migration:rollback": "npm run auditlog-migration:rollback && knex --knexfile ./src/db/knexfile.ts migrate:rollback",
"migrate:org": "tsx ./scripts/migrate-organization.ts",
"seed:new": "tsx ./scripts/create-seed-file.ts",
"seed": "knex --knexfile ./src/db/knexfile.ts --client pg seed:run",
"db:reset": "npm run migration:rollback -- --all && npm run migration:latest"
@ -160,6 +161,7 @@
"google-auth-library": "^9.9.0",
"googleapis": "^137.1.0",
"handlebars": "^4.7.8",
"hdb": "^0.19.10",
"ioredis": "^5.3.2",
"jmespath": "^0.16.0",
"jsonwebtoken": "^9.0.2",

@ -0,0 +1,84 @@
/* eslint-disable */
import promptSync from "prompt-sync";
import { execSync } from "child_process";
import path from "path";
import { existsSync } from "fs";
const prompt = promptSync({
sigint: true
});
const exportDb = () => {
const exportHost = prompt("Enter your Postgres Host to migrate from: ");
const exportPort = prompt("Enter your Postgres Port to migrate from [Default = 5432]: ") ?? "5432";
const exportUser = prompt("Enter your Postgres User to migrate from: [Default = infisical]: ") ?? "infisical";
const exportPassword = prompt("Enter your Postgres Password to migrate from: ");
const exportDatabase = prompt("Enter your Postgres Database to migrate from [Default = infisical]: ") ?? "infisical";
// we do not include the audit_log and secret_sharing entries
execSync(
`PGDATABASE="${exportDatabase}" PGPASSWORD="${exportPassword}" PGHOST="${exportHost}" PGPORT=${exportPort} PGUSER=${exportUser} pg_dump infisical --exclude-table-data="secret_sharing" --exclude-table-data="audit_log*" > ${path.join(
__dirname,
"../src/db/dump.sql"
)}`,
{ stdio: "inherit" }
);
};
const importDbForOrg = () => {
const importHost = prompt("Enter your Postgres Host to migrate to: ");
const importPort = prompt("Enter your Postgres Port to migrate to [Default = 5432]: ") ?? "5432";
const importUser = prompt("Enter your Postgres User to migrate to: [Default = infisical]: ") ?? "infisical";
const importPassword = prompt("Enter your Postgres Password to migrate to: ");
const importDatabase = prompt("Enter your Postgres Database to migrate to [Default = infisical]: ") ?? "infisical";
const orgId = prompt("Enter the organization ID to migrate: ");
if (!existsSync(path.join(__dirname, "../src/db/dump.sql"))) {
console.log("File not found, please export the database first.");
return;
}
execSync(
`PGDATABASE="${importDatabase}" PGPASSWORD="${importPassword}" PGHOST="${importHost}" PGPORT=${importPort} PGUSER=${importUser} psql -f ${path.join(
__dirname,
"../src/db/dump.sql"
)}`
);
execSync(
`PGDATABASE="${importDatabase}" PGPASSWORD="${importPassword}" PGHOST="${importHost}" PGPORT=${importPort} PGUSER=${importUser} psql -c "DELETE FROM public.organizations WHERE id != '${orgId}'"`
);
// delete global/instance-level resources not relevant to the organization to migrate
// users
execSync(
`PGDATABASE="${importDatabase}" PGPASSWORD="${importPassword}" PGHOST="${importHost}" PGPORT=${importPort} PGUSER=${importUser} psql -c 'DELETE FROM users WHERE users.id NOT IN (SELECT org_memberships."userId" FROM org_memberships)'`
);
// identities
execSync(
`PGDATABASE="${importDatabase}" PGPASSWORD="${importPassword}" PGHOST="${importHost}" PGPORT=${importPort} PGUSER=${importUser} psql -c 'DELETE FROM identities WHERE id NOT IN (SELECT "identityId" FROM identity_org_memberships)'`
);
// reset slack configuration in superAdmin
execSync(
`PGDATABASE="${importDatabase}" PGPASSWORD="${importPassword}" PGHOST="${importHost}" PGPORT=${importPort} PGUSER=${importUser} psql -c 'UPDATE super_admin SET "encryptedSlackClientId" = null, "encryptedSlackClientSecret" = null'`
);
console.log("Organization migrated successfully.");
};
const main = () => {
const action = prompt(
"Enter the action to perform\n 1. Export from existing instance.\n 2. Import org to instance.\n \n Action: "
);
if (action === "1") {
exportDb();
} else if (action === "2") {
importDbForOrg();
} else {
console.log("Invalid action");
}
};
main();

4
backend/src/@types/hdb.d.ts vendored Normal file

@ -0,0 +1,4 @@
declare module "hdb" {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Untyped, the function returns `any`.
function createClient(options): any;
}

@ -0,0 +1,19 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasColumn(TableName.Organization, "enforceMfa"))) {
await knex.schema.alterTable(TableName.Organization, (tb) => {
tb.boolean("enforceMfa").defaultTo(false).notNullable();
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.Organization, "enforceMfa")) {
await knex.schema.alterTable(TableName.Organization, (t) => {
t.dropColumn("enforceMfa");
});
}
}

@ -0,0 +1,21 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.SamlConfig, "orgId")) {
await knex.schema.alterTable(TableName.SamlConfig, (t) => {
t.dropForeign("orgId");
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.SamlConfig, "orgId")) {
await knex.schema.alterTable(TableName.SamlConfig, (t) => {
t.dropForeign("orgId");
t.foreign("orgId").references("id").inTable(TableName.Organization);
});
}
}

@ -20,7 +20,8 @@ export const OrganizationsSchema = z.object({
scimEnabled: z.boolean().default(false).nullable().optional(),
kmsDefaultKeyId: z.string().uuid().nullable().optional(),
kmsEncryptedDataKey: zodBuffer.nullable().optional(),
defaultMembershipRole: z.string().default("member")
defaultMembershipRole: z.string().default("member"),
enforceMfa: z.boolean().default(false)
});
export type TOrganizations = z.infer<typeof OrganizationsSchema>;

@ -165,7 +165,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
querystring: z.object({
offset: z.coerce.number().min(0).max(100).default(0).describe(GROUPS.LIST_USERS.offset),
limit: z.coerce.number().min(1).max(100).default(10).describe(GROUPS.LIST_USERS.limit),
username: z.string().optional().describe(GROUPS.LIST_USERS.username)
username: z.string().trim().optional().describe(GROUPS.LIST_USERS.username),
search: z.string().trim().optional().describe(GROUPS.LIST_USERS.search)
}),
response: {
200: z.object({

@ -58,7 +58,7 @@ export const accessApprovalPolicyServiceFactory = ({
enforcementLevel
}: TCreateAccessApprovalPolicy) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
// If there is a group approver people might be added to the group later to meet the approvers quota
const groupApprovers = approvers
@ -89,7 +89,7 @@ export const accessApprovalPolicyServiceFactory = ({
ProjectPermissionSub.SecretApproval
);
const env = await projectEnvDAL.findOne({ slug: environment, projectId: project.id });
if (!env) throw new NotFoundError({ message: "Environment not found" });
if (!env) throw new NotFoundError({ message: `Environment with slug '${environment}' not found` });
let approverUserIds = userApprovers;
if (userApproverNames.length) {
@ -124,7 +124,9 @@ export const accessApprovalPolicyServiceFactory = ({
const verifyAllApprovers = [...approverUserIds];
for (const groupId of groupApprovers) {
usersPromises.push(groupDAL.findAllGroupPossibleMembers({ orgId: actorOrgId, groupId, offset: 0 }));
usersPromises.push(
groupDAL.findAllGroupPossibleMembers({ orgId: actorOrgId, groupId, offset: 0 }).then((group) => group.members)
);
}
const verifyGroupApprovers = (await Promise.all(usersPromises))
.flat()
@ -192,7 +194,7 @@ export const accessApprovalPolicyServiceFactory = ({
projectSlug
}: TListAccessApprovalPoliciesDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
// Anyone in the project should be able to get the policies.
/* const { permission } = */ await permissionService.getProjectPermission(
@ -243,7 +245,9 @@ export const accessApprovalPolicyServiceFactory = ({
throw new BadRequestError({ message: "Approvals cannot be greater than approvers" });
}
if (!accessApprovalPolicy) throw new NotFoundError({ message: "Secret approval policy not found" });
if (!accessApprovalPolicy) {
throw new NotFoundError({ message: `Secret approval policy with ID '${policyId}' not found` });
}
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
@ -327,7 +331,11 @@ export const accessApprovalPolicyServiceFactory = ({
>[] = [];
for (const groupId of groupApprovers) {
usersPromises.push(groupDAL.findAllGroupPossibleMembers({ orgId: actorOrgId, groupId, offset: 0 }));
usersPromises.push(
groupDAL
.findAllGroupPossibleMembers({ orgId: actorOrgId, groupId, offset: 0 })
.then((group) => group.members)
);
}
const verifyGroupApprovers = (await Promise.all(usersPromises))
.flat()
@ -376,7 +384,7 @@ export const accessApprovalPolicyServiceFactory = ({
actorOrgId
}: TDeleteAccessApprovalPolicy) => {
const policy = await accessApprovalPolicyDAL.findById(policyId);
if (!policy) throw new NotFoundError({ message: "Secret approval policy not found" });
if (!policy) throw new NotFoundError({ message: `Secret approval policy with ID '${policyId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -404,7 +412,7 @@ export const accessApprovalPolicyServiceFactory = ({
}: TGetAccessPolicyCountByEnvironmentDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const { membership } = await permissionService.getProjectPermission(
actor,
@ -418,10 +426,10 @@ export const accessApprovalPolicyServiceFactory = ({
}
const environment = await projectEnvDAL.findOne({ projectId: project.id, slug: envSlug });
if (!environment) throw new NotFoundError({ message: "Environment not found" });
if (!environment) throw new NotFoundError({ message: `Environment with slug '${envSlug}' not found` });
const policies = await accessApprovalPolicyDAL.find({ envId: environment.id, projectId: project.id });
if (!policies) throw new NotFoundError({ message: "No policies found" });
if (!policies) throw new NotFoundError({ message: `No policies found in environment with slug '${envSlug}'` });
return { count: policies.length };
};
@ -437,7 +445,7 @@ export const accessApprovalPolicyServiceFactory = ({
if (!policy) {
throw new NotFoundError({
message: "Cannot find access approval policy"
message: `Cannot find access approval policy with ID ${policyId}`
});
}

@ -99,7 +99,7 @@ export const accessApprovalRequestServiceFactory = ({
}: TCreateAccessApprovalRequestDTO) => {
const cfg = getConfig();
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
// Anyone can create an access approval request.
const { membership } = await permissionService.getProjectPermission(
@ -121,13 +121,17 @@ export const accessApprovalRequestServiceFactory = ({
const { envSlug, secretPath, accessTypes } = verifyRequestedPermissions({ permissions: requestedPermissions });
const environment = await projectEnvDAL.findOne({ projectId: project.id, slug: envSlug });
if (!environment) throw new NotFoundError({ message: "Environment not found" });
if (!environment) throw new NotFoundError({ message: `Environment with slug '${envSlug}' not found` });
const policy = await accessApprovalPolicyDAL.findOne({
envId: environment.id,
secretPath
});
if (!policy) throw new NotFoundError({ message: "No policy matching criteria was found." });
if (!policy) {
throw new NotFoundError({
message: `No policy in environment with slug '${environment.slug}' and with secret path '${secretPath}' was found.`
});
}
const approverIds: string[] = [];
const approverGroupIds: string[] = [];
@ -147,10 +151,12 @@ export const accessApprovalRequestServiceFactory = ({
const groupUsers = (
await Promise.all(
approverGroupIds.map((groupApproverId) =>
groupDAL.findAllGroupPossibleMembers({
orgId: actorOrgId,
groupId: groupApproverId
})
groupDAL
.findAllGroupPossibleMembers({
orgId: actorOrgId,
groupId: groupApproverId
})
.then((group) => group.members)
)
)
).flat();
@ -264,7 +270,7 @@ export const accessApprovalRequestServiceFactory = ({
actorAuthMethod
}: TListApprovalRequestsDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const { membership } = await permissionService.getProjectPermission(
actor,
@ -300,7 +306,9 @@ export const accessApprovalRequestServiceFactory = ({
actorOrgId
}: TReviewAccessRequestDTO) => {
const accessApprovalRequest = await accessApprovalRequestDAL.findById(requestId);
if (!accessApprovalRequest) throw new NotFoundError({ message: "Secret approval request not found" });
if (!accessApprovalRequest) {
throw new NotFoundError({ message: `Secret approval request with ID '${requestId}' not found` });
}
const { policy } = accessApprovalRequest;
const { membership, hasRole } = await permissionService.getProjectPermission(
@ -421,7 +429,7 @@ export const accessApprovalRequestServiceFactory = ({
const getCount = async ({ projectSlug, actor, actorAuthMethod, actorId, actorOrgId }: TGetAccessRequestCountDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const { membership } = await permissionService.getProjectPermission(
actor,

@ -130,7 +130,7 @@ export const auditLogStreamServiceFactory = ({
});
const logStream = await auditLogStreamDAL.findById(id);
if (!logStream) throw new NotFoundError({ message: "Audit log stream not found" });
if (!logStream) throw new NotFoundError({ message: `Audit log stream with ID '${id}' not found` });
const { orgId } = logStream;
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
@ -182,7 +182,7 @@ export const auditLogStreamServiceFactory = ({
if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID attached to authentication token" });
const logStream = await auditLogStreamDAL.findById(id);
if (!logStream) throw new NotFoundError({ message: "Audit log stream not found" });
if (!logStream) throw new NotFoundError({ message: `Audit log stream with ID '${id}' not found` });
const { orgId } = logStream;
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
@ -194,7 +194,7 @@ export const auditLogStreamServiceFactory = ({
const getById = async ({ id, actor, actorId, actorOrgId, actorAuthMethod }: TGetDetailsAuditLogStreamDTO) => {
const logStream = await auditLogStreamDAL.findById(id);
if (!logStream) throw new NotFoundError({ message: "Audit log stream not found" });
if (!logStream) throw new NotFoundError({ message: `Audit log stream with ID '${id}' not found` });
const { orgId } = logStream;
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);

@ -34,7 +34,7 @@ export const certificateAuthorityCrlServiceFactory = ({
*/
const getCrlById = async (crlId: TGetCrlById) => {
const caCrl = await certificateAuthorityCrlDAL.findById(crlId);
if (!caCrl) throw new NotFoundError({ message: "CRL not found" });
if (!caCrl) throw new NotFoundError({ message: `CRL with ID '${crlId}' not found` });
const ca = await certificateAuthorityDAL.findById(caCrl.caId);
@ -64,7 +64,7 @@ export const certificateAuthorityCrlServiceFactory = ({
*/
const getCaCrls = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCrlsDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,

@ -211,7 +211,7 @@ export const certificateEstServiceFactory = ({
const certTemplate = await certificateTemplateDAL.findById(certificateTemplateId);
if (!certTemplate) {
throw new NotFoundError({
message: "Certificate template not found"
message: `Certificate template with ID '${certificateTemplateId}' not found`
});
}
@ -236,7 +236,7 @@ export const certificateEstServiceFactory = ({
const ca = await certificateAuthorityDAL.findById(certTemplate.caId);
if (!ca) {
throw new NotFoundError({
message: "Certificate Authority not found"
message: `Certificate Authority with ID '${certTemplate.caId}' not found`
});
}

@ -61,7 +61,7 @@ export const dynamicSecretLeaseServiceFactory = ({
}: TCreateDynamicSecretLeaseDTO) => {
const appCfg = getConfig();
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -84,10 +84,16 @@ export const dynamicSecretLeaseServiceFactory = ({
}
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${path}' in environment with slug '${environmentSlug}' not found`
});
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new NotFoundError({ message: "Dynamic secret not found" });
if (!dynamicSecretCfg)
throw new NotFoundError({
message: `Dynamic secret with name '${name}' in folder with path '${path}' not found`
});
const totalLeasesTaken = await dynamicSecretLeaseDAL.countLeasesForDynamicSecret(dynamicSecretCfg.id);
if (totalLeasesTaken >= appCfg.MAX_LEASE_LIMIT)
@ -134,7 +140,7 @@ export const dynamicSecretLeaseServiceFactory = ({
leaseId
}: TRenewDynamicSecretLeaseDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -157,10 +163,15 @@ export const dynamicSecretLeaseServiceFactory = ({
}
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${path}' in environment with slug '${environmentSlug}' not found`
});
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
if (!dynamicSecretLease) throw new NotFoundError({ message: "Dynamic secret lease not found" });
if (!dynamicSecretLease) {
throw new NotFoundError({ message: `Dynamic secret lease with ID '${leaseId}' not found` });
}
const dynamicSecretCfg = dynamicSecretLease.dynamicSecret;
const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders];
@ -208,7 +219,7 @@ export const dynamicSecretLeaseServiceFactory = ({
isForced
}: TDeleteDynamicSecretLeaseDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -224,10 +235,14 @@ export const dynamicSecretLeaseServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${path}' in environment with slug '${environmentSlug}' not found`
});
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
if (!dynamicSecretLease) throw new NotFoundError({ message: "Dynamic secret lease not found" });
if (!dynamicSecretLease)
throw new NotFoundError({ message: `Dynamic secret lease with ID '${leaseId}' not found` });
const dynamicSecretCfg = dynamicSecretLease.dynamicSecret;
const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders];
@ -273,7 +288,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actorAuthMethod
}: TListDynamicSecretLeasesDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -289,10 +304,16 @@ export const dynamicSecretLeaseServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${path}' in environment with slug '${environmentSlug}' not found`
});
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new NotFoundError({ message: "Dynamic secret not found" });
if (!dynamicSecretCfg)
throw new NotFoundError({
message: `Dynamic secret with name '${name}' in folder with path '${path}' not found`
});
const dynamicSecretLeases = await dynamicSecretLeaseDAL.find({ dynamicSecretId: dynamicSecretCfg.id });
return dynamicSecretLeases;
@ -309,7 +330,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actorAuthMethod
}: TDetailsDynamicSecretLeaseDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -325,10 +346,11 @@ export const dynamicSecretLeaseServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) throw new NotFoundError({ message: `Folder with path '${path}' not found` });
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
if (!dynamicSecretLease) throw new NotFoundError({ message: "Dynamic secret lease not found" });
if (!dynamicSecretLease)
throw new NotFoundError({ message: `Dynamic secret lease with ID '${leaseId}' not found` });
return dynamicSecretLease;
};

@ -0,0 +1,20 @@
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { getDbConnectionHost } from "@app/lib/knex";
export const verifyHostInputValidity = (host: string) => {
const appCfg = getConfig();
const dbHost = appCfg.DB_HOST || getDbConnectionHost(appCfg.DB_CONNECTION_URI);
if (
appCfg.isCloud &&
// localhost
// internal ips
(host === "host.docker.internal" || host.match(/^10\.\d+\.\d+\.\d+/) || host.match(/^192\.168\.\d+\.\d+/))
)
throw new BadRequestError({ message: "Invalid db host" });
if (host === "localhost" || host === "127.0.0.1" || dbHost === host) {
throw new BadRequestError({ message: "Invalid db host" });
}
};

@ -66,7 +66,7 @@ export const dynamicSecretServiceFactory = ({
actorAuthMethod
}: TCreateDynamicSecretDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -89,7 +89,9 @@ export const dynamicSecretServiceFactory = ({
}
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) {
throw new NotFoundError({ message: `Folder with path '${path}' in environment '${environmentSlug}' not found` });
}
const existingDynamicSecret = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (existingDynamicSecret)
@ -134,7 +136,7 @@ export const dynamicSecretServiceFactory = ({
actorAuthMethod
}: TUpdateDynamicSecretDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
@ -158,11 +160,15 @@ export const dynamicSecretServiceFactory = ({
}
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({ message: `Folder with path '${path}' in environment '${environmentSlug}' not found` });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new NotFoundError({ message: "Dynamic secret not found" });
if (!dynamicSecretCfg) {
throw new NotFoundError({
message: `Dynamic secret with name '${name}' in folder '${folder.path}' not found`
});
}
if (newName) {
const existingDynamicSecret = await dynamicSecretDAL.findOne({ name: newName, folderId: folder.id });
if (existingDynamicSecret)
@ -213,7 +219,7 @@ export const dynamicSecretServiceFactory = ({
isForced
}: TDeleteDynamicSecretDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
@ -230,10 +236,13 @@ export const dynamicSecretServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({ message: `Folder with path '${path}' in environment '${environmentSlug}' not found` });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
if (!dynamicSecretCfg) {
throw new NotFoundError({ message: `Dynamic secret with name '${name}' in folder '${folder.path}' not found` });
}
const leases = await dynamicSecretLeaseDAL.find({ dynamicSecretId: dynamicSecretCfg.id });
// when not forced we check with the external system to first remove the things
@ -271,7 +280,7 @@ export const dynamicSecretServiceFactory = ({
actor
}: TDetailsDynamicSecretDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -287,10 +296,13 @@ export const dynamicSecretServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({ message: `Folder with path '${path}' in environment '${environmentSlug}' not found` });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new NotFoundError({ message: "Dynamic secret not found" });
if (!dynamicSecretCfg) {
throw new NotFoundError({ message: `Dynamic secret with name '${name} in folder '${path}' not found` });
}
const decryptedStoredInput = JSON.parse(
infisicalSymmetricDecrypt({
keyEncoding: dynamicSecretCfg.keyEncoding as SecretKeyEncoding,
@ -335,7 +347,11 @@ export const dynamicSecretServiceFactory = ({
}
const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environmentSlugs, path);
if (!folders.length) throw new NotFoundError({ message: "Folders not found" });
if (!folders.length) {
throw new NotFoundError({
message: `Folders with path '${path}' in environments with slugs '${environmentSlugs.join(", ")}' not found`
});
}
const dynamicSecretCfg = await dynamicSecretDAL.find(
{ $in: { folderId: folders.map((folder) => folder.id) }, $search: search ? { name: `%${search}%` } : undefined },
@ -369,7 +385,9 @@ export const dynamicSecretServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) {
throw new NotFoundError({ message: `Folder with path '${path}' in environment '${environmentSlug}' not found` });
}
const dynamicSecretCfg = await dynamicSecretDAL.find(
{ folderId: folder.id, $search: search ? { name: `%${search}%` } : undefined },
@ -398,7 +416,7 @@ export const dynamicSecretServiceFactory = ({
if (!projectId) {
if (!projectSlug) throw new BadRequestError({ message: "Project ID or slug required" });
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
projectId = project.id;
}
@ -415,7 +433,8 @@ export const dynamicSecretServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({ message: `Folder with path '${path}' in environment '${environmentSlug}' not found` });
const dynamicSecretCfg = await dynamicSecretDAL.find(
{ folderId: folder.id, $search: search ? { name: `%${search}%` } : undefined },
@ -459,7 +478,10 @@ export const dynamicSecretServiceFactory = ({
}
const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environmentSlugs, path);
if (!folders.length) throw new NotFoundError({ message: "Folders not found" });
if (!folders.length)
throw new NotFoundError({
message: `Folders with path '${path} in environments with slugs '${environmentSlugs.join(", ")}' not found`
});
const dynamicSecretCfg = await dynamicSecretDAL.listDynamicSecretsByFolderIds({
folderIds: folders.map((folder) => folder.id),

@ -2,10 +2,9 @@ import { Client as ElasticSearchClient } from "@elastic/elasticsearch";
import { customAlphabet } from "nanoid";
import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { verifyHostInputValidity } from "../dynamic-secret-fns";
import { DynamicSecretElasticSearchSchema, ElasticSearchAuthTypes, TDynamicProviderFns } from "./models";
const generatePassword = () => {
@ -19,23 +18,8 @@ const generateUsername = () => {
export const ElasticSearchProvider = (): TDynamicProviderFns => {
const validateProviderInputs = async (inputs: unknown) => {
const appCfg = getConfig();
const isCloud = Boolean(appCfg.LICENSE_SERVER_KEY); // quick and dirty way to check if its cloud or not
const providerInputs = await DynamicSecretElasticSearchSchema.parseAsync(inputs);
if (
isCloud &&
// localhost
// internal ips
(providerInputs.host === "host.docker.internal" ||
providerInputs.host.match(/^10\.\d+\.\d+\.\d+/) ||
providerInputs.host.match(/^192\.168\.\d+\.\d+/))
) {
throw new BadRequestError({ message: "Invalid db host" });
}
if (providerInputs.host === "localhost" || providerInputs.host === "127.0.0.1") {
throw new BadRequestError({ message: "Invalid db host" });
}
verifyHostInputValidity(providerInputs.host);
return providerInputs;
};

@ -9,6 +9,7 @@ import { MongoAtlasProvider } from "./mongo-atlas";
import { MongoDBProvider } from "./mongo-db";
import { RabbitMqProvider } from "./rabbit-mq";
import { RedisDatabaseProvider } from "./redis";
import { SapHanaProvider } from "./sap-hana";
import { SqlDatabaseProvider } from "./sql-database";
export const buildDynamicSecretProviders = () => ({
@ -22,5 +23,6 @@ export const buildDynamicSecretProviders = () => ({
[DynamicSecretProviders.ElasticSearch]: ElasticSearchProvider(),
[DynamicSecretProviders.RabbitMq]: RabbitMqProvider(),
[DynamicSecretProviders.AzureEntraID]: AzureEntraIDProvider(),
[DynamicSecretProviders.Ldap]: LdapProvider()
[DynamicSecretProviders.Ldap]: LdapProvider(),
[DynamicSecretProviders.SapHana]: SapHanaProvider()
});

@ -166,6 +166,17 @@ export const DynamicSecretMongoDBSchema = z.object({
)
});
export const DynamicSecretSapHanaSchema = z.object({
host: z.string().trim().toLowerCase(),
port: z.number(),
username: z.string().trim(),
password: z.string().trim(),
creationStatement: z.string().trim(),
revocationStatement: z.string().trim(),
renewStatement: z.string().trim().optional(),
ca: z.string().optional()
});
export const AzureEntraIDSchema = z.object({
tenantId: z.string().trim().min(1),
userId: z.string().trim().min(1),
@ -196,7 +207,8 @@ export enum DynamicSecretProviders {
MongoDB = "mongo-db",
RabbitMq = "rabbit-mq",
AzureEntraID = "azure-entra-id",
Ldap = "ldap"
Ldap = "ldap",
SapHana = "sap-hana"
}
export const DynamicSecretProviderSchema = z.discriminatedUnion("type", [
@ -204,6 +216,7 @@ export const DynamicSecretProviderSchema = z.discriminatedUnion("type", [
z.object({ type: z.literal(DynamicSecretProviders.Cassandra), inputs: DynamicSecretCassandraSchema }),
z.object({ type: z.literal(DynamicSecretProviders.AwsIam), inputs: DynamicSecretAwsIamSchema }),
z.object({ type: z.literal(DynamicSecretProviders.Redis), inputs: DynamicSecretRedisDBSchema }),
z.object({ type: z.literal(DynamicSecretProviders.SapHana), inputs: DynamicSecretSapHanaSchema }),
z.object({ type: z.literal(DynamicSecretProviders.AwsElastiCache), inputs: DynamicSecretAwsElastiCacheSchema }),
z.object({ type: z.literal(DynamicSecretProviders.MongoAtlas), inputs: DynamicSecretMongoAtlasSchema }),
z.object({ type: z.literal(DynamicSecretProviders.ElasticSearch), inputs: DynamicSecretElasticSearchSchema }),

@ -2,10 +2,9 @@ import { MongoClient } from "mongodb";
import { customAlphabet } from "nanoid";
import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { verifyHostInputValidity } from "../dynamic-secret-fns";
import { DynamicSecretMongoDBSchema, TDynamicProviderFns } from "./models";
const generatePassword = (size = 48) => {
@ -19,22 +18,8 @@ const generateUsername = () => {
export const MongoDBProvider = (): TDynamicProviderFns => {
const validateProviderInputs = async (inputs: unknown) => {
const appCfg = getConfig();
const providerInputs = await DynamicSecretMongoDBSchema.parseAsync(inputs);
if (
appCfg.isCloud &&
// localhost
// internal ips
(providerInputs.host === "host.docker.internal" ||
providerInputs.host.match(/^10\.\d+\.\d+\.\d+/) ||
providerInputs.host.match(/^192\.168\.\d+\.\d+/))
)
throw new BadRequestError({ message: "Invalid db host" });
if (providerInputs.host === "localhost" || providerInputs.host === "127.0.0.1") {
throw new BadRequestError({ message: "Invalid db host" });
}
verifyHostInputValidity(providerInputs.host);
return providerInputs;
};

@ -3,12 +3,11 @@ import https from "https";
import { customAlphabet } from "nanoid";
import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { removeTrailingSlash } from "@app/lib/fn";
import { logger } from "@app/lib/logger";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { verifyHostInputValidity } from "../dynamic-secret-fns";
import { DynamicSecretRabbitMqSchema, TDynamicProviderFns } from "./models";
const generatePassword = () => {
@ -79,23 +78,8 @@ async function deleteRabbitMqUser({ axiosInstance, usernameToDelete }: TDeleteRa
export const RabbitMqProvider = (): TDynamicProviderFns => {
const validateProviderInputs = async (inputs: unknown) => {
const appCfg = getConfig();
const isCloud = Boolean(appCfg.LICENSE_SERVER_KEY); // quick and dirty way to check if its cloud or not
const providerInputs = await DynamicSecretRabbitMqSchema.parseAsync(inputs);
if (
isCloud &&
// localhost
// internal ips
(providerInputs.host === "host.docker.internal" ||
providerInputs.host.match(/^10\.\d+\.\d+\.\d+/) ||
providerInputs.host.match(/^192\.168\.\d+\.\d+/))
) {
throw new BadRequestError({ message: "Invalid db host" });
}
if (providerInputs.host === "localhost" || providerInputs.host === "127.0.0.1") {
throw new BadRequestError({ message: "Invalid db host" });
}
verifyHostInputValidity(providerInputs.host);
return providerInputs;
};

@ -3,11 +3,10 @@ import { Redis } from "ioredis";
import { customAlphabet } from "nanoid";
import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { getDbConnectionHost } from "@app/lib/knex";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { verifyHostInputValidity } from "../dynamic-secret-fns";
import { DynamicSecretRedisDBSchema, TDynamicProviderFns } from "./models";
const generatePassword = () => {
@ -51,22 +50,8 @@ const executeTransactions = async (connection: Redis, commands: string[]): Promi
export const RedisDatabaseProvider = (): TDynamicProviderFns => {
const validateProviderInputs = async (inputs: unknown) => {
const appCfg = getConfig();
const isCloud = Boolean(appCfg.LICENSE_SERVER_KEY); // quick and dirty way to check if its cloud or not
const dbHost = appCfg.DB_HOST || getDbConnectionHost(appCfg.DB_CONNECTION_URI);
const providerInputs = await DynamicSecretRedisDBSchema.parseAsync(inputs);
if (
isCloud &&
// localhost
// internal ips
(providerInputs.host === "host.docker.internal" ||
providerInputs.host.match(/^10\.\d+\.\d+\.\d+/) ||
providerInputs.host.match(/^192\.168\.\d+\.\d+/))
)
throw new BadRequestError({ message: "Invalid db host" });
if (providerInputs.host === "localhost" || providerInputs.host === "127.0.0.1" || dbHost === providerInputs.host)
throw new BadRequestError({ message: "Invalid db host" });
verifyHostInputValidity(providerInputs.host);
return providerInputs;
};

@ -0,0 +1,174 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import handlebars from "handlebars";
import hdb from "hdb";
import { customAlphabet } from "nanoid";
import { z } from "zod";
import { BadRequestError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { verifyHostInputValidity } from "../dynamic-secret-fns";
import { DynamicSecretSapHanaSchema, TDynamicProviderFns } from "./models";
const generatePassword = (size = 48) => {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return customAlphabet(charset, 48)(size);
};
const generateUsername = () => {
return alphaNumericNanoId(32);
};
export const SapHanaProvider = (): TDynamicProviderFns => {
const validateProviderInputs = async (inputs: unknown) => {
const providerInputs = await DynamicSecretSapHanaSchema.parseAsync(inputs);
verifyHostInputValidity(providerInputs.host);
return providerInputs;
};
const getClient = async (providerInputs: z.infer<typeof DynamicSecretSapHanaSchema>) => {
const client = hdb.createClient({
host: providerInputs.host,
port: providerInputs.port,
user: providerInputs.username,
password: providerInputs.password,
...(providerInputs.ca
? {
ca: providerInputs.ca
}
: {})
});
await new Promise((resolve, reject) => {
client.connect((err: any) => {
if (err) {
return reject(err);
}
if (client.readyState) {
return resolve(true);
}
reject(new Error("SAP HANA client not ready"));
});
});
return client;
};
const validateConnection = async (inputs: unknown) => {
const providerInputs = await validateProviderInputs(inputs);
const client = await getClient(providerInputs);
const testResult: boolean = await new Promise((resolve, reject) => {
client.exec("SELECT 1 FROM DUMMY;", (err: any) => {
if (err) {
reject();
}
resolve(true);
});
});
return testResult;
};
const create = async (inputs: unknown, expireAt: number) => {
const providerInputs = await validateProviderInputs(inputs);
const username = generateUsername();
const password = generatePassword();
const expiration = new Date(expireAt).toISOString();
const client = await getClient(providerInputs);
const creationStatement = handlebars.compile(providerInputs.creationStatement, { noEscape: true })({
username,
password,
expiration
});
const queries = creationStatement.toString().split(";").filter(Boolean);
for await (const query of queries) {
await new Promise((resolve, reject) => {
client.exec(query, (err: any) => {
if (err) {
reject(
new BadRequestError({
message: err.message
})
);
}
resolve(true);
});
});
}
return { entityId: username, data: { DB_USERNAME: username, DB_PASSWORD: password } };
};
const revoke = async (inputs: unknown, username: string) => {
const providerInputs = await validateProviderInputs(inputs);
const client = await getClient(providerInputs);
const revokeStatement = handlebars.compile(providerInputs.revocationStatement)({ username });
const queries = revokeStatement.toString().split(";").filter(Boolean);
for await (const query of queries) {
await new Promise((resolve, reject) => {
client.exec(query, (err: any) => {
if (err) {
reject(
new BadRequestError({
message: err.message
})
);
}
resolve(true);
});
});
}
return { entityId: username };
};
const renew = async (inputs: unknown, username: string, expireAt: number) => {
const providerInputs = await validateProviderInputs(inputs);
const client = await getClient(providerInputs);
try {
const expiration = new Date(expireAt).toISOString();
const renewStatement = handlebars.compile(providerInputs.renewStatement)({ username, expiration });
const queries = renewStatement.toString().split(";").filter(Boolean);
for await (const query of queries) {
await new Promise((resolve, reject) => {
client.exec(query, (err: any) => {
if (err) {
reject(
new BadRequestError({
message: err.message
})
);
}
resolve(true);
});
});
}
} finally {
client.disconnect();
}
return { entityId: username };
};
return {
validateProviderInputs,
validateConnection,
create,
revoke,
renew
};
};

@ -3,11 +3,9 @@ import knex from "knex";
import { customAlphabet } from "nanoid";
import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { getDbConnectionHost } from "@app/lib/knex";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { verifyHostInputValidity } from "../dynamic-secret-fns";
import { DynamicSecretSqlDBSchema, SqlProviders, TDynamicProviderFns } from "./models";
const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
@ -29,27 +27,8 @@ const generateUsername = (provider: SqlProviders) => {
export const SqlDatabaseProvider = (): TDynamicProviderFns => {
const validateProviderInputs = async (inputs: unknown) => {
const appCfg = getConfig();
const isCloud = Boolean(appCfg.LICENSE_SERVER_KEY); // quick and dirty way to check if its cloud or not
const dbHost = appCfg.DB_HOST || getDbConnectionHost(appCfg.DB_CONNECTION_URI);
const providerInputs = await DynamicSecretSqlDBSchema.parseAsync(inputs);
if (
isCloud &&
// localhost
// internal ips
(providerInputs.host === "host.docker.internal" ||
providerInputs.host.match(/^10\.\d+\.\d+\.\d+/) ||
providerInputs.host.match(/^192\.168\.\d+\.\d+/))
)
throw new BadRequestError({ message: "Invalid db host" });
if (
providerInputs.host === "localhost" ||
providerInputs.host === "127.0.0.1" ||
// database infisical uses
dbHost === providerInputs.host
)
throw new BadRequestError({ message: "Invalid db host" });
verifyHostInputValidity(providerInputs.host);
return providerInputs;
};

@ -145,7 +145,7 @@ export const externalKmsServiceFactory = ({
const kmsName = name ? slugify(name) : undefined;
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
if (!externalKmsDoc) throw new NotFoundError({ message: "External kms not found" });
if (!externalKmsDoc) throw new NotFoundError({ message: `External KMS with ID '${kmsId}' not found` });
let sanitizedProviderInput = "";
const { encryptor: orgDataKeyEncryptor, decryptor: orgDataKeyDecryptor } =
@ -220,7 +220,7 @@ export const externalKmsServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Kms);
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
if (!externalKmsDoc) throw new NotFoundError({ message: "External kms not found" });
if (!externalKmsDoc) throw new NotFoundError({ message: `External KMS with ID '${kmsId}' not found` });
const externalKms = await externalKmsDAL.transaction(async (tx) => {
const kms = await kmsDAL.deleteById(kmsDoc.id, tx);
@ -258,7 +258,7 @@ export const externalKmsServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Kms);
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
if (!externalKmsDoc) throw new NotFoundError({ message: "External kms not found" });
if (!externalKmsDoc) throw new NotFoundError({ message: `External KMS with ID '${kmsId}' not found` });
const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization,
@ -298,7 +298,7 @@ export const externalKmsServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Kms);
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
if (!externalKmsDoc) throw new NotFoundError({ message: "External kms not found" });
if (!externalKmsDoc) throw new NotFoundError({ message: `External KMS with ID '${kmsDoc.id}' not found` });
const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization,

@ -65,16 +65,18 @@ export const groupDALFactory = (db: TDbClient) => {
groupId,
offset = 0,
limit,
username
username, // depreciated in favor of search
search
}: {
orgId: string;
groupId: string;
offset?: number;
limit?: number;
username?: string;
search?: string;
}) => {
try {
let query = db
const query = db
.replicaNode()(TableName.OrgMembership)
.where(`${TableName.OrgMembership}.orgId`, orgId)
.join(TableName.Users, `${TableName.OrgMembership}.userId`, `${TableName.Users}.id`)
@ -92,31 +94,39 @@ export const groupDALFactory = (db: TDbClient) => {
db.ref("username").withSchema(TableName.Users),
db.ref("firstName").withSchema(TableName.Users),
db.ref("lastName").withSchema(TableName.Users),
db.ref("id").withSchema(TableName.Users).as("userId")
db.ref("id").withSchema(TableName.Users).as("userId"),
db.raw(`count(*) OVER() as total_count`)
)
.where({ isGhost: false })
.offset(offset);
.offset(offset)
.orderBy("firstName", "asc");
if (limit) {
query = query.limit(limit);
void query.limit(limit);
}
if (username) {
query = query.andWhere(`${TableName.Users}.username`, "ilike", `%${username}%`);
if (search) {
void query.andWhereRaw(`CONCAT_WS(' ', "firstName", "lastName", "username") ilike '%${search}%'`);
} else if (username) {
void query.andWhere(`${TableName.Users}.username`, "ilike", `%${username}%`);
}
const members = await query;
return members.map(
({ email, username: memberUsername, firstName, lastName, userId, groupId: memberGroupId }) => ({
id: userId,
email,
username: memberUsername,
firstName,
lastName,
isPartOfGroup: !!memberGroupId
})
);
return {
members: members.map(
({ email, username: memberUsername, firstName, lastName, userId, groupId: memberGroupId }) => ({
id: userId,
email,
username: memberUsername,
firstName,
lastName,
isPartOfGroup: !!memberGroupId
})
),
// @ts-expect-error col select is raw and not strongly typed
totalCount: Number(members?.[0]?.total_count ?? 0)
};
} catch (error) {
throw new DatabaseError({ error, name: "Find all org members" });
}

@ -74,7 +74,7 @@ const addAcceptedUsersToGroup = async ({
if (!ghostUser) {
throw new NotFoundError({
message: "Failed to find project owner"
message: `Failed to find project owner of project with ID '${projectId}'`
});
}
@ -82,7 +82,7 @@ const addAcceptedUsersToGroup = async ({
if (!ghostUserLatestKey) {
throw new NotFoundError({
message: "Failed to find project owner's latest key"
message: `Failed to find project owner's latest key in project with ID '${projectId}'`
});
}
@ -90,7 +90,7 @@ const addAcceptedUsersToGroup = async ({
if (!bot) {
throw new NotFoundError({
message: "Failed to find project bot"
message: `Failed to find project bot in project with ID '${projectId}'`
});
}

@ -221,7 +221,8 @@ export const groupServiceFactory = ({
actor,
actorId,
actorAuthMethod,
actorOrgId
actorOrgId,
search
}: TListGroupUsersDTO) => {
if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID provided in request" });
@ -244,17 +245,16 @@ export const groupServiceFactory = ({
message: `Failed to find group with ID ${id}`
});
const users = await groupDAL.findAllGroupPossibleMembers({
const { members, totalCount } = await groupDAL.findAllGroupPossibleMembers({
orgId: group.orgId,
groupId: group.id,
offset,
limit,
username
username,
search
});
const count = await orgDAL.countAllOrgMembers(group.orgId);
return { users, totalCount: count };
return { users: members, totalCount };
};
const addUserToGroup = async ({ id, username, actor, actorId, actorAuthMethod, actorOrgId }: TAddUserToGroupDTO) => {

@ -38,6 +38,7 @@ export type TListGroupUsersDTO = {
offset: number;
limit: number;
username?: string;
search?: string;
} & TGenericPermission;
export type TAddUserToGroupDTO = {

@ -65,7 +65,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
...dto
}: TCreateIdentityPrivilegeDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
@ -137,7 +137,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
actorAuthMethod
}: TUpdateIdentityPrivilegeDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
@ -167,7 +167,11 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
slug,
projectMembershipId: identityProjectMembership.id
});
if (!identityPrivilege) throw new NotFoundError({ message: "Identity additional privilege not found" });
if (!identityPrivilege) {
throw new NotFoundError({
message: `Identity additional privilege with slug '${slug}' not found for the specified identity with ID '${identityProjectMembership.identityId}'`
});
}
if (data?.slug) {
const existingSlug = await identityProjectAdditionalPrivilegeDAL.findOne({
slug: data.slug,
@ -218,7 +222,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
actorAuthMethod
}: TDeleteIdentityPrivilegeDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
@ -248,7 +252,11 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
slug,
projectMembershipId: identityProjectMembership.id
});
if (!identityPrivilege) throw new NotFoundError({ message: "Identity additional privilege not found" });
if (!identityPrivilege) {
throw new NotFoundError({
message: `Identity additional privilege with slug '${slug}' not found for the specified identity with ID '${identityProjectMembership.identityId}'`
});
}
const deletedPrivilege = await identityProjectAdditionalPrivilegeDAL.deleteById(identityPrivilege.id);
return {
@ -268,7 +276,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
actorAuthMethod
}: TGetIdentityPrivilegeDetailsDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
@ -287,8 +295,11 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
slug,
projectMembershipId: identityProjectMembership.id
});
if (!identityPrivilege) throw new NotFoundError({ message: "Identity additional privilege not found" });
if (!identityPrivilege) {
throw new NotFoundError({
message: `Identity additional privilege with slug '${slug}' not found for the specified identity with ID '${identityProjectMembership.identityId}'`
});
}
return {
...identityPrivilege,
permissions: unpackPermissions(identityPrivilege.permissions)
@ -304,7 +315,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
projectSlug
}: TListIdentityPrivilegesDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });

@ -247,7 +247,11 @@ export const ldapConfigServiceFactory = ({
};
const orgBot = await orgBotDAL.findOne({ orgId });
if (!orgBot) throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
if (!orgBot)
throw new NotFoundError({
message: `Organization bot in organization with ID '${orgId}' not found`,
name: "OrgBotNotFound"
});
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
iv: orgBot.symmetricKeyIV,
@ -283,10 +287,19 @@ export const ldapConfigServiceFactory = ({
const getLdapCfg = async (filter: { orgId: string; isActive?: boolean; id?: string }) => {
const ldapConfig = await ldapConfigDAL.findOne(filter);
if (!ldapConfig) throw new NotFoundError({ message: "Failed to find organization LDAP data" });
if (!ldapConfig) {
throw new NotFoundError({
message: `Failed to find organization LDAP data in organization with ID '${filter.orgId}'`
});
}
const orgBot = await orgBotDAL.findOne({ orgId: ldapConfig.orgId });
if (!orgBot) throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
if (!orgBot) {
throw new NotFoundError({
message: `Organization bot not found in organization with ID ${ldapConfig.orgId}`,
name: "OrgBotNotFound"
});
}
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
@ -369,7 +382,7 @@ export const ldapConfigServiceFactory = ({
const bootLdap = async (organizationSlug: string) => {
const organization = await orgDAL.findOne({ slug: organizationSlug });
if (!organization) throw new NotFoundError({ message: "Organization not found" });
if (!organization) throw new NotFoundError({ message: `Organization with slug '${organizationSlug}' not found` });
const ldapConfig = await getLdapCfg({
orgId: organization.id,
@ -426,7 +439,7 @@ export const ldapConfigServiceFactory = ({
});
const organization = await orgDAL.findOrgById(orgId);
if (!organization) throw new NotFoundError({ message: "Organization not found" });
if (!organization) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
if (userAlias) {
await userDAL.transaction(async (tx) => {
@ -700,7 +713,11 @@ export const ldapConfigServiceFactory = ({
orgId
});
if (!ldapConfig) throw new NotFoundError({ message: "Failed to find organization LDAP data" });
if (!ldapConfig) {
throw new NotFoundError({
message: `Failed to find organization LDAP data with ID '${ldapConfigId}' in organization with ID ${orgId}`
});
}
const groupMaps = await ldapGroupMapDAL.findLdapGroupMapsByLdapConfigId(ldapConfigId);
@ -747,7 +764,11 @@ export const ldapConfigServiceFactory = ({
}
const group = await groupDAL.findOne({ slug: groupSlug, orgId });
if (!group) throw new NotFoundError({ message: "Failed to find group" });
if (!group) {
throw new NotFoundError({
message: `Failed to find group with slug '${groupSlug}' in organization with ID '${orgId}'`
});
}
const groupMap = await ldapGroupMapDAL.create({
ldapConfigId,
@ -781,7 +802,11 @@ export const ldapConfigServiceFactory = ({
orgId
});
if (!ldapConfig) throw new NotFoundError({ message: "Failed to find organization LDAP data" });
if (!ldapConfig) {
throw new NotFoundError({
message: `Failed to find organization LDAP data with ID '${ldapConfigId}' in organization with ID ${orgId}`
});
}
const [deletedGroupMap] = await ldapGroupMapDAL.delete({
ldapConfigId: ldapConfig.id,

@ -46,7 +46,8 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
writeLimit: 200,
secretsLimit: 40
},
pkiEst: false
pkiEst: false,
enforceMfa: false
});
export const setupLicenseRequestWithStore = (baseURL: string, refreshUrl: string, licenseKey: string) => {

@ -145,7 +145,7 @@ export const licenseServiceFactory = ({
if (cachedPlan) return JSON.parse(cachedPlan) as TFeatureSet;
const org = await orgDAL.findOrgById(orgId);
if (!org) throw new NotFoundError({ message: "Organization not found" });
if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
const {
data: { currentPlan }
} = await licenseServerCloudApi.request.get<{ currentPlan: TFeatureSet }>(
@ -204,7 +204,7 @@ export const licenseServiceFactory = ({
const updateSubscriptionOrgMemberCount = async (orgId: string, tx?: Knex) => {
if (instanceType === InstanceType.Cloud) {
const org = await orgDAL.findOrgById(orgId);
if (!org) throw new NotFoundError({ message: "Organization not found" });
if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
const quantity = await licenseDAL.countOfOrgMembers(orgId, tx);
const quantityIdentities = await licenseDAL.countOrgUsersAndIdentities(orgId, tx);
@ -267,7 +267,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
@ -341,7 +341,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
const { data } = await licenseServerCloudApi.request.get(
@ -358,7 +358,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
const { data } = await licenseServerCloudApi.request.get(
@ -374,7 +374,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
@ -399,7 +399,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
const { data } = await licenseServerCloudApi.request.patch(
@ -419,7 +419,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
@ -446,7 +446,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
const {
@ -475,7 +475,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
@ -492,7 +492,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
const {
@ -510,7 +510,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
@ -531,7 +531,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
@ -548,7 +548,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}
@ -565,7 +565,7 @@ export const licenseServiceFactory = ({
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with ID '${orgId}' not found`
});
}

@ -64,6 +64,7 @@ export type TFeatureSet = {
secretsLimit: number;
};
pkiEst: boolean;
enforceMfa: boolean;
};
export type TOrgPlansTableDTO = {

@ -79,7 +79,7 @@ export const oidcConfigServiceFactory = ({
const org = await orgDAL.findOne({ slug: dto.orgSlug });
if (!org) {
throw new NotFoundError({
message: "Organization not found",
message: `Organization with slug '${dto.orgSlug}' not found`,
name: "OrgNotFound"
});
}
@ -100,14 +100,17 @@ export const oidcConfigServiceFactory = ({
if (!oidcCfg) {
throw new NotFoundError({
message: "Failed to find organization OIDC configuration"
message: `OIDC configuration for organization with slug '${dto.orgSlug}' not found`
});
}
// decrypt and return cfg
const orgBot = await orgBotDAL.findOne({ orgId: oidcCfg.orgId });
if (!orgBot) {
throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
throw new NotFoundError({
message: `Organization bot for organization with ID '${oidcCfg.orgId}' not found`,
name: "OrgBotNotFound"
});
}
const key = infisicalSymmetricDecrypt({
@ -174,7 +177,7 @@ export const oidcConfigServiceFactory = ({
});
const organization = await orgDAL.findOrgById(orgId);
if (!organization) throw new NotFoundError({ message: "Organization not found" });
if (!organization) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
let user: TUsers;
if (userAlias) {
@ -366,7 +369,7 @@ export const oidcConfigServiceFactory = ({
if (!org) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with slug '${orgSlug}' not found`
});
}
@ -387,7 +390,11 @@ export const oidcConfigServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso);
const orgBot = await orgBotDAL.findOne({ orgId: org.id });
if (!orgBot) throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
if (!orgBot)
throw new NotFoundError({
message: `Organization bot for organization with ID '${org.id}' not found`,
name: "OrgBotNotFound"
});
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
iv: orgBot.symmetricKeyIV,
@ -455,7 +462,7 @@ export const oidcConfigServiceFactory = ({
});
if (!org) {
throw new NotFoundError({
message: "Organization not found"
message: `Organization with slug '${orgSlug}' not found`
});
}
@ -561,7 +568,7 @@ export const oidcConfigServiceFactory = ({
if (!org) {
throw new NotFoundError({
message: "Organization not found."
message: `Organization with slug '${orgSlug}' not found`
});
}

@ -64,7 +64,7 @@ export const permissionServiceFactory = ({
permissions as PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[]
);
default:
throw new NotFoundError({ name: "OrgRoleInvalid", message: "Organization role not found" });
throw new NotFoundError({ name: "OrgRoleInvalid", message: `Organization role '${role}' not found` });
}
})
.reduce((curr, prev) => prev.concat(curr), []);
@ -94,7 +94,7 @@ export const permissionServiceFactory = ({
default:
throw new NotFoundError({
name: "ProjectRoleInvalid",
message: "Project role not found"
message: `Project role '${role}' not found`
});
}
})
@ -145,7 +145,7 @@ export const permissionServiceFactory = ({
const membership = await permissionDAL.getOrgIdentityPermission(identityId, orgId);
if (!membership) throw new ForbiddenRequestError({ name: "Identity is not apart of this organization" });
if (membership.role === OrgMembershipRole.Custom && !membership.permissions) {
throw new NotFoundError({ name: "Custom organization permission not found" });
throw new NotFoundError({ name: `Custom organization permission not found for identity ${identityId}` });
}
return {
permission: buildOrgPermission([{ role: membership.role, permissions: membership.permissions }]),
@ -179,7 +179,10 @@ export const permissionServiceFactory = ({
const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole);
if (isCustomRole) {
const orgRole = await orgRoleDAL.findOne({ slug: role, orgId });
if (!orgRole) throw new NotFoundError({ message: "Specified role was not found" });
if (!orgRole)
throw new NotFoundError({
message: `Specified role '${role}' was not found in the organization with ID '${orgId}'`
});
return {
permission: buildOrgPermission([{ role: OrgMembershipRole.Custom, permissions: orgRole.permissions }]),
role: orgRole
@ -264,7 +267,9 @@ export const permissionServiceFactory = ({
): Promise<TProjectPermissionRT<ActorType.IDENTITY>> => {
const identityProjectPermission = await permissionDAL.getProjectIdentityPermission(identityId, projectId);
if (!identityProjectPermission)
throw new ForbiddenRequestError({ name: "Identity is not a member of the specified project" });
throw new ForbiddenRequestError({
name: `Identity is not a member of the specified project with ID '${projectId}'`
});
if (
identityProjectPermission.roles.some(
@ -326,7 +331,7 @@ export const permissionServiceFactory = ({
actorOrgId: string | undefined
) => {
const serviceToken = await serviceTokenDAL.findById(serviceTokenId);
if (!serviceToken) throw new NotFoundError({ message: "Service token not found" });
if (!serviceToken) throw new NotFoundError({ message: `Service token with ID '${serviceTokenId}' not found` });
const serviceTokenProject = await projectDAL.findById(serviceToken.projectId);
@ -337,11 +342,15 @@ export const permissionServiceFactory = ({
}
if (serviceToken.projectId !== projectId) {
throw new ForbiddenRequestError({ name: "Service token not a part of the specified project" });
throw new ForbiddenRequestError({
name: `Service token not a part of the specified project with ID ${projectId}`
});
}
if (serviceTokenProject.orgId !== actorOrgId) {
throw new ForbiddenRequestError({ message: "Service token not a part of the specified organization" });
throw new ForbiddenRequestError({
message: `Service token not a part of the specified organization with ID ${actorOrgId}`
});
}
const scopes = ServiceTokenScopes.parse(serviceToken.scopes || []);

@ -42,7 +42,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
...dto
}: TCreateUserPrivilegeDTO) => {
const projectMembership = await projectMembershipDAL.findById(projectMembershipId);
if (!projectMembership) throw new NotFoundError({ message: "Project membership not found" });
if (!projectMembership)
throw new NotFoundError({ message: `Project membership with ID '${projectMembershipId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -94,14 +95,18 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
...dto
}: TUpdateUserPrivilegeDTO) => {
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
if (!userPrivilege) throw new NotFoundError({ message: "User additional privilege not found" });
if (!userPrivilege)
throw new NotFoundError({ message: `User additional privilege with ID '${privilegeId}' not found` });
const projectMembership = await projectMembershipDAL.findOne({
userId: userPrivilege.userId,
projectId: userPrivilege.projectId
});
if (!projectMembership) throw new NotFoundError({ message: "Project membership not found" });
if (!projectMembership)
throw new NotFoundError({
message: `Project membership for user with ID '${userPrivilege.userId}' not found in project with ID '${userPrivilege.projectId}'`
});
const { permission } = await permissionService.getProjectPermission(
actor,
@ -147,13 +152,17 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
const deleteById = async ({ actorId, actor, actorOrgId, actorAuthMethod, privilegeId }: TDeleteUserPrivilegeDTO) => {
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
if (!userPrivilege) throw new NotFoundError({ message: "User additional privilege not found" });
if (!userPrivilege)
throw new NotFoundError({ message: `User additional privilege with ID '${privilegeId}' not found` });
const projectMembership = await projectMembershipDAL.findOne({
userId: userPrivilege.userId,
projectId: userPrivilege.projectId
});
if (!projectMembership) throw new NotFoundError({ message: "Project membership not found" });
if (!projectMembership)
throw new NotFoundError({
message: `Project membership for user with ID '${userPrivilege.userId}' not found in project with ID '${userPrivilege.projectId}'`
});
const { permission } = await permissionService.getProjectPermission(
actor,
@ -176,13 +185,17 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
actorAuthMethod
}: TGetUserPrivilegeDetailsDTO) => {
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
if (!userPrivilege) throw new NotFoundError({ message: "User additional privilege not found" });
if (!userPrivilege)
throw new NotFoundError({ message: `User additional privilege with ID '${privilegeId}' not found` });
const projectMembership = await projectMembershipDAL.findOne({
userId: userPrivilege.userId,
projectId: userPrivilege.projectId
});
if (!projectMembership) throw new NotFoundError({ message: "Project membership not found" });
if (!projectMembership)
throw new NotFoundError({
message: `Project membership for user with ID '${userPrivilege.userId}' not found in project with ID '${userPrivilege.projectId}'`
});
const { permission } = await permissionService.getProjectPermission(
actor,
@ -204,7 +217,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
actorAuthMethod
}: TListUserPrivilegesDTO) => {
const projectMembership = await projectMembershipDAL.findById(projectMembershipId);
if (!projectMembership) throw new NotFoundError({ message: "Project membership not found" });
if (!projectMembership)
throw new NotFoundError({ message: `Project membership with ID '${projectMembershipId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,

@ -191,7 +191,11 @@ export const samlConfigServiceFactory = ({
const updateQuery: TSamlConfigsUpdate = { authProvider, isActive, lastUsed: null };
const orgBot = await orgBotDAL.findOne({ orgId });
if (!orgBot) throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
if (!orgBot)
throw new NotFoundError({
message: `Organization bot not found for organization with ID '${orgId}'`,
name: "OrgBotNotFound"
});
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
iv: orgBot.symmetricKeyIV,
@ -257,7 +261,7 @@ export const samlConfigServiceFactory = ({
ssoConfig = await samlConfigDAL.findById(id);
}
if (!ssoConfig) throw new NotFoundError({ message: "Failed to find organization SSO data" });
if (!ssoConfig) throw new NotFoundError({ message: `Failed to find SSO data` });
// when dto is type id means it's internally used
if (dto.type === "org") {
@ -283,7 +287,11 @@ export const samlConfigServiceFactory = ({
} = ssoConfig;
const orgBot = await orgBotDAL.findOne({ orgId: ssoConfig.orgId });
if (!orgBot) throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
if (!orgBot)
throw new NotFoundError({
message: `Organization bot not found in organization with ID '${ssoConfig.orgId}'`,
name: "OrgBotNotFound"
});
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
iv: orgBot.symmetricKeyIV,
@ -355,7 +363,7 @@ export const samlConfigServiceFactory = ({
});
const organization = await orgDAL.findOrgById(orgId);
if (!organization) throw new NotFoundError({ message: "Organization not found" });
if (!organization) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
let user: TUsers;
if (userAlias) {

@ -183,7 +183,7 @@ export const scimServiceFactory = ({
const deleteScimToken = async ({ scimTokenId, actor, actorId, actorAuthMethod, actorOrgId }: TDeleteScimTokenDTO) => {
let scimToken = await scimDAL.findById(scimTokenId);
if (!scimToken) throw new NotFoundError({ message: "Failed to find SCIM token to delete" });
if (!scimToken) throw new NotFoundError({ message: `SCIM token with ID '${scimTokenId}' not found` });
const { permission } = await permissionService.getOrgPermission(
actor,
@ -834,10 +834,12 @@ export const scimServiceFactory = ({
});
}
const users = await groupDAL.findAllGroupPossibleMembers({
orgId: group.orgId,
groupId: group.id
});
const users = await groupDAL
.findAllGroupPossibleMembers({
orgId: group.orgId,
groupId: group.id
})
.then((g) => g.members);
const orgMemberships = await orgDAL.findMembership({
[`${TableName.OrgMembership}.orgId` as "orgId"]: orgId,

@ -95,7 +95,10 @@ export const secretApprovalPolicyServiceFactory = ({
}
const env = await projectEnvDAL.findOne({ slug: environment, projectId });
if (!env) throw new NotFoundError({ message: "Environment not found" });
if (!env)
throw new NotFoundError({
message: `Environment with slug '${environment}' not found in project with ID ${projectId}`
});
const secretApproval = await secretApprovalPolicyDAL.transaction(async (tx) => {
const doc = await secretApprovalPolicyDAL.create(
@ -178,7 +181,11 @@ export const secretApprovalPolicyServiceFactory = ({
.filter(Boolean) as string[];
const secretApprovalPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId);
if (!secretApprovalPolicy) throw new NotFoundError({ message: "Secret approval policy not found" });
if (!secretApprovalPolicy) {
throw new NotFoundError({
message: `Secret approval policy with ID '${secretPolicyId}' not found`
});
}
const { permission } = await permissionService.getProjectPermission(
actor,
@ -271,7 +278,8 @@ export const secretApprovalPolicyServiceFactory = ({
actorOrgId
}: TDeleteSapDTO) => {
const sapPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId);
if (!sapPolicy) throw new NotFoundError({ message: "Secret approval policy not found" });
if (!sapPolicy)
throw new NotFoundError({ message: `Secret approval policy with ID '${secretPolicyId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -320,7 +328,11 @@ export const secretApprovalPolicyServiceFactory = ({
const getSecretApprovalPolicy = async (projectId: string, environment: string, path: string) => {
const secretPath = removeTrailingSlash(path);
const env = await projectEnvDAL.findOne({ slug: environment, projectId });
if (!env) throw new NotFoundError({ message: "Environment not found" });
if (!env) {
throw new NotFoundError({
message: `Environment with slug '${environment}' not found in project with ID ${projectId}`
});
}
const policies = await secretApprovalPolicyDAL.find({ envId: env.id });
if (!policies.length) return;
@ -369,7 +381,7 @@ export const secretApprovalPolicyServiceFactory = ({
if (!sapPolicy) {
throw new NotFoundError({
message: "Cannot find secret approval policy"
message: `Secret approval policy with ID '${sapId}' not found`
});
}

@ -204,7 +204,8 @@ export const secretApprovalRequestServiceFactory = ({
if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" });
const secretApprovalRequest = await secretApprovalRequestDAL.findById(id);
if (!secretApprovalRequest) throw new NotFoundError({ message: "Secret approval request not found" });
if (!secretApprovalRequest)
throw new NotFoundError({ message: `Secret approval request with ID '${id}' not found` });
const { projectId } = secretApprovalRequest;
const { botKey, shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId);
@ -271,7 +272,7 @@ export const secretApprovalRequestServiceFactory = ({
: undefined
}));
} else {
if (!botKey) throw new NotFoundError({ message: "Project bot key not found" });
if (!botKey) throw new NotFoundError({ message: `Project bot key not found`, name: "BotKeyNotFound" }); // CLI depends on this error message. TODO(daniel): Make API check for name BotKeyNotFound instead of message
const encrypedSecrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id);
secrets = encrypedSecrets.map((el) => ({
...el,
@ -307,7 +308,9 @@ export const secretApprovalRequestServiceFactory = ({
actorOrgId
}: TReviewRequestDTO) => {
const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId);
if (!secretApprovalRequest) throw new NotFoundError({ message: "Secret approval request not found" });
if (!secretApprovalRequest) {
throw new NotFoundError({ message: `Secret approval request with ID '${approvalId}' not found` });
}
if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" });
const plan = await licenseService.getPlan(actorOrgId);
@ -365,7 +368,9 @@ export const secretApprovalRequestServiceFactory = ({
actorAuthMethod
}: TStatusChangeDTO) => {
const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId);
if (!secretApprovalRequest) throw new NotFoundError({ message: "Secret approval request not found" });
if (!secretApprovalRequest) {
throw new NotFoundError({ message: `Secret approval request with ID '${approvalId}' not found` });
}
if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" });
const plan = await licenseService.getPlan(actorOrgId);
@ -414,7 +419,8 @@ export const secretApprovalRequestServiceFactory = ({
bypassReason
}: TMergeSecretApprovalRequestDTO) => {
const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId);
if (!secretApprovalRequest) throw new NotFoundError({ message: "Secret approval request not found" });
if (!secretApprovalRequest)
throw new NotFoundError({ message: `Secret approval request with ID '${approvalId}' not found` });
if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" });
const plan = await licenseService.getPlan(actorOrgId);
@ -462,7 +468,9 @@ export const secretApprovalRequestServiceFactory = ({
const secretApprovalSecrets = await secretApprovalRequestSecretDAL.findByRequestIdBridgeSecretV2(
secretApprovalRequest.id
);
if (!secretApprovalSecrets) throw new NotFoundError({ message: "No secrets found" });
if (!secretApprovalSecrets) {
throw new NotFoundError({ message: `No secrets found in secret change request with ID '${approvalId}'` });
}
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager,
@ -602,7 +610,9 @@ export const secretApprovalRequestServiceFactory = ({
});
} else {
const secretApprovalSecrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id);
if (!secretApprovalSecrets) throw new NotFoundError({ message: "No secrets found" });
if (!secretApprovalSecrets) {
throw new NotFoundError({ message: `No secrets found in secret change request with ID '${approvalId}'` });
}
const conflicts: Array<{ secretId: string; op: SecretOperations }> = [];
let secretCreationCommits = secretApprovalSecrets.filter(({ op }) => op === SecretOperations.Create);
@ -610,10 +620,10 @@ export const secretApprovalRequestServiceFactory = ({
const { secsGroupedByBlindIndex: conflictGroupByBlindIndex } = await fnSecretBlindIndexCheckV2({
folderId,
secretDAL,
inputSecrets: secretCreationCommits.map(({ secretBlindIndex }) => {
inputSecrets: secretCreationCommits.map(({ secretBlindIndex, secret }) => {
if (!secretBlindIndex) {
throw new NotFoundError({
message: "Secret blind index not found"
message: `Secret blind index not found on secret with ID '${secret.id}`
});
}
return { secretBlindIndex };
@ -637,10 +647,10 @@ export const secretApprovalRequestServiceFactory = ({
userId: "",
inputSecrets: secretUpdationCommits
.filter(({ secretBlindIndex, secret }) => secret && secret.secretBlindIndex !== secretBlindIndex)
.map(({ secretBlindIndex }) => {
.map(({ secretBlindIndex, secret }) => {
if (!secretBlindIndex) {
throw new NotFoundError({
message: "Secret blind index not found"
message: `Secret blind index not found on secret with ID '${secret.id}`
});
}
return { secretBlindIndex };
@ -760,10 +770,10 @@ export const secretApprovalRequestServiceFactory = ({
actorId: "",
secretDAL,
secretQueueService,
inputSecrets: secretDeletionCommits.map(({ secretBlindIndex }) => {
inputSecrets: secretDeletionCommits.map(({ secretBlindIndex, secret }) => {
if (!secretBlindIndex) {
throw new NotFoundError({
message: "Secret blind index not found"
message: `Secret blind index not found on secret with ID '${secret.id}`
});
}
return { secretBlindIndex, type: SecretType.Shared };
@ -789,7 +799,9 @@ export const secretApprovalRequestServiceFactory = ({
await snapshotService.performSnapshot(folderId);
const [folder] = await folderDAL.findSecretPathByFolderIds(projectId, [folderId]);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) {
throw new NotFoundError({ message: `Folder with ID '${folderId}' not found in project with ID '${projectId}'` });
}
await secretQueueService.syncSecrets({
projectId,
secretPath: folder.path,
@ -861,14 +873,18 @@ export const secretApprovalRequestServiceFactory = ({
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder)
throw new NotFoundError({
message: "Folder not found for the given environment slug & secret path",
message: `Folder not found for environment with slug '${environment}' & secret path '${secretPath}'`,
name: "GenSecretApproval"
});
const folderId = folder.id;
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg) throw new NotFoundError({ message: "Blind index not found", name: "Update secret" });
if (!blindIndexCfg) {
throw new NotFoundError({
message: `Blind index not found for project with ID '${projectId}'`,
name: "Update secret"
});
}
const commits: Omit<TSecretApprovalRequestsSecretsInsert, "requestId">[] = [];
const commitTagIds: Record<string, string[]> = {};
// for created secret approval change
@ -961,7 +977,9 @@ export const secretApprovalRequestServiceFactory = ({
secretDAL
});
const secretsGroupedByBlindIndex = groupBy(secrets, (i) => {
if (!i.secretBlindIndex) throw new NotFoundError({ message: "Secret blind index not found" });
if (!i.secretBlindIndex) {
throw new NotFoundError({ message: `Secret blind index not found for secret with ID '${i.id}'` });
}
return i.secretBlindIndex;
});
const deletedSecretIds = deletedSecrets.map(
@ -972,7 +990,7 @@ export const secretApprovalRequestServiceFactory = ({
...deletedSecrets.map((el) => {
const secretId = secretsGroupedByBlindIndex[keyName2BlindIndex[el.secretName]][0].id;
if (!latestSecretVersions[secretId].secretBlindIndex)
throw new NotFoundError({ message: "Secret blind index not found" });
throw new NotFoundError({ message: `Secret blind index not found for secret with ID '${secretId}'` });
return {
op: SecretOperations.Delete as const,
...latestSecretVersions[secretId],
@ -988,7 +1006,7 @@ export const secretApprovalRequestServiceFactory = ({
const tagIds = unique(Object.values(commitTagIds).flat());
const tags = tagIds.length ? await secretTagDAL.findManyTagsById(projectId, tagIds) : [];
if (tagIds.length !== tags.length) throw new NotFoundError({ message: "Tag not found" });
if (tagIds.length !== tags.length) throw new NotFoundError({ message: "One or more tags not found" });
const secretApprovalRequest = await secretApprovalRequestDAL.transaction(async (tx) => {
const doc = await secretApprovalRequestDAL.create(
@ -1054,7 +1072,7 @@ export const secretApprovalRequestServiceFactory = ({
const commitsGroupByBlindIndex = groupBy(approvalCommits, (i) => {
if (!i.secretBlindIndex) {
throw new NotFoundError({ message: "Secret blind index not found" });
throw new NotFoundError({ message: `Secret blind index not found for secret with ID '${i.id}'` });
}
return i.secretBlindIndex;
});
@ -1133,7 +1151,7 @@ export const secretApprovalRequestServiceFactory = ({
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder)
throw new NotFoundError({
message: "Folder not found for the given environment slug & secret path",
message: `Folder not found for the environment slug '${environment}' & secret path '${secretPath}'`,
name: "GenSecretApproval"
});
const folderId = folder.id;
@ -1291,7 +1309,7 @@ export const secretApprovalRequestServiceFactory = ({
const tagIds = unique(Object.values(commitTagIds).flat());
const tags = tagIds.length ? await secretTagDAL.findManyTagsById(projectId, tagIds) : [];
if (tagIds.length !== tags.length) throw new NotFoundError({ message: "Tag not found" });
if (tagIds.length !== tags.length) throw new NotFoundError({ message: "One or more tags not found" });
const secretApprovalRequest = await secretApprovalRequestDAL.transaction(async (tx) => {
const doc = await secretApprovalRequestDAL.create(

@ -295,7 +295,10 @@ export const secretReplicationServiceFactory = ({
const [destinationFolder] = await folderDAL.findSecretPathByFolderIds(projectId, [
destinationSecretImport.folderId
]);
if (!destinationFolder) throw new NotFoundError({ message: "Imported folder not found" });
if (!destinationFolder)
throw new NotFoundError({
message: `Imported folder with ID '${destinationSecretImport.folderId}' not found in project with ID ${projectId}`
});
let destinationReplicationFolder = await folderDAL.findOne({
parentId: destinationFolder.id,
@ -506,7 +509,7 @@ export const secretReplicationServiceFactory = ({
return;
}
if (!botKey) throw new NotFoundError({ message: "Project bot not found" });
if (!botKey) throw new NotFoundError({ message: `Bot key not found for project with ID ${projectId}` });
// these are the secrets to be added in replicated folders
const sourceLocalSecrets = await secretDAL.find({ folderId: folder.id, type: SecretType.Shared });
const sourceSecretImports = await secretImportDAL.find({ folderId: folder.id });
@ -545,7 +548,11 @@ export const secretReplicationServiceFactory = ({
const [destinationFolder] = await folderDAL.findSecretPathByFolderIds(projectId, [
destinationSecretImport.folderId
]);
if (!destinationFolder) throw new NotFoundError({ message: "Imported folder not found" });
if (!destinationFolder) {
throw new NotFoundError({
message: `Imported folder with ID '${destinationSecretImport.folderId}' not found in project with ID ${projectId}`
});
}
let destinationReplicationFolder = await folderDAL.findOne({
parentId: destinationFolder.id,

@ -332,7 +332,10 @@ export const secretRotationQueueFactory = ({
);
});
} else {
if (!botKey) throw new NotFoundError({ message: "Project bot not found" });
if (!botKey)
throw new NotFoundError({
message: `Project bot not found for project with ID '${secretRotation.projectId}'`
});
const encryptedSecrets = rotationOutputs.map(({ key: outputKey, secretId }) => ({
secretId,
value: encryptSymmetric128BitHexKeyUTF8(
@ -372,7 +375,9 @@ export const secretRotationQueueFactory = ({
);
await secretVersionDAL.insertMany(
updatedSecrets.map(({ id, updatedAt, createdAt, ...el }) => {
if (!el.secretBlindIndex) throw new NotFoundError({ message: "Secret blind index not found" });
if (!el.secretBlindIndex) {
throw new NotFoundError({ message: `Secret blind index not found on secret with ID '${id}` });
}
return {
...el,
secretId: id,

@ -94,7 +94,11 @@ export const secretRotationServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) throw new NotFoundError({ message: "Secret path not found" });
if (!folder) {
throw new NotFoundError({
message: `Secret path with path '${secretPath}' not found in environment with slug '${environment}'`
});
}
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
@ -108,14 +112,14 @@ export const secretRotationServiceFactory = ({
$in: { id: Object.values(outputs) }
});
if (selectedSecrets.length !== Object.values(outputs).length)
throw new NotFoundError({ message: "Secrets not found" });
throw new NotFoundError({ message: `Secrets not found in folder with ID '${folder.id}'` });
} else {
const selectedSecrets = await secretDAL.find({
folderId: folder.id,
$in: { id: Object.values(outputs) }
});
if (selectedSecrets.length !== Object.values(outputs).length)
throw new NotFoundError({ message: "Secrets not found" });
throw new NotFoundError({ message: `Secrets not found in folder with ID '${folder.id}'` });
}
const plan = await licenseService.getPlan(project.orgId);
@ -125,7 +129,7 @@ export const secretRotationServiceFactory = ({
});
const selectedTemplate = rotationTemplates.find(({ name }) => name === provider);
if (!selectedTemplate) throw new NotFoundError({ message: "Provider not found" });
if (!selectedTemplate) throw new NotFoundError({ message: `Provider with name '${provider}' not found` });
const formattedInputs: Record<string, unknown> = {};
Object.entries(inputs).forEach(([key, value]) => {
const { type } = selectedTemplate.template.inputs.properties[key];
@ -198,7 +202,7 @@ export const secretRotationServiceFactory = ({
return docs;
}
if (!botKey) throw new NotFoundError({ message: "Project bot not found" });
if (!botKey) throw new NotFoundError({ message: `Project bot not found for project with ID '${projectId}'` });
const docs = await secretRotationDAL.find({ projectId });
return docs.map((el) => ({
...el,
@ -220,7 +224,7 @@ export const secretRotationServiceFactory = ({
const restartById = async ({ actor, actorId, actorOrgId, actorAuthMethod, rotationId }: TRestartDTO) => {
const doc = await secretRotationDAL.findById(rotationId);
if (!doc) throw new NotFoundError({ message: "Rotation not found" });
if (!doc) throw new NotFoundError({ message: `Rotation with ID '${rotationId}' not found` });
const project = await projectDAL.findById(doc.projectId);
const plan = await licenseService.getPlan(project.orgId);
@ -244,7 +248,7 @@ export const secretRotationServiceFactory = ({
const deleteById = async ({ actor, actorId, actorOrgId, actorAuthMethod, rotationId }: TDeleteDTO) => {
const doc = await secretRotationDAL.findById(rotationId);
if (!doc) throw new NotFoundError({ message: "Rotation not found" });
if (!doc) throw new NotFoundError({ message: `Rotation with ID '${rotationId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,

@ -99,7 +99,11 @@ export const secretSnapshotServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) {
throw new NotFoundError({
message: `Folder with path '${path}' not found in environment with slug '${environment}'`
});
}
return snapshotDAL.countOfSnapshotsByFolderId(folder.id);
};
@ -131,7 +135,10 @@ export const secretSnapshotServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${path}' not found in environment with slug '${environment}'`
});
const snapshots = await snapshotDAL.find({ folderId: folder.id }, { limit, offset, sort: [["createdAt", "desc"]] });
return snapshots;
@ -139,7 +146,7 @@ export const secretSnapshotServiceFactory = ({
const getSnapshotData = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TGetSnapshotDataDTO) => {
const snapshot = await snapshotDAL.findById(id);
if (!snapshot) throw new NotFoundError({ message: "Snapshot not found" });
if (!snapshot) throw new NotFoundError({ message: `Snapshot with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
@ -173,7 +180,8 @@ export const secretSnapshotServiceFactory = ({
} else {
const encryptedSnapshotDetails = await snapshotDAL.findSecretSnapshotDataById(id);
const { botKey } = await projectBotService.getBotKey(snapshot.projectId);
if (!botKey) throw new NotFoundError({ message: "Project bot not found" });
if (!botKey)
throw new NotFoundError({ message: `Project bot key not found for project with ID '${snapshot.projectId}'` });
snapshotDetails = {
...encryptedSnapshotDetails,
secretVersions: encryptedSnapshotDetails.secretVersions.map((el) => ({
@ -225,7 +233,7 @@ export const secretSnapshotServiceFactory = ({
try {
if (!licenseService.isValidLicense) throw new InternalServerError({ message: "Invalid license" });
const folder = await folderDAL.findById(folderId);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) throw new NotFoundError({ message: `Folder with ID '${folderId}' not found` });
const shouldUseSecretV2Bridge = folder.projectVersion === 3;
if (shouldUseSecretV2Bridge) {
@ -311,7 +319,7 @@ export const secretSnapshotServiceFactory = ({
actorOrgId
}: TRollbackSnapshotDTO) => {
const snapshot = await snapshotDAL.findById(snapshotId);
if (!snapshot) throw new NotFoundError({ message: "Snapshot not found" });
if (!snapshot) throw new NotFoundError({ message: `Snapshot with ID '${snapshotId}' not found` });
const shouldUseBridge = snapshot.projectVersion === 3;
const { permission } = await permissionService.getProjectPermission(

@ -18,7 +18,8 @@ export const GROUPS = {
id: "The id of the group to list users for",
offset: "The offset to start from. If you enter 10, it will start from the 10th user.",
limit: "The number of users to return.",
username: "The username to search for."
username: "The username to search for.",
search: "The text string that user email or name will be filtered by."
},
ADD_USER: {
id: "The id of the group to add the user to.",

@ -18,6 +18,7 @@ export type TAuthMode =
user: TUsers;
orgId: string;
authMethod: AuthMethod;
isMfaVerified?: boolean;
}
| {
authMode: AuthMode.API_KEY;
@ -121,7 +122,8 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
tokenVersionId,
actor,
orgId: orgId as string,
authMethod: token.authMethod
authMethod: token.authMethod,
isMfaVerified: token.isMfaVerified
};
break;
}

@ -107,7 +107,8 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => {
userId: decodedToken.userId,
tokenVersionId: tokenVersion.id,
accessVersion: tokenVersion.accessVersion,
organizationId: decodedToken.organizationId
organizationId: decodedToken.organizationId,
isMfaVerified: decodedToken.isMfaVerified
},
appCfg.AUTH_SECRET,
{ expiresIn: appCfg.JWT_AUTH_LIFETIME }

@ -258,7 +258,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
.refine((v) => slugify(v) === v, {
message: "Membership role must be a valid slug"
})
.optional()
.optional(),
enforceMfa: z.boolean().optional()
}),
response: {
200: z.object({

@ -280,10 +280,6 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
providerAuthToken: req.body.providerAuthToken
});
if (data.isMfaEnabled) {
return { mfaEnabled: true, token: data.token } as const; // for discriminated union
}
void res.setCookie("jid", data.token.refresh, {
httpOnly: true,
path: "/",
@ -292,7 +288,6 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
});
return {
mfaEnabled: false,
encryptionVersion: data.user.encryptionVersion,
token: data.token.access,
publicKey: data.user.publicKey,

@ -47,7 +47,8 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
}),
response: {
200: z.object({
token: z.string()
token: z.string(),
isMfaEnabled: z.boolean()
})
}
},
@ -60,6 +61,13 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
ipAddress: req.realIp
});
if (tokens.isMfaEnabled) {
return {
token: tokens.mfa as string,
isMfaEnabled: true
};
}
void res.setCookie("jid", tokens.refresh, {
httpOnly: true,
path: "/",
@ -67,7 +75,7 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
secure: cfg.HTTPS_ENABLED
});
return { token: tokens.access };
return { token: tokens.access, isMfaEnabled: false };
}
});
@ -86,21 +94,17 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
password: z.string().optional()
}),
response: {
200: z.discriminatedUnion("mfaEnabled", [
z.object({ mfaEnabled: z.literal(true), token: z.string() }),
z.object({
mfaEnabled: z.literal(false),
encryptionVersion: z.number().default(1).nullable().optional(),
protectedKey: z.string().nullable(),
protectedKeyIV: z.string().nullable(),
protectedKeyTag: z.string().nullable(),
publicKey: z.string(),
encryptedPrivateKey: z.string(),
iv: z.string(),
tag: z.string(),
token: z.string()
})
])
200: z.object({
encryptionVersion: z.number().default(1).nullable().optional(),
protectedKey: z.string().nullable(),
protectedKeyIV: z.string().nullable(),
protectedKeyTag: z.string().nullable(),
publicKey: z.string(),
encryptedPrivateKey: z.string(),
iv: z.string(),
tag: z.string(),
token: z.string()
})
}
},
handler: async (req, res) => {
@ -118,10 +122,6 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
password: req.body.password
});
if (data.isMfaEnabled) {
return { mfaEnabled: true, token: data.token } as const; // for discriminated union
}
void res.setCookie("jid", data.token.refresh, {
httpOnly: true,
path: "/",
@ -130,7 +130,6 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
});
return {
mfaEnabled: false,
encryptionVersion: data.user.encryptionVersion,
token: data.token.access,
publicKey: data.user.publicKey,

@ -45,7 +45,7 @@ export const apiKeyServiceFactory = ({ apiKeyDAL, userDAL }: TApiKeyServiceFacto
const deleteApiKey = async (userId: string, apiKeyId: string) => {
const [apiKeyData] = await apiKeyDAL.delete({ id: apiKeyId, userId });
if (!apiKeyData) throw new NotFoundError({ message: "API key not found" });
if (!apiKeyData) throw new NotFoundError({ message: `API key with ID '${apiKeyId}' not found` });
return formatApiKey(apiKeyData);
};

@ -156,7 +156,7 @@ export const tokenServiceFactory = ({ tokenDAL, userDAL, orgMembershipDAL }: TAu
}
const user = await userDAL.findById(session.userId);
if (!user || !user.isAccepted) throw new NotFoundError({ message: "User not found" });
if (!user || !user.isAccepted) throw new NotFoundError({ message: `User with ID '${session.userId}' not found` });
if (token.organizationId) {
const orgMembership = await orgMembershipDAL.findOne({

@ -99,13 +99,15 @@ export const authLoginServiceFactory = ({
ip,
userAgent,
organizationId,
authMethod
authMethod,
isMfaVerified
}: {
user: TUsers;
ip: string;
userAgent: string;
organizationId?: string;
authMethod: AuthMethod;
isMfaVerified?: boolean;
}) => {
const cfg = getConfig();
await updateUserDeviceSession(user, ip, userAgent);
@ -123,7 +125,8 @@ export const authLoginServiceFactory = ({
userId: user.id,
tokenVersionId: tokenSession.id,
accessVersion: tokenSession.accessVersion,
organizationId
organizationId,
isMfaVerified
},
cfg.AUTH_SECRET,
{ expiresIn: cfg.JWT_AUTH_LIFETIME }
@ -136,7 +139,8 @@ export const authLoginServiceFactory = ({
userId: user.id,
tokenVersionId: tokenSession.id,
refreshVersion: tokenSession.refreshVersion,
organizationId
organizationId,
isMfaVerified
},
cfg.AUTH_SECRET,
{ expiresIn: cfg.JWT_REFRESH_LIFETIME }
@ -298,30 +302,6 @@ export const authLoginServiceFactory = ({
});
}
// send multi factor auth token if they it enabled
if (userEnc.isMfaEnabled && userEnc.email) {
enforceUserLockStatus(Boolean(user.isLocked), user.temporaryLockDateEnd);
const mfaToken = jwt.sign(
{
authMethod,
authTokenType: AuthTokenType.MFA_TOKEN,
userId: userEnc.userId
},
cfg.AUTH_SECRET,
{
expiresIn: cfg.JWT_MFA_LIFETIME
}
);
await sendUserMfaCode({
userId: userEnc.userId,
email: userEnc.email
});
return { isMfaEnabled: true, token: mfaToken } as const;
}
const token = await generateUserTokens({
user: {
...userEnc,
@ -333,7 +313,7 @@ export const authLoginServiceFactory = ({
organizationId
});
return { token, isMfaEnabled: false, user: userEnc } as const;
return { token, user: userEnc } as const;
};
const selectOrganization = async ({
@ -373,15 +353,43 @@ export const authLoginServiceFactory = ({
});
}
// send multi factor auth token if they it enabled
if ((selectedOrg.enforceMfa || user.isMfaEnabled) && user.email && !decodedToken.isMfaVerified) {
enforceUserLockStatus(Boolean(user.isLocked), user.temporaryLockDateEnd);
const mfaToken = jwt.sign(
{
authMethod: decodedToken.authMethod,
authTokenType: AuthTokenType.MFA_TOKEN,
userId: user.id
},
cfg.AUTH_SECRET,
{
expiresIn: cfg.JWT_MFA_LIFETIME
}
);
await sendUserMfaCode({
userId: user.id,
email: user.email
});
return { isMfaEnabled: true, mfa: mfaToken } as const;
}
const tokens = await generateUserTokens({
authMethod: decodedToken.authMethod,
user,
userAgent,
ip: ipAddress,
organizationId
organizationId,
isMfaVerified: decodedToken.isMfaVerified
});
return tokens;
return {
...tokens,
isMfaEnabled: false
};
};
/*
@ -504,7 +512,8 @@ export const authLoginServiceFactory = ({
ip,
userAgent,
organizationId: orgId,
authMethod: decodedToken.authMethod
authMethod: decodedToken.authMethod,
isMfaVerified: true
});
return { token, user: userEnc };
@ -629,7 +638,6 @@ export const authLoginServiceFactory = ({
const oauth2TokenExchange = async ({ userAgent, ip, providerAuthToken, email }: TOauthTokenExchangeDTO) => {
const decodedProviderToken = validateProviderAuthToken(providerAuthToken, email);
const appCfg = getConfig();
const { authMethod, userName } = decodedProviderToken;
if (!userName) throw new BadRequestError({ message: "Missing user name" });
const organizationId =
@ -644,29 +652,6 @@ export const authLoginServiceFactory = ({
if (!userEnc) throw new BadRequestError({ message: "Invalid token" });
if (!userEnc.serverEncryptedPrivateKey)
throw new BadRequestError({ message: "Key handoff incomplete. Please try logging in again." });
// send multi factor auth token if they it enabled
if (userEnc.isMfaEnabled && userEnc.email) {
enforceUserLockStatus(Boolean(userEnc.isLocked), userEnc.temporaryLockDateEnd);
const mfaToken = jwt.sign(
{
authMethod,
authTokenType: AuthTokenType.MFA_TOKEN,
userId: userEnc.userId
},
appCfg.AUTH_SECRET,
{
expiresIn: appCfg.JWT_MFA_LIFETIME
}
);
await sendUserMfaCode({
userId: userEnc.userId,
email: userEnc.email
});
return { isMfaEnabled: true, token: mfaToken } as const;
}
const token = await generateUserTokens({
user: { ...userEnc, id: userEnc.userId },

@ -52,6 +52,7 @@ export type AuthModeJwtTokenPayload = {
tokenVersionId: string;
accessVersion: number;
organizationId?: string;
isMfaVerified?: boolean;
};
export type AuthModeMfaJwtTokenPayload = {
@ -69,6 +70,7 @@ export type AuthModeRefreshJwtTokenPayload = {
tokenVersionId: string;
refreshVersion: number;
organizationId?: string;
isMfaVerified?: boolean;
};
export type AuthModeProviderJwtTokenPayload = {

@ -113,10 +113,10 @@ export const getCaCredentials = async ({
kmsService
}: TGetCaCredentialsDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const caSecret = await certificateAuthoritySecretDAL.findOne({ caId });
if (!caSecret) throw new NotFoundError({ message: "CA secret not found" });
if (!caSecret) throw new NotFoundError({ message: `CA secret for CA with ID '${caId}' not found` });
const keyId = await getProjectKmsCertificateKeyId({
projectId: ca.projectId,
@ -165,7 +165,7 @@ export const getCaCertChains = async ({
kmsService
}: TGetCaCertChainsDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const keyId = await getProjectKmsCertificateKeyId({
projectId: ca.projectId,
@ -256,7 +256,7 @@ export const rebuildCaCrl = async ({
kmsService
}: TRebuildCaCrlDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const caSecret = await certificateAuthoritySecretDAL.findOne({ caId: ca.id });

@ -76,7 +76,7 @@ export const certificateAuthorityQueueFactory = ({
logger.info(`secretReminderQueue.process: [secretDocument=${caId}]`);
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const caSecret = await certificateAuthoritySecretDAL.findOne({ caId: ca.id });

@ -122,7 +122,7 @@ export const certificateAuthorityServiceFactory = ({
actorOrgId
}: TCreateCaDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -290,7 +290,7 @@ export const certificateAuthorityServiceFactory = ({
*/
const getCaById = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -321,7 +321,7 @@ export const certificateAuthorityServiceFactory = ({
actorOrgId
}: TUpdateCaDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -346,7 +346,7 @@ export const certificateAuthorityServiceFactory = ({
*/
const deleteCaById = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TDeleteCaDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -371,7 +371,7 @@ export const certificateAuthorityServiceFactory = ({
*/
const getCaCsr = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCsrDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -430,7 +430,7 @@ export const certificateAuthorityServiceFactory = ({
*/
const renewCaCert = async ({ caId, notAfter, actorId, actorAuthMethod, actor, actorOrgId }: TRenewCaCertDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
if (!ca.activeCaCertId) throw new BadRequestError({ message: "CA does not have a certificate installed" });
@ -702,7 +702,7 @@ export const certificateAuthorityServiceFactory = ({
const getCaCerts = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCertsDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -736,7 +736,7 @@ export const certificateAuthorityServiceFactory = ({
*/
const getCaCert = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCertDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
if (!ca.activeCaCertId) throw new BadRequestError({ message: "CA does not have a certificate installed" });
const { permission } = await permissionService.getProjectPermission(
@ -778,7 +778,7 @@ export const certificateAuthorityServiceFactory = ({
});
if (!caCert) {
throw new NotFoundError({ message: "CA certificate not found" });
throw new NotFoundError({ message: `Ca certificate with ID '${caCertId}' not found for CA with ID '${caId}'` });
}
const ca = await certificateAuthorityDAL.findById(caId);
@ -963,7 +963,7 @@ export const certificateAuthorityServiceFactory = ({
certificateChain
}: TImportCertToCaDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1115,7 +1115,7 @@ export const certificateAuthorityServiceFactory = ({
certificateTemplate = await certificateTemplateDAL.getById(certificateTemplateId);
if (!certificateTemplate) {
throw new NotFoundError({
message: "Certificate template not found"
message: `Certificate template with ID '${certificateTemplateId}' not found`
});
}
@ -1124,7 +1124,7 @@ export const certificateAuthorityServiceFactory = ({
}
if (!ca) {
throw new NotFoundError({ message: "CA not found" });
throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
}
const { permission } = await permissionService.getProjectPermission(
@ -1442,7 +1442,7 @@ export const certificateAuthorityServiceFactory = ({
certificateTemplate = await certificateTemplateDAL.getById(certificateTemplateId);
if (!certificateTemplate) {
throw new NotFoundError({
message: "Certificate template not found"
message: `Certificate template with ID '${certificateTemplateId}' not found`
});
}
@ -1451,7 +1451,7 @@ export const certificateAuthorityServiceFactory = ({
}
if (!ca) {
throw new NotFoundError({ message: "CA not found" });
throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
}
if (!dto.isInternal) {
@ -1484,7 +1484,7 @@ export const certificateAuthorityServiceFactory = ({
// check PKI collection
if (pkiCollectionId) {
const pkiCollection = await pkiCollectionDAL.findById(pkiCollectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${pkiCollectionId}' not found` });
if (pkiCollection.projectId !== ca.projectId) throw new BadRequestError({ message: "Invalid PKI collection" });
}
@ -1810,7 +1810,7 @@ export const certificateAuthorityServiceFactory = ({
actorOrgId
}: TGetCaCertificateTemplatesDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,

@ -64,7 +64,7 @@ export const certificateTemplateServiceFactory = ({
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) {
throw new NotFoundError({
message: "CA not found"
message: `CA with ID ${caId} not found`
});
}
const { permission } = await permissionService.getProjectPermission(
@ -98,7 +98,7 @@ export const certificateTemplateServiceFactory = ({
const certificateTemplate = await certificateTemplateDAL.getById(id, tx);
if (!certificateTemplate) {
throw new NotFoundError({
message: "Certificate template not found"
message: `Certificate template with ID ${id} not found`
});
}
@ -124,7 +124,7 @@ export const certificateTemplateServiceFactory = ({
const certTemplate = await certificateTemplateDAL.getById(id);
if (!certTemplate) {
throw new NotFoundError({
message: "Certificate template not found."
message: `Certificate template with ID ${id} not found`
});
}
@ -169,7 +169,7 @@ export const certificateTemplateServiceFactory = ({
const updatedTemplate = await certificateTemplateDAL.getById(id, tx);
if (!updatedTemplate) {
throw new NotFoundError({
message: "Certificate template not found"
message: `Certificate template with ID ${id} not found`
});
}
@ -181,7 +181,7 @@ export const certificateTemplateServiceFactory = ({
const certTemplate = await certificateTemplateDAL.getById(id);
if (!certTemplate) {
throw new NotFoundError({
message: "Certificate template not found."
message: `Certificate template with ID ${id} not found`
});
}
@ -207,7 +207,7 @@ export const certificateTemplateServiceFactory = ({
const certTemplate = await certificateTemplateDAL.getById(id);
if (!certTemplate) {
throw new NotFoundError({
message: "Certificate template not found."
message: `Certificate template with ID ${id} not found`
});
}
@ -247,7 +247,7 @@ export const certificateTemplateServiceFactory = ({
const certTemplate = await certificateTemplateDAL.getById(certificateTemplateId);
if (!certTemplate) {
throw new NotFoundError({
message: "Certificate template not found."
message: `Certificate template with ID ${certificateTemplateId} not found`
});
}
@ -324,7 +324,7 @@ export const certificateTemplateServiceFactory = ({
const certTemplate = await certificateTemplateDAL.getById(certificateTemplateId);
if (!certTemplate) {
throw new NotFoundError({
message: "Certificate template not found."
message: `Certificate template with ID ${certificateTemplateId} not found`
});
}
@ -347,7 +347,7 @@ export const certificateTemplateServiceFactory = ({
if (!originalCaEstConfig) {
throw new NotFoundError({
message: "EST configuration not found"
message: `EST configuration with certificate template ID ${certificateTemplateId} not found`
});
}
@ -403,7 +403,7 @@ export const certificateTemplateServiceFactory = ({
const certTemplate = await certificateTemplateDAL.getById(certificateTemplateId);
if (!certTemplate) {
throw new NotFoundError({
message: "Certificate template not found."
message: `Certificate template with ID ${certificateTemplateId} not found`
});
}
@ -428,7 +428,7 @@ export const certificateTemplateServiceFactory = ({
if (!estConfig) {
throw new NotFoundError({
message: "EST configuration not found"
message: `EST configuration with certificate template ID ${certificateTemplateId} not found`
});
}

@ -46,7 +46,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
const updateCmekById = async ({ keyId, ...data }: TUpdabteCmekByIdDTO, actor: FastifyRequest["permission"]) => {
const key = await kmsDAL.findById(keyId);
if (!key) throw new NotFoundError({ message: "Key not found" });
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
if (!key.projectId || key.isReserved) throw new BadRequestError({ message: "Key is not customer managed" });
@ -68,7 +68,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
const deleteCmekById = async (keyId: string, actor: FastifyRequest["permission"]) => {
const key = await kmsDAL.findById(keyId);
if (!key) throw new NotFoundError({ message: "Key not found" });
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
if (!key.projectId || key.isReserved) throw new BadRequestError({ message: "Key is not customer managed" });
@ -109,7 +109,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
const cmekEncrypt = async ({ keyId, plaintext }: TCmekEncryptDTO, actor: FastifyRequest["permission"]) => {
const key = await kmsDAL.findById(keyId);
if (!key) throw new NotFoundError({ message: "Key not found" });
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
if (!key.projectId || key.isReserved) throw new BadRequestError({ message: "Key is not customer managed" });
@ -135,7 +135,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
const cmekDecrypt = async ({ keyId, ciphertext }: TCmekDecryptDTO, actor: FastifyRequest["permission"]) => {
const key = await kmsDAL.findById(keyId);
if (!key) throw new NotFoundError({ message: "Key not found" });
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
if (!key.projectId || key.isReserved) throw new BadRequestError({ message: "Key is not customer managed" });

@ -169,7 +169,7 @@ export const groupProjectServiceFactory = ({
if (!ghostUser) {
throw new NotFoundError({
message: "Failed to find project owner"
message: `Failed to find project owner of project with name ${project.name}`
});
}
@ -177,7 +177,7 @@ export const groupProjectServiceFactory = ({
if (!ghostUserLatestKey) {
throw new NotFoundError({
message: "Failed to find project owner's latest key"
message: `Failed to find project owner's latest key in project with name ${project.name}`
});
}
@ -185,7 +185,7 @@ export const groupProjectServiceFactory = ({
if (!bot) {
throw new NotFoundError({
message: "Failed to find project bot"
message: `Failed to find project bot in project with name ${project.name}`
});
}
@ -425,7 +425,7 @@ export const groupProjectServiceFactory = ({
if (!groupMembership) {
throw new NotFoundError({
message: "Cannot find group membership"
message: `Group membership with ID ${groupId} not found in project with ID ${projectId}`
});
}

@ -98,6 +98,9 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
const removeExpiredTokens = async (tx?: Knex) => {
logger.info(`${QueueName.DailyResourceCleanUp}: remove expired access token started`);
const MAX_TTL = 315_360_000; // Maximum TTL value in seconds (10 years)
try {
const docs = (tx || db)(TableName.IdentityAccessToken)
.where({
@ -120,7 +123,8 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
.whereNotNull("accessTokenLastRenewedAt")
// accessTokenLastRenewedAt + convert_integer_to_seconds(accessTokenTTL) < present_date
.andWhereRaw(
`"${TableName.IdentityAccessToken}"."accessTokenLastRenewedAt" + make_interval(secs => "${TableName.IdentityAccessToken}"."accessTokenTTL") < NOW()`
`"${TableName.IdentityAccessToken}"."accessTokenLastRenewedAt" + make_interval(secs => LEAST("${TableName.IdentityAccessToken}"."accessTokenTTL", ?)) < NOW()`,
[MAX_TTL]
);
})
.orWhere((qb3) => {
@ -128,7 +132,8 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
.whereNull("accessTokenLastRenewedAt")
// created + convert_integer_to_seconds(accessTokenTTL) < present_date
.andWhereRaw(
`"${TableName.IdentityAccessToken}"."createdAt" + make_interval(secs => "${TableName.IdentityAccessToken}"."accessTokenTTL") < NOW()`
`"${TableName.IdentityAccessToken}"."createdAt" + make_interval(secs => LEAST("${TableName.IdentityAccessToken}"."accessTokenTTL", ?)) < NOW()`,
[MAX_TTL]
);
});
});

@ -154,7 +154,7 @@ export const identityAwsAuthServiceFactory = ({
actorOrgId
}: TAttachAwsAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethod)
throw new BadRequestError({
message: "Failed to add AWS Auth to already configured identity"
@ -233,7 +233,7 @@ export const identityAwsAuthServiceFactory = ({
actorOrgId
}: TUpdateAwsAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_AUTH)
throw new BadRequestError({
message: "Failed to update AWS Auth"
@ -292,7 +292,7 @@ export const identityAwsAuthServiceFactory = ({
const getAwsAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAwsAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_AUTH)
throw new BadRequestError({
message: "The identity does not have AWS Auth attached"
@ -319,7 +319,7 @@ export const identityAwsAuthServiceFactory = ({
actorOrgId
}: TRevokeAwsAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_AUTH)
throw new BadRequestError({
message: "The identity does not have aws auth"

@ -125,7 +125,7 @@ export const identityAzureAuthServiceFactory = ({
actorOrgId
}: TAttachAzureAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethod)
throw new BadRequestError({
message: "Failed to add Azure Auth to already configured identity"
@ -203,7 +203,7 @@ export const identityAzureAuthServiceFactory = ({
actorOrgId
}: TUpdateAzureAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AZURE_AUTH)
throw new BadRequestError({
message: "Failed to update Azure Auth"
@ -265,7 +265,7 @@ export const identityAzureAuthServiceFactory = ({
const getAzureAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAzureAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AZURE_AUTH)
throw new BadRequestError({
message: "The identity does not have Azure Auth attached"
@ -293,7 +293,7 @@ export const identityAzureAuthServiceFactory = ({
actorOrgId
}: TRevokeAzureAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AZURE_AUTH)
throw new BadRequestError({
message: "The identity does not have azure auth"

@ -167,7 +167,7 @@ export const identityGcpAuthServiceFactory = ({
actorOrgId
}: TAttachGcpAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethod)
throw new BadRequestError({
message: "Failed to add GCP Auth to already configured identity"
@ -247,7 +247,7 @@ export const identityGcpAuthServiceFactory = ({
actorOrgId
}: TUpdateGcpAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.GCP_AUTH)
throw new BadRequestError({
message: "Failed to update GCP Auth"
@ -310,7 +310,7 @@ export const identityGcpAuthServiceFactory = ({
const getGcpAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetGcpAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.GCP_AUTH)
throw new BadRequestError({
message: "The identity does not have GCP Auth attached"
@ -338,7 +338,7 @@ export const identityGcpAuthServiceFactory = ({
actorOrgId
}: TRevokeGcpAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.GCP_AUTH)
throw new BadRequestError({
message: "The identity does not have gcp auth"

@ -72,10 +72,19 @@ export const identityKubernetesAuthServiceFactory = ({
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({
identityId: identityKubernetesAuth.identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: "Identity organization membership not found" });
if (!identityMembershipOrg) {
throw new NotFoundError({
message: `Identity organization membership for identity with ID '${identityKubernetesAuth.identityId}' not found`
});
}
const orgBot = await orgBotDAL.findOne({ orgId: identityMembershipOrg.orgId });
if (!orgBot) throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
if (!orgBot) {
throw new NotFoundError({
message: `Organization bot not found for organization with ID ${identityMembershipOrg.orgId}`,
name: "OrgBotNotFound"
});
}
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
@ -250,7 +259,7 @@ export const identityKubernetesAuthServiceFactory = ({
actorOrgId
}: TAttachKubernetesAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethod)
throw new BadRequestError({
message: "Failed to add Kubernetes Auth to already configured identity"
@ -394,7 +403,7 @@ export const identityKubernetesAuthServiceFactory = ({
actorOrgId
}: TUpdateKubernetesAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.KUBERNETES_AUTH)
throw new BadRequestError({
message: "Failed to update Kubernetes Auth"
@ -451,8 +460,12 @@ export const identityKubernetesAuthServiceFactory = ({
};
const orgBot = await orgBotDAL.findOne({ orgId: identityMembershipOrg.orgId });
if (!orgBot) throw new NotFoundError({ message: "Org bot not found", name: "OrgBotNotFound" });
if (!orgBot) {
throw new NotFoundError({
message: `Organization bot not found for organization with ID ${identityMembershipOrg.orgId}`,
name: "OrgBotNotFound"
});
}
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
iv: orgBot.symmetricKeyIV,
@ -518,7 +531,7 @@ export const identityKubernetesAuthServiceFactory = ({
actorOrgId
}: TGetKubernetesAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.KUBERNETES_AUTH)
throw new BadRequestError({
message: "The identity does not have Kubernetes Auth attached"
@ -536,7 +549,11 @@ export const identityKubernetesAuthServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
const orgBot = await orgBotDAL.findOne({ orgId: identityMembershipOrg.orgId });
if (!orgBot) throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
if (!orgBot)
throw new NotFoundError({
message: `Organization bot not found for organization with ID ${identityMembershipOrg.orgId}`,
name: "OrgBotNotFound"
});
const key = infisicalSymmetricDecrypt({
ciphertext: orgBot.encryptedSymmetricKey,
@ -579,7 +596,7 @@ export const identityKubernetesAuthServiceFactory = ({
actorOrgId
}: TRevokeKubernetesAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.KUBERNETES_AUTH)
throw new BadRequestError({
message: "The identity does not have kubernetes auth"

@ -68,12 +68,17 @@ export const identityOidcAuthServiceFactory = ({
identityId: identityOidcAuth.identityId
});
if (!identityMembershipOrg) {
throw new NotFoundError({ message: "Identity organization membership not found" });
throw new NotFoundError({
message: `Identity organization membership for identity with ID '${identityOidcAuth.identityId}' not found`
});
}
const orgBot = await orgBotDAL.findOne({ orgId: identityMembershipOrg.orgId });
if (!orgBot) {
throw new NotFoundError({ message: "Organization bot was not found", name: "OrgBotNotFound" });
throw new NotFoundError({
message: `Organization bot not found for organization with ID '${identityMembershipOrg.orgId}'`,
name: "OrgBotNotFound"
});
}
const key = infisicalSymmetricDecrypt({
@ -221,7 +226,7 @@ export const identityOidcAuthServiceFactory = ({
}: TAttachOidcAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) {
throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
}
if (identityMembershipOrg.identity.authMethod)
throw new BadRequestError({
@ -360,7 +365,7 @@ export const identityOidcAuthServiceFactory = ({
}: TUpdateOidcAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) {
throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
}
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.OIDC_AUTH) {
@ -422,7 +427,10 @@ export const identityOidcAuthServiceFactory = ({
const orgBot = await orgBotDAL.findOne({ orgId: identityMembershipOrg.orgId });
if (!orgBot) {
throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
throw new NotFoundError({
message: `Organization bot not found for organization with ID '${identityMembershipOrg.orgId}'`,
name: "OrgBotNotFound"
});
}
const key = infisicalSymmetricDecrypt({
@ -460,7 +468,7 @@ export const identityOidcAuthServiceFactory = ({
const getOidcAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetOidcAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) {
throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
}
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.OIDC_AUTH) {
@ -482,7 +490,10 @@ export const identityOidcAuthServiceFactory = ({
const orgBot = await orgBotDAL.findOne({ orgId: identityMembershipOrg.orgId });
if (!orgBot) {
throw new NotFoundError({ message: "Organization bot not found", name: "OrgBotNotFound" });
throw new NotFoundError({
message: `Organization bot not found for organization with ID ${identityMembershipOrg.orgId}`,
name: "OrgBotNotFound"
});
}
const key = infisicalSymmetricDecrypt({

@ -66,7 +66,7 @@ export const identityProjectServiceFactory = ({
const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId });
if (existingIdentity)
throw new BadRequestError({
message: `Identity with id ${identityId} already exists in project with id ${projectId}`
message: `Identity with ID ${identityId} already exists in project with ID ${projectId}`
});
const project = await projectDAL.findById(projectId);
@ -76,7 +76,7 @@ export const identityProjectServiceFactory = ({
});
if (!identityOrgMembership)
throw new NotFoundError({
message: `Failed to find identity with id ${identityId}`
message: `Failed to find identity with ID ${identityId}`
});
for await (const { role: requestedRoleChange } of roles) {
@ -104,7 +104,7 @@ export const identityProjectServiceFactory = ({
})
: [];
if (customRoles.length !== customInputRoles.length)
throw new NotFoundError({ message: "Custom project roles not found" });
throw new NotFoundError({ message: "One or more custom project roles not found" });
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
const projectIdentity = await identityProjectDAL.transaction(async (tx) => {
@ -166,7 +166,7 @@ export const identityProjectServiceFactory = ({
const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId });
if (!projectIdentity)
throw new NotFoundError({
message: `Identity with id ${identityId} doesn't exists in project with id ${projectId}`
message: `Identity with ID ${identityId} doesn't exists in project with ID ${projectId}`
});
for await (const { role: requestedRoleChange } of roles) {
@ -192,7 +192,7 @@ export const identityProjectServiceFactory = ({
})
: [];
if (customRoles.length !== customInputRoles.length)
throw new NotFoundError({ message: "Custom project roles not found" });
throw new NotFoundError({ message: "One or more custom project roles not found" });
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
@ -237,8 +237,9 @@ export const identityProjectServiceFactory = ({
projectId
}: TDeleteProjectIdentityDTO) => {
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
if (!identityProjectMembership)
throw new NotFoundError({ message: `Failed to find identity with id ${identityId}` });
if (!identityProjectMembership) {
throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
}
const { permission } = await permissionService.getProjectPermission(
actor,
@ -314,7 +315,10 @@ export const identityProjectServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Identity);
const [identityMembership] = await identityProjectDAL.findByProjectId(projectId, { identityId });
if (!identityMembership) throw new NotFoundError({ message: `Membership not found for identity ${identityId}` });
if (!identityMembership)
throw new NotFoundError({
message: `Project membership for identity with ID '${identityId} in project with ID '${projectId}' not found`
});
return identityMembership;
};

@ -64,7 +64,7 @@ export const identityTokenAuthServiceFactory = ({
actorOrgId
}: TAttachTokenAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethod)
throw new BadRequestError({
message: "Failed to add Token Auth to already configured identity"
@ -136,7 +136,7 @@ export const identityTokenAuthServiceFactory = ({
actorOrgId
}: TUpdateTokenAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
throw new BadRequestError({
message: "Failed to update Token Auth"
@ -196,7 +196,7 @@ export const identityTokenAuthServiceFactory = ({
const getTokenAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetTokenAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
throw new BadRequestError({
message: "The identity does not have Token Auth attached"
@ -224,7 +224,7 @@ export const identityTokenAuthServiceFactory = ({
actorOrgId
}: TRevokeTokenAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
throw new BadRequestError({
message: "The identity does not have Token Auth"
@ -269,7 +269,7 @@ export const identityTokenAuthServiceFactory = ({
name
}: TCreateTokenAuthTokenDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
throw new BadRequestError({
message: "The identity does not have Token Auth"
@ -343,7 +343,7 @@ export const identityTokenAuthServiceFactory = ({
actorOrgId
}: TGetTokenAuthTokensDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
throw new BadRequestError({
message: "The identity does not have Token Auth"
@ -376,9 +376,11 @@ export const identityTokenAuthServiceFactory = ({
actorOrgId
}: TUpdateTokenAuthTokenDTO) => {
const foundToken = await identityAccessTokenDAL.findById(tokenId);
if (!foundToken) throw new NotFoundError({ message: "Failed to find token" });
if (!foundToken) throw new NotFoundError({ message: `Token with ID ${tokenId} not found` });
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: foundToken.identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) {
throw new NotFoundError({ message: `Failed to find identity with ID ${foundToken.identityId}` });
}
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
throw new BadRequestError({
message: "The identity does not have Token Auth"
@ -431,7 +433,7 @@ export const identityTokenAuthServiceFactory = ({
});
if (!identityAccessToken)
throw new NotFoundError({
message: "Failed to find token"
message: `Token with ID ${tokenId} not found or already revoked`
});
const identityOrgMembership = await identityOrgMembershipDAL.findOne({
@ -439,7 +441,7 @@ export const identityTokenAuthServiceFactory = ({
});
if (!identityOrgMembership) {
throw new NotFoundError({ message: "No identity organization membership found" });
throw new NotFoundError({ message: `Failed to find identity with ID ${identityAccessToken.identityId}` });
}
const { permission } = await permissionService.getOrgPermission(

@ -28,6 +28,7 @@ export const identityUaClientSecretDALFactory = (db: TDbClient) => {
const removeExpiredClientSecrets = async (tx?: Knex) => {
const BATCH_SIZE = 10000;
const MAX_RETRY_ON_FAILURE = 3;
const MAX_TTL = 315_360_000; // Maximum TTL value in seconds (10 years)
let deletedClientSecret: { id: string }[] = [];
let numberOfRetryOnFailure = 0;
@ -53,7 +54,8 @@ export const identityUaClientSecretDALFactory = (db: TDbClient) => {
void qb
.where("clientSecretTTL", ">", 0)
.andWhereRaw(
`"${TableName.IdentityUaClientSecret}"."createdAt" + make_interval(secs => "${TableName.IdentityUaClientSecret}"."clientSecretTTL") < NOW()`
`"${TableName.IdentityUaClientSecret}"."createdAt" + make_interval(secs => LEAST("${TableName.IdentityUaClientSecret}"."clientSecretTTL", ?)) < NOW()`,
[MAX_TTL]
);
})
.select("id")

@ -155,7 +155,7 @@ export const identityUaServiceFactory = ({
actorOrgId
}: TAttachUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethod)
throw new BadRequestError({
message: "Failed to add universal auth to already configured identity"
@ -246,7 +246,7 @@ export const identityUaServiceFactory = ({
actorOrgId
}: TUpdateUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
throw new BadRequestError({
message: "Failed to updated universal auth"
@ -320,7 +320,7 @@ export const identityUaServiceFactory = ({
const getIdentityUniversalAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
throw new BadRequestError({
message: "The identity does not have universal auth"
@ -347,7 +347,7 @@ export const identityUaServiceFactory = ({
actorOrgId
}: TRevokeUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
throw new BadRequestError({
message: "The identity does not have universal auth"
@ -392,7 +392,7 @@ export const identityUaServiceFactory = ({
numUsesLimit
}: TCreateUaClientSecretDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
throw new BadRequestError({
message: "The identity does not have universal auth"
@ -452,7 +452,7 @@ export const identityUaServiceFactory = ({
identityId
}: TGetUaClientSecretsDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
throw new BadRequestError({
message: "The identity does not have universal auth"
@ -499,7 +499,7 @@ export const identityUaServiceFactory = ({
clientSecretId
}: TGetUniversalAuthClientSecretByIdDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
throw new BadRequestError({
message: "The identity does not have universal auth"
@ -538,7 +538,7 @@ export const identityUaServiceFactory = ({
clientSecretId
}: TRevokeUaClientSecretDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new NotFoundError({ message: "Failed to find identity" });
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
throw new BadRequestError({
message: "The identity does not have universal auth"

@ -1113,6 +1113,8 @@ export const getApps = async ({
});
case Integrations.AZURE_KEY_VAULT:
return [];
case Integrations.AZURE_APP_CONFIGURATION:
return [];
case Integrations.AWS_PARAMETER_STORE:
return [];
case Integrations.AWS_SECRET_MANAGER:
@ -1259,6 +1261,6 @@ export const getApps = async ({
});
default:
throw new NotFoundError({ message: "integration not found" });
throw new NotFoundError({ message: `Integration '${integration}' not found` });
}
};

@ -110,7 +110,7 @@ export const integrationAuthServiceFactory = ({
const getIntegrationAuth = async ({ actor, id, actorId, actorAuthMethod, actorOrgId }: TGetIntegrationAuthDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -195,7 +195,7 @@ export const integrationAuthServiceFactory = ({
updateDoc.encryptedAccess = accessToken;
}
} else {
if (!botKey) throw new NotFoundError({ message: "Project bot key not found" });
if (!botKey) throw new NotFoundError({ message: `Project bot key for project with ID '${projectId}' not found` });
if (tokenExchange.refreshToken) {
const refreshEncToken = encryptSymmetric128BitHexKeyUTF8(tokenExchange.refreshToken, botKey);
updateDoc.refreshIV = refreshEncToken.iv;
@ -317,7 +317,7 @@ export const integrationAuthServiceFactory = ({
}
}
} else {
if (!botKey) throw new NotFoundError({ message: "Project bot key not found" });
if (!botKey) throw new NotFoundError({ message: `Project bot key for project with ID '${projectId}' not found` });
if (refreshToken) {
const tokenDetails = await exchangeRefresh(
integration,
@ -371,7 +371,8 @@ export const integrationAuthServiceFactory = ({
let accessId: string | undefined;
// this means its not access token based
if (
integrationAuth.integration === Integrations.AWS_SECRET_MANAGER &&
(integrationAuth.integration === Integrations.AWS_SECRET_MANAGER ||
integrationAuth.integration === Integrations.AWS_PARAMETER_STORE) &&
(shouldUseSecretV2Bridge
? integrationAuth.encryptedAwsAssumeIamRoleArn
: integrationAuth.awsAssumeIamRoleArnCipherText)
@ -496,7 +497,7 @@ export const integrationAuthServiceFactory = ({
workspaceSlug
}: TIntegrationAuthAppsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -530,7 +531,7 @@ export const integrationAuthServiceFactory = ({
id
}: TIntegrationAuthTeamsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -560,7 +561,7 @@ export const integrationAuthServiceFactory = ({
actorOrgId
}: TIntegrationAuthVercelBranchesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -601,7 +602,7 @@ export const integrationAuthServiceFactory = ({
accountId
}: TIntegrationAuthChecklyGroupsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -629,7 +630,7 @@ export const integrationAuthServiceFactory = ({
const getGithubOrgs = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TIntegrationAuthGithubOrgsDTO) => {
const appCfg = getConfig();
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -703,7 +704,7 @@ export const integrationAuthServiceFactory = ({
repoName
}: TIntegrationAuthGithubEnvsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -750,7 +751,7 @@ export const integrationAuthServiceFactory = ({
const getQoveryOrgs = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TIntegrationAuthQoveryOrgsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -784,7 +785,7 @@ export const integrationAuthServiceFactory = ({
region
}: TIntegrationAuthAwsKmsKeyDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -842,7 +843,7 @@ export const integrationAuthServiceFactory = ({
orgId
}: TIntegrationAuthQoveryProjectDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -878,7 +879,7 @@ export const integrationAuthServiceFactory = ({
actorOrgId
}: TIntegrationAuthQoveryEnvironmentsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -919,7 +920,7 @@ export const integrationAuthServiceFactory = ({
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -959,7 +960,7 @@ export const integrationAuthServiceFactory = ({
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -999,7 +1000,7 @@ export const integrationAuthServiceFactory = ({
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID ${id} not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1038,7 +1039,7 @@ export const integrationAuthServiceFactory = ({
actorOrgId
}: TIntegrationAuthHerokuPipelinesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1078,7 +1079,7 @@ export const integrationAuthServiceFactory = ({
appId
}: TIntegrationAuthRailwayEnvDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1146,7 +1147,7 @@ export const integrationAuthServiceFactory = ({
appId
}: TIntegrationAuthRailwayServicesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1220,7 +1221,7 @@ export const integrationAuthServiceFactory = ({
id
}: TIntegrationAuthBitbucketWorkspaceDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1269,7 +1270,7 @@ export const integrationAuthServiceFactory = ({
appId
}: TIntegrationAuthNorthflankSecretGroupDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1337,7 +1338,7 @@ export const integrationAuthServiceFactory = ({
actor
}: TGetIntegrationAuthTeamCityBuildConfigDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1399,7 +1400,7 @@ export const integrationAuthServiceFactory = ({
actorOrgId
}: TDeleteIntegrationAuthByIdDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" });
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -1412,7 +1413,7 @@ export const integrationAuthServiceFactory = ({
const delIntegrationAuth = await integrationAuthDAL.transaction(async (tx) => {
const doc = await integrationAuthDAL.deleteById(integrationAuth.id, tx);
if (!doc) throw new NotFoundError({ message: "Faled to find integration" });
if (!doc) throw new NotFoundError({ message: `Integration auth with ID '${integrationAuth.id}' not found` });
await integrationDAL.delete({ integrationAuthId: doc.id }, tx);
return doc;
});
@ -1431,7 +1432,7 @@ export const integrationAuthServiceFactory = ({
}: TDuplicateGithubIntegrationAuthDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) {
throw new NotFoundError({ message: "Failed to find integration" });
throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
}
const { permission: sourcePermission } = await permissionService.getProjectPermission(

@ -314,7 +314,7 @@ export const deleteIntegrationSecrets = async ({
if (!folder) {
throw new NotFoundError({
message: "Folder not found."
message: `Folder with path '${integration.secretPath}' not found in environment with slug '${integration.environment.slug}'`
});
}

@ -33,7 +33,8 @@ export enum Integrations {
NORTHFLANK = "northflank",
HASURA_CLOUD = "hasura-cloud",
RUNDECK = "rundeck",
AZURE_DEVOPS = "azure-devops"
AZURE_DEVOPS = "azure-devops",
AZURE_APP_CONFIGURATION = "azure-app-configuration"
}
export enum IntegrationType {
@ -206,6 +207,15 @@ export const getIntegrationOptions = async () => {
clientId: appCfg.CLIENT_ID_AZURE,
docsLink: ""
},
{
name: "Azure App Configuration",
slug: "azure-app-configuration",
image: "Microsoft Azure.png",
isAvailable: true,
type: "oauth",
clientId: appCfg.CLIENT_ID_AZURE,
docsLink: ""
},
{
name: "Circle CI",
slug: "circleci",

@ -24,6 +24,7 @@ import { Octokit } from "@octokit/rest";
import AWS, { AWSError } from "aws-sdk";
import { AxiosError } from "axios";
import { randomUUID } from "crypto";
import https from "https";
import sodium from "libsodium-wrappers";
import isEqual from "lodash.isequal";
import { z } from "zod";
@ -270,6 +271,180 @@ const syncSecretsGCPSecretManager = async ({
}
};
const syncSecretsAzureAppConfig = async ({
integration,
secrets,
accessToken,
createManySecretsRawFn,
updateManySecretsRawFn,
integrationDAL
}: {
integration: TIntegrations & {
projectId: string;
environment: {
id: string;
name: string;
slug: string;
};
secretPath: string;
};
secrets: Record<string, { value: string; comment?: string } | null>;
accessToken: string;
createManySecretsRawFn: (params: TCreateManySecretsRawFn) => Promise<Array<{ id: string }>>;
updateManySecretsRawFn: (params: TUpdateManySecretsRawFn) => Promise<Array<{ id: string }>>;
integrationDAL: Pick<TIntegrationDALFactory, "updateById">;
}) => {
interface AzureAppConfigKeyValue {
key: string;
value: string;
}
const getCompleteAzureAppConfigValues = async (url: string) => {
let result: AzureAppConfigKeyValue[] = [];
while (url) {
const res = await request.get(url, {
headers: {
Authorization: `Bearer ${accessToken}`
},
// we force IPV4 because docker setup fails with ipv6
httpsAgent: new https.Agent({
family: 4
})
});
result = result.concat(res.data.items);
url = res.data.nextLink;
}
return result;
};
const metadata = IntegrationMetadataSchema.parse(integration.metadata);
const azureAppConfigSecrets = (
await getCompleteAzureAppConfigValues(
`${integration.app}/kv?api-version=2023-11-01&key=${metadata.secretPrefix || ""}*`
)
).reduce(
(accum, entry) => {
accum[entry.key] = entry.value;
return accum;
},
{} as Record<string, string>
);
const secretsToAdd: { [key: string]: string } = {};
const secretsToUpdate: { [key: string]: string } = {};
Object.keys(azureAppConfigSecrets).forEach((key) => {
if (!integration.lastUsed) {
// first time using integration
// -> apply initial sync behavior
switch (metadata.initialSyncBehavior) {
case IntegrationInitialSyncBehavior.OVERWRITE_TARGET: {
if (!(key in secrets)) {
secrets[key] = null;
}
break;
}
case IntegrationInitialSyncBehavior.PREFER_TARGET: {
if (!(key in secrets)) {
secretsToAdd[key] = azureAppConfigSecrets[key];
} else if (secrets[key]?.value !== azureAppConfigSecrets[key]) {
secretsToUpdate[key] = azureAppConfigSecrets[key];
}
secrets[key] = {
value: azureAppConfigSecrets[key]
};
break;
}
case IntegrationInitialSyncBehavior.PREFER_SOURCE: {
if (!(key in secrets)) {
secrets[key] = {
value: azureAppConfigSecrets[key]
};
secretsToAdd[key] = azureAppConfigSecrets[key];
}
break;
}
default: {
break;
}
}
} else if (!(key in secrets)) {
secrets[key] = null;
}
});
if (Object.keys(secretsToAdd).length) {
await createManySecretsRawFn({
projectId: integration.projectId,
environment: integration.environment.slug,
path: integration.secretPath,
secrets: Object.keys(secretsToAdd).map((key) => ({
secretName: key,
secretValue: secretsToAdd[key],
type: SecretType.Shared,
secretComment: ""
}))
});
}
if (Object.keys(secretsToUpdate).length) {
await updateManySecretsRawFn({
projectId: integration.projectId,
environment: integration.environment.slug,
path: integration.secretPath,
secrets: Object.keys(secretsToUpdate).map((key) => ({
secretName: key,
secretValue: secretsToUpdate[key],
type: SecretType.Shared,
secretComment: ""
}))
});
}
// create or update secrets on Azure App Config
for await (const key of Object.keys(secrets)) {
if (!(key in azureAppConfigSecrets) || secrets[key]?.value !== azureAppConfigSecrets[key]) {
await request.put(
`${integration.app}/kv/${key}?api-version=2023-11-01`,
{
value: secrets[key]?.value
},
{
headers: {
Authorization: `Bearer ${accessToken}`
},
// we force IPV4 because docker setup fails with ipv6
httpsAgent: new https.Agent({
family: 4
})
}
);
}
}
for await (const key of Object.keys(azureAppConfigSecrets)) {
if (!(key in secrets) || secrets[key] === null) {
// case: delete secret
await request.delete(`${integration.app}/kv/${key}?api-version=2023-11-01`, {
headers: {
Authorization: `Bearer ${accessToken}`
},
// we force IPV4 because docker setup fails with ipv6
httpsAgent: new https.Agent({
family: 4
})
});
}
}
await integrationDAL.updateById(integration.id, {
lastUsed: new Date()
});
};
/**
* Sync/push [secrets] to Azure Key Vault with vault URI [integration.app]
*/
@ -555,24 +730,63 @@ const syncSecretsAWSParameterStore = async ({
secrets,
accessId,
accessToken,
projectId
projectId,
awsAssumeRoleArn
}: {
integration: TIntegrations & { secretPath: string; environment: { slug: string } };
secrets: Record<string, { value: string; comment?: string }>;
accessId: string | null;
accessToken: string;
awsAssumeRoleArn: string | null;
projectId?: string;
}) => {
const appCfg = getConfig();
let response: { isSynced: boolean; syncMessage: string } | null = null;
if (!accessId) {
throw new Error("AWS access ID is required");
if (!accessId && !awsAssumeRoleArn) {
throw new Error("AWS access ID/AWS Assume Role is required");
}
let accessKeyId = "";
let secretAccessKey = "";
let sessionToken;
if (awsAssumeRoleArn) {
const client = new STSClient({
region: integration.region as string,
credentials:
appCfg.CLIENT_ID_AWS_INTEGRATION && appCfg.CLIENT_SECRET_AWS_INTEGRATION
? {
accessKeyId: appCfg.CLIENT_ID_AWS_INTEGRATION,
secretAccessKey: appCfg.CLIENT_SECRET_AWS_INTEGRATION
}
: undefined
});
const command = new AssumeRoleCommand({
RoleArn: awsAssumeRoleArn,
RoleSessionName: `infisical-parameter-store-${randomUUID()}`,
DurationSeconds: 900, // 15mins
ExternalId: projectId
});
const assumeRes = await client.send(command);
if (!assumeRes.Credentials?.AccessKeyId || !assumeRes.Credentials?.SecretAccessKey) {
throw new Error("Failed to assume role");
}
accessKeyId = assumeRes.Credentials?.AccessKeyId;
secretAccessKey = assumeRes.Credentials?.SecretAccessKey;
sessionToken = assumeRes.Credentials?.SessionToken;
} else {
accessKeyId = accessId as string;
secretAccessKey = accessToken;
}
const config = new AWS.Config({
region: integration.region as string,
credentials: {
accessKeyId: accessId,
secretAccessKey: accessToken
accessKeyId,
secretAccessKey,
sessionToken
}
});
@ -4041,12 +4255,23 @@ export const syncIntegrationSecrets = async ({
accessToken
});
break;
case Integrations.AZURE_APP_CONFIGURATION:
await syncSecretsAzureAppConfig({
integration,
integrationDAL,
secrets,
accessToken,
createManySecretsRawFn,
updateManySecretsRawFn
});
break;
case Integrations.AWS_PARAMETER_STORE:
response = await syncSecretsAWSParameterStore({
integration,
secrets,
accessId,
accessToken,
awsAssumeRoleArn,
projectId
});
break;

@ -131,6 +131,35 @@ const exchangeCodeAzure = async ({ code }: { code: string }) => {
};
};
const exchangeCodeAzureAppConfig = async ({ code }: { code: string }) => {
const accessExpiresAt = new Date();
const appCfg = getConfig();
if (!appCfg.CLIENT_ID_AZURE || !appCfg.CLIENT_SECRET_AZURE) {
throw new BadRequestError({ message: "Missing client id and client secret" });
}
const res = (
await request.post<ExchangeCodeAzureResponse>(
IntegrationUrls.AZURE_TOKEN_URL,
new URLSearchParams({
grant_type: "authorization_code",
code,
scope: "https://azconfig.io/.default openid offline_access",
client_id: appCfg.CLIENT_ID_AZURE,
client_secret: appCfg.CLIENT_SECRET_AZURE,
redirect_uri: `${appCfg.SITE_URL}/integrations/azure-app-configuration/oauth2/callback`
})
)
).data;
accessExpiresAt.setSeconds(accessExpiresAt.getSeconds() + res.expires_in);
return {
accessToken: res.access_token,
refreshToken: res.refresh_token,
accessExpiresAt
};
};
const exchangeCodeHeroku = async ({ code }: { code: string }) => {
const accessExpiresAt = new Date();
const appCfg = getConfig();
@ -434,6 +463,10 @@ export const exchangeCode = async ({
return exchangeCodeAzure({
code
});
case Integrations.AZURE_APP_CONFIGURATION:
return exchangeCodeAzureAppConfig({
code
});
case Integrations.HEROKU:
return exchangeCodeHeroku({
code
@ -746,6 +779,7 @@ export const exchangeRefresh = async (
accessExpiresAt: Date;
}> => {
switch (integration) {
case Integrations.AZURE_APP_CONFIGURATION:
case Integrations.AZURE_KEY_VAULT:
return exchangeRefreshAzure({
refreshToken

@ -76,7 +76,8 @@ export const integrationServiceFactory = ({
targetEnvironmentId
}: TCreateIntegrationDTO) => {
const integrationAuth = await integrationAuthDAL.findById(integrationAuthId);
if (!integrationAuth) throw new NotFoundError({ message: "Integration auth not found" });
if (!integrationAuth)
throw new NotFoundError({ message: `Integration auth with ID '${integrationAuthId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -93,7 +94,11 @@ export const integrationServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(integrationAuth.projectId, sourceEnvironment, secretPath);
if (!folder) throw new NotFoundError({ message: "Folder path not found" });
if (!folder) {
throw new NotFoundError({
message: `Folder with path '${secretPath}' not found in environment with slug'${sourceEnvironment}'`
});
}
const integration = await integrationDAL.create({
envId: folder.envId,
@ -145,7 +150,7 @@ export const integrationServiceFactory = ({
metadata
}: TUpdateIntegrationDTO) => {
const integration = await integrationDAL.findById(id);
if (!integration) throw new NotFoundError({ message: "Integration auth not found" });
if (!integration) throw new NotFoundError({ message: `Integration with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -167,7 +172,11 @@ export const integrationServiceFactory = ({
}
const folder = await folderDAL.findBySecretPath(integration.projectId, newEnvironment, newSecretPath);
if (!folder) throw new NotFoundError({ message: "Folder path not found" });
if (!folder) {
throw new NotFoundError({
message: `Folder with path '${newSecretPath}' not found in environment with slug '${newEnvironment}'`
});
}
const updatedIntegration = await integrationDAL.updateById(id, {
envId: folder.envId,
@ -200,7 +209,7 @@ export const integrationServiceFactory = ({
if (!integration) {
throw new NotFoundError({
message: "Integration not found"
message: `Integration with ID '${id}' not found`
});
}
@ -215,7 +224,7 @@ export const integrationServiceFactory = ({
if (!integration) {
throw new NotFoundError({
message: "Integration not found"
message: `Integration with ID '${id}' not found`
});
}
@ -231,7 +240,7 @@ export const integrationServiceFactory = ({
shouldDeleteIntegrationSecrets
}: TDeleteIntegrationDTO) => {
const integration = await integrationDAL.findById(id);
if (!integration) throw new NotFoundError({ message: "Integration auth not found" });
if (!integration) throw new NotFoundError({ message: `Integration with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -285,7 +294,7 @@ export const integrationServiceFactory = ({
const syncIntegration = async ({ id, actorId, actor, actorOrgId, actorAuthMethod }: TSyncIntegrationDTO) => {
const integration = await integrationDAL.findById(id);
if (!integration) {
throw new NotFoundError({ message: "Integration not found" });
throw new NotFoundError({ message: `Integration with ID '${id}' not found` });
}
const { permission } = await permissionService.getProjectPermission(

@ -164,7 +164,7 @@ export const kmsServiceFactory = ({
let org = await orgDAL.findById(orgId, trx);
if (!org) {
throw new NotFoundError({ message: "Org not found" });
throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
}
if (!org.kmsDefaultKeyId) {
@ -247,7 +247,7 @@ export const kmsServiceFactory = ({
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId, tx);
if (!kmsDoc) {
throw new NotFoundError({ message: "KMS ID not found" });
throw new NotFoundError({ message: `KMS with ID '${kmsId}' not found` });
}
if (kmsDoc.externalKms) {
@ -315,7 +315,7 @@ export const kmsServiceFactory = ({
const encryptWithKmsKey = async ({ kmsId }: Omit<TEncryptWithKmsDTO, "plainText">, tx?: Knex) => {
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId, tx);
if (!kmsDoc) {
throw new NotFoundError({ message: "KMS ID not found" });
throw new NotFoundError({ message: `KMS with ID '${kmsId}' not found` });
}
if (kmsDoc.externalKms) {
@ -382,7 +382,7 @@ export const kmsServiceFactory = ({
let org = await orgDAL.findById(orgId, trx);
if (!org) {
throw new NotFoundError({ message: "Org not found" });
throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
}
if (!org.kmsEncryptedDataKey) {
@ -460,7 +460,7 @@ export const kmsServiceFactory = ({
const getProjectSecretManagerKmsKeyId = async (projectId: string, trx?: Knex) => {
let project = await projectDAL.findById(projectId, trx);
if (!project) {
throw new NotFoundError({ message: "Project not found" });
throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
}
if (!project.kmsSecretManagerKeyId) {
@ -650,12 +650,12 @@ export const kmsServiceFactory = ({
const project = await projectDAL.findById(projectId);
if (!project) {
throw new NotFoundError({
message: "Project not found."
message: `Project with ID '${projectId}' not found`
});
}
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId);
if (!kmsDoc) {
throw new NotFoundError({ message: "KMS ID not found." });
throw new NotFoundError({ message: `KMS with ID '${kmsId}' not found` });
}
if (kmsDoc.orgId !== project.orgId) {
@ -702,7 +702,7 @@ export const kmsServiceFactory = ({
const project = await projectDAL.findById(projectId);
if (!project) {
throw new NotFoundError({
message: "Project not found"
message: `Project with ID '${projectId}' not found`
});
}
@ -730,7 +730,7 @@ export const kmsServiceFactory = ({
const project = await projectDAL.findById(projectId);
if (!project) {
throw new NotFoundError({
message: "Project not found"
message: `Project with ID '${projectId}' not found`
});
}
@ -785,7 +785,7 @@ export const kmsServiceFactory = ({
if (!kms.id) {
throw new NotFoundError({
message: "KMS not found"
message: `KMS with ID '${kmsKeyId}' not found`
});
}
const { id, name, orgId, isExternal } = kms;

@ -90,7 +90,7 @@ export const orgAdminServiceFactory = ({
);
const project = await projectDAL.findById(projectId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
if (project.version === ProjectVersion.V1) {
throw new BadRequestError({ message: "Please upgrade your project on your dashboard" });
@ -120,21 +120,21 @@ export const orgAdminServiceFactory = ({
const ghostUser = await projectDAL.findProjectGhostUser(projectId);
if (!ghostUser) {
throw new NotFoundError({
message: "Failed to find project owner"
message: `Project owner of project with ID '${projectId}' not found`
});
}
const ghostUserLatestKey = await projectKeyDAL.findLatestProjectKey(ghostUser.id, projectId);
if (!ghostUserLatestKey) {
throw new NotFoundError({
message: "Failed to find project owner's latest key"
message: `Project owner's latest key of project with ID '${projectId}' not found`
});
}
const bot = await projectBotDAL.findOne({ projectId });
if (!bot) {
throw new NotFoundError({
message: "Failed to find project bot"
message: `Project bot for project with ID '${projectId}' not found`
});
}
@ -146,7 +146,8 @@ export const orgAdminServiceFactory = ({
});
const userEncryptionKey = await userDAL.findUserEncKeyByUserId(actorId);
if (!userEncryptionKey) throw new NotFoundError({ message: "User encryption key not found" });
if (!userEncryptionKey)
throw new NotFoundError({ message: `User encryption key for user with ID '${actorId}' not found` });
const [newWsMember] = assignWorkspaceKeysToMembers({
decryptKey: ghostUserLatestKey,
userPrivateKey: botPrivateKey,

@ -5,7 +5,7 @@ import { TOrgRoleDALFactory } from "@app/services/org/org-role-dal";
const RESERVED_ORG_ROLE_SLUGS = Object.values(OrgMembershipRole).filter((role) => role !== "custom");
export const isCustomOrgRole = (roleSlug: string) => !RESERVED_ORG_ROLE_SLUGS.includes(roleSlug as OrgMembershipRole);
export const isCustomOrgRole = (roleSlug: string) => !RESERVED_ORG_ROLE_SLUGS.find((r) => r === roleSlug);
// this is only for updating an org
export const getDefaultOrgMembershipRoleForUpdateOrg = async ({
@ -27,7 +27,12 @@ export const getDefaultOrgMembershipRoleForUpdateOrg = async ({
});
const customRole = await orgRoleDAL.findOne({ slug: membershipRoleSlug, orgId });
if (!customRole) throw new NotFoundError({ name: "UpdateOrg", message: "Organization role not found" });
if (!customRole) {
throw new NotFoundError({
name: "UpdateOrg",
message: `Organization role with slug '${membershipRoleSlug}' not found`
});
}
// use ID for default role
return customRole.id;

@ -100,7 +100,7 @@ export const orgRoleServiceFactory = ({
}
default: {
const role = await orgRoleDAL.findOne({ id: roleId, orgId });
if (!role) throw new NotFoundError({ message: "Organization role not found" });
if (!role) throw new NotFoundError({ message: `Organization role with ID '${roleId}' not found` });
return role;
}
}
@ -125,7 +125,7 @@ export const orgRoleServiceFactory = ({
{ id: roleId, orgId },
{ ...data, permissions: data.permissions ? JSON.stringify(data.permissions) : undefined }
);
if (!updatedRole) throw new NotFoundError({ message: "Organization role not found" });
if (!updatedRole) throw new NotFoundError({ message: `Organization role with ID '${roleId}' not found` });
return updatedRole;
};
@ -143,7 +143,7 @@ export const orgRoleServiceFactory = ({
if (!org)
throw new NotFoundError({
message: "Failed to find organization"
message: `Organization with ID '${orgId}' not found`
});
if (org.defaultMembershipRole === roleId)
@ -163,7 +163,8 @@ export const orgRoleServiceFactory = ({
});
const [deletedRole] = await orgRoleDAL.delete({ id: roleId, orgId });
if (!deletedRole) throw new NotFoundError({ message: "Organization role not found", name: "Update role" });
if (!deletedRole)
throw new NotFoundError({ message: `Organization role with ID '${roleId}' not found`, name: "UpdateRole" });
return deletedRole;
};

@ -138,7 +138,7 @@ export const orgServiceFactory = ({
) => {
await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
const org = await orgDAL.findOrgById(orgId);
if (!org) throw new NotFoundError({ message: "Organization not found" });
if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
return org;
};
/*
@ -268,13 +268,28 @@ export const orgServiceFactory = ({
actorOrgId,
actorAuthMethod,
orgId,
data: { name, slug, authEnforced, scimEnabled, defaultMembershipRoleSlug }
data: { name, slug, authEnforced, scimEnabled, defaultMembershipRoleSlug, enforceMfa }
}: TUpdateOrgDTO) => {
const appCfg = getConfig();
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
const plan = await licenseService.getPlan(orgId);
if (enforceMfa !== undefined) {
if (!plan.enforceMfa) {
throw new BadRequestError({
message: "Failed to enforce user MFA due to plan restriction. Upgrade plan to enforce/un-enforce MFA."
});
}
if (!appCfg.isSmtpConfigured) {
throw new BadRequestError({
message: "Failed to enforce user MFA due to missing instance SMTP configuration."
});
}
}
if (authEnforced !== undefined) {
if (!plan?.samlSSO || !plan.oidcSSO)
throw new BadRequestError({
@ -298,7 +313,7 @@ export const orgServiceFactory = ({
if (!samlCfg && !oidcCfg)
throw new NotFoundError({
message: "No enforceable SSO config found"
message: `SAML or OIDC configuration for organization with ID '${orgId}' not found`
});
}
@ -317,9 +332,10 @@ export const orgServiceFactory = ({
slug: slug ? slugify(slug) : undefined,
authEnforced,
scimEnabled,
defaultMembershipRole
defaultMembershipRole,
enforceMfa
});
if (!org) throw new NotFoundError({ message: "Organization not found" });
if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
return org;
};
/*
@ -433,7 +449,8 @@ export const orgServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member);
const foundMembership = await orgMembershipDAL.findById(membershipId);
if (!foundMembership) throw new NotFoundError({ message: "Failed to find organization membership" });
if (!foundMembership)
throw new NotFoundError({ message: `Organization membership with ID ${membershipId} not found` });
if (foundMembership.orgId !== orgId)
throw new UnauthorizedError({ message: "Updated org member doesn't belong to the organization" });
if (foundMembership.userId === userId)
@ -629,8 +646,12 @@ export const orgServiceFactory = ({
const orgRole = isCustomOrgRole ? OrgMembershipRole.Custom : organizationRoleSlug;
if (isCustomOrgRole) {
const customRole = await orgRoleDAL.findOne({ slug: organizationRoleSlug, orgId });
if (!customRole)
throw new NotFoundError({ name: "InviteUser", message: "Custom organization role not found" });
if (!customRole) {
throw new NotFoundError({
name: "InviteUser",
message: `Custom organization role with slug '${orgRole}' not found`
});
}
roleId = customRole.id;
}
@ -788,7 +809,7 @@ export const orgServiceFactory = ({
if (!bot) {
throw new NotFoundError({
name: "InviteUser",
message: "Failed to find project bot"
message: `Failed to find project bot for project with ID '${projectId}'`
});
}
@ -796,7 +817,7 @@ export const orgServiceFactory = ({
if (!ghostUserLatestKey) {
throw new NotFoundError({
name: "InviteUser",
message: "Failed to find project owner's latest key"
message: `Failed to find project owner's latest key for project with ID '${projectId}'`
});
}
@ -985,7 +1006,7 @@ export const orgServiceFactory = ({
const membership = await orgMembershipDAL.findOrgMembershipById(membershipId);
if (!membership) {
throw new NotFoundError({ message: "Organization membership not found" });
throw new NotFoundError({ message: `Organization membership with ID '${membershipId}' not found` });
}
if (membership.orgId !== orgId) {
throw new ForbiddenRequestError({ message: "Membership does not belong to organization" });
@ -1031,7 +1052,7 @@ export const orgServiceFactory = ({
const membership = await orgMembershipDAL.findOrgMembershipById(orgMembershipId);
if (!membership) {
throw new NotFoundError({ message: "Organization membership not found" });
throw new NotFoundError({ message: `Organization membership with ID '${orgMembershipId}' not found` });
}
if (membership.orgId !== orgId) throw new NotFoundError({ message: "Failed to find organization membership" });

@ -64,6 +64,7 @@ export type TUpdateOrgDTO = {
authEnforced: boolean;
scimEnabled: boolean;
defaultMembershipRoleSlug: string;
enforceMfa: boolean;
}>;
} & TOrgPermission;

@ -84,7 +84,7 @@ export const pkiAlertServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.PkiAlerts);
const pkiCollection = await pkiCollectionDAL.findById(pkiCollectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${pkiCollectionId}' not found` });
if (pkiCollection.projectId !== projectId)
throw new ForbiddenRequestError({ message: "PKI collection does not belong to the specified project." });
@ -100,7 +100,7 @@ export const pkiAlertServiceFactory = ({
const getPkiAlertById = async ({ alertId, actorId, actorAuthMethod, actor, actorOrgId }: TGetAlertByIdDTO) => {
const alert = await pkiAlertDAL.findById(alertId);
if (!alert) throw new NotFoundError({ message: "Alert not found" });
if (!alert) throw new NotFoundError({ message: `Alert with ID '${alertId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -126,7 +126,7 @@ export const pkiAlertServiceFactory = ({
actorOrgId
}: TUpdateAlertDTO) => {
let alert = await pkiAlertDAL.findById(alertId);
if (!alert) throw new NotFoundError({ message: "Alert not found" });
if (!alert) throw new NotFoundError({ message: `Alert with ID '${alertId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -140,7 +140,7 @@ export const pkiAlertServiceFactory = ({
if (pkiCollectionId) {
const pkiCollection = await pkiCollectionDAL.findById(pkiCollectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${pkiCollectionId}' not found` });
if (pkiCollection.projectId !== alert.projectId) {
throw new ForbiddenRequestError({ message: "PKI collection does not belong to the specified project." });
}
@ -158,7 +158,7 @@ export const pkiAlertServiceFactory = ({
const deletePkiAlert = async ({ alertId, actorId, actorAuthMethod, actor, actorOrgId }: TDeleteAlertDTO) => {
let alert = await pkiAlertDAL.findById(alertId);
if (!alert) throw new NotFoundError({ message: "Alert not found" });
if (!alert) throw new NotFoundError({ message: `Alert with ID '${alertId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,

@ -80,7 +80,7 @@ export const pkiCollectionServiceFactory = ({
actorOrgId
}: TGetPkiCollectionByIdDTO) => {
const pkiCollection = await pkiCollectionDAL.findById(collectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${collectionId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -104,7 +104,7 @@ export const pkiCollectionServiceFactory = ({
actorOrgId
}: TUpdatePkiCollectionDTO) => {
let pkiCollection = await pkiCollectionDAL.findById(collectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${collectionId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -131,7 +131,7 @@ export const pkiCollectionServiceFactory = ({
actorOrgId
}: TDeletePkiCollectionDTO) => {
let pkiCollection = await pkiCollectionDAL.findById(collectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${collectionId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -160,7 +160,7 @@ export const pkiCollectionServiceFactory = ({
actorOrgId
}: TGetPkiCollectionItems) => {
const pkiCollection = await pkiCollectionDAL.findById(collectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${collectionId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -203,7 +203,7 @@ export const pkiCollectionServiceFactory = ({
itemId
}: TAddItemToPkiCollectionDTO) => {
const pkiCollection = await pkiCollectionDAL.findById(collectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${collectionId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -235,7 +235,7 @@ export const pkiCollectionServiceFactory = ({
projectId: pkiCollection.projectId
});
if (!ca) throw new NotFoundError({ message: "CA not found" });
if (!ca) throw new NotFoundError({ message: `CA with ID '${itemId}' not found` });
pkiCollectionItem = await pkiCollectionItemDAL.create({
pkiCollectionId: collectionId,
@ -261,7 +261,7 @@ export const pkiCollectionServiceFactory = ({
},
id: itemId
});
if (!certificate) throw new NotFoundError({ message: "Certificate not found" });
if (!certificate) throw new NotFoundError({ message: `Certificate with ID '${itemId}' not found` });
pkiCollectionItem = await pkiCollectionItemDAL.create({
pkiCollectionId: collectionId,
@ -289,14 +289,14 @@ export const pkiCollectionServiceFactory = ({
itemId
}: TRemoveItemFromPkiCollectionDTO) => {
const pkiCollection = await pkiCollectionDAL.findById(collectionId);
if (!pkiCollection) throw new NotFoundError({ message: "PKI collection not found" });
if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${collectionId}' not found` });
let pkiCollectionItem = await pkiCollectionItemDAL.findOne({
pkiCollectionId: collectionId,
id: itemId
});
if (!pkiCollectionItem) throw new NotFoundError({ message: "PKI collection item not found" });
if (!pkiCollectionItem) throw new NotFoundError({ message: `PKI collection item with ID '${itemId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,

@ -28,7 +28,7 @@ export const getBotKeyFnFactory = (
const project = await projectDAL.findById(projectId);
if (!project)
throw new NotFoundError({
message: "Project not found during bot lookup. Are you sure you are using the correct project ID?"
message: `Project with ID '${projectId}' not found during bot lookup. Are you sure you are using the correct project ID?`
});
if (project.version === 3 && !shouldGetBotKey) {
@ -39,8 +39,11 @@ export const getBotKeyFnFactory = (
if (!bot || !bot.isActive || !bot.encryptedProjectKey || !bot.encryptedProjectKeyNonce) {
// trying to set bot automatically
const projectV1Keys = await projectBotDAL.findProjectUserWorkspaceKey(projectId);
if (!projectV1Keys) throw new NotFoundError({ message: "Bot not found. Please ask admin user to login" });
if (!projectV1Keys) {
throw new NotFoundError({
message: `Project bot not found for project with ID '${projectId}'. Please ask an administrator to log-in to the Infisical Console.`
});
}
let userPrivateKey = "";
if (
projectV1Keys?.serverEncryptedPrivateKey &&

@ -91,7 +91,7 @@ export const projectBotServiceFactory = ({
const bot = await projectBotDAL.findProjectByBotId(botId);
return bot;
} catch (e) {
throw new NotFoundError({ message: "Failed to find bot by ID" });
throw new NotFoundError({ message: `Project bot with ID '${botId}' not found` });
}
};
@ -105,7 +105,7 @@ export const projectBotServiceFactory = ({
isActive
}: TSetActiveStateDTO) => {
const bot = await projectBotDAL.findById(botId);
if (!bot) throw new NotFoundError({ message: "Bot not found" });
if (!bot) throw new NotFoundError({ message: `Project bot with ID '${botId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -119,7 +119,7 @@ export const projectBotServiceFactory = ({
const project = await projectBotDAL.findProjectByBotId(botId);
if (!project) {
throw new NotFoundError({ message: "Failed to find project by bot ID" });
throw new NotFoundError({ message: `Project not found for bot with ID '${botId}'` });
}
if (project.version === ProjectVersion.V2) {
@ -128,7 +128,9 @@ export const projectBotServiceFactory = ({
if (isActive) {
if (!botKey?.nonce || !botKey?.encryptedKey) {
throw new NotFoundError({ message: "Bot key not found, failed to set bot active" });
throw new NotFoundError({
message: `Bot key not found for bot in project with ID '${botId}'. Failed to set bot state to active.`
});
}
const doc = await projectBotDAL.updateById(botId, {
isActive: true,
@ -136,7 +138,8 @@ export const projectBotServiceFactory = ({
encryptedProjectKeyNonce: botKey.nonce,
senderId: actorId
});
if (!doc) throw new BadRequestError({ message: "Failed to update bot active state" });
if (!doc)
throw new BadRequestError({ message: `Project bot with ID '${botId}' not found. Failed to update bot.` });
return doc;
}
@ -145,7 +148,7 @@ export const projectBotServiceFactory = ({
encryptedProjectKey: null,
encryptedProjectKeyNonce: null
});
if (!doc) throw new BadRequestError({ message: "Failed to update bot active state" });
if (!doc) throw new BadRequestError({ message: `Project bot with ID '${botId}' not found. Failed to update bot.` });
return doc;
};

@ -153,8 +153,11 @@ export const projectEnvServiceFactory = ({
}
const oldEnv = await projectEnvDAL.findOne({ id, projectId });
if (!oldEnv) throw new NotFoundError({ message: "Environment not found", name: "UpdateEnvironment" });
if (!oldEnv) {
throw new NotFoundError({
message: `Environment with id '${id}' in project with ID '${projectId}' not found`
});
}
if (slug) {
const existingEnv = await projectEnvDAL.findOne({ slug, projectId });
if (existingEnv && existingEnv.id !== id) {
@ -216,7 +219,7 @@ export const projectEnvServiceFactory = ({
const [doc] = await projectEnvDAL.delete({ id, projectId }, tx);
if (!doc)
throw new NotFoundError({
message: "Environment doesn't exist",
message: `Environment with id '${id}' in project with ID '${projectId}' not found`,
name: "DeleteEnvironment"
});
@ -240,7 +243,7 @@ export const projectEnvServiceFactory = ({
if (!environment) {
throw new NotFoundError({
message: "Environment does not exist"
message: `Environment with ID '${id}' not found`
});
}

@ -129,7 +129,7 @@ export const projectMembershipServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
const [membership] = await projectMembershipDAL.findAllProjectMembers(projectId, { username });
if (!membership) throw new NotFoundError({ message: `Project membership not found for user ${username}` });
if (!membership) throw new NotFoundError({ message: `Project membership not found for user '${username}'` });
return membership;
};
@ -143,7 +143,7 @@ export const projectMembershipServiceFactory = ({
sendEmails = true
}: TAddUsersToWorkspaceDTO) => {
const project = await projectDAL.findById(projectId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -259,7 +259,7 @@ export const projectMembershipServiceFactory = ({
})
: [];
if (customRoles.length !== customInputRoles.length) {
throw new NotFoundError({ message: "Custom project roles not found" });
throw new NotFoundError({ message: "One or more custom roles not found" });
}
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
@ -352,7 +352,7 @@ export const projectMembershipServiceFactory = ({
if (!project) {
throw new NotFoundError({
message: "Project not found"
message: `Project with ID '${projectId}' not found`
});
}
@ -426,7 +426,7 @@ export const projectMembershipServiceFactory = ({
}
const project = await projectDAL.findById(projectId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
if (project.version === ProjectVersion.V1) {
throw new BadRequestError({
@ -437,7 +437,7 @@ export const projectMembershipServiceFactory = ({
const projectMembers = await projectMembershipDAL.findAllProjectMembers(projectId);
if (!projectMembers?.length) {
throw new NotFoundError({ message: "Failed to find project members" });
throw new NotFoundError({ message: `Project members not found for project with ID '${projectId}'` });
}
if (projectMembers.length < 2) {

@ -43,7 +43,7 @@ export const projectRoleServiceFactory = ({
}: TProjectRoleServiceFactoryDep) => {
const createRole = async ({ projectSlug, data, actor, actorId, actorAuthMethod, actorOrgId }: TCreateRoleDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -75,7 +75,7 @@ export const projectRoleServiceFactory = ({
roleSlug
}: TGetRoleBySlugDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -92,7 +92,7 @@ export const projectRoleServiceFactory = ({
}
const customRole = await projectRoleDAL.findOne({ slug: roleSlug, projectId });
if (!customRole) throw new NotFoundError({ message: "Project role not found" });
if (!customRole) throw new NotFoundError({ message: `Project role with slug '${roleSlug}' not found` });
return { ...customRole, permissions: unpackPermissions(customRole.permissions) };
};
@ -106,7 +106,7 @@ export const projectRoleServiceFactory = ({
data
}: TUpdateRoleDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -131,13 +131,17 @@ export const projectRoleServiceFactory = ({
permissions: data.permissions ? data.permissions : undefined
}
);
if (!updatedRole) throw new NotFoundError({ message: "Project role not found", name: "Update role" });
if (!updatedRole) {
throw new NotFoundError({
message: `Project role with ID '${roleId}' in project with ID '${projectId}' not found`
});
}
return { ...updatedRole, permissions: unpackPermissions(updatedRole.permissions) };
};
const deleteRole = async ({ actor, actorId, actorAuthMethod, actorOrgId, projectSlug, roleId }: TDeleteRoleDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new NotFoundError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
const projectId = project.id;
const { permission } = await permissionService.getProjectPermission(
@ -166,7 +170,12 @@ export const projectRoleServiceFactory = ({
}
const [deletedRole] = await projectRoleDAL.delete({ id: roleId, projectId });
if (!deletedRole) throw new NotFoundError({ message: "Project role not found", name: "Delete role" });
if (!deletedRole) {
throw new NotFoundError({
message: `Project role with ID '${roleId}' in project with ID '${projectId}' not found`,
name: "DeleteRole"
});
}
return { ...deletedRole, permissions: unpackPermissions(deletedRole.permissions) };
};

@ -186,7 +186,7 @@ export const projectDALFactory = (db: TDbClient) => {
})?.[0];
if (!project) {
throw new NotFoundError({ message: "Project not found" });
throw new NotFoundError({ message: `Project with ID '${id}' not found` });
}
return project;
@ -235,7 +235,7 @@ export const projectDALFactory = (db: TDbClient) => {
})?.[0];
if (!project) {
throw new NotFoundError({ message: "Project not found" });
throw new NotFoundError({ message: `Project with slug '${slug}' not found` });
}
return project;
@ -295,7 +295,7 @@ export const projectDALFactory = (db: TDbClient) => {
.first();
if (!project) {
throw new NotFoundError({ message: "Project not found" });
throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
}
return {

@ -75,7 +75,7 @@ export const getProjectKmsCertificateKeyId = async ({
const keyId = await projectDAL.transaction(async (tx) => {
const project = await projectDAL.findOne({ id: projectId }, tx);
if (!project) {
throw new NotFoundError({ message: "Project not found" });
throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
}
if (!project.kmsCertificateKeyId) {

@ -327,7 +327,7 @@ export const projectServiceFactory = ({
// If identity org membership not found, throw error
if (!identityOrgMembership) {
throw new NotFoundError({
message: `Failed to find identity with id ${actorId}`
message: `Failed to find identity with id '${actorId}'`
});
}
@ -496,7 +496,7 @@ export const projectServiceFactory = ({
const project = await projectDAL.findProjectBySlug(workspaceSlug, actorOrgId);
if (!project) {
throw new NotFoundError({
message: "Project not found"
message: `Project with slug '${workspaceSlug}' not found`
});
}
@ -527,7 +527,7 @@ export const projectServiceFactory = ({
const project = await projectDAL.findProjectBySlug(workspaceSlug, actorOrgId);
if (!project) {
throw new NotFoundError({
message: "Project not found."
message: `Project with slug '${workspaceSlug}' not found`
});
}
@ -634,7 +634,7 @@ export const projectServiceFactory = ({
if (!project) {
throw new NotFoundError({
message: `Project with id ${projectId} not found`
message: `Project with ID '${projectId}' not found`
});
}
@ -933,7 +933,7 @@ export const projectServiceFactory = ({
const project = await projectDAL.findById(projectId);
if (!project) {
throw new NotFoundError({
message: "Project not found"
message: `Project with ID '${projectId}' not found`
});
}
@ -967,14 +967,21 @@ export const projectServiceFactory = ({
const project = await projectDAL.findById(projectId);
if (!project) {
throw new NotFoundError({
message: "Project not found"
message: `Project with ID '${projectId}' not found`
});
}
const slackIntegration = await slackIntegrationDAL.findByIdWithWorkflowIntegrationDetails(slackIntegrationId);
if (!slackIntegration) {
throw new NotFoundError({
message: "Slack integration not found"
message: `Slack integration with ID '${slackIntegrationId}' not found`
});
}
if (slackIntegration.orgId !== actorOrgId) {
throw new ForbiddenRequestError({
message: "Selected slack integration is not in the same organization"
});
}

@ -79,13 +79,15 @@ export const secretBlindIndexServiceFactory = ({
}
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg) throw new NotFoundError({ message: "Blind index not found", name: "CreateSecret" });
if (!blindIndexCfg)
throw new NotFoundError({ message: `Blind index for project with ID '${projectId}' not found` });
const secrets = await secretBlindIndexDAL.findSecretsByProjectId(
projectId,
secretsToUpdate.map(({ secretId }) => secretId)
);
if (secrets.length !== secretsToUpdate.length) throw new NotFoundError({ message: "Secret not found" });
if (secrets.length !== secretsToUpdate.length)
throw new NotFoundError({ message: "One or more secrets to update not found" });
const operations = await Promise.all(
secretsToUpdate.map(async ({ secretName, secretId: id }) => {

@ -76,7 +76,11 @@ export const secretFolderServiceFactory = ({
}
const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new NotFoundError({ message: "Environment not found", name: "Create folder" });
if (!env) {
throw new NotFoundError({
message: `Environment with slug '${environment}' in project with ID '${projectId}' not found`
});
}
const folder = await folderDAL.transaction(async (tx) => {
// the logic is simple we need to avoid creating same folder in same path multiple times
@ -86,7 +90,11 @@ export const secretFolderServiceFactory = ({
const pathWithFolder = path.join(secretPath, name);
const parentFolder = await folderDAL.findClosestFolder(projectId, environment, pathWithFolder, tx);
// no folder found is not possible root should be their
if (!parentFolder) throw new NotFoundError({ message: "Secret path not found" });
if (!parentFolder) {
throw new NotFoundError({
message: `Folder with path '${pathWithFolder}' in environment with slug '${environment}' not found`
});
}
// exact folder
if (parentFolder.path === pathWithFolder) return parentFolder;
@ -149,7 +157,7 @@ export const secretFolderServiceFactory = ({
}: TUpdateManyFoldersDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) {
throw new NotFoundError({ message: "Project not found" });
throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
}
const { permission } = await permissionService.getProjectPermission(
@ -184,12 +192,18 @@ export const secretFolderServiceFactory = ({
const parentFolder = await folderDAL.findBySecretPath(project.id, environment, secretPath);
if (!parentFolder) {
throw new NotFoundError({ message: "Secret path not found", name: "Batch update folder" });
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`,
name: "UpdateManyFolders"
});
}
const env = await projectEnvDAL.findOne({ projectId: project.id, slug: environment });
if (!env) {
throw new NotFoundError({ message: "Environment not found", name: "Batch update folder" });
throw new NotFoundError({
message: `Environment with slug '${environment}' in project with ID '${project.id}' not found`,
name: "UpdateManyFolders"
});
}
const folder = await folderDAL
.findOne({ envId: env.id, id, parentId: parentFolder.id })
@ -198,7 +212,10 @@ export const secretFolderServiceFactory = ({
.catch(() => folderDAL.findOne({ envId: env.id, name: id, parentId: parentFolder.id }));
if (!folder) {
throw new NotFoundError({ message: "Folder not found" });
throw new NotFoundError({
message: `Folder with id '${id}' in environment with slug '${env.slug}' not found`,
name: "UpdateManyFolders"
});
}
if (name !== folder.name) {
// ensure that new folder name is unique
@ -231,7 +248,10 @@ export const secretFolderServiceFactory = ({
tx
);
if (!doc) {
throw new NotFoundError({ message: "Folder not found", name: "Batch update folder" });
throw new NotFoundError({
message: `Failed to update folder with id '${id}', not found`,
name: "UpdateManyFolders"
});
}
return { oldFolder: folder, newFolder: doc };
@ -283,17 +303,23 @@ export const secretFolderServiceFactory = ({
}
const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!parentFolder) throw new NotFoundError({ message: "Secret path not found" });
if (!parentFolder)
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`,
name: "UpdateFolder"
});
const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new NotFoundError({ message: "Environment not found", name: "Update folder" });
if (!env) {
throw new NotFoundError({ message: `Environment with slug '${environment}' not found`, name: "UpdateFolder" });
}
const folder = await folderDAL
.findOne({ envId: env.id, id, parentId: parentFolder.id, isReserved: false })
// now folder api accepts id based change
// this is for cli backward compatiability and when cli removes this, we will remove this logic
.catch(() => folderDAL.findOne({ envId: env.id, name: id, parentId: parentFolder.id }));
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) throw new NotFoundError({ message: `Folder with ID '${id}' not found`, name: "UpdateFolder" });
if (name !== folder.name) {
// ensure that new folder name is unique
const folderToCheck = await folderDAL.findOne({
@ -305,7 +331,7 @@ export const secretFolderServiceFactory = ({
if (folderToCheck) {
throw new BadRequestError({
message: "Folder with specified name already exists",
name: "Update folder"
name: "UpdateFolder"
});
}
}
@ -325,7 +351,7 @@ export const secretFolderServiceFactory = ({
},
tx
);
if (!doc) throw new NotFoundError({ message: "Folder not found", name: "Update folder" });
if (!doc) throw new NotFoundError({ message: `Failed to update folder with ID '${id}'`, name: "UpdateFolder" });
return doc;
});
@ -367,11 +393,14 @@ export const secretFolderServiceFactory = ({
}
const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new NotFoundError({ message: "Environment not found", name: "Create folder" });
if (!env) throw new NotFoundError({ message: `Environment with slug '${environment}' not found` });
const folder = await folderDAL.transaction(async (tx) => {
const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath, tx);
if (!parentFolder) throw new NotFoundError({ message: "Secret path not found" });
if (!parentFolder)
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`
});
const [doc] = await folderDAL.delete(
{
@ -382,7 +411,7 @@ export const secretFolderServiceFactory = ({
},
tx
);
if (!doc) throw new NotFoundError({ message: "Folder not found", name: "Delete folder" });
if (!doc) throw new NotFoundError({ message: `Failed to delete folder with ID '${idOrName}', not found` });
return doc;
});
@ -409,7 +438,7 @@ export const secretFolderServiceFactory = ({
await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new NotFoundError({ message: "Environment not found", name: "get folders" });
if (!env) throw new NotFoundError({ message: `Environment with slug '${environment}' not found` });
const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!parentFolder) return [];
@ -448,7 +477,10 @@ export const secretFolderServiceFactory = ({
const envs = await projectEnvDAL.findBySlugs(projectId, environments);
if (!envs.length)
throw new NotFoundError({ message: "Environment(s) not found", name: "get project folder count" });
throw new NotFoundError({
message: `Environments '${environments.join(", ")}' not found`,
name: "GetFoldersMultiEnv"
});
const parentFolders = await folderDAL.findBySecretPathMultiEnv(projectId, environments, secretPath);
if (!parentFolders.length) return [];
@ -479,8 +511,7 @@ export const secretFolderServiceFactory = ({
const envs = await projectEnvDAL.findBySlugs(projectId, environments);
if (!envs.length)
throw new NotFoundError({ message: "Environment(s) not found", name: "get project folder count" });
if (!envs.length) throw new NotFoundError({ message: `Environments '${environments.join(", ")}' not found` });
const parentFolders = await folderDAL.findBySecretPathMultiEnv(projectId, environments, secretPath);
if (!parentFolders.length) return 0;
@ -502,7 +533,7 @@ export const secretFolderServiceFactory = ({
const getFolderById = async ({ actor, actorId, actorOrgId, actorAuthMethod, id }: TGetFolderByIdDTO) => {
const folder = await folderDAL.findById(id);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) throw new NotFoundError({ message: `Folder with ID '${id}' not found` });
// folder list is allowed to be read by anyone
// permission to check does user has access
await permissionService.getProjectPermission(actor, actorId, folder.projectId, actorAuthMethod, actorOrgId);
@ -510,7 +541,9 @@ export const secretFolderServiceFactory = ({
const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(folder.projectId, [folder.id]);
if (!folderWithPath) {
throw new NotFoundError({ message: "Folder path not found" });
throw new NotFoundError({
message: `Folder with ID '${folder.id}' in project with ID '${folder.projectId}' not found`
});
}
return {

@ -107,10 +107,17 @@ export const secretImportServiceFactory = ({
await projectDAL.checkProjectUpgradeStatus(projectId);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) throw new NotFoundError({ message: "Folder not found", name: "Create import" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`
});
const [importEnv] = await projectEnvDAL.findBySlugs(projectId, [data.environment]);
if (!importEnv) throw new NotFoundError({ error: "Imported env not found", name: "Create import" });
if (!importEnv) {
throw new NotFoundError({
error: `Imported environment with slug '${data.environment}' in project with ID '${projectId}' not found`
});
}
const sourceFolder = await folderDAL.findBySecretPath(projectId, data.environment, data.path);
if (sourceFolder) {
@ -119,7 +126,7 @@ export const secretImportServiceFactory = ({
importEnv: folder.environment.id,
importPath: secretPath
});
if (existingImport) throw new NotFoundError({ message: "Cyclic import not allowed" });
if (existingImport) throw new BadRequestError({ message: `Cyclic import not allowed` });
}
const secImport = await secretImportDAL.transaction(async (tx) => {
@ -195,7 +202,11 @@ export const secretImportServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) throw new NotFoundError({ message: "Folder not found", name: "Update import" });
if (!folder) {
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`
});
}
const secImpDoc = await secretImportDAL.findOne({ folderId: folder.id, id });
if (!secImpDoc) throw ERR_SEC_IMP_NOT_FOUND;
@ -203,7 +214,11 @@ export const secretImportServiceFactory = ({
const importedEnv = data.environment // this is get env information of new one or old one
? (await projectEnvDAL.findBySlugs(projectId, [data.environment]))?.[0]
: await projectEnvDAL.findById(secImpDoc.importEnv);
if (!importedEnv) throw new NotFoundError({ error: "Imported env not found", name: "Create import" });
if (!importedEnv) {
throw new NotFoundError({
error: `Imported environment with slug '${data.environment}' in project with ID '${projectId}' not found`
});
}
const sourceFolder = await folderDAL.findBySecretPath(
projectId,
@ -216,7 +231,7 @@ export const secretImportServiceFactory = ({
importEnv: folder.environment.id,
importPath: secretPath
});
if (existingImport) throw new NotFoundError({ message: "Cyclic import not allowed" });
if (existingImport) throw new BadRequestError({ message: "Cyclic import not allowed" });
}
const updatedSecImport = await secretImportDAL.transaction(async (tx) => {
@ -281,11 +296,14 @@ export const secretImportServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) throw new NotFoundError({ message: "Folder not found", name: "Delete import" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`
});
const secImport = await secretImportDAL.transaction(async (tx) => {
const [doc] = await secretImportDAL.delete({ folderId: folder.id, id }, tx);
if (!doc) throw new NotFoundError({ message: "Secret import not found" });
if (!doc) throw new NotFoundError({ message: `Secret import with folder ID '${id}' not found` });
if (doc.isReplication) {
const replicationFolderPath = path.join(secretPath, getReplicationFolderName(doc.id));
const replicatedFolder = await folderDAL.findBySecretPath(projectId, environment, replicationFolderPath, tx);
@ -307,7 +325,11 @@ export const secretImportServiceFactory = ({
}
const importEnv = await projectEnvDAL.findById(doc.importEnv);
if (!importEnv) throw new NotFoundError({ error: "Imported env not found" });
if (!importEnv) {
throw new NotFoundError({
error: `Imported environment with ID '${doc.importEnv}' in project with ID '${projectId}' not found`
});
}
return { ...doc, importEnv };
});
@ -354,13 +376,18 @@ export const secretImportServiceFactory = ({
}
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder) {
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`
});
}
const [secretImportDoc] = await secretImportDAL.find({
folderId: folder.id,
[`${TableName.SecretImport}.id` as "id"]: secretImportDocId
});
if (!secretImportDoc) throw new NotFoundError({ message: "Failed to find secret import" });
if (!secretImportDoc)
throw new NotFoundError({ message: `Secret import with ID '${secretImportDocId}' not found` });
if (!secretImportDoc.isReplication) throw new BadRequestError({ message: "Import is not in replication mode" });
@ -418,7 +445,10 @@ export const secretImportServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) throw new NotFoundError({ message: "Folder not found", name: "Get imports" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`
});
const count = await secretImportDAL.getProjectImportCount({ folderId: folder.id, search });
@ -450,7 +480,10 @@ export const secretImportServiceFactory = ({
);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) throw new NotFoundError({ message: "Folder not found" });
if (!folder)
throw new NotFoundError({
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`
});
const secImports = await secretImportDAL.find({ folderId: folder.id, search, limit, offset });
return secImports;
@ -466,18 +499,22 @@ export const secretImportServiceFactory = ({
const importDoc = await secretImportDAL.findById(importId);
if (!importDoc) {
throw new NotFoundError({ message: "Secret import not found" });
throw new NotFoundError({ message: `Secret import with ID '${importId}' not found` });
}
// the folder to import into
const folder = await folderDAL.findById(importDoc.folderId);
if (!folder) throw new NotFoundError({ message: "Secret import folder not found" });
if (!folder) throw new NotFoundError({ message: `Secret import folder with ID '${importDoc.folderId}' not found` });
// the folder to import into, with path
const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(folder.projectId, [folder.id]);
if (!folderWithPath) throw new NotFoundError({ message: "Folder path not found" });
if (!folderWithPath) {
throw new NotFoundError({
message: `Folder with ID '${folder.id}' in project with ID ${folder.projectId} not found`
});
}
const { permission } = await permissionService.getProjectPermission(
actor,
@ -500,7 +537,11 @@ export const secretImportServiceFactory = ({
slug: folder.environment.envSlug
});
if (!importIntoEnv) throw new NotFoundError({ message: "Environment to import into not found" });
if (!importIntoEnv) {
throw new NotFoundError({
message: `Environment with slug '${folder.environment.envSlug}' in project with ID ${folder.projectId} not found`
});
}
return {
...importDoc,
@ -606,7 +647,7 @@ export const secretImportServiceFactory = ({
if (!botKey)
throw new NotFoundError({
message: "Project bot not found. Please upgrade your project.",
message: `Project bot not found for project with ID '${projectId}'. Please upgrade your project.`,
name: "bot_not_found_error"
});

@ -199,7 +199,7 @@ export const secretSharingServiceFactory = ({
if (!sharedSecret)
throw new NotFoundError({
message: "Shared secret not found"
message: `Shared secret with ID '${sharedSecretId}' not found`
});
const { accessType, expiresAt, expiresAfterViews } = sharedSecret;

@ -47,7 +47,7 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe
const updateTag = async ({ actorId, actor, actorOrgId, actorAuthMethod, id, color, slug }: TUpdateTagDTO) => {
const tag = await secretTagDAL.findById(id);
if (!tag) throw new NotFoundError({ message: "Tag not found" });
if (!tag) throw new NotFoundError({ message: `Tag with ID '${id}' not found` });
if (slug) {
const existingTag = await secretTagDAL.findOne({ slug, projectId: tag.projectId });
@ -69,7 +69,7 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe
const deleteTag = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteTagDTO) => {
const tag = await secretTagDAL.findById(id);
if (!tag) throw new NotFoundError({ message: "Tag not found" });
if (!tag) throw new NotFoundError({ message: `Tag with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -86,7 +86,7 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe
const getTagById = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TGetTagByIdDTO) => {
const tag = await secretTagDAL.findById(id);
if (!tag) throw new NotFoundError({ message: "Tag not found" });
if (!tag) throw new NotFoundError({ message: `Tag with ID '${id}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,
@ -102,7 +102,7 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe
const getTagBySlug = async ({ actorId, actor, actorOrgId, actorAuthMethod, slug, projectId }: TGetTagBySlugDTO) => {
const tag = await secretTagDAL.findOne({ projectId, slug });
if (!tag) throw new NotFoundError({ message: "Tag not found" });
if (!tag) throw new NotFoundError({ message: `Tag with slug '${slug}' not found` });
const { permission } = await permissionService.getProjectPermission(
actor,

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