UNPKG

@jovijovi/two-fa.js

Version:

A two-factor authentication(2FA) based on HOTP & TOTP written in TypeScript

103 lines 3.35 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GenKey = exports.DecodeKey = exports.EncodeKey = exports.toBuffer = exports.GetCode = void 0; const crypto_1 = require("crypto"); const random_1 = require("./random"); const options_1 = require("./options"); const base32 = __importStar(require("./base32")); const CodeDigits6 = 6; const CodeDigits7 = 7; const CodeDigits8 = 8; const power = new Map([ [CodeDigits6, 1e6], [CodeDigits7, 1e7], [CodeDigits8, 1e8], ]); function GetCode(key, tm) { const raw = Buffer.from(DecodeKey(key)); const code = tOTP(raw, tm ? tm : new Date().getTime(), CodeDigits6).toString(); if (code.length < CodeDigits6) { return code.padStart(CodeDigits6, '0'); } return code; } exports.GetCode = GetCode; function checkDigits(digits) { if (!power.has(digits)) { throw new Error('invalid digits'); } } function toBuffer(value) { let buf = Buffer.alloc(8); let tmp = value; for (let i = 0; i < 8; i++) { buf[7 - i] = tmp & 0xFF; tmp = tmp >> 8; } return buf; } exports.toBuffer = toBuffer; function hOTP(key, counter, digits) { checkDigits(digits); const hmac = (0, crypto_1.createHmac)('sha1', key); const digest = hmac.update(toBuffer(counter)).digest(); const bin = digest.subarray(digest[digest.length - 1] & 0x0F).readUInt32BE() & 0x7FFFFFFF; return bin % power.get(digits); } function tOTP(key, tm, digits) { return hOTP(key, Math.floor(tm / 30e3), digits); } // EncodeKey returns encoded key function EncodeKey(raw, ...opt) { const opts = (0, options_1.NewOptions)(...opt); let key; if (opts.withHash) { const digest = opts.HashFunc.Hash(raw); key = base32.Encode(digest).toUpperCase(); } else { key = base32.Encode(raw).toUpperCase(); } // TODO: QR if (opts.withQR) { } return key; } exports.EncodeKey = EncodeKey; function DecodeKey(key) { return base32.Decode(key); } exports.DecodeKey = DecodeKey; // GenKey returns random encoded key function GenKey(...opt) { const val = (0, random_1.NewRand)(); if (!val) { throw new Error('invalid random'); } return EncodeKey(val.toString(), ...opt); } exports.GenKey = GenKey; //# sourceMappingURL=twofa.js.map