db(couchdb): auto-provision databases on startup for production strategy; add TokenService with CouchDB-backed token storage and localStorage fallback; switch OAuth to unified config for client IDs and redirect URI; express Request typing for req.user; align exportAsEnvVars with show-config expectations; remove Vite importmap from index.html; prefer babel-jest over ts-jest; remove duplicate uuid mocking from Jest config

This commit is contained in:
William Valentin
2025-09-09 12:30:38 -07:00
parent 062e0973c1
commit 15170a4f43
17 changed files with 1097 additions and 67 deletions

View File

@@ -3,6 +3,7 @@ import { AuthenticatedUser } from './auth.types';
import { EmailVerificationService } from './emailVerification.service';
import { databaseService } from '../database';
import { logger } from '../logging';
import { tokenService } from './token.service';
const emailVerificationService = new EmailVerificationService();
@@ -203,17 +204,13 @@ const authService = {
const expiresAt = new Date();
expiresAt.setHours(expiresAt.getHours() + 1); // 1 hour expiry
// Store reset token (in production, save to database)
const resetTokens = JSON.parse(
localStorage.getItem('password_reset_tokens') || '[]'
);
resetTokens.push({
// Persist reset token
await tokenService.savePasswordResetToken({
userId: user._id,
email: user.email,
email: user.email!,
token: resetToken,
expiresAt,
});
localStorage.setItem('password_reset_tokens', JSON.stringify(resetTokens));
// Send reset email
const emailSent = await emailVerificationService.sendPasswordResetEmail(
@@ -229,14 +226,8 @@ const authService = {
},
async resetPassword(token: string, newPassword: string) {
// Get reset tokens
const resetTokens = JSON.parse(
localStorage.getItem('password_reset_tokens') || '[]'
);
const resetToken = resetTokens.find(
(t: { token: string; userId: string; email: string; expiresAt: Date }) =>
t.token === token
);
// Load reset token
const resetToken = await tokenService.findPasswordResetToken(token);
if (!resetToken) {
throw new Error('Invalid or expired reset token');
@@ -265,14 +256,7 @@ const authService = {
});
// Remove used token
const filteredTokens = resetTokens.filter(
(t: { token: string; userId: string; email: string; expiresAt: Date }) =>
t.token !== token
);
localStorage.setItem(
'password_reset_tokens',
JSON.stringify(filteredTokens)
);
await tokenService.deletePasswordResetToken(token);
return {
user: updatedUser,