From e6469c46bf345241e97c880f980d7503c077595c Mon Sep 17 00:00:00 2001 From: Oswald Rodrigues Date: Wed, 12 Aug 2026 10:46:15 +0530 Subject: [PATCH] mpin scheme version changes --- src/entities/user-device-credential.entity.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/entities/user-device-credential.entity.ts b/src/entities/user-device-credential.entity.ts index cb0b2477..490670f0 100644 --- a/src/entities/user-device-credential.entity.ts +++ b/src/entities/user-device-credential.entity.ts @@ -38,6 +38,23 @@ export class UserDeviceCredential extends CommonEntity { @Column() mpinScheme: string; + /** + * The hashing *policy* version this row was hashed under - not a version of + * MPIN itself. It comes from `HashingService.currentVersion()`, which + * `BcryptService` currently returns as **2**, so freshly created rows read + * 2, exactly as `ss_user.password_scheme_version` does. + * + * It matters because `BcryptService.normalize` applies the configured + * pepper only when `version >= 2`. Storing the version per row means an + * older hash still verifies after the policy changes: `compare()` uses the + * version the row was written with, and `needsRehash()` upgrades it on the + * next successful login. + * + * The `default: 1` is inherited from the `User` precedent and is never + * reached, since every write path sets this explicitly. Note it would be + * *wrong* if it ever were: a row hashed at 2 but recorded as 1 would be + * compared without the pepper and could never authenticate. + */ @Column({ default: 1 }) mpinSchemeVersion: number;