feat(tenancy): add team invitation acceptance page
Some checks failed
Some checks failed
New standalone page at /store/{store_code}/invitation/accept?token=xxx
where invited team members can:
- Review their name and email (pre-filled from invitation)
- Set their password
- Accept the invitation
Page handles all routing modes (dev path, platform path, prod subdomain,
custom domain) via store context middleware. After acceptance, redirects
to the platform-aware store login page.
New service method get_invitation_info() validates the token and returns
invitation details without modifying anything.
Error states: expired token, already accepted, invalid token.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ Store pages for authentication and account management:
|
||||
- Settings
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi import APIRouter, Depends, Query, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -100,6 +100,43 @@ async def store_login_page(
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/invitation/accept", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def store_invitation_accept_page(
|
||||
request: Request,
|
||||
token: str = Query(..., description="Invitation token from email"),
|
||||
store_code: str = Depends(get_resolved_store_code),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render invitation acceptance page.
|
||||
|
||||
Public route — no auth required. Validates the token and shows a form
|
||||
to review name and set password.
|
||||
"""
|
||||
from app.modules.tenancy.services.store_team_service import store_team_service
|
||||
|
||||
language = getattr(request.state, "language", "en")
|
||||
platform_code = getattr(request.state, "platform_code", None)
|
||||
|
||||
# Get invitation info (without accepting it)
|
||||
info = store_team_service.get_invitation_info(db, token)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"tenancy/store/invitation-accept.html",
|
||||
{
|
||||
"request": request,
|
||||
"store_code": store_code,
|
||||
"platform_code": platform_code,
|
||||
"frontend_type": "store",
|
||||
"token": token,
|
||||
"invitation": info,
|
||||
**get_jinja2_globals(language),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# AUTHENTICATED ROUTES (Store Users Only)
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user