mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-19 16:01:44 +00:00
125 lines
3.9 KiB
TypeScript
125 lines
3.9 KiB
TypeScript
import { requestContext } from "@fastify/request-context";
|
|
import { z } from "zod";
|
|
|
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
|
import { getConfig } from "@app/lib/config/env";
|
|
import { BadRequestError } from "@app/lib/errors";
|
|
import { writeLimit } from "@app/server/config/rateLimiter";
|
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
|
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
|
|
|
export const registerAssumePrivilegeRouter = async (server: FastifyZodProvider) => {
|
|
server.route({
|
|
method: "POST",
|
|
url: "/:projectId/assume-privileges",
|
|
config: {
|
|
rateLimit: writeLimit
|
|
},
|
|
schema: {
|
|
params: z.object({
|
|
projectId: z.string()
|
|
}),
|
|
body: z.object({
|
|
actorType: z.enum([ActorType.USER, ActorType.IDENTITY]),
|
|
actorId: z.string()
|
|
}),
|
|
response: {
|
|
200: z.object({
|
|
message: z.string()
|
|
})
|
|
}
|
|
},
|
|
onRequest: verifyAuth([AuthMode.JWT]),
|
|
handler: async (req, res) => {
|
|
if (req.auth.authMode === AuthMode.JWT) {
|
|
const payload = await server.services.assumePrivileges.assumeProjectPrivileges({
|
|
targetActorType: req.body.actorType,
|
|
targetActorId: req.body.actorId,
|
|
projectId: req.params.projectId,
|
|
actorPermissionDetails: req.permission,
|
|
tokenVersionId: req.auth.tokenVersionId
|
|
});
|
|
|
|
const appCfg = getConfig();
|
|
void res.setCookie("infisical-project-assume-privileges", payload.assumePrivilegesToken, {
|
|
httpOnly: true,
|
|
path: "/",
|
|
sameSite: "strict",
|
|
secure: appCfg.HTTPS_ENABLED,
|
|
maxAge: 3600 // 1 hour in seconds
|
|
});
|
|
|
|
await server.services.auditLog.createAuditLog({
|
|
...req.auditLogInfo,
|
|
orgId: req.permission.orgId,
|
|
event: {
|
|
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_START,
|
|
metadata: {
|
|
projectId: req.params.projectId,
|
|
requesterEmail: req.auth.user.username,
|
|
requesterId: req.auth.user.id,
|
|
targetActorType: req.body.actorType,
|
|
targetActorId: req.body.actorId,
|
|
duration: "1hr"
|
|
}
|
|
}
|
|
});
|
|
|
|
return { message: "Successfully assumed role" };
|
|
}
|
|
|
|
throw new BadRequestError({ message: "Invalid auth mode" });
|
|
}
|
|
});
|
|
|
|
server.route({
|
|
method: "DELETE",
|
|
url: "/:projectId/assume-privileges",
|
|
config: {
|
|
rateLimit: writeLimit
|
|
},
|
|
schema: {
|
|
params: z.object({
|
|
projectId: z.string()
|
|
}),
|
|
response: {
|
|
200: z.object({
|
|
message: z.string()
|
|
})
|
|
}
|
|
},
|
|
onRequest: verifyAuth([AuthMode.JWT]),
|
|
handler: async (req, res) => {
|
|
const assumedPrivilegeDetails = requestContext.get("assumedPrivilegeDetails");
|
|
if (req.auth.authMode === AuthMode.JWT && assumedPrivilegeDetails) {
|
|
const appCfg = getConfig();
|
|
void res.setCookie("infisical-project-assume-privileges", "", {
|
|
httpOnly: true,
|
|
path: "/",
|
|
sameSite: "strict",
|
|
secure: appCfg.HTTPS_ENABLED,
|
|
expires: new Date(0)
|
|
});
|
|
|
|
await server.services.auditLog.createAuditLog({
|
|
...req.auditLogInfo,
|
|
orgId: req.permission.orgId,
|
|
event: {
|
|
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_END,
|
|
metadata: {
|
|
projectId: req.params.projectId,
|
|
requesterEmail: req.auth.user.username,
|
|
requesterId: req.auth.user.id,
|
|
targetActorId: assumedPrivilegeDetails.actorId,
|
|
targetActorType: assumedPrivilegeDetails.actorType
|
|
}
|
|
}
|
|
});
|
|
return { message: "Successfully exited assumed role" };
|
|
}
|
|
|
|
throw new BadRequestError({ message: "Invalid auth mode" });
|
|
}
|
|
});
|
|
};
|