# Auth Login Patterns **Selector:** Set this once per project. ``` ACTIVE_LOGIN_METHOD=pb-oauth-via-microsoft ``` (Other methods can be added; only one should be active.) --- ## Environment Variables ### Required Variables **Azure AD / Microsoft Authentication:** - `CLIENT_ID` - Azure AD Application Client ID - `CLIENT_SECRET` - Azure AD Application Client Secret - `TENANT_ID` - Azure AD Tenant ID - `REDIRECT_URI` - OAuth redirect URI **PocketBase:** - `PB_DB` - PocketBase database URL (e.g., `https://pocketbase.ccllc.pro`) - `PB_COLLECTION` - Collection name for job data (e.g., `Job_Info_TestEnv`) - `PB_AUTH_COLLECTION` - Collection name for user authentication (e.g., `Users`) **Redis/Valkey (Caching & Search):** - `REDIS_URL` - Redis/Valkey connection URL (e.g., `redis://localhost:6379` or `redis://redis-server:6379`) - If not provided, defaults to `redis://localhost:6379` - For production, connect to the same Redis/Valkey instance as Job-Info-Prod **Optional:** - `PORT` - Server port (default: 3025) --- ## Caching & Search This application uses Redis/Valkey for: 1. **Data Caching**: Job records are cached for 5 minutes (300 seconds) to reduce PocketBase queries 2. **Search Results Caching**: Search results are cached for 3 minutes (180 seconds) 3. **Cache Invalidation**: Automatically clears cache when data is updated ### API Endpoints **Get All Jobs (with caching):** ``` GET /api/jobs Headers: X-PocketBase-Token: ``` **Search Jobs (with caching):** ``` GET /api/jobs/search?q= Headers: X-PocketBase-Token: ``` Searches across: Job_Number, Job_Full_Name, Job_Name, Company_Client, Contact_Person, Estimator, Job_Status, Project_Manager, Notes **Clear Cache (admin):** ``` POST /api/cache/clear Headers: X-PocketBase-Token: ``` ### Cache Strategy - **Source of Truth**: PocketBase remains the source of truth for updates - **Read Operations**: Check cache first, fallback to PocketBase if cache miss - **Write Operations**: Update PocketBase, then invalidate cache - **Future**: Will switch to Job-Info-Prod for production data synchronization --- ## Shared Rules (All Methods) - Serve frontend from the project’s `frontend` folder; show login UI only when not authenticated. - Secrets come from `.env`; never hardcode or log secrets/tokens. - Token storage: use in-memory auth store (avoid localStorage/sessionStorage unless explicitly required). - On logout, clear the auth store and hide the protected UI. - Log only context + message; exclude raw tokens or secrets. --- ## Method: pb-oauth-via-microsoft (PocketBase + Microsoft) **Frontend** - Use PocketBase SDK OAuth (`provider: 'microsoft'`). - Show login button when `!pb.authStore.isValid`; hide the form until valid. - On success: keep token in `pb.authStore`; display user email; show logout. - On logout: `pb.authStore.clear()`; hide protected UI. **Backend** - Endpoints expecting auth (e.g., `/api/submit`) must receive `pbToken`. - Call `setUserPocketBaseAuth(pbToken)` before PocketBase operations. - Required `.env` keys: `CLIENT_ID`, `CLIENT_SECRET`, `TENANT_ID`, `REDIRECT_URI`, `PB_DB`, `PB_COLLECTION`, `PB_AUTH_COLLECTION`. - Validate token via PocketBase client; reject if missing/invalid. - Do not log tokens; log context and error message only. **UI States** - Logged out: show login UI only. - Logged in: hide login UI, show form/app content. - Errors: show a visible error container; avoid alert loops. **Security** - Enforce CORS as needed; HTTPS in production. - Keep `.env` out of version control; use deploy-time secrets. --- ## Method: pb-and-graph-via-microsoft (PocketBase + Microsoft Graph) **Frontend** - Same UI pattern as `pb-oauth-via-microsoft` (PocketBase OAuth `provider: 'microsoft'`). - Show login when `!pb.authStore.isValid`; hide protected UI until valid. - On success: keep token in `pb.authStore`; display user email; show logout; on logout clear auth store. **Backend** - Expect `pbToken` on protected endpoints; call `setUserPocketBaseAuth(pbToken)` before PB operations. - Acquire Graph token via client credentials for Excel sync. - Required `.env` keys: - Azure AD: `CLIENT_ID`, `CLIENT_SECRET`, `TENANT_ID`, `REDIRECT_URI` - PocketBase: `PB_DB`, `PB_COLLECTION`, `PB_AUTH_COLLECTION` - Graph/Excel: `DRIVE_ID`, `ITEM_ID`, `EXCEL_TABLE`, `EXCEL_TABLE_WRITEBACK` (if used) - Use Graph scope: `https://graph.microsoft.com/.default` - Do not log tokens; log context + message only. **Token Handling** - PocketBase token (user): stored in memory via `pb.authStore`; sent to backend as `pbToken`. - Graph token (app): obtained server-side via client credentials; never exposed to frontend; short-lived, fetched on demand. **UI States** - Logged out: show login UI only. - Logged in: hide login UI, show form/app content. - Errors: show visible error container; avoid alert loops. **Security** - Enforce CORS as needed; HTTPS in production. - Keep `.env` out of version control; use deploy-time secrets. - Do not log raw tokens or secrets. --- ## Method: PBandGraphOauth (PocketBase + Microsoft Graph OAuth) **Frontend** - Use PocketBase SDK OAuth (`provider: 'microsoft'`). - Show login button when `!pb.authStore.isValid`; hide protected UI until valid. - On success: keep token in `pb.authStore`; display user email; show logout. - On logout: `pb.authStore.clear()`; hide protected UI. **Backend** - Endpoints expecting auth (e.g., `/api/submit`) must receive `pbToken` from the frontend. - Call `setUserPocketBaseAuth(pbToken)` before PocketBase operations. - Obtain a Microsoft Graph access token using Azure AD app credentials. - Required `.env` keys (exactly from current `.env`): - Azure AD: `CLIENT_ID`, `CLIENT_SECRET`, `TENANT_ID`, `REDIRECT_URI` - PocketBase: `PB_DB`, `PB_COLLECTION`, `PB_AUTH_COLLECTION` - Graph token scope: `https://graph.microsoft.com/.default`. - Never log raw tokens or secrets; log only context + messages. **Token Handling** - PocketBase token (user): stored in memory via `pb.authStore`; sent to backend as `pbToken` on protected calls. - Graph token (app): acquired server-side via client credentials using `CLIENT_ID`/`CLIENT_SECRET`/`TENANT_ID`; never exposed to the frontend. **UI States** - Logged out: show login UI only. - Logged in: hide login UI; show protected UI. - Errors: show a visible error container; avoid alert loops. **Security** - Enforce CORS as needed; HTTPS in production. - Keep `.env` out of version control; use deploy-time secrets. - Do not log raw tokens or secrets. --- ## Adding Another Method (Template) ``` # Example selector ACTIVE_LOGIN_METHOD=custom-sso Frontend: - Describe SDK/flow - Show/hide rules - Token storage rules Backend: - How tokens are validated - Required .env keys - How errors are logged/returned Security: - CORS/HTTPS rules - Logging redactions ``` --- ## How to Use 1) Copy this folder into a new project (outside your app code) or reference it as the canonical auth guide. 2) Set `ACTIVE_LOGIN_METHOD` to the one in use. 3) Follow only the active method; do not mix flows. 4) Keep .env values in deploy-time secrets; never commit them.