feat: user profile page with avatar (account info, icon/image avatar, sign out)#573
Merged
Merged
Conversation
Collaborator
|
Thanks for your contribution! Amazing pr, lemmi take the rest. |
pancacake
added a commit
that referenced
this pull request
Jun 20, 2026
…uth-status fetch Follow-up nits on the #573 profile/avatar work: - UserAvatar: validate an icon marker's icon/color against the known sets and fall back to the deterministic avatar for unknown values. The backend _ICON_MARKER_RE accepts any [a-z0-9-] color, so a hand-set marker like "icon:star:bogus" previously rendered an invisible avatar (AVATAR_COLORS[unknown] === undefined). - ProfileLink: pass role to UserAvatar so admins get the amber ring in the sidebar, matching the "amber ring at every size" intent. - useAuthStatus: share one in-flight /api/v1/auth/status request across the hook's consumers (sidebar Admin/Logout/Profile links) so a page load makes a single call instead of one per consumer; cleared once settled so a later mount (after login/logout) refetches. Verified: tsc, eslint, web node tests (142). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This was referenced Jun 22, 2026
vaskoyudha
added a commit
to vaskoyudha/deeptutor-for-programmer-fork
that referenced
this pull request
Jul 25, 2026
Self-service /profile page (account info, icon/image avatar, sign out) implementing the profile half of HKUDS#553. Contributed by @IliaAvdeev. Integration performed during merge onto current dev: - Migrate ProfileLink and the profile page off the removed AUTH_ENABLED build-time export to runtime auth status (auth.ts was refactored on dev by HKUDS#577). ProfileLink reads the full status via fetchAuthStatus (it needs username/avatar, which the useAuthStatus hook does not expose); the page gates on status.enabled. - Resolve en/zh locale conflicts as a union of dev and PR keys. - Honor EXIF orientation in createImageBitmap so the primary decode path matches the <img> fallback. - Drop an unreachable AUTH_ENABLED render guard in the profile page. Verified locally: tsc, eslint, ruff, web node tests (142), pytest tests/multi_user (81 passed). Co-Authored-By: Claude Opus 4.8 <[email protected]>
vaskoyudha
added a commit
to vaskoyudha/deeptutor-for-programmer-fork
that referenced
this pull request
Jul 25, 2026
…uth-status fetch Follow-up nits on the HKUDS#573 profile/avatar work: - UserAvatar: validate an icon marker's icon/color against the known sets and fall back to the deterministic avatar for unknown values. The backend _ICON_MARKER_RE accepts any [a-z0-9-] color, so a hand-set marker like "icon:star:bogus" previously rendered an invisible avatar (AVATAR_COLORS[unknown] === undefined). - ProfileLink: pass role to UserAvatar so admins get the amber ring in the sidebar, matching the "amber ring at every size" intent. - useAuthStatus: share one in-flight /api/v1/auth/status request across the hook's consumers (sidebar Admin/Logout/Profile links) so a page load makes a single call instead of one per consumer; cleared once settled so a later mount (after login/logout) refetches. Verified: tsc, eslint, web node tests (142). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Implements the Profile half of #553: a self-service account page for any
signed-in user. Today a regular user can only see their identity in the
Admin → User Management table, and only if they're an admin — this gives every
user one place to see who they're logged in as, pick an avatar, and sign out.
The Admin → User Management redesign (the other half of #553) will follow as a
separate, independent PR.
Frontend — a new
/profileroute (under the existing(utility)group):(16 icons × 8 colors). Uploads are cropped to a square and resized to 256px
client-side via
<canvas>(which also strips EXIF), keeping the stored filesmall.
UserAvatarcomponent (image → picked icon → deterministic fallbackby username hash). Admins get an amber ring + shield badge, always paired with
an
aria-label/role badge so the cue is never color-only.Backend — no new dependencies:
UserRecordgains an optional, backward-compatibleavatarmarker(
"","icon:<name>:<color>", or"img:<version>"); surfaced on/auth/statusand/auth/users.GET/PUT /api/v1/auth/profile,PUT/DELETE /api/v1/auth/profile/avatar,GET /api/v1/auth/avatar/{user_id}.rejected as a stored-XSS vector), capped at 1 MB, stored on disk under
multi-user/_system/auth/avatars/<user_id>.<ext>with an atomicwrite-then-replace, and served with
nosniff+ private caching. Deleting auser also removes their avatar file.
Related Issues
Module(s) Affected
agentsapiconfigcoreknowledgeloggingservicestoolsutilsweb(Frontend)docs(Documentation)scriptstestsmulti_user(identity store / user model)Checklist
pre-commit run --all-filesand fixed any issues.Additional Notes
Rebased onto the latest
devand verified end-to-end in the Docker build (authenabled): login → Profile link in the sidebar → upload an image, pick an
icon/color, remove photo, and sign out all work. Screenshots below.
Design decisions (answering the open questions in #553):
(utility)group.stored in the user record, with image bytes on disk rather than in the user
JSON.
own record, and
img:markers can only be set via the validated uploadendpoint.
Intentional tradeoffs (happy to change):
/auth/statusnow reads the user store to include the avatar marker so thesidebar avatar needs no extra request — could be cached for very large user
stores.
set_avatartakes the existing users-file write lock; the siblingdelete_user/set_rolehelpers predate it and don't — I left that asymmetryalone to keep the diff scoped, happy to align them.
AUTH_ENABLED=false(default localhost mode) the Profile link is hiddenand the page redirects, matching the existing admin-area behavior.
This is a proposal, not a fixed design. If you disagree with any of it, or want
something added, reworked, split up differently, renamed, or dropped — no problem
at all, I'm happy to discuss and iterate on whatever direction you prefer.
Screenshots