mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-16 15:08:46 +00:00
101 lines
2.7 KiB
TypeScript
101 lines
2.7 KiB
TypeScript
import pg from "pg";
|
|
import { IntegrityError } from "./error";
|
|
import db from "./kysely";
|
|
import type { MekState } from "./schema";
|
|
|
|
interface Mek {
|
|
userId: number;
|
|
version: number;
|
|
state: MekState;
|
|
}
|
|
|
|
interface ClientMekWithDetails extends Mek {
|
|
clientId: number;
|
|
encMek: string;
|
|
encMekSig: string;
|
|
}
|
|
|
|
export const registerInitialMek = async (
|
|
userId: number,
|
|
createdBy: number,
|
|
encMek: string,
|
|
encMekSig: string,
|
|
) => {
|
|
await db.transaction().execute(async (trx) => {
|
|
try {
|
|
await trx
|
|
.insertInto("master_encryption_key")
|
|
.values({
|
|
user_id: userId,
|
|
version: 1,
|
|
state: "active",
|
|
})
|
|
.execute();
|
|
await trx
|
|
.insertInto("client_master_encryption_key")
|
|
.values({
|
|
user_id: userId,
|
|
client_id: createdBy,
|
|
version: 1,
|
|
encrypted_key: encMek,
|
|
encrypted_key_signature: encMekSig,
|
|
})
|
|
.execute();
|
|
await trx
|
|
.insertInto("master_encryption_key_log")
|
|
.values({
|
|
user_id: userId,
|
|
master_encryption_key_version: 1,
|
|
timestamp: new Date(),
|
|
action: "create",
|
|
action_by: createdBy,
|
|
})
|
|
.execute();
|
|
} catch (e) {
|
|
if (e instanceof pg.DatabaseError && e.code === "23505") {
|
|
throw new IntegrityError("MEK already registered");
|
|
}
|
|
throw e;
|
|
}
|
|
});
|
|
};
|
|
|
|
export const getInitialMek = async (userId: number) => {
|
|
const mek = await db
|
|
.selectFrom("master_encryption_key")
|
|
.selectAll()
|
|
.where("user_id", "=", userId)
|
|
.where("version", "=", 1)
|
|
.limit(1)
|
|
.executeTakeFirst();
|
|
return mek
|
|
? ({ userId: mek.user_id, version: mek.version, state: mek.state } satisfies Mek)
|
|
: null;
|
|
};
|
|
|
|
export const getAllValidClientMeks = async (userId: number, clientId: number) => {
|
|
const clientMeks = await db
|
|
.selectFrom("client_master_encryption_key")
|
|
.innerJoin("master_encryption_key", (join) =>
|
|
join
|
|
.onRef("client_master_encryption_key.user_id", "=", "master_encryption_key.user_id")
|
|
.onRef("client_master_encryption_key.version", "=", "master_encryption_key.version"),
|
|
)
|
|
.selectAll()
|
|
.where("client_master_encryption_key.user_id", "=", userId)
|
|
.where("client_master_encryption_key.client_id", "=", clientId)
|
|
.where((eb) => eb.or([eb("state", "=", "active"), eb("state", "=", "retired")]))
|
|
.execute();
|
|
return clientMeks.map(
|
|
({ user_id, client_id, version, state, encrypted_key, encrypted_key_signature }) =>
|
|
({
|
|
userId: user_id,
|
|
version,
|
|
state: state as "active" | "retired",
|
|
clientId: client_id,
|
|
encMek: encrypted_key,
|
|
encMekSig: encrypted_key_signature,
|
|
}) satisfies ClientMekWithDetails,
|
|
);
|
|
};
|