"use strict";
/*
 * @adonisjs/auth
 *
 * (c) Harminder Virk <virk@adonisjs.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseGuard = void 0;
const utils_1 = require("@poppinss/utils");
const InvalidCredentialsException_1 = require("../../Exceptions/InvalidCredentialsException");
/**
 * Base guard with shared abilities
 */
class BaseGuard {
    constructor(name, config, provider) {
        this.name = name;
        this.config = config;
        this.provider = provider;
        /**
         * Whether or not the authentication has been attempted
         * for the current request
         */
        this.authenticationAttempted = false;
        /**
         * Find if the user has been logged out in the current request
         */
        this.isLoggedOut = false;
        /**
         * A boolean to know if user is retrieved by authenticating
         * the current request or not
         */
        this.isAuthenticated = false;
        /**
         * A boolean to know if user is loggedin via remember me token
         * or not.
         */
        this.viaRemember = false;
    }
    /**
     * Reference to the name of the guard driver
     */
    get driver() {
        return this.config.driver;
    }
    /**
     * Accessor to know if user is logged in
     */
    get isLoggedIn() {
        return !!this.user;
    }
    /**
     * Accessor to know if user is a guest. It is always opposite
     * of [[isLoggedIn]]
     */
    get isGuest() {
        return !this.isLoggedIn;
    }
    /**
     * Lookup user using UID
     */
    async lookupUsingUid(uid) {
        const providerUser = await this.provider.findByUid(uid);
        if (!providerUser.user) {
            throw InvalidCredentialsException_1.InvalidCredentialsException.invalidUid(this.name);
        }
        return providerUser;
    }
    /**
     * Verify user password
     */
    async verifyPassword(providerUser, password) {
        /**
         * Verify password or raise exception
         */
        const verified = await providerUser.verifyPassword(password);
        if (!verified) {
            throw InvalidCredentialsException_1.InvalidCredentialsException.invalidPassword(this.name);
        }
    }
    /**
     * Finds user by their id and returns the provider user instance
     */
    async findById(id) {
        const providerUser = await this.provider.findById(id);
        if (!providerUser.user) {
            throw InvalidCredentialsException_1.InvalidCredentialsException.invalidUid(this.name);
        }
        return providerUser;
    }
    /**
     * Returns the provider user instance from the regular user details. Raises
     * exception when id is missing
     */
    async getUserForLogin(user, identifierKey) {
        const providerUser = await this.provider.getUserFor(user);
        /**
         * Ensure id exists on the user
         */
        const id = providerUser.getId();
        if (!id) {
            throw new utils_1.Exception(`Cannot login user. Value of "${identifierKey}" is not defined`);
        }
        return providerUser;
    }
    /**
     * Marks user as logged-in
     */
    markUserAsLoggedIn(user, authenticated, viaRemember) {
        this.user = user;
        this.isLoggedOut = false;
        authenticated && (this.isAuthenticated = true);
        viaRemember && (this.viaRemember = true);
    }
    /**
     * Marks the user as logged out
     */
    markUserAsLoggedOut() {
        this.isLoggedOut = true;
        this.isAuthenticated = false;
        this.viaRemember = false;
        this.user = null;
    }
    /**
     * Verifies user credentials
     */
    async verifyCredentials(uid, password) {
        if (!uid || !password) {
            throw InvalidCredentialsException_1.InvalidCredentialsException.invalidUid(this.name);
        }
        const providerUser = await this.lookupUsingUid(uid);
        await this.verifyPassword(providerUser, password);
        return providerUser.user;
    }
}
exports.BaseGuard = BaseGuard;
