Add PR suggestions
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"author": "Infisical Inc, <daniel@infisical.com>",
|
"author": "Infisical Inc, <daniel@infisical.com>",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "The Infisical SDK provides a convenient way to interact with the Infisical API.",
|
"description": "The Infisical SDK provides a convenient way to programmatically interact with the Infisical API.",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.5.1",
|
"@types/node": "^22.5.1",
|
||||||
"tsc": "^2.0.4",
|
"tsc": "^2.0.4",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export class ApiClient {
|
|||||||
|
|
||||||
if (!config._retryCount) config._retryCount = 0;
|
if (!config._retryCount) config._retryCount = 0;
|
||||||
|
|
||||||
|
// handle rate limits and network errors
|
||||||
if (
|
if (
|
||||||
(error.response?.status === 429 ||
|
(error.response?.status === 429 ||
|
||||||
error.response?.status === undefined) &&
|
error.response?.status === undefined) &&
|
||||||
|
|||||||
@@ -9,11 +9,7 @@ export class EnvironmentsApi {
|
|||||||
): Promise<CreateEnvironmentResponse> {
|
): Promise<CreateEnvironmentResponse> {
|
||||||
return this.apiClient.post<CreateEnvironmentResponse>(
|
return this.apiClient.post<CreateEnvironmentResponse>(
|
||||||
`/api/v1/workspace/${data.projectId}/environments`,
|
`/api/v1/workspace/${data.projectId}/environments`,
|
||||||
{
|
data
|
||||||
name: data.name,
|
|
||||||
slug: data.slug,
|
|
||||||
position: data.position,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,7 @@ export class ProjectsApi {
|
|||||||
): Promise<InviteMembersResponse> {
|
): Promise<InviteMembersResponse> {
|
||||||
return this.apiClient.post<InviteMembersResponse>(
|
return this.apiClient.post<InviteMembersResponse>(
|
||||||
`/api/v2/workspace/${data.projectId}/memberships`,
|
`/api/v2/workspace/${data.projectId}/memberships`,
|
||||||
{
|
data
|
||||||
emails: data.emails,
|
|
||||||
usernames: data.usernames,
|
|
||||||
roleSlugs: data.roleSlugs,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export class SecretsApi {
|
|||||||
const { secretName, ...queryParams } = params;
|
const { secretName, ...queryParams } = params;
|
||||||
return this.apiClient.get<GetSecretResponse>(
|
return this.apiClient.get<GetSecretResponse>(
|
||||||
`/api/v3/secrets/raw/${encodeURIComponent(secretName)}`,
|
`/api/v3/secrets/raw/${encodeURIComponent(secretName)}`,
|
||||||
{ params: queryParams }
|
{ params }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,3 +87,43 @@ export interface RenewLeaseRequest {
|
|||||||
export interface RenewLeaseResponse {
|
export interface RenewLeaseResponse {
|
||||||
lease: Lease;
|
lease: Lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CreateDynamicSecretOptions = {
|
||||||
|
provider: TDynamicSecretProvider;
|
||||||
|
defaultTTL: string;
|
||||||
|
maxTTL: string;
|
||||||
|
name: string;
|
||||||
|
projectSlug: string;
|
||||||
|
environmentSlug: string;
|
||||||
|
path?: string;
|
||||||
|
metadata?: Record<string, any>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteDynamicSecretOptions = {
|
||||||
|
environmentSlug: string;
|
||||||
|
projectSlug: string;
|
||||||
|
path?: string;
|
||||||
|
isForced?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateDynamicSecretLeaseOptions = {
|
||||||
|
dynamicSecretName: string;
|
||||||
|
environmentSlug: string;
|
||||||
|
projectSlug: string;
|
||||||
|
path?: string;
|
||||||
|
ttl?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteDynamicSecretLeaseOptions = {
|
||||||
|
environmentSlug: string;
|
||||||
|
projectSlug: string;
|
||||||
|
path?: string;
|
||||||
|
isForced?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RenewDynamicSecretLeaseOptions = {
|
||||||
|
environmentSlug: string;
|
||||||
|
projectSlug: string;
|
||||||
|
path?: string;
|
||||||
|
ttl?: string;
|
||||||
|
};
|
||||||
|
|||||||
@@ -16,5 +16,14 @@ export interface CreateEnvironmentRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type CreateEnvironmentResponse = {
|
export type CreateEnvironmentResponse = {
|
||||||
|
message: string;
|
||||||
|
workspace: string;
|
||||||
environment: Environment;
|
environment: Environment;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CreateEnvironmentOptions = {
|
||||||
|
name: string;
|
||||||
|
projectId: string;
|
||||||
|
slug: string;
|
||||||
|
position?: number;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
export interface Folder {
|
export interface Folder {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
envId: string;
|
||||||
workspaceId: string;
|
|
||||||
environment: string;
|
|
||||||
description?: string;
|
description?: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
|
parentId?: string;
|
||||||
|
isReserved?: boolean;
|
||||||
|
lastSecretModified?: string;
|
||||||
|
version?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateFolderRequest {
|
export interface CreateFolderRequest {
|
||||||
@@ -33,3 +35,18 @@ export interface ListFoldersResponse {
|
|||||||
folders: Folder[];
|
folders: Folder[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CreateFolderOptions = {
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
projectId: string;
|
||||||
|
environment: string;
|
||||||
|
description?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ListFoldersOptions = {
|
||||||
|
environment: string;
|
||||||
|
projectId: string;
|
||||||
|
path?: string;
|
||||||
|
recursive?: boolean;
|
||||||
|
lastSecretModified?: string;
|
||||||
|
};
|
||||||
|
|||||||
@@ -41,3 +41,19 @@ export interface Membership {
|
|||||||
export interface InviteMembersResponse {
|
export interface InviteMembersResponse {
|
||||||
memberships: Membership[];
|
memberships: Membership[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CreateProjectOptions = {
|
||||||
|
projectName: string;
|
||||||
|
type: string;
|
||||||
|
projectDescription?: string;
|
||||||
|
slug?: string;
|
||||||
|
template?: string;
|
||||||
|
kmsKeyId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type InviteMemberToProjectOptions = {
|
||||||
|
projectId: string;
|
||||||
|
emails?: string[];
|
||||||
|
usernames?: string[];
|
||||||
|
roleSlugs?: string[];
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
type SecretType = "shared" | "personal";
|
||||||
|
|
||||||
export interface Secret {
|
export interface Secret {
|
||||||
id: string;
|
id: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
@@ -6,7 +8,21 @@ export interface Secret {
|
|||||||
secretValue: string;
|
secretValue: string;
|
||||||
secretComment?: string;
|
secretComment?: string;
|
||||||
secretPath?: string;
|
secretPath?: string;
|
||||||
type: "shared" | "personal";
|
secretValueHidden: boolean;
|
||||||
|
secretReminderNote?: string;
|
||||||
|
secretReminderRepeatDays?: number;
|
||||||
|
skipMultilineEncoding?: boolean;
|
||||||
|
folderId?: string;
|
||||||
|
actor?: {
|
||||||
|
actorId?: string;
|
||||||
|
name?: string;
|
||||||
|
actorType?: string;
|
||||||
|
membershipId?: string;
|
||||||
|
}
|
||||||
|
isRotatedSecret: boolean;
|
||||||
|
rotationId?: string;
|
||||||
|
secretMetadata?: Record<string, any>;
|
||||||
|
type: SecretType;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
version: number;
|
version: number;
|
||||||
@@ -29,6 +45,8 @@ export interface ListSecretsResponse {
|
|||||||
imports?: Array<{
|
imports?: Array<{
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
secrets: Secret[];
|
secrets: Secret[];
|
||||||
|
folderId?: string;
|
||||||
|
environment: string;
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +57,7 @@ export interface GetSecretRequest {
|
|||||||
expandSecretReferences?: string;
|
expandSecretReferences?: string;
|
||||||
includeImports?: string;
|
includeImports?: string;
|
||||||
secretPath?: string;
|
secretPath?: string;
|
||||||
type?: "shared" | "personal";
|
type?: SecretType;
|
||||||
version?: number;
|
version?: number;
|
||||||
viewSecretValue?: string;
|
viewSecretValue?: string;
|
||||||
}
|
}
|
||||||
@@ -58,7 +76,7 @@ export interface CreateSecretRequest {
|
|||||||
secretReminderRepeatDays?: number;
|
secretReminderRepeatDays?: number;
|
||||||
skipMultilineEncoding?: boolean;
|
skipMultilineEncoding?: boolean;
|
||||||
tagIds?: string[];
|
tagIds?: string[];
|
||||||
type?: "shared" | "personal";
|
type?: SecretType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateSecretRequest {
|
export interface UpdateSecretRequest {
|
||||||
@@ -72,7 +90,7 @@ export interface UpdateSecretRequest {
|
|||||||
secretReminderRepeatDays?: number;
|
secretReminderRepeatDays?: number;
|
||||||
skipMultilineEncoding?: boolean;
|
skipMultilineEncoding?: boolean;
|
||||||
tagIds?: string[];
|
tagIds?: string[];
|
||||||
type?: "shared" | "personal";
|
type?: SecretType;
|
||||||
metadata?: Record<string, any>;
|
metadata?: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,5 +98,58 @@ export interface DeleteSecretRequest {
|
|||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath?: string;
|
secretPath?: string;
|
||||||
type?: "shared" | "personal";
|
type?: SecretType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ListSecretsOptions = {
|
||||||
|
environment: string;
|
||||||
|
projectId: string;
|
||||||
|
expandSecretReferences?: boolean;
|
||||||
|
includeImports?: boolean;
|
||||||
|
recursive?: boolean;
|
||||||
|
secretPath?: string;
|
||||||
|
tagSlugs?: string[];
|
||||||
|
viewSecretValue?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetSecretOptions = {
|
||||||
|
environment: string;
|
||||||
|
secretName: string;
|
||||||
|
expandSecretReferences?: boolean;
|
||||||
|
includeImports?: boolean;
|
||||||
|
secretPath?: string;
|
||||||
|
type?: SecretType;
|
||||||
|
version?: number;
|
||||||
|
projectId: string;
|
||||||
|
viewSecretValue?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BaseSecretOptions = {
|
||||||
|
environment: string;
|
||||||
|
projectId: string;
|
||||||
|
secretComment?: string;
|
||||||
|
secretPath?: string;
|
||||||
|
secretReminderNote?: string;
|
||||||
|
secretReminderRepeatDays?: number;
|
||||||
|
skipMultilineEncoding?: boolean;
|
||||||
|
tagIds?: string[];
|
||||||
|
type?: SecretType;
|
||||||
|
metadata?: Record<string, any>;
|
||||||
|
secretMetadata?: Record<string, any>[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateSecretOptions = {
|
||||||
|
secretValue?: string;
|
||||||
|
newSecretName?: string;
|
||||||
|
} & BaseSecretOptions;
|
||||||
|
|
||||||
|
export type CreateSecretOptions = {
|
||||||
|
secretValue: string;
|
||||||
|
} & BaseSecretOptions;
|
||||||
|
|
||||||
|
export type DeleteSecretOptions = {
|
||||||
|
environment: string;
|
||||||
|
projectId: string;
|
||||||
|
secretPath?: string;
|
||||||
|
type?: SecretType;
|
||||||
|
};
|
||||||
|
|||||||
@@ -27,19 +27,11 @@ export const renewToken = async (apiClient: AuthApi, token?: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default class AuthClient {
|
export default class AuthClient {
|
||||||
#sdkAuthenticator: AuthenticatorFunction;
|
|
||||||
#apiClient: AuthApi;
|
|
||||||
#accessToken?: string;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
authenticator: AuthenticatorFunction,
|
private sdkAuthenticator: AuthenticatorFunction,
|
||||||
apiInstance: AuthApi,
|
private apiClient: AuthApi,
|
||||||
accessToken?: string
|
private _accessToken?: string
|
||||||
) {
|
) {}
|
||||||
this.#sdkAuthenticator = authenticator;
|
|
||||||
this.#apiClient = apiInstance;
|
|
||||||
this.#accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
awsIamAuth = {
|
awsIamAuth = {
|
||||||
login: async (options?: AwsAuthLoginOptions) => {
|
login: async (options?: AwsAuthLoginOptions) => {
|
||||||
@@ -53,7 +45,7 @@ export default class AuthClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const iamRequest = await performAwsIamLogin(await getAwsRegion());
|
const iamRequest = await performAwsIamLogin(await getAwsRegion());
|
||||||
const res = await this.#apiClient.awsIamAuthLogin({
|
const res = await this.apiClient.awsIamAuthLogin({
|
||||||
iamHttpRequestMethod: iamRequest.iamHttpRequestMethod,
|
iamHttpRequestMethod: iamRequest.iamHttpRequestMethod,
|
||||||
iamRequestBody: Buffer.from(iamRequest.iamRequestBody).toString(
|
iamRequestBody: Buffer.from(iamRequest.iamRequestBody).toString(
|
||||||
"base64"
|
"base64"
|
||||||
@@ -64,7 +56,7 @@ export default class AuthClient {
|
|||||||
identityId,
|
identityId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.#sdkAuthenticator(res.accessToken);
|
return this.sdkAuthenticator(res.accessToken);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw newInfisicalError(err);
|
throw newInfisicalError(err);
|
||||||
}
|
}
|
||||||
@@ -72,10 +64,10 @@ export default class AuthClient {
|
|||||||
renew: async () => {
|
renew: async () => {
|
||||||
try {
|
try {
|
||||||
const refreshedToken = await renewToken(
|
const refreshedToken = await renewToken(
|
||||||
this.#apiClient,
|
this.apiClient,
|
||||||
this.#accessToken
|
this._accessToken
|
||||||
);
|
);
|
||||||
return this.#sdkAuthenticator(refreshedToken.accessToken);
|
return this.sdkAuthenticator(refreshedToken.accessToken);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw newInfisicalError(err);
|
throw newInfisicalError(err);
|
||||||
}
|
}
|
||||||
@@ -85,8 +77,8 @@ export default class AuthClient {
|
|||||||
universalAuth = {
|
universalAuth = {
|
||||||
login: async (options: UniversalAuthLoginRequest) => {
|
login: async (options: UniversalAuthLoginRequest) => {
|
||||||
try {
|
try {
|
||||||
const res = await this.#apiClient.universalAuthLogin(options);
|
const res = await this.apiClient.universalAuthLogin(options);
|
||||||
return this.#sdkAuthenticator(res.accessToken);
|
return this.sdkAuthenticator(res.accessToken);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw newInfisicalError(err);
|
throw newInfisicalError(err);
|
||||||
}
|
}
|
||||||
@@ -94,10 +86,10 @@ export default class AuthClient {
|
|||||||
renew: async () => {
|
renew: async () => {
|
||||||
try {
|
try {
|
||||||
const refreshedToken = await renewToken(
|
const refreshedToken = await renewToken(
|
||||||
this.#apiClient,
|
this.apiClient,
|
||||||
this.#accessToken
|
this._accessToken
|
||||||
);
|
);
|
||||||
return this.#sdkAuthenticator(refreshedToken.accessToken);
|
return this.sdkAuthenticator(refreshedToken.accessToken);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw newInfisicalError(err);
|
throw newInfisicalError(err);
|
||||||
}
|
}
|
||||||
@@ -105,6 +97,6 @@ export default class AuthClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
accessToken = (token: string) => {
|
accessToken = (token: string) => {
|
||||||
return this.#sdkAuthenticator(token);
|
return this.sdkAuthenticator(token);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,13 @@
|
|||||||
import { DynamicSecretsApi } from "../api/endpoints/dynamic-secrets";
|
import { DynamicSecretsApi } from "../api/endpoints/dynamic-secrets";
|
||||||
import { TDynamicSecretProvider } from "./schemas/dynamic-secrets";
|
import { TDynamicSecretProvider } from "./schemas/dynamic-secrets";
|
||||||
import { newInfisicalError } from "./errors";
|
import { newInfisicalError } from "./errors";
|
||||||
|
import {
|
||||||
export type CreateDynamicSecretOptions = {
|
CreateDynamicSecretOptions,
|
||||||
provider: TDynamicSecretProvider;
|
DeleteDynamicSecretOptions,
|
||||||
defaultTTL: string;
|
CreateDynamicSecretLeaseOptions,
|
||||||
maxTTL: string;
|
DeleteDynamicSecretLeaseOptions,
|
||||||
name: string;
|
RenewDynamicSecretLeaseOptions,
|
||||||
projectSlug: string;
|
} from "../api/types/dynamic-secrets";
|
||||||
environmentSlug: string;
|
|
||||||
path?: string;
|
|
||||||
metadata?: Record<string, any>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DeleteDynamicSecretOptions = {
|
|
||||||
environmentSlug: string;
|
|
||||||
projectSlug: string;
|
|
||||||
path?: string;
|
|
||||||
isForced?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateDynamicSecretLeaseOptions = {
|
|
||||||
dynamicSecretName: string;
|
|
||||||
environmentSlug: string;
|
|
||||||
projectSlug: string;
|
|
||||||
path?: string;
|
|
||||||
ttl?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DeleteDynamicSecretLeaseOptions = {
|
|
||||||
environmentSlug: string;
|
|
||||||
projectSlug: string;
|
|
||||||
path?: string;
|
|
||||||
isForced?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RenewDynamicSecretLeaseOptions = {
|
|
||||||
environmentSlug: string;
|
|
||||||
projectSlug: string;
|
|
||||||
path?: string;
|
|
||||||
ttl?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class DynamicSecretsClient {
|
export default class DynamicSecretsClient {
|
||||||
constructor(private apiClient: DynamicSecretsApi) {}
|
constructor(private apiClient: DynamicSecretsApi) {}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
import { EnvironmentsApi } from "../api/endpoints/environments";
|
import { EnvironmentsApi } from "../api/endpoints/environments";
|
||||||
import { newInfisicalError } from "./errors";
|
import { newInfisicalError } from "./errors";
|
||||||
|
import { CreateEnvironmentOptions } from "../api/types/environments";
|
||||||
export type CreateEnvironmentOptions = {
|
|
||||||
name: string;
|
|
||||||
projectId: string;
|
|
||||||
slug: string;
|
|
||||||
position?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class EnvironmentsClient {
|
export default class EnvironmentsClient {
|
||||||
constructor(private apiClient: EnvironmentsApi) {}
|
constructor(private apiClient: EnvironmentsApi) {}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
export class InfisicalSDKError extends Error {
|
export class InfisicalSDKError extends Error {
|
||||||
constructor(message: string) {
|
constructor(message: string) {
|
||||||
super(message);
|
super(message);
|
||||||
@@ -22,7 +24,7 @@ export class InfisicalSDKRequestError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const newInfisicalError = (error: any) => {
|
export const newInfisicalError = (error: any) => {
|
||||||
if (error?.isAxiosError) {
|
if (axios.isAxiosError(error)) {
|
||||||
const data = error?.response?.data;
|
const data = error?.response?.data;
|
||||||
|
|
||||||
if (data?.message) {
|
if (data?.message) {
|
||||||
@@ -39,6 +41,7 @@ export const newInfisicalError = (error: any) => {
|
|||||||
} else if (error.message) {
|
} else if (error.message) {
|
||||||
return new InfisicalSDKError(error.message);
|
return new InfisicalSDKError(error.message);
|
||||||
} else if (error.code) {
|
} else if (error.code) {
|
||||||
|
// If theres no message but a code is present, it's likely to be an aggregation error. This is not specific to Axios, but it falls under the AxiosError type
|
||||||
return new InfisicalSDKError(error.code);
|
return new InfisicalSDKError(error.code);
|
||||||
} else {
|
} else {
|
||||||
return new InfisicalSDKError("Request failed with unknown error");
|
return new InfisicalSDKError("Request failed with unknown error");
|
||||||
|
|||||||
@@ -1,21 +1,6 @@
|
|||||||
import { FoldersApi } from "../api/endpoints/folders";
|
import { FoldersApi } from "../api/endpoints/folders";
|
||||||
import { newInfisicalError } from "./errors";
|
import { newInfisicalError } from "./errors";
|
||||||
|
import { CreateFolderOptions, ListFoldersOptions } from "../api/types/folders";
|
||||||
export type CreateFolderOptions = {
|
|
||||||
name: string;
|
|
||||||
path: string;
|
|
||||||
projectId: string;
|
|
||||||
environment: string;
|
|
||||||
description?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ListFoldersOptions = {
|
|
||||||
environment: string;
|
|
||||||
projectId: string;
|
|
||||||
path?: string;
|
|
||||||
recursive?: boolean;
|
|
||||||
lastSecretModified?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class FoldersClient {
|
export default class FoldersClient {
|
||||||
constructor(private apiClient: FoldersApi) {}
|
constructor(private apiClient: FoldersApi) {}
|
||||||
|
|||||||
@@ -1,21 +1,6 @@
|
|||||||
import { ProjectsApi } from "../api/endpoints/projects";
|
import { ProjectsApi } from "../api/endpoints/projects";
|
||||||
import { newInfisicalError } from "./errors";
|
import { newInfisicalError } from "./errors";
|
||||||
|
import { CreateProjectOptions, InviteMemberToProjectOptions } from "../api/types/projects";
|
||||||
export type CreateProjectOptions = {
|
|
||||||
projectName: string;
|
|
||||||
type: string;
|
|
||||||
projectDescription?: string;
|
|
||||||
slug?: string;
|
|
||||||
template?: string;
|
|
||||||
kmsKeyId?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type InviteMemberToProjectOptions = {
|
|
||||||
projectId: string;
|
|
||||||
emails?: string[];
|
|
||||||
usernames?: string[];
|
|
||||||
roleSlugs?: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class ProjectsClient {
|
export default class ProjectsClient {
|
||||||
constructor(private apiClient: ProjectsApi) {}
|
constructor(private apiClient: ProjectsApi) {}
|
||||||
|
|||||||
@@ -1,301 +1,394 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export enum SqlProviders {
|
export enum SqlProviders {
|
||||||
Postgres = "postgres",
|
Postgres = "postgres",
|
||||||
MySQL = "mysql2",
|
MySQL = "mysql2",
|
||||||
Oracle = "oracledb",
|
Oracle = "oracledb",
|
||||||
MsSQL = "mssql",
|
MsSQL = "mssql",
|
||||||
SapAse = "sap-ase"
|
SapAse = "sap-ase",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ElasticSearchAuthTypes {
|
export enum ElasticSearchAuthTypes {
|
||||||
User = "user",
|
User = "user",
|
||||||
ApiKey = "api-key"
|
ApiKey = "api-key",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LdapCredentialType {
|
export enum LdapCredentialType {
|
||||||
Dynamic = "dynamic",
|
Dynamic = "dynamic",
|
||||||
Static = "static"
|
Static = "static",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TotpConfigType {
|
export enum TotpConfigType {
|
||||||
URL = "url",
|
URL = "url",
|
||||||
MANUAL = "manual"
|
MANUAL = "manual",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TotpAlgorithm {
|
export enum TotpAlgorithm {
|
||||||
SHA1 = "sha1",
|
SHA1 = "sha1",
|
||||||
SHA256 = "sha256",
|
SHA256 = "sha256",
|
||||||
SHA512 = "sha512"
|
SHA512 = "sha512",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const passwordRequirementsSchema = z.object({
|
||||||
|
length: z
|
||||||
|
.number()
|
||||||
|
.min(1, { message: "Password length must be at least 1" })
|
||||||
|
.max(250, { message: "Password length must be at most 250" }),
|
||||||
|
|
||||||
|
required: z.object({
|
||||||
|
minUppercase: z.number().min(0).optional(),
|
||||||
|
minLowercase: z.number().min(0).optional(),
|
||||||
|
minDigits: z.number().min(0).optional(),
|
||||||
|
minSymbols: z.number().min(0).optional(),
|
||||||
|
}),
|
||||||
|
allowedSymbols: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
const DynamicSecretRedisDBSchema = z.object({
|
const DynamicSecretRedisDBSchema = z.object({
|
||||||
host: z.string().trim().toLowerCase(),
|
host: z.string().trim().toLowerCase(),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
username: z.string().trim(), // this is often "default".
|
username: z.string().trim(), // this is often "default".
|
||||||
password: z.string().trim().optional(),
|
password: z.string().trim().optional(),
|
||||||
creationStatement: z.string().trim(),
|
creationStatement: z.string().trim(),
|
||||||
revocationStatement: z.string().trim(),
|
revocationStatement: z.string().trim(),
|
||||||
renewStatement: z.string().trim().optional(),
|
renewStatement: z.string().trim().optional(),
|
||||||
ca: z.string().optional()
|
ca: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretAwsElastiCacheSchema = z.object({
|
const DynamicSecretAwsElastiCacheSchema = z.object({
|
||||||
clusterName: z.string().trim().min(1),
|
clusterName: z.string().trim().min(1),
|
||||||
accessKeyId: z.string().trim().min(1),
|
accessKeyId: z.string().trim().min(1),
|
||||||
secretAccessKey: z.string().trim().min(1),
|
secretAccessKey: z.string().trim().min(1),
|
||||||
|
|
||||||
region: z.string().trim(),
|
region: z.string().trim(),
|
||||||
creationStatement: z.string().trim(),
|
creationStatement: z.string().trim(),
|
||||||
revocationStatement: z.string().trim(),
|
revocationStatement: z.string().trim(),
|
||||||
ca: z.string().optional()
|
ca: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretElasticSearchSchema = z.object({
|
const DynamicSecretElasticSearchSchema = z.object({
|
||||||
host: z.string().trim().min(1),
|
host: z.string().trim().min(1),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
roles: z.array(z.string().trim().min(1)).min(1),
|
roles: z.array(z.string().trim().min(1)).min(1),
|
||||||
|
|
||||||
// two auth types "user, apikey"
|
// two auth types "user, apikey"
|
||||||
auth: z.discriminatedUnion("type", [
|
auth: z.discriminatedUnion("type", [
|
||||||
z.object({
|
z.object({
|
||||||
type: z.literal(ElasticSearchAuthTypes.User),
|
type: z.literal(ElasticSearchAuthTypes.User),
|
||||||
username: z.string().trim(),
|
username: z.string().trim(),
|
||||||
password: z.string().trim()
|
password: z.string().trim(),
|
||||||
}),
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
type: z.literal(ElasticSearchAuthTypes.ApiKey),
|
type: z.literal(ElasticSearchAuthTypes.ApiKey),
|
||||||
apiKey: z.string().trim(),
|
apiKey: z.string().trim(),
|
||||||
apiKeyId: z.string().trim()
|
apiKeyId: z.string().trim(),
|
||||||
})
|
}),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
ca: z.string().optional()
|
ca: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretRabbitMqSchema = z.object({
|
const DynamicSecretRabbitMqSchema = z.object({
|
||||||
host: z.string().trim().min(1),
|
host: z.string().trim().min(1),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
tags: z.array(z.string().trim()).default([]),
|
tags: z.array(z.string().trim()).default([]),
|
||||||
|
|
||||||
username: z.string().trim().min(1),
|
username: z.string().trim().min(1),
|
||||||
password: z.string().trim().min(1),
|
password: z.string().trim().min(1),
|
||||||
|
|
||||||
ca: z.string().optional(),
|
ca: z.string().optional(),
|
||||||
|
|
||||||
virtualHost: z.object({
|
virtualHost: z.object({
|
||||||
name: z.string().trim().min(1),
|
name: z.string().trim().min(1),
|
||||||
permissions: z.object({
|
permissions: z.object({
|
||||||
read: z.string().trim().min(1),
|
read: z.string().trim().min(1),
|
||||||
write: z.string().trim().min(1),
|
write: z.string().trim().min(1),
|
||||||
configure: z.string().trim().min(1)
|
configure: z.string().trim().min(1),
|
||||||
})
|
}),
|
||||||
})
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretSqlDBSchema = z.object({
|
const DynamicSecretSqlDBSchema = z.object({
|
||||||
client: z.nativeEnum(SqlProviders),
|
client: z.nativeEnum(SqlProviders),
|
||||||
host: z.string().trim().toLowerCase(),
|
host: z.string().trim().toLowerCase(),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
database: z.string().trim(),
|
database: z.string().trim(),
|
||||||
username: z.string().trim(),
|
username: z.string().trim(),
|
||||||
password: z.string().trim(),
|
password: z.string().trim(),
|
||||||
creationStatement: z.string().trim(),
|
creationStatement: z.string().trim(),
|
||||||
revocationStatement: z.string().trim(),
|
revocationStatement: z.string().trim(),
|
||||||
renewStatement: z.string().trim().optional(),
|
renewStatement: z.string().trim().optional(),
|
||||||
ca: z.string().optional()
|
ca: z.string().optional(),
|
||||||
|
passwordRequirements: passwordRequirementsSchema.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretCassandraSchema = z.object({
|
const DynamicSecretCassandraSchema = z.object({
|
||||||
host: z.string().trim().toLowerCase(),
|
host: z.string().trim().toLowerCase(),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
localDataCenter: z.string().trim().min(1),
|
localDataCenter: z.string().trim().min(1),
|
||||||
keyspace: z.string().trim().optional(),
|
keyspace: z.string().trim().optional(),
|
||||||
username: z.string().trim(),
|
username: z.string().trim(),
|
||||||
password: z.string().trim(),
|
password: z.string().trim(),
|
||||||
creationStatement: z.string().trim(),
|
creationStatement: z.string().trim(),
|
||||||
revocationStatement: z.string().trim(),
|
revocationStatement: z.string().trim(),
|
||||||
renewStatement: z.string().trim().optional(),
|
renewStatement: z.string().trim().optional(),
|
||||||
ca: z.string().optional()
|
ca: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretSapAseSchema = z.object({
|
const DynamicSecretSapAseSchema = z.object({
|
||||||
host: z.string().trim().toLowerCase(),
|
host: z.string().trim().toLowerCase(),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
database: z.string().trim(),
|
database: z.string().trim(),
|
||||||
username: z.string().trim(),
|
username: z.string().trim(),
|
||||||
password: z.string().trim(),
|
password: z.string().trim(),
|
||||||
creationStatement: z.string().trim(),
|
creationStatement: z.string().trim(),
|
||||||
revocationStatement: z.string().trim()
|
revocationStatement: z.string().trim(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretAwsIamSchema = z.object({
|
const DynamicSecretAwsIamSchema = z.object({
|
||||||
accessKey: z.string().trim().min(1),
|
accessKey: z.string().trim().min(1),
|
||||||
secretAccessKey: z.string().trim().min(1),
|
secretAccessKey: z.string().trim().min(1),
|
||||||
region: z.string().trim().min(1),
|
region: z.string().trim().min(1),
|
||||||
awsPath: z.string().trim().optional(),
|
awsPath: z.string().trim().optional(),
|
||||||
permissionBoundaryPolicyArn: z.string().trim().optional(),
|
permissionBoundaryPolicyArn: z.string().trim().optional(),
|
||||||
policyDocument: z.string().trim().optional(),
|
policyDocument: z.string().trim().optional(),
|
||||||
userGroups: z.string().trim().optional(),
|
userGroups: z.string().trim().optional(),
|
||||||
policyArns: z.string().trim().optional()
|
policyArns: z.string().trim().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretMongoAtlasSchema = z.object({
|
const DynamicSecretMongoAtlasSchema = z.object({
|
||||||
adminPublicKey: z.string().trim().min(1).describe("Admin user public api key"),
|
adminPublicKey: z
|
||||||
adminPrivateKey: z.string().trim().min(1).describe("Admin user private api key"),
|
.string()
|
||||||
groupId: z.string().trim().min(1).describe("Unique 24-hexadecimal digit string that identifies your project. This is same as project id"),
|
.trim()
|
||||||
roles: z
|
.min(1)
|
||||||
.object({
|
.describe("Admin user public api key"),
|
||||||
collectionName: z.string().optional().describe("Collection on which this role applies."),
|
adminPrivateKey: z
|
||||||
databaseName: z.string().min(1).describe("Database to which the user is granted access privileges."),
|
.string()
|
||||||
roleName: z
|
.trim()
|
||||||
.string()
|
.min(1)
|
||||||
.min(1)
|
.describe("Admin user private api key"),
|
||||||
.describe(
|
groupId: z
|
||||||
' Enum: "atlasAdmin" "backup" "clusterMonitor" "dbAdmin" "dbAdminAnyDatabase" "enableSharding" "read" "readAnyDatabase" "readWrite" "readWriteAnyDatabase" "<a custom role name>".Human-readable label that identifies a group of privileges assigned to a database user. This value can either be a built-in role or a custom role.'
|
.string()
|
||||||
)
|
.trim()
|
||||||
})
|
.min(1)
|
||||||
.array()
|
.describe(
|
||||||
.min(1),
|
"Unique 24-hexadecimal digit string that identifies your project. This is same as project id"
|
||||||
scopes: z
|
),
|
||||||
.object({
|
roles: z
|
||||||
name: z
|
.object({
|
||||||
.string()
|
collectionName: z
|
||||||
.min(1)
|
.string()
|
||||||
.describe("Human-readable label that identifies the cluster or MongoDB Atlas Data Lake that this database user can access."),
|
.optional()
|
||||||
type: z.string().min(1).describe("Category of resource that this database user can access. Enum: CLUSTER, DATA_LAKE, STREAM")
|
.describe("Collection on which this role applies."),
|
||||||
})
|
databaseName: z
|
||||||
.array()
|
.string()
|
||||||
|
.min(1)
|
||||||
|
.describe("Database to which the user is granted access privileges."),
|
||||||
|
roleName: z
|
||||||
|
.string()
|
||||||
|
.min(1)
|
||||||
|
.describe(
|
||||||
|
' Enum: "atlasAdmin" "backup" "clusterMonitor" "dbAdmin" "dbAdminAnyDatabase" "enableSharding" "read" "readAnyDatabase" "readWrite" "readWriteAnyDatabase" "<a custom role name>".Human-readable label that identifies a group of privileges assigned to a database user. This value can either be a built-in role or a custom role.'
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
.min(1),
|
||||||
|
scopes: z
|
||||||
|
.object({
|
||||||
|
name: z
|
||||||
|
.string()
|
||||||
|
.min(1)
|
||||||
|
.describe(
|
||||||
|
"Human-readable label that identifies the cluster or MongoDB Atlas Data Lake that this database user can access."
|
||||||
|
),
|
||||||
|
type: z
|
||||||
|
.string()
|
||||||
|
.min(1)
|
||||||
|
.describe(
|
||||||
|
"Category of resource that this database user can access. Enum: CLUSTER, DATA_LAKE, STREAM"
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.array(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretMongoDBSchema = z.object({
|
const DynamicSecretMongoDBSchema = z.object({
|
||||||
host: z.string().min(1).trim().toLowerCase(),
|
host: z.string().min(1).trim().toLowerCase(),
|
||||||
port: z.number().optional(),
|
port: z.number().optional(),
|
||||||
username: z.string().min(1).trim(),
|
username: z.string().min(1).trim(),
|
||||||
password: z.string().min(1).trim(),
|
password: z.string().min(1).trim(),
|
||||||
database: z.string().min(1).trim(),
|
database: z.string().min(1).trim(),
|
||||||
ca: z.string().min(1).optional(),
|
ca: z.string().min(1).optional(),
|
||||||
roles: z
|
roles: z
|
||||||
.string()
|
.string()
|
||||||
.array()
|
.array()
|
||||||
.min(1)
|
.min(1)
|
||||||
.describe(
|
.describe(
|
||||||
'Enum: "atlasAdmin" "backup" "clusterMonitor" "dbAdmin" "dbAdminAnyDatabase" "enableSharding" "read" "readAnyDatabase" "readWrite" "readWriteAnyDatabase" "<a custom role name>".Human-readable label that identifies a group of privileges assigned to a database user. This value can either be a built-in role or a custom role.'
|
'Enum: "atlasAdmin" "backup" "clusterMonitor" "dbAdmin" "dbAdminAnyDatabase" "enableSharding" "read" "readAnyDatabase" "readWrite" "readWriteAnyDatabase" "<a custom role name>".Human-readable label that identifies a group of privileges assigned to a database user. This value can either be a built-in role or a custom role.'
|
||||||
)
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretSapHanaSchema = z.object({
|
const DynamicSecretSapHanaSchema = z.object({
|
||||||
host: z.string().trim().toLowerCase(),
|
host: z.string().trim().toLowerCase(),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
username: z.string().trim(),
|
username: z.string().trim(),
|
||||||
password: z.string().trim(),
|
password: z.string().trim(),
|
||||||
creationStatement: z.string().trim(),
|
creationStatement: z.string().trim(),
|
||||||
revocationStatement: z.string().trim(),
|
revocationStatement: z.string().trim(),
|
||||||
renewStatement: z.string().trim().optional(),
|
renewStatement: z.string().trim().optional(),
|
||||||
ca: z.string().optional()
|
ca: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DynamicSecretSnowflakeSchema = z.object({
|
const DynamicSecretSnowflakeSchema = z.object({
|
||||||
accountId: z.string().trim().min(1),
|
accountId: z.string().trim().min(1),
|
||||||
orgId: z.string().trim().min(1),
|
orgId: z.string().trim().min(1),
|
||||||
username: z.string().trim().min(1),
|
username: z.string().trim().min(1),
|
||||||
password: z.string().trim().min(1),
|
password: z.string().trim().min(1),
|
||||||
creationStatement: z.string().trim().min(1),
|
creationStatement: z.string().trim().min(1),
|
||||||
revocationStatement: z.string().trim().min(1),
|
revocationStatement: z.string().trim().min(1),
|
||||||
renewStatement: z.string().trim().optional()
|
renewStatement: z.string().trim().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const AzureEntraIDSchema = z.object({
|
const AzureEntraIDSchema = z.object({
|
||||||
tenantId: z.string().trim().min(1),
|
tenantId: z.string().trim().min(1),
|
||||||
userId: z.string().trim().min(1),
|
userId: z.string().trim().min(1),
|
||||||
email: z.string().trim().min(1),
|
email: z.string().trim().min(1),
|
||||||
applicationId: z.string().trim().min(1),
|
applicationId: z.string().trim().min(1),
|
||||||
clientSecret: z.string().trim().min(1)
|
clientSecret: z.string().trim().min(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
const LdapSchema = z.union([
|
const LdapSchema = z.union([
|
||||||
z.object({
|
z.object({
|
||||||
url: z.string().trim().min(1),
|
url: z.string().trim().min(1),
|
||||||
binddn: z.string().trim().min(1),
|
binddn: z.string().trim().min(1),
|
||||||
bindpass: z.string().trim().min(1),
|
bindpass: z.string().trim().min(1),
|
||||||
ca: z.string().optional(),
|
ca: z.string().optional(),
|
||||||
credentialType: z.literal(LdapCredentialType.Dynamic).optional().default(LdapCredentialType.Dynamic),
|
credentialType: z
|
||||||
creationLdif: z.string().min(1),
|
.literal(LdapCredentialType.Dynamic)
|
||||||
revocationLdif: z.string().min(1),
|
.optional()
|
||||||
rollbackLdif: z.string().optional()
|
.default(LdapCredentialType.Dynamic),
|
||||||
}),
|
creationLdif: z.string().min(1),
|
||||||
z.object({
|
revocationLdif: z.string().min(1),
|
||||||
url: z.string().trim().min(1),
|
rollbackLdif: z.string().optional(),
|
||||||
binddn: z.string().trim().min(1),
|
}),
|
||||||
bindpass: z.string().trim().min(1),
|
z.object({
|
||||||
ca: z.string().optional(),
|
url: z.string().trim().min(1),
|
||||||
credentialType: z.literal(LdapCredentialType.Static),
|
binddn: z.string().trim().min(1),
|
||||||
rotationLdif: z.string().min(1)
|
bindpass: z.string().trim().min(1),
|
||||||
})
|
ca: z.string().optional(),
|
||||||
|
credentialType: z.literal(LdapCredentialType.Static),
|
||||||
|
rotationLdif: z.string().min(1),
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const DynamicSecretTotpSchema = z.discriminatedUnion("configType", [
|
const DynamicSecretTotpSchema = z.discriminatedUnion("configType", [
|
||||||
z.object({
|
z.object({
|
||||||
configType: z.literal(TotpConfigType.URL),
|
configType: z.literal(TotpConfigType.URL),
|
||||||
url: z
|
url: z
|
||||||
.string()
|
.string()
|
||||||
.url()
|
.url()
|
||||||
.trim()
|
.trim()
|
||||||
.min(1)
|
.min(1)
|
||||||
.refine(val => {
|
.refine((val) => {
|
||||||
const urlObj = new URL(val);
|
const urlObj = new URL(val);
|
||||||
const secret = urlObj.searchParams.get("secret");
|
const secret = urlObj.searchParams.get("secret");
|
||||||
|
|
||||||
return Boolean(secret);
|
return Boolean(secret);
|
||||||
}, "OTP URL must contain secret field")
|
}, "OTP URL must contain secret field"),
|
||||||
}),
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
configType: z.literal(TotpConfigType.MANUAL),
|
configType: z.literal(TotpConfigType.MANUAL),
|
||||||
secret: z
|
secret: z
|
||||||
.string()
|
.string()
|
||||||
.trim()
|
.trim()
|
||||||
.min(1)
|
.min(1)
|
||||||
.transform(val => val.replace(/\s+/g, "")),
|
.transform((val) => val.replace(/\s+/g, "")),
|
||||||
period: z.number().optional(),
|
period: z.number().optional(),
|
||||||
algorithm: z.nativeEnum(TotpAlgorithm).optional(),
|
algorithm: z.nativeEnum(TotpAlgorithm).optional(),
|
||||||
digits: z.number().optional()
|
digits: z.number().optional(),
|
||||||
})
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export enum DynamicSecretProviders {
|
export enum DynamicSecretProviders {
|
||||||
SqlDatabase = "sql-database",
|
SqlDatabase = "sql-database",
|
||||||
Cassandra = "cassandra",
|
Cassandra = "cassandra",
|
||||||
AwsIam = "aws-iam",
|
AwsIam = "aws-iam",
|
||||||
Redis = "redis",
|
Redis = "redis",
|
||||||
AwsElastiCache = "aws-elasticache",
|
AwsElastiCache = "aws-elasticache",
|
||||||
MongoAtlas = "mongo-db-atlas",
|
MongoAtlas = "mongo-db-atlas",
|
||||||
ElasticSearch = "elastic-search",
|
ElasticSearch = "elastic-search",
|
||||||
MongoDB = "mongo-db",
|
MongoDB = "mongo-db",
|
||||||
RabbitMq = "rabbit-mq",
|
RabbitMq = "rabbit-mq",
|
||||||
AzureEntraID = "azure-entra-id",
|
AzureEntraID = "azure-entra-id",
|
||||||
Ldap = "ldap",
|
Ldap = "ldap",
|
||||||
SapHana = "sap-hana",
|
SapHana = "sap-hana",
|
||||||
Snowflake = "snowflake",
|
Snowflake = "snowflake",
|
||||||
Totp = "totp",
|
Totp = "totp",
|
||||||
SapAse = "sap-ase"
|
SapAse = "sap-ase",
|
||||||
}
|
}
|
||||||
|
|
||||||
const DynamicSecretProviderSchema = z.discriminatedUnion("type", [
|
const DynamicSecretProviderSchema = z.discriminatedUnion("type", [
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.SqlDatabase), inputs: DynamicSecretSqlDBSchema }),
|
z.object({
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.Cassandra), inputs: DynamicSecretCassandraSchema }),
|
type: z.literal(DynamicSecretProviders.SqlDatabase),
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.SapAse), inputs: DynamicSecretSapAseSchema }),
|
inputs: DynamicSecretSqlDBSchema,
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.AwsIam), inputs: DynamicSecretAwsIamSchema }),
|
}),
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.Redis), inputs: DynamicSecretRedisDBSchema }),
|
z.object({
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.SapHana), inputs: DynamicSecretSapHanaSchema }),
|
type: z.literal(DynamicSecretProviders.Cassandra),
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.AwsElastiCache), inputs: DynamicSecretAwsElastiCacheSchema }),
|
inputs: DynamicSecretCassandraSchema,
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.MongoAtlas), inputs: DynamicSecretMongoAtlasSchema }),
|
}),
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.ElasticSearch), inputs: DynamicSecretElasticSearchSchema }),
|
z.object({
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.MongoDB), inputs: DynamicSecretMongoDBSchema }),
|
type: z.literal(DynamicSecretProviders.SapAse),
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.RabbitMq), inputs: DynamicSecretRabbitMqSchema }),
|
inputs: DynamicSecretSapAseSchema,
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.AzureEntraID), inputs: AzureEntraIDSchema }),
|
}),
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.Ldap), inputs: LdapSchema }),
|
z.object({
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.Snowflake), inputs: DynamicSecretSnowflakeSchema }),
|
type: z.literal(DynamicSecretProviders.AwsIam),
|
||||||
z.object({ type: z.literal(DynamicSecretProviders.Totp), inputs: DynamicSecretTotpSchema })
|
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,
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(DynamicSecretProviders.MongoDB),
|
||||||
|
inputs: DynamicSecretMongoDBSchema,
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(DynamicSecretProviders.RabbitMq),
|
||||||
|
inputs: DynamicSecretRabbitMqSchema,
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(DynamicSecretProviders.AzureEntraID),
|
||||||
|
inputs: AzureEntraIDSchema,
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(DynamicSecretProviders.Ldap),
|
||||||
|
inputs: LdapSchema,
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(DynamicSecretProviders.Snowflake),
|
||||||
|
inputs: DynamicSecretSnowflakeSchema,
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(DynamicSecretProviders.Totp),
|
||||||
|
inputs: DynamicSecretTotpSchema,
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export type TDynamicSecretProvider = z.infer<typeof DynamicSecretProviderSchema>;
|
export type TDynamicSecretProvider = z.infer<
|
||||||
|
typeof DynamicSecretProviderSchema
|
||||||
|
>;
|
||||||
|
|||||||
@@ -1,61 +1,7 @@
|
|||||||
import { SecretsApi } from "../api/endpoints/secrets";
|
import { SecretsApi } from "../api/endpoints/secrets";
|
||||||
import { Secret } from "../api/types";
|
import { Secret } from "../api/types";
|
||||||
import { newInfisicalError } from "./errors";
|
import { newInfisicalError } from "./errors";
|
||||||
|
import { ListSecretsOptions, GetSecretOptions, UpdateSecretOptions, CreateSecretOptions, DeleteSecretOptions } from "../api/types/secrets";
|
||||||
type SecretType = "shared" | "personal";
|
|
||||||
|
|
||||||
type ListSecretsOptions = {
|
|
||||||
environment: string;
|
|
||||||
projectId: string;
|
|
||||||
expandSecretReferences?: boolean;
|
|
||||||
includeImports?: boolean;
|
|
||||||
recursive?: boolean;
|
|
||||||
secretPath?: string;
|
|
||||||
tagSlugs?: string[];
|
|
||||||
viewSecretValue?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type GetSecretOptions = {
|
|
||||||
environment: string;
|
|
||||||
secretName: string;
|
|
||||||
expandSecretReferences?: boolean;
|
|
||||||
includeImports?: boolean;
|
|
||||||
secretPath?: string;
|
|
||||||
type?: SecretType;
|
|
||||||
version?: number;
|
|
||||||
projectId: string;
|
|
||||||
viewSecretValue?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type BaseSecretOptions = {
|
|
||||||
environment: string;
|
|
||||||
projectId: string;
|
|
||||||
secretComment?: string;
|
|
||||||
secretPath?: string;
|
|
||||||
secretReminderNote?: string;
|
|
||||||
secretReminderRepeatDays?: number;
|
|
||||||
skipMultilineEncoding?: boolean;
|
|
||||||
tagIds?: string[];
|
|
||||||
type?: SecretType;
|
|
||||||
metadata?: Record<string, any>;
|
|
||||||
secretMetadata?: Record<string, any>[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UpdateSecretOptions = {
|
|
||||||
secretValue?: string;
|
|
||||||
newSecretName?: string;
|
|
||||||
} & BaseSecretOptions;
|
|
||||||
|
|
||||||
export type CreateSecretOptions = {
|
|
||||||
secretValue: string;
|
|
||||||
} & BaseSecretOptions;
|
|
||||||
|
|
||||||
export type DeleteSecretOptions = {
|
|
||||||
environment: string;
|
|
||||||
projectId: string;
|
|
||||||
secretPath?: string;
|
|
||||||
type?: SecretType;
|
|
||||||
};
|
|
||||||
|
|
||||||
const convertBool = (value?: boolean) => (value ? "true" : "false");
|
const convertBool = (value?: boolean) => (value ? "true" : "false");
|
||||||
|
|
||||||
@@ -100,6 +46,11 @@ export default class SecretsClient {
|
|||||||
if (imports) {
|
if (imports) {
|
||||||
for (const imp of imports) {
|
for (const imp of imports) {
|
||||||
for (const importedSecret of imp.secrets) {
|
for (const importedSecret of imp.secrets) {
|
||||||
|
// CASE: We need to ensure that the imported values don't override the "base" secrets.
|
||||||
|
// Priority order is:
|
||||||
|
// Local/Preset variables -> Actual secrets -> Imported secrets (high->low)
|
||||||
|
|
||||||
|
// Check if the secret already exists in the secrets list
|
||||||
if (!secrets.find((s) => s.secretKey === importedSecret.secretKey)) {
|
if (!secrets.find((s) => s.secretKey === importedSecret.secretKey)) {
|
||||||
secrets.push({
|
secrets.push({
|
||||||
...importedSecret,
|
...importedSecret,
|
||||||
|
|||||||
@@ -97,10 +97,3 @@ export {
|
|||||||
TDynamicSecretProvider,
|
TDynamicSecretProvider,
|
||||||
DynamicSecretProviders,
|
DynamicSecretProviders,
|
||||||
} from "./custom/schemas";
|
} from "./custom/schemas";
|
||||||
|
|
||||||
// Export domain-specific types
|
|
||||||
export * from "./custom/secrets";
|
|
||||||
export * from "./custom/dynamic-secrets";
|
|
||||||
export * from "./custom/environments";
|
|
||||||
export * from "./custom/projects";
|
|
||||||
export * from "./custom/folders";
|
|
||||||
|
|||||||
Reference in New Issue
Block a user