import { create, get } from '../../../../node_modules/@github/webauthn-json/dist/esm/webauthn-json.mjs';
import { omitUser } from '../utils/index.mjs';
import { logger } from '../utils/logger.mjs';

class HeadlessWebAuthnClient {
    _networkClient;
    _subscriptionService;
    dfpProtectedAuth;
    register;
    authenticate;
    constructor(_networkClient, _subscriptionService, dfpProtectedAuth){
        this._networkClient = _networkClient;
        this._subscriptionService = _subscriptionService;
        this.dfpProtectedAuth = dfpProtectedAuth;
        this.register = this._subscriptionService.withUpdateSession(async (options)=>{
            const startResp = await this._networkClient.fetchSDK({
                url: '/webauthn/register/start',
                method: 'POST',
                body: {
                    domain: options?.domain ?? window.location.hostname,
                    authenticator_type: options?.authenticator_type ?? undefined,
                    return_passkey_credential_options: options?.is_passkey,
                    override_id: options?.override_id,
                    override_name: options?.override_name,
                    override_display_name: options?.override_display_name,
                    user_agent: navigator.userAgent,
                    use_base64_url_encoding: options?.use_base64_url_encoding
                }
            });
            const publicKeyCredentialCreationOptions = startResp.public_key_credential_creation_options;
            const publicKey = JSON.parse(publicKeyCredentialCreationOptions);
            const credential = await create({
                publicKey: publicKey
            });
            const resp = await this._networkClient.fetchSDK({
                url: '/webauthn/register',
                method: 'POST',
                body: {
                    public_key_credential: JSON.stringify(credential),
                    session_duration_minutes: options?.session_duration_minutes
                }
            });
            return omitUser(resp);
        });
        this.authenticate = this._subscriptionService.withUpdateSession(async (options)=>{
            const { dfp_telemetry_id, captcha_token } = await this.dfpProtectedAuth.getDFPTelemetryIDAndCaptcha();
            if (options.conditional_mediation) {
                if (!await this.browserSupportsAutofill()) {
                    logger.error('Browser does not support WebAuthn autofill');
                    return null;
                }
                if (!options.disable_input_check && !this.checkEligibleInputs()) {
                    return null;
                }
            }
            const isLoggedIn = !!this._subscriptionService.getSession();
            const endpoint = isLoggedIn ? '/webauthn/authenticate/start/secondary' : '/webauthn/authenticate/start/primary';
            const startResp = await this._networkClient.fetchSDK({
                url: endpoint,
                method: 'POST',
                body: {
                    domain: options.domain ?? window.location.hostname,
                    return_passkey_credential_options: options?.is_passkey
                }
            });
            const publicKeyCredentialRequestOptions = startResp.public_key_credential_request_options;
            const abortController = new AbortController();
            const credReqOptions = {
                publicKey: JSON.parse(publicKeyCredentialRequestOptions),
                signal: options.signal ?? abortController.signal
            };
            const conditionalMediationCredReqOption = {
                ...credReqOptions,
                mediation: 'conditional'
            };
            const credential = await get(options.conditional_mediation ? conditionalMediationCredReqOption : credReqOptions);
            const authenticationData = await this._networkClient.retriableFetchSDK({
                url: '/webauthn/authenticate',
                method: 'POST',
                body: {
                    public_key_credential: JSON.stringify(credential),
                    session_duration_minutes: options.session_duration_minutes,
                    dfp_telemetry_id,
                    captcha_token
                },
                retryCallback: this.dfpProtectedAuth.retryWithCaptchaAndDFP
            });
            return omitUser(authenticationData);
        });
    }
    async update(options) {
        const url = '/webauthn/update/' + options.webauthn_registration_id;
        return await this._networkClient.fetchSDK({
            url: url,
            method: 'PUT',
            body: {
                name: options.name
            }
        });
    }
    async browserSupportsAutofill() {
        return await window.PublicKeyCredential?.isConditionalMediationAvailable?.() ?? false;
    }
    checkEligibleInputs = ()=>{
        // Check for an <input> with "webauthn" in its `autocomplete` attribute
        const eligibleInputs = document.querySelectorAll("input[autocomplete*='webauthn']");
        // WebAuthn autofill requires at least one valid input
        if (eligibleInputs.length < 1) {
            logger.error('No <input> with `"webauthn"` in its `autocomplete` attribute was detected');
            return false;
        }
        return true;
    };
}

export { HeadlessWebAuthnClient };
//# sourceMappingURL=HeadlessWebAuthnClient.mjs.map
