planethoster / time2fa Goto Github PK
View Code? Open in Web Editor NEWA comprehensive Node.js package that simplifies the implementation of One-Time Password (OTP).
Home Page: https://www.npmjs.com/package/time2fa
License: MIT License
A comprehensive Node.js package that simplifies the implementation of One-Time Password (OTP).
Home Page: https://www.npmjs.com/package/time2fa
License: MIT License
The resolved type is generateUrl(options: UrlOptions, config: ValidTotpConfig): string
but the example in the readme doesn't include the required config
attribute.
Hello,
on using generateKey i get the following error:
`ERROR in ./node_modules/time2fa/dist/index.mjs 1:0-28
Module not found: Error: Can't resolve 'crypto' in 'C:\Users\sheimann\source\repos\SecVault\secvaultweb\node_modules\time2fa\dist'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "crypto": false }
webpack compiled with 1 error and 1 warning`
Is there any dependency missing..??
Regards
Sascha
Hi
I wanted to use your package. But I face an issue.
I tried to following to create a TOTP
// Generate the OTP
const config = generateConfig({
period: 120,
});
const secret = generateSecret(config.secretSize);
const codes = Totp.generatePasscodes({ secret: secret }, config);
and the following to validate (of course with passcode and secret from above)
// Validate the OTP
const config = generateConfig({
period: 120,
});
const valid = Totp.validate({ passcode: '097991', secret: '2X4A3XCNPJJSHU4O' }, config);
This always results in false
. When I remove the period: 120
in the config, it works.
Any idea? Is there a limit for the period?
const config = { algo: "sha1", digits: 6, period: 30, secretSize: 10 };
const secret = "F5LE3AAKV7OD264A";
console.log(generateUrl(
{
issuer: "N0C",
user: "[email protected]",
secret: secret
},
config
));
// result: https://totp/?issuer=N0C&period=30&secret=F5LE3AAKV7OD264A
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are awaiting their schedule. Click on a checkbox to get an update now.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
.github/workflows/build.yml
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
.github/workflows/publish.yml
actions/checkout v4
actions/setup-node v4
package.json
@antfu/ni ^0.21.2
@types/node ^20.0.0
@typescript-eslint/eslint-plugin ^7.0.0
@typescript-eslint/parser ^7.0.0
@vitest/coverage-v8 ^1.0.0
bumpp ^9.1.0
eslint ^8.38.0
eslint-config-prettier ^9.0.0
esno ^4.0.0
lint-staged ^15.0.0
prettier ^3.0.0
rimraf ^5.0.0
simple-git-hooks ^2.8.1
ts-node ^10.9.1
typescript ^5.0.3
unbuild ^2.0.0
vitest ^1.0.0
Hi! I really like how easy this library is to implement.
However to easily wrap it in a Typescript class it would be neat to have the config object interfaces exported as well.
Thanks!
Not sure why this repo doesn't have more stars yet.
Hello,
First, thank you for this typescript/no external dep implementation of totp, it was about time to replace speakeasy.
I was writing the tests for my application and got a bit confused about a ValidationError: Invalid passcode exception being thrown. Initially, I thought something was broken in my NestJS application, because the string was actually the same one I used in my custom exception!
While reviewing the validate
method in the TOTP (time based) implementation:
public validate(options: TotpValidateOptions, config?: TotpConfig): boolean {
const validatedConfig = generateConfig(config);
const passcode = options?.passcode.replace(/\s/g, "") || "";
if (passcode.length !== validatedConfig.digits) {
throw new ValidationError("Invalid passcode");
}
const codes = this.generatePasscodes(options, validatedConfig);
if (codes.includes(passcode)) {
return true;
}
return false;
}
I noticed that when the length of the passcode is not equal to validatedConfig.digits, the code throws a ValidationError stating "Invalid passcode".
Since the validation seems to be logically part of the overall functionality and not related to the configuration issues of the library itself, I was wondering if it's more appropriate for this situation to return false instead of throwing a ValidationError.
By adjusting this, users of the library might have a smoother experience, specifically when the throw error interrupts application flow. Instead, they could manage the false return value in a way that suits their specific context.
Or maybe we should update the docs to add the try/catch in the usage section.
Does this adjustment make sense from your perspective, or are there specific reasons that a ValidationError needs to be thrown in this method?
Thank you,
Renato
Validating always returns false when adding a custom config.
This key works when validated:
const key = Totp.generateKey({
issuer: "app",
user: ctx.session.user.email,
});
This always returns false when validated:
const key = Totp.generateKey({
issuer: "app",
user: ctx.session.user.email,
}, {
period: 60,
});
This also doesn't work:
const config = generateConfig();
const key = Totp.generateKey({
issuer: "app",
user: ctx.session.user.email,
}, {
...config,
period: 60,
});
When generating a new TOTP is successful:
const config = generateConfig({
digits: 6,
period: 30,
algo: "sha256",
secretSize: 10,
});
const secret = TOTP_SECRET; // from ENV variable;
const codes = Totp.generatePasscodes({ secret }, config);
const totp = codes[0];
But when validating the just newly created TOTP it evaluates to false:
const { totp } = req.body;
const secret = TOTP_SECRET; // from ENV variable
const config = {
digits: 6,
period: 30,
algo: "sha256",
secretSize: 10,
};
const isValid = Totp.validate(
{
passcode: totp,
secret: secret,
},
config
);
console.log({ isValid }); // Evaluates to false when the totp is valid
What could be wrong with my code?
Hi,
Upon using the library I have noticed that the otpauth url produced by the generateUrl function causes issues when scanned by Google Authenticator. I believe this is because the algorithm parameter appended to the otpauth url string does not fit the specification for googles otpauth URL.
Currently TotpConfig
has an algo
typed property supporting 'sha1', 'sha256' & 'sha512' all lowercase. However, I believe google authenticator expects these to be capitalised when presented in the otpauth url within the algorithm parameter. This is suggested in the documentation here
Here is the defined type:
type Algorithms = "sha1" | "sha256" | "sha512";
Code the produces the invalid otpauth url:
const tokenConfig = time2fa.generateConfig({
algo: 'sha256', // notice lowercase
digits: 6,
period: 60,
secretSize: 10
})
const url = time2fa.generateUrl({ secret: 'S5V43NFEQPKEH3C4', issuer: 'exampleissuer', user: '[email protected]'}, tokenConfig)
This produces an otpauth like this:
otpauth://totp/exampleissuer:example%4example.com?issuer=exampleissuer&period=60&secret=S5V43NFEQPKEH3C4&algorithm=sha256
This causes Google Authenticator app to fail scanning the QR code. Showing the "Can't scan this QR code"
Code that produces valid otpauth url:
const tokenConfig = time2fa.generateConfig({
algo: 'SHA256', // notice capitalised even though unsupported in terms of the type
digits: 6,
period: 60,
secretSize: 10
})
const url = time2fa.generateUrl({ secret: 'S5V43NFEQPKEH3C4', issuer: 'exampleissuer', user: '[email protected]'}, tokenConfig)
This produces an otpauth like this:
otpauth://totp/exampleissuer:example%4example.com?issuer=exampleissuer&period=60&secret=S5V43NFEQPKEH3C4&algorithm=SHA256
This scans correctly in Google Authenticator.
Therefore, I think you need to update your type "Algorithms" with the capitalised version or need to convert config.algo toUpperCase() when setting as a url param within generateUrl function.
Here:
if (config.algo !== DEFAULT_TOTP_ALGO) {
params.set("algorithm", config.algo);
}
Getting this error with:
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "^5.0.1",
i already tried adding the packages below to the dependencies in the package.json but then i get a different error
"crypto":"npm:crypto-browserify",
"stream":"npm:stream-browserify",
"buffer":"npm:buffer"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.