Authentication
Overview
CommonPlace uses an invite-code-gated authentication system built on Supabase Auth. New users can only create accounts if they have a valid invite code, which is shared by existing members. This gating mechanism ensures that the platform grows through genuine social connections rather than open registration, supporting the human-scale social context that CommonPlace values.
The authentication flow is intentionally simple: email and password with an invite code for registration. There are no social login providers (Google, Facebook, etc.), no phone number verification, and no complex onboarding funnels. The UI presents a clean, calm interface with a toggle between sign-in and sign-up modes.
After account creation, a database trigger automatically creates the user's profile record, seeding it with the display name provided during registration.
Relevant Invariants
- Invariant #7: "Human-Scale Social Contexts" -- Invite codes ensure growth happens through personal connections, not viral mechanisms.
- Invariant #18: "Defaults Are Moral Decisions" -- The system defaults to requiring an invite, making the barrier to entry intentional.
- Invariant #16: "AI Never Observes Individuals" -- Authentication collects only email and display name; no behavioral data or profiling.
User Experience
Sign-In Flow
- User arrives at the app and sees "Welcome back" with email and password fields.
- User enters credentials and clicks "Sign In".
- On success, Supabase Auth sets the session and the app renders the authenticated experience.
- On error, a descriptive error message appears above the form.
Sign-Up Flow
- User clicks "Sign up" to toggle to registration mode.
- The form expands to show four fields: Your Name, Invite Code, Email, and Password.
- The invite code is validated client-side before the signup request is sent.
- On valid code: Supabase
signUpis called with the email, password, and display_name in user metadata. - A database trigger creates the
profilesrecord automatically. - On invalid code: "Invalid invite code. Ask a friend for the code!" error is shown.
Form States
| State | Display |
|---|---|
| Sign In mode | Email + Password fields, "Sign In" button |
| Sign Up mode | Name + Invite Code + Email + Password fields, "Create Account" button |
| Loading | Button shows "Please wait..." and is disabled |
| Error | Red error message above the form |
Technical Implementation
Key Files
| File | Purpose |
|---|---|
src/components/Auth.jsx | Complete authentication component with sign-in/sign-up toggle, form handling, invite code validation, and Supabase Auth integration (132 lines) |
src/lib/supabase.js | Supabase client initialization |
Invite Code System
The invite code is configured via the VITE_INVITE_CODE environment variable, with a fallback default. Validation is performed client-side before the Supabase signup call:
const INVITE_CODE = import.meta.env.VITE_INVITE_CODE || 'friendsonly2024'
If the provided code does not match, the error "Invalid invite code. Ask a friend for the code!" is thrown before any API call is made.
Supabase Auth Integration
Sign In:
supabase.auth.signInWithPassword({ email, password })
Sign Up:
supabase.auth.signUp({
email,
password,
options: {
data: {
display_name: displayName
}
}
})
The display_name is passed in the options.data object, making it available in user_metadata for the database trigger that creates the profile.
Profile Creation
A database trigger (not in the frontend code) fires on new user creation and inserts a row into the profiles table using the display_name from user_metadata. This ensures every authenticated user has a corresponding profile record.
Session Management
Session management is handled by Supabase Auth's built-in session persistence. The App.jsx component listens for auth state changes and renders either the Auth component or the authenticated application based on the session state.
Database Tables
| Table | Purpose |
|---|---|
profiles | User profile created by database trigger on auth signup. Contains id, display_name, email, avatar_url, username, bio, and other profile fields |
Security Considerations
- Passwords have a minimum length of 6 characters (enforced by the HTML
minLengthattribute). - The invite code is stored in an environment variable, not hardcoded in production builds.
- No sensitive data is stored in localStorage by the Auth component.
- All subsequent API calls use the Supabase session token with RLS policies for authorization.
Edge Cases
| Scenario | Behavior |
|---|---|
| Wrong password | Supabase Auth returns error; displayed above the form |
| Email already registered | Supabase Auth returns appropriate error |
| Invalid invite code | Client-side error before API call: "Invalid invite code. Ask a friend for the code!" |
| Empty required fields | HTML form validation prevents submission |
| Password too short | HTML minLength={6} prevents submission |
| Toggle between sign-in and sign-up | Error state is cleared on toggle |
| Network error | Caught by try/catch; error message displayed |
Related
- HomeRoom -- Profile created during auth is the basis for the user's HomeRoom
- Friends -- Authenticated users can send and receive friend requests
Last updated: 2026-02-07