core: compute usesFallbackPWHash instead of storing it

this fixes the fallback logic for already logged in users
This commit is contained in:
Abdullah Atta
2024-12-23 13:35:36 +05:00
committed by Abdullah Atta
parent ab00645c23
commit 6e8610c358
3 changed files with 31 additions and 13 deletions

View File

@@ -190,7 +190,6 @@ class UserManager {
salt: user.salt
});
}
await this.db.kv().write("usesFallbackPWHash", usesFallback);
EV.publish(EVENTS.userLoggedIn, user);
} catch (e) {
await this.tokenManager.saveToken(token);
@@ -333,7 +332,7 @@ class UserManager {
`${constants.API_HOST}${ENDPOINTS.deleteUser}`,
{
password: await this.db.storage().hash(password, user.email, {
usesFallback: await this.db.kv().read("usesFallbackPWHash")
usesFallback: await this.usesFallbackPWHash(password)
})
},
token
@@ -485,17 +484,12 @@ class UserManager {
type: "change_email",
new_email: newEmail,
password: await this.db.storage().hash(password, email, {
usesFallback: await this.db.kv().read("usesFallbackPWHash")
usesFallback: await this.usesFallbackPWHash(password)
}),
verification_code: code
},
token
);
await this.db.storage().deriveCryptoKey({
password,
salt: user.salt
});
}
recoverAccount(email: string) {
@@ -566,7 +560,7 @@ class UserManager {
if (old_password)
old_password = await this.db.storage().hash(old_password, email, {
usesFallback: await this.db.kv().read("usesFallbackPWHash")
usesFallback: await this.usesFallbackPWHash(old_password)
});
if (new_password)
new_password = await this.db.storage().hash(new_password, email);
@@ -580,10 +574,32 @@ class UserManager {
},
token
);
await this.db.kv().write("usesFallbackPWHash", false);
return true;
}
private async usesFallbackPWHash(password: string) {
const user = await this.getUser();
const encryptionKey = await this.getEncryptionKey();
if (!user || !encryptionKey) return false;
const fallbackCryptoKey = await this.db
.storage()
.generateCryptoKeyFallback(password, user.salt);
const cryptoKey = await this.db
.storage()
.generateCryptoKey(password, user.salt);
if (!encryptionKey.key || !fallbackCryptoKey.key || !cryptoKey.key)
throw new Error("Failed to generate crypto keys.");
if (
fallbackCryptoKey.key !== encryptionKey.key &&
cryptoKey.key !== encryptionKey.key
)
throw new Error("Wrong password.");
return fallbackCryptoKey.key === encryptionKey.key;
}
}
export default UserManager;

View File

@@ -30,7 +30,6 @@ interface KV {
deviceId: string;
lastBackupTime: number;
fullOfflineMode: boolean;
usesFallbackPWHash: boolean;
}
export const KEYS: (keyof KV)[] = [
@@ -41,8 +40,7 @@ export const KEYS: (keyof KV)[] = [
"monographs",
"deviceId",
"lastBackupTime",
"fullOfflineMode",
"usesFallbackPWHash"
"fullOfflineMode"
];
export class KVStorage {

View File

@@ -66,6 +66,10 @@ export interface IStorage {
getCryptoKey(): Promise<string | undefined>;
generateCryptoKey(password: string, salt?: string): Promise<SerializedKey>;
generateCryptoKeyFallback(
password: string,
salt?: string
): Promise<SerializedKey>;
deriveCryptoKeyFallback(credentials: SerializedKey): Promise<void>;
// async generateRandomKey() {