Add user profile page, password change, reset links, auto-seed RBAC

Backend:
- POST /v1/auth/change-password (current user)
- POST /v1/auth/reset-password/:userId (admin generates 24h signed link)
- POST /v1/auth/reset-password (token-based reset, no auth required)
- GET/PATCH /v1/auth/me (profile read/update)
- Auto-seed system permissions on server startup

Frontend:
- Profile page with name edit, password change, theme/color settings
- Sidebar user link goes to profile page (replaces dropdown)
- Users page: "Reset Password Link" in kebab (copies to clipboard)
- Sign out button below profile link
This commit is contained in:
Ryan Moon
2026-03-28 17:59:55 -05:00
parent 58bf54a251
commit 7dea20e818
7 changed files with 385 additions and 81 deletions

View File

@@ -15,7 +15,7 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { MoreVertical, Shield, Plus, X } from 'lucide-react'
import { MoreVertical, Shield, Plus, X, KeyRound } from 'lucide-react'
import { toast } from 'sonner'
import { queryOptions } from '@tanstack/react-query'
@@ -181,6 +181,18 @@ function UsersPage() {
<Shield className="mr-2 h-4 w-4" />
Manage Roles
</DropdownMenuItem>
<DropdownMenuItem onClick={async () => {
try {
const res = await api.post<{ resetLink: string }>(`/v1/auth/reset-password/${user.id}`, {})
await navigator.clipboard.writeText(res.resetLink)
toast.success('Reset link copied to clipboard')
} catch (err) {
toast.error(err instanceof Error ? err.message : 'Failed to generate link')
}
}}>
<KeyRound className="mr-2 h-4 w-4" />
Reset Password Link
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>