Skip to main content

13. Contractor authentication and invitations

Date: 2026-06-06

Status

Accepted

Context

Contractors (Philippines-based) authenticate with email + password (Supabase Auth), distinct from admins who use Google SSO. An admin invites a contractor; the contractor sets their own password and gains access. Invites must be secure (single-use, expiring, unguessable) and the contractor and admin areas must stay cleanly separated.

Decision

  • Invitations: inviteContractor (admin action) creates an invited contractor row and a contractor_invitations record storing only the SHA-256 hash of a 256-bit CSPRNG token (src/lib/crypto/tokens.ts), with a 7-day expiry. The raw token exists only in the returned /invite/<token> link. (Email delivery is manual for now; Gmail automation is Step 12.)
  • Acceptance: the public /invite/[token] page validates the token by hash up front. acceptInvitation re-validates, creates the Supabase auth user via the service role (email_confirm: true — the invite proves email control), links contractors.user_id, flips the invitation to accepted and the contractor to onboarding, signs the user in, records the session, and redirects to /contractor.
  • Login: loginContractor uses signInWithPassword, then confirms the user maps to a contractor row (else signs out) and records the session.
  • Gating: the proxy (src/proxy.ts) is role-aware — it resolves admin vs contractor and keeps each audience in its own area, routing to the correct login page and avoiding redirect loops. It reuses the sessions table for force-logout and absolute timeout (contractors get a longer default, 720 min, since they log hours intermittently). /invite/* is public.

Consequences

  • Two fully separated auth audiences share one gate and one session-control surface.
  • Invite tokens are single-use, hashed at rest, and expiring; rate limiting on the accept/login endpoints is a follow-up (the 256-bit token plus single-use + expiry is the core defense).
  • Password minimum is 8 characters (Zod); can be hardened later.
  • The first contractor data appears here; assignment, rates, documents, and the DocuSeal contract come in the onboarding step (Step 4/5).