update
This commit is contained in:
1 parent
7a3db27ffa
commit
1ba3147ed2
96 files changed
+9400
-6269
No files matched your search
+35
-3
@@ -1,6 +1,8 @@
|
||||
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
||||
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
const SIGNING_KEY = randomBytes(32);
|
||||
let signingKey: Buffer | null = null;
|
||||
const TOKEN_TTL_MS = 48 * 60 * 60 * 1000; // 48 hours
|
||||
|
||||
interface TokenPayload {
|
||||
@@ -12,20 +14,22 @@ interface TokenPayload {
|
||||
}
|
||||
|
||||
function sign(payload: TokenPayload): string {
|
||||
const key = getSigningKey();
|
||||
const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
|
||||
const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
||||
const signature = createHmac("sha256", SIGNING_KEY)
|
||||
const signature = createHmac("sha256", key)
|
||||
.update(`${header}.${body}`)
|
||||
.digest("base64url");
|
||||
return `${header}.${body}.${signature}`;
|
||||
}
|
||||
|
||||
function verify(token: string): TokenPayload | null {
|
||||
const key = getSigningKey();
|
||||
const parts = token.split(".");
|
||||
if (parts.length !== 3) return null;
|
||||
const [header, body, signature] = parts as [string, string, string];
|
||||
|
||||
const expectedSignature = createHmac("sha256", SIGNING_KEY)
|
||||
const expectedSignature = createHmac("sha256", key)
|
||||
.update(`${header}.${body}`)
|
||||
.digest("base64url");
|
||||
|
||||
@@ -44,6 +48,34 @@ function verify(token: string): TokenPayload | null {
|
||||
}
|
||||
}
|
||||
|
||||
function getSigningKey() {
|
||||
if (!signingKey) {
|
||||
throw new Error("Agent token signing key was used before initialization.");
|
||||
}
|
||||
return signingKey;
|
||||
}
|
||||
|
||||
export function initializeAgentTokenSigningKey(profileDir: string) {
|
||||
const keyPath = join(profileDir, "agent-api-signing.key");
|
||||
mkdirSync(profileDir, { recursive: true });
|
||||
try {
|
||||
const nextKey = randomBytes(32);
|
||||
writeFileSync(keyPath, nextKey, { flag: "wx", mode: 0o600 });
|
||||
signingKey = nextKey;
|
||||
return;
|
||||
} catch (error) {
|
||||
const code = (error as NodeJS.ErrnoException).code;
|
||||
if (code !== "EEXIST") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
const persistedKey = readFileSync(keyPath);
|
||||
if (persistedKey.length !== 32) {
|
||||
throw new Error(`Invalid agent API signing key length at ${keyPath}. Expected 32 bytes, received ${persistedKey.length}.`);
|
||||
}
|
||||
signingKey = persistedKey;
|
||||
}
|
||||
|
||||
export function createAgentToken(agentId: string, companyId: string, runId: string): string {
|
||||
const now = Date.now();
|
||||
return sign({ agentId, companyId, runId, iat: now, exp: now + TOKEN_TTL_MS });
|
||||
|
||||
Reference in new issue
Block a user