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
fetchcalls 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 answersPHONE_REQUIRED.
await client.setupMfaDevice('sms', { phoneNumber: '+15551234567', deviceName: 'Work phone' });
- Backup code generation works.
client.generateBackupCodes()shipped but no route served it, so it returned404. Requiresmfa.backup.enabled.
Security
- Three self-service operations no longer take a user id from the caller.
canSetPasswordhad 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
handlebarsadvisory.
Breaking changes
Only if you call the core services directly. The mounted routes and the client SDK are unchanged.
| Before | After |
|---|---|
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.