"use strict";
/*
 * @adonisjs/hash
 *
 * (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.
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Argon = void 0;
/// <reference path="../../adonis-typings/hash.ts" />
const format_1 = __importDefault(require("@phc/format"));
const phc_argon2_1 = __importDefault(require("phc-argon2"));
/**
 * Hash driver built on top of argon hashing algorithm. The driver adheres
 * to `phc` string format.
 */
class Argon {
    constructor(config) {
        this.config = config;
        /**
         * A list of ids to find if hash belongs to this driver
         * or not.
         */
        this.ids = ['argon2d', 'argon2i', 'argon2id'];
        /**
         * A list of params encoded to the hash value.
         */
        this.params = {
            iterations: 't',
            memory: 'm',
            parallelism: 'p',
        };
        /**
         * The current argon version in use
         */
        this.version = 19;
    }
    /**
     * Hash a value using argon algorithm. The options can be used to override
     * default settings.
     */
    make(value) {
        return phc_argon2_1.default.hash(value, this.config);
    }
    /**
     * Verifies the hash against a plain value to find if it's
     * a valid hash or not.
     */
    verify(hashedValue, plainValue) {
        return phc_argon2_1.default.verify(hashedValue, plainValue);
    }
    /**
     * Returns a boolean telling if the hash needs a rehash or not. The rehash is
     * required when
     *
     * 1. The argon2 version is changed
     * 2. Number of iterations are changed.
     * 3. The memory value is changed.
     * 4. The parellelism value is changed.
     * 5. The argon variant is changed.
     */
    needsReHash(value) {
        const deserialized = format_1.default.deserialize(value);
        if (!this.ids.includes(deserialized.id)) {
            throw new Error('value is not an argon2 hash');
        }
        /**
         * Version mis-match
         */
        if (deserialized.version !== this.version) {
            return true;
        }
        /**
         * Variant mis-match
         */
        if (deserialized.id !== `argon2${this.config.variant}`) {
            return true;
        }
        /**
         * Check for params mis-match
         */
        return !!Object.keys(this.params).find((key) => {
            return deserialized.params[this.params[key]] !== this.config[key];
        });
    }
}
exports.Argon = Argon;
