Compare commits

..

7 Commits

Author SHA1 Message Date
Tuan Dang
c621592807 Add .pem loader to tsup 2024-03-14 09:31:58 -07:00
BlackMagiq
bd400a6196 Merge pull request #1569 from Infisical/render-integration
Add pagination to getAppsRender
2024-03-14 09:30:42 -07:00
Tuan Dang
a93c2d9236 Add pagination to getAppsRender 2024-03-14 09:24:04 -07:00
BlackMagiq
bb6e09a895 Merge pull request #1568 from Infisical/license-docs
Add simple docs for Infisical EE
2024-03-13 18:07:46 -07:00
Tuan Dang
715b193a8e Add simple docs for Infisical EE 2024-03-13 18:05:13 -07:00
BlackMagiq
57be493da8 Merge pull request #1567 from Infisical/offline-license
Add EE license support for air-gapped / offline environments
2024-03-13 17:25:35 -07:00
Tuan Dang
cc731fe031 Add EE license support for air-gapped / offline environments 2024-03-13 17:18:55 -07:00
33 changed files with 314 additions and 561 deletions

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas";
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
import { AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs";
import { removeTrailingSlash } from "@app/lib/fn";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -20,13 +19,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.workspaceId)
workspaceId: z.string().trim()
}),
querystring: z.object({
environment: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(PROJECTS.GET_SNAPSHOTS.path),
offset: z.coerce.number().default(0).describe(PROJECTS.GET_SNAPSHOTS.offset),
limit: z.coerce.number().default(20).describe(PROJECTS.GET_SNAPSHOTS.limit)
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash),
offset: z.coerce.number().default(0),
limit: z.coerce.number().default(20)
}),
response: {
200: z.object({
@@ -90,16 +89,16 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
workspaceId: z.string().trim().describe(AUDIT_LOGS.EXPORT.workspaceId)
workspaceId: z.string().trim()
}),
querystring: z.object({
eventType: z.nativeEnum(EventType).optional().describe(AUDIT_LOGS.EXPORT.eventType),
userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType),
startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate),
endDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.endDate),
offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset),
limit: z.coerce.number().default(20).describe(AUDIT_LOGS.EXPORT.limit),
actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor)
eventType: z.nativeEnum(EventType).optional(),
userAgentType: z.nativeEnum(UserAgentType).optional(),
startDate: z.string().datetime().optional(),
endDate: z.string().datetime().optional(),
offset: z.coerce.number().default(0),
limit: z.coerce.number().default(20),
actor: z.string().optional()
}),
response: {
200: z.object({

View File

@@ -1,7 +1,6 @@
import { z } from "zod";
import { SecretSnapshotsSchema, SecretTagsSchema, SecretVersionsSchema } from "@app/db/schemas";
import { PROJECTS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -66,7 +65,7 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
secretSnapshotId: z.string().trim().describe(PROJECTS.ROLLBACK_TO_SNAPSHOT.secretSnapshotId)
secretSnapshotId: z.string().trim()
}),
response: {
200: z.object({

View File

@@ -8,6 +8,7 @@ import { ForbiddenError } from "@casl/ability";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { verifyOfflineLicense } from "@app/lib/crypto";
import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { TOrgDALFactory } from "@app/services/org/org-dal";
@@ -26,6 +27,7 @@ import {
TFeatureSet,
TGetOrgBillInfoDTO,
TGetOrgTaxIdDTO,
TOfflineLicenseContents,
TOrgInvoiceDTO,
TOrgLicensesDTO,
TOrgPlanDTO,
@@ -96,6 +98,36 @@ export const licenseServiceFactory = ({
}
return;
}
if (appCfg.LICENSE_KEY_OFFLINE) {
let isValidOfflineLicense = true;
const contents: TOfflineLicenseContents = JSON.parse(
Buffer.from(appCfg.LICENSE_KEY_OFFLINE, "base64").toString("utf8")
);
const isVerified = await verifyOfflineLicense(JSON.stringify(contents.license), contents.signature);
if (!isVerified) {
isValidOfflineLicense = false;
logger.warn(`Infisical EE offline license verification failed`);
}
if (contents.license.terminatesAt) {
const terminationDate = new Date(contents.license.terminatesAt);
if (terminationDate < new Date()) {
isValidOfflineLicense = false;
logger.warn(`Infisical EE offline license has expired`);
}
}
if (isValidOfflineLicense) {
onPremFeatures = contents.license.features;
instanceType = InstanceType.EnterpriseOnPrem;
logger.info(`Instance type: ${InstanceType.EnterpriseOnPrem}`);
isValidLicense = true;
return;
}
}
// this means this is self hosted oss version
// else it would reach catch statement
isValidLicense = true;

View File

@@ -6,6 +6,21 @@ export enum InstanceType {
Cloud = "cloud"
}
export type TOfflineLicenseContents = {
license: TOfflineLicense;
signature: string;
};
export type TOfflineLicense = {
issuedTo: string;
licenseId: string;
customerId: string | null;
issuedAt: string;
expiresAt: string | null;
terminatesAt: string | null;
features: TFeatureSet;
};
export type TFeatureSet = {
_id: null;
slug: null;

View File

@@ -1,286 +0,0 @@
export const IDENTITIES = {
CREATE: {
name: "The name of the identity to create.",
organizationId: "The organization ID to which the identity belongs.",
role: "The role of the identity. Possible values are 'no-access', 'member', and 'admin'."
},
UPDATE: {
identityId: "The ID of the identity to update.",
name: "The new name of the identity.",
role: "The new role of the identity."
},
DELETE: {
identityId: "The ID of the identity to delete."
}
} as const;
export const UNIVERSAL_AUTH = {
LOGIN: {
clientId: "Your Machine Identity Client ID.",
clientSecret: "Your Machine Identity Client Secret."
},
ATTACH: {
identityId: "The ID of the identity to attach the configuration onto.",
clientSecretTrustedIps:
"A list of IPs or CIDR ranges that the Client Secret can be used from together with the Client ID to get back an access token. You can use 0.0.0.0/0, to allow usage from any network address.",
accessTokenTrustedIps:
"A list of IPs or CIDR ranges that access tokens can be used from. You can use 0.0.0.0/0, to allow usage from any network address.",
accessTokenTTL: "The lifetime for an access token in seconds. This value will be referenced at renewal time.",
accessTokenMaxTTL:
"The maximum lifetime for an access token in seconds. This value will be referenced at renewal time.",
accessTokenNumUsesLimit:
"The maximum number of times that an access token can be used; a value of 0 implies infinite number of uses."
},
RETRIEVE: {
identityId: "The ID of the identity to retrieve."
},
UPDATE: {
identityId: "The ID of the identity to update.",
clientSecretTrustedIps: "The new list of IPs or CIDR ranges that the Client Secret can be used from.",
accessTokenTrustedIps: "The new list of IPs or CIDR ranges that access tokens can be used from.",
accessTokenTTL: "The new lifetime for an access token in seconds.",
accessTokenMaxTTL: "The new maximum lifetime for an access token in seconds.",
accessTokenNumUsesLimit: "The new maximum number of times that an access token can be used."
},
CREATE_CLIENT_SECRET: {
identityId: "The ID of the identity to create a client secret for.",
description: "The description of the client secret.",
numUsesLimit:
"The maximum number of times that the client secret can be used; a value of 0 implies infinite number of uses.",
ttl: "The lifetime for the client secret in seconds."
},
LIST_CLIENT_SECRETS: {
identityId: "The ID of the identity to list client secrets for."
},
REVOKE_CLIENT_SECRET: {
identityId: "The ID of the identity to revoke the client secret from.",
clientSecretId: "The ID of the client secret to revoke."
},
RENEW_ACCESS_TOKEN: {
accessToken: "The access token to renew."
}
} as const;
export const ORGANIZATIONS = {
LIST_USER_MEMBERSHIPS: {
organizationId: "The ID of the organization to get memberships from."
},
UPDATE_USER_MEMBERSHIP: {
organizationId: "The ID of the organization to update the membership for.",
membershipId: "The ID of the membership to update.",
role: "The new role of the membership."
},
DELETE_USER_MEMBERSHIP: {
organizationId: "The ID of the organization to delete the membership from.",
membershipId: "The ID of the membership to delete."
},
LIST_IDENTITY_MEMBERSHIPS: {
orgId: "The ID of the organization to get identity memberships from."
},
GET_PROJECTS: {
organizationId: "The ID of the organization to get projects from."
}
} as const;
export const PROJECTS = {
CREATE: {
organizationId: "The ID of the organization to create the project in.",
projectName: "The name of the project to create.",
slug: "An optional slug for the project."
},
DELETE: {
workspaceId: "The ID of the project to delete."
},
GET: {
workspaceId: "The ID of the project."
},
UPDATE: {
workspaceId: "The ID of the project to update.",
name: "The new name of the project.",
autoCapitalization: "Disable or enable auto-capitalization for the project."
},
INVITE_MEMBER: {
projectId: "The ID of the project to invite the member to.",
emails: "A list of organization member emails to invite to the project.",
usernames: "A list of usernames to invite to the project."
},
REMOVE_MEMBER: {
projectId: "The ID of the project to remove the member from.",
emails: "A list of organization member emails to remove from the project.",
usernames: "A list of usernames to remove from the project."
},
GET_USER_MEMBERSHIPS: {
workspaceId: "The ID of the project to get memberships from."
},
UPDATE_USER_MEMBERSHIP: {
workspaceId: "The ID of the project to update the membership for.",
membershipId: "The ID of the membership to update.",
roles: "A list of roles to update the membership to."
},
LIST_IDENTITY_MEMBERSHIPS: {
projectId: "The ID of the project to get identity memberships from."
},
UPDATE_IDENTITY_MEMBERSHIP: {
projectId: "The ID of the project to update the identity membership for.",
identityId: "The ID of the identity to update the membership for.",
roles: "A list of roles to update the membership to."
},
DELETE_IDENTITY_MEMBERSHIP: {
projectId: "The ID of the project to delete the identity membership from.",
identityId: "The ID of the identity to delete the membership from."
},
GET_KEY: {
workspaceId: "The ID of the project to get the key from."
},
GET_SNAPSHOTS: {
workspaceId: "The ID of the project to get snapshots from.",
environment: "The environment to get snapshots from.",
path: "The secret path to get snapshots from.",
offset: "The offset to start from. If you enter 10, it will start from the 10th snapshot.",
limit: "The number of snapshots to return."
},
ROLLBACK_TO_SNAPSHOT: {
secretSnapshotId: "The ID of the snapshot to rollback to."
}
} as const;
export const ENVIRONMENTS = {
CREATE: {
workspaceId: "The ID of the project to create the environment in.",
name: "The name of the environment to create.",
slug: "The slug of the environment to create."
},
UPDATE: {
workspaceId: "The ID of the project to update the environment in.",
id: "The ID of the environment to update.",
name: "The new name of the environment.",
slug: "The new slug of the environment.",
position: "The new position of the environment. The lowest number will be displayed as the first environment."
},
DELETE: {
workspaceId: "The ID of the project to delete the environment from.",
id: "The ID of the environment to delete."
}
} as const;
export const FOLDERS = {
LIST: {
workspaceId: "The ID of the project to list folders from.",
environment: "The slug of the environment to list folders from.",
path: "The path to list folders from.",
directory: "The directory to list folders from. (Deprecated in favor of path)"
},
CREATE: {
workspaceId: "The ID of the project to create the folder in.",
environment: "The slug of the environment to create the folder in.",
name: "The name of the folder to create.",
path: "The path of the folder to create.",
directory: "The directory of the folder to create. (Deprecated in favor of path)"
},
UPDATE: {
folderId: "The ID of the folder to update.",
environment: "The slug of the environment where the folder is located.",
name: "The new name of the folder.",
path: "The path of the folder to update.",
directory: "The new directory of the folder to update. (Deprecated in favor of path)",
workspaceId: "The ID of the project where the folder is located."
},
DELETE: {
folderIdOrName: "The ID or name of the folder to delete.",
workspaceId: "The ID of the project to delete the folder from.",
environment: "The slug of the environment where the folder is located.",
directory: "The directory of the folder to delete. (Deprecated in favor of path)",
path: "The path of the folder to delete."
}
} as const;
export const RAW_SECRETS = {
LIST: {
workspaceId: "The ID of the project to list secrets from.",
environment: "The slug of the environment to list secrets from.",
secretPath: "The secret path to list secrets from.",
includeImports: "Weather to include imported secrets or not."
},
CREATE: {
secretName: "The name of the secret to create.",
environment: "The slug of the environment to create the secret in.",
secretComment: "Attach a comment to the secret.",
secretPath: "The path to create the secret in.",
secretValue: "The value of the secret to create.",
skipMultilineEncoding: "Skip multiline encoding for the secret value.",
type: "The type of the secret to create.",
workspaceId: "The ID of the project to create the secret in."
},
GET: {
secretName: "The name of the secret to get.",
workspaceId: "The ID of the project to get the secret from.",
environment: "The slug of the environment to get the secret from.",
secretPath: "The path of the secret to get.",
version: "The version of the secret to get.",
type: "The type of the secret to get.",
includeImports: "Weather to include imported secrets or not."
},
UPDATE: {
secretName: "The name of the secret to update.",
environment: "The slug of the environment where the secret is located.",
secretPath: "The path of the secret to update",
secretValue: "The new value of the secret.",
skipMultilineEncoding: "Skip multiline encoding for the secret value.",
type: "The type of the secret to update.",
workspaceId: "The ID of the project to update the secret in."
},
DELETE: {
secretName: "The name of the secret to delete.",
environment: "The slug of the environment where the secret is located.",
secretPath: "The path of the secret.",
type: "The type of the secret to delete.",
workspaceId: "The ID of the project where the secret is located."
}
} as const;
export const SECRET_IMPORTS = {
LIST: {
workspaceId: "The ID of the project to list secret imports from.",
environment: "The slug of the environment to list secret imports from.",
path: "The path to list secret imports from."
},
CREATE: {
environment: "The slug of the environment to import into.",
path: "The path to import into.",
workspaceId: "The ID of the project you are working in.",
import: {
environment: "The slug of the environment to import from.",
path: "The path to import from."
}
},
UPDATE: {
secretImportId: "The ID of the secret import to update.",
environment: "The slug of the environment where the secret import is located.",
import: {
environment: "The new environment slug to import from.",
path: "The new path to import from.",
position: "The new position of the secret import. The lowest number will be displayed as the first import."
},
path: "The path of the secret import to update.",
workspaceId: "The ID of the project where the secret import is located."
},
DELETE: {
workspaceId: "The ID of the project to delete the secret import from.",
secretImportId: "The ID of the secret import to delete.",
environment: "The slug of the environment where the secret import is located.",
path: "The path of the secret import to delete."
}
} as const;
export const AUDIT_LOGS = {
EXPORT: {
workspaceId: "The ID of the project to export audit logs from.",
eventType: "The type of the event to export.",
userAgentType: "Choose which consuming application to export audit logs for.",
startDate: "The date to start the export from.",
endDate: "The date to end the export at.",
offset: "The offset to start from. If you enter 10, it will start from the 10th audit log.",
limit: "The number of audit logs to return.",
actor: "The actor to filter the audit logs by."
}
} as const;

View File

@@ -1 +0,0 @@
export * from "./constants";

View File

@@ -106,6 +106,7 @@ const envSchema = z
LICENSE_SERVER_URL: zpStr(z.string().optional().default("https://portal.infisical.com")),
LICENSE_SERVER_KEY: zpStr(z.string().optional()),
LICENSE_KEY: zpStr(z.string().optional()),
LICENSE_KEY_OFFLINE: zpStr(z.string().optional()),
// GENERIC
STANDALONE_MODE: z

View File

@@ -17,4 +17,5 @@ export {
decryptSecrets,
decryptSecretVersions
} from "./secret-encryption";
export { verifyOfflineLicense } from "./signing";
export { generateSrpServerKey, srpCheckClientProof } from "./srp";

View File

@@ -0,0 +1,8 @@
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEApchBY3BXTu4zWGBguB7nM/pjpVLY3V7VGZOAxmR5ueQTJOwiGM13
5HN3EM9fDlQnZu9VSc0OFqRM/bUeUaI1oLPE6WzTHjdHyKjDI/S+TLx3VGEsvhM1
uukZpYX+3KX2w4wzRHBaBWyglFy0CVNth9UJhhpD+KKfv7dzcRmsbyoUWi9wGfJu
wLYCwaCwZRXIt1sLGmMncPz14vfwdnm2a5Tj1Jbt0GTyBl+1/ZqLbO6SsslLg2G+
o7FfGS9z8OUTkvDdu16qxL+p2wCEFZMnOz5BB4oakuT2gS9iOO2l5AOPcT4WzPzy
PYbX3d7cN9BkOY9I5z0cX4wzqHjQTvGNLQIDAQAB
-----END RSA PUBLIC KEY-----

View File

@@ -0,0 +1,22 @@
import crypto, { KeyObject } from "crypto";
import fs from "fs/promises";
import path from "path";
export const verifySignature = (data: string, signature: Buffer, publicKey: KeyObject) => {
const verify = crypto.createVerify("SHA256");
verify.update(data);
verify.end();
return verify.verify(publicKey, signature);
};
export const verifyOfflineLicense = async (licenseContents: string, signature: string) => {
const publicKeyPem = await fs.readFile(path.join(__dirname, "license_public_key.pem"), "utf8");
const publicKey = crypto.createPublicKey({
key: publicKeyPem,
format: "pem",
type: "pkcs1"
});
return verifySignature(licenseContents, Buffer.from(signature, "base64"), publicKey);
};

View File

@@ -1,7 +1,5 @@
import { z } from "zod";
import { UNIVERSAL_AUTH } from "@app/lib/api-docs";
export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/token/renew",
@@ -9,7 +7,7 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid
schema: {
description: "Renew access token",
body: z.object({
accessToken: z.string().trim().describe(UNIVERSAL_AUTH.RENEW_ACCESS_TOKEN.accessToken)
accessToken: z.string().trim()
}),
response: {
200: z.object({

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import { IdentitiesSchema, OrgMembershipRole } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { IDENTITIES } from "@app/lib/api-docs";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -21,9 +20,9 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}
],
body: z.object({
name: z.string().trim().describe(IDENTITIES.CREATE.name),
organizationId: z.string().trim().describe(IDENTITIES.CREATE.organizationId),
role: z.string().trim().min(1).default(OrgMembershipRole.NoAccess).describe(IDENTITIES.CREATE.role)
name: z.string().trim(),
organizationId: z.string().trim(),
role: z.string().trim().min(1).default(OrgMembershipRole.NoAccess)
}),
response: {
200: z.object({
@@ -79,11 +78,11 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().describe(IDENTITIES.UPDATE.identityId)
identityId: z.string()
}),
body: z.object({
name: z.string().trim().optional().describe(IDENTITIES.UPDATE.name),
role: z.string().trim().min(1).optional().describe(IDENTITIES.UPDATE.role)
name: z.string().trim().optional(),
role: z.string().trim().min(1).optional()
}),
response: {
200: z.object({
@@ -128,7 +127,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().describe(IDENTITIES.DELETE.identityId)
identityId: z.string()
}),
response: {
200: z.object({

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import { IdentityUaClientSecretsSchema, IdentityUniversalAuthsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { UNIVERSAL_AUTH } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { TIdentityTrustedIp } from "@app/services/identity/identity-types";
@@ -27,8 +26,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
schema: {
description: "Login with Universal Auth",
body: z.object({
clientId: z.string().trim().describe(UNIVERSAL_AUTH.LOGIN.clientId),
clientSecret: z.string().trim().describe(UNIVERSAL_AUTH.LOGIN.clientSecret)
clientId: z.string().trim(),
clientSecret: z.string().trim()
}),
response: {
200: z.object({
@@ -77,7 +76,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().trim().describe(UNIVERSAL_AUTH.ATTACH.identityId)
identityId: z.string().trim()
}),
body: z.object({
clientSecretTrustedIps: z
@@ -86,16 +85,14 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
})
.array()
.min(1)
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }])
.describe(UNIVERSAL_AUTH.ATTACH.clientSecretTrustedIps),
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
accessTokenTrustedIps: z
.object({
ipAddress: z.string().trim()
})
.array()
.min(1)
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }])
.describe(UNIVERSAL_AUTH.ATTACH.accessTokenTrustedIps),
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
accessTokenTTL: z
.number()
.int()
@@ -103,22 +100,15 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
.refine((value) => value !== 0, {
message: "accessTokenTTL must have a non zero number"
})
.default(2592000)
.describe(UNIVERSAL_AUTH.ATTACH.accessTokenTTL), // 30 days
.default(2592000),
accessTokenMaxTTL: z
.number()
.int()
.refine((value) => value !== 0, {
message: "accessTokenMaxTTL must have a non zero number"
})
.default(2592000)
.describe(UNIVERSAL_AUTH.ATTACH.accessTokenMaxTTL), // 30 days
accessTokenNumUsesLimit: z
.number()
.int()
.min(0)
.default(0)
.describe(UNIVERSAL_AUTH.ATTACH.accessTokenNumUsesLimit)
.default(2592000), // 30 days
accessTokenNumUsesLimit: z.number().int().min(0).default(0)
}),
response: {
200: z.object({
@@ -166,7 +156,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().describe(UNIVERSAL_AUTH.UPDATE.identityId)
identityId: z.string()
}),
body: z.object({
clientSecretTrustedIps: z
@@ -175,23 +165,16 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
})
.array()
.min(1)
.optional()
.describe(UNIVERSAL_AUTH.UPDATE.clientSecretTrustedIps),
.optional(),
accessTokenTrustedIps: z
.object({
ipAddress: z.string().trim()
})
.array()
.min(1)
.optional()
.describe(UNIVERSAL_AUTH.UPDATE.accessTokenTrustedIps),
accessTokenTTL: z.number().int().min(0).optional().describe(UNIVERSAL_AUTH.UPDATE.accessTokenTTL),
accessTokenNumUsesLimit: z
.number()
.int()
.min(0)
.optional()
.describe(UNIVERSAL_AUTH.UPDATE.accessTokenNumUsesLimit),
.optional(),
accessTokenTTL: z.number().int().min(0).optional(),
accessTokenNumUsesLimit: z.number().int().min(0).optional(),
accessTokenMaxTTL: z
.number()
.int()
@@ -199,7 +182,6 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
message: "accessTokenMaxTTL must have a non zero number"
})
.optional()
.describe(UNIVERSAL_AUTH.UPDATE.accessTokenMaxTTL)
}),
response: {
200: z.object({
@@ -248,7 +230,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().describe(UNIVERSAL_AUTH.RETRIEVE.identityId)
identityId: z.string()
}),
response: {
200: z.object({
@@ -291,12 +273,12 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.identityId)
identityId: z.string()
}),
body: z.object({
description: z.string().trim().default("").describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.description),
numUsesLimit: z.number().min(0).default(0).describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.numUsesLimit),
ttl: z.number().min(0).default(0).describe(UNIVERSAL_AUTH.CREATE_CLIENT_SECRET.ttl)
description: z.string().trim().default(""),
numUsesLimit: z.number().min(0).default(0),
ttl: z.number().min(0).default(0)
}),
response: {
200: z.object({
@@ -342,7 +324,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().describe(UNIVERSAL_AUTH.LIST_CLIENT_SECRETS.identityId)
identityId: z.string()
}),
response: {
200: z.object({
@@ -384,8 +366,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
identityId: z.string().describe(UNIVERSAL_AUTH.REVOKE_CLIENT_SECRET.identityId),
clientSecretId: z.string().describe(UNIVERSAL_AUTH.REVOKE_CLIENT_SECRET.clientSecretId)
identityId: z.string(),
clientSecretId: z.string()
}),
response: {
200: z.object({

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import { ProjectEnvironmentsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ENVIRONMENTS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -19,11 +18,11 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
workspaceId: z.string().trim().describe(ENVIRONMENTS.CREATE.workspaceId)
workspaceId: z.string().trim()
}),
body: z.object({
name: z.string().trim().describe(ENVIRONMENTS.CREATE.name),
slug: z.string().trim().describe(ENVIRONMENTS.CREATE.slug)
name: z.string().trim(),
slug: z.string().trim()
}),
response: {
200: z.object({
@@ -74,13 +73,13 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
workspaceId: z.string().trim().describe(ENVIRONMENTS.UPDATE.workspaceId),
id: z.string().trim().describe(ENVIRONMENTS.UPDATE.id)
workspaceId: z.string().trim(),
id: z.string().trim()
}),
body: z.object({
slug: z.string().trim().optional().describe(ENVIRONMENTS.UPDATE.slug),
name: z.string().trim().optional().describe(ENVIRONMENTS.UPDATE.name),
position: z.number().optional().describe(ENVIRONMENTS.UPDATE.position)
slug: z.string().trim().optional(),
name: z.string().trim().optional(),
position: z.number().optional()
}),
response: {
200: z.object({
@@ -137,8 +136,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
workspaceId: z.string().trim().describe(ENVIRONMENTS.DELETE.workspaceId),
id: z.string().trim().describe(ENVIRONMENTS.DELETE.id)
workspaceId: z.string().trim(),
id: z.string().trim()
}),
response: {
200: z.object({

View File

@@ -9,7 +9,6 @@ import {
UsersSchema
} from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { PROJECTS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types";
@@ -27,7 +26,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
}
],
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET_USER_MEMBERSHIPS.workspaceId)
workspaceId: z.string().trim()
}),
response: {
200: z.object({
@@ -135,8 +134,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
}
],
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.UPDATE_USER_MEMBERSHIP.workspaceId),
membershipId: z.string().trim().describe(PROJECTS.UPDATE_USER_MEMBERSHIP.membershipId)
workspaceId: z.string().trim(),
membershipId: z.string().trim()
}),
body: z.object({
roles: z
@@ -157,7 +156,6 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
)
.min(1)
.refine((data) => data.some(({ isTemporary }) => !isTemporary), "At least long lived role is required")
.describe(PROJECTS.UPDATE_USER_MEMBERSHIP.roles)
}),
response: {
200: z.object({

View File

@@ -7,7 +7,6 @@ import {
UserEncryptionKeysSchema,
UsersSchema
} from "@app/db/schemas";
import { PROJECTS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -126,7 +125,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
method: "GET",
schema: {
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET.workspaceId)
workspaceId: z.string().trim()
}),
response: {
200: z.object({
@@ -178,7 +177,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
method: "DELETE",
schema: {
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.DELETE.workspaceId)
workspaceId: z.string().trim()
}),
response: {
200: z.object({
@@ -236,16 +235,11 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
method: "PATCH",
schema: {
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.UPDATE.workspaceId)
workspaceId: z.string().trim()
}),
body: z.object({
name: z
.string()
.trim()
.max(64, { message: "Name must be 64 or fewer characters" })
.optional()
.describe(PROJECTS.UPDATE.name),
autoCapitalization: z.boolean().optional().describe(PROJECTS.UPDATE.autoCapitalization)
name: z.string().trim().max(64, { message: "Name must be 64 or fewer characters" }).optional(),
autoCapitalization: z.boolean().optional()
}),
response: {
200: z.object({

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import { SecretFoldersSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { FOLDERS } from "@app/lib/api-docs";
import { removeTrailingSlash } from "@app/lib/fn";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -20,12 +19,12 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
}
],
body: z.object({
workspaceId: z.string().trim().describe(FOLDERS.CREATE.workspaceId),
environment: z.string().trim().describe(FOLDERS.CREATE.environment),
name: z.string().trim().describe(FOLDERS.CREATE.name),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.CREATE.path),
workspaceId: z.string().trim(),
environment: z.string().trim(),
name: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash),
// backward compatiability with cli
directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.CREATE.directory)
directory: z.string().trim().default("/").transform(removeTrailingSlash)
}),
response: {
200: z.object({
@@ -74,15 +73,15 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
],
params: z.object({
// old way this was name
folderId: z.string().describe(FOLDERS.UPDATE.folderId)
folderId: z.string()
}),
body: z.object({
workspaceId: z.string().trim().describe(FOLDERS.UPDATE.workspaceId),
environment: z.string().trim().describe(FOLDERS.UPDATE.environment),
name: z.string().trim().describe(FOLDERS.UPDATE.name),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.UPDATE.path),
workspaceId: z.string().trim(),
environment: z.string().trim(),
name: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash),
// backward compatiability with cli
directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.UPDATE.directory)
directory: z.string().trim().default("/").transform(removeTrailingSlash)
}),
response: {
200: z.object({
@@ -120,7 +119,6 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
}
});
// TODO(daniel): Expose this route in api reference and write docs for it.
server.route({
url: "/:folderIdOrName",
method: "DELETE",
@@ -133,14 +131,14 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
}
],
params: z.object({
folderIdOrName: z.string().describe(FOLDERS.DELETE.folderIdOrName)
folderIdOrName: z.string()
}),
body: z.object({
workspaceId: z.string().trim().describe(FOLDERS.DELETE.workspaceId),
environment: z.string().trim().describe(FOLDERS.DELETE.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.DELETE.path),
workspaceId: z.string().trim(),
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash),
// keep this here as cli need directory
directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.DELETE.directory)
directory: z.string().trim().default("/").transform(removeTrailingSlash)
}),
response: {
200: z.object({
@@ -189,11 +187,11 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
}
],
querystring: z.object({
workspaceId: z.string().trim().describe(FOLDERS.LIST.workspaceId),
environment: z.string().trim().describe(FOLDERS.LIST.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.LIST.path),
workspaceId: z.string().trim(),
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash),
// backward compatiability with cli
directory: z.string().trim().default("/").transform(removeTrailingSlash).describe(FOLDERS.LIST.directory)
directory: z.string().trim().default("/").transform(removeTrailingSlash)
}),
response: {
200: z.object({

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { SECRET_IMPORTS } from "@app/lib/api-docs";
import { removeTrailingSlash } from "@app/lib/fn";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -20,12 +19,12 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
}
],
body: z.object({
workspaceId: z.string().trim().describe(SECRET_IMPORTS.CREATE.workspaceId),
environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.path),
workspaceId: z.string().trim(),
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash),
import: z.object({
environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.import.environment),
path: z.string().trim().transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.import.path)
environment: z.string().trim(),
path: z.string().trim().transform(removeTrailingSlash)
})
}),
response: {
@@ -81,21 +80,20 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
}
],
params: z.object({
secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId)
secretImportId: z.string().trim()
}),
body: z.object({
workspaceId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.workspaceId),
environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path),
workspaceId: z.string().trim(),
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash),
import: z.object({
environment: z.string().trim().optional().describe(SECRET_IMPORTS.UPDATE.import.environment),
environment: z.string().trim().optional(),
path: z
.string()
.trim()
.optional()
.transform((val) => (val ? removeTrailingSlash(val) : val))
.describe(SECRET_IMPORTS.UPDATE.import.path),
position: z.number().optional().describe(SECRET_IMPORTS.UPDATE.import.position)
.transform((val) => (val ? removeTrailingSlash(val) : val)),
position: z.number().optional()
})
}),
response: {
@@ -152,12 +150,12 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
}
],
params: z.object({
secretImportId: z.string().trim().describe(SECRET_IMPORTS.DELETE.secretImportId)
secretImportId: z.string().trim()
}),
body: z.object({
workspaceId: z.string().trim().describe(SECRET_IMPORTS.DELETE.workspaceId),
environment: z.string().trim().describe(SECRET_IMPORTS.DELETE.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.DELETE.path)
workspaceId: z.string().trim(),
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash)
}),
response: {
200: z.object({
@@ -212,9 +210,9 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
}
],
querystring: z.object({
workspaceId: z.string().trim().describe(SECRET_IMPORTS.LIST.workspaceId),
environment: z.string().trim().describe(SECRET_IMPORTS.LIST.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.LIST.path)
workspaceId: z.string().trim(),
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash)
}),
response: {
200: z.object({

View File

@@ -1,7 +1,6 @@
import { z } from "zod";
import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas";
import { ORGANIZATIONS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -19,7 +18,7 @@ export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
orgId: z.string().trim().describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.orgId)
orgId: z.string().trim()
}),
response: {
200: z.object({

View File

@@ -7,7 +7,6 @@ import {
ProjectMembershipRole,
ProjectUserMembershipRolesSchema
} from "@app/db/schemas";
import { PROJECTS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types";
@@ -56,8 +55,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}
],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.UPDATE_IDENTITY_MEMBERSHIP.projectId),
identityId: z.string().trim().describe(PROJECTS.UPDATE_IDENTITY_MEMBERSHIP.identityId)
projectId: z.string().trim(),
identityId: z.string().trim()
}),
body: z.object({
roles: z
@@ -77,7 +76,6 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
])
)
.min(1)
.describe(PROJECTS.UPDATE_IDENTITY_MEMBERSHIP.roles)
}),
response: {
200: z.object({
@@ -110,8 +108,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}
],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.DELETE_IDENTITY_MEMBERSHIP.projectId),
identityId: z.string().trim().describe(PROJECTS.DELETE_IDENTITY_MEMBERSHIP.identityId)
projectId: z.string().trim(),
identityId: z.string().trim()
}),
response: {
200: z.object({
@@ -143,7 +141,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}
],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_IDENTITY_MEMBERSHIPS.projectId)
projectId: z.string().trim()
}),
response: {
200: z.object({

View File

@@ -1,7 +1,6 @@
import { z } from "zod";
import { OrganizationsSchema, OrgMembershipsSchema, UserEncryptionKeysSchema, UsersSchema } from "@app/db/schemas";
import { ORGANIZATIONS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
@@ -18,7 +17,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
organizationId: z.string().trim().describe(ORGANIZATIONS.LIST_USER_MEMBERSHIPS.organizationId)
organizationId: z.string().trim()
}),
response: {
200: z.object({
@@ -63,7 +62,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
organizationId: z.string().trim().describe(ORGANIZATIONS.GET_PROJECTS.organizationId)
organizationId: z.string().trim()
}),
response: {
200: z.object({
@@ -107,12 +106,9 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
apiKeyAuth: []
}
],
params: z.object({
organizationId: z.string().trim().describe(ORGANIZATIONS.UPDATE_USER_MEMBERSHIP.organizationId),
membershipId: z.string().trim().describe(ORGANIZATIONS.UPDATE_USER_MEMBERSHIP.membershipId)
}),
params: z.object({ organizationId: z.string().trim(), membershipId: z.string().trim() }),
body: z.object({
role: z.string().trim().describe(ORGANIZATIONS.UPDATE_USER_MEMBERSHIP.role)
role: z.string().trim()
}),
response: {
200: z.object({
@@ -146,10 +142,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
apiKeyAuth: []
}
],
params: z.object({
organizationId: z.string().trim().describe(ORGANIZATIONS.DELETE_USER_MEMBERSHIP.organizationId),
membershipId: z.string().trim().describe(ORGANIZATIONS.DELETE_USER_MEMBERSHIP.membershipId)
}),
params: z.object({ organizationId: z.string().trim(), membershipId: z.string().trim() }),
response: {
200: z.object({
membership: OrgMembershipsSchema

View File

@@ -2,7 +2,6 @@ import { z } from "zod";
import { ProjectMembershipsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { PROJECTS } from "@app/lib/api-docs";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@@ -12,11 +11,11 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
url: "/:projectId/memberships",
schema: {
params: z.object({
projectId: z.string().describe(PROJECTS.INVITE_MEMBER.projectId)
projectId: z.string().describe("The ID of the project.")
}),
body: z.object({
emails: z.string().email().array().default([]).describe(PROJECTS.INVITE_MEMBER.emails),
usernames: z.string().array().default([]).describe(PROJECTS.INVITE_MEMBER.usernames)
emails: z.string().email().array().default([]).describe("Emails of the users to add to the project."),
usernames: z.string().array().default([]).describe("Usernames of the users to add to the project.")
}),
response: {
200: z.object({
@@ -56,12 +55,12 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
url: "/:projectId/memberships",
schema: {
params: z.object({
projectId: z.string().describe(PROJECTS.REMOVE_MEMBER.projectId)
projectId: z.string().describe("The ID of the project.")
}),
body: z.object({
emails: z.string().email().array().default([]).describe(PROJECTS.REMOVE_MEMBER.emails),
usernames: z.string().array().default([]).describe(PROJECTS.REMOVE_MEMBER.usernames)
emails: z.string().email().array().default([]).describe("Emails of the users to remove from the project."),
usernames: z.string().array().default([]).describe("Usernames of the users to remove from the project.")
}),
response: {
200: z.object({

View File

@@ -3,7 +3,6 @@ import { z } from "zod";
import { ProjectKeysSchema, ProjectsSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { PROJECTS } from "@app/lib/api-docs";
import { authRateLimit } from "@app/server/config/rateLimiter";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -30,7 +29,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET_KEY.workspaceId)
workspaceId: z.string().trim()
}),
response: {
200: ProjectKeysSchema.merge(
@@ -128,7 +127,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
},
schema: {
body: z.object({
projectName: z.string().trim().describe(PROJECTS.CREATE.projectName),
projectName: z.string().trim(),
slug: z
.string()
.min(5)
@@ -136,9 +135,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
.refine((v) => slugify(v) === v, {
message: "Slug must be a valid slug"
})
.optional()
.describe(PROJECTS.CREATE.slug),
organizationId: z.string().trim().describe(PROJECTS.CREATE.organizationId)
.optional(),
organizationId: z.string().trim()
}),
response: {
200: z.object({

View File

@@ -10,7 +10,6 @@ import {
} from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { CommitType } from "@app/ee/services/secret-approval-request/secret-approval-request-types";
import { RAW_SECRETS } from "@app/lib/api-docs";
import { BadRequestError } from "@app/lib/errors";
import { removeTrailingSlash } from "@app/lib/fn";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
@@ -34,14 +33,13 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
],
querystring: z.object({
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.LIST.workspaceId),
environment: z.string().trim().optional().describe(RAW_SECRETS.LIST.environment),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.LIST.secretPath),
workspaceId: z.string().trim().optional(),
environment: z.string().trim().optional(),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
include_imports: z
.enum(["true", "false"])
.default("false")
.transform((value) => value === "true")
.describe(RAW_SECRETS.LIST.includeImports)
}),
response: {
200: z.object({
@@ -125,19 +123,18 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
secretName: z.string().trim().describe(RAW_SECRETS.GET.secretName)
secretName: z.string().trim()
}),
querystring: z.object({
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.GET.workspaceId),
environment: z.string().trim().optional().describe(RAW_SECRETS.GET.environment),
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),
workspaceId: z.string().trim().optional(),
environment: z.string().trim().optional(),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
version: z.coerce.number().optional(),
type: z.nativeEnum(SecretType).default(SecretType.Shared),
include_imports: z
.enum(["true", "false"])
.default("false")
.transform((value) => value === "true")
.describe(RAW_SECRETS.GET.includeImports)
}),
response: {
200: z.object({
@@ -216,24 +213,16 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
secretName: z.string().trim().describe(RAW_SECRETS.CREATE.secretName)
secretName: z.string().trim()
}),
body: z.object({
workspaceId: z.string().trim().describe(RAW_SECRETS.CREATE.workspaceId),
environment: z.string().trim().describe(RAW_SECRETS.CREATE.environment),
secretPath: z
.string()
.trim()
.default("/")
.transform(removeTrailingSlash)
.describe(RAW_SECRETS.CREATE.secretPath),
secretValue: z
.string()
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim()))
.describe(RAW_SECRETS.CREATE.secretValue),
secretComment: z.string().trim().optional().default("").describe(RAW_SECRETS.CREATE.secretComment),
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.CREATE.skipMultilineEncoding),
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.CREATE.type)
workspaceId: z.string().trim(),
environment: z.string().trim(),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
secretValue: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
secretComment: z.string().trim().optional().default(""),
skipMultilineEncoding: z.boolean().optional(),
type: z.nativeEnum(SecretType).default(SecretType.Shared)
}),
response: {
200: z.object({
@@ -301,23 +290,15 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
secretName: z.string().trim().describe(RAW_SECRETS.UPDATE.secretName)
secretName: z.string().trim()
}),
body: z.object({
workspaceId: z.string().trim().describe(RAW_SECRETS.UPDATE.workspaceId),
environment: z.string().trim().describe(RAW_SECRETS.UPDATE.environment),
secretValue: z
.string()
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim()))
.describe(RAW_SECRETS.UPDATE.secretValue),
secretPath: z
.string()
.trim()
.default("/")
.transform(removeTrailingSlash)
.describe(RAW_SECRETS.UPDATE.secretPath),
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.UPDATE.skipMultilineEncoding),
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.UPDATE.type)
workspaceId: z.string().trim(),
environment: z.string().trim(),
secretValue: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
skipMultilineEncoding: z.boolean().optional(),
type: z.nativeEnum(SecretType).default(SecretType.Shared)
}),
response: {
200: z.object({
@@ -383,18 +364,13 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}
],
params: z.object({
secretName: z.string().trim().describe(RAW_SECRETS.DELETE.secretName)
secretName: z.string().trim()
}),
body: z.object({
workspaceId: z.string().trim().describe(RAW_SECRETS.DELETE.workspaceId),
environment: z.string().trim().describe(RAW_SECRETS.DELETE.environment),
secretPath: z
.string()
.trim()
.default("/")
.transform(removeTrailingSlash)
.describe(RAW_SECRETS.DELETE.secretPath),
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.DELETE.type)
workspaceId: z.string().trim(),
environment: z.string().trim(),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
type: z.nativeEnum(SecretType).default(SecretType.Shared)
}),
response: {
200: z.object({

View File

@@ -260,20 +260,44 @@ const getAppsGithub = async ({ accessToken }: { accessToken: string }) => {
* Return list of services for Render integration
*/
const getAppsRender = async ({ accessToken }: { accessToken: string }) => {
const res = (
await request.get<{ service: { name: string; id: string } }[]>(`${IntegrationUrls.RENDER_API_URL}/v1/services`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json",
"Accept-Encoding": "application/json"
}
})
).data;
const apps: Array<{ name: string; appId: string }> = [];
let hasMorePages = true;
const perPage = 100;
let cursor;
const apps = res.map((a) => ({
name: a.service.name,
appId: a.service.id
}));
interface RenderService {
cursor: string;
service: { name: string; id: string };
}
while (hasMorePages) {
const res: RenderService[] = (
await request.get<RenderService[]>(`${IntegrationUrls.RENDER_API_URL}/v1/services`, {
params: new URLSearchParams({
...(cursor ? { cursor: String(cursor) } : {}),
limit: String(perPage)
}),
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json",
"Accept-Encoding": "application/json"
}
})
).data;
res.forEach((a) => {
apps.push({
name: a.service.name,
appId: a.service.id
});
});
if (res.length < perPage) {
hasMorePages = false;
} else {
cursor = res[res.length - 1].cursor;
}
}
return apps;
};

View File

@@ -23,7 +23,8 @@ export default defineConfig({
loader: {
".handlebars": "copy",
".md": "copy",
".txt": "copy"
".txt": "copy",
".pem": "copy"
},
external: ["../../../frontend/node_modules/next/dist/server/next-server.js"],
outDir: "dist",

View File

@@ -1,4 +1,4 @@
---
title: "Delete"
openapi: "DELETE /api/v1/folders/{folderIdOrName}"
openapi: "DELETE /api/v1/folders/{folderId}"
---

View File

@@ -39,32 +39,32 @@
"name": "Start for Free",
"url": "https://app.infisical.com/signup"
},
"tabs": [
"anchors": [
{
"name": "Changelog",
"url": "changelog"
},
{
"name": "API Reference",
"url": "api-reference"
"name": "Internals",
"icon": "sitemap",
"url": "internals"
},
{
"name": "SDKs",
"icon": "puzzle-piece",
"url": "sdks"
},
{
"name": "Contributing",
"url": "contributing"
}
],
"anchors": [
"name": "API Reference",
"icon": "cloud",
"url": "api-reference"
},
{
"name": "Changelog",
"icon": "timer",
"url": "changelog"
},
{
"name": "Contributing",
"icon": "code",
"url": "contributing"
},
{
"name": "Blog",
"icon": "newspaper",
@@ -79,11 +79,6 @@
"name": "GitHub",
"icon": "github",
"url": "https://github.com/Infisical/infisical"
},
{
"name": "Internals",
"icon": "sitemap",
"url": "internals"
}
],
"navigation": [
@@ -196,6 +191,7 @@
"self-hosting/guides/mongo-to-postgres"
]
},
"self-hosting/ee",
"self-hosting/faq"
]
},
@@ -361,18 +357,7 @@
},
{
"group": "Overview",
"pages": [
"sdks/overview"
]
},
{
"group": "SDK's",
"pages": [
"sdks/languages/node",
"sdks/languages/python",
"sdks/languages/java",
"sdks/languages/csharp"
]
"pages": ["sdks/overview"]
},
{
"group": "Overview",

View File

@@ -1,7 +1,6 @@
---
title: "Infisical .NET SDK"
sidebarTitle: ".NET"
icon: "bars"
icon: "C#"
---
If you're working with C#, the official [Infisical C# SDK](https://github.com/Infisical/sdk/tree/main/languages/csharp) package is the easiest way to fetch and work with secrets for your application.

View File

@@ -1,6 +1,5 @@
---
title: "Infisical Java SDK"
sidebarTitle: "Java"
icon: "java"
---

View File

@@ -1,6 +1,5 @@
---
title: "Infisical Node.js SDK"
sidebarTitle: "Node.js"
icon: "node"
---

View File

@@ -1,6 +1,5 @@
---
title: "Infisical Python SDK"
sidebarTitle: "Python"
icon: "python"
---

28
docs/self-hosting/ee.mdx Normal file
View File

@@ -0,0 +1,28 @@
---
title: "Using Infisical EE"
description: "How to activate Infisical Enterprise Edition (EE) features"
---
While most features in Infisical are free to use, others are paid and require purchasing an enterprise license to use them.
This guide walks through how you can use these paid features in Infisical.
<Steps>
<Step title="Purchase a license">
Start by either signing up for a free demo [here](https://infisical.com/schedule-demo) or contacting team@infisical.com to purchase a license.
Once purchased, you will be issued a license key.
</Step>
<Step title="Activate the license">
Depending on whether or not the environment where Infisical is deployed has internet access, you may be issued a regular license or an offline license.
- If using a regular license, you should set the value of the environment variable `LICENSE_KEY` in Infisical to the issued license key.
- If using an offline license, you should set the value of the environment variable `LICENSE_KEY_OFFLINE` in Infisical to the issued license key.
Once your instance starts up, the license key will be validated and youll be able to use the paid features.
<Note>
Once the license expires, Infisical will continue to run, but EE features will be disabled until the license is renewed or a new one is purchased.
</Note>
</Step>
</Steps>