Authentication Flow
Overview
ForgeX uses SuperTokens with Google OAuth for authentication. The system enforces invitation-based access - users cannot self-register.
Architecture
┌─────────────────┐ ┌─ ─────────────────┐ ┌─────────────────┐
│ Portal/Bids │────▶│ Bids Backend │────▶│ SuperTokens │
│ Frontend │ │ (Express) │ │ Core │
│ │ │ │ │ │
│ SuperTokens │ │ SuperTokens │ │ PostgreSQL │
│ Auth React │ │ Node SDK │ │ (sessions) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ User Table │
│ (bids_db) │
└─────────────────┘
Main Authentication Flow
Session Validation Flow
User Invitation Flow
Key Implementation Details
SuperTokens Configuration
supertokens.init({
appInfo: {
apiDomain: process.env.API_DOMAIN, // MUST match production URL
websiteDomain: process.env.WEBSITE_DOMAIN, // MUST match production URL
apiBasePath: "/api/auth",
},
recipeList: [
ThirdParty.init({
override: {
functions: (original) => ({
signInUp: async (input) => {
// Custom logic: Check User table
// Validate status is ACTIVE
// Update supertokensId
},
}),
},
}),
Session.init({
cookieSecure: process.env.NODE_ENV === "production",
}),
],
});
Session Cookie Configuration
{
httpOnly: true, // Not accessible via JavaScript
secure: true, // HTTPS only (production)
sameSite: 'lax', // CSRF protection
domain: '.precisionsiteservices.com', // Shared across subdomains
}
User Status States
| Status | Can Login | Description |
|---|---|---|
PENDING_INVITATION | ❌ | Invited but hasn't accepted |
ACTIVE | ✅ | Can log in normally |
DISABLED | ❌ | Account disabled by admin |
Environment Variables
Backend (Required)
SUPERTOKENS_CONNECTION_URI=https://supertokens.example.com
API_DOMAIN=https://api.precisionsiteservices.com
WEBSITE_DOMAIN=https://portal.precisionsiteservices.com
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
Frontend (Required)
VITE_API_URL=https://api.precisionsiteservices.com
VITE_GOOGLE_CLIENT_ID=your-client-id
Security Features
HTTP-Only Cookies
Session tokens not accessible via JavaScript (XSS protection)
Secure Cookies
HTTPS only in production
SameSite Protection
Prevents CSRF attacks
Invitation-Based
No self-registration - admin must invite
Status Validation
Disabled/pending accounts cannot authenticate
Token Expiration
Sessions expire, requiring re-authentication
Common Flows
First-Time User
Admin creates user account with PENDING_INVITATION status and sends invitation email
User clicks link, signs in with Google, account status updated to ACTIVE
HTTP-only cookies set, user redirected to dashboard
Returning User
User clicks "Sign in with Google"
Google authenticates, returns to callback
SuperTokens creates session, cookies set
Session Expired
Frontend makes request, receives 401 Unauthorized
Frontend clears cookies and state
User redirected to login page
Troubleshooting
Session expired error
Sessions expire after inactivity. User must log in again via Google OAuth.
Wrong Google account
User must sign in with the same Google account that received the invitation.
Invitation expired
Admin must resend invitation via /api/admin/users/:id/resend-invite.
No account found
User must receive invitation from admin before logging in.
CORS errors
Ensure API_DOMAIN and WEBSITE_DOMAIN are correctly configured and match production URLs.
Related Resources
- Authentication API
- User Management
- Database ERD