Skip to content

Historical snapshot archived 2026-09-25. This records an earlier review or plan, not current implementation or live ticket state. For current work, follow root AGENTS.md, the relevant BloxClips skill, and owning repository source/tests. Preserve approved decisions as evidence; verify their present authority before acting.

Authentication and Authorization ​

Authentication ​

Login flow ​

mermaid
sequenceDiagram
    actor U as User
    participant F as Frontend /login
    participant B as Backend auth router
    participant P as Discord or Google
    participant D as PostgreSQL
    U->>F: choose provider
    F->>B: GET OAuth initiation
    B->>P: redirect with state + callback
    P->>B: callback authorization code
    B->>P: exchange code / fetch profile
    B->>D: upsert AuthAccount + WebUser
    B-->>F: set HTTP-only auth_token and redirect
    F->>B: GET /api/auth/me with cookie
    B->>D: verify jwtVersion and ban state
    B-->>F: current user

OAuth state is stored in an HTTP-only, same-site cookie and can carry only a dashboard-relative return path. Discord and Google provider tokens are encrypted before persistence. Google’s verified provider email may be used to merge/link an existing verified-email user; Discord starts without verified email unless separately verified.

The backend signs a seven-day JWT and places it in the HTTP-only auth_token cookie (Secure in production, SameSite=Lax). The token contains the WebUser ID and jwtVersion. requireAuth validates the signature, checks that the database revocation version still matches, resolves user context, and rejects active bans. Logout clears the cookie; “revoke all” increments jwtVersion.

The frontend does not read the token. app/dashboard/layout.tsx calls /api/auth/me with credentials and exposes the returned user through AuthContext.

Onboarding and social verification ​

Authentication and onboarding are separate. New users complete profile fields and referral attribution through /api/onboarding; onboardingCompletedAt records completion. Social account ownership is another separate bio-code verification, producing LinkedSocialAccount records used during submission creation.

Email verification endpoints and UI exist. However, the EmailGate wrappers in submission/payout UI and corresponding backend action checks are commented out. Email verification is therefore not currently confirmed as an enforcement gate.

Authorization ​

Backend enforcement ​

BoundaryEnforcement
Authenticated creator APIsrequireAuth middleware
Administrator APIsrequireAuth followed by requireAdmin
Admin identityDiscord ID in ADMIN_DISCORD_IDS, or verified email in ADMIN_EMAILS
Payout/tax-sensitive actionsadmin middleware plus requireTOTP on selected routes
User-owned resourcesrouters query with resolved webUserId/legacy Discord ID; inspect each domain because ownership patterns are not centralized in policies
Banned identitiesactive ban check on authenticated requests; identity blacklist also affects account/profile reuse

There is no separate policy/ability framework. Authorization is expressed by middleware placement and query predicates inside routers. When adding or changing an endpoint, copy neither a neighboring mount nor frontend visibility blindly—trace the router’s actual middleware and ownership filter.

UI visibility versus security ​

  • Admin sidebar/routes are hidden or redirected by frontend checks.
  • Every traced admin backend router also enforces admin middleware; this is the actual security boundary.
  • Creator button visibility such as canSubmit, payout eligibility displays, or disabled controls is usability guidance. Backend validation must independently enforce the rule.

Current dashboard mismatch ​

app/dashboard/layout.tsx always calls /api/admin/check and redirects non-admins away from the entire dashboard. This affects creator overview, campaigns, submission, payout, and profile pages. The backend counterparts generally require only an authenticated creator. Onboarding redirects toward /dashboard, making intent ambiguous. Confirm expected product access with the prior team before modifying this gate.

CSRF and browser boundaries ​

There is no synchronizer CSRF token. The API configures credentialed CORS, same-site cookies, JSON-only body parsing, and a production guard that rejects state-changing requests without an approved Origin (payment webhooks are handled separately). This is a layered browser defense, but any new route/middleware order must preserve it.

Ambiguities and cautions ​

  • Legacy userId often means Discord ID; newer ownership uses webUserId. Mixed fallback queries can broaden or narrow access unexpectedly.
  • Verified Google email can carry admin status if listed; the exact operational ownership of ADMIN_EMAILS is outside the repo.
  • GuildConfig.managerRole and Discord permission helpers authorize bot commands, separate from website admin allowlists.
  • The source contains TOS acceptance UI/state, but the dashboard’s non-admin branch makes some intended creator behavior unreachable.
  • No automated authorization regression suite was found.