mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 21:51:56 +00:00
Merge branch 'main' into feat/secretsBatchUI
This commit is contained in:
@@ -49,6 +49,7 @@ export type TServerConfig = {
|
||||
authConsentContent?: string;
|
||||
pageFrameContent?: string;
|
||||
invalidatingCache: boolean;
|
||||
fipsEnabled: boolean;
|
||||
envOverrides?: Record<string, string>;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./queries";
|
||||
export * from "./types";
|
||||
@@ -0,0 +1,37 @@
|
||||
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
import { appConnectionKeys } from "@app/hooks/api/appConnections";
|
||||
|
||||
import { TChecklyAccount } from "./types";
|
||||
|
||||
const checklyConnectionKeys = {
|
||||
all: [...appConnectionKeys.all, "checkly"] as const,
|
||||
listAccounts: (connectionId: string) =>
|
||||
[...checklyConnectionKeys.all, "workspace-scopes", connectionId] as const
|
||||
};
|
||||
|
||||
export const useChecklyConnectionListAccounts = (
|
||||
connectionId: string,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
TChecklyAccount[],
|
||||
unknown,
|
||||
TChecklyAccount[],
|
||||
ReturnType<typeof checklyConnectionKeys.listAccounts>
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: checklyConnectionKeys.listAccounts(connectionId),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<{ accounts: TChecklyAccount[] }>(
|
||||
`/api/v1/app-connections/checkly/${connectionId}/accounts`
|
||||
);
|
||||
|
||||
return data.accounts;
|
||||
},
|
||||
...options
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export type TChecklyAccount = {
|
||||
id: string;
|
||||
name: string;
|
||||
runtimeId: string;
|
||||
};
|
||||
@@ -3,21 +3,23 @@ import { useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { appConnectionKeys } from "../queries";
|
||||
import { TCloudflareProject } from "./types";
|
||||
import { TCloudflarePagesProject, TCloudflareWorkersScript } from "./types";
|
||||
|
||||
const cloudflareConnectionKeys = {
|
||||
all: [...appConnectionKeys.all, "cloudflare"] as const,
|
||||
listPagesProjects: (connectionId: string) =>
|
||||
[...cloudflareConnectionKeys.all, "pages-projects", connectionId] as const
|
||||
[...cloudflareConnectionKeys.all, "pages-projects", connectionId] as const,
|
||||
listWorkersScripts: (connectionId: string) =>
|
||||
[...cloudflareConnectionKeys.all, "workers-scripts", connectionId] as const
|
||||
};
|
||||
|
||||
export const useCloudflareConnectionListPagesProjects = (
|
||||
connectionId: string,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
TCloudflareProject[],
|
||||
TCloudflarePagesProject[],
|
||||
unknown,
|
||||
TCloudflareProject[],
|
||||
TCloudflarePagesProject[],
|
||||
ReturnType<typeof cloudflareConnectionKeys.listPagesProjects>
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
@@ -26,7 +28,7 @@ export const useCloudflareConnectionListPagesProjects = (
|
||||
return useQuery({
|
||||
queryKey: cloudflareConnectionKeys.listPagesProjects(connectionId),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<TCloudflareProject[]>(
|
||||
const { data } = await apiRequest.get<TCloudflarePagesProject[]>(
|
||||
`/api/v1/app-connections/cloudflare/${connectionId}/cloudflare-pages-projects`
|
||||
);
|
||||
|
||||
@@ -35,3 +37,28 @@ export const useCloudflareConnectionListPagesProjects = (
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
export const useCloudflareConnectionListWorkersScripts = (
|
||||
connectionId: string,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
TCloudflareWorkersScript[],
|
||||
unknown,
|
||||
TCloudflareWorkersScript[],
|
||||
ReturnType<typeof cloudflareConnectionKeys.listWorkersScripts>
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: cloudflareConnectionKeys.listWorkersScripts(connectionId),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<TCloudflareWorkersScript[]>(
|
||||
`/api/v1/app-connections/cloudflare/${connectionId}/cloudflare-workers-scripts`
|
||||
);
|
||||
|
||||
return data;
|
||||
},
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
export type TCloudflareProject = {
|
||||
export type TCloudflarePagesProject = {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type TCloudflareWorkersScript = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
@@ -30,5 +30,6 @@ export enum AppConnection {
|
||||
Cloudflare = "cloudflare",
|
||||
Bitbucket = "bitbucket",
|
||||
Zabbix = "zabbix",
|
||||
Railway = "railway"
|
||||
Railway = "railway",
|
||||
Checkly = "checkly"
|
||||
}
|
||||
|
||||
@@ -144,6 +144,10 @@ export type TRailwayConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.Railway;
|
||||
};
|
||||
|
||||
export type TChecklyConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.Checkly;
|
||||
};
|
||||
|
||||
export type TAppConnectionOption =
|
||||
| TAwsConnectionOption
|
||||
| TGitHubConnectionOption
|
||||
@@ -174,7 +178,8 @@ export type TAppConnectionOption =
|
||||
| TCloudflareConnectionOption
|
||||
| TBitbucketConnectionOption
|
||||
| TZabbixConnectionOption
|
||||
| TRailwayConnectionOption;
|
||||
| TRailwayConnectionOption
|
||||
| TChecklyConnectionOption;
|
||||
|
||||
export type TAppConnectionOptionMap = {
|
||||
[AppConnection.AWS]: TAwsConnectionOption;
|
||||
@@ -209,4 +214,5 @@ export type TAppConnectionOptionMap = {
|
||||
[AppConnection.Bitbucket]: TBitbucketConnectionOption;
|
||||
[AppConnection.Zabbix]: TZabbixConnectionOption;
|
||||
[AppConnection.Railway]: TRailwayConnectionOption;
|
||||
[AppConnection.Checkly]: TChecklyConnectionOption;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
|
||||
|
||||
export enum ChecklyConnectionMethod {
|
||||
ApiKey = "api-key"
|
||||
}
|
||||
|
||||
export type TChecklyConnection = TRootAppConnection & {
|
||||
app: AppConnection.Checkly;
|
||||
method: ChecklyConnectionMethod.ApiKey;
|
||||
credentials: {
|
||||
apiKey: string;
|
||||
};
|
||||
};
|
||||
@@ -9,6 +9,7 @@ import { TAzureDevOpsConnection } from "./azure-devops-connection";
|
||||
import { TAzureKeyVaultConnection } from "./azure-key-vault-connection";
|
||||
import { TBitbucketConnection } from "./bitbucket-connection";
|
||||
import { TCamundaConnection } from "./camunda-connection";
|
||||
import { TChecklyConnection } from "./checkly-connection";
|
||||
import { TCloudflareConnection } from "./cloudflare-connection";
|
||||
import { TDatabricksConnection } from "./databricks-connection";
|
||||
import { TFlyioConnection } from "./flyio-connection";
|
||||
@@ -97,7 +98,8 @@ export type TAppConnection =
|
||||
| TCloudflareConnection
|
||||
| TBitbucketConnection
|
||||
| TZabbixConnection
|
||||
| TRailwayConnection;
|
||||
| TRailwayConnection
|
||||
| TChecklyConnection;
|
||||
|
||||
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
|
||||
|
||||
@@ -157,4 +159,5 @@ export type TAppConnectionMap = {
|
||||
[AppConnection.Bitbucket]: TBitbucketConnection;
|
||||
[AppConnection.Zabbix]: TZabbixConnection;
|
||||
[AppConnection.Railway]: TRailwayConnection;
|
||||
[AppConnection.Checkly]: TChecklyConnection;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { encodeBase64 } from "tweetnacl-util";
|
||||
|
||||
import { encodeBase64 } from "@app/components/utilities/cryptography/crypto";
|
||||
import { apiRequest } from "@app/config/request";
|
||||
import { cmekKeys } from "@app/hooks/api/cmeks/queries";
|
||||
import {
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||
|
||||
import {
|
||||
decryptAssymmetric,
|
||||
decryptSymmetric
|
||||
} from "@app/components/utilities/cryptography/crypto";
|
||||
import { apiRequest } from "@app/config/request";
|
||||
import { TReactQueryOptions } from "@app/types/reactQuery";
|
||||
|
||||
import { UserWsKeyPair } from "../keys/types";
|
||||
import { EncryptedSecret, SecretType, SecretV3RawSanitized } from "../secrets/types";
|
||||
import {
|
||||
TGetSecretApprovalRequestCount,
|
||||
TGetSecretApprovalRequestDetails,
|
||||
@@ -41,79 +35,6 @@ export const secretApprovalRequestKeys = {
|
||||
]
|
||||
};
|
||||
|
||||
export const decryptSecrets = (
|
||||
encryptedSecrets: EncryptedSecret[],
|
||||
decryptFileKey: UserWsKeyPair
|
||||
) => {
|
||||
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string;
|
||||
const key = decryptAssymmetric({
|
||||
ciphertext: decryptFileKey.encryptedKey,
|
||||
nonce: decryptFileKey.nonce,
|
||||
publicKey: decryptFileKey.sender.publicKey,
|
||||
privateKey: PRIVATE_KEY
|
||||
});
|
||||
|
||||
const personalSecrets: Record<string, { id: string; value: string }> = {};
|
||||
const secrets: SecretV3RawSanitized[] = [];
|
||||
encryptedSecrets.forEach((encSecret) => {
|
||||
const secretKey = decryptSymmetric({
|
||||
ciphertext: encSecret.secretKeyCiphertext,
|
||||
iv: encSecret.secretKeyIV,
|
||||
tag: encSecret.secretKeyTag,
|
||||
key
|
||||
});
|
||||
|
||||
const secretValue = decryptSymmetric({
|
||||
ciphertext: encSecret.secretValueCiphertext,
|
||||
iv: encSecret.secretValueIV,
|
||||
tag: encSecret.secretValueTag,
|
||||
key
|
||||
});
|
||||
|
||||
const secretComment = decryptSymmetric({
|
||||
ciphertext: encSecret.secretCommentCiphertext,
|
||||
iv: encSecret.secretCommentIV,
|
||||
tag: encSecret.secretCommentTag,
|
||||
key
|
||||
});
|
||||
|
||||
const decryptedSecret: SecretV3RawSanitized = {
|
||||
id: encSecret.id,
|
||||
env: encSecret.environment,
|
||||
key: secretKey,
|
||||
secretValueHidden: encSecret.secretValueHidden,
|
||||
value: secretValue,
|
||||
tags: encSecret.tags,
|
||||
comment: secretComment,
|
||||
reminderRepeatDays: encSecret.secretReminderRepeatDays,
|
||||
reminderNote: encSecret.secretReminderNote,
|
||||
createdAt: encSecret.createdAt,
|
||||
updatedAt: encSecret.updatedAt,
|
||||
version: encSecret.version,
|
||||
skipMultilineEncoding: encSecret.skipMultilineEncoding
|
||||
};
|
||||
|
||||
if (encSecret.type === SecretType.Personal) {
|
||||
personalSecrets[decryptedSecret.key] = {
|
||||
id: encSecret.id,
|
||||
value: secretValue
|
||||
};
|
||||
} else {
|
||||
secrets.push(decryptedSecret);
|
||||
}
|
||||
});
|
||||
|
||||
secrets.forEach((sec) => {
|
||||
if (personalSecrets?.[sec.key]) {
|
||||
sec.idOverride = personalSecrets[sec.key].id;
|
||||
sec.valueOverride = personalSecrets[sec.key].value;
|
||||
sec.overrideAction = "modified";
|
||||
}
|
||||
});
|
||||
|
||||
return secrets;
|
||||
};
|
||||
|
||||
const fetchSecretApprovalRequestList = async ({
|
||||
workspaceId,
|
||||
environment,
|
||||
|
||||
@@ -43,6 +43,7 @@ export type TSecretApprovalRequest = {
|
||||
isReplicated?: boolean;
|
||||
slug: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
committerUserId: string;
|
||||
reviewers: {
|
||||
userId: string;
|
||||
|
||||
@@ -21,8 +21,11 @@ export enum SecretSync {
|
||||
Flyio = "flyio",
|
||||
GitLab = "gitlab",
|
||||
CloudflarePages = "cloudflare-pages",
|
||||
CloudflareWorkers = "cloudflare-workers",
|
||||
|
||||
Zabbix = "zabbix",
|
||||
Railway = "railway"
|
||||
Railway = "railway",
|
||||
Checkly = "checkly"
|
||||
}
|
||||
|
||||
export enum SecretSyncStatus {
|
||||
|
||||
@@ -6,7 +6,7 @@ export type TAzureDevOpsSync = TRootSecretSync & {
|
||||
destination: SecretSync.AzureDevOps;
|
||||
destinationConfig: {
|
||||
devopsProjectId: string;
|
||||
devopsProjectName: string;
|
||||
devopsProjectName?: string;
|
||||
};
|
||||
connection: {
|
||||
app: AppConnection.AzureDevOps;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
|
||||
|
||||
export type TChecklySync = TRootSecretSync & {
|
||||
destination: SecretSync.Checkly;
|
||||
destinationConfig: {
|
||||
accountId: string;
|
||||
accountName: string;
|
||||
};
|
||||
connection: {
|
||||
app: AppConnection.Checkly;
|
||||
name: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
|
||||
|
||||
export type TCloudflareWorkersSync = TRootSecretSync & {
|
||||
destination: SecretSync.CloudflareWorkers;
|
||||
destinationConfig: {
|
||||
scriptId: string;
|
||||
};
|
||||
connection: {
|
||||
app: AppConnection.Cloudflare;
|
||||
name: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
@@ -9,7 +9,9 @@ import { TAzureAppConfigurationSync } from "./azure-app-configuration-sync";
|
||||
import { TAzureDevOpsSync } from "./azure-devops-sync";
|
||||
import { TAzureKeyVaultSync } from "./azure-key-vault-sync";
|
||||
import { TCamundaSync } from "./camunda-sync";
|
||||
import { TChecklySync } from "./checkly-sync";
|
||||
import { TCloudflarePagesSync } from "./cloudflare-pages-sync";
|
||||
import { TCloudflareWorkersSync } from "./cloudflare-workers-sync";
|
||||
import { TDatabricksSync } from "./databricks-sync";
|
||||
import { TFlyioSync } from "./flyio-sync";
|
||||
import { TGcpSync } from "./gcp-sync";
|
||||
@@ -56,8 +58,10 @@ export type TSecretSync =
|
||||
| TFlyioSync
|
||||
| TGitLabSync
|
||||
| TCloudflarePagesSync
|
||||
| TCloudflareWorkersSync
|
||||
| TZabbixSync
|
||||
| TRailwaySync;
|
||||
| TRailwaySync
|
||||
| TChecklySync;
|
||||
|
||||
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export * from "./secrets/types";
|
||||
export type { CreateServiceTokenDTO, ServiceToken } from "./serviceTokens/types";
|
||||
export type { SubscriptionPlan } from "./subscriptions/types";
|
||||
export type { WsTag } from "./tags/types";
|
||||
export type { AddUserToWsDTOE2EE, OrgUser, TWorkspaceUser, User, UserEnc } from "./users/types";
|
||||
export type { OrgUser, TWorkspaceUser, User, UserEnc } from "./users/types";
|
||||
export type { TWebhook } from "./webhooks/types";
|
||||
export type {
|
||||
CreateEnvironmentDTO,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export {
|
||||
useAddUserToWsE2EE,
|
||||
useAddUserToWsNonE2EE,
|
||||
useRemoveMyDuplicateAccounts,
|
||||
useRevokeMySessionById,
|
||||
|
||||
@@ -1,51 +1,10 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import {
|
||||
decryptAssymmetric,
|
||||
encryptAssymmetric
|
||||
} from "@app/components/utilities/cryptography/crypto";
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { workspaceKeys } from "../workspace";
|
||||
import { userKeys } from "./query-keys";
|
||||
import { AddUserToWsDTOE2EE, AddUserToWsDTONonE2EE } from "./types";
|
||||
|
||||
export const useAddUserToWsE2EE = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<object, object, AddUserToWsDTOE2EE>({
|
||||
mutationFn: async ({ workspaceId, members, decryptKey, userPrivateKey }) => {
|
||||
// assymmetrically decrypt symmetric key with local private key
|
||||
const key = decryptAssymmetric({
|
||||
ciphertext: decryptKey.encryptedKey,
|
||||
nonce: decryptKey.nonce,
|
||||
publicKey: decryptKey.sender.publicKey,
|
||||
privateKey: userPrivateKey
|
||||
});
|
||||
|
||||
const newWsMembers = members.map(({ orgMembershipId, userPublicKey }) => {
|
||||
const { ciphertext: inviteeCipherText, nonce: inviteeNonce } = encryptAssymmetric({
|
||||
plaintext: key,
|
||||
publicKey: userPublicKey,
|
||||
privateKey: userPrivateKey
|
||||
});
|
||||
|
||||
return {
|
||||
orgMembershipId,
|
||||
workspaceEncryptedKey: inviteeCipherText,
|
||||
workspaceEncryptedNonce: inviteeNonce
|
||||
};
|
||||
});
|
||||
const { data } = await apiRequest.post(`/api/v1/workspace/${workspaceId}/memberships`, {
|
||||
members: newWsMembers
|
||||
});
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { workspaceId }) => {
|
||||
queryClient.invalidateQueries({ queryKey: workspaceKeys.getWorkspaceUsers(workspaceId) });
|
||||
}
|
||||
});
|
||||
};
|
||||
import { AddUserToWsDTONonE2EE } from "./types";
|
||||
|
||||
export const useAddUserToWsNonE2EE = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { MfaMethod } from "../auth/types";
|
||||
import { UserWsKeyPair } from "../keys/types";
|
||||
import { ProjectType, ProjectUserMembershipTemporaryMode } from "../workspace/types";
|
||||
|
||||
export enum AuthMethod {
|
||||
@@ -129,16 +128,6 @@ export type TWorkspaceUser = {
|
||||
deniedPermissions: any[];
|
||||
};
|
||||
|
||||
export type AddUserToWsDTOE2EE = {
|
||||
workspaceId: string;
|
||||
decryptKey: UserWsKeyPair;
|
||||
userPrivateKey: string;
|
||||
members: {
|
||||
orgMembershipId: string;
|
||||
userPublicKey: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type AddUserToWsDTONonE2EE = {
|
||||
projectId: string;
|
||||
usernames: string[];
|
||||
|
||||
Reference in New Issue
Block a user