Skip to main content

Documentation Index

Fetch the complete documentation index at: https://grantmaster.dev/llms.txt

Use this file to discover all available pages before exploring further.

shared/auth — API Reference

The shared/auth module handles all authentication-adjacent business logic: session management, API key issuance, MFA enrolment, security event monitoring, security policy administration, invitation flows, and referral code capture at sign-up.
Firebase Auth itself (sign-in, sign-out, token refresh) is managed by src/core/firebase.ts and Firebase’s own SDK. This module wraps the application-level concerns that sit on top of it.

Module Map

FileResponsibility
authService.tsPending signup creation, referral code capture, URL param extraction
SessionService.tsSession CRUD, concurrent session enforcement, session activity updates
apiKeyService.tsAPI key generation, scoping, rate-limit config, rotation
mfaService.tsMFA enrolment (SMS/TOTP), verification, recovery code management
securityMonitoringService.tsSecurity event logging, suspicious login detection, alert dispatch
securityPolicyService.tsOrg-level security policy (password, MFA, session, login) CRUD
securityAlertService.tsSecurity alert CRUD and resolution workflow
invitationService.tsUser invitation creation, acceptance, and expiry management
onboardingService.tsAuth-time onboarding state tracking

authService

Lightweight helpers used during the sign-up flow.
import { createPendingSignup, extractReferralCode, getStoredReferralCode } from '@/shared/auth/authService';

// Store a pending signup (watched by Cloud Function for post-signup processing)
await createPendingSignup('user@example.com', { name: 'Alice', referralCode: 'PARTNER_GRA_X7K9P2' });

// Extract ?ref= from current URL and persist to localStorage
const code = extractReferralCode();

// Read back from localStorage
const stored = getStoredReferralCode();
Firestore collection: pendingSignups/{email} — Cloud Functions watch this collection to process referral credits and org provisioning after Firebase Auth confirms the account.

SessionService

Manages UserSession records in Firestore. Enforces concurrent session limits defined in the org’s SessionPolicy.

Singleton Export

import { sessionService } from '@/shared/auth/SessionService';

Key Methods

sessionService.createSession(userId, organizationId, metadata?): Promise<UserSession>
sessionService.updateSessionActivity(sessionId): Promise<void>
sessionService.deleteSession(sessionId): Promise<void>
sessionService.deleteAllUserSessions(userId): Promise<void>
sessionService.getUserActiveSessions(userId): Promise<UserSession[]>
sessionService.enforceSessionLimit(userId, maxSessions): Promise<void>  // evicts oldest
Firestore collection: sessions/{sessionId} — documents include userId, organizationId, ipAddress, userAgent, createdAt, lastActiveAt, expiresAt.

apiKeyService

Issues and manages API keys for third-party integration access.

Key Methods

createApiKey(orgId, userId, name, description?, scopes, environment, options?): Promise<ApiKeyWithSecret>
getApiKey(orgId, keyId): Promise<ApiKey | null>
listApiKeys(orgId): Promise<ApiKey[]>
revokeApiKey(orgId, keyId, revokedBy): Promise<void>
rotateApiKey(orgId, keyId, userId): Promise<ApiKeyWithSecret>  // revoke + issue new
validateApiKey(rawKey): Promise<ApiKey | null>

ApiKeyScope

type ApiKeyScope =
  | 'read:grants' | 'write:grants'
  | 'read:projects' | 'write:projects'
  | 'read:expenses' | 'write:expenses'
  | 'read:reports'
  | 'webhooks';

Rate Limits

Default rate limits (from DEFAULT_RATE_LIMITS): 1,000 requests/hour, 10,000/day. Custom limits can be set per key at creation time. Firestore collection: organizations/{orgId}/api_keys/{keyId} — the raw secret is hashed (SHA-256) before storage; the plaintext is returned only at creation.

mfaService

Wraps Firebase Multi-Factor Authentication (SMS-based second factor).

Key Methods

// Enrolment
startMfaEnrolment(user, phoneNumber, recaptchaVerifier): Promise<MFAEnrollmentData>
completeMfaEnrolment(user, verificationId, otp): Promise<void>
unenrolMfa(user): Promise<void>
isMfaEnrolled(user): boolean

// Recovery codes
generateRecoveryCodes(): RecoveryCode[]              // 10 codes, format XXXX-XXXX
storeRecoveryCodes(userId, codes): Promise<void>
validateRecoveryCode(userId, code): Promise<boolean>
markRecoveryCodeUsed(userId, code): Promise<void>

