1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | 'use strict';
|
9 |
|
10 | var _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 |
|
12 | var _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 |
|
14 | Object.defineProperty(exports, '__esModule', { value: true });
|
15 |
|
16 | var otplibUtils = require('./utils');
|
17 |
|
18 | function hotpCounter(counter) {
|
19 | var hexCounter = otplibUtils.intToHex(counter);
|
20 | return otplibUtils.leftPad(hexCounter, 16);
|
21 | }
|
22 |
|
23 | function hotpSecret(secret, options) {
|
24 | return new Buffer(secret, options.encoding);
|
25 | }
|
26 |
|
27 | function 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 |
|
41 | function 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 |
|
53 | function 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 |
|
68 | function 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 |
|
78 | function totpCounter(epoch, step) {
|
79 | return Math.floor(epoch / step / 1000);
|
80 | }
|
81 |
|
82 | function 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 |
|
97 | var defaultOptions = {
|
98 | createHmacSecret: totpSecret,
|
99 | epoch: null,
|
100 | step: 30
|
101 | };
|
102 | function 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 |
|
110 | function 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 |
|
118 | function 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 |
|
128 | exports.hotpCheck = hotpCheck;
|
129 | exports.hotpCounter = hotpCounter;
|
130 | exports.hotpDigest = hotpDigest;
|
131 | exports.hotpOptions = hotpOptions;
|
132 | exports.hotpSecret = hotpSecret;
|
133 | exports.hotpToken = hotpToken;
|
134 | exports.totpCheck = totpCheck;
|
135 | exports.totpCounter = totpCounter;
|
136 | exports.totpOptions = totpOptions;
|
137 | exports.totpSecret = totpSecret;
|
138 | exports.totpToken = totpToken; |
\ | No newline at end of file |