"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "Signer", {
    enumerable: true,
    get: function() {
        return Signer;
    }
});
const _crypto = /*#__PURE__*/ _interop_require_default(require("crypto"));
const _sequelize = require("sequelize");
const _constants = require("@tamanu/constants");
const _Model = require("./Model");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
let Signer = class Signer extends _Model.Model {
    static initModel({ primaryKey, ...options }) {
        super.init({
            id: primaryKey,
            createdAt: {
                type: _sequelize.DataTypes.DATE,
                allowNull: false,
                defaultValue: _sequelize.DataTypes.NOW
            },
            deletedAt: {
                type: _sequelize.DataTypes.DATE,
                allowNull: true
            },
            countryCode: {
                type: _sequelize.DataTypes.STRING,
                allowNull: false
            },
            privateKey: {
                // encrypted with integrations.signer.keySecret
                type: _sequelize.DataTypes.BLOB,
                allowNull: true
            },
            publicKey: {
                type: _sequelize.DataTypes.BLOB,
                allowNull: false
            },
            request: {
                // certificate request
                type: _sequelize.DataTypes.TEXT,
                allowNull: false
            },
            requestSentAt: {
                type: _sequelize.DataTypes.DATE,
                allowNull: true
            },
            certificate: {
                // issued by CSCA
                type: _sequelize.DataTypes.TEXT,
                allowNull: true
            },
            workingPeriodStart: {
                // start of the working period of this certificate
                // extracted/cached from certificate PKUP (Private Key Usage Period)
                type: _sequelize.DataTypes.DATE,
                allowNull: true
            },
            workingPeriodEnd: {
                // end of the working period of this certificate
                // extracted/cached from certificate PKUP (Private Key Usage Period)
                type: _sequelize.DataTypes.DATE,
                allowNull: true
            },
            validityPeriodStart: {
                // start of the validity period of this certificate
                // extracted/cached from certificate Not Before field
                type: _sequelize.DataTypes.DATE,
                allowNull: true
            },
            validityPeriodEnd: {
                // end of the validity period of this certificate
                // extracted/cached from certificate Not After field
                type: _sequelize.DataTypes.DATE,
                allowNull: true
            },
            signaturesIssued: {
                // bumped on each signature issuance
                type: _sequelize.DataTypes.INTEGER,
                allowNull: false,
                defaultValue: 0
            }
        }, {
            ...options,
            syncDirection: _constants.SYNC_DIRECTIONS.DO_NOT_SYNC,
            paranoid: true,
            indexes: [
                {
                    fields: [
                        'validity_period_start'
                    ]
                },
                {
                    fields: [
                        'validity_period_end'
                    ]
                },
                {
                    fields: [
                        'working_period_start'
                    ]
                },
                {
                    fields: [
                        'working_period_end'
                    ]
                }
            ]
        });
    }
    static findActive() {
        return Signer.findOne({
            where: {
                validityPeriodStart: {
                    [_sequelize.Op.lte]: _sequelize.Sequelize.literal('CURRENT_TIMESTAMP')
                },
                workingPeriodStart: {
                    [_sequelize.Op.lte]: _sequelize.Sequelize.literal('CURRENT_TIMESTAMP')
                },
                workingPeriodEnd: {
                    [_sequelize.Op.gt]: _sequelize.Sequelize.literal('CURRENT_TIMESTAMP')
                },
                validityPeriodEnd: {
                    [_sequelize.Op.gt]: _sequelize.Sequelize.literal('CURRENT_TIMESTAMP')
                },
                certificate: {
                    [_sequelize.Op.not]: null
                },
                privateKey: {
                    [_sequelize.Op.not]: null
                }
            }
        });
    }
    /**
   * Fetches pending signer, those without certificates
   * Errors if multiple pending signers are found
   * return {Signer} The pending signer, or null if there's none
   */ static async findPending() {
        const pending = await Signer.findAll({
            where: {
                certificate: {
                    [_sequelize.Op.is]: null
                },
                privateKey: {
                    [_sequelize.Op.not]: null
                }
            }
        });
        if (pending.length > 1) {
            throw new Error('More than one pending signer, you need to fix this manually');
        }
        return pending[0] ?? null;
    }
    /**
   * @return {boolean} True if the signer is active (can be used).
   */ isActive() {
        const now = new Date();
        return !!(this.validityPeriodStart <= now && this.workingPeriodStart <= now && this.workingPeriodEnd > now && this.validityPeriodEnd > now && this.certificate && this.privateKey);
    }
    decryptPrivateKey(keySecret) {
        return _crypto.default.createPrivateKey({
            key: Buffer.from(this.privateKey),
            format: 'der',
            type: 'pkcs8',
            passphrase: Buffer.from(keySecret, 'base64')
        });
    }
};

//# sourceMappingURL=Signer.js.map