Skip to main content

v0.6.0

Added​

  • Trusted device management. A device could be trusted to skip MFA, but never reviewed or untrusted afterwards. Users can now see what is trusted on their account and take it back — and administrators can do the same for any user.
const { trustedDevices } = await client.listTrustedDevices();
await client.revokeTrustedDevice(deviceId);
await client.revokeAllTrustedDevices(); // e.g. after a lost laptop

Expired devices are filtered out, so the list is what can currently skip MFA rather than everything ever trusted. Revoking removes the MFA bypass only — it does not sign the device out, so pair it with logoutAll() if that is what you mean.

  • The frontend SDK now covers every shipped route. Around eighteen endpoints the backend already served had no SDK method, so integrators were hand-building fetch calls against them. Those are now first-class:
// Sessions — a "signed-in devices" screen
const { sessions } = await client.listSessions();
await client.revokeSession(sessionId);

// A social-only account setting its first password
if ((await client.canSetPassword()).canSetPassword) {
await client.setPasswordForSocialUser(newPassword);
}

// Admin
await client.admin.getUserByEmail({ email });
await client.admin.revokeUserSession(sub, sessionId);
await client.admin.updateVerifiedStatus(sub, { isEmailVerified: true });
  • Enrol a phone or email the account does not have yet. setupMfaDevice() now takes enrolment data, so a password-only or social account can add SMS without already holding a verified number. Without it the server answers PHONE_REQUIRED.
await client.setupMfaDevice('sms', { phoneNumber: '+15551234567', deviceName: 'Work phone' });
  • Backup code generation works. client.generateBackupCodes() shipped but no route served it, so it returned 404. Requires mfa.backup.enabled.

Security​

  • Three self-service operations no longer take a user id from the caller. canSetPassword had no ownership check, so any signed-in user could learn whether an arbitrary account was passwordless. All three now act on the authenticated caller.

Fixed​

  • Session lists no longer include expired sessions. Nothing prunes expired rows, so a devices screen grew without bound and offered dead sessions to sign out of. Both the user's own list and the administrative one are affected.

  • Dependency security updates across the email, SMS and social packages, including a critical handlebars advisory.

Breaking changes​

Only if you call the core services directly. The mounted routes and the client SDK are unchanged.

BeforeAfter
mfaService.getAvailableMethods({ sub })mfaService.getAvailableMethods()
socialAuthService.canSetPassword({ sub })socialAuthService.canSetPassword()
setPasswordForSocialUser({ sub, password })setPasswordForSocialUser({ password })

CanSetPasswordDTO and GetAvailableMethodsDTO are removed — both held only sub, which now comes from the authenticated context.