import { randomUUID, sign as cryptoSign } from 'node:crypto';
export const DEFAULT_WORKFLOW_TOKEN_TTL_SECONDS = 2 * 60 * 60;
export const DEFAULT_ADMIN_AGENT_NAME = 'relay-admin';
export const DEFAULT_ADMIN_SCOPES = [
    'relayauth:*:manage:*',
    'relayauth:*:read:*',
    'relayfile:*:*:*',
    'fs:read',
    'fs:write',
    'sync:trigger',
    'ops:read',
    'admin:read',
];
function base64urlEncode(value) {
    return Buffer.from(JSON.stringify(value)).toString('base64url');
}
function normalizeTtlSeconds(ttlSeconds) {
    if (ttlSeconds === undefined) {
        return DEFAULT_WORKFLOW_TOKEN_TTL_SECONDS;
    }
    return Math.max(1, Math.floor(ttlSeconds));
}
export function mintAgentToken(opts) {
    const now = Math.floor(Date.now() / 1000);
    const header = { alg: 'RS256', typ: 'JWT', kid: opts.kid };
    const payload = {
        sub: `agent_${opts.agentName}`,
        org: 'org_relay',
        wks: opts.workspace,
        workspace_id: opts.workspace,
        agent_name: opts.agentName,
        scopes: [...opts.scopes],
        sponsorId: 'relay-local',
        sponsorChain: ['relay-local'],
        token_type: 'access',
        iss: 'relayauth:local',
        aud: ['relayauth', 'relayfile'],
        iat: now,
        exp: now + normalizeTtlSeconds(opts.ttlSeconds),
        jti: `tok-${now}-${randomUUID()}`,
    };
    const unsigned = `${base64urlEncode(header)}.${base64urlEncode(payload)}`;
    const signature = cryptoSign('RSA-SHA256', Buffer.from(unsigned), opts.privateKey).toString('base64url');
    return `${unsigned}.${signature}`;
}
export class WorkflowTokenFactory {
    privateKey;
    kid;
    workspace;
    tokens = new Map();
    ttlSeconds;
    constructor(privateKey, kid, workspace, ttlSeconds = DEFAULT_WORKFLOW_TOKEN_TTL_SECONDS) {
        this.privateKey = privateKey;
        this.kid = kid;
        this.workspace = workspace;
        this.ttlSeconds = normalizeTtlSeconds(ttlSeconds);
    }
    mintForAgent(agentName, scopes, ttlSeconds = this.ttlSeconds) {
        const token = mintAgentToken({
            privateKey: this.privateKey,
            kid: this.kid,
            workspace: this.workspace,
            agentName,
            scopes,
            ttlSeconds,
        });
        this.tokens.set(agentName, token);
        return token;
    }
    mintAdmin(ttlSeconds = this.ttlSeconds) {
        return this.mintForAgent(DEFAULT_ADMIN_AGENT_NAME, DEFAULT_ADMIN_SCOPES, ttlSeconds);
    }
    getToken(agentName) {
        return this.tokens.get(agentName);
    }
}
//# sourceMappingURL=token.js.map