const { Model } = require('flitter-orm')
const speakeasy = require('speakeasy')
const MFARecoveryCode = require('./MFARecoveryCode.model')
const uuid = require('uuid').v4

class MFATokenModel extends Model {
    static get services() {
        return [...super.services, 'MFA']
    }

    static get schema() {
        return {
            secret: String,
            otpauth_url: String,
            recovery_codes: [MFARecoveryCode],
        }
    }

    async attempt_recovery(code) {
        for ( const token of this.recovery_codes ) {
            if ( await token.verify(code) && !token.used ) {
                token.used = true
                return true
            }
        }

        return false
    }

    async generate_recovery() {
        this.recovery_codes = []
        const values = []

        for ( let i = 0; i < 4; i++ ) {
            const value = uuid()
            values.push(value)
            this.recovery_codes.push(await MFARecoveryCode.create(value))
        }

        return values
    }

    verify(value) {
        return speakeasy.totp.verify({
            secret: this.secret,
            encoding: 'base32',
            token: value,
        })
    }
}

module.exports = exports = MFATokenModel
