- added api UserController.ts for 2FA
Some checks failed
CI Pipeline / japa-tests (push) Failing after 56s
Some checks failed
CI Pipeline / japa-tests (push) Failing after 56s
- added PersonalTotpSettings.vue vor enablin/disabling 2FA - changed User.ts: added attributes: state, twoFactorSecret and twoFactorRecoveryCodes - added resources/js/utils/toast.ts for notifications - modified start/routes/api.ts - npm updates
This commit is contained in:
parent
18635f77b3
commit
ebc62d9117
18 changed files with 1151 additions and 315 deletions
|
@ -1,9 +1,10 @@
|
|||
import Config from '@ioc:Adonis/Core/Config';
|
||||
import User from 'App/Models/User';
|
||||
import { generateSecret } from 'node-2fa/dist/index';
|
||||
import { generateSecret, verifyToken } from 'node-2fa/dist/index';
|
||||
// import cryptoRandomString from 'crypto-random-string';
|
||||
import QRCode from 'qrcode';
|
||||
import crypto from 'crypto';
|
||||
import { TotpState } from 'Contracts/enums';
|
||||
|
||||
// npm install node-2fa --save
|
||||
// npm install crypto-random-string --save
|
||||
|
@ -57,7 +58,7 @@ class TwoFactorAuthProvider {
|
|||
private generateRandomString(length: number, type: 'hex' | 'base64' | 'numeric' = 'hex'): string {
|
||||
const byteLength = Math.ceil(length * 0.5); // For hex encoding, each byte generates 2 characters
|
||||
const randomBytes = crypto.randomBytes(byteLength);
|
||||
|
||||
|
||||
switch (type) {
|
||||
case 'hex':
|
||||
return randomBytes.toString('hex').slice(0, length);
|
||||
|
@ -73,16 +74,44 @@ class TwoFactorAuthProvider {
|
|||
}
|
||||
}
|
||||
|
||||
public async generateQrCode(user: User) : Promise<{svg: string; url: string; }> {
|
||||
// public async generateQrCode(user: User) : Promise<{svg: string; url: string; secret: string; }> {
|
||||
// const issuer = encodeURIComponent(this.issuer); // 'TethysCloud'
|
||||
// // const userName = encodeURIComponent(user.email); // 'rrqx9472%40tethys.at'
|
||||
// const label = `${this.issuer}:${user.email}`;
|
||||
|
||||
// const algorithm = encodeURIComponent("SHA256");
|
||||
// const query = `?secret=${user.twoFactorSecret}&issuer=${issuer}&algorithm=${algorithm}&digits=6`; // '?secret=FEYCLOSO627CB7SMLX6QQ7BP75L7SJ54&issuer=TethysCloud'
|
||||
// const url = `otpauth://totp/${label}${query}`; // 'otpauth://totp/rrqx9472%40tethys.at?secret=FEYCLOSO627CB7SMLX6QQ7BP75L7SJ54&issuer=TethysCloud'
|
||||
// const svg = await QRCode.toDataURL(url);
|
||||
// const secret = user.twoFactorSecret as string;
|
||||
// return { svg, url, secret };
|
||||
// }
|
||||
|
||||
public async generateQrCode(user: User, twoFactorSecret?: string): Promise<{ svg: string; url: string; secret: string }> {
|
||||
const issuer = encodeURIComponent(this.issuer); // 'TethysCloud'
|
||||
// const userName = encodeURIComponent(user.email); // 'rrqx9472%40tethys.at'
|
||||
const label = `${this.issuer}:${user.email}`;
|
||||
|
||||
const algorithm = encodeURIComponent("SHA256");
|
||||
const query = `?secret=${user.twoFactorSecret}&issuer=${issuer}&algorithm=${algorithm}&digits=6`; // '?secret=FEYCLOSO627CB7SMLX6QQ7BP75L7SJ54&issuer=TethysCloud'
|
||||
|
||||
// const algorithm = encodeURIComponent('SHA256');
|
||||
const secret = twoFactorSecret ? twoFactorSecret : (user.twoFactorSecret as string);
|
||||
const query = `?secret=${secret}&issuer=${issuer}&digits=6`; // '?secret=FEYCLOSO627CB7SMLX6QQ7BP75L7SJ54&issuer=TethysCloud'
|
||||
|
||||
const url = `otpauth://totp/${label}${query}`; // 'otpauth://totp/rrqx9472%40tethys.at?secret=FEYCLOSO627CB7SMLX6QQ7BP75L7SJ54&issuer=TethysCloud'
|
||||
const svg = await QRCode.toDataURL(url);
|
||||
return { svg, url };
|
||||
|
||||
return { svg, url, secret };
|
||||
}
|
||||
|
||||
public async enable(user: User, token: string): Promise<boolean> {
|
||||
const isValid = verifyToken(user.twoFactorSecret as string, token, 1);
|
||||
if (!isValid) {
|
||||
return false;
|
||||
}
|
||||
user.state = TotpState.STATE_ENABLED;
|
||||
if (await user.save()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue