Files
infisical/backend/src/server/routes/v2/service-token-router.ts
T

151 lines
4.2 KiB
TypeScript

import { z } from "zod";
import { ServiceTokensSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { removeTrailingSlash } from "@app/lib/fn";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { sanitizedServiceTokenUserSchema } from "../sanitizedSchemas";
export const sanitizedServiceTokenSchema = ServiceTokensSchema.omit({
secretHash: true,
encryptedKey: true,
iv: true,
tag: true
});
export const registerServiceTokenRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/",
method: "GET",
onRequest: verifyAuth([AuthMode.SERVICE_TOKEN]),
schema: {
response: {
200: ServiceTokensSchema.merge(
z.object({
workspace: z.string(),
user: sanitizedServiceTokenUserSchema.merge(
z.object({
_id: z.string(),
__v: z.number().default(0)
})
),
_id: z.string(),
__v: z.number().default(0)
})
)
}
},
handler: async (req) => {
const { serviceToken, user } = await server.services.serviceToken.getServiceToken({
actorId: req.permission.id,
actor: req.permission.type
});
const formattedUser = {
...user,
_id: user.id,
__v: 0
} as const;
const formattedServiceToken = {
...serviceToken,
_id: serviceToken.id,
__v: 0
} as const;
// We return the user here because older versions of the deprecated Python SDK depend on it to properly parse the API response.
return { ...formattedServiceToken, workspace: serviceToken.projectId, user: formattedUser };
}
});
server.route({
url: "/",
method: "POST",
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
body: z.object({
name: z.string().trim(),
workspaceId: z.string().trim(),
scopes: z
.object({
environment: z.string().trim(),
secretPath: z.string().trim().transform(removeTrailingSlash)
})
.array()
.min(1),
encryptedKey: z.string().trim(),
iv: z.string().trim(),
tag: z.string().trim(),
expiresIn: z.number().nullable(),
permissions: z.enum(["read", "write"]).array()
}),
response: {
200: z.object({
serviceToken: z.string(),
serviceTokenData: sanitizedServiceTokenSchema
})
}
},
handler: async (req) => {
const { serviceToken, token } = await server.services.serviceToken.createServiceToken({
actorId: req.permission.id,
actor: req.permission.type,
...req.body,
projectId: req.body.workspaceId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: serviceToken.projectId,
event: {
type: EventType.CREATE_SERVICE_TOKEN,
metadata: {
name: serviceToken.name,
scopes: req.body.scopes
}
}
});
return { serviceToken: token, serviceTokenData: serviceToken };
}
});
server.route({
url: "/:serviceTokenId",
method: "DELETE",
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
params: z.object({
serviceTokenId: z.string().trim()
}),
response: {
200: z.object({
serviceTokenData: sanitizedServiceTokenSchema
})
}
},
handler: async (req) => {
const serviceTokenData = await server.services.serviceToken.deleteServiceToken({
actorId: req.permission.id,
actor: req.permission.type,
id: req.params.serviceTokenId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: serviceTokenData.projectId,
event: {
type: EventType.DELETE_SERVICE_TOKEN,
metadata: {
name: serviceTokenData.name,
scopes: serviceTokenData.scopes as Array<{ environment: string; secretPath: string }>
}
}
});
return { serviceTokenData };
}
});
};