fix: resolve frontend routing, API mismatches, and missing UI components
- Add servers list page and missing routes (servers, settings redirect, account security)
- Fix members page .map error (API returns { data } wrapper, not flat array)
- Fix auth store fetchUser expecting flat User but API returns { user } wrapper
- Add node token display dialog after creation
- Add allocation management UI to node detail page
- Add account security page with password change
- Add change-password API endpoint
- Add node servers and stats API endpoints
- Fix config save using PATCH instead of PUT, add api.put method
- Fix audit logs field name mismatch (userName vs username)
- Replace admin nodes page to avoid orgId dependency
- Remove duplicate sidebar nav items
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -171,6 +171,39 @@ export default async function authRoutes(app: FastifyInstance) {
|
||||
return { success: true };
|
||||
});
|
||||
|
||||
// POST /api/auth/change-password
|
||||
app.post('/change-password', { onRequest: [app.authenticate] }, async (request) => {
|
||||
const { currentPassword, newPassword } = request.body as {
|
||||
currentPassword: string;
|
||||
newPassword: string;
|
||||
};
|
||||
|
||||
if (!currentPassword || !newPassword || newPassword.length < 8) {
|
||||
throw AppError.badRequest('New password must be at least 8 characters');
|
||||
}
|
||||
|
||||
const user = await app.db.query.users.findFirst({
|
||||
where: eq(users.id, request.user.sub),
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw AppError.notFound('User not found');
|
||||
}
|
||||
|
||||
const isValid = await verifyPassword(user.passwordHash, currentPassword);
|
||||
if (!isValid) {
|
||||
throw AppError.unauthorized('Current password is incorrect', 'INVALID_PASSWORD');
|
||||
}
|
||||
|
||||
const newHash = await hashPassword(newPassword);
|
||||
await app.db
|
||||
.update(users)
|
||||
.set({ passwordHash: newHash, updatedAt: new Date() })
|
||||
.where(eq(users.id, user.id));
|
||||
|
||||
return { success: true };
|
||||
});
|
||||
|
||||
// GET /api/auth/me
|
||||
app.get('/me', { onRequest: [app.authenticate] }, async (request) => {
|
||||
const payload = request.user;
|
||||
|
||||
Reference in New Issue
Block a user