(function (exports) { 'use strict'; var Unibabel = exports.Unibabel; // Generate a key function generateOtpKey() { // 20 cryptographically random binary bytes (160-bit key) var key = window.crypto.getRandomValues(new Uint8Array(20)); return key; } // Text-encode the key as base32 (in the style of Google Authenticator - same as Facebook, Microsoft, etc) function encodeGoogleAuthKey(bin) { // 32 ascii characters without trailing '='s var base32 = Unibabel.bufferToBase32(bin).replace(/=/g, ''); // lowercase with a space every 4 characters var key = base32.toLowerCase().replace(/(\w{4})/g, "$1 ").trim(); return key; } function generateGoogleAuthKey() { return encodeGoogleAuthKey(generateOtpKey()); } // Binary-decode the key from base32 (Google Authenticator, FB, M$, etc) function decodeGoogleAuthKey(key) { // decode base32 google auth key to binary var unformatted = key.replace(/\W+/g, '').toUpperCase(); var bin = Unibabel.base32ToBuffer(unformatted); return bin; } // Generate a Google Auth Token function generateGoogleAuthToken(key) { var bin = decodeGoogleAuthKey(key); var totp = exports.totp || require('notp').totp; return totp.gen(bin); } // Verify a Google Auth Token function verifyGoogleAuthToken(key, token) { var bin = decodeGoogleAuthKey(key); var totp = exports.totp || require('notp').totp; token = token.replace(/\W+/g, ''); // window is +/- 1 period of 30 seconds return totp.verify(token, bin, { window: 1, time: 30 }); } exports.generateKey = generateGoogleAuthKey; exports.generateToken = generateGoogleAuthToken; exports.verifyToken = verifyGoogleAuthToken; //var key = exports.generateKey(); var key = 'hxdm vjec jjws rb3h wizr 4ifu gftm xboz'; console.log('key', key); exports.generateToken(key).then(function (token) { console.log('token', token); exports.verifyToken(key, token).then(function (result) { console.log('verify', result); }); }); }( 'undefined' !== typeof window ? window : module.exports ));