@imajin/rx-otp
Version:
HMAC-based (HOTP) and Time-based (TOTP) One-Time Password manager. Works with Google Authenticator for Two-Factor Authentication.
71 lines (70 loc) • 3.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.U2F = void 0;
const buffer_1 = require("buffer");
const crypto = require("crypto");
const qr = require("qr-image");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const thirty_two_1 = require("thirty-two");
const totp_1 = require("./totp");
const validator_1 = require("../schemas/validator");
class U2F {
}
exports.U2F = U2F;
U2F.generateOTPKey = (asBuffer = false) => (0, rxjs_1.of)(crypto.randomBytes(20).toString('hex'))
.pipe((0, operators_1.map)((key) => !!asBuffer ? buffer_1.Buffer.from(key, 'hex') : key));
U2F.encodeAuthKey = (buffer) => (0, rxjs_1.of)(buffer)
.pipe((0, operators_1.map)(_ => (0, thirty_two_1.encode)(_).toString().replace(/=/g, '')), (0, operators_1.map)(_ => _.replace(/(\w{4})/g, '$1 ').trim()));
U2F.decodeAuthKey = (base32_key) => U2F._cleanBase32Key(base32_key)
.pipe((0, operators_1.map)(_ => (0, thirty_two_1.decode)(_)));
U2F.generateAuthKey = () => U2F.generateOTPKey(true)
.pipe((0, rxjs_1.mergeMap)((_) => U2F.encodeAuthKey(_)));
U2F.generateTOTPUri = (secret, account_name, issuer, options = {}) => U2F._cleanBase32Key(secret)
.pipe((0, operators_1.map)(_ => Object.assign({}, options, { secret: _, account_name: account_name, issuer: issuer })), (0, rxjs_1.mergeMap)((data) => validator_1.Validator.validateDataWithSchemaReference('/rx-otp/schemas/u2f-uri.json', data)), (0, operators_1.map)((_) => `otpauth://totp/${encodeURI(_.issuer)}:${encodeURI(_.account_name)}?secret=${_.secret}&issuer=${encodeURIComponent(_.issuer)}&algorithm=${_.algorithm}&digits=${_.code_digits}&period=${_.time}`));
U2F.generateAuthToken = (base32_key, options = {}) => U2F.decodeAuthKey(base32_key)
.pipe((0, operators_1.map)((_) => Object.assign({}, options, { key: _.toString('hex') })), (0, rxjs_1.mergeMap)((data) => validator_1.Validator.validateDataWithSchemaReference('/rx-otp/schemas/u2f-generate.json', data)), (0, operators_1.map)((_) => ({
key: _.key,
options: {
key_format: 'hex',
time: _.time,
timestamp: _.timestamp,
code_digits: _.code_digits,
add_checksum: _.add_checksum,
truncation_offset: _.truncation_offset,
algorithm: _.algorithm
}
})), (0, rxjs_1.mergeMap)((_) => totp_1.TOTP.generate(_.key, _.options)));
U2F.verifyAuthToken = (token, base32_key, options = {}) => U2F.decodeAuthKey(base32_key)
.pipe((0, operators_1.map)((_) => Object.assign({}, options, { token: token, key: _.toString('hex') })), (0, rxjs_1.mergeMap)((data) => validator_1.Validator.validateDataWithSchemaReference('/rx-otp/schemas/u2f-verify.json', data)), (0, operators_1.map)((_) => ({
token: _.token,
key: _.key,
options: {
key_format: 'hex',
window: _.window,
time: _.time,
timestamp: _.timestamp,
add_checksum: _.add_checksum,
truncation_offset: _.truncation_offset,
algorithm: _.algorithm
}
})), (0, rxjs_1.mergeMap)((_) => totp_1.TOTP.verify(_.token, _.key, _.options)));
U2F.qrCode = (text, options = {}) => (0, rxjs_1.of)(Object.assign({}, options, { text: text }))
.pipe((0, rxjs_1.mergeMap)((data) => validator_1.Validator.validateDataWithSchemaReference('/rx-otp/schemas/u2f-qr.json', data)), (0, operators_1.map)((_) => ({
text: _.text,
options: {
ec_level: _.ec_level,
type: _.type,
size: _.size
}
})), (0, operators_1.map)(_ => !!_.options.size ?
_ :
({
text: _.text,
options: {
ec_level: _.options.ec_level,
type: _.options.type,
}
})), (0, operators_1.map)((_) => qr.imageSync(_.text, _.options)));
U2F._cleanBase32Key = (base32_key) => (0, rxjs_1.of)(base32_key)
.pipe((0, operators_1.map)(_ => _.replace(/[\s\.\_\-]+/g, '')));