registration errors in progress
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 6m16s

This commit is contained in:
2025-12-10 08:41:30 -08:00
parent 7912d29961
commit 8da5a2118e
3 changed files with 109 additions and 45 deletions

View File

@@ -74,62 +74,47 @@ router.post('/register', async (req, res, next) => {
return res.status(400).json({ message: passwordValidation.feedback });
}
const client = await getPool().connect();
let newUser;
try {
await client.query('BEGIN');
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
logger.info(`Hashing password for new user: ${email}`);
const repoWithTransaction = new (await import('../services/db/user.db')).UserRepository(client);
try {
newUser = await repoWithTransaction.createUser(email, hashedPassword, { full_name, avatar_url });
} catch (error) {
if (error instanceof UniqueConstraintError) {
return res.status(409).json({ message: error.message });
}
throw error;
}
// The createUser method in UserRepository now handles its own transaction.
const newUser = await userRepo.createUser(email, hashedPassword, { full_name, avatar_url });
await client.query('COMMIT');
const userEmail = newUser.user.email || 'unknown';
const userId = newUser.user_id || 'unknown';
logger.info(`Successfully created new user in DB: ${userEmail} (ID: ${userId})`);
// Use the new standardized logging function
await adminRepo.logActivity({
userId: newUser.user_id,
action: 'user_registered',
displayText: `${userEmail} has registered.`,
icon: 'user-plus',
});
const payload = { user_id: newUser.user_id, email: userEmail };
const token = jwt.sign(payload, JWT_SECRET, { expiresIn: '1h' });
const refreshToken = crypto.randomBytes(64).toString('hex');
await userRepo.saveRefreshToken(newUser.user_id, refreshToken);
res.cookie('refreshToken', refreshToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
});
return res.status(201).json({ message: 'User registered successfully!', user: payload, token });
} catch (error: unknown) {
if (error instanceof UniqueConstraintError) {
// If the email is a duplicate, return a 409 Conflict status.
return res.status(409).json({ message: error.message });
}
await client.query('ROLLBACK');
logger.error(`Transaction failed during user registration for email: ${email}.`, { error });
// The createUser method now handles its own transaction logging, so we just log the route failure.
logger.error(`User registration route failed for email: ${email}.`, { error });
return next(error);
} finally {
client.release();
}
// Safe access to prevent crashing if the returned object structure is unexpected during tests
const userEmail = (newUser as UserProfile)?.user?.email || 'unknown';
const userId = newUser?.user_id || 'unknown';
logger.info(`Successfully created new user in DB: ${userEmail} (ID: ${userId})`);
// Use the new standardized logging function
await adminRepo.logActivity({
userId: newUser.user_id,
action: 'user_registered',
displayText: `${userEmail} has registered.`,
icon: 'user-plus',
});
const payload = { user_id: newUser.user_id, email: userEmail };
const token = jwt.sign(payload, JWT_SECRET, { expiresIn: '1h' });
const refreshToken = crypto.randomBytes(64).toString('hex');
await userRepo.saveRefreshToken(newUser.user_id, refreshToken);
res.cookie('refreshToken', refreshToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
});
return res.status(201).json({ message: 'User registered successfully!', user: payload, token });
});
// Login Route

View File

@@ -86,8 +86,27 @@ export class UserRepository {
JOIN public.profiles p ON u.user_id = p.user_id
WHERE u.user_id = $1;
`;
const finalProfileRes = await client.query<UserProfile>(profileQuery, [newUserId]);
const fullUserProfile = finalProfileRes.rows[0];
const finalProfileRes = await client.query(profileQuery, [newUserId]);
const flatProfile = finalProfileRes.rows[0];
if (!flatProfile) {
throw new Error('Failed to create or retrieve user profile after registration.');
}
// Construct the nested UserProfile object to match the type definition.
const fullUserProfile: UserProfile = {
user: {
user_id: flatProfile.user_id,
email: flatProfile.email,
},
user_id: flatProfile.user_id,
full_name: flatProfile.full_name,
avatar_url: flatProfile.avatar_url,
role: flatProfile.role,
points: flatProfile.points,
preferences: flatProfile.preferences,
};
logger.debug(`[DB createUser] Fetched full profile for new user:`, { user: fullUserProfile });
await client.query('COMMIT');