Removes redundant comments to improve code readability
This commit is contained in:
@@ -1317,19 +1317,15 @@ router.post("/complete-reset", async (req, res) => {
|
|||||||
.where(eq(users.username, username));
|
.where(eq(users.username, username));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check if user has an active session with DEK (logged in while resetting)
|
|
||||||
const hasActiveSession = authManager.isUserUnlocked(userId);
|
const hasActiveSession = authManager.isUserUnlocked(userId);
|
||||||
|
|
||||||
if (hasActiveSession) {
|
if (hasActiveSession) {
|
||||||
// User is logged in - preserve their data by keeping the same DEK
|
|
||||||
// This happens when user resets password from settings page
|
|
||||||
const success = await authManager.resetUserPasswordWithPreservedDEK(
|
const success = await authManager.resetUserPasswordWithPreservedDEK(
|
||||||
userId,
|
userId,
|
||||||
newPassword,
|
newPassword,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// If preservation fails, fall back to new DEK (will lose data)
|
|
||||||
authLogger.warn(
|
authLogger.warn(
|
||||||
`Failed to preserve DEK during password reset for ${username}. Creating new DEK - data will be lost.`,
|
`Failed to preserve DEK during password reset for ${username}. Creating new DEK - data will be lost.`,
|
||||||
{
|
{
|
||||||
@@ -1351,7 +1347,6 @@ router.post("/complete-reset", async (req, res) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// User is NOT logged in - create new DEK (data will be inaccessible)
|
|
||||||
await authManager.registerUser(userId, newPassword);
|
await authManager.registerUser(userId, newPassword);
|
||||||
authManager.logoutUser(userId);
|
authManager.logoutUser(userId);
|
||||||
|
|
||||||
@@ -2049,7 +2044,6 @@ router.post("/change-password", authenticateJWT, async (req, res) => {
|
|||||||
.set({ password_hash: newPasswordHash })
|
.set({ password_hash: newPasswordHash })
|
||||||
.where(eq(users.id, userId));
|
.where(eq(users.id, userId));
|
||||||
|
|
||||||
// Trigger database save to persist password hash
|
|
||||||
const { saveMemoryDatabaseToFile } = await import("../db/index.js");
|
const { saveMemoryDatabaseToFile } = await import("../db/index.js");
|
||||||
await saveMemoryDatabaseToFile();
|
await saveMemoryDatabaseToFile();
|
||||||
|
|
||||||
|
|||||||
@@ -249,7 +249,6 @@ class UserCrypto {
|
|||||||
newPassword: string,
|
newPassword: string,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
// Validate current password
|
|
||||||
const isValid = await this.validatePassword(userId, oldPassword);
|
const isValid = await this.validatePassword(userId, oldPassword);
|
||||||
if (!isValid) return false;
|
if (!isValid) return false;
|
||||||
|
|
||||||
@@ -260,35 +259,24 @@ class UserCrypto {
|
|||||||
const encryptedDEK = await this.getEncryptedDEK(userId);
|
const encryptedDEK = await this.getEncryptedDEK(userId);
|
||||||
if (!encryptedDEK) return false;
|
if (!encryptedDEK) return false;
|
||||||
|
|
||||||
// Decrypt DEK with old password's KEK
|
|
||||||
const DEK = this.decryptDEK(encryptedDEK, oldKEK);
|
const DEK = this.decryptDEK(encryptedDEK, oldKEK);
|
||||||
|
|
||||||
// The DEK stays the same - only the KEK changes with the new password
|
|
||||||
// This preserves all encrypted user data
|
|
||||||
|
|
||||||
// Generate new KEK from new password
|
|
||||||
const newKekSalt = await this.generateKEKSalt();
|
const newKekSalt = await this.generateKEKSalt();
|
||||||
const newKEK = this.deriveKEK(newPassword, newKekSalt);
|
const newKEK = this.deriveKEK(newPassword, newKekSalt);
|
||||||
|
|
||||||
// Re-encrypt the same DEK with new KEK
|
|
||||||
const newEncryptedDEK = this.encryptDEK(DEK, newKEK);
|
const newEncryptedDEK = this.encryptDEK(DEK, newKEK);
|
||||||
|
|
||||||
// Store new KEK salt and new encrypted DEK
|
|
||||||
await this.storeKEKSalt(userId, newKekSalt);
|
await this.storeKEKSalt(userId, newKekSalt);
|
||||||
await this.storeEncryptedDEK(userId, newEncryptedDEK);
|
await this.storeEncryptedDEK(userId, newEncryptedDEK);
|
||||||
|
|
||||||
// Trigger database save to persist the encryption key changes
|
|
||||||
const { saveMemoryDatabaseToFile } = await import("../database/db/index.js");
|
const { saveMemoryDatabaseToFile } = await import("../database/db/index.js");
|
||||||
await saveMemoryDatabaseToFile();
|
await saveMemoryDatabaseToFile();
|
||||||
|
|
||||||
// Clean up sensitive data from memory
|
|
||||||
oldKEK.fill(0);
|
oldKEK.fill(0);
|
||||||
newKEK.fill(0);
|
newKEK.fill(0);
|
||||||
|
|
||||||
// Create a copy of DEK for the session before zeroing it out
|
|
||||||
const dekCopy = Buffer.from(DEK);
|
const dekCopy = Buffer.from(DEK);
|
||||||
|
|
||||||
// Keep user session active with the same DEK
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const oldSession = this.userSessions.get(userId);
|
const oldSession = this.userSessions.get(userId);
|
||||||
if (oldSession) {
|
if (oldSession) {
|
||||||
@@ -301,7 +289,6 @@ class UserCrypto {
|
|||||||
expiresAt: now + UserCrypto.SESSION_DURATION,
|
expiresAt: now + UserCrypto.SESSION_DURATION,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Zero out the original DEK from memory
|
|
||||||
DEK.fill(0);
|
DEK.fill(0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -320,36 +307,26 @@ class UserCrypto {
|
|||||||
newPassword: string,
|
newPassword: string,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
// This method preserves the existing DEK by re-encrypting it with the new password
|
|
||||||
// Used for password reset when user is logged in
|
|
||||||
|
|
||||||
// Check if user has an active session with DEK
|
|
||||||
const existingDEK = this.getUserDataKey(userId);
|
const existingDEK = this.getUserDataKey(userId);
|
||||||
if (!existingDEK) {
|
if (!existingDEK) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate new KEK from new password
|
|
||||||
const newKekSalt = await this.generateKEKSalt();
|
const newKekSalt = await this.generateKEKSalt();
|
||||||
const newKEK = this.deriveKEK(newPassword, newKekSalt);
|
const newKEK = this.deriveKEK(newPassword, newKekSalt);
|
||||||
|
|
||||||
// Re-encrypt the existing DEK with new KEK
|
|
||||||
const newEncryptedDEK = this.encryptDEK(existingDEK, newKEK);
|
const newEncryptedDEK = this.encryptDEK(existingDEK, newKEK);
|
||||||
|
|
||||||
// Store new KEK salt and new encrypted DEK
|
|
||||||
await this.storeKEKSalt(userId, newKekSalt);
|
await this.storeKEKSalt(userId, newKekSalt);
|
||||||
await this.storeEncryptedDEK(userId, newEncryptedDEK);
|
await this.storeEncryptedDEK(userId, newEncryptedDEK);
|
||||||
|
|
||||||
// Trigger database save to persist the encryption key changes
|
|
||||||
const { saveMemoryDatabaseToFile } = await import(
|
const { saveMemoryDatabaseToFile } = await import(
|
||||||
"../database/db/index.js"
|
"../database/db/index.js"
|
||||||
);
|
);
|
||||||
await saveMemoryDatabaseToFile();
|
await saveMemoryDatabaseToFile();
|
||||||
|
|
||||||
// Clean up sensitive data
|
|
||||||
newKEK.fill(0);
|
newKEK.fill(0);
|
||||||
|
|
||||||
// Update session activity timestamp
|
|
||||||
const session = this.userSessions.get(userId);
|
const session = this.userSessions.get(userId);
|
||||||
if (session) {
|
if (session) {
|
||||||
session.lastActivity = Date.now();
|
session.lastActivity = Date.now();
|
||||||
|
|||||||
Reference in New Issue
Block a user