This javascript library allows you to generate a TOTP Token from a TOTP secret code. It purely run in javascript and doesn't have any dependency. This library was originally written by Kevin Gut. I just modified it a little bit and add an OTPAuth token fetcher
You can try the demo using a TOTP secret code or an OTPAuth url.
Add the library to your page :
<!-- Use Normal Version -->
<script type="text/javascript" src="https://a99us.github.io/totp-js/totp.js"></script>
<!-- Or Minified Version -->
<script type="text/javascript" src="https://a99us.github.io/totp-js/totp.min.js"></script>
Here are the available functions in the library :
Since most (if not all) of TOTP secret code are in base32, you will need to convert them into hex string. TOTP.otp
function only takes secret code in hex.
let secret = "AABBCC56", secrethex
secrethex = Convert.base32toHex(secret)
Calculate TOTP counter for the current time. Only have 1 argument, period. If left empty, it will choose default value of 30
let counter, period = 15
counter = TOTP.getCurrentCounter(period) // period : 15
counter = TOTP.getCurrentCounter() // period : 30 (default value)
let token = await TOTP.otp(secret, digits, counter, period, debug)
This is the function to generate TOTP token. It takes 5 arguments :
- secret (string, mandatory) : Secret key as hex string. If it's in base32, it need to be converted
- digits (number, optional) : The expected result length of the token (digit). Usually 6. Default value is 6
- counter (number, optional) : Counter for the OTP function. If undefined or false, will automatically default to the counter value of current time
- period (number, optional) : Default value is false. If not false / defined, will automatically add
TOTP.getCurrentCounter()
to counter (read more detail in example below) - debug (boolean, optional) : If true, function will show
console.debug
from function's process
let secret = "AABBCC456",
digits = 8,
period = 15,
counter, token
// ======================================
// =========== USAGE EXAMPLES ===========
// If secret is in base32, you'll need to convert it to hex first
secret = Convert.base32toHex(secret)
// User only gives 1 argument : secret
// Digit will default to 6
// Counter will default to current time of 30s period
token = await TOTP.otp(secret)
// User gives 2 arguments : secret and digits
// Counter will default to current time of 30s period
token = await TOTP.otp(secret, digits)
// User gives 3 arguments : secret, digits and counter
// Calculates counter individually
counter = TOTP.getCurrentCounter(period)
token = await TOTP.otp(secret, digits, counter)
// You can add or subtract the value of counter
// to get the next or previous token
let nextToken = await TOTP.otp(secret, digits, counter+1)
let previousToken = await TOTP.otp(secret, digits, counter-1)
/*
User gives 4 arguments : secret, digits, counter and period.
Calculates counter automatically in the function according to
the period given. In place of counter arg in function, you should
put the amount of addition or subtraction of the counter.
If you put 0 in place of counter, you'll get the value of
counter in the current period of time. 1 for the next counter.
-1 for the previous counter, and so on
*/
// Get the token of current time period
token = await TOTP.otp(secret, digits, 0, period)
// Get the token of next time period
nextToken = await TOTP.otp(secret, digits, 1, period)
// Get the token of previous time period
previousToken = await TOTP.otp(secret, digits, -1, period)
Calculate the countdown until a new token, in second. Only have 1 argument, period. If left empty, it will choose default value of 30
let countdown, period = 15
countdown = TOTP.getCountdown(period) // period : 15
countdown = TOTP.getCountdown() // period : 30 (default value)
Changes / breaking changes from the original codes :
- Renaming some variables to eliminate confusion : interval-period, length-size-digits, current-counter, etc
- Add default value : interval, etc
- Option to automate counterInt value in
TOTP.otp
args - Rearranging
TOTP.otp
args placement, to accomodate automation of counterInt value and for better readibility TOTP.otp
andTOTP.hmac
functions have been converted into asynchronous functions so it can return a value directly instead- Remove callback args completely from
TOTP.otp
andTOTP.hmac
- Add
TOTP.getCountdown()
function. Countdown from now until the new time period, in second
- Function to process OTPAuth url and return array object of token, issuer, username, countdown, etc
Credit goes to the original author, Kevin Gut