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
| File | Responsibility |
|---|
authService.ts | Pending signup creation, referral code capture, URL param extraction |
SessionService.ts | Session CRUD, concurrent session enforcement, session activity updates |
apiKeyService.ts | API key generation, scoping, rate-limit config, rotation |
mfaService.ts | MFA enrolment (SMS/TOTP), verification, recovery code management |
securityMonitoringService.ts | Security event logging, suspicious login detection, alert dispatch |
securityPolicyService.ts | Org-level security policy (password, MFA, session, login) CRUD |
securityAlertService.ts | Security alert CRUD and resolution workflow |
invitationService.ts | User invitation creation, acceptance, and expiry management |
onboardingService.ts | Auth-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
| Policy | Key defaults |
|---|
| MFA | Optional; 30-day grace period; recovery code bypass allowed |
| Session | 60-min idle timeout; 12-hour absolute timeout; 3 concurrent sessions max |
| Login | 5 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
| Event | Emitted By |
|---|
SECURITY_ALERT_TRIGGERED | securityMonitoringService.logSecurityEvent() |
SUSPICIOUS_LOGIN_DETECTED | securityMonitoringService.detectSuspiciousLogin() |
MFA_ENROLLED | mfaService.completeMfaEnrolment() |
MFA_UNENROLLED | mfaService.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
| Caller | Uses |
|---|
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() |