[INIT] Initial Project Structure
Some checks failed
Deploy Edge / deploy-edge (push) Failing after 2s
S3 Repo Backup / s3-repo-backup (push) Failing after 2s

This commit is contained in:
Dunemask 2024-08-24 12:41:04 -06:00
commit 0fc5f05b6a
105 changed files with 10448 additions and 0 deletions

View file

@ -0,0 +1,48 @@
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<CProjectContract["CreateResponse"]> {
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 };
}
}

View file

@ -0,0 +1,22 @@
import { VixpressRoute } from "@dunemask/vix";
import { contract } from "@dunemask/vix/express";
import { Router } from "express";
import ProjectController from "./project.controller";
import { ProjectContract } from "@lib/contracts/project.contracts";
import RouteGuard from "@lib/vix/RouteGuard";
export class ProjectRoute extends VixpressRoute {
async configureRoutes(router: Router) {
const jsonOpts = { limit: "20mb" };
const cBase = { json: jsonOpts, reqParams: ProjectContract.ProjectParams };
// Controllers
const projController = this.useController(ProjectController);
// Configuration
const projCreate = { ...cBase, reqBody: ProjectContract.Create };
// Middleware
// Routes
router.post("/create", RouteGuard.MangeProjectsCreate, contract(projController.create, projCreate));
}
}

View file

@ -0,0 +1,36 @@
import bcrypt from "bcrypt";
import { signToken, verifyToken } from "@lib/svc/token.service";
import config from "@lib/config";
import { decrypt } from "@lib/svc/crypt.service";
const { HashRounds } = config.SigningOptions;
export async function getUserToken(id: string, encryptedPrivateKey: string) {
const privateKey = await decrypt(encryptedPrivateKey, config.SigningOptions.Keys.KeyPair);
const tokenPayload = {
iss: config.SigningOptions.Issuer,
sub: [config.SigningOptions.Subjects.User],
aud: [config.SigningOptions.Issuer],
id,
};
return signToken(tokenPayload, privateKey);
}
export async function userTokenLogin(token: string, encryptedPublicKey: string): Promise<boolean> {
const publicKey = await decrypt(encryptedPublicKey, config.SigningOptions.Keys.KeyPair);
return !!verifyToken(token, publicKey);
}
export async function getUserTokenId(token: string, encryptedPublicKey: string): Promise<string | undefined> {
const publicKey = await decrypt(encryptedPublicKey, config.SigningOptions.Keys.KeyPair);
const tokenData = verifyToken(token, publicKey);
if (!tokenData) return undefined;
return tokenData.id;
}
export async function hashText(password: string) {
return bcrypt.hash(password, HashRounds);
}
export async function hashCompare(password: string, hash: string) {
return bcrypt.compare(password, hash);
}