Merge branch 'main' into add-bull-queue

This commit is contained in:
Maidul Islam
2023-08-19 13:46:26 -04:00
committed by GitHub
383 changed files with 7173 additions and 8536 deletions
@@ -0,0 +1,43 @@
import { EventType, UserAgentType } from "./enums";
export const eventToNameMap: { [K in EventType]: string } = {
[EventType.GET_SECRETS]: "List secrets",
[EventType.GET_SECRET]: "Read secret",
[EventType.CREATE_SECRET]: "Create secret",
[EventType.UPDATE_SECRET]: "Update secret",
[EventType.DELETE_SECRET]: "Delete secret",
[EventType.GET_WORKSPACE_KEY]: "Read project key",
[EventType.AUTHORIZE_INTEGRATION]: "Authorize integration",
[EventType.UNAUTHORIZE_INTEGRATION]: "Unauthorize integration",
[EventType.CREATE_INTEGRATION]: "Create integration",
[EventType.DELETE_INTEGRATION]: "Delete integration",
[EventType.ADD_TRUSTED_IP]: "Add trusted IP",
[EventType.UPDATE_TRUSTED_IP]: "Update trusted IP",
[EventType.DELETE_TRUSTED_IP]: "Delete trusted IP",
[EventType.CREATE_SERVICE_TOKEN]: "Create service token",
[EventType.DELETE_SERVICE_TOKEN]: "Delete service token",
[EventType.CREATE_ENVIRONMENT]: "Create environment",
[EventType.UPDATE_ENVIRONMENT]: "Update environment",
[EventType.DELETE_ENVIRONMENT]: "Delete environment",
[EventType.ADD_WORKSPACE_MEMBER]: "Add member",
[EventType.REMOVE_WORKSPACE_MEMBER]: "Remove member",
[EventType.CREATE_FOLDER]: "Create folder",
[EventType.UPDATE_FOLDER]: "Update folder",
[EventType.DELETE_FOLDER]: "Delete folder",
[EventType.CREATE_WEBHOOK]: "Create webhook",
[EventType.UPDATE_WEBHOOK_STATUS]: "Update webhook status",
[EventType.DELETE_WEBHOOK]: "Delete webhook",
[EventType.GET_SECRET_IMPORTS]: "List secret imports",
[EventType.CREATE_SECRET_IMPORT]: "Create secret import",
[EventType.UPDATE_SECRET_IMPORT]: "Update secret import",
[EventType.DELETE_SECRET_IMPORT]: "Delete secret import",
[EventType.UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS]: "Update denied permissions",
[EventType.UPDATE_USER_WORKSPACE_ROLE]: "Update user role"
};
export const userAgentTTypeoNameMap: { [K in UserAgentType]: string } = {
[UserAgentType.WEB]: "Web",
[UserAgentType.CLI]: "CLI",
[UserAgentType.K8_OPERATOR]: "K8s operator",
[UserAgentType.OTHER]: "Other",
};
@@ -0,0 +1,46 @@
export enum ActorType {
USER = "user",
SERVICE = "service"
}
export enum UserAgentType {
WEB = "web",
CLI = "cli",
K8_OPERATOR = "k8-operator",
OTHER = "other"
}
export enum EventType {
GET_SECRETS = "get-secrets",
GET_SECRET = "get-secret",
CREATE_SECRET = "create-secret",
UPDATE_SECRET = "update-secret",
DELETE_SECRET = "delete-secret",
GET_WORKSPACE_KEY = "get-workspace-key",
AUTHORIZE_INTEGRATION = "authorize-integration",
UNAUTHORIZE_INTEGRATION = "unauthorize-integration",
CREATE_INTEGRATION = "create-integration",
DELETE_INTEGRATION = "delete-integration",
ADD_TRUSTED_IP = "add-trusted-ip",
UPDATE_TRUSTED_IP = "update-trusted-ip",
DELETE_TRUSTED_IP = "delete-trusted-ip",
CREATE_SERVICE_TOKEN = "create-service-token",
DELETE_SERVICE_TOKEN = "delete-service-token",
CREATE_ENVIRONMENT = "create-environment",
UPDATE_ENVIRONMENT = "update-environment",
DELETE_ENVIRONMENT = "delete-environment",
ADD_WORKSPACE_MEMBER = "add-workspace-member",
REMOVE_WORKSPACE_MEMBER = "remove-workspace-member",
CREATE_FOLDER = "create-folder",
UPDATE_FOLDER = "update-folder",
DELETE_FOLDER = "delete-folder",
CREATE_WEBHOOK = "create-webhook",
UPDATE_WEBHOOK_STATUS = "update-webhook-status",
DELETE_WEBHOOK = "delete-webhook",
GET_SECRET_IMPORTS = "get-secret-imports",
CREATE_SECRET_IMPORT = "create-secret-import",
UPDATE_SECRET_IMPORT = "update-secret-import",
DELETE_SECRET_IMPORT = "delete-secret-import",
UPDATE_USER_WORKSPACE_ROLE = "update-user-workspace-role",
UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS = "update-user-workspace-denied-permissions"
}
@@ -0,0 +1 @@
export * from "./queries";
@@ -0,0 +1,59 @@
import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import {
Actor,
AuditLog,
AuditLogFilters
} from "./types";
export const workspaceKeys = {
getAuditLogs: (workspaceId: string, filters: AuditLogFilters) => [{ workspaceId, filters }, "audit-logs"] as const,
getAuditLogActorFilterOpts: (workspaceId: string) => [{ workspaceId }, "audit-log-actor-filters"] as const
}
export const useGetAuditLogs = (workspaceId: string, filters: AuditLogFilters) => {
return useQuery({
queryKey: workspaceKeys.getAuditLogs(workspaceId, filters),
queryFn: async () => {
const params = new URLSearchParams();
if (filters.eventType) {
params.append("eventType", filters.eventType);
}
if (filters.userAgentType) {
params.append("userAgentType", filters.userAgentType);
}
if (filters.actor) {
params.append("actor", filters.actor);
}
if (filters.startDate) {
params.append("startDate", filters.startDate.toISOString());
}
if (filters.endDate) {
params.append("endDate", filters.endDate.toISOString());
}
params.append("offset", String(filters.offset));
params.append("limit", String(filters.limit));
const { data } = await apiRequest.get<{ auditLogs: AuditLog[], totalCount: number }>(`/api/v1/workspace/${workspaceId}/audit-logs`, { params });
return data;
}
});
}
export const useGetAuditLogActorFilterOpts = (workspaceId: string) => {
return useQuery({
queryKey: workspaceKeys.getAuditLogActorFilterOpts(workspaceId),
queryFn: async () => {
const { data } = await apiRequest.get<{ actors: Actor[] }>(`/api/v1/workspace/${workspaceId}/audit-logs/filters/actors`);
return data.actors;
}
});
}
+429
View File
@@ -0,0 +1,429 @@
import {
ActorType,
EventType,
UserAgentType
} from "./enums";
interface UserActorMetadata {
userId: string;
email: string;
}
interface ServiceActorMetadata {
serviceId: string;
name: string;
}
interface UserActor {
type: ActorType.USER;
metadata: UserActorMetadata;
}
export interface ServiceActor {
type: ActorType.SERVICE;
metadata: ServiceActorMetadata;
}
export type Actor =
| UserActor
| ServiceActor;
interface GetSecretsEvent {
type: EventType.GET_SECRETS;
metadata: {
environment: string;
secretPath: string;
numberOfSecrets: number;
};
}
interface GetSecretEvent {
type: EventType.GET_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
};
}
interface CreateSecretEvent {
type: EventType.CREATE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
}
}
interface UpdateSecretEvent {
type: EventType.UPDATE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
}
}
interface DeleteSecretEvent {
type: EventType.DELETE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
}
}
interface GetWorkspaceKeyEvent {
type: EventType.GET_WORKSPACE_KEY,
metadata: {
keyId: string;
}
}
interface AuthorizeIntegrationEvent {
type: EventType.AUTHORIZE_INTEGRATION;
metadata: {
integration: string;
}
}
interface UnauthorizeIntegrationEvent {
type: EventType.UNAUTHORIZE_INTEGRATION;
metadata: {
integration: string;
}
}
interface CreateIntegrationEvent {
type: EventType.CREATE_INTEGRATION;
metadata: {
integrationId: string;
integration: string;
environment: string;
secretPath: string;
url?: string;
app?: string;
appId?: string;
targetEnvironment?: string;
targetEnvironmentId?: string;
targetService?: string;
targetServiceId?: string;
path?: string;
region?: string;
}
}
interface DeleteIntegrationEvent {
type: EventType.DELETE_INTEGRATION;
metadata: {
integrationId: string;
integration: string;
environment: string;
secretPath: string;
url?: string;
app?: string;
appId?: string;
targetEnvironment?: string;
targetEnvironmentId?: string;
targetService?: string;
targetServiceId?: string;
path?: string;
region?: string;
}
}
interface AddTrustedIPEvent {
type: EventType.ADD_TRUSTED_IP;
metadata: {
trustedIpId: string;
ipAddress: string;
prefix?: number;
}
}
interface UpdateTrustedIPEvent {
type: EventType.UPDATE_TRUSTED_IP;
metadata: {
trustedIpId: string;
ipAddress: string;
prefix?: number;
}
}
interface DeleteTrustedIPEvent {
type: EventType.DELETE_TRUSTED_IP;
metadata: {
trustedIpId: string;
ipAddress: string;
prefix?: number;
}
}
interface CreateServiceTokenEvent {
type: EventType.CREATE_SERVICE_TOKEN;
metadata: {
name: string;
scopes: Array<{
environment: string;
secretPath: string;
}>;
}
}
interface DeleteServiceTokenEvent {
type: EventType.DELETE_SERVICE_TOKEN;
metadata: {
name: string;
scopes: Array<{
environment: string;
secretPath: string;
}>;
}
}
interface CreateEnvironmentEvent {
type: EventType.CREATE_ENVIRONMENT;
metadata: {
name: string;
slug: string;
}
}
interface UpdateEnvironmentEvent {
type: EventType.UPDATE_ENVIRONMENT;
metadata: {
oldName: string;
newName: string;
oldSlug: string;
newSlug: string;
}
}
interface DeleteEnvironmentEvent {
type: EventType.DELETE_ENVIRONMENT;
metadata: {
name: string;
slug: string;
}
}
interface AddWorkspaceMemberEvent {
type: EventType.ADD_WORKSPACE_MEMBER;
metadata: {
userId: string;
email: string;
}
}
interface RemoveWorkspaceMemberEvent {
type: EventType.REMOVE_WORKSPACE_MEMBER;
metadata: {
userId: string;
email: string;
}
}
interface CreateFolderEvent {
type: EventType.CREATE_FOLDER;
metadata: {
environment: string;
folderId: string;
folderName: string;
folderPath: string;
}
}
interface UpdateFolderEvent {
type: EventType.UPDATE_FOLDER;
metadata: {
environment: string;
folderId: string;
oldFolderName: string;
newFolderName: string;
folderPath: string;
}
}
interface DeleteFolderEvent {
type: EventType.DELETE_FOLDER;
metadata: {
environment: string;
folderId: string;
folderName: string;
folderPath: string;
}
}
interface CreateWebhookEvent {
type: EventType.CREATE_WEBHOOK,
metadata: {
webhookId: string;
environment: string;
secretPath: string;
webhookUrl: string;
isDisabled: boolean;
}
}
interface UpdateWebhookStatusEvent {
type: EventType.UPDATE_WEBHOOK_STATUS,
metadata: {
webhookId: string;
environment: string;
secretPath: string;
webhookUrl: string;
isDisabled: boolean;
}
}
interface DeleteWebhookEvent {
type: EventType.DELETE_WEBHOOK,
metadata: {
webhookId: string;
environment: string;
secretPath: string;
webhookUrl: string;
isDisabled: boolean;
}
}
interface GetSecretImportsEvent {
type: EventType.GET_SECRET_IMPORTS,
metadata: {
environment: string;
secretImportId: string;
folderId: string;
numberOfImports: number;
}
}
interface CreateSecretImportEvent {
type: EventType.CREATE_SECRET_IMPORT,
metadata: {
secretImportId: string;
folderId: string;
importFromEnvironment: string;
importFromSecretPath: string;
importToEnvironment: string;
importToSecretPath: string;
}
}
interface UpdateSecretImportEvent {
type: EventType.UPDATE_SECRET_IMPORT,
metadata: {
secretImportId: string;
folderId: string;
importToEnvironment: string;
importToSecretPath: string;
orderBefore: {
environment: string;
secretPath: string;
}[],
orderAfter: {
environment: string;
secretPath: string;
}[]
}
}
interface DeleteSecretImportEvent {
type: EventType.DELETE_SECRET_IMPORT,
metadata: {
secretImportId: string;
folderId: string;
importFromEnvironment: string;
importFromSecretPath: string;
importToEnvironment: string;
importToSecretPath: string;
}
}
interface UpdateUserRole {
type: EventType.UPDATE_USER_WORKSPACE_ROLE,
metadata: {
userId: string;
email: string;
oldRole: string;
newRole: string;
}
}
interface UpdateUserDeniedPermissions {
type: EventType.UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS,
metadata: {
userId: string;
email: string;
deniedPermissions: {
environmentSlug: string;
ability: string;
}[]
}
}
export type Event =
| GetSecretsEvent
| GetSecretEvent
| CreateSecretEvent
| UpdateSecretEvent
| DeleteSecretEvent
| GetWorkspaceKeyEvent
| AuthorizeIntegrationEvent
| UnauthorizeIntegrationEvent
| CreateIntegrationEvent
| DeleteIntegrationEvent
| AddTrustedIPEvent
| UpdateTrustedIPEvent
| DeleteTrustedIPEvent
| CreateServiceTokenEvent
| DeleteServiceTokenEvent
| CreateEnvironmentEvent
| UpdateEnvironmentEvent
| DeleteEnvironmentEvent
| AddWorkspaceMemberEvent
| RemoveWorkspaceMemberEvent
| CreateFolderEvent
| UpdateFolderEvent
| DeleteFolderEvent
| CreateWebhookEvent
| UpdateWebhookStatusEvent
| DeleteWebhookEvent
| GetSecretImportsEvent
| CreateSecretImportEvent
| UpdateSecretImportEvent
| DeleteSecretImportEvent
| UpdateUserRole
| UpdateUserDeniedPermissions;
export type AuditLog = {
_id: string;
actor: Actor;
organization: string;
workspace: string;
ipAddress: string;
event: Event;
userAgent: string;
userAgentType: UserAgentType;
createdAt: string;
updatedAt: string;
}
export type AuditLogFilters = {
eventType?: EventType;
userAgentType?: UserAgentType;
actor?: string;
offset: number;
limit: number;
startDate?: Date;
endDate?: Date;
}
+6 -2
View File
@@ -1,6 +1,10 @@
export {
useGetAuthToken,
useGetCommonPasswords,
useResetPassword,
useSendMfaToken,
useVerifyMfaToken
} from "./queries"
useSendPasswordResetEmail,
useSendVerificationEmail,
useVerifyEmailVerificationCode,
useVerifyMfaToken,
useVerifyPasswordResetCode} from "./queries"
+216 -3
View File
@@ -4,16 +4,86 @@ import { apiRequest } from "@app/config/request";
import { setAuthToken } from "@app/reactQuery";
import {
ChangePasswordDTO,
CompleteAccountDTO,
CompleteAccountSignupDTO,
GetAuthTokenAPI,
GetBackupEncryptedPrivateKeyDTO,
IssueBackupPrivateKeyDTO,
Login1DTO,
Login1Res,
Login2DTO,
Login2Res,
ResetPasswordDTO,
SendMfaTokenDTO,
SRP1DTO,
SRPR1Res,
VerifyMfaTokenDTO,
VerifyMfaTokenRes} from "./types";
VerifyMfaTokenRes,
VerifySignupInviteDTO} from "./types";
const authKeys = {
getAuthToken: ["token"] as const,
commonPasswords: ["common-passwords"] as const
};
export const login1 = async (loginDetails: Login1DTO) => {
const { data } = await apiRequest.post<Login1Res>("/api/v3/auth/login1", loginDetails);
return data;
}
export const login2 = async (loginDetails: Login2DTO) => {
const { data } = await apiRequest.post<Login2Res>("/api/v3/auth/login2", loginDetails);
return data;
}
export const useLogin1 = () => {
return useMutation({
mutationFn: async (details: {
email: string;
clientPublicKey: string;
providerAuthToken?: string;
}) => {
return login1(details);
}
});
}
export const useLogin2 = () => {
return useMutation({
mutationFn: async (details: {
email: string;
clientProof: string;
providerAuthToken?: string;
}) => {
return login2(details);
}
});
}
export const srp1 = async (details: SRP1DTO) => {
const { data } = await apiRequest.post<SRPR1Res>("/api/v1/password/srp1", details);
return data;
}
export const completeAccountSignup = async (details: CompleteAccountSignupDTO) => {
const { data } = await apiRequest.post("/api/v3/signup/complete-account/signup", details);
return data;
}
export const completeAccountSignupInvite = async (details: CompleteAccountDTO) => {
const { data } = await apiRequest.post("/api/v2/signup/complete-account/invite", details);
return data;
}
export const useCompleteAccountSignup = () => {
return useMutation({
mutationFn: async (details: CompleteAccountSignupDTO) => {
return completeAccountSignup(details);
}
});
}
export const useSendMfaToken = () => {
return useMutation<{}, {}, SendMfaTokenDTO>({
mutationFn: async ({ email }) => {
@@ -23,18 +93,161 @@ export const useSendMfaToken = () => {
});
}
export const verifyMfaToken = async ({
email,
mfaCode
}: {
email: string;
mfaCode: string;
}) => {
const { data } = await apiRequest.post("/api/v2/auth/mfa/verify", {
email,
mfaToken: mfaCode
});
return data;
}
export const useVerifyMfaToken = () => {
return useMutation<VerifyMfaTokenRes, {}, VerifyMfaTokenDTO>({
mutationFn: async ({ email, mfaCode }) => {
const { data } = await apiRequest.post("/api/v2/auth/mfa/verify", {
return verifyMfaToken({
email,
mfaToken: mfaCode
mfaCode
});
}
});
}
export const verifySignupInvite = async (details: VerifySignupInviteDTO) => {
const { data } = await apiRequest.post("/api/v1/invite-org/verify", details);
return data;
}
export const useSendVerificationEmail = () => {
return useMutation({
mutationFn: async ({
email
}: {
email: string;
}) => {
const { data } = await apiRequest.post("/api/v1/signup/email/signup", {
email
});
return data;
}
});
}
export const useVerifyEmailVerificationCode = () => {
return useMutation({
mutationFn: async ({
email,
code
}: {
email: string;
code: string;
}) => {
const { data } = await apiRequest.post("/api/v1/signup/email/verify", {
email,
code
});
return data;
}
});
}
export const useSendPasswordResetEmail = () => {
return useMutation({
mutationFn: async ({
email
}: {
email: string;
}) => {
const { data } = await apiRequest.post("/api/v1/password/email/password-reset", {
email
});
return data;
}
});
}
export const useVerifyPasswordResetCode = () => {
return useMutation({
mutationFn: async ({
email,
code
}: {
email: string;
code: string;
}) => {
const { data } = await apiRequest.post("/api/v1/password/email/password-reset-verify", {
email,
code
});
return data;
}
});
}
export const issueBackupPrivateKey = async (details: IssueBackupPrivateKeyDTO) => {
const { data } = await apiRequest.post("/api/v1/password/backup-private-key", details);
return data;
}
export const getBackupEncryptedPrivateKey = async ({
verificationToken
}: GetBackupEncryptedPrivateKeyDTO) => {
const { data } = await apiRequest.get("/api/v1/password/backup-private-key", {
headers: {
Authorization: `Bearer ${verificationToken}`
}
});
return data.backupPrivateKey;
}
export const useResetPassword = () => {
return useMutation({
mutationFn: async (details: ResetPasswordDTO) => {
const { data } = await apiRequest.post("/api/v1/password/password-reset", {
protectedKey: details.protectedKey,
protectedKeyIV: details.protectedKeyIV,
protectedKeyTag: details.protectedKeyTag,
encryptedPrivateKey: details.encryptedPrivateKey,
encryptedPrivateKeyIV: details.encryptedPrivateKeyIV,
encryptedPrivateKeyTag: details.encryptedPrivateKeyTag,
salt: details.salt,
verifier: details.verifier
}, {
headers: {
Authorization: `Bearer ${details.verificationToken}`
}
});
return data;
}
});
}
export const changePassword = async (details: ChangePasswordDTO) => {
const { data } = await apiRequest.post("/api/v1/password/change-password", details);
return data;
}
export const useChangePassword = () => {
// note: use after srp1
return useMutation({
mutationFn: async (details: ChangePasswordDTO) => {
return changePassword(details);
}
});
}
// Refresh token is set as cookie when logged in
// Using that we fetch the auth bearer token needed for auth calls
const fetchAuthToken = async () => {
+103
View File
@@ -21,4 +21,107 @@ export type VerifyMfaTokenRes = {
encryptedPrivateKey: string;
iv: string;
tag: string;
}
export type Login1DTO = {
email: string;
clientPublicKey: string;
providerAuthToken?: string;
}
export type Login2DTO = {
email: string;
clientProof: string;
providerAuthToken?: string;
}
export type Login1Res = {
serverPublicKey: string;
salt: string;
}
export type Login2Res = {
mfaEnabled: boolean;
token: string;
encryptionVersion?: number;
protectedKey?: string;
protectedKeyIV?: string;
protectedKeyTag?: string;
publicKey?: string;
encryptedPrivateKey?: string;
iv?: string;
tag?: string;
}
export type SRP1DTO = {
clientPublicKey: string;
}
export type SRPR1Res = {
serverPublicKey: string;
salt: string;
}
export type CompleteAccountDTO = {
email: string;
firstName: string;
lastName: string;
protectedKey: string;
protectedKeyIV: string;
protectedKeyTag: string;
publicKey: string;
encryptedPrivateKey: string;
encryptedPrivateKeyIV: string;
encryptedPrivateKeyTag: string;
salt: string;
verifier: string;
}
export type CompleteAccountSignupDTO = CompleteAccountDTO & {
providerAuthToken?: string;
attributionSource?: string;
organizationName: string;
}
export type VerifySignupInviteDTO = {
email: string;
code: string;
organizationId: string;
}
export type ChangePasswordDTO = {
clientProof: string;
protectedKey: string;
protectedKeyIV: string;
protectedKeyTag: string;
encryptedPrivateKey: string;
encryptedPrivateKeyIV: string;
encryptedPrivateKeyTag: string;
salt: string;
verifier: string;
}
export type ResetPasswordDTO = {
protectedKey: string;
protectedKeyIV: string;
protectedKeyTag: string;
encryptedPrivateKey: string;
encryptedPrivateKeyIV: string;
encryptedPrivateKeyTag: string;
salt: string;
verifier: string;
verificationToken: string;
}
export type IssueBackupPrivateKeyDTO = {
encryptedPrivateKey: string;
iv: string;
tag: string;
salt: string;
verifier: string;
clientProof: string;
}
export type GetBackupEncryptedPrivateKeyDTO = {
verificationToken: string;
}
+8 -11
View File
@@ -8,29 +8,26 @@ const queryKeys = {
getBot: (workspaceId: string) => [{ workspaceId }, "bot"] as const
};
const fetchWorkspaceBot = async (workspaceId: string) => {
const { data } = await apiRequest.get<{ bot: TBot }>(`/api/v1/bot/${workspaceId}`);
return data.bot;
};
export const useGetWorkspaceBot = (workspaceId: string) =>
useQuery({
queryKey: queryKeys.getBot(workspaceId),
queryFn: () => fetchWorkspaceBot(workspaceId),
queryFn: async () => {
const { data: { bot } } = await apiRequest.get<{ bot: TBot }>(`/api/v1/bot/${workspaceId}`);
return bot;
},
enabled: Boolean(workspaceId)
});
// mutation
export const useUpdateBotActiveStatus = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, TSetBotActiveStatusDto>({
mutationFn: ({ botId, isActive, botKey }) =>
apiRequest.patch(`/api/v1/bot/${botId}/active`, {
mutationFn: ({ botId, isActive, botKey }) => {
return apiRequest.patch(`/api/v1/bot/${botId}/active`, {
isActive,
botKey
}),
});
},
onSuccess: (_, { workspaceId }) => {
queryClient.invalidateQueries(queryKeys.getBot(workspaceId));
}
@@ -8,18 +8,16 @@ const incidentContactKeys = {
getAllContact: (orgId: string) => ["org-incident-contacts", { orgId }] as const
};
const fetchOrgIncidentContacts = async (orgId: string) => {
const { data } = await apiRequest.get<{ incidentContactsOrg: IncidentContact[] }>(
`/api/v1/organization/${orgId}/incidentContactOrg`
);
return data.incidentContactsOrg;
};
export const useGetOrgIncidentContact = (orgId: string) =>
useQuery({
queryKey: incidentContactKeys.getAllContact(orgId),
queryFn: () => fetchOrgIncidentContacts(orgId),
queryFn: async () => {
const { data } = await apiRequest.get<{ incidentContactsOrg: IncidentContact[] }>(
`/api/v1/organization/${orgId}/incidentContactOrg`
);
return data.incidentContactsOrg;
},
enabled: Boolean(orgId)
});
+1
View File
@@ -1,3 +1,4 @@
export * from "./auditLogs";
export * from "./auth";
export * from "./bots";
export * from "./incidentContacts";
@@ -1,4 +1,5 @@
export {
useAuthorizeIntegration,
useDeleteIntegrationAuth,
useGetIntegrationAuthApps,
useGetIntegrationAuthBitBucketWorkspaces,
@@ -7,4 +8,6 @@ export {
useGetIntegrationAuthRailwayEnvironments,
useGetIntegrationAuthRailwayServices,
useGetIntegrationAuthTeams,
useGetIntegrationAuthVercelBranches} from "./queries";
useGetIntegrationAuthVercelBranches,
useSaveIntegrationAccessToken
} from "./queries";
@@ -312,6 +312,69 @@ export const useGetIntegrationAuthNorthflankSecretGroups = ({
});
};
export const useAuthorizeIntegration = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
workspaceId,
code,
integration
}: {
workspaceId: string;
code: string;
integration: string;
}) => {
const { data: { integrationAuth } } = await apiRequest.post("/api/v1/integration-auth/oauth-token", {
workspaceId,
code,
integration
});
return integrationAuth;
},
onSuccess: (res) => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceAuthorization(res.workspace));
}
});
};
export const useSaveIntegrationAccessToken = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
workspaceId,
integration,
accessId,
accessToken,
url,
namespace
}: {
workspaceId: string | null;
integration: string | undefined;
accessId: string | null;
accessToken: string;
url: string | null;
namespace: string | null;
}) => {
const { data: { integrationAuth } } = await apiRequest.post("/api/v1/integration-auth/access-token", {
workspaceId,
integration,
accessId,
accessToken,
url,
namespace
});
return integrationAuth;
},
onSuccess: (res) => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceAuthorization(res.workspace));
}
});
};
export const useDeleteIntegrationAuth = () => {
const queryClient = useQueryClient();
@@ -1 +1,5 @@
export { useDeleteIntegration,useGetCloudIntegrations } from "./queries";
export {
useCreateIntegration,
useDeleteIntegration,
useGetCloudIntegrations
} from "./queries";
@@ -23,6 +23,63 @@ export const useGetCloudIntegrations = () =>
queryFn: () => fetchIntegrations()
});
export const useCreateIntegration = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
integrationAuthId,
isActive,
app,
appId,
sourceEnvironment,
targetEnvironment,
targetEnvironmentId,
targetService,
targetServiceId,
owner,
path,
region,
secretPath
}: {
integrationAuthId: string;
isActive: boolean;
secretPath: string;
app: string | null;
appId: string | null;
sourceEnvironment: string;
targetEnvironment: string | null;
targetEnvironmentId: string | null;
targetService: string | null;
targetServiceId: string | null;
owner: string | null;
path: string | null;
region: string | null;
}) => {
const { data: { integration } } = await apiRequest.post("/api/v1/integration", {
integrationAuthId,
isActive,
app,
appId,
sourceEnvironment,
targetEnvironment,
targetEnvironmentId,
targetService,
targetServiceId,
owner,
path,
region,
secretPath
});
return integration;
},
onSuccess: (res) => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceIntegrations(res.workspace));
}
});
};
export const useDeleteIntegration = () => {
const queryClient = useQueryClient();
@@ -32,4 +89,4 @@ export const useDeleteIntegration = () => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceIntegrations(workspaceId));
}
});
};
};
+18 -3
View File
@@ -8,7 +8,7 @@ const encKeyKeys = {
getUserWorkspaceKey: (workspaceID: string) => ["workspace-key-pair", { workspaceID }] as const
};
const fetchUserWsKey = async (workspaceID: string) => {
export const fetchUserWsKey = async (workspaceID: string) => {
const { data } = await apiRequest.get<{ latestKey: UserWsKeyPair }>(
`/api/v1/key/${workspaceID}/latest`
);
@@ -24,8 +24,23 @@ export const useGetUserWsKey = (workspaceID: string) =>
});
// mutations
export const uploadWsKey = async ({
workspaceId,
userId,
encryptedKey,
nonce
}: UploadWsKeyDTO) => {
return apiRequest.post(`/api/v1/key/${workspaceId}`, { key: { userId, encryptedKey, nonce } })
}
export const useUploadWsKey = () =>
useMutation<{}, {}, UploadWsKeyDTO>({
mutationFn: ({ encryptedKey, nonce, userId, workspaceId }) =>
apiRequest.post(`/api/v1/key/${workspaceId}`, { key: { userId, encryptedKey, nonce } })
mutationFn: async ({ encryptedKey, nonce, userId, workspaceId }) => {
return uploadWsKey({
workspaceId,
userId,
encryptedKey,
nonce
});
}
});
+1 -1
View File
@@ -4,7 +4,7 @@ export {
useCreateCustomerPortalSession,
useDeleteOrgPmtMethod,
useDeleteOrgTaxId,
useGetOrganization,
useGetOrganizations,
useGetOrgBillingDetails,
useGetOrgInvoices,
useGetOrgLicenses,
+16 -11
View File
@@ -12,10 +12,11 @@ import {
PmtMethod,
ProductsTable,
RenameOrgDTO,
TaxID} from "./types";
TaxID
} from "./types";
const organizationKeys = {
getUserOrganization: ["organization"] as const,
getUserOrganizations: ["organization"] as const,
getOrgPlanBillingInfo: (orgId: string) => [{ orgId }, "organization-plan-billing"] as const,
getOrgPlanTable: (orgId: string) => [{ orgId }, "organization-plan-table"] as const,
getOrgPlansTable: (orgId: string, billingCycle: "monthly" | "yearly") => [{ orgId, billingCycle }, "organization-plans-table"] as const,
@@ -26,13 +27,16 @@ const organizationKeys = {
getOrgLicenses: (orgId: string) => [{ orgId }, "organization-licenses"] as const
};
export const useGetOrganization = () => {
return useQuery({
queryKey: organizationKeys.getUserOrganization,
queryFn: async () => {
const { data } = await apiRequest.get<{ organizations: Organization[] }>("/api/v1/organization");
export const fetchOrganizations = async () => {
const { data: { organizations } } = await apiRequest.get<{ organizations: Organization[] }>("/api/v1/organization");
return organizations;
}
return data.organizations;
export const useGetOrganizations = () => {
return useQuery({
queryKey: organizationKeys.getUserOrganizations,
queryFn: async () => {
return fetchOrganizations();
}
});
}
@@ -41,10 +45,11 @@ export const useRenameOrg = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, RenameOrgDTO>({
mutationFn: ({ newOrgName, orgId }) =>
apiRequest.patch(`/api/v1/organization/${orgId}/name`, { name: newOrgName }),
mutationFn: ({ newOrgName, orgId }) => {
return apiRequest.patch(`/api/v1/organization/${orgId}/name`, { name: newOrgName });
},
onSuccess: () => {
queryClient.invalidateQueries(organizationKeys.getUserOrganization);
queryClient.invalidateQueries(organizationKeys.getUserOrganizations);
}
});
};
+23 -2
View File
@@ -11,13 +11,13 @@ import { apiRequest } from "@app/config/request";
import { secretSnapshotKeys } from "../secretSnapshots/queries";
import {
BatchSecretDTO,
CreateSecretDTO,
DecryptedSecret,
EncryptedSecret,
EncryptedSecretVersion,
GetProjectSecretsDTO,
GetSecretVersionsDTO,
TGetProjectSecretsAllEnvDTO
} from "./types";
TGetProjectSecretsAllEnvDTO} from "./types";
export const secretKeys = {
// this is also used in secretSnapshot part
@@ -324,3 +324,24 @@ export const useBatchSecretsOp = () => {
}
});
};
export const createSecret = async (dto: CreateSecretDTO) => {
const { data } = await apiRequest.post(`/api/v3/secrets/${dto.secretKey}`, dto);
return data;
}
export const useCreateSecret = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, CreateSecretDTO>({
mutationFn: async (dto) => {
const data = createSecret(dto);
return data;
},
onSuccess: (_, dto) => {
queryClient.invalidateQueries(
secretKeys.getProjectSecret(dto.workspaceId, dto.environment)
);
}
});
};
+23 -1
View File
@@ -79,7 +79,7 @@ export type UpdateSecretArg = {
export type CreateSecretArg = Omit<UpdateSecretArg, "_id">;
export type DeleteSecretArg = { _id: string };
export type DeleteSecretArg = { _id: string, secretName: string; };
export type BatchSecretDTO = {
workspaceId: string;
@@ -147,3 +147,25 @@ export type TDeleteSecretsV3DTO = {
secretPath: string;
secretName: string;
};
// --- v3
export type CreateSecretDTO = {
workspaceId: string;
environment: string;
type: "shared" | "personal";
secretKey: string;
secretKeyCiphertext: string;
secretKeyIV: string;
secretKeyTag: string;
secretValueCiphertext: string;
secretValueIV: string;
secretValueTag: string;
secretCommentCiphertext: string;
secretCommentIV: string;
secretCommentTag: string;
secretPath: string;
metadata?: {
source?: string;
}
}
@@ -23,12 +23,13 @@ const fetchWorkspaceServiceTokens = async (workspaceID: string) => {
type UseGetWorkspaceServiceTokensProps = { workspaceID: string };
export const useGetUserWsServiceTokens = ({ workspaceID }: UseGetWorkspaceServiceTokensProps) =>
useQuery({
export const useGetUserWsServiceTokens = ({ workspaceID }: UseGetWorkspaceServiceTokensProps) => {
return useQuery({
queryKey: serviceTokenKeys.getAllWorkspaceServiceToken(workspaceID),
queryFn: () => fetchWorkspaceServiceTokens(workspaceID),
enabled: Boolean(workspaceID)
});
}
// mutation
export const useCreateServiceToken = () => {
@@ -36,6 +37,7 @@ export const useCreateServiceToken = () => {
return useMutation<CreateServiceTokenRes, {}, CreateServiceTokenDTO>({
mutationFn: async (body) => {
console.log("useCreateServiceToken");
const { data } = await apiRequest.post("/api/v2/service-token/", body);
data.serviceToken += `.${body.randomBytes}`;
return data;
@@ -51,6 +53,7 @@ export const useDeleteServiceToken = () => {
return useMutation<DeleteServiceTokenRes, {}, string>({
mutationFn: async (serviceTokenId) => {
console.log("useDeleteServiceToken");
const { data } = await apiRequest.delete(`/api/v2/service-token/${serviceTokenId}`);
return data;
},
@@ -3,6 +3,7 @@ export type SubscriptionPlan = {
membersUsed: number;
memberLimit: number;
auditLogs: boolean;
auditLogsRetentionDays: number;
customAlerts: boolean;
customRateLimits: boolean;
pitRecovery: boolean;
+4 -4
View File
@@ -10,7 +10,6 @@ import {
UserWsTags
} from "./types";
const workspaceTags = {
getWsTags: (workspaceID: string) => ["workspace-tags", { workspaceID }] as const
};
@@ -23,12 +22,13 @@ const fetchWsTag = async (workspaceID: string) => {
return data.workspaceTags;
};
export const useGetWsTags = (workspaceID: string) =>
useQuery({
export const useGetWsTags = (workspaceID: string) => {
return useQuery({
queryKey: workspaceTags.getWsTags(workspaceID),
queryFn: () => fetchWsTag(workspaceID),
enabled: Boolean(workspaceID)
});
}
export const useCreateWsTag = () => {
const queryClient = useQueryClient();
@@ -59,4 +59,4 @@ export const useDeleteWsTag = () => {
queryClient.invalidateQueries(workspaceTags.getWsTags(tagData?.workspace));
}
});
};
};
+4 -2
View File
@@ -7,6 +7,7 @@ export {
useDeleteOrgMembership,
useGetMyAPIKeys,
useGetMyIp,
useGetMyOrganizationProjects,
useGetMySessions,
useGetOrgUsers,
useGetUser,
@@ -14,6 +15,7 @@ export {
useLogoutUser,
useRegisterUserAction,
useRevokeMySessions,
useUpdateMfaEnabled,
useUpdateOrgUserRole,
useUpdateUserAuthProvider
} from "./queries";
useUpdateUserAuthMethods
} from "./queries";
+66 -15
View File
@@ -13,13 +13,15 @@ import {
AddUserToWsDTO,
AddUserToWsRes,
APIKeyData,
AuthMethod,
CreateAPIKeyRes,
DeletOrgMembershipDTO,
OrgUser,
RenameUserDTO,
TokenVersion,
UpdateOrgUserRoleDTO,
User} from "./types";
User
} from "./types";
const userKeys = {
getUser: ["user"] as const,
@@ -27,7 +29,8 @@ const userKeys = {
getOrgUsers: (orgId: string) => [{ orgId }, "user"],
myIp: ["ip"] as const,
myAPIKeys: ["api-keys"] as const,
mySessions: ["sessions"] as const
mySessions: ["sessions"] as const,
myOrganizationProjects: (orgId: string) => [{ orgId }, "organization-projects"] as const
};
export const fetchUserDetails = async () => {
@@ -38,7 +41,7 @@ export const fetchUserDetails = async () => {
export const useGetUser = () => useQuery(userKeys.getUser, fetchUserDetails);
const fetchUserAction = async (action: string) => {
export const fetchUserAction = async (action: string) => {
const { data } = await apiRequest.get<{ userAction: string }>("/api/v1/user-action", {
params: {
action
@@ -59,17 +62,18 @@ export const useRenameUser = () => {
});
};
export const useUpdateUserAuthProvider = () => {
export const useUpdateUserAuthMethods = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
authProvider
authMethods
}: {
authProvider: string;
authMethods: AuthMethod[];
}) => {
const { data: { user } } = await apiRequest.patch("/api/v2/users/me/auth-provider", {
authProvider
const { data: { user } } = await apiRequest.put("/api/v2/users/me/auth-methods", {
authMethods
});
return user;
@@ -146,7 +150,9 @@ export const useAddUserToOrg = () => {
}
return useMutation<Response, {}, AddUserToOrgDTO>({
mutationFn: (dto) => apiRequest.post("/api/v1/invite-org/signup", dto),
mutationFn: (dto) => {
return apiRequest.post("/api/v1/invite-org/signup", dto);
},
onSuccess: (_, { organizationId }) => {
queryClient.invalidateQueries(userKeys.getOrgUsers(organizationId));
}
@@ -157,8 +163,9 @@ export const useDeleteOrgMembership = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, DeletOrgMembershipDTO>({
mutationFn: ({ membershipId, orgId }) =>
apiRequest.delete(`/api/v2/organizations/${orgId}/memberships/${membershipId}`),
mutationFn: ({ membershipId, orgId }) => {
return apiRequest.delete(`/api/v2/organizations/${orgId}/memberships/${membershipId}`)
},
onSuccess: (_, { orgId }) => {
queryClient.invalidateQueries(userKeys.getOrgUsers(orgId));
}
@@ -169,10 +176,11 @@ export const useUpdateOrgUserRole = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, UpdateOrgUserRoleDTO>({
mutationFn: ({ organizationId, membershipId, role }) =>
apiRequest.patch(`/api/v2/organizations/${organizationId}/memberships/${membershipId}`, {
mutationFn: ({ organizationId, membershipId, role }) => {
return apiRequest.patch(`/api/v2/organizations/${organizationId}/memberships/${membershipId}`, {
role
}),
});
},
onSuccess: (_, { organizationId }) => {
queryClient.invalidateQueries(userKeys.getOrgUsers(organizationId));
},
@@ -195,7 +203,9 @@ export const useRegisterUserAction = () => {
export const useLogoutUser = () =>
useMutation({
mutationFn: () => apiRequest.post("/api/v1/auth/logout"),
mutationFn: async () => {
await apiRequest.post("/api/v1/auth/logout");
},
onSuccess: () => {
setAuthToken("");
// Delete the cookie by not setting a value; Alternatively clear the local storage
@@ -303,4 +313,45 @@ export const useRevokeMySessions = () => {
queryClient.invalidateQueries(userKeys.mySessions);
}
});
}
export const useUpdateMfaEnabled = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
isMfaEnabled
}: {
isMfaEnabled: boolean;
}) => {
const { data: { user } } = await apiRequest.patch(
"/api/v2/users/me/mfa",
{
isMfaEnabled
}
);
return user;
},
onSuccess() {
queryClient.invalidateQueries(userKeys.getUser);
}
});
}
export const fetchMyOrganizationProjects = async (orgId: string) => {
const { data: { workspaces } } = await apiRequest.get(
`/api/v1/organization/${orgId}/my-workspaces`
);
return workspaces;
}
export const useGetMyOrganizationProjects = (orgId: string) => {
return useQuery({
queryKey: userKeys.myOrganizationProjects(orgId),
queryFn: async () => {
return fetchMyOrganizationProjects(orgId);
},
enabled: true
});
}
+8 -4
View File
@@ -1,18 +1,22 @@
import { UserWsKeyPair } from "../keys/types";
export enum AuthProvider {
export enum AuthMethod {
EMAIL = "email",
GOOGLE = "google",
OKTA_SAML = "okta-saml"
GITHUB = "github",
OKTA_SAML = "okta-saml",
AZURE_SAML = "azure-saml",
JUMPCLOUD_SAML = "jumpcloud-saml"
}
export type User = {
createdAt: Date;
updatedAt: Date;
email?: string;
email: string;
firstName?: string;
lastName?: string;
authProvider?: AuthProvider;
authProvider?: AuthMethod;
authMethods: AuthMethod[];
encryptionVersion?: number;
protectedKey?: string;
protectedKeyIV?: string;
+6 -2
View File
@@ -1,6 +1,8 @@
export {
useAddUserToWorkspace,
useCreateWorkspace,
useCreateWsEnvironment,
useDeleteUserFromWorkspace,
useDeleteWorkspace,
useDeleteWsEnvironment,
useGetUserWorkspaceMemberships,
@@ -11,8 +13,10 @@ export {
useGetWorkspaceIndexStatus,
useGetWorkspaceIntegrations,
useGetWorkspaceSecrets,
useGetWorkspaceUsers,
useNameWorkspaceSecrets,
useRenameWorkspace,
useReorderWsEnvironment,
useToggleAutoCapitalization,
useUpdateWsEnvironment
} from "./queries";
useUpdateUserWorkspaceRole,
useUpdateWsEnvironment} from "./queries";
+120 -16
View File
@@ -13,6 +13,7 @@ import {
GetWsEnvironmentDTO,
NameWorkspaceSecretsDTO,
RenameWorkspaceDTO,
ReorderEnvironmentsDTO,
ToggleAutoCapitalizationDTO,
UpdateEnvironmentDTO,
Workspace,
@@ -28,7 +29,9 @@ export const workspaceKeys = {
getWorkspaceAuthorization: (workspaceId: string) => [{ workspaceId }, "workspace-authorizations"],
getWorkspaceIntegrations: (workspaceId: string) => [{ workspaceId }, "workspace-integrations"],
getAllUserWorkspace: ["workspaces"] as const,
getUserWsEnvironments: (workspaceId: string) => ["workspace-env", { workspaceId }] as const
getUserWsEnvironments: (workspaceId: string) => ["workspace-env", { workspaceId }] as const,
getWorkspaceAuditLogs: (workspaceId: string) => [{ workspaceId }] as const,
getWorkspaceUsers: (workspaceId: string) => [{ workspaceId }] as const
};
const fetchWorkspaceById = async (workspaceId: string) => {
@@ -165,13 +168,21 @@ export const useGetWorkspaceIntegrations = (workspaceId: string) =>
enabled: Boolean(workspaceId)
});
// mutation
export const createWorkspace = ({
organizationId,
workspaceName
}: CreateWorkspaceDTO): Promise<{ data: { workspace: Workspace } }> => {
return apiRequest.post("/api/v1/workspace", { workspaceName, organizationId });
}
export const useCreateWorkspace = () => {
const queryClient = useQueryClient();
return useMutation<{ data: { workspace: Workspace } }, {}, CreateWorkspaceDTO>({
mutationFn: async ({ organizationId, workspaceName }) =>
apiRequest.post("/api/v1/workspace", { workspaceName, organizationId }),
mutationFn: async ({ organizationId, workspaceName }) => createWorkspace({
organizationId,
workspaceName
}),
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
@@ -182,8 +193,9 @@ export const useRenameWorkspace = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, RenameWorkspaceDTO>({
mutationFn: ({ workspaceID, newWorkspaceName }) =>
apiRequest.post(`/api/v1/workspace/${workspaceID}/name`, { name: newWorkspaceName }),
mutationFn: ({ workspaceID, newWorkspaceName }) => {
return apiRequest.post(`/api/v1/workspace/${workspaceID}/name`, { name: newWorkspaceName });
},
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
@@ -208,7 +220,9 @@ export const useDeleteWorkspace = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, DeleteWorkspaceDTO>({
mutationFn: ({ workspaceID }) => apiRequest.delete(`/api/v1/workspace/${workspaceID}`),
mutationFn: ({ workspaceID }) => {
return apiRequest.delete(`/api/v1/workspace/${workspaceID}`);
},
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
@@ -219,11 +233,27 @@ export const useCreateWsEnvironment = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, CreateEnvironmentDTO>({
mutationFn: ({ workspaceID, environmentName, environmentSlug }) =>
apiRequest.post(`/api/v2/workspace/${workspaceID}/environments`, {
mutationFn: ({ workspaceID, environmentName, environmentSlug }) => {
return apiRequest.post(`/api/v2/workspace/${workspaceID}/environments`, {
environmentName,
environmentSlug
}),
});
},
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
});
};
export const useReorderWsEnvironment = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, ReorderEnvironmentsDTO>({
mutationFn: ({ workspaceID, environmentSlug, environmentName, otherEnvironmentSlug, otherEnvironmentName}) => {
return apiRequest.patch(`/api/v2/workspace/${workspaceID}/environments`, {
environmentSlug, environmentName, otherEnvironmentSlug, otherEnvironmentName
});
},
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
@@ -234,12 +264,13 @@ export const useUpdateWsEnvironment = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, UpdateEnvironmentDTO>({
mutationFn: ({ workspaceID, environmentName, environmentSlug, oldEnvironmentSlug }) =>
apiRequest.put(`/api/v2/workspace/${workspaceID}/environments`, {
mutationFn: ({ workspaceID, environmentName, environmentSlug, oldEnvironmentSlug }) => {
return apiRequest.put(`/api/v2/workspace/${workspaceID}/environments`, {
environmentName,
environmentSlug,
oldEnvironmentSlug
}),
});
},
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
@@ -250,12 +281,85 @@ export const useDeleteWsEnvironment = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, DeleteEnvironmentDTO>({
mutationFn: ({ workspaceID, environmentSlug }) =>
apiRequest.delete(`/api/v2/workspace/${workspaceID}/environments`, {
mutationFn: ({ workspaceID, environmentSlug }) => {
return apiRequest.delete(`/api/v2/workspace/${workspaceID}/environments`, {
data: { environmentSlug }
}),
});
},
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
});
};
export const useGetWorkspaceUsers = (workspaceId: string) => {
return useQuery({
queryKey: workspaceKeys.getWorkspaceUsers(workspaceId),
queryFn: async () => {
const { data: { users } } = await apiRequest.get(
`/api/v1/workspace/${workspaceId}/users`
);
return users;
},
enabled: true
});
}
export const useAddUserToWorkspace = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
email,
workspaceId
}: {
email: string;
workspaceId: string;
}) => {
const { data: { invitee, latestKey } } = await apiRequest.post(`/api/v1/workspace/${workspaceId}/invite-signup`, { email });
return ({
invitee,
latestKey
});
},
onSuccess: (_, dto) => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceUsers(dto.workspaceId));
}
});
};
export const useDeleteUserFromWorkspace = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (membershipId: string) => {
const { data: { deletedMembership } } = await apiRequest.delete(`/api/v1/membership/${membershipId}`);
return deletedMembership;
},
onSuccess: (res) => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceUsers(res.workspace));
}
});
};
export const useUpdateUserWorkspaceRole = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
membershipId,
role
}: {
membershipId: string;
role: string;
}) => {
const { data: { membership } } = await apiRequest.post(`/api/v1/membership/${membershipId}/change-role`, {
role
});
return membership;
},
onSuccess: (res) => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceUsers(res.workspace));
}
});
};
+10 -1
View File
@@ -46,6 +46,15 @@ export type CreateEnvironmentDTO = {
environmentName: string;
};
export type ReorderEnvironmentsDTO = {
workspaceID: string;
environmentSlug: string;
environmentName: string;
otherEnvironmentSlug: string;
otherEnvironmentName: string;
};
export type UpdateEnvironmentDTO = {
workspaceID: string;
oldEnvironmentSlug: string;
@@ -53,4 +62,4 @@ export type UpdateEnvironmentDTO = {
environmentName: string;
};
export type DeleteEnvironmentDTO = { workspaceID: string; environmentSlug: string };
export type DeleteEnvironmentDTO = { workspaceID: string; environmentSlug: string };