"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PasskeySetupService = void 0;
const http_1 = __importDefault(require("../../utils/http"));
const KnowhowClient_1 = require("../../services/KnowhowClient");
const browserLogin_1 = require("../../auth/browserLogin");
const spinner_1 = require("../../auth/spinner");
const config_1 = require("../../config");
class PasskeySetupService {
    baseUrl;
    constructor(baseUrl = KnowhowClient_1.KNOWHOW_API_URL) {
        if (!baseUrl) {
            throw new Error("KNOWHOW_API_URL environment variable not set");
        }
        this.baseUrl = baseUrl;
    }
    async setup(jwt) {
        const spinner = new spinner_1.Spinner();
        try {
            spinner.start("Creating passkey setup session");
            const session = await this.createSetupSession(jwt);
            spinner.stop();
            await (0, browserLogin_1.openBrowser)(session.browserUrl);
            console.log(`\nIf the browser didn't open automatically, please visit:\n  ${session.browserUrl}\n`);
            spinner.start("Waiting for passkey registration in browser…");
            const credential = await this.pollForCompletion(session.sessionId, spinner);
            spinner.stop();
            spinner.start("Saving passkey credential to config");
            await this.saveCredential(credential);
            spinner.stop();
            console.log("✅ Passkey registered successfully!");
            console.log("   Worker will now require passkey authentication for new connections.");
        }
        catch (error) {
            spinner.stop();
            throw error;
        }
    }
    async reset() {
        const config = await (0, config_1.getConfig)();
        if (!config.worker?.auth?.passkey) {
            console.log("ℹ️  No passkey configured for this worker.");
            return;
        }
        const updatedConfig = {
            ...config,
            worker: {
                ...config.worker,
                auth: {
                    ...config.worker.auth,
                    required: false,
                    passkey: undefined,
                },
            },
        };
        await (0, config_1.updateConfig)(updatedConfig);
        console.log("✅ Passkey requirement removed from config.");
    }
    async createSetupSession(jwt) {
        try {
            const response = await http_1.default.post(`${this.baseUrl}/api/worker/passkey/setup/session`, {}, {
                headers: { Authorization: `Bearer ${jwt}` },
            });
            return response.data;
        }
        catch (error) {
            if (http_1.default.isHttpError(error)) {
                throw new Error(`Failed to create passkey setup session: ${error.message}`);
            }
            throw error;
        }
    }
    async pollForCompletion(sessionId, spinner) {
        const maxAttempts = 60;
        let attempt = 0;
        while (attempt < maxAttempts) {
            attempt++;
            try {
                const response = await http_1.default.get(`${this.baseUrl}/api/worker/passkey/setup/status/${sessionId}`);
                const { status, credential } = response.data;
                if (status === "complete" && credential) {
                    return credential;
                }
                else if (status === "expired") {
                    throw new Error("Passkey setup session expired. Please run 'knowhow worker --passkey' again.");
                }
            }
            catch (error) {
                if (http_1.default.isHttpError(error) && error.status === 408) {
                }
                else if (!(error instanceof Error && error.message.includes("expired"))) {
                    throw error;
                }
                else {
                    throw error;
                }
            }
            await this.sleep(5000);
        }
        throw new Error("Passkey setup timed out. Please try again.");
    }
    async saveCredential(credential) {
        const config = await (0, config_1.getConfig)();
        const updatedConfig = {
            ...config,
            worker: {
                ...config.worker,
                auth: {
                    ...config.worker?.auth,
                    required: true,
                    passkey: {
                        publicKey: credential.publicKey,
                        credentialId: credential.credentialId,
                        algorithm: credential.algorithm,
                    },
                    sessionDurationHours: config.worker?.auth?.sessionDurationHours ?? 3,
                },
            },
        };
        await (0, config_1.updateConfig)(updatedConfig);
    }
    async sleep(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }
}
exports.PasskeySetupService = PasskeySetupService;
//# sourceMappingURL=PasskeySetup.js.map