feat(interfaces): add MFA and passkey contracts
This commit is contained in:
@@ -16,6 +16,13 @@ export type TActivityAction =
|
|||||||
| 'role_changed'
|
| 'role_changed'
|
||||||
| 'org_app_role_mappings_updated'
|
| 'org_app_role_mappings_updated'
|
||||||
| 'profile_updated'
|
| 'profile_updated'
|
||||||
|
| 'totp_enabled'
|
||||||
|
| 'totp_disabled'
|
||||||
|
| 'backup_codes_regenerated'
|
||||||
|
| 'mfa_completed'
|
||||||
|
| 'passkey_registered'
|
||||||
|
| 'passkey_revoked'
|
||||||
|
| 'passkey_login'
|
||||||
| 'app_connected'
|
| 'app_connected'
|
||||||
| 'app_disconnected';
|
| 'app_disconnected';
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ export * from './billingplan.js';
|
|||||||
export * from './device.js';
|
export * from './device.js';
|
||||||
export * from './jwt.js';
|
export * from './jwt.js';
|
||||||
export * from './loginsession.js';
|
export * from './loginsession.js';
|
||||||
|
export * from './mfa.js';
|
||||||
export * from './organization.js';
|
export * from './organization.js';
|
||||||
export * from './paddlecheckoutdata.js';
|
export * from './paddlecheckoutdata.js';
|
||||||
|
export * from './passkey.js';
|
||||||
export * from './passportchallenge.js';
|
export * from './passportchallenge.js';
|
||||||
export * from './passportdevice.js';
|
export * from './passportdevice.js';
|
||||||
export * from './passportnonce.js';
|
export * from './passportnonce.js';
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
export type TMfaMethod = 'totp' | 'backupCode' | 'passkey';
|
||||||
|
|
||||||
|
export type TMfaChallengeStatus = 'pending' | 'completed' | 'expired';
|
||||||
|
|
||||||
|
export type TTotpCredentialStatus = 'pending' | 'active' | 'disabled';
|
||||||
|
|
||||||
|
export interface ITotpBackupCode {
|
||||||
|
id: string;
|
||||||
|
codeHash: string;
|
||||||
|
usedAt?: number | null;
|
||||||
|
createdAt: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ITotpCredential {
|
||||||
|
id: string;
|
||||||
|
data: {
|
||||||
|
userId: string;
|
||||||
|
status: TTotpCredentialStatus;
|
||||||
|
secretCiphertext: string;
|
||||||
|
secretIv: string;
|
||||||
|
secretAuthTag: string;
|
||||||
|
algorithm: 'sha1' | 'sha256' | 'sha512';
|
||||||
|
digits: 6 | 7 | 8;
|
||||||
|
period: number;
|
||||||
|
backupCodes: ITotpBackupCode[];
|
||||||
|
createdAt: number;
|
||||||
|
verifiedAt?: number | null;
|
||||||
|
disabledAt?: number | null;
|
||||||
|
lastUsedAt?: number | null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IMfaChallenge {
|
||||||
|
id: string;
|
||||||
|
data: {
|
||||||
|
userId: string;
|
||||||
|
tokenHash: string;
|
||||||
|
status: TMfaChallengeStatus;
|
||||||
|
availableMethods: TMfaMethod[];
|
||||||
|
primaryAuthMethod: 'password' | 'email';
|
||||||
|
createdAt: number;
|
||||||
|
expiresAt: number;
|
||||||
|
completedAt?: number | null;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
export type TPasskeyCredentialStatus = 'active' | 'revoked';
|
||||||
|
|
||||||
|
export type TPasskeyChallengeType = 'registration' | 'login' | 'mfa';
|
||||||
|
|
||||||
|
export type TPasskeyChallengeStatus = 'pending' | 'completed' | 'expired';
|
||||||
|
|
||||||
|
export type TPasskeyTransport =
|
||||||
|
| 'ble'
|
||||||
|
| 'cable'
|
||||||
|
| 'hybrid'
|
||||||
|
| 'internal'
|
||||||
|
| 'nfc'
|
||||||
|
| 'smart-card'
|
||||||
|
| 'usb';
|
||||||
|
|
||||||
|
export type TPasskeyDeviceType = 'singleDevice' | 'multiDevice';
|
||||||
|
|
||||||
|
export interface IPasskeyCredential {
|
||||||
|
id: string;
|
||||||
|
data: {
|
||||||
|
userId: string;
|
||||||
|
label: string;
|
||||||
|
credentialId: string;
|
||||||
|
publicKeyBase64: string;
|
||||||
|
counter: number;
|
||||||
|
deviceType: TPasskeyDeviceType;
|
||||||
|
backedUp: boolean;
|
||||||
|
transports?: TPasskeyTransport[];
|
||||||
|
status: TPasskeyCredentialStatus;
|
||||||
|
createdAt: number;
|
||||||
|
lastUsedAt?: number | null;
|
||||||
|
revokedAt?: number | null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IWebAuthnChallenge {
|
||||||
|
id: string;
|
||||||
|
data: {
|
||||||
|
userId?: string | null;
|
||||||
|
username?: string | null;
|
||||||
|
mfaChallengeId?: string | null;
|
||||||
|
type: TPasskeyChallengeType;
|
||||||
|
challenge: string;
|
||||||
|
status: TPasskeyChallengeStatus;
|
||||||
|
createdAt: number;
|
||||||
|
expiresAt: number;
|
||||||
|
completedAt?: number | null;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ export * from './authorization.js';
|
|||||||
export * from './billingplan.js';
|
export * from './billingplan.js';
|
||||||
export * from './jwt.js';
|
export * from './jwt.js';
|
||||||
export * from './login.js';
|
export * from './login.js';
|
||||||
|
export * from './mfa.js';
|
||||||
export * from './organization.js';
|
export * from './organization.js';
|
||||||
export * from './passport.js';
|
export * from './passport.js';
|
||||||
export * from './plan.js';
|
export * from './plan.js';
|
||||||
|
|||||||
+6
-1
@@ -14,6 +14,8 @@ export interface IReq_LoginWithEmailOrUsernameAndPassword
|
|||||||
response: {
|
response: {
|
||||||
refreshToken?: string;
|
refreshToken?: string;
|
||||||
twoFaNeeded: boolean;
|
twoFaNeeded: boolean;
|
||||||
|
mfaChallengeToken?: string;
|
||||||
|
availableMfaMethods?: data.TMfaMethod[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +45,10 @@ export interface IReq_LoginWithEmailAfterEmailTokenAquired
|
|||||||
token: string;
|
token: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
refreshToken: string;
|
refreshToken?: string;
|
||||||
|
twoFaNeeded?: boolean;
|
||||||
|
mfaChallengeToken?: string;
|
||||||
|
availableMfaMethods?: data.TMfaMethod[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,208 @@
|
|||||||
|
import * as plugins from '../plugins.js';
|
||||||
|
import * as data from '../data/index.js';
|
||||||
|
|
||||||
|
export interface IReq_GetMfaStatus
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetMfaStatus
|
||||||
|
> {
|
||||||
|
method: 'getMfaStatus';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
totpEnabled: boolean;
|
||||||
|
backupCodesRemaining: number;
|
||||||
|
passkeys: data.IPasskeyCredential[];
|
||||||
|
availableMethods: data.TMfaMethod[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_StartTotpEnrollment
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_StartTotpEnrollment
|
||||||
|
> {
|
||||||
|
method: 'startTotpEnrollment';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
credentialId: string;
|
||||||
|
secret: string;
|
||||||
|
otpauthUrl: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_FinishTotpEnrollment
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_FinishTotpEnrollment
|
||||||
|
> {
|
||||||
|
method: 'finishTotpEnrollment';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
credentialId: string;
|
||||||
|
code: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
success: boolean;
|
||||||
|
backupCodes: string[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_DisableTotp
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_DisableTotp
|
||||||
|
> {
|
||||||
|
method: 'disableTotp';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
code: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_RegenerateBackupCodes
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_RegenerateBackupCodes
|
||||||
|
> {
|
||||||
|
method: 'regenerateBackupCodes';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
code: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
backupCodes: string[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_VerifyMfaChallenge
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_VerifyMfaChallenge
|
||||||
|
> {
|
||||||
|
method: 'verifyMfaChallenge';
|
||||||
|
request: {
|
||||||
|
mfaChallengeToken: string;
|
||||||
|
method: Extract<data.TMfaMethod, 'totp' | 'backupCode'>;
|
||||||
|
code: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
refreshToken: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_StartPasskeyRegistration
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_StartPasskeyRegistration
|
||||||
|
> {
|
||||||
|
method: 'startPasskeyRegistration';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
label?: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
challengeId: string;
|
||||||
|
options: Record<string, any>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_FinishPasskeyRegistration
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_FinishPasskeyRegistration
|
||||||
|
> {
|
||||||
|
method: 'finishPasskeyRegistration';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
challengeId: string;
|
||||||
|
label?: string;
|
||||||
|
response: Record<string, any>;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
success: boolean;
|
||||||
|
passkey: data.IPasskeyCredential;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_RevokePasskey
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_RevokePasskey
|
||||||
|
> {
|
||||||
|
method: 'revokePasskey';
|
||||||
|
request: {
|
||||||
|
jwt: string;
|
||||||
|
passkeyId: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_StartPasskeyLogin
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_StartPasskeyLogin
|
||||||
|
> {
|
||||||
|
method: 'startPasskeyLogin';
|
||||||
|
request: {
|
||||||
|
username?: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
challengeId: string;
|
||||||
|
options: Record<string, any>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_FinishPasskeyLogin
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_FinishPasskeyLogin
|
||||||
|
> {
|
||||||
|
method: 'finishPasskeyLogin';
|
||||||
|
request: {
|
||||||
|
challengeId: string;
|
||||||
|
response: Record<string, any>;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
refreshToken: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_StartPasskeyMfa
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_StartPasskeyMfa
|
||||||
|
> {
|
||||||
|
method: 'startPasskeyMfa';
|
||||||
|
request: {
|
||||||
|
mfaChallengeToken: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
challengeId: string;
|
||||||
|
options: Record<string, any>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IReq_FinishPasskeyMfa
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_FinishPasskeyMfa
|
||||||
|
> {
|
||||||
|
method: 'finishPasskeyMfa';
|
||||||
|
request: {
|
||||||
|
mfaChallengeToken: string;
|
||||||
|
challengeId: string;
|
||||||
|
response: Record<string, any>;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
refreshToken: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user