mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 03:27:15 +00:00
Update permission implementation for ST V3
This commit is contained in:
@@ -9,6 +9,7 @@ JWT_SIGNUP_SECRET=3679e04ca949f914c03332aaaeba805a
|
|||||||
JWT_REFRESH_SECRET=5f2f3c8f0159068dc2bbb3a652a716ff
|
JWT_REFRESH_SECRET=5f2f3c8f0159068dc2bbb3a652a716ff
|
||||||
JWT_AUTH_SECRET=4be6ba5602e0fa0ac6ac05c3cd4d247f
|
JWT_AUTH_SECRET=4be6ba5602e0fa0ac6ac05c3cd4d247f
|
||||||
JWT_SERVICE_SECRET=f32f716d70a42c5703f4656015e76200
|
JWT_SERVICE_SECRET=f32f716d70a42c5703f4656015e76200
|
||||||
|
JWT_SERVICE_TOKEN_SECRET=f32f716d70a42c5703f4656015e76200
|
||||||
JWT_PROVIDER_AUTH_SECRET=f32f716d70a42c5703f4656015e76201
|
JWT_PROVIDER_AUTH_SECRET=f32f716d70a42c5703f4656015e76201
|
||||||
|
|
||||||
# JWT lifetime
|
# JWT lifetime
|
||||||
|
|||||||
@@ -110,14 +110,14 @@ export const getSecretsRaw = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
requiredPermissions: [Permission.READ]
|
||||||
});
|
});
|
||||||
permissionCheckFn = (env: string, secPath: string) =>
|
permissionCheckFn = (env: string, secPath: string) =>
|
||||||
isValidScopeV3({
|
isValidScopeV3({
|
||||||
authPayload: req.authData.authPayload as IServiceTokenDataV3,
|
authPayload: req.authData.authPayload as IServiceTokenDataV3,
|
||||||
environment: env,
|
environment: env,
|
||||||
secretPath: secPath,
|
secretPath: secPath,
|
||||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
requiredPermissions: [Permission.READ]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
requiredPermissions: [Permission.READ]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -285,7 +285,7 @@ export const createSecretRaw = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -384,7 +384,7 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -464,7 +464,7 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -559,14 +559,14 @@ export const getSecrets = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
requiredPermissions: [Permission.READ]
|
||||||
});
|
});
|
||||||
permissionCheckFn = (env: string, secPath: string) =>
|
permissionCheckFn = (env: string, secPath: string) =>
|
||||||
isValidScopeV3({
|
isValidScopeV3({
|
||||||
authPayload: req.authData.authPayload as IServiceTokenDataV3,
|
authPayload: req.authData.authPayload as IServiceTokenDataV3,
|
||||||
environment: env,
|
environment: env,
|
||||||
secretPath: secPath,
|
secretPath: secPath,
|
||||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
requiredPermissions: [Permission.READ]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -644,7 +644,7 @@ export const getSecretByName = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
requiredPermissions: [Permission.READ]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -717,7 +717,7 @@ export const createSecret = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -816,7 +816,7 @@ export const updateSecretByName = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -892,7 +892,7 @@ export const deleteSecretByName = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -950,7 +950,7 @@ export const createSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -999,7 +999,7 @@ export const updateSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1048,7 +1048,7 @@ export const deleteSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions: [Permission.READ_WRITE]
|
requiredPermissions: [Permission.WRITE]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
|||||||
user,
|
user,
|
||||||
workspace: new Types.ObjectId(workspaceId),
|
workspace: new Types.ObjectId(workspaceId),
|
||||||
publicKey,
|
publicKey,
|
||||||
|
usageCount: 0,
|
||||||
scopes,
|
scopes,
|
||||||
isActive,
|
isActive,
|
||||||
expiresAt
|
expiresAt
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class EELicenseService {
|
|||||||
secretVersioning: true,
|
secretVersioning: true,
|
||||||
pitRecovery: false,
|
pitRecovery: false,
|
||||||
ipAllowlisting: false,
|
ipAllowlisting: false,
|
||||||
rbac: true,
|
rbac: false,
|
||||||
customRateLimits: false,
|
customRateLimits: false,
|
||||||
customAlerts: false,
|
customAlerts: false,
|
||||||
auditLogs: false,
|
auditLogs: false,
|
||||||
|
|||||||
@@ -249,7 +249,8 @@ export const getAuthSTDPayload = async ({
|
|||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lastUsed: new Date()
|
lastUsed: new Date(),
|
||||||
|
$inc: { usageCount: 1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
new: true
|
new: true
|
||||||
|
|||||||
@@ -69,12 +69,12 @@ export const isValidScopeV3 = ({
|
|||||||
authPayload,
|
authPayload,
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions
|
requiredPermissions
|
||||||
}: {
|
}: {
|
||||||
authPayload: IServiceTokenDataV3,
|
authPayload: IServiceTokenDataV3,
|
||||||
environment: string,
|
environment: string,
|
||||||
secretPath: string,
|
secretPath: string,
|
||||||
acceptedPermissions: Permission[]
|
requiredPermissions: Permission[]
|
||||||
}) => {
|
}) => {
|
||||||
const { scopes } = authPayload;
|
const { scopes } = authPayload;
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ export const isValidScopeV3 = ({
|
|||||||
scope.environment === environment
|
scope.environment === environment
|
||||||
);
|
);
|
||||||
|
|
||||||
if (validScope && !acceptedPermissions.includes(validScope.permission)) {
|
if (validScope && !requiredPermissions.every(permission => validScope.permissions.includes(permission))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { Document, Schema, Types, model } from "mongoose";
|
|||||||
|
|
||||||
export enum Permission {
|
export enum Permission {
|
||||||
READ = "read",
|
READ = "read",
|
||||||
READ_WRITE = "readWrite"
|
WRITE = "write"
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Scope {
|
export interface Scope {
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
permission: Permission;
|
permissions: Permission[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IServiceTokenDataV3 extends Document {
|
export interface IServiceTokenDataV3 extends Document {
|
||||||
@@ -19,6 +19,7 @@ export interface IServiceTokenDataV3 extends Document {
|
|||||||
publicKey: string;
|
publicKey: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
lastUsed?: Date;
|
lastUsed?: Date;
|
||||||
|
usageCount: number;
|
||||||
expiresAt?: Date;
|
expiresAt?: Date;
|
||||||
scopes: Array<Scope>;
|
scopes: Array<Scope>;
|
||||||
}
|
}
|
||||||
@@ -51,6 +52,11 @@ const serviceTokenDataV3Schema = new Schema(
|
|||||||
type: Date,
|
type: Date,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
usageCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
expiresAt: {
|
expiresAt: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -68,9 +74,10 @@ const serviceTokenDataV3Schema = new Schema(
|
|||||||
default: "/",
|
default: "/",
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
permission: {
|
permissions: {
|
||||||
type: String,
|
type: [String],
|
||||||
enum: [Permission.READ, Permission.READ_WRITE],
|
enum: [Permission.READ, Permission.WRITE],
|
||||||
|
default: [Permission.READ],
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import { isValidScopeV3 } from "../helpers";
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
environment,
|
environment,
|
||||||
secretPath = "/",
|
secretPath = "/",
|
||||||
acceptedPermissions
|
requiredPermissions
|
||||||
}: {
|
}: {
|
||||||
serviceTokenData: IServiceTokenDataV3;
|
serviceTokenData: IServiceTokenDataV3;
|
||||||
workspaceId: Types.ObjectId;
|
workspaceId: Types.ObjectId;
|
||||||
environment?: string;
|
environment?: string;
|
||||||
secretPath?: string;
|
secretPath?: string;
|
||||||
acceptedPermissions: Permission[];
|
requiredPermissions: Permission[];
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
if (!serviceTokenData.workspace.equals(workspaceId)) {
|
if (!serviceTokenData.workspace.equals(workspaceId)) {
|
||||||
@@ -41,7 +41,7 @@ import { isValidScopeV3 } from "../helpers";
|
|||||||
authPayload: serviceTokenData,
|
authPayload: serviceTokenData,
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
acceptedPermissions
|
requiredPermissions
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isValid) throw UnauthorizedRequestError({
|
if (!isValid) throw UnauthorizedRequestError({
|
||||||
@@ -57,7 +57,7 @@ export const CreateServiceTokenV3 = z.object({
|
|||||||
publicKey: z.string().trim(),
|
publicKey: z.string().trim(),
|
||||||
scopes: z
|
scopes: z
|
||||||
.object({
|
.object({
|
||||||
permission: z.enum(["read", "readWrite"]),
|
permissions: z.enum(["read", "write"]).array(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim()
|
secretPath: z.string().trim()
|
||||||
})
|
})
|
||||||
@@ -78,7 +78,7 @@ export const UpdateServiceTokenV3 = z.object({
|
|||||||
isActive: z.boolean().optional(),
|
isActive: z.boolean().optional(),
|
||||||
scopes: z
|
scopes: z
|
||||||
.object({
|
.object({
|
||||||
permission: z.enum(["read", "readWrite"]),
|
permissions: z.enum(["read", "write"]).array(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim()
|
secretPath: z.string().trim()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export enum Permission {
|
||||||
|
READ = "read",
|
||||||
|
WRITE = "write"
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Permission } from "./enums";
|
||||||
|
|
||||||
export type ServiceTokenScope = {
|
export type ServiceTokenScope = {
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
@@ -37,7 +39,7 @@ export type DeleteServiceTokenRes = { serviceTokenData: ServiceToken };
|
|||||||
// --- v3
|
// --- v3
|
||||||
|
|
||||||
export type ServiceTokenV3Scope = {
|
export type ServiceTokenV3Scope = {
|
||||||
permission: string;
|
permissions: Permission[];
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
};
|
};
|
||||||
@@ -48,6 +50,7 @@ export type ServiceTokenDataV3 = {
|
|||||||
workspace: string;
|
workspace: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
lastUsed?: string;
|
lastUsed?: string;
|
||||||
|
usageCount: number;
|
||||||
scopes: ServiceTokenV3Scope[];
|
scopes: ServiceTokenV3Scope[];
|
||||||
expiresAt?: string;
|
expiresAt?: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
|||||||
+34
-5
@@ -32,6 +32,9 @@ import {
|
|||||||
useGetUserWsKey,
|
useGetUserWsKey,
|
||||||
useUpdateServiceTokenV3
|
useUpdateServiceTokenV3
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
|
import {
|
||||||
|
Permission
|
||||||
|
} from "@app/hooks/api/serviceTokens/enums";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
const expirations = [
|
const expirations = [
|
||||||
@@ -43,7 +46,13 @@ const expirations = [
|
|||||||
{ label: "12 months", value: "31104000" }
|
{ label: "12 months", value: "31104000" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const permissionValues: Array<"read" | "readWrite"> = ["read", "readWrite"];
|
const permissionsMap: {
|
||||||
|
"read": Permission[],
|
||||||
|
"readWrite": Permission[]
|
||||||
|
} = {
|
||||||
|
"read": [Permission.READ],
|
||||||
|
"readWrite": [Permission.READ, Permission.WRITE],
|
||||||
|
}
|
||||||
|
|
||||||
const schema = yup.object({
|
const schema = yup.object({
|
||||||
name: yup.string().required("ST V3 name is required"),
|
name: yup.string().required("ST V3 name is required"),
|
||||||
@@ -51,7 +60,7 @@ const schema = yup.object({
|
|||||||
scopes: yup
|
scopes: yup
|
||||||
.array(
|
.array(
|
||||||
yup.object({
|
yup.object({
|
||||||
permission: yup.string().oneOf(permissionValues, "Invalid permission").required().label("Permission"),
|
permission: yup.string().oneOf(Object.keys(permissionsMap), "Invalid permission").required().label("Permission") as yup.SchemaOf<"read" | "readWrite", object>,
|
||||||
environment: yup.string().max(50).required().label("Environment"),
|
environment: yup.string().max(50).required().label("Environment"),
|
||||||
secretPath: yup
|
secretPath: yup
|
||||||
.string()
|
.string()
|
||||||
@@ -112,7 +121,18 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
if (serviceTokenData) {
|
if (serviceTokenData) {
|
||||||
reset({
|
reset({
|
||||||
name: serviceTokenData.name,
|
name: serviceTokenData.name,
|
||||||
scopes: serviceTokenData.scopes
|
scopes: serviceTokenData.scopes.map((scope) => {
|
||||||
|
let permission = "read";
|
||||||
|
if (scope.permissions.includes(Permission.WRITE)) {
|
||||||
|
permission = "readWrite";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ({
|
||||||
|
environment: scope.environment,
|
||||||
|
secretPath: scope.secretPath,
|
||||||
|
permission
|
||||||
|
})
|
||||||
|
})
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
reset({
|
reset({
|
||||||
@@ -140,12 +160,21 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
scopes: any;
|
scopes: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// convert read/readWrite permission => ["read", "write"] format
|
||||||
|
const reformattedScopes = scopes.map((scope) => {
|
||||||
|
return ({
|
||||||
|
environment: scope.environment,
|
||||||
|
secretPath: scope.secretPath,
|
||||||
|
permissions: permissionsMap[scope.permission]
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
if (serviceTokenData) {
|
if (serviceTokenData) {
|
||||||
// update
|
// update
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
serviceTokenDataId: serviceTokenData.serviceTokenDataId,
|
serviceTokenDataId: serviceTokenData.serviceTokenDataId,
|
||||||
name,
|
name,
|
||||||
scopes,
|
scopes: reformattedScopes,
|
||||||
expiresIn: expiresIn === "" ? undefined : Number(expiresIn)
|
expiresIn: expiresIn === "" ? undefined : Number(expiresIn)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -176,7 +205,7 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
name,
|
name,
|
||||||
workspaceId: currentWorkspace._id,
|
workspaceId: currentWorkspace._id,
|
||||||
publicKey,
|
publicKey,
|
||||||
scopes,
|
scopes: reformattedScopes,
|
||||||
expiresIn: expiresIn === "" ? undefined : Number(expiresIn),
|
expiresIn: expiresIn === "" ? undefined : Number(expiresIn),
|
||||||
encryptedKey: ciphertext,
|
encryptedKey: ciphertext,
|
||||||
nonce
|
nonce
|
||||||
|
|||||||
+14
-4
@@ -21,9 +21,8 @@ import {
|
|||||||
useGetWorkspaceServiceTokenDataV3,
|
useGetWorkspaceServiceTokenDataV3,
|
||||||
useUpdateServiceTokenV3
|
useUpdateServiceTokenV3
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
import {
|
import { ServiceTokenV3Scope } from "@app/hooks/api/serviceTokens/types"
|
||||||
ServiceTokenV3Scope
|
import { Permission } from "@app/hooks/api/serviceTokens/enums"
|
||||||
} from "@app/hooks/api/serviceTokens/types"
|
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -90,6 +89,7 @@ export const ServiceTokenV3Table = ({
|
|||||||
<Th>Name</Th>
|
<Th>Name</Th>
|
||||||
<Th>Status</Th>
|
<Th>Status</Th>
|
||||||
<Th>Scopes</Th>
|
<Th>Scopes</Th>
|
||||||
|
<Th># Times Used</Th>
|
||||||
<Th>Last Used</Th>
|
<Th>Last Used</Th>
|
||||||
<Th>Created At</Th>
|
<Th>Created At</Th>
|
||||||
<Th>Expires At</Th>
|
<Th>Expires At</Th>
|
||||||
@@ -106,6 +106,7 @@ export const ServiceTokenV3Table = ({
|
|||||||
name,
|
name,
|
||||||
isActive,
|
isActive,
|
||||||
lastUsed,
|
lastUsed,
|
||||||
|
usageCount,
|
||||||
scopes,
|
scopes,
|
||||||
createdAt,
|
createdAt,
|
||||||
expiresAt
|
expiresAt
|
||||||
@@ -135,16 +136,25 @@ export const ServiceTokenV3Table = ({
|
|||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
{scopes.map((scope) => {
|
{scopes.map((scope) => {
|
||||||
|
let permissionText = "read"
|
||||||
|
if (
|
||||||
|
scope.permissions.includes(Permission.WRITE) &&
|
||||||
|
scope.permissions.includes(Permission.READ)
|
||||||
|
) {
|
||||||
|
permissionText = "readWrite";
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p key={`service-token-${_id}-scope-${scope.environment}-${scope.secretPath}`}>
|
<p key={`service-token-${_id}-scope-${scope.environment}-${scope.secretPath}`}>
|
||||||
<span className="font-bold">
|
<span className="font-bold">
|
||||||
{scope.permission}
|
{scope.permissions}
|
||||||
</span>
|
</span>
|
||||||
{` @${scope.environment} - ${scope.secretPath}`}
|
{` @${scope.environment} - ${scope.secretPath}`}
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Td>
|
</Td>
|
||||||
|
<Td>{usageCount}</Td>
|
||||||
<Td>{lastUsed ? formatDate(lastUsed) : "-"}</Td>
|
<Td>{lastUsed ? formatDate(lastUsed) : "-"}</Td>
|
||||||
<Td>{formatDate(createdAt)}</Td>
|
<Td>{formatDate(createdAt)}</Td>
|
||||||
<Td>{expiresAt ? formatDate(expiresAt) : "-"}</Td>
|
<Td>{expiresAt ? formatDate(expiresAt) : "-"}</Td>
|
||||||
|
|||||||
Reference in New Issue
Block a user