Feature: Password reset flow via Gmail OAuth (bypass Keycloak SMTP) #132
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/basketball-api#132
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
plan-wkq→ Phase 11 (Girls Tryout — March 24)Supersedes basketball-api #131 (Keycloak SMTP not configured)
Repo
forgejo_admin/basketball-api(backend) +forgejo_admin/westside-app(frontend)User Story
As a player/parent
I want to reset my password via email
So that I can regain access to my account without contacting an admin
Context
Keycloak's built-in "Forgot Password?" flow requires SMTP, which it doesn't support via OAuth. Our platform uses Gmail OAuth exclusively (westsidebasketball@gmail.com) — no app passwords, no SendGrid. Rather than fight Keycloak's SMTP limitation, we bypass it entirely: basketball-api generates the reset token via Keycloak admin API and sends the email through the existing Gmail OAuth pipeline. Single email path, single auth mechanism.
The existing Gmail OAuth tokens are in k8s secret
gmail-oauth-westsidebasketballin thebasketball-apinamespace. The email service (services/email.py) already sends registration confirmations, roster exports, and tryout announcements through this pipeline.File Targets
basketball-api:
src/basketball_api/routes/password_reset.py— new router with two endpointssrc/basketball_api/services/email.py— addsend_password_reset_email()functionsrc/basketball_api/main.py— register the new routertests/test_password_reset.py— new test filewestside-app:
src/routes/forgot-password/+page.svelte— new page, email input formsrc/routes/reset-password/+page.svelte— new page, new password form (reads token from query param)src/routes/+layout.svelte— add/forgot-passwordand/reset-passwordto PUBLIC_ROUTESFiles NOT to touch:
Acceptance Criteria
POST /api/password-reset/requestaccepts{email}, generates a time-limited reset token, stores it, sends reset link via Gmail OAuth to the player's emailPOST /api/password-reset/confirmaccepts{token, new_password}, validates token, calls Keycloak admin API to set the new password/forgot-passwordpage: enter email → "check your email" confirmation/reset-password?token=Xpage: enter new password → success → redirect to signinwestsidebasketball@gmail.comwith "Westside Kings & Queens" display nameTest Expectations
pytest tests/test_password_reset.pyConstraints
services/email.py— no new auth mechanismsChecklist
Related
feedback_gmail_oauth_not_smtp.md— all email = Gmail OAuth, no exceptionsgmail-oauth-westsidebasketball— existing OAuth tokenssrc/basketball_api/services/email.py— existing email service to extend