feat(workspace): wire reset-password into members Actions menu (#2572) - #5507
feat(workspace): wire reset-password into members Actions menu (#2572)#5507AJ-ing wants to merge 3 commits into
Conversation
Expose the existing GenerateResetLinkModal / PasswordResetLinkModal from the workspace members Actions dropdown and call POST /api/profile/reset-password. Permission-gated via invite/role-modify rights. Addresses Agenta-AI#2572 (prior Agenta-AI#4561 was closed for missing demo/template). Co-authored-by: Cursor <cursoragent@cursor.com>
|
@AJ-ing is attempting to deploy a commit to the agenta projects Team on Vercel. A member of the Team first needs to authorize it. |
|
✅ Thanks @AJ-ing! This PR now meets the contribution requirements and has been reopened. A maintainer will review it soon. |
📝 WalkthroughWalkthroughWorkspace member actions now support generating password reset links for active members with permission. The UI calls a new profile service endpoint, manages loading and errors, and displays confirmation and generated-link modals. ChangesWorkspace password reset
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant WorkspaceUser
participant MemberActions
participant GenerateResetLinkModal
participant ProfileService
participant ResetPasswordAPI
participant PasswordResetLinkModal
WorkspaceUser->>MemberActions: Select Reset password
MemberActions->>GenerateResetLinkModal: Open confirmation
WorkspaceUser->>GenerateResetLinkModal: Confirm reset
GenerateResetLinkModal->>MemberActions: Invoke reset handler
MemberActions->>ProfileService: resetPassword(user.id)
ProfileService->>ResetPasswordAPI: POST reset-password with user_id
ResetPasswordAPI-->>ProfileService: Return reset link
ProfileService-->>MemberActions: Return reset link
MemberActions->>PasswordResetLinkModal: Open with generated link
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@AJ-ing editing the PR to include the demo will reopen it automatically |
Demo artifact for Agenta-AI#2572 / PR contribution check (members Actions → confirm modal → generated reset link modal). Co-authored-by: Cursor <cursoragent@cursor.com>
|
Updated the PR description with a demo screenshot of the UI flow (Actions menu → confirmation → generated reset link): @mmabrouk — please let me know if you prefer a full local-stack screen recording as well; happy to add one once I finish the Docker/dev setup. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx (1)
215-221: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winKeep the confirmation modal open until the reset request completes.
GenerateResetLinkModalinvokesonOkand immediately invokesonCancel. With this wiring, the modal closes beforeresetPasswordresolves, soconfirmLoadingis not visible and failures remove the confirmation dialog before the user can retry. Let the parent close it only after success, or make the modal awaitonOk.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1e5d6e6f-8932-4ba8-8b15-3b0b658838a1
⛔ Files ignored due to path filters (1)
docs/demos/2572-reset-password-demo.pngis excluded by!**/*.png
📒 Files selected for processing (2)
web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsxweb/oss/src/services/profile/index.ts
| /** | ||
| * Generate a password reset link for a workspace member (admin action). | ||
| * Calls POST /api/profile/reset-password?user_id=... | ||
| */ | ||
| export const resetPassword = async (userId: string): Promise<string> => { | ||
| const base = getBaseUrl() | ||
| const url = new URL("api/profile/reset-password", base) | ||
| url.searchParams.set("user_id", userId) | ||
| return fetchJson<string>(url, { | ||
| method: "POST", | ||
| }) | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate files =="
fd 'index\.ts$' . | sed -n '1,80p' | rg 'web/oss/src/services/profile|resources|profile' || true
echo "== profile service excerpt =="
if [ -f web/oss/src/services/profile/index.ts ]; then
wc -l web/oss/src/services/profile/index.ts
sed -n '1,140p' web/oss/src/services/profile/index.ts | cat -n
fi
echo "== search resetPassword usages =="
rg -n "resetPassword|reset-password" web -S || true
echo "== profile Fern accessors/resources relevant symbols =="
rg -n "profile|Profile|resetPassword|queryParams|safeParseWithLogging|reset-password|fetchJson" web/packages/agenta-sdk web -S --glob '*.ts' --glob '*.tsx' | sed -n '1,220p' || true
echo "== package script / lint config if available =="
fd 'package\.json|eslint|prettier|AGENTS\.md' . | sed -n '1,60p'Repository: Agenta-AI/agenta
Length of output: 29422
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== generated users reset-password excerpt =="
sed -n '210,300p' web/packages/agenta-api-client/src/generated/api/resources/users/client/Client.ts | cat -n || true
echo "== search resetPassword in generated package =="
rg -n "resetPassword|ResetPassword|reset-password|safeParseWithLogging|queryParams" web/packages/agenta-api-client -S --glob '*.ts' || true
echo "== referenced SDK resource/profile excerpts if present =="
if [ -f web/packages/agenta-sdk/src/resources/users.ts ]; then
echo "== users.ts resetPassword? =="
rg -n "resetPassword|ResetPassword|reset-password|queryParams" web/packages/agenta-sdk/src/resources/users.ts -S || true
fi
echo "== use the cell renderer excerpt =="
sed -n '90,125p' web/oss/src/pages/settings/cellRenderers.tsx 2>/dev/null || sed -n '90,125p' web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx | cat -n
echo "== AST/text check resetPassword generic at string type only =="
python3 - <<'PY'
from pathlib import Path
p = Path('web/oss/src/services/profile/index.ts')
text = p.read_text()
start = text.index('export const resetPassword')
end = text.index('\n\n/**', start)
snippet = text[start:end]
print(snippet)
print("uses fetchJson<string>:", "fetchJson<string>" in snippet)
print("uses queryParams:", "queryParams" in snippet)
print("imports safeParseWithLogging:", "safeParseWithLogging" in p.read_text())
PYRepository: Agenta-AI/agenta
Length of output: 50372
Use the generated users.resetUserPassword accessor and validate the response.
The generated client already exposes resetUserPassword({ user_id }); use that Fern-style accessor instead of a manual new URL(...)?user_id=... request. Since the generated response remains unknown, validate the reset link with Zod and safeParseWithLogging before returning it to the UI so malformed JSON cannot be displayed as [object Object].
Source: Coding guidelines
|
Hey @AJ-ing please live qa this within agenta not outside of it like now done. You need to set agenta locally in dev mode. Let me know if you are able to |
|
Quick question on community channels: the Slack invite in README/CONTRIBUTING appears expired on my side. Is there an active invite, or another preferred channel for contributor questions? |
|
@mmabrouk Live QA recorded from local OSS dev stack (Docker compose, branch feat/workspace-reset-password): Flow: Settings → Workspace → Members → Actions (⋯) → Reset password → confirm → generated link modal. Tested on http://localhost with two workspace members. CLA signed. Screen.Recording.2026-07-26.at.7.17.11.PM.mov |

Summary
Wires the existing password-reset modals into the workspace members Actions dropdown so admins can generate a reset link for a member.
resetPassword(userId)inweb/oss/src/services/profile/index.ts→POST /api/profile/reset-password?user_id=...GenerateResetLinkModal+PasswordResetLinkModalalready in the codebaseFixes #2572
Testing
canInviteMembers || canModifyRolesDemo
Screenshot of the implemented UI flow:
Direct file in PR:
docs/demos/2572-reset-password-demo.pngChecklist