@absolutejs/auth 0.27.0-beta.1 → 0.27.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +57 -1
- package/dist/index.js.map +8 -7
- package/dist/mfa/rotation.d.ts +17 -0
- package/dist/mfa/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8437,6 +8437,8 @@ export { consumeBackupCode, generateBackupCodes } from './mfa/backupCodes';
|
|
|
8437
8437
|
export { createMfaGate } from './mfa/gate';
|
|
8438
8438
|
export { mfaChallenge } from './mfa/challenge';
|
|
8439
8439
|
export { mfaRoutes } from './mfa/routes';
|
|
8440
|
+
export { rotateMfaEncryptionKey } from './mfa/rotation';
|
|
8441
|
+
export type { MfaKeyRotationResult } from './mfa/rotation';
|
|
8440
8442
|
export { mfaTotpRoutes } from './mfa/totp';
|
|
8441
8443
|
export { decryptTotpSecret, encryptTotpSecret } from './mfa/secret';
|
|
8442
8444
|
export { createInMemoryMfaStore } from './mfa/inMemoryMfaStore';
|
package/dist/index.js
CHANGED
|
@@ -17843,6 +17843,56 @@ var createPostgresCredentialStore = (db) => ({
|
|
|
17843
17843
|
await db.update(credentialsTable).set({ email_verified: true, updated_at_ms: Date.now() }).where(eq(credentialsTable.email, email.toLowerCase()));
|
|
17844
17844
|
}
|
|
17845
17845
|
});
|
|
17846
|
+
// src/mfa/rotation.ts
|
|
17847
|
+
var tryDecrypt = async (ciphertext, key) => {
|
|
17848
|
+
try {
|
|
17849
|
+
return await decryptTotpSecret(ciphertext, key);
|
|
17850
|
+
} catch {
|
|
17851
|
+
return;
|
|
17852
|
+
}
|
|
17853
|
+
};
|
|
17854
|
+
var ensureReadable = async (ciphertext, key, userId) => {
|
|
17855
|
+
if (await tryDecrypt(ciphertext, key) === undefined) {
|
|
17856
|
+
throw new Error(`TOTP secret for ${userId} decrypts with neither the old nor the new key`);
|
|
17857
|
+
}
|
|
17858
|
+
};
|
|
17859
|
+
var planEnrollment = async (enrollment, oldKey, newKey) => {
|
|
17860
|
+
const ciphertext = enrollment.totpSecretCiphertext;
|
|
17861
|
+
if (ciphertext === undefined || ciphertext.length === 0) {
|
|
17862
|
+
const plan2 = { kind: "skip" };
|
|
17863
|
+
return plan2;
|
|
17864
|
+
}
|
|
17865
|
+
const secret = await tryDecrypt(ciphertext, oldKey);
|
|
17866
|
+
if (secret === undefined) {
|
|
17867
|
+
await ensureReadable(ciphertext, newKey, enrollment.userId);
|
|
17868
|
+
const plan2 = { kind: "already" };
|
|
17869
|
+
return plan2;
|
|
17870
|
+
}
|
|
17871
|
+
const plan = {
|
|
17872
|
+
enrollment: {
|
|
17873
|
+
...enrollment,
|
|
17874
|
+
totpSecretCiphertext: await encryptTotpSecret(secret, newKey),
|
|
17875
|
+
updatedAt: Date.now()
|
|
17876
|
+
},
|
|
17877
|
+
kind: "rotate"
|
|
17878
|
+
};
|
|
17879
|
+
return plan;
|
|
17880
|
+
};
|
|
17881
|
+
var rotateMfaEncryptionKey = async ({
|
|
17882
|
+
mfaStore,
|
|
17883
|
+
newKey,
|
|
17884
|
+
oldKey
|
|
17885
|
+
}) => {
|
|
17886
|
+
const enrollments = await mfaStore.listEnrollments();
|
|
17887
|
+
const plans = await Promise.all(enrollments.map((enrollment) => planEnrollment(enrollment, oldKey, newKey)));
|
|
17888
|
+
await Promise.all(plans.map((plan) => plan.kind === "rotate" ? mfaStore.saveEnrollment(plan.enrollment) : Promise.resolve()));
|
|
17889
|
+
return {
|
|
17890
|
+
alreadyRotated: plans.filter((plan) => plan.kind === "already").length,
|
|
17891
|
+
rotated: plans.filter((plan) => plan.kind === "rotate").length,
|
|
17892
|
+
skippedNoSecret: plans.filter((plan) => plan.kind === "skip").length,
|
|
17893
|
+
total: plans.length
|
|
17894
|
+
};
|
|
17895
|
+
};
|
|
17846
17896
|
// src/mfa/inMemoryMfaStore.ts
|
|
17847
17897
|
var cloneEnrollment = (value) => ({
|
|
17848
17898
|
...value,
|
|
@@ -17855,6 +17905,7 @@ var createInMemoryMfaStore = () => {
|
|
|
17855
17905
|
const enrollment = enrollments.get(userId);
|
|
17856
17906
|
return enrollment ? cloneEnrollment(enrollment) : undefined;
|
|
17857
17907
|
},
|
|
17908
|
+
listEnrollments: async () => Array.from(enrollments.values()).map(cloneEnrollment),
|
|
17858
17909
|
removeEnrollment: async (userId) => {
|
|
17859
17910
|
enrollments.delete(userId);
|
|
17860
17911
|
},
|
|
@@ -17889,6 +17940,10 @@ var createPostgresMfaStore = (db) => ({
|
|
|
17889
17940
|
const [row] = await db.select().from(mfaEnrollmentsTable).where(eq(mfaEnrollmentsTable.user_id, userId)).limit(1);
|
|
17890
17941
|
return row ? toEnrollment(row) : undefined;
|
|
17891
17942
|
},
|
|
17943
|
+
listEnrollments: async () => {
|
|
17944
|
+
const rows = await db.select().from(mfaEnrollmentsTable);
|
|
17945
|
+
return rows.map(toEnrollment);
|
|
17946
|
+
},
|
|
17892
17947
|
removeEnrollment: async (userId) => {
|
|
17893
17948
|
await db.delete(mfaEnrollmentsTable).where(eq(mfaEnrollmentsTable.user_id, userId));
|
|
17894
17949
|
},
|
|
@@ -19438,6 +19493,7 @@ export {
|
|
|
19438
19493
|
scimTokensTable,
|
|
19439
19494
|
scimRoutes,
|
|
19440
19495
|
samlSsoRoutes,
|
|
19496
|
+
rotateMfaEncryptionKey,
|
|
19441
19497
|
rolesTable,
|
|
19442
19498
|
roleRoutes,
|
|
19443
19499
|
revokeUserSessions,
|
|
@@ -19639,5 +19695,5 @@ export {
|
|
|
19639
19695
|
AuthIdentityConflictError
|
|
19640
19696
|
};
|
|
19641
19697
|
|
|
19642
|
-
//# debugId=
|
|
19698
|
+
//# debugId=F0BD7B32BDA8B43664756E2164756E21
|
|
19643
19699
|
//# sourceMappingURL=index.js.map
|