1cc62230ab
* Create schema and migration for organization access tokens * Add helpers for creating and authenticating OATs * Adapt the auth service to also accept OATs * Accept OATs in the whoami v2 endpoint * Enable deployments with the CLI using OATs * Avoid reading env variables directly in the token utils * Remove duplicate cli token utils * Validate ENCRYPTION_KEY length when parsing env vars * Make token utils a server-only module * Disallow revoking already revoked OATs * Simplify generics in authenticateRequest * Use 32 bytes mock encryption key in the test setup * Update dummy encryption key values in tests and templates * Add a column in the OATs table to differentiate between user and system generated * Simplify args for v3ProjectPath Co-authored-by: Matt Aitken <matt@mattaitken.com> * Add index on org id and createdAt * Avoid storing the encrypted oat token and its obfuscated version in the DB at all It is a safer approach. Also we do not need to ever read the decrypted token value after creation. * Fix prisma update condition * Add token type to the OAT table index * Accept OATs in the mcp auth flow * Simplify env auth flow around the /projects endpoints --------- Co-authored-by: Matt Aitken <matt@mattaitken.com>
35 lines
969 B
TypeScript
35 lines
969 B
TypeScript
import nodeCrypto from "node:crypto";
|
|
|
|
export function encryptToken(value: string, key: string) {
|
|
const nonce = nodeCrypto.randomBytes(12);
|
|
const cipher = nodeCrypto.createCipheriv("aes-256-gcm", key, nonce);
|
|
|
|
let encrypted = cipher.update(value, "utf8", "hex");
|
|
encrypted += cipher.final("hex");
|
|
|
|
const tag = cipher.getAuthTag().toString("hex");
|
|
|
|
return {
|
|
nonce: nonce.toString("hex"),
|
|
ciphertext: encrypted,
|
|
tag,
|
|
};
|
|
}
|
|
|
|
export function decryptToken(nonce: string, ciphertext: string, tag: string, key: string): string {
|
|
const decipher = nodeCrypto.createDecipheriv("aes-256-gcm", key, Buffer.from(nonce, "hex"));
|
|
|
|
decipher.setAuthTag(Buffer.from(tag, "hex"));
|
|
|
|
let decrypted = decipher.update(ciphertext, "hex", "utf8");
|
|
decrypted += decipher.final("utf8");
|
|
|
|
return decrypted;
|
|
}
|
|
|
|
export function hashToken(token: string): string {
|
|
const hash = nodeCrypto.createHash("sha256");
|
|
hash.update(token);
|
|
return hash.digest("hex");
|
|
}
|