- 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
63
app/Models/TotpSecret.ts
Normal file
63
app/Models/TotpSecret.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
import { column, BaseModel, SnakeCaseNamingStrategy, belongsTo, BelongsTo } from '@ioc:Adonis/Lucid/Orm';
|
||||
import User from './User';
|
||||
import { DateTime } from 'luxon';
|
||||
import dayjs from 'dayjs';
|
||||
import Encryption from '@ioc:Adonis/Core/Encryption';
|
||||
|
||||
export default class TotpSecret extends BaseModel {
|
||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||
public static table = 'totp_secrets';
|
||||
// public static fillable: string[] = ['value', 'label', 'type', 'relation'];
|
||||
|
||||
@column({
|
||||
isPrimary: true,
|
||||
})
|
||||
public id: number;
|
||||
|
||||
@column({})
|
||||
public user_id: number;
|
||||
|
||||
// @column()
|
||||
// public twoFactorSecret: string;
|
||||
@column({
|
||||
serializeAs: null,
|
||||
consume: (value: string) => (value ? JSON.parse(Encryption.decrypt(value) ?? '{}') : null),
|
||||
prepare: (value: string) => Encryption.encrypt(JSON.stringify(value)),
|
||||
})
|
||||
public twoFactorSecret?: string | null;
|
||||
|
||||
// serializeAs: null removes the model properties from the serialized output.
|
||||
@column({
|
||||
serializeAs: null,
|
||||
consume: (value: string) => (value ? JSON.parse(Encryption.decrypt(value) ?? '[]') : []),
|
||||
prepare: (value: string[]) => Encryption.encrypt(JSON.stringify(value)),
|
||||
})
|
||||
public twoFactorRecoveryCodes?: string[] | null;
|
||||
|
||||
@column({})
|
||||
public state: number;
|
||||
|
||||
@column.dateTime({
|
||||
serialize: (value: Date | null) => {
|
||||
// return value ? moment(value).format('MMMM Do YYYY, HH:mm:ss') : value;
|
||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||
},
|
||||
autoCreate: true,
|
||||
})
|
||||
public created_at: DateTime;
|
||||
|
||||
@column.dateTime({
|
||||
serialize: (value: Date | null) => {
|
||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||
},
|
||||
autoCreate: true,
|
||||
autoUpdate: true,
|
||||
})
|
||||
public updated_at: DateTime;
|
||||
|
||||
@belongsTo(() => User, {
|
||||
foreignKey: 'user_id',
|
||||
})
|
||||
public user: BelongsTo<typeof User>;
|
||||
|
||||
}
|
|
@ -7,6 +7,8 @@ import Config from '@ioc:Adonis/Core/Config';
|
|||
import Dataset from './Dataset';
|
||||
import BaseModel from './BaseModel';
|
||||
import Encryption from '@ioc:Adonis/Core/Encryption';
|
||||
import { TotpState } from 'Contracts/enums';
|
||||
// import TotpSecret from './TotpSecret';
|
||||
|
||||
// export default interface IUser {
|
||||
// id: number;
|
||||
|
@ -51,7 +53,7 @@ export default class User extends BaseModel {
|
|||
consume: (value: string) => (value ? JSON.parse(Encryption.decrypt(value) ?? '{}') : null),
|
||||
prepare: (value: string) => Encryption.encrypt(JSON.stringify(value)),
|
||||
})
|
||||
public twoFactorSecret?: string;
|
||||
public twoFactorSecret?: string | null;
|
||||
|
||||
// serializeAs: null removes the model properties from the serialized output.
|
||||
@column({
|
||||
|
@ -59,7 +61,15 @@ export default class User extends BaseModel {
|
|||
consume: (value: string) => (value ? JSON.parse(Encryption.decrypt(value) ?? '[]') : []),
|
||||
prepare: (value: string[]) => Encryption.encrypt(JSON.stringify(value)),
|
||||
})
|
||||
public twoFactorRecoveryCodes?: string[];
|
||||
public twoFactorRecoveryCodes?: string[] | null;
|
||||
|
||||
@column({})
|
||||
public state: number;
|
||||
|
||||
// @hasOne(() => TotpSecret, {
|
||||
// foreignKey: 'user_id',
|
||||
// })
|
||||
// public totp_secret: HasOne<typeof TotpSecret>;
|
||||
|
||||
@beforeSave()
|
||||
public static async hashPassword(user) {
|
||||
|
@ -68,8 +78,9 @@ export default class User extends BaseModel {
|
|||
}
|
||||
}
|
||||
|
||||
public get isTwoFactorEnabled() {
|
||||
return Boolean(this?.twoFactorSecret);
|
||||
public get isTwoFactorEnabled(): boolean {
|
||||
return Boolean(this?.twoFactorSecret && this.state == TotpState.STATE_ENABLED);
|
||||
// return Boolean(this.totp_secret?.twoFactorSecret);
|
||||
}
|
||||
|
||||
@manyToMany(() => Role, {
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue