"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GoogleAuthProvider = void 0;
const google_auth_library_1 = require("google-auth-library");
const common_1 = require("@nestjs/common");
const base_auth_provider_1 = require("./base-auth.provider");
const auth_constants_1 = require("../../auth.constants");
const typeorm_1 = require("typeorm");
const user_entity_1 = require("../../user/entities/user.entity");
const identity_entity_1 = require("../../user/entities/identity.entity");
let GoogleAuthProvider = class GoogleAuthProvider extends base_auth_provider_1.BaseAuthProvider {
    dataSource;
    providerName = auth_constants_1.GOOGLE_AUTH_PROVIDER;
    skipMfa = true;
    client;
    googleConfig;
    constructor(dataSource) {
        const userRepository = dataSource.getRepository(user_entity_1.NestAuthUser);
        const authIdentityRepository = dataSource.getRepository(identity_entity_1.NestAuthIdentity);
        super(userRepository, authIdentityRepository);
        this.dataSource = dataSource;
        this.googleConfig = this.options.google;
        this.enabled = Boolean(this.googleConfig);
        if (this.enabled) {
            this.client = new google_auth_library_1.OAuth2Client(this.googleConfig.clientId, this.googleConfig.clientSecret);
        }
    }
    async validate(credentials) {
        const { token, type = 'id' } = credentials;
        let payload;
        if (type === 'id') {
            try {
                const ticket = await this.client.verifyIdToken({
                    idToken: token,
                    audience: this.googleConfig.clientId,
                });
                payload = ticket.getPayload();
            }
            catch (error) {
                console.error('Google ID Token validation failed:', error);
                throw new common_1.UnauthorizedException('Invalid Google ID token');
            }
        }
        else if (type === 'access') {
            try {
                const tokenInfo = await this.client.getTokenInfo(token);
                const res = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', {
                    headers: {
                        Authorization: `Bearer ${token}`,
                    },
                });
                if (!res.ok) {
                    console.error('userinfo error status:', res.status, await res.text());
                    throw new common_1.UnauthorizedException('Failed to fetch Google user info');
                }
                const userInfo = (await res.json());
                payload = {
                    ...userInfo,
                    sub: tokenInfo.sub ?? userInfo.sub,
                    email: userInfo.email ?? tokenInfo.email,
                    name: userInfo.name,
                    picture: userInfo.picture,
                    locale: userInfo.locale,
                };
            }
            catch (error) {
                console.error('Google Access Token validation failed:', error);
                throw new common_1.UnauthorizedException('Invalid Google Access token');
            }
        }
        else {
            throw new common_1.UnauthorizedException('Missing or invalid Google token type (id | access) in credentials');
        }
        if (!payload || !payload.sub) {
            throw new common_1.UnauthorizedException(`Invalid Google ${type} token`);
        }
        return {
            userId: payload.sub,
            email: payload.email || '',
            metadata: {
                name: payload.name,
                picture: payload.picture,
                locale: payload.locale,
            },
        };
    }
    getRequiredFields() {
        return ['token'];
    }
};
exports.GoogleAuthProvider = GoogleAuthProvider;
exports.GoogleAuthProvider = GoogleAuthProvider = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeorm_1.DataSource])
], GoogleAuthProvider);
//# sourceMappingURL=google-auth.provider.js.map