import { Express } from "express"; import { VixpressController } from "@dunemask/vix"; import Cairo from "@lib/Cairo"; import type PostgresService from "@lib/database/PostgresService"; import { ContractRouteContext } from "@dunemask/vix/express"; import { ProjectErrors } from "@lib/vix/ClientErrors"; import { CDatabaseContract } from "@lib/contracts/database.contracts"; import { CProjectContract, ProjectContract } from "@lib/contracts/project.contracts"; import { KeyPairType } from "@prisma/client"; import { decrypt } from "@lib/svc/crypt.service"; import config from "@lib/config"; import { UserRequest } from "@lib/types/ApiRequests"; import { PolicyString } from "@lib/Policies"; import { Resource } from "@lib/vix/AppResources"; type CreateCRC = ContractRouteContext<{ RequestBodyContract: typeof ProjectContract.Create; RequestParamsContract: typeof ProjectContract.ProjectParams; }>; export default class ProjectController extends VixpressController { declare pg: PostgresService; constructor(app: Express) { super(app); this.pg = this.app.get(Cairo.PostgresService); } async create(crc: CreateCRC): Promise { const { project: parentProject } = crc.req as UserRequest; const proj = await this.pg.project.create({ ...crc.reqBody, parentProject: parentProject.id }); const rolePolicy = await this.pg.rolePolicy.create({ name: `${crc.reqBody.slug} Project Root`, authority: config.RolePolicy.Root.id, projectId: proj.id, policies: [`${Resource.CairoProjectRoot}.root`] as PolicyString[], }); const [user] = await Promise.all([ this.pg.users.$upsertRootUser(proj.id, rolePolicy.id), this.pg.keypair.upsertProjecttDefaultKeyPairs(proj.id), ]); const kp = await this.pg.keypair.byUsage(proj.id, KeyPairType.UserToken); if (!kp) throw ProjectErrors.BadRequestProjectIncomplete; if (!user) throw ProjectErrors.UnexpectedRootUserError; const userData: CDatabaseContract["User"] = { username: user.username, rolePolicyId: user.rolePolicyId }; const publicKey = await decrypt(kp.encryptedPublicKey, config.SigningOptions.Keys.KeyPair); return { user: userData, project: proj, publicKey }; } }