"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkerPasskeyAuthService = void 0;
const crypto_1 = __importDefault(require("crypto"));
const server_1 = require("@simplewebauthn/server");
class WorkerPasskeyAuthService {
    passkeyConfig;
    locked = true;
    sessionExpiry = null;
    sessionDurationMs;
    pendingChallenge = null;
    pendingChallengeExpiry = null;
    CHALLENGE_TTL_MS = 5 * 60 * 1000;
    constructor(passkeyConfig, sessionDurationHours = 3) {
        this.passkeyConfig = passkeyConfig;
        this.sessionDurationMs = sessionDurationHours * 60 * 60 * 1000;
    }
    isLocked() {
        if (!this.locked) {
            if (this.sessionExpiry && Date.now() > this.sessionExpiry) {
                console.log("🔒 Passkey session expired, locking worker");
                this.locked = true;
                this.sessionExpiry = null;
            }
        }
        return this.locked;
    }
    generateChallenge() {
        const challengeBytes = crypto_1.default.randomBytes(32);
        const challenge = challengeBytes.toString("base64url");
        this.pendingChallenge = challenge;
        this.pendingChallengeExpiry = Date.now() + this.CHALLENGE_TTL_MS;
        return challenge;
    }
    async unlock(params) {
        if (!this.pendingChallenge) {
            return { success: false, reason: "No pending challenge. Call getChallenge first." };
        }
        if (this.pendingChallengeExpiry && Date.now() > this.pendingChallengeExpiry) {
            this.pendingChallenge = null;
            this.pendingChallengeExpiry = null;
            return { success: false, reason: "Challenge expired. Please request a new challenge." };
        }
        let clientData;
        try {
            const clientDataBytes = Buffer.from(params.clientDataJSON, "base64url");
            clientData = JSON.parse(clientDataBytes.toString("utf8"));
        }
        catch {
            return { success: false, reason: "Invalid clientDataJSON" };
        }
        if (clientData.challenge !== this.pendingChallenge) {
            return { success: false, reason: "Challenge mismatch" };
        }
        if (clientData.type !== "webauthn.get") {
            return { success: false, reason: "Invalid clientData type" };
        }
        if (params.credentialId !== this.passkeyConfig.credentialId) {
            return { success: false, reason: "Unknown credential" };
        }
        const valid = await this.verifySignature(params, clientData.origin);
        if (!valid) {
            return { success: false, reason: "Invalid signature" };
        }
        this.locked = false;
        this.sessionExpiry = Date.now() + this.sessionDurationMs;
        this.pendingChallenge = null;
        this.pendingChallengeExpiry = null;
        const expiresAt = new Date(this.sessionExpiry).toISOString();
        console.log(`🔓 Worker unlocked! Session expires at ${expiresAt}`);
        return { success: true };
    }
    lock() {
        this.locked = true;
        this.sessionExpiry = null;
        this.pendingChallenge = null;
        this.pendingChallengeExpiry = null;
        console.log("🔒 Worker locked");
    }
    getSessionInfo() {
        if (this.locked || !this.sessionExpiry) {
            return { locked: true, expiresAt: null };
        }
        return {
            locked: false,
            expiresAt: new Date(this.sessionExpiry).toISOString(),
        };
    }
    getCredentialId() {
        return this.passkeyConfig.credentialId;
    }
    async verifySignature(params, origin) {
        try {
            const { verified } = await (0, server_1.verifyAuthenticationResponse)({
                response: {
                    id: params.credentialId,
                    rawId: params.credentialId,
                    response: {
                        authenticatorData: params.authenticatorData,
                        clientDataJSON: params.clientDataJSON,
                        signature: params.signature,
                    },
                    type: "public-key",
                    clientExtensionResults: {},
                },
                expectedChallenge: this.pendingChallenge,
                expectedOrigin: origin,
                expectedRPID: new URL(origin).hostname,
                credential: {
                    id: this.passkeyConfig.credentialId,
                    publicKey: Buffer.from(this.passkeyConfig.publicKey, "base64url"),
                    counter: 0,
                    transports: undefined,
                },
                requireUserVerification: false,
            });
            return verified;
        }
        catch (err) {
            console.error("Signature verification error:", err);
            return false;
        }
    }
}
exports.WorkerPasskeyAuthService = WorkerPasskeyAuthService;
//# sourceMappingURL=WorkerPasskeyAuth.js.map