fix: auto-login after signup and context-aware token clearing
This fixes the "Authorization header required for API calls" error during vendor onboarding after signup. Changes: - Generate JWT access token on signup completion - Set vendor_token cookie for page navigation - Return access_token in signup response for localStorage - Store vendor_token in localStorage after signup completion - Make clearTokens() context-aware to prevent cross-portal interference - Fix vendor logout to not clear admin/customer tokens 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,11 +14,12 @@ All endpoints are public (no authentication required).
|
||||
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, Response
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.environment import should_use_secure_cookies
|
||||
from app.services.platform_signup_service import platform_signup_service
|
||||
|
||||
router = APIRouter()
|
||||
@@ -111,6 +112,7 @@ class CompleteSignupResponse(BaseModel):
|
||||
vendor_id: int
|
||||
redirect_url: str
|
||||
trial_ends_at: str
|
||||
access_token: str | None = None # JWT token for automatic login
|
||||
|
||||
|
||||
# =============================================================================
|
||||
@@ -215,12 +217,14 @@ async def setup_payment(request: SetupPaymentRequest) -> SetupPaymentResponse:
|
||||
@router.post("/signup/complete", response_model=CompleteSignupResponse) # public
|
||||
async def complete_signup(
|
||||
request: CompleteSignupRequest,
|
||||
response: Response,
|
||||
db: Session = Depends(get_db),
|
||||
) -> CompleteSignupResponse:
|
||||
"""
|
||||
Complete signup after card collection.
|
||||
|
||||
Step 5: Verify SetupIntent, attach payment method, create subscription.
|
||||
Also sets HTTP-only cookie for page navigation and returns token for localStorage.
|
||||
"""
|
||||
result = platform_signup_service.complete_signup(
|
||||
db=db,
|
||||
@@ -228,12 +232,27 @@ async def complete_signup(
|
||||
setup_intent_id=request.setup_intent_id,
|
||||
)
|
||||
|
||||
# Set HTTP-only cookie for page navigation (same as login does)
|
||||
# This enables the user to access vendor pages immediately after signup
|
||||
if result.access_token:
|
||||
response.set_cookie(
|
||||
key="vendor_token",
|
||||
value=result.access_token,
|
||||
httponly=True, # JavaScript cannot access (XSS protection)
|
||||
secure=should_use_secure_cookies(), # HTTPS only in production/staging
|
||||
samesite="lax", # CSRF protection
|
||||
max_age=3600 * 24, # 24 hours
|
||||
path="/vendor", # RESTRICTED TO VENDOR ROUTES ONLY
|
||||
)
|
||||
logger.info(f"Set vendor_token cookie for new vendor {result.vendor_code}")
|
||||
|
||||
return CompleteSignupResponse(
|
||||
success=result.success,
|
||||
vendor_code=result.vendor_code,
|
||||
vendor_id=result.vendor_id,
|
||||
redirect_url=result.redirect_url,
|
||||
trial_ends_at=result.trial_ends_at,
|
||||
access_token=result.access_token,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user