// Challenge (during sign-in)
startMfaChallenge(multiFactorError, recaptchaVerifier): Promise<string>  // verificationId
completeMfaChallenge(multiFactorError, verificationId, otp): Promise<void>
Firestore path: employees/{userId} — MFA enrolment state and recovery codes stored in the user document.

securityMonitoringService

Records and analyses security events; dispatches notifications for anomalies.

Key Methods

logSecurityEvent(event: Omit<SecurityEvent, 'id' | 'timestamp' | 'resolved'>): Promise<string>
getSecurityEvents(orgId, options?): Promise<SecurityEvent[]>
getUnresolvedEvents(orgId): Promise<SecurityEvent[]>
resolveSecurityEvent(eventId, resolvedBy, notes?): Promise<void>

// Anomaly detectors (called from auth flow)
detectSuspiciousLogin(userId, orgId, ipAddress, countryCode?): Promise<void>
checkMultipleFailedLogins(userId, orgId): Promise<void>
When anomalies are detected, the service calls notifySecurityAlert(), notifySuspiciousLogin(), and notifyMultipleFailedLogins() from shared/notifications. Firestore collection: securityEvents/{eventId}.

securityPolicyService

Manages the four policy layers that govern account security for each organisation.

Policy Types

interface SecurityPolicy {
  passwordPolicy: PasswordPolicy;  // min length, complexity, history, rotation
  mfaPolicy: MFAPolicy;            // required, requiredForRoles, gracePeriod
  sessionPolicy: SessionPolicy;    // idleTimeout, absoluteTimeout, concurrentSessions
  loginPolicy: LoginPolicy;        // maxFailedAttempts, lockoutDuration, IP restrictions
}

Key Methods

getSecurityPolicy(orgId): Promise<SecurityPolicy>
updatePasswordPolicy(orgId, policy, updatedBy): Promise<void>
updateMfaPolicy(orgId, policy, updatedBy): Promise<void>
updateSessionPolicy(orgId, policy, updatedBy): Promise<void>
updateLoginPolicy(orgId, policy, updatedBy): Promise<void>
resetToDefaults(orgId, updatedBy): Promise<void>
validatePasswordAgainstPolicy(orgId, password): Promise<ValidationResult>

// SuperAdmin: platform-wide policy override
getPlatformSecurityPolicy(): Promise<SecurityPolicy>
updatePlatformSecurityPolicy(policy, updatedBy): Promise<void>

Defaults

PolicyKey defaults
MFAOptional; 30-day grace period; recovery code bypass allowed
Session60-min idle timeout; 12-hour absolute timeout; 3 concurrent sessions max
Login5 failed attempts; 15-min lockout
Firestore paths: organizations/{orgId}/settings/security and platform/settings/security.

invitationService

Handles user invitations (separate from partner invitations in shared/partnerships).

Key Methods

createInvitation(orgId, inviterId, email, role, options?): Promise<Invitation>
getInvitationByToken(token): Promise<Invitation | null>
acceptInvitation(token, userId): Promise<void>
revokeInvitation(invitationId, revokedBy): Promise<void>
expirePendingInvitations(): Promise<number>   // Cloud Function batch job
listInvitations(orgId, status?): Promise<Invitation[]>
Firestore collection: invitations/{invitationId}.

EventBus Events

EventEmitted By
SECURITY_ALERT_TRIGGEREDsecurityMonitoringService.logSecurityEvent()
SUSPICIOUS_LOGIN_DETECTEDsecurityMonitoringService.detectSuspiciousLogin()
MFA_ENROLLEDmfaService.completeMfaEnrolment()
MFA_UNENROLLEDmfaService.unenrolMfa()
Gap: API key creation/rotation and session policy changes currently emit no EventBus events. If audit workflows need to react to these, emissions should be added to apiKeyService and securityPolicyService.

Callers

CallerUses
src/features/users/invitationService, apiKeyService, MFA enrolment UI
src/features/settings/securityPolicyService — Security Settings panel
src/features/onboarding/onboardingService, authService.createPendingSignup()
Firebase Auth trigger (Cloud Function)Reads pendingSignups, processes referral and provisioning
src/features/superadmin/securityPolicyService.getPlatformSecurityPolicy()