fix: auto fix some lint error

This commit is contained in:
lancegin
2017-09-03 12:47:08 +08:00
parent e06a8f9b3e
commit 5a9f7f2730
7 changed files with 348 additions and 337 deletions
+14 -14
View File
@@ -4,35 +4,35 @@
* @author : Gin (gin.lance.inside@hotmail.com)
*/
const nibbler = require("./nibbler/nibbler");
const nibbler = require('./nibbler/nibbler');
export class Base32 {
/*
/*
* Base32 decode function
*
* @param {secret}
* @type {String}
* @type {String}
* @desc input string
*
* @return {String}
*/
static decode(secret) {
return nibbler.b32decode(secret);
}
static decode(secret) {
return nibbler.b32decode(secret);
}
/*
/*
* Base32 generate random b32 encoded string function
*
* @param {length}
* @type {int}
* @type {int}
* @desc the length of random b32 encoded string
*
* @return {String}
*/
static random_gen(length=16) {
let random_str = Math.random().toString(36);
random_str = nibbler.b32encode(random_str);
static random_gen(length = 16) {
let random_str = Math.random().toString(36);
random_str = nibbler.b32encode(random_str);
return random_str.substring(0, length);
}
}
return random_str.substring(0, length);
}
}
+21 -22
View File
@@ -6,11 +6,11 @@
import { OTP } from './otp';
export class HOTP extends OTP {
/*
/*
* Generate the OTP with the given count
*
* @param {count}
* @type {int}
* @type {int}
* @desc the OTP HMAC counter
*
* @return {OTP}
@@ -21,20 +21,20 @@ export class HOTP extends OTP {
* hotp.at(0); // => 432143
* ```
*/
at(count) {
let digit = super.generate_otp(count);
return digit;
}
at(count) {
const digit = super.generate_otp(count);
return digit;
}
/*
/*
* Verifies the OTP passed in against the current counter.
*
* @param {otp}
* @type {String}
* @type {String}
* @desc the OTP waiting for checking
*
* @param {counter}
* @type {int}
* @type {int}
* @desc the OTP HMAC counter
*
* @return {Boolean}
@@ -47,26 +47,25 @@ export class HOTP extends OTP {
* hotp.verify(432143, 1); // => false
* ```
*/
verify(otp, counter) {
let otp_count = this.at(counter);
verify(otp, counter) {
const otp_count = this.at(counter);
if (otp === otp_count) {
return true;
} else {
return false;
}
if (otp === otp_count) {
return true;
}
return false;
}
/*
/*
* Generate a url with HOTP instance.
*
* @param {issuer}
* @type {String}
* @type {String}
* @desc maybe it is the Service name
*
* @return {String}
*/
url_gen(issuer="") {
return super.url_gen(issuer, "hotp");
}
}
url_gen(issuer = '') {
return super.url_gen(issuer, 'hotp');
}
}
+16 -16
View File
@@ -10,42 +10,42 @@ import { HOTP } from './hotp';
import { Base32 } from './base32';
import { Util } from './util';
/*
/*
* Generate and return HOTP object
*
* @param {secret}
* @type {String}
* @type {String}
* @desc random base32-encoded key to generate OTP.
*
* @return {OTP}
*/
function hotp_gen(secret, digits=6, digest="SHA-1") {
let hotp = new HOTP(secret, digits, digest);
return hotp;
function hotp_gen(secret, digits = 6, digest = 'SHA-1') {
const hotp = new HOTP(secret, digits, digest);
return hotp;
}
/*
/*
* Generate and return TOTP object
*
* @param {secret}
* @type {String}
* @type {String}
* @desc random base32-encoded key to generate OTP.
*
* @param {interval}
* @type {int}
* @type {int}
* @desc the time interval in seconds for OTP.
* This defaults to 30.
*
* @return {OTP}
*/
function totp_gen(secret, interval=30) {
let totp = new TOTP(secret, interval);
return totp;
function totp_gen(secret, interval = 30) {
const totp = new TOTP(secret, interval);
return totp;
}
export {
hotp_gen as HOTP,
totp_gen as TOTP,
Base32,
Util
};
hotp_gen as HOTP,
totp_gen as TOTP,
Base32,
Util,
};
+164 -150
View File
@@ -3,174 +3,188 @@ Adapted for Node.js by Matt Robenolt
Reference: http://www.tumuski.com/2010/04/nibbler/
*/
var Nibbler = function (options) {
var construct,
// options
pad, dataBits, codeBits, keyString, arrayData,
// private instance variables
mask, group, max,
// private methods
gcd, translate,
// public methods
encode, decode;
const Nibbler = function (options) {
let construct,
// options
pad,
dataBits,
codeBits,
keyString,
arrayData,
// private instance variables
mask,
group,
max,
// private methods
gcd,
translate,
// public methods
encode,
decode;
// pseudo-constructor
construct = function () {
var i, mag, prev;
construct = function () {
let i,
mag,
prev;
// options
pad = options.pad || '';
dataBits = options.dataBits;
codeBits = options.codeBits;
keyString = options.keyString;
arrayData = options.arrayData;
// bitmasks
mag = Math.max(dataBits, codeBits);
prev = 0;
mask = [];
for (i = 0; i < mag; i += 1) {
mask.push(prev);
prev += prev + 1;
}
max = prev;
// ouput code characters in multiples of this number
group = dataBits / gcd(dataBits, codeBits);
// options
pad = options.pad || '';
dataBits = options.dataBits;
codeBits = options.codeBits;
keyString = options.keyString;
arrayData = options.arrayData;
// bitmasks
mag = Math.max(dataBits, codeBits);
prev = 0;
mask = [];
for (i = 0; i < mag; i += 1) {
mask.push(prev);
prev += prev + 1;
}
max = prev;
// ouput code characters in multiples of this number
group = dataBits / gcd(dataBits, codeBits);
};
// greatest common divisor
gcd = function (a, b) {
let t;
while (b !== 0) {
t = b;
b = a % b;
a = t;
}
return a;
};
// the re-coder
translate = function (input, bitsIn, bitsOut, decoding) {
let i,
len,
chr,
byteIn,
buffer,
size,
output,
write;
// append a byte to the output
write = function (n) {
if (!decoding) {
output.push(keyString.charAt(n));
} else if (arrayData) {
output.push(n);
} else {
output.push(String.fromCharCode(n));
}
};
// greatest common divisor
gcd = function (a, b) {
var t;
while (b !== 0) {
t = b;
b = a % b;
a = t;
buffer = 0;
size = 0;
output = [];
len = input.length;
for (i = 0; i < len; i += 1) {
// the new size the buffer will be after adding these bits
size += bitsIn;
// read a character
if (decoding) {
// decode it
chr = input.charAt(i);
byteIn = keyString.indexOf(chr);
if (chr === pad) {
break;
} else if (byteIn < 0) {
throw `the character "${chr}" is not a member of ${keyString}`;
}
return a;
};
// the re-coder
translate = function (input, bitsIn, bitsOut, decoding) {
var i, len, chr, byteIn,
buffer, size, output,
write;
// append a byte to the output
write = function (n) {
if (!decoding) {
output.push(keyString.charAt(n));
} else if (arrayData) {
output.push(n);
} else {
output.push(String.fromCharCode(n));
}
};
buffer = 0;
size = 0;
output = [];
len = input.length;
for (i = 0; i < len; i += 1) {
// the new size the buffer will be after adding these bits
size += bitsIn;
// read a character
if (decoding) {
// decode it
chr = input.charAt(i);
byteIn = keyString.indexOf(chr);
if (chr === pad) {
break;
} else if (byteIn < 0) {
throw 'the character "' + chr + '" is not a member of ' + keyString;
}
} else {
if (arrayData) {
byteIn = input[i];
} else {
byteIn = input.charCodeAt(i);
}
if ((byteIn | max) !== max) {
throw byteIn + " is outside the range 0-" + max;
}
}
// shift the buffer to the left and add the new bits
buffer = (buffer << bitsIn) | byteIn;
// as long as there's enough in the buffer for another output...
while (size >= bitsOut) {
// the new size the buffer will be after an output
size -= bitsOut;
// output the part that lies to the left of that number of bits
// by shifting the them to the right
write(buffer >> size);
// remove the bits we wrote from the buffer
// by applying a mask with the new size
buffer &= mask[size];
}
} else {
if (arrayData) {
byteIn = input[i];
} else {
byteIn = input.charCodeAt(i);
}
// If we're encoding and there's input left over, pad the output.
// Otherwise, leave the extra bits off, 'cause they themselves are padding
if (!decoding && size > 0) {
// flush the buffer
write(buffer << (bitsOut - size));
// add padding keyString for the remainder of the group
len = output.length % group;
for (i = 0; i < len; i += 1) {
output.push(pad);
}
if ((byteIn | max) !== max) {
throw `${byteIn} is outside the range 0-${max}`;
}
}
// string!
return (arrayData && decoding) ? output : output.join('');
};
/**
// shift the buffer to the left and add the new bits
buffer = (buffer << bitsIn) | byteIn;
// as long as there's enough in the buffer for another output...
while (size >= bitsOut) {
// the new size the buffer will be after an output
size -= bitsOut;
// output the part that lies to the left of that number of bits
// by shifting the them to the right
write(buffer >> size);
// remove the bits we wrote from the buffer
// by applying a mask with the new size
buffer &= mask[size];
}
}
// If we're encoding and there's input left over, pad the output.
// Otherwise, leave the extra bits off, 'cause they themselves are padding
if (!decoding && size > 0) {
// flush the buffer
write(buffer << (bitsOut - size));
// add padding keyString for the remainder of the group
len = output.length % group;
for (i = 0; i < len; i += 1) {
output.push(pad);
}
}
// string!
return (arrayData && decoding) ? output : output.join('');
};
/**
* Encode. Input and output are strings.
*/
encode = function (input) {
return translate(input, dataBits, codeBits, false);
};
/**
encode = function (input) {
return translate(input, dataBits, codeBits, false);
};
/**
* Decode. Input and output are strings.
*/
decode = function (input) {
return translate(input, codeBits, dataBits, true);
};
this.encode = encode;
this.decode = decode;
construct();
decode = function (input) {
return translate(input, codeBits, dataBits, true);
};
this.encode = encode;
this.decode = decode;
construct();
};
var Base32 = new Nibbler({
dataBits: 8,
codeBits: 5,
keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
pad: '='
const Base32 = new Nibbler({
dataBits: 8,
codeBits: 5,
keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
pad: '=',
});
var Base64 = new Nibbler({
dataBits: 8,
codeBits: 6,
keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
pad: '='
const Base64 = new Nibbler({
dataBits: 8,
codeBits: 6,
keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
pad: '=',
});
exports.Nibbler = Nibbler;
exports.b32encode = Base32.encode;
exports.b32decode = Base32.decode;
exports.b64encode = Base64.encode;
exports.b64decode = Base64.decode;
exports.b64decode = Base64.decode;
+46 -45
View File
@@ -2,96 +2,97 @@
* @module : OTP module to generate the password
* @author : Gin (gin.lance.inside@hotmail.com)
*/
const jsSHA = require("jssha");
const jsSHA = require('jssha');
import { Base32 } from './base32';
import { Util } from './util';
export class OTP {
/*
export class OTP {
/*
* This constructor will create OTP instance.
*
* @param {secret}
* @type {String}
* @desc random base32-encoded key, it is the
* @desc random base32-encoded key, it is the
* key that be used to verify.
*
* @param {digits}
* @type {int}
* @type {int}
* @desc the length of the one-time password, default to be 6
*
* @param {digest}
* @type {String}
* @desc the key that be used to do HMAC encoding, dedault and
* @desc the key that be used to do HMAC encoding, dedault and
* only to be "sha1"
*
*/
constructor(secret, digits=6, digest="SHA-1") {
this.secret = secret;
this.digits = digits;
this.digest = digest;
}
constructor(secret, digits = 6, digest = 'SHA-1') {
this.secret = secret;
this.digits = digits;
this.digest = digest;
}
/*
/*
* When class HOTP or TOTP pass the input params to this
* function, it will generate the OTP object with params,
* the params may be counter or time.
* the params may be counter or time.
*
* @param {input}
* @type {int}
* @type {int}
* @desc input params to generate OTP object, maybe
* counter or time.
*
* @return {OTP}
*/
generate_otp(input) {
// generate HMAC object with SHA-1 digest
let hmacObj = new jsSHA(this.digest, "BYTES");
// set hmac token
hmacObj.setHMACKey(Util.byte_secret(this.secret), "BYTES");
// hamc encode the input param
hmacObj.update(Util.int_to_bytestring(input));
generate_otp(input) {
// generate HMAC object with SHA-1 digest
const hmacObj = new jsSHA(this.digest, 'BYTES');
// set hmac token
hmacObj.setHMACKey(Util.byte_secret(this.secret), 'BYTES');
// hamc encode the input param
hmacObj.update(Util.int_to_bytestring(input));
// get HMAC ans
let hmac = hmacObj.getHMAC("BYTES");
// get HMAC ans
const hmac = hmacObj.getHMAC('BYTES');
// transfer hmac to Array
let hmac_a = hmac.split("");
// transfer hmac to Array
const hmac_a = hmac.split('');
// calculate the init offset
let offset = hmac_a[hmac_a.length - 1].charCodeAt() & 0xf;
// calculate the init offset
const offset = hmac_a[hmac_a.length - 1].charCodeAt() & 0xf;
// calculate the code
let code = (
(hmac_a[offset].charCodeAt() & 0x7f) << 24 |
// calculate the code
const code = (
(hmac_a[offset].charCodeAt() & 0x7f) << 24 |
(hmac_a[offset + 1].charCodeAt() & 0xff) << 16 |
(hmac_a[offset + 2].charCodeAt() & 0xff) << 8 |
(hmac_a[offset + 2].charCodeAt() & 0xff) << 8 |
(hmac_a[offset + 3].charCodeAt() & 0xff)
);
);
// get the init str code
let str_code = (code % 10 ** this.digits).toString();
// get the init str code
let str_code = (code % 10 ** this.digits).toString();
// rjust format
str_code = Util.rjust(str_code, this.digits);
// rjust format
str_code = Util.rjust(str_code, this.digits);
return str_code;
}
return str_code;
}
/*
/*
* Generate a url with TOTP or HOTP instance.
*
* @param {issuer}
* @type {String}
* @type {String}
* @desc maybe it is the Service name
*
* @param {type}
* @type {String}
* @type {String}
* @desc type of OTP instance
*
* @return {String}
*/
url_gen(issuer, type) {
return `otpauth://${type}/SK?secret=${this.secret}&issuer=${issuer}`;
}
}
url_gen(issuer, type) {
return `otpauth://${type}/SK?secret=${this.secret}&issuer=${issuer}`;
}
}
+35 -36
View File
@@ -7,24 +7,24 @@ import { OTP } from './otp';
import { Util } from './util';
export class TOTP extends OTP {
/*
/*
* @param {secret}
* @type {String}
* @type {String}
* @desc random base32-encoded key to generate OTP.
*
* @param {interval}
* @type {int}
* @type {int}
* @desc the time interval in seconds for OTP.
* This defaults to 30.
*
* @return {OTP}
*/
constructor(secret, interval=30) {
super(secret);
this.interval = interval;
}
constructor(secret, interval = 30) {
super(secret);
this.interval = interval;
}
/*
/*
* Generate the OTP with current time.
*
* @return {OTP}
@@ -35,24 +35,24 @@ export class TOTP extends OTP {
* totp.now(); // => 432143
* ```
*/
now() {
// get now time string
let now = Util.timecode(new Date(), this.interval);
now() {
// get now time string
const now = Util.timecode(new Date(), this.interval);
// generate the one-time password
let digit = super.generate_otp(now);
return digit;
}
// generate the one-time password
const digit = super.generate_otp(now);
return digit;
}
/*
/*
* Verifies the OTP passed in against the current time OTP.
*
* @param {otp}
* @type {String}
* @type {String}
* @desc the OTP waiting for checking
*
* @param {time}
* @type {int or datetime}
* @type {int or datetime}
* @desc Time to check OTP at (defaults to now)
*
* @return {Boolean}
@@ -67,31 +67,30 @@ export class TOTP extends OTP {
* totp.verify(432143); // => false
* ```
*/
verify(otp, time=null) {
let otp_time;
verify(otp, time = null) {
let otp_time;
if (null == time) {
time = new Date();
otp_time = this.now()
}
if (otp === otp_time) {
return true;
} else {
return false;
}
if (time == null) {
time = new Date();
otp_time = this.now();
}
/*
if (otp === otp_time) {
return true;
}
return false;
}
/*
* Generate a url with TOTP instance.
*
* @param {issuer}
* @type {String}
* @type {String}
* @desc maybe it is the Service name
*
* @return {String}
*/
url_gen(issuer="") {
return super.url_gen(issuer, "totp");
}
}
url_gen(issuer = '') {
return super.url_gen(issuer, 'totp');
}
}
+52 -54
View File
@@ -6,113 +6,111 @@
import { Base32 } from './base32';
export class Util {
/*
/*
* Util rjust number with 0
*
* @param {num}
* @type {int}
* @type {int}
* @desc input number
*
* @param {n}
* @type {int}
* @type {int}
* @desc wanted length
*
* @return {String}
*/
static rjust(num, n) {
let len = num.toString().length;
static rjust(num, n) {
let len = num.toString().length;
while (len < n) {
num = "0" + num;
len++;
}
return num;
while (len < n) {
num = `0${num}`;
len++;
}
/*
return num;
}
/*
* Util rjust array with ""
*
* @param {arr}
* @type {Array}
* @type {Array}
* @desc input array
*
* @param {n}
* @type {int}
* @type {int}
* @desc wanted length
*
* @return {BYTES}
*/
static arr_rjust(arr, n) {
if (n <= arr.length) {
arr = arr.splice(arr.length - 1 - n);
return arr;
} else {
let diff = n - arr.length;
for (let i = 0; i < diff; i++) {
arr.unshift(String.fromCharCode(0));
}
return arr;
}
static arr_rjust(arr, n) {
if (n <= arr.length) {
arr = arr.splice(arr.length - 1 - n);
return arr;
}
const diff = n - arr.length;
for (let i = 0; i < diff; i++) {
arr.unshift(String.fromCharCode(0));
}
return arr;
}
/*
/*
* Base32 decode the init secret
*
* @param {secret}
* @type {String}
* @type {String}
* @desc input param, the init secret
*
* @return {String}
*/
static byte_secret(secret) {
return Base32.decode(secret.toUpperCase());
}
static byte_secret(secret) {
return Base32.decode(secret.toUpperCase());
}
/*
/*
* transfer the int type to BYTES type
*
* @param {input}
* @type {int}
* @type {int}
* @desc input param, maybe counter or time
*
* @return {BYTES}
*/
static int_to_bytestring(input, padding=8) {
let result = [];
static int_to_bytestring(input, padding = 8) {
let result = [];
while (0 != input) {
result.push(String.fromCharCode(input & 0xFF));
input >>= 8;
}
result = result.reverse();
result = Util.arr_rjust(result, padding).join("");
return result;
while (input != 0) {
result.push(String.fromCharCode(input & 0xFF));
input >>= 8;
}
/*
result = result.reverse();
result = Util.arr_rjust(result, padding).join('');
return result;
}
/*
* format the time string to int
*
* @param {time}
* @type {Date}
* @type {Date}
* @desc the time need to be format
*
* @param {interval}
* @type {Int}
* @type {Int}
* @desc interval means the one-time password's life,
* default to be 30.
*
* @return {Int}
*/
static timecode(time, interval) {
let time_str = Date.parse(time).toString();
static timecode(time, interval) {
const time_str = Date.parse(time).toString();
// fotmat the time, the ms is not needed.
let format_time = time_str.substring(0, time_str.length-3);
// fotmat the time, the ms is not needed.
const format_time = time_str.substring(0, time_str.length - 3);
return parseInt(parseInt(format_time) / interval);
}
}
return parseInt(parseInt(format_time) / interval);
}
}