mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 16:40:30 +00:00
Merge branch 'main' into feat/allowShareToAnyoneEdition
This commit is contained in:
@@ -21,3 +21,10 @@ export const slugSchema = ({ min = 1, max = 32, field = "Slug" }: SlugSchemaInpu
|
||||
message: `${field} field can only contain lowercase letters, numbers, and hyphens`
|
||||
});
|
||||
};
|
||||
|
||||
export const GenericResourceNameSchema = z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "Name must be at least 1 character" })
|
||||
.max(64, { message: "Name must be 64 or fewer characters" })
|
||||
.regex(/^[a-zA-Z0-9\-_\s]+$/, "Name can only contain alphanumeric characters, dashes, underscores, and spaces");
|
||||
|
||||
@@ -635,6 +635,7 @@ export const registerRoutes = async (
|
||||
});
|
||||
const superAdminService = superAdminServiceFactory({
|
||||
userDAL,
|
||||
identityDAL,
|
||||
userAliasDAL,
|
||||
authService: loginService,
|
||||
serverCfgDAL: superAdminDAL,
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ProjectRolesSchema,
|
||||
ProjectsSchema,
|
||||
SecretApprovalPoliciesSchema,
|
||||
SecretTagsSchema,
|
||||
UsersSchema
|
||||
} from "@app/db/schemas";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
@@ -241,3 +242,11 @@ export const SanitizedProjectSchema = ProjectsSchema.pick({
|
||||
kmsCertificateKeyId: true,
|
||||
auditLogsRetentionDays: true
|
||||
});
|
||||
|
||||
export const SanitizedTagSchema = SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
}).extend({
|
||||
name: z.string()
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import DOMPurify from "isomorphic-dompurify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { OrganizationsSchema, SuperAdminSchema, UsersSchema } from "@app/db/schemas";
|
||||
import { IdentitiesSchema, OrganizationsSchema, SuperAdminSchema, UsersSchema } from "@app/db/schemas";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
@@ -118,7 +118,12 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
|
||||
querystring: z.object({
|
||||
searchTerm: z.string().default(""),
|
||||
offset: z.coerce.number().default(0),
|
||||
limit: z.coerce.number().max(100).default(20)
|
||||
limit: z.coerce.number().max(100).default(20),
|
||||
// TODO: remove this once z.coerce.boolean() is supported
|
||||
adminsOnly: z
|
||||
.string()
|
||||
.transform((val) => val === "true")
|
||||
.default("false")
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -149,6 +154,43 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/identity-management/identities",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
querystring: z.object({
|
||||
searchTerm: z.string().default(""),
|
||||
offset: z.coerce.number().default(0),
|
||||
limit: z.coerce.number().max(100).default(20)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
identities: IdentitiesSchema.pick({
|
||||
name: true,
|
||||
id: true
|
||||
}).array()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: (req, res, done) => {
|
||||
verifyAuth([AuthMode.JWT])(req, res, () => {
|
||||
verifySuperAdmin(req, res, done);
|
||||
});
|
||||
},
|
||||
handler: async (req) => {
|
||||
const identities = await server.services.superAdmin.getIdentities({
|
||||
...req.query
|
||||
});
|
||||
|
||||
return {
|
||||
identities
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/integrations/slack/config",
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { ForbiddenError, subject } from "@casl/ability";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ActionProjectType, SecretFoldersSchema, SecretImportsSchema, SecretTagsSchema } from "@app/db/schemas";
|
||||
import { ActionProjectType, SecretFoldersSchema, SecretImportsSchema } from "@app/db/schemas";
|
||||
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import {
|
||||
ProjectPermissionDynamicSecretActions,
|
||||
ProjectPermissionSecretActions,
|
||||
ProjectPermissionSub
|
||||
} from "@app/ee/services/permission/project-permission";
|
||||
import { DASHBOARD } from "@app/lib/api-docs";
|
||||
@@ -15,7 +16,7 @@ import { secretsLimit } from "@app/server/config/rateLimiter";
|
||||
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
|
||||
import { getUserAgentType } from "@app/server/plugins/audit-log";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { SanitizedDynamicSecretSchema, secretRawSchema } from "@app/server/routes/sanitizedSchemas";
|
||||
import { SanitizedDynamicSecretSchema, SanitizedTagSchema, secretRawSchema } from "@app/server/routes/sanitizedSchemas";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { ResourceMetadataSchema } from "@app/services/resource-metadata/resource-metadata-schema";
|
||||
import { SecretsOrderBy } from "@app/services/secret/secret-types";
|
||||
@@ -116,16 +117,10 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
dynamicSecrets: SanitizedDynamicSecretSchema.extend({ environment: z.string() }).array().optional(),
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretValueHidden: z.boolean(),
|
||||
secretPath: z.string().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional()
|
||||
tags: SanitizedTagSchema.array().optional()
|
||||
})
|
||||
.array()
|
||||
.optional(),
|
||||
@@ -294,6 +289,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
|
||||
if (remainingLimit > 0 && totalSecretCount > adjustedOffset) {
|
||||
secrets = await server.services.secret.getSecretsRawMultiEnv({
|
||||
viewSecretValue: true,
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
@@ -393,6 +389,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
.optional(),
|
||||
search: z.string().trim().describe(DASHBOARD.SECRET_DETAILS_LIST.search).optional(),
|
||||
tags: z.string().trim().transform(decodeURIComponent).describe(DASHBOARD.SECRET_DETAILS_LIST.tags).optional(),
|
||||
viewSecretValue: booleanSchema.default(true),
|
||||
includeSecrets: booleanSchema.describe(DASHBOARD.SECRET_DETAILS_LIST.includeSecrets),
|
||||
includeFolders: booleanSchema.describe(DASHBOARD.SECRET_DETAILS_LIST.includeFolders),
|
||||
includeDynamicSecrets: booleanSchema.describe(DASHBOARD.SECRET_DETAILS_LIST.includeDynamicSecrets),
|
||||
@@ -410,16 +407,10 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
dynamicSecrets: SanitizedDynamicSecretSchema.array().optional(),
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretValueHidden: z.boolean(),
|
||||
secretPath: z.string().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional()
|
||||
tags: SanitizedTagSchema.array().optional()
|
||||
})
|
||||
.array()
|
||||
.optional(),
|
||||
@@ -601,23 +592,25 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
});
|
||||
|
||||
if (remainingLimit > 0 && totalSecretCount > adjustedOffset) {
|
||||
const secretsRaw = await server.services.secret.getSecretsRaw({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
environment,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
projectId,
|
||||
path: secretPath,
|
||||
orderBy,
|
||||
orderDirection,
|
||||
search,
|
||||
limit: remainingLimit,
|
||||
offset: adjustedOffset,
|
||||
tagSlugs: tags
|
||||
});
|
||||
|
||||
secrets = secretsRaw.secrets;
|
||||
secrets = (
|
||||
await server.services.secret.getSecretsRaw({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
viewSecretValue: req.query.viewSecretValue,
|
||||
throwOnMissingReadValuePermission: false,
|
||||
actorOrgId: req.permission.orgId,
|
||||
environment,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
projectId,
|
||||
path: secretPath,
|
||||
orderBy,
|
||||
orderDirection,
|
||||
search,
|
||||
limit: remainingLimit,
|
||||
offset: adjustedOffset,
|
||||
tagSlugs: tags
|
||||
})
|
||||
).secrets;
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId,
|
||||
@@ -696,16 +689,10 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
.optional(),
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretValueHidden: z.boolean(),
|
||||
secretPath: z.string().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional()
|
||||
tags: SanitizedTagSchema.array().optional()
|
||||
})
|
||||
.array()
|
||||
.optional()
|
||||
@@ -749,6 +736,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
|
||||
const secrets = await server.services.secret.getSecretsRawByFolderMappings(
|
||||
{
|
||||
filterByAction: ProjectPermissionSecretActions.DescribeSecret,
|
||||
projectId,
|
||||
folderMappings,
|
||||
filters: {
|
||||
@@ -846,6 +834,52 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/accessible-secrets",
|
||||
config: {
|
||||
rateLimit: secretsLimit
|
||||
},
|
||||
schema: {
|
||||
querystring: z.object({
|
||||
projectId: z.string().trim(),
|
||||
environment: z.string().trim(),
|
||||
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||
filterByAction: z
|
||||
.enum([ProjectPermissionSecretActions.DescribeSecret, ProjectPermissionSecretActions.ReadValue])
|
||||
.default(ProjectPermissionSecretActions.ReadValue)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretPath: z.string().optional(),
|
||||
secretValueHidden: z.boolean()
|
||||
})
|
||||
.array()
|
||||
.optional()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const { projectId, environment, secretPath, filterByAction } = req.query;
|
||||
|
||||
const { secrets } = await server.services.secret.getAccessibleSecrets({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
environment,
|
||||
secretPath,
|
||||
projectId,
|
||||
filterByAction
|
||||
});
|
||||
|
||||
return { secrets };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/secrets-by-keys",
|
||||
@@ -862,22 +896,17 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
projectId: z.string().trim(),
|
||||
environment: z.string().trim(),
|
||||
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||
keys: z.string().trim().transform(decodeURIComponent)
|
||||
keys: z.string().trim().transform(decodeURIComponent),
|
||||
viewSecretValue: booleanSchema.default(false)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretValueHidden: z.boolean(),
|
||||
secretPath: z.string().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional()
|
||||
tags: SanitizedTagSchema.array().optional()
|
||||
})
|
||||
.array()
|
||||
.optional()
|
||||
@@ -886,7 +915,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const { secretPath, projectId, environment } = req.query;
|
||||
const { secretPath, projectId, environment, viewSecretValue } = req.query;
|
||||
|
||||
const keys = req.query.keys?.split(",").filter((key) => Boolean(key.trim())) ?? [];
|
||||
if (!keys.length) throw new BadRequestError({ message: "One or more keys required" });
|
||||
@@ -895,6 +924,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
viewSecretValue,
|
||||
environment,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
projectId,
|
||||
|
||||
@@ -91,7 +91,6 @@ export const registerV1Routes = async (server: FastifyZodProvider) => {
|
||||
await projectRouter.register(registerProjectMembershipRouter);
|
||||
await projectRouter.register(registerSecretTagRouter);
|
||||
},
|
||||
|
||||
{ prefix: "/workspace" }
|
||||
);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-t
|
||||
import { AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs";
|
||||
import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { slugSchema } from "@app/server/lib/schemas";
|
||||
import { GenericResourceNameSchema, slugSchema } from "@app/server/lib/schemas";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { ActorType, AuthMode, MfaMethod } from "@app/services/auth/auth-type";
|
||||
import { sanitizedOrganizationSchema } from "@app/services/org/org-schema";
|
||||
@@ -251,7 +251,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
schema: {
|
||||
params: z.object({ organizationId: z.string().trim() }),
|
||||
body: z.object({
|
||||
name: z.string().trim().max(64, { message: "Name must be 64 or fewer characters" }).optional(),
|
||||
name: GenericResourceNameSchema.optional(),
|
||||
slug: slugSchema({ max: 64 }).optional(),
|
||||
authEnforced: z.boolean().optional(),
|
||||
scimEnabled: z.boolean().optional(),
|
||||
|
||||
@@ -6,6 +6,7 @@ import { authRateLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { validateSignUpAuthorization } from "@app/services/auth/auth-fns";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { UserEncryption } from "@app/services/user/user-types";
|
||||
|
||||
export const registerPasswordRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -113,20 +114,16 @@ export const registerPasswordRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
message: z.string(),
|
||||
user: UsersSchema,
|
||||
token: z.string()
|
||||
token: z.string(),
|
||||
userEncryptionVersion: z.nativeEnum(UserEncryption)
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const { token, user } = await server.services.password.verifyPasswordResetEmail(req.body.email, req.body.code);
|
||||
const passwordReset = await server.services.password.verifyPasswordResetEmail(req.body.email, req.body.code);
|
||||
|
||||
return {
|
||||
message: "Successfully verified email",
|
||||
user,
|
||||
token
|
||||
};
|
||||
return passwordReset;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,10 +2,12 @@ import { z } from "zod";
|
||||
|
||||
import {
|
||||
IntegrationsSchema,
|
||||
ProjectEnvironmentsSchema,
|
||||
ProjectMembershipsSchema,
|
||||
ProjectRolesSchema,
|
||||
ProjectSlackConfigsSchema,
|
||||
ProjectType,
|
||||
SecretFoldersSchema,
|
||||
UserEncryptionKeysSchema,
|
||||
UsersSchema
|
||||
} from "@app/db/schemas";
|
||||
@@ -675,4 +677,31 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
return slackConfig;
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:workspaceId/environment-folder-tree",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
workspaceId: z.string().trim()
|
||||
}),
|
||||
response: {
|
||||
200: z.record(
|
||||
ProjectEnvironmentsSchema.extend({ folders: SecretFoldersSchema.extend({ path: z.string() }).array() })
|
||||
)
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const environmentsFolders = await server.services.folder.getProjectEnvironmentsFolders(
|
||||
req.params.workspaceId,
|
||||
req.permission
|
||||
);
|
||||
|
||||
return environmentsFolders;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import { registerIdentityOrgRouter } from "./identity-org-router";
|
||||
import { registerIdentityProjectRouter } from "./identity-project-router";
|
||||
import { registerMfaRouter } from "./mfa-router";
|
||||
import { registerOrgRouter } from "./organization-router";
|
||||
import { registerPasswordRouter } from "./password-router";
|
||||
import { registerProjectMembershipRouter } from "./project-membership-router";
|
||||
import { registerProjectRouter } from "./project-router";
|
||||
import { registerServiceTokenRouter } from "./service-token-router";
|
||||
@@ -12,6 +13,7 @@ export const registerV2Routes = async (server: FastifyZodProvider) => {
|
||||
await server.register(registerMfaRouter, { prefix: "/auth" });
|
||||
await server.register(registerUserRouter, { prefix: "/users" });
|
||||
await server.register(registerServiceTokenRouter, { prefix: "/service-token" });
|
||||
await server.register(registerPasswordRouter, { prefix: "/password" });
|
||||
await server.register(
|
||||
async (orgRouter) => {
|
||||
await orgRouter.register(registerOrgRouter);
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { ORGANIZATIONS } from "@app/lib/api-docs";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { GenericResourceNameSchema } from "@app/server/lib/schemas";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
@@ -330,7 +331,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
schema: {
|
||||
body: z.object({
|
||||
name: z.string().trim()
|
||||
name: GenericResourceNameSchema
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { authRateLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { validatePasswordResetAuthorization } from "@app/services/auth/auth-fns";
|
||||
import { ResetPasswordV2Type } from "@app/services/auth/auth-password-type";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
export const registerPasswordRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/password-reset",
|
||||
config: {
|
||||
rateLimit: authRateLimit
|
||||
},
|
||||
schema: {
|
||||
body: z.object({
|
||||
newPassword: z.string().trim()
|
||||
})
|
||||
},
|
||||
handler: async (req) => {
|
||||
const token = validatePasswordResetAuthorization(req.headers.authorization);
|
||||
await server.services.password.resetPasswordV2({
|
||||
type: ResetPasswordV2Type.Recovery,
|
||||
newPassword: req.body.newPassword,
|
||||
userId: token.userId
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/user/password-reset",
|
||||
schema: {
|
||||
body: z.object({
|
||||
oldPassword: z.string().trim(),
|
||||
newPassword: z.string().trim()
|
||||
})
|
||||
},
|
||||
config: {
|
||||
rateLimit: authRateLimit
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT], { requireOrg: false }),
|
||||
handler: async (req) => {
|
||||
await server.services.password.resetPasswordV2({
|
||||
type: ResetPasswordV2Type.LoggedInReset,
|
||||
userId: req.permission.id,
|
||||
newPassword: req.body.newPassword,
|
||||
oldPassword: req.body.oldPassword
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,13 +1,7 @@
|
||||
import picomatch from "picomatch";
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
SecretApprovalRequestsSchema,
|
||||
SecretsSchema,
|
||||
SecretTagsSchema,
|
||||
SecretType,
|
||||
ServiceTokenScopes
|
||||
} from "@app/db/schemas";
|
||||
import { SecretApprovalRequestsSchema, SecretsSchema, SecretType, ServiceTokenScopes } from "@app/db/schemas";
|
||||
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { RAW_SECRETS, SECRETS } from "@app/lib/api-docs";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
@@ -23,7 +17,7 @@ import { SecretOperations, SecretProtectionType } from "@app/services/secret/sec
|
||||
import { SecretUpdateMode } from "@app/services/secret-v2-bridge/secret-v2-bridge-types";
|
||||
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
||||
|
||||
import { secretRawSchema } from "../sanitizedSchemas";
|
||||
import { SanitizedTagSchema, secretRawSchema } from "../sanitizedSchemas";
|
||||
|
||||
const SecretReferenceNode = z.object({
|
||||
key: z.string(),
|
||||
@@ -31,6 +25,14 @@ const SecretReferenceNode = z.object({
|
||||
environment: z.string(),
|
||||
secretPath: z.string()
|
||||
});
|
||||
|
||||
const convertStringBoolean = (defaultValue: boolean = false) => {
|
||||
return z
|
||||
.enum(["true", "false"])
|
||||
.default(defaultValue ? "true" : "false")
|
||||
.transform((value) => value === "true");
|
||||
};
|
||||
|
||||
type TSecretReferenceNode = z.infer<typeof SecretReferenceNode> & { children: TSecretReferenceNode[] };
|
||||
|
||||
const SecretReferenceNodeTree: z.ZodType<TSecretReferenceNode> = SecretReferenceNode.extend({
|
||||
@@ -75,17 +77,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).merge(
|
||||
z.object({
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
})
|
||||
)
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).extend({
|
||||
tags: SanitizedTagSchema.array()
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -139,13 +133,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).extend({
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
tags: SanitizedTagSchema.array()
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -247,21 +235,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
workspaceSlug: z.string().trim().optional().describe(RAW_SECRETS.LIST.workspaceSlug),
|
||||
environment: z.string().trim().optional().describe(RAW_SECRETS.LIST.environment),
|
||||
secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.LIST.secretPath),
|
||||
expandSecretReferences: z
|
||||
.enum(["true", "false"])
|
||||
.default("false")
|
||||
.transform((value) => value === "true")
|
||||
.describe(RAW_SECRETS.LIST.expand),
|
||||
recursive: z
|
||||
.enum(["true", "false"])
|
||||
.default("false")
|
||||
.transform((value) => value === "true")
|
||||
.describe(RAW_SECRETS.LIST.recursive),
|
||||
include_imports: z
|
||||
.enum(["true", "false"])
|
||||
.default("false")
|
||||
.transform((value) => value === "true")
|
||||
.describe(RAW_SECRETS.LIST.includeImports),
|
||||
viewSecretValue: convertStringBoolean(true).describe(RAW_SECRETS.LIST.viewSecretValue),
|
||||
expandSecretReferences: convertStringBoolean().describe(RAW_SECRETS.LIST.expand),
|
||||
recursive: convertStringBoolean().describe(RAW_SECRETS.LIST.recursive),
|
||||
include_imports: convertStringBoolean().describe(RAW_SECRETS.LIST.includeImports),
|
||||
tagSlugs: z
|
||||
.string()
|
||||
.describe(RAW_SECRETS.LIST.tagSlugs)
|
||||
@@ -274,15 +251,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretPath: z.string().optional(),
|
||||
secretValueHidden: z.boolean(),
|
||||
secretMetadata: ResourceMetadataSchema.optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional()
|
||||
tags: SanitizedTagSchema.array().optional()
|
||||
})
|
||||
.array(),
|
||||
imports: z
|
||||
@@ -293,6 +264,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secrets: secretRawSchema
|
||||
.omit({ createdAt: true, updatedAt: true })
|
||||
.extend({
|
||||
secretValueHidden: z.boolean(),
|
||||
secretMetadata: ResourceMetadataSchema.optional()
|
||||
})
|
||||
.array()
|
||||
@@ -342,6 +314,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
expandSecretReferences: req.query.expandSecretReferences,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
projectId: workspaceId,
|
||||
viewSecretValue: req.query.viewSecretValue,
|
||||
path: secretPath,
|
||||
metadataFilter: req.query.metadataFilter,
|
||||
includeImports: req.query.include_imports,
|
||||
@@ -376,6 +349,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return { secrets, imports };
|
||||
}
|
||||
});
|
||||
@@ -394,14 +368,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
200: z.object({
|
||||
secret: secretRawSchema.extend({
|
||||
secretPath: z.string(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional(),
|
||||
tags: SanitizedTagSchema.array().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.optional()
|
||||
})
|
||||
})
|
||||
@@ -445,28 +412,15 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.GET.secretPath),
|
||||
version: z.coerce.number().optional().describe(RAW_SECRETS.GET.version),
|
||||
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.GET.type),
|
||||
expandSecretReferences: z
|
||||
.enum(["true", "false"])
|
||||
.default("false")
|
||||
.transform((value) => value === "true")
|
||||
.describe(RAW_SECRETS.GET.expand),
|
||||
include_imports: z
|
||||
.enum(["true", "false"])
|
||||
.default("false")
|
||||
.transform((value) => value === "true")
|
||||
.describe(RAW_SECRETS.GET.includeImports)
|
||||
viewSecretValue: convertStringBoolean(true).describe(RAW_SECRETS.GET.viewSecretValue),
|
||||
expandSecretReferences: convertStringBoolean().describe(RAW_SECRETS.GET.expand),
|
||||
include_imports: convertStringBoolean().describe(RAW_SECRETS.GET.includeImports)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
secret: secretRawSchema.extend({
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional(),
|
||||
secretValueHidden: z.boolean(),
|
||||
tags: SanitizedTagSchema.array().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.optional()
|
||||
})
|
||||
})
|
||||
@@ -498,6 +452,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
expandSecretReferences: req.query.expandSecretReferences,
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
viewSecretValue: req.query.viewSecretValue,
|
||||
projectSlug: workspaceSlug,
|
||||
path: secretPath,
|
||||
secretName: req.params.secretName,
|
||||
@@ -704,7 +659,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secret: secretRawSchema
|
||||
secret: secretRawSchema.extend({
|
||||
secretValueHidden: z.boolean()
|
||||
})
|
||||
}),
|
||||
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||
])
|
||||
@@ -800,7 +757,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secret: secretRawSchema
|
||||
secret: secretRawSchema.extend({
|
||||
secretValueHidden: z.boolean()
|
||||
})
|
||||
}),
|
||||
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||
])
|
||||
@@ -822,6 +781,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||
return { approval: secretOperation.approval };
|
||||
}
|
||||
|
||||
const { secret } = secretOperation;
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
@@ -884,13 +844,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
workspace: z.string(),
|
||||
environment: z.string(),
|
||||
secretPath: z.string().optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
tags: SanitizedTagSchema.array()
|
||||
})
|
||||
.array(),
|
||||
imports: z
|
||||
@@ -986,10 +940,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
||||
version: z.coerce.number().optional(),
|
||||
include_imports: z
|
||||
.enum(["true", "false"])
|
||||
.default("false")
|
||||
.transform((value) => value === "true")
|
||||
include_imports: convertStringBoolean()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -1260,6 +1211,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).merge(
|
||||
z.object({
|
||||
secretValueHidden: z.boolean(),
|
||||
_id: z.string(),
|
||||
workspace: z.string(),
|
||||
environment: z.string()
|
||||
@@ -1429,13 +1381,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).merge(
|
||||
z.object({
|
||||
_id: z.string(),
|
||||
workspace: z.string(),
|
||||
environment: z.string()
|
||||
})
|
||||
)
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).extend({
|
||||
_id: z.string(),
|
||||
secretValueHidden: z.boolean(),
|
||||
workspace: z.string(),
|
||||
environment: z.string()
|
||||
})
|
||||
}),
|
||||
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||
])
|
||||
@@ -1747,7 +1698,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secrets: SecretsSchema.omit({ secretBlindIndex: true }).array()
|
||||
secrets: SecretsSchema.omit({ secretBlindIndex: true }).extend({ secretValueHidden: z.boolean() }).array()
|
||||
}),
|
||||
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||
])
|
||||
@@ -1862,7 +1813,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secrets: SecretsSchema.omit({ secretBlindIndex: true }).array()
|
||||
secrets: SecretsSchema.omit({ secretBlindIndex: true })
|
||||
.extend({
|
||||
secretValueHidden: z.boolean()
|
||||
})
|
||||
.array()
|
||||
}),
|
||||
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||
])
|
||||
@@ -2124,7 +2079,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secrets: secretRawSchema.array()
|
||||
secrets: secretRawSchema.extend({ secretValueHidden: z.boolean() }).array()
|
||||
}),
|
||||
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||
])
|
||||
@@ -2246,7 +2201,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secrets: secretRawSchema.array()
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretValueHidden: z.boolean()
|
||||
})
|
||||
.array()
|
||||
}),
|
||||
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||
])
|
||||
|
||||
@@ -4,6 +4,7 @@ import { UsersSchema } from "@app/db/schemas";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { ForbiddenRequestError } from "@app/lib/errors";
|
||||
import { authRateLimit } from "@app/server/config/rateLimiter";
|
||||
import { GenericResourceNameSchema } from "@app/server/lib/schemas";
|
||||
import { getServerCfg } from "@app/services/super-admin/super-admin-service";
|
||||
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
||||
|
||||
@@ -100,7 +101,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => {
|
||||
encryptedPrivateKeyTag: z.string().trim(),
|
||||
salt: z.string().trim(),
|
||||
verifier: z.string().trim(),
|
||||
organizationName: z.string().trim().min(1),
|
||||
organizationName: GenericResourceNameSchema,
|
||||
providerAuthToken: z.string().trim().optional().nullish(),
|
||||
attributionSource: z.string().trim().optional(),
|
||||
password: z.string()
|
||||
|
||||
Reference in New Issue
Block a user