← back to Watches
api/user/profile.js
192 lines
/**
* User Profile API Routes
* Get, update, and delete user profile
*/
import pool from '../../database/connection.js';
/**
* GET /api/user/profile
* Get current user's profile
*/
export async function getProfile(req, res) {
if (!req.user) {
return res.status(401).json({ success: false, error: 'Not authenticated' });
}
try {
const result = await pool.query(
`SELECT id, email, name, avatar_url, role, provider, email_verified,
created_at, last_login_at, login_count
FROM users WHERE id = $1`,
[req.user.id]
);
if (result.rows.length === 0) {
return res.status(404).json({ success: false, error: 'User not found' });
}
// Get user preferences
const prefs = await pool.query(
`SELECT currency, theme, language, email_notifications, push_notifications,
alert_notifications, marketing_emails
FROM user_preferences WHERE user_id = $1`,
[req.user.id]
);
res.json({
success: true,
user: result.rows[0],
preferences: prefs.rows[0] || {}
});
} catch (error) {
console.error('Get profile error:', error);
res.status(500).json({ success: false, error: 'Failed to get profile' });
}
}
/**
* PATCH /api/user/profile
* Update user profile
*/
export async function updateProfile(req, res) {
if (!req.user) {
return res.status(401).json({ success: false, error: 'Not authenticated' });
}
const { name } = req.body;
try {
const result = await pool.query(
`UPDATE users SET name = COALESCE($1, name), updated_at = NOW()
WHERE id = $2
RETURNING id, email, name, avatar_url`,
[name, req.user.id]
);
res.json({
success: true,
user: result.rows[0]
});
} catch (error) {
console.error('Update profile error:', error);
res.status(500).json({ success: false, error: 'Failed to update profile' });
}
}
/**
* DELETE /api/user/profile
* Delete user account
*/
export async function deleteProfile(req, res) {
if (!req.user) {
return res.status(401).json({ success: false, error: 'Not authenticated' });
}
try {
// Soft delete by deactivating
await pool.query(
`UPDATE users SET is_active = false, email = email || '_deleted_' || id, updated_at = NOW()
WHERE id = $1`,
[req.user.id]
);
// Invalidate all sessions
await pool.query(
`UPDATE user_sessions SET is_valid = false, revoked_at = NOW(), revoke_reason = 'account_deleted'
WHERE user_id = $1`,
[req.user.id]
);
res.clearCookie('session_token');
res.json({ success: true, message: 'Account deleted' });
} catch (error) {
console.error('Delete profile error:', error);
res.status(500).json({ success: false, error: 'Failed to delete account' });
}
}
/**
* GET /api/user/preferences
* Get user preferences
*/
export async function getPreferences(req, res) {
if (!req.user) {
return res.status(401).json({ success: false, error: 'Not authenticated' });
}
try {
const result = await pool.query(
`SELECT * FROM user_preferences WHERE user_id = $1`,
[req.user.id]
);
res.json({
success: true,
preferences: result.rows[0] || {}
});
} catch (error) {
console.error('Get preferences error:', error);
res.status(500).json({ success: false, error: 'Failed to get preferences' });
}
}
/**
* PATCH /api/user/preferences
* Update user preferences
*/
export async function updatePreferences(req, res) {
if (!req.user) {
return res.status(401).json({ success: false, error: 'Not authenticated' });
}
const {
currency, theme, language,
email_notifications, push_notifications, alert_notifications, marketing_emails,
quiet_hours_start, quiet_hours_end, max_alerts_per_day
} = req.body;
try {
const result = await pool.query(
`UPDATE user_preferences
SET currency = COALESCE($1, currency),
theme = COALESCE($2, theme),
language = COALESCE($3, language),
email_notifications = COALESCE($4, email_notifications),
push_notifications = COALESCE($5, push_notifications),
alert_notifications = COALESCE($6, alert_notifications),
marketing_emails = COALESCE($7, marketing_emails),
quiet_hours_start = COALESCE($8, quiet_hours_start),
quiet_hours_end = COALESCE($9, quiet_hours_end),
max_alerts_per_day = COALESCE($10, max_alerts_per_day),
updated_at = NOW()
WHERE user_id = $11
RETURNING *`,
[currency, theme, language, email_notifications, push_notifications,
alert_notifications, marketing_emails, quiet_hours_start, quiet_hours_end,
max_alerts_per_day, req.user.id]
);
res.json({
success: true,
preferences: result.rows[0]
});
} catch (error) {
console.error('Update preferences error:', error);
res.status(500).json({ success: false, error: 'Failed to update preferences' });
}
}
export default {
getProfile,
updateProfile,
deleteProfile,
getPreferences,
updatePreferences
};