"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseOAuthProvider = void 0;
const rxjs_1 = require("rxjs");
const oauth_errors_1 = require("../oauth.errors");
class BaseOAuthProvider {
    constructor(http) {
        this.http = http;
    }
    async fetchToken({ code, url, clientId, clientSecret, redirectUri, }) {
        const body = new URLSearchParams({
            client_id: clientId,
            client_secret: clientSecret,
            redirect_uri: redirectUri,
            grant_type: 'authorization_code',
            code,
        }).toString();
        const response = await (0, rxjs_1.lastValueFrom)(this.http.post(url, body, {
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        }));
        return response.data;
    }
    async fetchProfile(accessToken, url) {
        const response = await (0, rxjs_1.lastValueFrom)(this.http.get(url, {
            headers: { Authorization: `Bearer ${accessToken}` },
        }));
        return response.data;
    }
    mapProviderError(provider, error) {
        var _a;
        const providerError = this.extractProviderError(error);
        const providerErrorCode = this.extractProviderErrorCode(error);
        const status = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status;
        if (this.isConsumedAuthorizationCodeError(error)) {
            return new oauth_errors_1.OAuthProviderException(provider, 'callback_consumed', 'OAuth callback is no longer valid. Start the sign-in flow again.', status, providerError, providerErrorCode);
        }
        if (this.isInvalidAuthorizationCodeError(error)) {
            return new oauth_errors_1.OAuthProviderException(provider, 'invalid_callback', 'OAuth callback is invalid or expired. Start the sign-in flow again.', status, providerError, providerErrorCode);
        }
        return new oauth_errors_1.OAuthProviderException(provider, 'upstream_failure', `Unable to complete ${provider} OAuth authentication.`, status, providerError, providerErrorCode);
    }
    extractProviderError(error) {
        var _a, _b;
        return ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) || (error === null || error === void 0 ? void 0 : error.code) || 'unknown_error';
    }
    extractProviderErrorCode(error) {
        var _a, _b;
        const description = String(((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error_description) || '');
        const match = description.match(/AADSTS\d+/i);
        return (match === null || match === void 0 ? void 0 : match[0]) || undefined;
    }
    isConsumedAuthorizationCodeError(error) {
        var _a, _b;
        const providerError = this.extractProviderError(error);
        const description = String(((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error_description) || '');
        return (providerError === 'invalid_grant' &&
            /(AADSTS54005|already redeemed|already been redeemed|authorization code was already redeemed)/i.test(description));
    }
    isInvalidAuthorizationCodeError(error) {
        return this.extractProviderError(error) === 'invalid_grant';
    }
}
exports.BaseOAuthProvider = BaseOAuthProvider;
//# sourceMappingURL=abstract.provider.js.map