mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Make fixes based on review
This commit is contained in:
@@ -816,8 +816,7 @@ export const registerRoutes = async (
|
||||
});
|
||||
const identityAccessTokenService = identityAccessTokenServiceFactory({
|
||||
identityAccessTokenDAL,
|
||||
identityOrgMembershipDAL,
|
||||
permissionService
|
||||
identityOrgMembershipDAL
|
||||
});
|
||||
const identityProjectService = identityProjectServiceFactory({
|
||||
permissionService,
|
||||
|
||||
@@ -2,8 +2,6 @@ import { z } from "zod";
|
||||
|
||||
import { UNIVERSAL_AUTH } from "@app/lib/api-docs";
|
||||
import { writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -63,37 +61,4 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
url: "/token/revoke-by-id",
|
||||
method: "POST",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
schema: {
|
||||
description: "Revoke access token by the id of the token",
|
||||
body: z.object({
|
||||
tokenId: z.string().trim()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
message: z.string()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
await server.services.identityAccessToken.revokeAccessTokenById({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.body
|
||||
});
|
||||
|
||||
return {
|
||||
message: "Successfully revoked access token"
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -253,6 +253,15 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
}
|
||||
});
|
||||
|
||||
// proposed
|
||||
// update token by id: PATCH /token-auth/tokens/:tokenId
|
||||
// revoke token by id: POST /token-auth/tokens/:tokenId/revoke
|
||||
|
||||
// current
|
||||
// revoke token by id: POST /token/revoke-by-id
|
||||
|
||||
// token-auth/identities/:identityId/tokens
|
||||
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/token-auth/identities/:identityId/tokens",
|
||||
@@ -284,7 +293,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
},
|
||||
handler: async (req) => {
|
||||
const { identityTokenAuth, accessToken, identityAccessToken, identityMembershipOrg } =
|
||||
await server.services.identityTokenAuth.createTokenTokenAuth({
|
||||
await server.services.identityTokenAuth.createTokenAuthToken({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
@@ -342,7 +351,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const { tokens, identityMembershipOrg } = await server.services.identityTokenAuth.getTokensTokenAuth({
|
||||
const { tokens, identityMembershipOrg } = await server.services.identityTokenAuth.getTokenAuthTokens({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
@@ -368,7 +377,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
|
||||
server.route({
|
||||
method: "PATCH",
|
||||
url: "/token-auth/identities/:identityId/tokens/:tokenId",
|
||||
url: "/token-auth/tokens/:tokenId",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
@@ -381,7 +390,6 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
}
|
||||
],
|
||||
params: z.object({
|
||||
identityId: z.string(),
|
||||
tokenId: z.string()
|
||||
}),
|
||||
body: z.object({
|
||||
@@ -394,12 +402,11 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const { token, identityMembershipOrg } = await server.services.identityTokenAuth.updateTokenTokenAuth({
|
||||
const { token, identityMembershipOrg } = await server.services.identityTokenAuth.updateTokenAuthToken({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
identityId: req.params.identityId,
|
||||
tokenId: req.params.tokenId,
|
||||
...req.body
|
||||
});
|
||||
@@ -410,7 +417,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
event: {
|
||||
type: EventType.UPDATE_TOKEN_IDENTITY_TOKEN_AUTH,
|
||||
metadata: {
|
||||
identityId: req.params.identityId,
|
||||
identityId: token.identityId,
|
||||
tokenId: token.id,
|
||||
name: req.body.name
|
||||
}
|
||||
@@ -420,4 +427,42 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
return { token };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/token-auth/tokens/:tokenId/revoke",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
schema: {
|
||||
description: "Revoke token for identity with Token Auth configured",
|
||||
security: [
|
||||
{
|
||||
bearerAuth: []
|
||||
}
|
||||
],
|
||||
params: z.object({
|
||||
tokenId: z.string()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
message: z.string()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
await server.services.identityTokenAuth.revokeTokenAuthToken({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
tokenId: req.params.tokenId
|
||||
});
|
||||
|
||||
return {
|
||||
message: "Successfully revoked access token"
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import jwt, { JwtPayload } from "jsonwebtoken";
|
||||
|
||||
import { TableName, TIdentityAccessTokens } from "@app/db/schemas";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { checkIPAgainstBlocklist, TIp } from "@app/lib/ip";
|
||||
@@ -11,24 +8,18 @@ import { checkIPAgainstBlocklist, TIp } from "@app/lib/ip";
|
||||
import { AuthTokenType } from "../auth/auth-type";
|
||||
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
||||
import { TIdentityAccessTokenDALFactory } from "./identity-access-token-dal";
|
||||
import {
|
||||
TIdentityAccessTokenJwtPayload,
|
||||
TRenewAccessTokenDTO,
|
||||
TRevokeAccessTokenByIdDTO
|
||||
} from "./identity-access-token-types";
|
||||
import { TIdentityAccessTokenJwtPayload, TRenewAccessTokenDTO } from "./identity-access-token-types";
|
||||
|
||||
type TIdentityAccessTokenServiceFactoryDep = {
|
||||
identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
|
||||
identityOrgMembershipDAL: TIdentityOrgDALFactory;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||
};
|
||||
|
||||
export type TIdentityAccessTokenServiceFactory = ReturnType<typeof identityAccessTokenServiceFactory>;
|
||||
|
||||
export const identityAccessTokenServiceFactory = ({
|
||||
identityAccessTokenDAL,
|
||||
identityOrgMembershipDAL,
|
||||
permissionService
|
||||
identityOrgMembershipDAL
|
||||
}: TIdentityAccessTokenServiceFactoryDep) => {
|
||||
const validateAccessTokenExp = async (identityAccessToken: TIdentityAccessTokens) => {
|
||||
const {
|
||||
@@ -147,43 +138,6 @@ export const identityAccessTokenServiceFactory = ({
|
||||
return { revokedToken };
|
||||
};
|
||||
|
||||
const revokeAccessTokenById = async ({
|
||||
tokenId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TRevokeAccessTokenByIdDTO) => {
|
||||
const identityAccessToken = await identityAccessTokenDAL.findOne({
|
||||
[`${TableName.IdentityAccessToken}.id` as "id"]: tokenId,
|
||||
isAccessTokenRevoked: false
|
||||
});
|
||||
if (!identityAccessToken) throw new UnauthorizedError();
|
||||
|
||||
const identityOrgMembership = await identityOrgMembershipDAL.findOne({
|
||||
identityId: identityAccessToken.identityId
|
||||
});
|
||||
|
||||
if (!identityOrgMembership) {
|
||||
throw new UnauthorizedError({ message: "Identity does not belong to any organization" });
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityOrgMembership.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const revokedToken = await identityAccessTokenDAL.updateById(identityAccessToken.id, {
|
||||
isAccessTokenRevoked: true
|
||||
});
|
||||
|
||||
return { revokedToken };
|
||||
};
|
||||
|
||||
const fnValidateIdentityAccessToken = async (token: TIdentityAccessTokenJwtPayload, ipAddress?: string) => {
|
||||
const identityAccessToken = await identityAccessTokenDAL.findOne({
|
||||
[`${TableName.IdentityAccessToken}.id` as "id"]: token.identityAccessTokenId,
|
||||
@@ -221,5 +175,5 @@ export const identityAccessTokenServiceFactory = ({
|
||||
return { ...identityAccessToken, orgId: identityOrgMembership.orgId };
|
||||
};
|
||||
|
||||
return { renewAccessToken, revokeAccessToken, revokeAccessTokenById, fnValidateIdentityAccessToken };
|
||||
return { renewAccessToken, revokeAccessToken, fnValidateIdentityAccessToken };
|
||||
};
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { TProjectPermission } from "@app/lib/types";
|
||||
|
||||
export type TRenewAccessTokenDTO = {
|
||||
accessToken: string;
|
||||
};
|
||||
@@ -10,7 +8,3 @@ export type TIdentityAccessTokenJwtPayload = {
|
||||
identityAccessTokenId: string;
|
||||
authTokenType: string;
|
||||
};
|
||||
|
||||
export type TRevokeAccessTokenByIdDTO = {
|
||||
tokenId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import { IdentityAuthMethod } from "@app/db/schemas";
|
||||
import { IdentityAuthMethod, TableName } from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
||||
|
||||
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
||||
@@ -18,12 +18,13 @@ import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identit
|
||||
import { TIdentityTokenAuthDALFactory } from "./identity-token-auth-dal";
|
||||
import {
|
||||
TAttachTokenAuthDTO,
|
||||
TCreateTokenTokenAuthDTO,
|
||||
TCreateTokenAuthTokenDTO,
|
||||
TGetTokenAuthDTO,
|
||||
TGetTokensTokenAuthDTO,
|
||||
TGetTokenAuthTokensDTO,
|
||||
TRevokeTokenAuthDTO,
|
||||
TRevokeTokenAuthTokenDTO,
|
||||
TUpdateTokenAuthDTO,
|
||||
TUpdateTokenTokenAuthDTO
|
||||
TUpdateTokenAuthTokenDTO
|
||||
} from "./identity-token-auth-types";
|
||||
|
||||
type TIdentityTokenAuthServiceFactoryDep = {
|
||||
@@ -33,7 +34,10 @@ type TIdentityTokenAuthServiceFactoryDep = {
|
||||
>;
|
||||
identityDAL: Pick<TIdentityDALFactory, "updateById">;
|
||||
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne">;
|
||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "find" | "update">;
|
||||
identityAccessTokenDAL: Pick<
|
||||
TIdentityAccessTokenDALFactory,
|
||||
"create" | "find" | "update" | "findById" | "findOne" | "updateById"
|
||||
>;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||
};
|
||||
@@ -243,7 +247,7 @@ export const identityTokenAuthServiceFactory = ({
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
throw new UnauthorizedError({
|
||||
message: "Failed to revoke Token Auth of identity with more privileged role"
|
||||
});
|
||||
|
||||
@@ -255,14 +259,14 @@ export const identityTokenAuthServiceFactory = ({
|
||||
return revokedIdentityTokenAuth;
|
||||
};
|
||||
|
||||
const createTokenTokenAuth = async ({
|
||||
const createTokenAuthToken = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
name
|
||||
}: TCreateTokenTokenAuthDTO) => {
|
||||
}: TCreateTokenAuthTokenDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
|
||||
@@ -328,7 +332,7 @@ export const identityTokenAuthServiceFactory = ({
|
||||
return { accessToken, identityTokenAuth, identityAccessToken, identityMembershipOrg };
|
||||
};
|
||||
|
||||
const getTokensTokenAuth = async ({
|
||||
const getTokenAuthTokens = async ({
|
||||
identityId,
|
||||
offset = 0,
|
||||
limit = 20,
|
||||
@@ -336,7 +340,7 @@ export const identityTokenAuthServiceFactory = ({
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TGetTokensTokenAuthDTO) => {
|
||||
}: TGetTokenAuthTokensDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
|
||||
@@ -350,20 +354,7 @@ export const identityTokenAuthServiceFactory = ({
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
ActorType.IDENTITY,
|
||||
identityMembershipOrg.identityId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to get tokens for identity with more privileged role"
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
const tokens = await identityAccessTokenDAL.find(
|
||||
{
|
||||
@@ -375,16 +366,17 @@ export const identityTokenAuthServiceFactory = ({
|
||||
return { tokens, identityMembershipOrg };
|
||||
};
|
||||
|
||||
const updateTokenTokenAuth = async ({
|
||||
identityId,
|
||||
const updateTokenAuthToken = async ({
|
||||
tokenId,
|
||||
name,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TUpdateTokenTokenAuthDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
}: TUpdateTokenAuthTokenDTO) => {
|
||||
const foundToken = await identityAccessTokenDAL.findById(tokenId);
|
||||
if (!foundToken) throw new NotFoundError({ message: "Failed to find token" });
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: foundToken.identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.TOKEN_AUTH)
|
||||
throw new BadRequestError({
|
||||
@@ -414,7 +406,7 @@ export const identityTokenAuthServiceFactory = ({
|
||||
|
||||
const [token] = await identityAccessTokenDAL.update(
|
||||
{
|
||||
identityId,
|
||||
identityId: foundToken.identityId,
|
||||
id: tokenId
|
||||
},
|
||||
{
|
||||
@@ -425,13 +417,54 @@ export const identityTokenAuthServiceFactory = ({
|
||||
return { token, identityMembershipOrg };
|
||||
};
|
||||
|
||||
const revokeTokenAuthToken = async ({
|
||||
tokenId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TRevokeTokenAuthTokenDTO) => {
|
||||
const identityAccessToken = await identityAccessTokenDAL.findOne({
|
||||
[`${TableName.IdentityAccessToken}.id` as "id"]: tokenId,
|
||||
isAccessTokenRevoked: false
|
||||
});
|
||||
if (!identityAccessToken)
|
||||
throw new NotFoundError({
|
||||
message: "Failed to find token"
|
||||
});
|
||||
|
||||
const identityOrgMembership = await identityOrgMembershipDAL.findOne({
|
||||
identityId: identityAccessToken.identityId
|
||||
});
|
||||
|
||||
if (!identityOrgMembership) {
|
||||
throw new UnauthorizedError({ message: "Identity does not belong to any organization" });
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityOrgMembership.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const revokedToken = await identityAccessTokenDAL.updateById(identityAccessToken.id, {
|
||||
isAccessTokenRevoked: true
|
||||
});
|
||||
|
||||
return { revokedToken };
|
||||
};
|
||||
|
||||
return {
|
||||
attachTokenAuth,
|
||||
updateTokenAuth,
|
||||
getTokenAuth,
|
||||
revokeIdentityTokenAuth,
|
||||
createTokenTokenAuth,
|
||||
getTokensTokenAuth,
|
||||
updateTokenTokenAuth
|
||||
createTokenAuthToken,
|
||||
getTokenAuthTokens,
|
||||
updateTokenAuthToken,
|
||||
revokeTokenAuthToken
|
||||
};
|
||||
};
|
||||
|
||||
@@ -24,19 +24,22 @@ export type TRevokeTokenAuthDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TCreateTokenTokenAuthDTO = {
|
||||
export type TCreateTokenAuthTokenDTO = {
|
||||
identityId: string;
|
||||
name?: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TGetTokensTokenAuthDTO = {
|
||||
export type TGetTokenAuthTokensDTO = {
|
||||
identityId: string;
|
||||
offset: number;
|
||||
limit: number;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TUpdateTokenTokenAuthDTO = {
|
||||
identityId: string;
|
||||
export type TUpdateTokenAuthTokenDTO = {
|
||||
tokenId: string;
|
||||
name?: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TRevokeTokenAuthTokenDTO = {
|
||||
tokenId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TLicenseServiceFactory } from "@app/ee/services/license/license-service
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { TOrgPermission } from "@app/lib/types";
|
||||
import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal";
|
||||
|
||||
@@ -213,7 +213,7 @@ export const identityServiceFactory = ({
|
||||
actorOrgId
|
||||
}: TListProjectIdentitiesByIdentityIdDTO) => {
|
||||
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${identityId}` });
|
||||
if (!identityOrgMembership) throw new NotFoundError({ message: `Failed to find identity with id ${identityId}` });
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
|
||||
@@ -17,16 +17,16 @@ export {
|
||||
useDeleteIdentityKubernetesAuth,
|
||||
useDeleteIdentityTokenAuth,
|
||||
useDeleteIdentityUniversalAuth,
|
||||
useRevokeIdentityTokenAuthToken,
|
||||
useRevokeIdentityUniversalAuthClientSecret,
|
||||
useRevokeToken,
|
||||
useUpdateIdentity,
|
||||
useUpdateIdentityAwsAuth,
|
||||
useUpdateIdentityAzureAuth,
|
||||
useUpdateIdentityGcpAuth,
|
||||
useUpdateIdentityKubernetesAuth,
|
||||
useUpdateIdentityTokenAuth,
|
||||
useUpdateIdentityUniversalAuth,
|
||||
useUpdateTokenIdentityTokenAuth} from "./mutations";
|
||||
useUpdateIdentityTokenAuthToken,
|
||||
useUpdateIdentityUniversalAuth} from "./mutations";
|
||||
export {
|
||||
useGetIdentityAwsAuth,
|
||||
useGetIdentityAzureAuth,
|
||||
@@ -37,4 +37,5 @@ export {
|
||||
useGetIdentityTokenAuth,
|
||||
useGetIdentityTokensTokenAuth,
|
||||
useGetIdentityUniversalAuth,
|
||||
useGetIdentityUniversalAuthClientSecrets} from "./queries";
|
||||
useGetIdentityUniversalAuthClientSecrets
|
||||
} from "./queries";
|
||||
|
||||
@@ -42,7 +42,8 @@ import {
|
||||
UpdateIdentityKubernetesAuthDTO,
|
||||
UpdateIdentityTokenAuthDTO,
|
||||
UpdateIdentityUniversalAuthDTO,
|
||||
UpdateTokenIdentityTokenAuthDTO} from "./types";
|
||||
UpdateTokenIdentityTokenAuthDTO
|
||||
} from "./types";
|
||||
|
||||
export const useCreateIdentity = () => {
|
||||
const queryClient = useQueryClient();
|
||||
@@ -706,14 +707,14 @@ export const useCreateTokenIdentityTokenAuth = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateTokenIdentityTokenAuth = () => {
|
||||
export const useUpdateIdentityTokenAuthToken = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<IdentityAccessToken, {}, UpdateTokenIdentityTokenAuthDTO>({
|
||||
mutationFn: async ({ identityId, tokenId, name }) => {
|
||||
mutationFn: async ({ tokenId, name }) => {
|
||||
const {
|
||||
data: { token }
|
||||
} = await apiRequest.patch<{ token: IdentityAccessToken }>(
|
||||
`/api/v1/auth/token-auth/identities/${identityId}/tokens/${tokenId}`,
|
||||
`/api/v1/auth/token-auth/tokens/${tokenId}`,
|
||||
{
|
||||
name
|
||||
}
|
||||
@@ -727,13 +728,13 @@ export const useUpdateTokenIdentityTokenAuth = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useRevokeToken = () => {
|
||||
export const useRevokeIdentityTokenAuthToken = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<RevokeTokenRes, {}, RevokeTokenDTO>({
|
||||
mutationFn: async ({ tokenId }) => {
|
||||
const { data } = await apiRequest.post<RevokeTokenRes>("/api/v1/auth/token/revoke-by-id", {
|
||||
tokenId
|
||||
});
|
||||
const { data } = await apiRequest.post<RevokeTokenRes>(
|
||||
`/api/v1/auth/token-auth/tokens/${tokenId}/revoke`
|
||||
);
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
@@ -21,9 +21,8 @@ import { withPermission } from "@app/hoc";
|
||||
import {
|
||||
useDeleteIdentity,
|
||||
useGetIdentityById,
|
||||
useRevokeIdentityUniversalAuthClientSecret,
|
||||
useRevokeToken
|
||||
} from "@app/hooks/api";
|
||||
useRevokeIdentityTokenAuthToken,
|
||||
useRevokeIdentityUniversalAuthClientSecret} from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
|
||||
import { IdentityAuthMethodModal } from "../MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal";
|
||||
@@ -35,7 +34,8 @@ import {
|
||||
IdentityDetailsSection,
|
||||
IdentityProjectsSection,
|
||||
IdentityTokenListModal,
|
||||
IdentityTokenModal} from "./components";
|
||||
IdentityTokenModal
|
||||
} from "./components";
|
||||
|
||||
export const IdentityPage = withPermission(
|
||||
() => {
|
||||
@@ -45,13 +45,14 @@ export const IdentityPage = withPermission(
|
||||
const orgId = currentOrg?.id || "";
|
||||
const { data } = useGetIdentityById(identityId);
|
||||
const { mutateAsync: deleteIdentity } = useDeleteIdentity();
|
||||
const { mutateAsync: revokeToken } = useRevokeToken();
|
||||
const { mutateAsync: revokeToken } = useRevokeIdentityTokenAuthToken();
|
||||
const { mutateAsync: revokeClientSecret } = useRevokeIdentityUniversalAuthClientSecret();
|
||||
|
||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||
"identity",
|
||||
"deleteIdentity",
|
||||
"identityAuthMethod",
|
||||
"revokeAuthMethod",
|
||||
"token",
|
||||
"tokenList",
|
||||
"revokeToken",
|
||||
|
||||
@@ -66,18 +66,6 @@ export const IdentityAuthenticationSection = ({ identityId, handlePopUpOpen }: P
|
||||
<div className="py-4">
|
||||
<div className="flex justify-between">
|
||||
<p className="text-sm font-semibold text-mineshaft-300">Auth Method</p>
|
||||
{/* <Button
|
||||
variant="link"
|
||||
onClick={() => {
|
||||
handlePopUpOpen("identityAuthMethod", {
|
||||
identityId,
|
||||
name: data.identity.name,
|
||||
authMethod: data.identity.authMethod
|
||||
});
|
||||
}}
|
||||
>
|
||||
Manage
|
||||
</Button> */}
|
||||
</div>
|
||||
<p className="text-sm text-mineshaft-300">
|
||||
{data.identity.authMethod
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { faKey, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faCheck, faCopy,faKey, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { format } from "date-fns";
|
||||
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { Button, IconButton, Tooltip } from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
import {
|
||||
useGetIdentityById,
|
||||
useGetIdentityUniversalAuth,
|
||||
@@ -25,6 +26,10 @@ type Props = {
|
||||
const SHOW_LIMIT = 3;
|
||||
|
||||
export const IdentityClientSecrets = ({ identityId, handlePopUpOpen }: Props) => {
|
||||
const [copyTextClientId, isCopyingClientId, setCopyTextClientId] = useTimedReset<string>({
|
||||
initialState: "Copy Client ID to clipboard"
|
||||
});
|
||||
|
||||
const { data } = useGetIdentityById(identityId);
|
||||
const { data: identityUniversalAuth } = useGetIdentityUniversalAuth(identityId);
|
||||
const { data: clientSecrets } = useGetIdentityUniversalAuthClientSecrets(identityId);
|
||||
@@ -32,7 +37,22 @@ export const IdentityClientSecrets = ({ identityId, handlePopUpOpen }: Props) =>
|
||||
<div>
|
||||
<div className="mb-4">
|
||||
<p className="text-sm font-semibold text-mineshaft-300">Client ID</p>
|
||||
<p className="text-sm text-mineshaft-300">{identityUniversalAuth?.clientId ?? ""}</p>
|
||||
<div className="flex align-top">
|
||||
<p className="text-sm text-mineshaft-300">{identityUniversalAuth?.clientId ?? ""}</p>
|
||||
<Tooltip content={copyTextClientId}>
|
||||
<IconButton
|
||||
ariaLabel="copy icon"
|
||||
variant="plain"
|
||||
className="group relative ml-2"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(identityUniversalAuth?.clientId ?? "");
|
||||
setCopyTextClientId("Copied");
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon icon={isCopyingClientId ? faCheck : faCopy} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
{clientSecrets?.length ? (
|
||||
<div className="flex justify-between">
|
||||
|
||||
@@ -86,17 +86,19 @@ export const IdentityTokens = ({ identityId, handlePopUpOpen }: Props) => {
|
||||
>
|
||||
Edit Token
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={async () => {
|
||||
handlePopUpOpen("revokeToken", {
|
||||
identityId,
|
||||
tokenId: token.id,
|
||||
name: token.name
|
||||
});
|
||||
}}
|
||||
>
|
||||
Revoke Token
|
||||
</DropdownMenuItem>
|
||||
{!token.isAccessTokenRevoked && (
|
||||
<DropdownMenuItem
|
||||
onClick={async () => {
|
||||
handlePopUpOpen("revokeToken", {
|
||||
identityId,
|
||||
tokenId: token.id,
|
||||
name: token.name
|
||||
});
|
||||
}}
|
||||
>
|
||||
Revoke Token
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { faPencil } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faCheck,faCopy, faPencil } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { IconButton,Tooltip } from "@app/components/v2";
|
||||
import { IconButton, Tooltip } from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
import { useGetIdentityById } from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
@@ -16,6 +17,10 @@ type Props = {
|
||||
};
|
||||
|
||||
export const IdentityDetailsSection = ({ identityId, handlePopUpOpen }: Props) => {
|
||||
const [copyTextId, isCopyingId, setCopyTextId] = useTimedReset<string>({
|
||||
initialState: "Copy ID to clipboard"
|
||||
});
|
||||
|
||||
const { data } = useGetIdentityById(identityId);
|
||||
return data ? (
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
@@ -49,7 +54,22 @@ export const IdentityDetailsSection = ({ identityId, handlePopUpOpen }: Props) =
|
||||
<div className="pt-4">
|
||||
<div className="mb-4">
|
||||
<p className="text-sm font-semibold text-mineshaft-300">ID</p>
|
||||
<p className="text-sm text-mineshaft-300">{data.identity.id}</p>
|
||||
<div className="flex align-top">
|
||||
<p className="text-sm text-mineshaft-300">{data.identity.id}</p>
|
||||
<Tooltip content={copyTextId}>
|
||||
<IconButton
|
||||
ariaLabel="copy icon"
|
||||
variant="plain"
|
||||
className="group relative ml-2"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(data.identity.id);
|
||||
setCopyTextId("Copied");
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon icon={isCopyingId ? faCheck : faCopy} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<p className="text-sm font-semibold text-mineshaft-300">Name</p>
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
import { useCreateTokenIdentityTokenAuth, useUpdateTokenIdentityTokenAuth } from "@app/hooks/api";
|
||||
import { useCreateTokenIdentityTokenAuth, useUpdateIdentityTokenAuthToken } from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
const schema = z
|
||||
@@ -34,7 +34,7 @@ type Props = {
|
||||
|
||||
export const IdentityTokenModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
const { mutateAsync: createToken } = useCreateTokenIdentityTokenAuth();
|
||||
const { mutateAsync: updateToken } = useUpdateTokenIdentityTokenAuth();
|
||||
const { mutateAsync: updateToken } = useUpdateIdentityTokenAuthToken();
|
||||
const [token, setToken] = useState("");
|
||||
const [copyTextToken, isCopyingToken, setCopyTextToken] = useTimedReset<string>({
|
||||
initialState: "Copy to clipboard"
|
||||
|
||||
@@ -3,15 +3,24 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import * as yup from "yup";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
DeleteActionModal,
|
||||
FormControl,
|
||||
Modal,
|
||||
ModalContent,
|
||||
Select,
|
||||
SelectItem,
|
||||
UpgradePlanModal
|
||||
} from "@app/components/v2";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
UpgradePlanModal} from "@app/components/v2";
|
||||
import { useOrganization } from "@app/context";
|
||||
import {
|
||||
useDeleteIdentityAwsAuth,
|
||||
useDeleteIdentityAzureAuth,
|
||||
useDeleteIdentityGcpAuth,
|
||||
useDeleteIdentityKubernetesAuth,
|
||||
useDeleteIdentityTokenAuth,
|
||||
useDeleteIdentityUniversalAuth} from "@app/hooks/api";
|
||||
import { IdentityAuthMethod , identityAuthToNameMap } from "@app/hooks/api/identities";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
import { IdentityAwsAuthForm } from "./IdentityAwsAuthForm";
|
||||
@@ -22,10 +31,10 @@ import { IdentityTokenAuthForm } from "./IdentityTokenAuthForm";
|
||||
import { IdentityUniversalAuthForm } from "./IdentityUniversalAuthForm";
|
||||
|
||||
type Props = {
|
||||
popUp: UsePopUpState<["identityAuthMethod", "upgradePlan"]>;
|
||||
popUp: UsePopUpState<["identityAuthMethod", "upgradePlan", "revokeAuthMethod"]>;
|
||||
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
|
||||
handlePopUpToggle: (
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "upgradePlan"]>,
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "upgradePlan", "revokeAuthMethod"]>,
|
||||
state?: boolean
|
||||
) => void;
|
||||
};
|
||||
@@ -48,6 +57,16 @@ const schema = yup
|
||||
export type FormData = yup.InferType<typeof schema>;
|
||||
|
||||
export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpToggle }: Props) => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const orgId = currentOrg?.id || "";
|
||||
|
||||
const { mutateAsync: revokeUniversalAuth } = useDeleteIdentityUniversalAuth();
|
||||
const { mutateAsync: revokeTokenAuth } = useDeleteIdentityTokenAuth();
|
||||
const { mutateAsync: revokeKubernetesAuth } = useDeleteIdentityKubernetesAuth();
|
||||
const { mutateAsync: revokeGcpAuth } = useDeleteIdentityGcpAuth();
|
||||
const { mutateAsync: revokeAwsAuth } = useDeleteIdentityAwsAuth();
|
||||
const { mutateAsync: revokeAzureAuth } = useDeleteIdentityAzureAuth();
|
||||
|
||||
const { control, watch, setValue } = useForm<FormData>({
|
||||
resolver: yupResolver(schema),
|
||||
defaultValues: {
|
||||
@@ -128,13 +147,84 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
default: {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onRevokeAuthMethodSubmit = async () => {
|
||||
if (!identityAuthMethodData.authMethod) return;
|
||||
if (!orgId) return;
|
||||
try {
|
||||
console.log("onRevokeAuthMethodSubmit identityId: ", identityAuthMethodData);
|
||||
switch (identityAuthMethodData.authMethod) {
|
||||
case IdentityAuthMethod.UNIVERSAL_AUTH: {
|
||||
await revokeUniversalAuth({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
break;
|
||||
}
|
||||
case IdentityAuthMethod.TOKEN_AUTH: {
|
||||
await revokeTokenAuth({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
break;
|
||||
}
|
||||
case IdentityAuthMethod.KUBERNETES_AUTH: {
|
||||
await revokeKubernetesAuth({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
break;
|
||||
}
|
||||
case IdentityAuthMethod.GCP_AUTH: {
|
||||
await revokeGcpAuth({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
break;
|
||||
}
|
||||
case IdentityAuthMethod.AWS_AUTH: {
|
||||
await revokeAwsAuth({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
break;
|
||||
}
|
||||
case IdentityAuthMethod.AZURE_AUTH: {
|
||||
await revokeAzureAuth({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
createNotification({
|
||||
text: `Successfully removed ${
|
||||
identityAuthToNameMap[identityAuthMethodData.authMethod]
|
||||
} on ${identityAuthMethodData.name}`,
|
||||
type: "success"
|
||||
});
|
||||
|
||||
handlePopUpToggle("revokeAuthMethod", false);
|
||||
handlePopUpToggle("identityAuthMethod", false);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
createNotification({
|
||||
text: `Failed to remove ${identityAuthToNameMap[identityAuthMethodData.authMethod]} on ${
|
||||
identityAuthMethodData.name
|
||||
}`,
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={popUp?.identityAuthMethod?.isOpen}
|
||||
@@ -175,6 +265,17 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||
text="You can use IP allowlisting if you switch to Infisical's Pro plan."
|
||||
/>
|
||||
<DeleteActionModal
|
||||
isOpen={popUp?.revokeAuthMethod?.isOpen}
|
||||
title={`Are you sure want to remove ${
|
||||
identityAuthMethodData?.authMethod
|
||||
? identityAuthToNameMap[identityAuthMethodData.authMethod]
|
||||
: "the auth method"
|
||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
||||
onChange={(isOpen) => handlePopUpToggle("revokeAuthMethod", isOpen)}
|
||||
deleteKey="confirm"
|
||||
onDeleteApproved={onRevokeAuthMethodSubmit}
|
||||
/>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -10,9 +10,9 @@ import { Button, FormControl, IconButton, Input } from "@app/components/v2";
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import {
|
||||
useAddIdentityAwsAuth,
|
||||
useDeleteIdentityAwsAuth,
|
||||
useGetIdentityAwsAuth,
|
||||
useUpdateIdentityAwsAuth} from "@app/hooks/api";
|
||||
useUpdateIdentityAwsAuth
|
||||
} from "@app/hooks/api";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
import { IdentityTrustedIp } from "@app/hooks/api/identities/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -42,7 +42,7 @@ export type FormData = yup.InferType<typeof schema>;
|
||||
type Props = {
|
||||
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
|
||||
handlePopUpToggle: (
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod"]>,
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "revokeAuthMethod"]>,
|
||||
state?: boolean
|
||||
) => void;
|
||||
identityAuthMethodData: {
|
||||
@@ -63,7 +63,6 @@ export const IdentityAwsAuthForm = ({
|
||||
|
||||
const { mutateAsync: addMutateAsync } = useAddIdentityAwsAuth();
|
||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAwsAuth();
|
||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentityAwsAuth();
|
||||
|
||||
const { data } = useGetIdentityAwsAuth(identityAuthMethodData?.identityId ?? "");
|
||||
|
||||
@@ -346,7 +345,7 @@ export const IdentityAwsAuthForm = ({
|
||||
variant="plain"
|
||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||
>
|
||||
{identityAuthMethodData?.authMethod ? "Cancel" : "Skip"}
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
{identityAuthMethodData?.authMethod && (
|
||||
@@ -355,14 +354,7 @@ export const IdentityAwsAuthForm = ({
|
||||
colorSchema="danger"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting}
|
||||
onClick={async () => {
|
||||
await deleteMutateAsync({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
|
||||
handlePopUpToggle("identityAuthMethod", false);
|
||||
}}
|
||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||
>
|
||||
Remove Auth Method
|
||||
</Button>
|
||||
|
||||
@@ -10,9 +10,9 @@ import { Button, FormControl, IconButton, Input } from "@app/components/v2";
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import {
|
||||
useAddIdentityAzureAuth,
|
||||
useDeleteIdentityAzureAuth,
|
||||
useGetIdentityAzureAuth,
|
||||
useUpdateIdentityAzureAuth} from "@app/hooks/api";
|
||||
useUpdateIdentityAzureAuth
|
||||
} from "@app/hooks/api";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
import { IdentityTrustedIp } from "@app/hooks/api/identities/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -40,7 +40,7 @@ export type FormData = z.infer<typeof schema>;
|
||||
type Props = {
|
||||
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
|
||||
handlePopUpToggle: (
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod"]>,
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "revokeAuthMethod"]>,
|
||||
state?: boolean
|
||||
) => void;
|
||||
identityAuthMethodData: {
|
||||
@@ -61,7 +61,6 @@ export const IdentityAzureAuthForm = ({
|
||||
|
||||
const { mutateAsync: addMutateAsync } = useAddIdentityAzureAuth();
|
||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAzureAuth();
|
||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentityAzureAuth();
|
||||
|
||||
const { data } = useGetIdentityAzureAuth(identityAuthMethodData?.identityId ?? "");
|
||||
|
||||
@@ -344,7 +343,7 @@ export const IdentityAzureAuthForm = ({
|
||||
variant="plain"
|
||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||
>
|
||||
{identityAuthMethodData?.authMethod ? "Cancel" : "Skip"}
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
{identityAuthMethodData?.authMethod && (
|
||||
@@ -353,14 +352,7 @@ export const IdentityAzureAuthForm = ({
|
||||
colorSchema="danger"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting}
|
||||
onClick={async () => {
|
||||
await deleteMutateAsync({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
|
||||
handlePopUpToggle("identityAuthMethod", false);
|
||||
}}
|
||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||
>
|
||||
Remove Auth Method
|
||||
</Button>
|
||||
|
||||
@@ -10,9 +10,9 @@ import { Button, FormControl, IconButton, Input, Select, SelectItem } from "@app
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import {
|
||||
useAddIdentityGcpAuth,
|
||||
useDeleteIdentityGcpAuth,
|
||||
useGetIdentityGcpAuth,
|
||||
useUpdateIdentityGcpAuth} from "@app/hooks/api";
|
||||
useUpdateIdentityGcpAuth
|
||||
} from "@app/hooks/api";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
import { IdentityTrustedIp } from "@app/hooks/api/identities/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -41,7 +41,7 @@ export type FormData = z.infer<typeof schema>;
|
||||
type Props = {
|
||||
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
|
||||
handlePopUpToggle: (
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod"]>,
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "revokeAuthMethod"]>,
|
||||
state?: boolean
|
||||
) => void;
|
||||
identityAuthMethodData: {
|
||||
@@ -62,7 +62,6 @@ export const IdentityGcpAuthForm = ({
|
||||
|
||||
const { mutateAsync: addMutateAsync } = useAddIdentityGcpAuth();
|
||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityGcpAuth();
|
||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentityGcpAuth();
|
||||
|
||||
const { data } = useGetIdentityGcpAuth(identityAuthMethodData?.identityId ?? "");
|
||||
|
||||
@@ -378,7 +377,7 @@ export const IdentityGcpAuthForm = ({
|
||||
variant="plain"
|
||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||
>
|
||||
{identityAuthMethodData?.authMethod ? "Cancel" : "Skip"}
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
{identityAuthMethodData?.authMethod && (
|
||||
@@ -387,14 +386,7 @@ export const IdentityGcpAuthForm = ({
|
||||
colorSchema="danger"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting}
|
||||
onClick={async () => {
|
||||
await deleteMutateAsync({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
|
||||
handlePopUpToggle("identityAuthMethod", false);
|
||||
}}
|
||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||
>
|
||||
Remove Auth Method
|
||||
</Button>
|
||||
|
||||
@@ -10,9 +10,9 @@ import { Button, FormControl, IconButton, Input, TextArea } from "@app/component
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import {
|
||||
useAddIdentityKubernetesAuth,
|
||||
useDeleteIdentityKubernetesAuth,
|
||||
useGetIdentityKubernetesAuth,
|
||||
useUpdateIdentityKubernetesAuth} from "@app/hooks/api";
|
||||
useUpdateIdentityKubernetesAuth
|
||||
} from "@app/hooks/api";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
import { IdentityTrustedIp } from "@app/hooks/api/identities/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -43,7 +43,7 @@ export type FormData = z.infer<typeof schema>;
|
||||
type Props = {
|
||||
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
|
||||
handlePopUpToggle: (
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod"]>,
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "revokeAuthMethod"]>,
|
||||
state?: boolean
|
||||
) => void;
|
||||
identityAuthMethodData: {
|
||||
@@ -64,7 +64,6 @@ export const IdentityKubernetesAuthForm = ({
|
||||
|
||||
const { mutateAsync: addMutateAsync } = useAddIdentityKubernetesAuth();
|
||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityKubernetesAuth();
|
||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentityKubernetesAuth();
|
||||
|
||||
const { data } = useGetIdentityKubernetesAuth(identityAuthMethodData?.identityId ?? "");
|
||||
|
||||
@@ -399,7 +398,7 @@ export const IdentityKubernetesAuthForm = ({
|
||||
variant="plain"
|
||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||
>
|
||||
{identityAuthMethodData?.authMethod ? "Cancel" : "Skip"}
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
{identityAuthMethodData?.authMethod && (
|
||||
@@ -408,14 +407,7 @@ export const IdentityKubernetesAuthForm = ({
|
||||
colorSchema="danger"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting}
|
||||
onClick={async () => {
|
||||
await deleteMutateAsync({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
|
||||
handlePopUpToggle("identityAuthMethod", false);
|
||||
}}
|
||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||
>
|
||||
Remove Auth Method
|
||||
</Button>
|
||||
|
||||
@@ -15,7 +15,7 @@ import { withPermission } from "@app/hoc";
|
||||
import { useDeleteIdentity } from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
|
||||
import { IdentityAuthMethodModal } from "./IdentityAuthMethodModal";
|
||||
// import { IdentityAuthMethodModal } from "./IdentityAuthMethodModal";
|
||||
import { IdentityModal } from "./IdentityModal";
|
||||
import { IdentityTable } from "./IdentityTable";
|
||||
import { IdentityTokenAuthTokenModal } from "./IdentityTokenAuthTokenModal";
|
||||
@@ -110,11 +110,11 @@ export const IdentitySection = withPermission(
|
||||
</div>
|
||||
<IdentityTable />
|
||||
<IdentityModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
||||
<IdentityAuthMethodModal
|
||||
{/* <IdentityAuthMethodModal
|
||||
popUp={popUp}
|
||||
handlePopUpOpen={handlePopUpOpen}
|
||||
handlePopUpToggle={handlePopUpToggle}
|
||||
/>
|
||||
/> */}
|
||||
{/* <IdentityUniversalAuthClientSecretModal
|
||||
popUp={popUp}
|
||||
handlePopUpOpen={handlePopUpOpen}
|
||||
|
||||
@@ -69,11 +69,13 @@ export const IdentityTable = () => {
|
||||
<TBody>
|
||||
{isLoading && <TableSkeleton columns={4} innerKey="org-identities" />}
|
||||
{!isLoading &&
|
||||
data &&
|
||||
data.length > 0 &&
|
||||
data.map(({ identity: { id, name }, role, customRole }) => {
|
||||
data?.map(({ identity: { id, name }, role, customRole }) => {
|
||||
return (
|
||||
<Tr className="h-10" key={`identity-${id}`}>
|
||||
<Tr
|
||||
className="h-10 cursor-pointer transition-colors duration-300 hover:bg-mineshaft-700"
|
||||
key={`identity-${id}`}
|
||||
onClick={() => router.push(`/org/${orgId}/identities/${id}`)}
|
||||
>
|
||||
<Td>
|
||||
<Link href={`/org/${orgId}/identities/${id}`}>{name}</Link>
|
||||
</Td>
|
||||
|
||||
@@ -9,9 +9,9 @@ import { Button, FormControl, IconButton, Input } from "@app/components/v2";
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import {
|
||||
useAddIdentityTokenAuth,
|
||||
useDeleteIdentityTokenAuth,
|
||||
useGetIdentityTokenAuth,
|
||||
useUpdateIdentityTokenAuth} from "@app/hooks/api";
|
||||
useUpdateIdentityTokenAuth
|
||||
} from "@app/hooks/api";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
@@ -35,7 +35,7 @@ export type FormData = z.infer<typeof schema>;
|
||||
type Props = {
|
||||
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
|
||||
handlePopUpToggle: (
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod"]>,
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "revokeAuthMethod"]>,
|
||||
state?: boolean
|
||||
) => void;
|
||||
identityAuthMethodData: {
|
||||
@@ -56,7 +56,6 @@ export const IdentityTokenAuthForm = ({
|
||||
|
||||
const { mutateAsync: addMutateAsync } = useAddIdentityTokenAuth();
|
||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityTokenAuth();
|
||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentityTokenAuth();
|
||||
|
||||
const { data } = useGetIdentityTokenAuth(identityAuthMethodData?.identityId ?? "");
|
||||
|
||||
@@ -256,7 +255,7 @@ export const IdentityTokenAuthForm = ({
|
||||
variant="plain"
|
||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||
>
|
||||
{identityAuthMethodData?.authMethod ? "Cancel" : "Skip"}
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
{identityAuthMethodData?.authMethod && (
|
||||
@@ -265,14 +264,7 @@ export const IdentityTokenAuthForm = ({
|
||||
colorSchema="danger"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting}
|
||||
onClick={async () => {
|
||||
await deleteMutateAsync({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
|
||||
handlePopUpToggle("identityAuthMethod", false);
|
||||
}}
|
||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||
>
|
||||
Remove Auth Method
|
||||
</Button>
|
||||
|
||||
@@ -10,9 +10,9 @@ import { Button, FormControl, IconButton, Input } from "@app/components/v2";
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import {
|
||||
useAddIdentityUniversalAuth,
|
||||
useDeleteIdentityUniversalAuth,
|
||||
useGetIdentityUniversalAuth,
|
||||
useUpdateIdentityUniversalAuth} from "@app/hooks/api";
|
||||
useUpdateIdentityUniversalAuth
|
||||
} from "@app/hooks/api";
|
||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||
import { IdentityTrustedIp } from "@app/hooks/api/identities/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -48,7 +48,7 @@ export type FormData = yup.InferType<typeof schema>;
|
||||
type Props = {
|
||||
handlePopUpOpen: (popUpName: keyof UsePopUpState<["upgradePlan"]>) => void;
|
||||
handlePopUpToggle: (
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod"]>,
|
||||
popUpName: keyof UsePopUpState<["identityAuthMethod", "revokeAuthMethod"]>,
|
||||
state?: boolean
|
||||
) => void;
|
||||
identityAuthMethodData: {
|
||||
@@ -68,7 +68,6 @@ export const IdentityUniversalAuthForm = ({
|
||||
const { subscription } = useSubscription();
|
||||
const { mutateAsync: addMutateAsync } = useAddIdentityUniversalAuth();
|
||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityUniversalAuth();
|
||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentityUniversalAuth();
|
||||
const { data } = useGetIdentityUniversalAuth(identityAuthMethodData?.identityId ?? "");
|
||||
|
||||
const {
|
||||
@@ -385,7 +384,7 @@ export const IdentityUniversalAuthForm = ({
|
||||
variant="plain"
|
||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||
>
|
||||
{identityAuthMethodData?.authMethod ? "Cancel" : "Skip"}
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
{identityAuthMethodData?.authMethod && (
|
||||
@@ -394,14 +393,7 @@ export const IdentityUniversalAuthForm = ({
|
||||
colorSchema="danger"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting}
|
||||
onClick={async () => {
|
||||
await deleteMutateAsync({
|
||||
identityId: identityAuthMethodData.identityId,
|
||||
organizationId: orgId
|
||||
});
|
||||
|
||||
handlePopUpToggle("identityAuthMethod", false);
|
||||
}}
|
||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||
>
|
||||
Remove Auth Method
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user