feat: rebrand Hemmelig to paste.es for cloudhost.es
- Set Spanish as default language with ephemeral/encrypted privacy focus - Translate all user-facing strings and legal pages to Spanish - Replace Norwegian flag with Spanish flag in footer - Remove Hemmelig/terces.cloud links, add cloudhost.es sponsorship - Rewrite PrivacyPage: zero data collection, ephemeral design emphasis - Rewrite TermsPage: Spanish law, RGPD, paste.es/CloudHost.es references - Update PWA manifest, HTML meta tags, package.json branding - Rename webhook headers to X-Paste-Event / X-Paste-Signature - Update API docs title and contact to paste.es / cloudhost.es Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
130
api/routes/account.ts
Normal file
130
api/routes/account.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user