diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 40cfa2c..0145430 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -1789,7 +1789,6 @@ function UsersSection({ onToast }: { onToast: (msg: string, type: string) => voi
setEditing({ ...editing, first_name: v })} />
setEditing({ ...editing, last_name: v })} />
- setEditing({ ...editing, password: v })} placeholder="Enter new password to change" />
setEditing({ ...editing, comments_disabled: e.target.checked })} />
diff --git a/src/app/api/admin/users/route.ts b/src/app/api/admin/users/route.ts
index 47da683..3b2cc0c 100644
--- a/src/app/api/admin/users/route.ts
+++ b/src/app/api/admin/users/route.ts
@@ -37,21 +37,7 @@ export async function PUT(request: NextRequest) {
try {
await requireRole('admin');
const body = await request.json();
- const { id, first_name, last_name, comments_disabled, password } = body;
-
- // If password provided, hash and update it too
- if (password) {
- const { hashPassword } = await import('@/lib/auth');
- const hash = await hashPassword(password);
- const { rows } = await db.query(
- 'UPDATE users SET first_name = $1, last_name = $2, comments_disabled = $3, password_hash = $4 WHERE id = $5 RETURNING id, username, role, first_name, last_name, comments_disabled, created_at',
- [first_name || null, last_name || null, comments_disabled === true, hash, id]
- );
- if (rows.length === 0) {
- return NextResponse.json({ error: 'User not found' }, { status: 404 });
- }
- return NextResponse.json({ data: rows[0] });
- }
+ const { id, first_name, last_name, comments_disabled } = body;
const { rows } = await db.query(
'UPDATE users SET first_name = $1, last_name = $2, comments_disabled = $3 WHERE id = $4 RETURNING id, username, role, first_name, last_name, comments_disabled, created_at',
diff --git a/src/app/api/user/password/route.ts b/src/app/api/user/password/route.ts
new file mode 100644
index 0000000..defa2ef
--- /dev/null
+++ b/src/app/api/user/password/route.ts
@@ -0,0 +1,39 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { requireAuth, hashPassword } from '@/lib/auth';
+import { db } from '@/lib/db';
+
+export async function POST(request: NextRequest) {
+ try {
+ const session = await requireAuth();
+ const body = await request.json();
+ const { current_password, new_password } = body;
+
+ if (!current_password || !new_password) {
+ return NextResponse.json({ error: 'Current and new password are required' }, { status: 400 });
+ }
+
+ if (new_password.length < 4) {
+ return NextResponse.json({ error: 'Password must be at least 4 characters' }, { status: 400 });
+ }
+
+ // Verify current password
+ const { rows } = await db.query('SELECT password_hash FROM users WHERE id = $1', [session.id]);
+ if (rows.length === 0) {
+ return NextResponse.json({ error: 'User not found' }, { status: 404 });
+ }
+
+ const { verifyPassword } = await import('@/lib/auth');
+ const valid = await verifyPassword(current_password, rows[0].password_hash);
+ if (!valid) {
+ return NextResponse.json({ error: 'Current password is incorrect' }, { status: 401 });
+ }
+
+ // Update to new password
+ const hash = await hashPassword(new_password);
+ await db.query('UPDATE users SET password_hash = $1 WHERE id = $2', [hash, session.id]);
+
+ return NextResponse.json({ ok: true });
+ } catch (err: any) {
+ return NextResponse.json({ error: err.message || 'Failed to change password' }, { status: err.message === 'Unauthorized' ? 401 : 500 });
+ }
+}
\ No newline at end of file
diff --git a/src/app/user/page.tsx b/src/app/user/page.tsx
index c0bd753..cab07c1 100644
--- a/src/app/user/page.tsx
+++ b/src/app/user/page.tsx
@@ -215,6 +215,11 @@ export default function UserPage() {