Files

131 lines
3.7 KiB
TypeScript
Raw Permalink Normal View History

import { zValidator } from '@hono/zod-validator';
import { Hono } from 'hono';
import { auth } from '../auth';
import prisma from '../lib/db';
import { handleNotFound } from '../lib/utils';
import { authMiddleware } from '../middlewares/auth';
import { updateAccountSchema, updatePasswordSchema } from '../validations/account';
const app = new Hono<{
Variables: {
user: typeof auth.$Infer.Session.user | null;
};
}>();
// Get user account information
app.get('/', authMiddleware, async (c) => {
const user = c.get('user');
if (!user) {
return c.json({ error: 'Unauthorized' }, 401);
}
return c.json({
username: user.username,
email: user.email,
});
});
// Update user account information
app.put('/', authMiddleware, zValidator('json', updateAccountSchema), async (c) => {
const user = c.get('user');
const { username, email } = c.req.valid('json');
if (!user) {
return c.json({ error: 'Unauthorized' }, 401);
}
try {
// Check if username is taken by another user
if (username) {
const existingUser = await prisma.user.findUnique({
where: { username },
select: { id: true },
});
if (existingUser && existingUser.id !== user.id) {
return c.json({ error: 'Username is already taken' }, 409);
}
}
// Check if email is taken by another user
if (email) {
const existingEmail = await prisma.user.findFirst({
where: { email },
select: { id: true },
});
if (existingEmail && existingEmail.id !== user.id) {
return c.json({ error: 'Email is already taken' }, 409);
}
}
const updatedUser = await prisma.user.update({
where: { id: user.id },
data: {
username,
email,
},
});
return c.json({
username: updatedUser.username,
email: updatedUser.email,
});
} catch (error) {
console.error('Failed to update account:', error);
return handleNotFound(error as Error & { code?: string }, c);
}
});
// Update user password
app.put('/password', authMiddleware, zValidator('json', updatePasswordSchema), async (c) => {
const user = c.get('user');
const { currentPassword, newPassword } = c.req.valid('json');
if (!user) {
return c.json({ error: 'Unauthorized' }, 401);
}
try {
// Use better-auth's changePassword API
const result = await auth.api.changePassword({
body: {
currentPassword,
newPassword,
},
headers: c.req.raw.headers,
});
if (!result) {
return c.json({ error: 'Failed to change password' }, 500);
}
return c.json({ message: 'Password updated successfully' });
} catch (error) {
console.error('Failed to update password:', error);
const message = error instanceof Error ? error.message : 'Failed to update password';
return c.json({ error: message }, 500);
}
});
// Delete user account
app.delete('/', authMiddleware, async (c) => {
const user = c.get('user');
if (!user) {
return c.json({ error: 'Unauthorized' }, 401);
}
try {
await prisma.user.delete({
where: { id: user.id },
});
return c.json({ message: 'Account deleted successfully' });
} catch (error) {
console.error('Failed to delete account:', error);
return handleNotFound(error as Error & { code?: string }, c);
}
});
export default app;