mirror of
https://github.com/logto-io/logto.git
synced 2025-03-24 22:41:28 -05:00
refactor(core): extract isNewMfaVerification property (#6338)
extract isNewMfaVerifrication property
This commit is contained in:
parent
58a5004aa2
commit
34c8bedef6
5 changed files with 35 additions and 25 deletions
|
@ -36,24 +36,6 @@ const isMfaVerificationRecord = (
|
|||
return mfaVerificationTypes.includes(verification.type);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the MFA verification record is a new bind MFA verification.
|
||||
* New bind MFA verification can only be used for binding new MFA factors.
|
||||
*/
|
||||
const isNewBindMfaVerification = (verification: MfaVerificationRecord) => {
|
||||
switch (verification.type) {
|
||||
case VerificationType.TOTP: {
|
||||
return Boolean(verification.secret);
|
||||
}
|
||||
case VerificationType.WebAuthn: {
|
||||
return Boolean(verification.registrationInfo);
|
||||
}
|
||||
case VerificationType.BackupCode: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export class MfaValidator {
|
||||
constructor(
|
||||
private readonly mfaSettings: Mfa,
|
||||
|
@ -137,7 +119,7 @@ export class MfaValidator {
|
|||
isMfaVerificationRecord(verification) &&
|
||||
verification.isVerified &&
|
||||
// New bind MFA verification can not be used for verification
|
||||
!isNewBindMfaVerification(verification) &&
|
||||
!verification.isNewBindMfaVerification &&
|
||||
// Check if the verification type is enabled in the user's MFA settings
|
||||
this.userEnabledMfaVerifications.some(
|
||||
(factor) => factor.type === mfaVerificationTypeToMfaFactorMap[verification.type]
|
||||
|
|
|
@ -7,7 +7,7 @@ import type Libraries from '#src/tenants/Libraries.js';
|
|||
import type Queries from '#src/tenants/Queries.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
|
||||
import { type VerificationRecord } from './verification-record.js';
|
||||
import { type MfaVerificationRecord } from './verification-record.js';
|
||||
|
||||
export type BackupCodeVerificationRecordData = {
|
||||
id: string;
|
||||
|
@ -24,7 +24,7 @@ export const backupCodeVerificationRecordDataGuard = z.object({
|
|||
code: z.string().optional(),
|
||||
}) satisfies ToZodObject<BackupCodeVerificationRecordData>;
|
||||
|
||||
export class BackupCodeVerification implements VerificationRecord<VerificationType.BackupCode> {
|
||||
export class BackupCodeVerification implements MfaVerificationRecord<VerificationType.BackupCode> {
|
||||
/**
|
||||
* Factory method to create a new BackupCodeVerification instance
|
||||
*
|
||||
|
@ -60,6 +60,10 @@ export class BackupCodeVerification implements VerificationRecord<VerificationTy
|
|||
return Boolean(this.code);
|
||||
}
|
||||
|
||||
get isNewBindMfaVerification() {
|
||||
return false;
|
||||
}
|
||||
|
||||
async verify(code: string) {
|
||||
const {
|
||||
users: { findUserById, updateUserById },
|
||||
|
|
|
@ -20,7 +20,7 @@ import type Libraries from '#src/tenants/Libraries.js';
|
|||
import type Queries from '#src/tenants/Queries.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
|
||||
import { type VerificationRecord } from './verification-record.js';
|
||||
import { type MfaVerificationRecord } from './verification-record.js';
|
||||
|
||||
const defaultDisplayName = 'Unnamed User';
|
||||
|
||||
|
@ -47,7 +47,7 @@ export const totpVerificationRecordDataGuard = z.object({
|
|||
verified: z.boolean(),
|
||||
}) satisfies ToZodObject<TotpVerificationRecordData>;
|
||||
|
||||
export class TotpVerification implements VerificationRecord<VerificationType.TOTP> {
|
||||
export class TotpVerification implements MfaVerificationRecord<VerificationType.TOTP> {
|
||||
/**
|
||||
* Factory method to create a new TotpVerification instance
|
||||
*
|
||||
|
@ -90,6 +90,10 @@ export class TotpVerification implements VerificationRecord<VerificationType.TOT
|
|||
return this.#secret;
|
||||
}
|
||||
|
||||
get isNewBindMfaVerification() {
|
||||
return Boolean(this.#secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new TOTP secret and QR code for the user.
|
||||
* The secret will be stored in the instance and can be used for verifying the TOTP.
|
||||
|
|
|
@ -37,3 +37,19 @@ export abstract class IdentifierVerificationRecord<
|
|||
/** Identify the user associated with the verification record. */
|
||||
abstract identifyUser(): Promise<User>;
|
||||
}
|
||||
|
||||
type MfaVerificationType =
|
||||
| VerificationType.TOTP
|
||||
| VerificationType.BackupCode
|
||||
| VerificationType.WebAuthn;
|
||||
|
||||
export abstract class MfaVerificationRecord<
|
||||
T extends MfaVerificationType = MfaVerificationType,
|
||||
Json extends Data<T> = Data<T>,
|
||||
> extends VerificationRecord<T, Json> {
|
||||
/**
|
||||
* Indicates if the verification record is for a new bind MFA verification.
|
||||
* A new bind MFA verification record can not be used for existing user's interaction verification.
|
||||
**/
|
||||
abstract get isNewBindMfaVerification(): boolean;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import type Libraries from '#src/tenants/Libraries.js';
|
|||
import type Queries from '#src/tenants/Queries.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
|
||||
import { type VerificationRecord } from './verification-record.js';
|
||||
import { type MfaVerificationRecord } from './verification-record.js';
|
||||
|
||||
export type WebAuthnVerificationRecordData = {
|
||||
id: string;
|
||||
|
@ -50,7 +50,7 @@ export const webAuthnVerificationRecordDataGuard = z.object({
|
|||
registrationInfo: bindWebAuthnGuard.optional(),
|
||||
}) satisfies ToZodObject<WebAuthnVerificationRecordData>;
|
||||
|
||||
export class WebAuthnVerification implements VerificationRecord<VerificationType.WebAuthn> {
|
||||
export class WebAuthnVerification implements MfaVerificationRecord<VerificationType.WebAuthn> {
|
||||
/**
|
||||
* Factory method to create a new WebAuthnVerification instance
|
||||
*
|
||||
|
@ -104,6 +104,10 @@ export class WebAuthnVerification implements VerificationRecord<VerificationType
|
|||
return this.#registrationInfo;
|
||||
}
|
||||
|
||||
get isNewBindMfaVerification() {
|
||||
return Boolean(this.#registrationInfo ?? this.registrationChallenge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @remarks
|
||||
* This method is used to generate the WebAuthn registration options for the user.
|
||||
|
|
Loading…
Add table
Reference in a new issue