Skip to content

fix(profiles): restore admin ability to edit other users' profiles - #338

Merged
jinglemansweep merged 1 commit into
mainfrom
fix/admin-profile-edit
Jul 24, 2026
Merged

fix(profiles): restore admin ability to edit other users' profiles#338
jinglemansweep merged 1 commit into
mainfrom
fix/admin-profile-edit

Conversation

@jinglemansweep

Copy link
Copy Markdown
Contributor

Summary

Fixes a regression from d37b30a where admins lost the ability to edit other users' profiles. The update_profile endpoint used RequireUserOwner (returns only user_id, no role info) and blocked all non-owner edits with 403 — no admin bypass existed despite the docstring claiming "Only the owner or admin can update."

Changes

Backend — api/routes/user_profiles.py

  • Import X_USER_ROLES_HEADER from auth.py
  • In update_profile, read roles from the request header and bypass the ownership check when the admin role is present (same pattern as node_tags.py:48-51 and routes.py:112)
  • RequireUserOwner stays as the dependency — regular members editing their own profiles are unaffected

Frontend — pages/Profile.tsx

  • Extracted ProfileEditForm component from OwnProfileView (with data-testids: profile-form, profile-name, profile-callsign, profile-description, profile-url, profile-save)
  • PublicProfileView now shows an inline edit form when an admin (hasRole("admin")) views another user's profile (!isOwner)
  • Owner still sees the existing edit link; non-admins see nothing
  • Cancel button (profile-admin-cancel) exits edit mode

Tests

Layer Tests What
Backend test_update_profile_admin_can_edit_other Admin headers editing other user's profile → 200 + all fields updated
Vitest (4 new) admin button visibility Admin sees button, non-admin doesn't, owner sees link not admin button
Vitest form submission apiPut called with /api/v1/user/profile/p1 + correct body
E2E (new spec) admin-profile-edit.spec.ts Admin edits Mem South's callsign, verifies persistence; admin on own profile sees no admin button
E2E members.spec.ts Negative: member viewing another profile sees no admin edit button

All: 34 backend / 335 frontend / pre-commit clean / e2e typecheck clean.

The update_profile endpoint used RequireUserOwner which returns only the
caller's user_id — no role information. The ownership check blocked ALL
non-owner edits with 403, including admins. This regressed in d37b30a
when the old Member model (RequireAdmin) was replaced with UserProfile.

Backend: read X-User-Roles header directly in update_profile (same
pattern as node_tags.py / routes.py) and bypass the ownership check when
the admin role is present. Regular members editing their own profiles
are unaffected — RequireUserOwner stays as the dependency.

Frontend: extract ProfileEditForm component (with data-testids) from
OwnProfileView. PublicProfileView now shows an inline edit form when an
admin views another user's profile. Owner still gets the existing edit
link; non-admins see nothing.

Tests:
- Backend: test_update_profile_admin_can_edit_other (admin edits other
  user's profile, asserts 200 + all fields updated)
- Vitest: 4 new tests — admin button visibility, non-admin hidden,
  owner link vs admin button, form submission to correct endpoint
- E2E: admin-profile-edit.spec.ts (admin edits Mem South's profile,
  verifies persistence; admin on own profile sees no admin button);
  members.spec.ts negative assertion (member sees no admin button)
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@jinglemansweep
jinglemansweep merged commit e0c1a67 into main Jul 24, 2026
5 checks passed
@jinglemansweep
jinglemansweep deleted the fix/admin-profile-edit branch July 24, 2026 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant