registration errors in progress
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 6m16s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 6m16s
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user