UNPKG

4.67 kBJavaScriptView Raw
1/**
2 * otplib-core
3 *
4 * @author Gerald Yeo <contact@fusedthought.com>
5 * @version: 7.0.0
6 * @license: MIT
7 **/
8'use strict';
9
10var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
11
12var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
13
14Object.defineProperty(exports, '__esModule', { value: true });
15
16var otplibUtils = require('./utils');
17
18function hotpCounter(counter) {
19 var hexCounter = otplibUtils.intToHex(counter);
20 return otplibUtils.leftPad(hexCounter, 16);
21}
22
23function hotpSecret(secret, options) {
24 return new Buffer(secret, options.encoding);
25}
26
27function hotpDigest(secret, counter, options) {
28 if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object' || options == null) {
29 throw new Error('Expecting options to be an object');
30 }
31 if (!options.crypto || typeof options.crypto.createHmac !== 'function') {
32 throw new Error('Expecting options.crypto to have a createHmac function');
33 }
34 var createHmacSecret = options.createHmacSecret || hotpSecret;
35 var hmacSecret = createHmacSecret(secret, options);
36 var hexCounter = hotpCounter(counter);
37 var cryptoHmac = options.crypto.createHmac(options.algorithm, hmacSecret);
38 return cryptoHmac.update(new Buffer(hexCounter, 'hex')).digest();
39}
40
41function hotpOptions() {
42 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
43
44 return _extends({
45 algorithm: 'sha1',
46 createHmacSecret: hotpSecret,
47 crypto: null,
48 digits: 6,
49 encoding: 'ascii'
50 }, options);
51}
52
53function hotpToken(secret, counter) {
54 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
55
56 if (counter == null) {
57 return '';
58 }
59 var opt = hotpOptions(options);
60 var digest = hotpDigest(secret, counter, opt);
61 var offset = digest[digest.length - 1] & 0xf;
62 var binary = (digest[offset] & 0x7f) << 24 | (digest[offset + 1] & 0xff) << 16 | (digest[offset + 2] & 0xff) << 8 | digest[offset + 3] & 0xff;
63 var token = binary % Math.pow(10, opt.digits);
64 token = otplibUtils.leftPad(token, opt.digits);
65 return token;
66}
67
68function hotpCheck(token, secret, counter) {
69 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
70
71 var systemToken = hotpToken(secret, counter, options);
72 if (systemToken.length < 1) {
73 return false;
74 }
75 return otplibUtils.isSameToken(token, systemToken);
76}
77
78function totpCounter(epoch, step) {
79 return Math.floor(epoch / step / 1000);
80}
81
82function totpSecret(secret, options) {
83 var encoded = new Buffer(secret, options.encoding);
84 var algorithm = options.algorithm.toLowerCase();
85 switch (algorithm) {
86 case 'sha1':
87 return otplibUtils.padSecret(encoded, 20, options.encoding);
88 case 'sha256':
89 return otplibUtils.padSecret(encoded, 32, options.encoding);
90 case 'sha512':
91 return otplibUtils.padSecret(encoded, 64, options.encoding);
92 default:
93 throw new Error('Unsupported algorithm ' + algorithm + '. Accepts: sha1, sha256, sha512');
94 }
95}
96
97var defaultOptions = {
98 createHmacSecret: totpSecret,
99 epoch: null,
100 step: 30
101};
102function totpOptions() {
103 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
104
105 var opt = _extends(hotpOptions(), defaultOptions, options);
106 opt.epoch = typeof opt.epoch === 'number' ? opt.epoch * 1000 : Date.now();
107 return opt;
108}
109
110function totpToken(secret) {
111 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
112
113 var opt = totpOptions(options);
114 var counter = totpCounter(opt.epoch, opt.step);
115 return hotpToken(secret, counter, opt);
116}
117
118function totpCheck(token, secret) {
119 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
120
121 var systemToken = totpToken(secret, options || {});
122 if (systemToken.length < 1) {
123 return false;
124 }
125 return otplibUtils.isSameToken(token, systemToken);
126}
127
128exports.hotpCheck = hotpCheck;
129exports.hotpCounter = hotpCounter;
130exports.hotpDigest = hotpDigest;
131exports.hotpOptions = hotpOptions;
132exports.hotpSecret = hotpSecret;
133exports.hotpToken = hotpToken;
134exports.totpCheck = totpCheck;
135exports.totpCounter = totpCounter;
136exports.totpOptions = totpOptions;
137exports.totpSecret = totpSecret;
138exports.totpToken = totpToken;
\No newline at end of file