--- name: route-map description: Complete HTTP route structure with auth layers, middleware chains, rate limiting, and handler mappings for all API and GUI endpoints. license: MIT --- ## Route Architecture All routes are defined in `cmd/api/main.go`. The server uses Gin with these global middleware applied to all routes: 1. `middleware.SecurityHeadersMiddleware()` -- CSP, HSTS, X-Frame-Options 2. `middleware.CORSMiddleware()` -- CORS headers 3. `middleware.AppIDMiddleware()` -- Extracts `X-App-ID` header (skips `/swagger`, `/admin`, `/gui`) ## Authentication Layers (4 systems) | Layer | Mechanism | Header/Cookie | Middleware | Scope | |-------|-----------|---------------|------------|-------| | User Auth | JWT Bearer | `Authorization: Bearer ` | `AuthMiddleware()` | End-user API routes | | Admin API Key | API key | `X-Admin-API-Key` | `AdminAuthMiddleware(adminRepo)` | `/admin/*` JSON API | | App API Key | API key | `X-App-API-Key` + `X-App-ID` | `AppApiKeyMiddleware(adminRepo)` | `/app/:id/*` routes | | Admin GUI Session | HTTP-only cookie | `admin_session` cookie | `GUIAuthMiddleware(accountService)` | `/gui/*` HTML interface | ## Public Routes (no auth, rate limited) ``` POST /register -> userHandler.Register [APIRegisterRateLimit: 3/min] POST /login -> userHandler.Login [APILoginRateLimit: 5/min, lockout 10->15min] POST /refresh-token -> userHandler.RefreshToken [APIRefreshTokenRateLimit: 10/min] POST /forgot-password -> userHandler.ForgotPassword [APIForgotPasswordRateLimit: 3/min] POST /reset-password -> userHandler.ResetPassword [APIResetPasswordRateLimit: 5/min] GET /verify-email -> userHandler.VerifyEmail POST /resend-verification -> userHandler.ResendVerification [APIResendVerificationRateLimit: 3/min] POST /2fa/login-verify -> twofaHandler.VerifyLogin [API2FAVerifyRateLimit: 5/min, lockout 10->15min] POST /2fa/email/resend -> twofaHandler.ResendEmail2FACode [API2FAVerifyRateLimit] POST /2fa/sms/resend -> twofaHandler.ResendSMS2FACode [API2FAVerifyRateLimit] POST /2fa/backup-email/resend -> twofaHandler.ResendBackupEmail2FACode [API2FAVerifyRateLimit] GET /2fa/backup-email/verify -> twofaHandler.VerifyBackupEmail GET /2fa/methods -> twofaHandler.GetAvailableMethods POST /2fa/passkey/begin -> webauthnHandler.BeginPasskey2FA [APIPasskey2FARateLimit: 10/min] POST /2fa/passkey/finish -> webauthnHandler.FinishPasskey2FA [APIPasskey2FARateLimit] POST /passkey/login/begin -> webauthnHandler.BeginPasswordlessLogin [APIPasskeyLoginRateLimit: 10/min] POST /passkey/login/finish -> webauthnHandler.FinishPasswordlessLogin [APIPasskeyLoginRateLimit] POST /magic-link/request -> userHandler.RequestMagicLink [APIMagicLinkRateLimit: 5/15min] POST /magic-link/verify -> userHandler.VerifyMagicLink [APIMagicLinkRateLimit] GET /health -> healthHandler.Health (no auth) GET /app-config/:app_id -> adminHandler.GetAppLoginConfig (no auth) ``` ## Social OAuth2 Routes (public, no rate limit) ``` GET /auth/google/login -> socialHandler.GoogleLogin GET /auth/google/callback -> socialHandler.GoogleCallback GET /auth/facebook/login -> socialHandler.FacebookLogin GET /auth/facebook/callback -> socialHandler.FacebookCallback GET /auth/github/login -> socialHandler.GithubLogin GET /auth/github/callback -> socialHandler.GithubCallback # Account linking callbacks (public -- user ID in OAuth state param) GET /auth/google/link/callback -> socialHandler.GoogleLinkCallback GET /auth/facebook/link/callback -> socialHandler.FacebookLinkCallback GET /auth/github/link/callback -> socialHandler.GithubLinkCallback ``` ## Account Linking Routes (JWT auth required) ``` GET /auth/google/link -> socialHandler.GoogleLink [AuthMiddleware] GET /auth/facebook/link -> socialHandler.FacebookLink [AuthMiddleware] GET /auth/github/link -> socialHandler.GithubLink [AuthMiddleware] ``` ## Protected User Routes (JWT auth + RBAC permissions) All routes use `AuthMiddleware()`. RBAC permissions shown as `resource:action`. ``` # Profile (user:read, user:write, user:delete) GET /profile -> userHandler.GetProfile [user:read] PUT /profile -> userHandler.UpdateProfile [user:write] DELETE /profile -> userHandler.DeleteAccount [user:delete] PUT /profile/email -> userHandler.UpdateEmail [user:write] PUT /profile/password -> userHandler.UpdatePassword [user:write] # Social accounts (user:read, user:write) GET /profile/social-accounts -> socialHandler.ListSocialAccounts [user:read] DELETE /profile/social-accounts/:id -> socialHandler.UnlinkSocialAccount [user:write] # Auth (no extra permission) GET /auth/validate -> userHandler.ValidateToken POST /logout -> userHandler.Logout # 2FA management (settings:write, settings:read) POST /2fa/generate -> twofaHandler.Generate2FA [settings:write] POST /2fa/verify-setup -> twofaHandler.VerifySetup [settings:write] POST /2fa/enable -> twofaHandler.Enable2FA [settings:write] POST /2fa/disable -> twofaHandler.Disable2FA [settings:write] POST /2fa/recovery-codes -> twofaHandler.GenerateRecoveryCodes [settings:write] POST /2fa/email/enable -> twofaHandler.EnableEmail2FA [settings:write] POST /2fa/sms/enable -> twofaHandler.EnableSMS2FA [settings:write] POST /2fa/backup-email -> twofaHandler.AddBackupEmail [settings:write] DELETE /2fa/backup-email -> twofaHandler.RemoveBackupEmail [settings:write] GET /2fa/backup-email/status -> twofaHandler.BackupEmailStatus [settings:read] POST /2fa/backup-email/enable -> twofaHandler.EnableBackupEmail2FA [settings:write] POST /2fa/backup-email/disable -> twofaHandler.DisableBackupEmail2FA [settings:write] GET /2fa/trusted-devices -> twofaHandler.ListTrustedDevices [settings:read] DELETE /2fa/trusted-devices/:id -> twofaHandler.RevokeTrustedDevice [settings:write] DELETE /2fa/trusted-devices -> twofaHandler.RevokeAllTrustedDevices [settings:write] # Phone / SMS management (settings:write, settings:read) POST /phone -> twofaHandler.AddPhone [settings:write] POST /phone/verify -> twofaHandler.VerifyPhone [settings:write] DELETE /phone -> twofaHandler.RemovePhone [settings:write] GET /phone/status -> twofaHandler.PhoneStatus [settings:read] # Passkey management (settings:write, settings:read) POST /passkey/register/begin -> webauthnHandler.BeginRegistration [settings:write] POST /passkey/register/finish -> webauthnHandler.FinishRegistration [settings:write] GET /passkeys -> webauthnHandler.ListCredentials [settings:read] PUT /passkeys/:id -> webauthnHandler.RenameCredential [settings:write] DELETE /passkeys/:id -> webauthnHandler.DeleteCredential [settings:write] # Activity logs (log:read) GET /activity-logs -> logHandler.GetUserActivityLogs [log:read] GET /activity-logs/event-types -> logHandler.GetEventTypes [log:read] GET /activity-logs/:id -> logHandler.GetActivityLogByID [log:read] GET /activity-logs/export -> logHandler.ExportUserActivityLogs [log:read] # Sessions (no extra permission) GET /sessions -> sessionHandler.ListSessions DELETE /sessions/:id -> sessionHandler.RevokeSession DELETE /sessions -> sessionHandler.RevokeAllSessions ``` ## Admin API Routes (Admin API Key auth) All routes use `AdminAuthMiddleware(adminRepo)`. Header: `X-Admin-API-Key`. ``` # Metrics (Admin API Key required) GET /metrics -> healthHandler.Metrics # Activity logs GET /admin/activity-logs -> logHandler.GetAllActivityLogs GET /admin/activity-logs/export -> logHandler.ExportAllActivityLogs # Tenants POST /admin/tenants -> adminHandler.CreateTenant GET /admin/tenants -> adminHandler.ListTenants # Applications POST /admin/apps -> adminHandler.CreateApp GET /admin/apps/:id -> adminHandler.GetAppDetails POST /admin/apps/:id/oauth-config -> adminHandler.UpsertOAuthConfig # IP Rules (per-app) GET /admin/apps/:id/ip-rules -> adminHandler.ListIPRules POST /admin/apps/:id/ip-rules -> adminHandler.CreateIPRule GET /admin/apps/:id/ip-rules/:rule_id -> adminHandler.GetIPRule PUT /admin/apps/:id/ip-rules/:rule_id -> adminHandler.UpdateIPRule DELETE /admin/apps/:id/ip-rules/:rule_id -> adminHandler.DeleteIPRule POST /admin/apps/:id/ip-rules/check -> adminHandler.CheckIPAccess # User import/export GET /admin/users/export -> adminHandler.ExportUsers POST /admin/users/import -> adminHandler.ImportUsers # Trusted devices (admin) GET /admin/users/:id/trusted-devices -> adminHandler.ListUserTrustedDevices DELETE /admin/users/:id/trusted-devices -> adminHandler.RevokeAllUserTrustedDevices # Webhooks GET /admin/webhooks -> webhookHandler.AdminListEndpoints GET /admin/webhooks/apps/:app_id -> webhookHandler.AdminListEndpointsByApp POST /admin/webhooks/apps/:app_id -> webhookHandler.AdminCreateEndpoint PUT /admin/webhooks/:id/toggle -> webhookHandler.AdminToggleEndpoint DELETE /admin/webhooks/:id -> webhookHandler.AdminDeleteEndpoint GET /admin/webhooks/:id/deliveries -> webhookHandler.AdminListDeliveriesByEndpoint GET /admin/webhooks/apps/:app_id/deliveries -> webhookHandler.AdminListDeliveriesByApp # OIDC client management POST /admin/oidc/apps/:id/clients -> oidcHandler.AdminCreateClient GET /admin/oidc/apps/:id/clients -> oidcHandler.AdminListClients GET /admin/oidc/apps/:id/clients/:cid -> oidcHandler.AdminGetClient PUT /admin/oidc/apps/:id/clients/:cid -> oidcHandler.AdminUpdateClient DELETE /admin/oidc/apps/:id/clients/:cid -> oidcHandler.AdminDeleteClient POST /admin/oidc/apps/:id/clients/:cid/rotate-secret -> oidcHandler.AdminRotateClientSecret # Email types GET /admin/email-types -> adminHandler.ListEmailTypes GET /admin/email-types/:code -> adminHandler.GetEmailType POST /admin/email-types -> adminHandler.CreateEmailType PUT /admin/email-types/:id -> adminHandler.UpdateEmailType DELETE /admin/email-types/:id -> adminHandler.DeleteEmailType # Email templates GET /admin/email-templates -> adminHandler.ListEmailTemplates GET /admin/email-templates/:id -> adminHandler.GetEmailTemplate POST /admin/email-templates -> adminHandler.SaveEmailTemplate DELETE /admin/email-templates/:id -> adminHandler.DeleteEmailTemplate POST /admin/email-templates/preview -> adminHandler.PreviewEmailTemplate # Email variables GET /admin/email-variables -> adminHandler.ListWellKnownVariables # Email server configs (per-app) GET /admin/apps/:id/email-config -> adminHandler.GetEmailServerConfig PUT /admin/apps/:id/email-config -> adminHandler.SaveEmailServerConfig DELETE /admin/apps/:id/email-config -> adminHandler.DeleteEmailServerConfig POST /admin/apps/:id/email-test -> adminHandler.SendTestEmail GET /admin/apps/:id/email-servers -> adminHandler.ListEmailServerConfigsByApp # Email server configs (global CRUD) GET /admin/email-servers -> adminHandler.ListAllEmailServerConfigs GET /admin/email-servers/:id -> adminHandler.GetEmailServerConfigByID POST /admin/email-servers -> adminHandler.CreateEmailServerConfig PUT /admin/email-servers/:id -> adminHandler.UpdateEmailServerConfigByID DELETE /admin/email-servers/:id -> adminHandler.DeleteEmailServerConfigByID POST /admin/email-servers/:id/test -> adminHandler.SendTestEmailByConfigID # Send email POST /admin/apps/:id/send-email -> adminHandler.SendCustomEmail # RBAC GET /admin/rbac/roles -> rbacHandler.ListRoles GET /admin/rbac/roles/:id -> rbacHandler.GetRole POST /admin/rbac/roles -> rbacHandler.CreateRole PUT /admin/rbac/roles/:id -> rbacHandler.UpdateRole DELETE /admin/rbac/roles/:id -> rbacHandler.DeleteRole PUT /admin/rbac/roles/:id/permissions -> rbacHandler.SetRolePermissions GET /admin/rbac/permissions -> rbacHandler.ListPermissions POST /admin/rbac/permissions -> rbacHandler.CreatePermission GET /admin/rbac/user-roles -> rbacHandler.ListUserRoles POST /admin/rbac/user-roles -> rbacHandler.AssignRole DELETE /admin/rbac/user-roles -> rbacHandler.RevokeRole GET /admin/rbac/user-roles/user -> rbacHandler.GetUserRoles ``` ## App API Routes (Per-App API Key auth) Middleware chain: `AppApiKeyMiddleware(adminRepo)` + `AppRouteGuardMiddleware()`. Headers: `X-App-API-Key` + `X-App-ID` (must match `:id` in URL). ``` GET /app/:id/email-config -> adminHandler.GetEmailServerConfig GET /app/:id/email-servers -> adminHandler.ListEmailServerConfigsByApp POST /app/:id/email-test -> adminHandler.SendTestEmail POST /app/:id/send-email -> adminHandler.SendCustomEmail # Webhooks (App API Key) GET /app/:id/webhooks -> webhookHandler.AppListEndpoints POST /app/:id/webhooks -> webhookHandler.AppCreateEndpoint PUT /app/:id/webhooks/:wid/toggle -> webhookHandler.AppToggleEndpoint DELETE /app/:id/webhooks/:wid -> webhookHandler.AppDeleteEndpoint GET /app/:id/webhooks/:wid/deliveries -> webhookHandler.AppListDeliveries ``` ## OIDC Provider Routes (opt-in, requires OIDC_ENABLED on application) ``` GET /.well-known/openid-configuration -> redirect to /oidc/:app_id/.well-known/openid-configuration GET /oidc/:app_id/.well-known/openid-configuration -> oidcHandler.WellKnownConfiguration GET /oidc/:app_id/.well-known/jwks.json -> oidcHandler.JWKS GET /oidc/:app_id/authorize -> oidcHandler.Authorize [OIDCAuthorizeRateLimit] POST /oidc/:app_id/authorize -> oidcHandler.AuthorizeSubmit [OIDCAuthorizeRateLimit] POST /oidc/:app_id/token -> oidcHandler.Token [OIDCTokenRateLimit] GET /oidc/:app_id/userinfo -> oidcHandler.UserInfo [OIDCUserInfoRateLimit] POST /oidc/:app_id/userinfo -> oidcHandler.UserInfo [OIDCUserInfoRateLimit] POST /oidc/:app_id/introspect -> oidcHandler.Introspect [OIDCIntrospectRateLimit] POST /oidc/:app_id/revoke -> oidcHandler.Revoke [OIDCRevokeRateLimit] GET /oidc/:app_id/end_session -> oidcHandler.EndSession POST /oidc/:app_id/end_session -> oidcHandler.EndSession ``` ## GUI Routes (Admin Web Interface) Static assets and login pages are public. Authenticated routes use `GUIAuthMiddleware` + `CSRFMiddleware`. ### Public GUI routes ``` GET /gui/static/* -> static.HTTPFileSystem() GET /gui/login -> guiHandler.LoginPage POST /gui/login -> guiHandler.LoginSubmit [LoginRateLimit: 5/min] POST /gui/passkey-login/begin -> guiHandler.PasskeyLoginBegin [GUIPasskeyLoginRateLimit: 10/min] POST /gui/passkey-login/finish -> guiHandler.PasskeyLoginFinish [GUIPasskeyLoginRateLimit] POST /gui/magic-link-login -> guiHandler.MagicLinkLoginRequest [GUIMagicLinkRateLimit: 3/15min] GET /gui/magic-link-login/verify -> guiHandler.MagicLinkLoginVerify GET /gui/2fa-verify -> guiHandler.TwoFAVerifyPage POST /gui/2fa-verify -> guiHandler.TwoFAVerifySubmit POST /gui/2fa-resend-email -> guiHandler.TwoFAResendEmail ``` ### Authenticated GUI routes (cookie session + CSRF) Covers: Dashboard, Tenants, Applications, OAuth, Users (with export/import, trusted device management), Logs (with CSV export), API Keys (with scope config and usage stats), Settings, Email Servers, Email Templates, Email Types, Roles, Permissions, User Roles, Sessions, Webhooks, OIDC Clients, IP Rules, Monitoring, My Account (email, password, 2FA, passkeys, magic link, backup email, trusted devices), Social Account/Passkey management for users. Each entity follows the HTMX CRUD pattern: ``` GET /gui/ -> Page (full page) GET /gui//list -> List (HTMX partial, paginated) GET /gui//new -> CreateForm (HTMX partial) POST /gui/ -> Create GET /gui//form-cancel -> FormCancel (HTMX partial) GET /gui//:id/edit -> EditForm (HTMX partial) PUT /gui//:id -> Update GET /gui//:id/delete -> DeleteConfirm (HTMX partial) DELETE /gui//:id -> Delete ``` ## Rate Limiting Summary | Endpoint Group | Prefix | Limit | Window | Lockout | |----------------|--------|-------|--------|---------| | GUI Login | `gui:login` | 5/min | 60s | 10 attempts -> 15min lockout | | API Login | `api:login` | 5/min | 60s | 10 -> 15min | | API Register | `api:register` | 3/min | 60s | none | | API Forgot Password | `api:forgot-password` | 3/min | 60s | none | | API Resend Verification | `api:resend-verification` | 3/min | 60s | none | | API Refresh Token | `api:refresh-token` | 10/min | 60s | none | | API Reset Password | `api:reset-password` | 5/min | 60s | none | | API 2FA Verify | `api:2fa-verify` | 5/min | 60s | 10 -> 15min | | API Passkey Login | `api:passkey-login` | 10/min | 60s | 20 -> 15min | | API Passkey 2FA | `api:passkey-2fa` | 10/min | 60s | 20 -> 15min | | API Magic Link | `api:magic-link` | 5/15min | 15min | none | | GUI Magic Link | `gui:magic-link` | 3/15min | 15min | none | | GUI Passkey Login | `gui:passkey-login` | 10/min | 60s | 20 -> 15min | | OIDC Authorize | `oidc:authorize` | 20/min | 60s | none | | OIDC Token | `oidc:token` | 30/min | 60s | none | | OIDC UserInfo | `oidc:userinfo` | 60/min | 60s | none | | OIDC Introspect | `oidc:introspect` | 30/min | 60s | none | | OIDC Revoke | `oidc:revoke` | 30/min | 60s | none | ## When To Use This Skill Load this skill when working on API endpoints, adding new routes, modifying middleware chains, changing rate limits, or debugging request flows.