61 lines
2.8 KiB
TypeScript
61 lines
2.8 KiB
TypeScript
|
import config from "@lib/config";
|
||
|
import TableService from "../TableService";
|
||
|
import { CKeyPairContract } from "@lib/contracts/keypair.contracts";
|
||
|
import { KeyPairErrors, ProjectErrors } from "@lib/vix/ClientErrors";
|
||
|
import { encrypt, generateKeypair } from "@lib/svc/crypt.service";
|
||
|
import { KeyPair, KeyPairType } from "@prisma/client";
|
||
|
|
||
|
declare type Custom = "Custom"; // Make sure this matches KeyPairType.Custom;
|
||
|
|
||
|
export default class KeyPairTableService extends TableService {
|
||
|
protected table = "KeyPair";
|
||
|
async byId(keypairId: string) {
|
||
|
const keypair = this.pg.keyPair.findUnique({ where: { id: keypairId } });
|
||
|
if (!keypair) throw KeyPairErrors.NotFoundKeypair;
|
||
|
}
|
||
|
|
||
|
async byUsage(projectIdentity: string, usage: Custom): Promise<KeyPair[]>;
|
||
|
async byUsage(projectIdentity: string, usage: Exclude<KeyPairType, Custom>): Promise<KeyPair | null>;
|
||
|
async byUsage(projectIdentity: string, usage: KeyPairType): Promise<KeyPair[] | KeyPair | null> {
|
||
|
const projectOr = { OR: [{ id: projectIdentity }, { slug: projectIdentity }] };
|
||
|
const projectInclude = { keyPairs: { where: { usage: KeyPairType.UserToken } } };
|
||
|
const project = await this.pg.project.findFirst({ where: projectOr, include: projectInclude });
|
||
|
if (!project) throw ProjectErrors.BadRequestProjectIncomplete;
|
||
|
const keypairs = project.keyPairs;
|
||
|
if (usage !== KeyPairType.Custom && keypairs.length > 1)
|
||
|
throw new Error(`Multiple keypairs found for project ${projectIdentity} and usage ${usage}`);
|
||
|
if (usage !== KeyPairType.Custom && keypairs.length === 0) return null;
|
||
|
if (usage !== KeyPairType.Custom) return keypairs[0];
|
||
|
return keypairs;
|
||
|
}
|
||
|
|
||
|
async $upsertDefaultKeyPairs() {
|
||
|
const projectSlug = config.Server.projectSlug;
|
||
|
const cairoProject = await this.pg.project.findUnique({ where: { slug: projectSlug } });
|
||
|
if (!cairoProject) throw new Error("Cairo Project Not Found!");
|
||
|
const projectId = cairoProject.id;
|
||
|
await this.upsertProjecttDefaultKeyPairs(projectId);
|
||
|
}
|
||
|
|
||
|
async upsertProjecttDefaultKeyPairs(projectId: string) {
|
||
|
const storeKeypair = this.create.bind(this);
|
||
|
const keyTypes = Object.values(KeyPairType).filter((kp) => kp !== KeyPairType.Custom);
|
||
|
await Promise.all(
|
||
|
keyTypes.map(async (kp) => {
|
||
|
const existingKp = await this.byUsage(projectId, kp);
|
||
|
if (!!existingKp) return;
|
||
|
const { publicKey, privateKey } = await generateKeypair();
|
||
|
const [encryptedPrivateKey, encryptedPublicKey] = await Promise.all([
|
||
|
encrypt(privateKey, config.SigningOptions.Keys.KeyPair),
|
||
|
encrypt(publicKey, config.SigningOptions.Keys.KeyPair),
|
||
|
]);
|
||
|
return storeKeypair({ encryptedPrivateKey, encryptedPublicKey, projectId, usage: kp });
|
||
|
}),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
async create(keypair: CKeyPairContract["Create"]) {
|
||
|
return this.pg.keyPair.create({ data: keypair });
|
||
|
}
|
||
|
}
|