Skip to main content

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

🔍 Click diagram to expand

Session Validation Flow

🔍 Click diagram to expand

User Invitation Flow

🔍 Click diagram to expand

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",
}),
],
});
{
httpOnly: true, // Not accessible via JavaScript
secure: true, // HTTPS only (production)
sameSite: 'lax', // CSRF protection
domain: '.precisionsiteservices.com', // Shared across subdomains
}

User Status States

StatusCan LoginDescription
PENDING_INVITATIONInvited but hasn't accepted
ACTIVECan log in normally
DISABLEDAccount 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

1
Admin Invitation

Admin creates user account with PENDING_INVITATION status and sends invitation email

2
User Accepts

User clicks link, signs in with Google, account status updated to ACTIVE

3
Session Created

HTTP-only cookies set, user redirected to dashboard

Returning User

1
Login

User clicks "Sign in with Google"

2
OAuth Flow

Google authenticates, returns to callback

3
Session Created

SuperTokens creates session, cookies set

Session Expired

1
API Request Fails

Frontend makes request, receives 401 Unauthorized

2
Session Cleared

Frontend clears cookies and state

3
Redirect to Login

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.