# Mode1Svelte - SvelteKit Auth Testing Suite A complete SvelteKit-based testing environment for authentication workflows with Microsoft Azure MSAL and PocketBase. This is a modern rewrite of Mode1 using the latest SvelteKit technology stack. ## Tech Stack - **Framework**: SvelteKit 2.x with TypeScript - **Backend**: Node.js Adapter (production-ready) - **Styling**: Tailwind CSS 4 - **Authentication**: - Azure MSAL Node (@azure/msal-node) - Microsoft Graph token management - PocketBase - User OAuth2 and token validation - **Build Tool**: Vite (integrated with SvelteKit) - **Runtime**: Node.js 18+ ## Features ### ✅ Frontend Authentication (PocketBase) - OAuth2 login initialization with Microsoft - Auth state management and retrieval - Token refresh and validation - Session persistence - Automatic logout on invalid tokens ### ✅ Backend Token Management (Microsoft Graph) - App-only token acquisition via MSAL - Automatic token caching with 60-second expiration buffer - Token refresh on demand - JWT payload inspection ### ✅ Token Validation & Comparison - PocketBase user token validation - User record retrieval from tokens - Side-by-side token comparison (Graph vs PocketBase) - Token payload analysis ### ✅ Interactive Testing Dashboard - Real-time authentication status - Visual token testing interface - API endpoint testing - Response inspection ## Project Structure ``` Mode1Svelte/ ├── src/ │ ├── lib/ │ │ └── auth/ │ │ ├── types.ts # TypeScript interfaces │ │ ├── backend.ts # Backend auth classes (MSAL, PocketBase) │ │ └── frontend.ts # Frontend PocketBase auth class │ ├── routes/ │ │ ├── +layout.svelte # App layout │ │ ├── +page.svelte # Main dashboard │ │ └── api/ │ │ └── auth/ │ │ ├── config/ # GET /api/auth/config │ │ ├── graph/ # GET /api/auth/graph/token │ │ ├── validate-pb-token/ # POST /api/auth/validate-pb-token │ │ ├── refresh-graph/ # POST /api/auth/refresh-graph │ │ └── compare-tokens/ # POST /api/auth/compare-tokens │ └── app.css # Tailwind directives ├── static/ # Static assets ├── package.json # Dependencies ├── svelte.config.js # SvelteKit config (Node adapter) ├── tailwind.config.js # Tailwind CSS config ├── vite.config.ts # Vite config └── tsconfig.json # TypeScript config ``` ## Installation ```bash cd Mode1Svelte npm install ``` ## Environment Setup Ensure your `.env` file or environment variables are set: ```bash export CLIENT_ID="" export TENANT_ID="" export CLIENT_SECRET="" export PB_URL="" export PB_DB="" export PORT=5173 ``` For development, create `/home/admin/secrets/.env`: ``` CLIENT_ID=your_client_id TENANT_ID=your_tenant_id CLIENT_SECRET=your_client_secret PB_URL=https://pocketbase.example.com PB_DB=https://pocketbase.example.com ``` ## Running the Application ### Development Mode ```bash npm run dev ``` Starts the dev server at `http://localhost:5173` with hot reloading. ### Production Build ```bash npm run build npm start ``` Builds the application and runs the Node.js server. ### Type Checking ```bash npm run check ``` Run TypeScript type checking across the project. ## API Endpoints ### GET `/api/auth/config` Returns frontend-safe configuration for PocketBase OAuth setup. **Response:** ```json { "pbUrl": "https://pocketbase.example.com", "provider": "microsoft", "collection": "Users" } ``` ### GET `/api/auth/graph/token` Fetches a Microsoft Graph token for backend API access. **Response:** ```json { "success": true, "token": "eyJ0eXAiOiJKV1Q...", "fullToken": "eyJ0eXAiOiJKV1QiLCJhbGc...", "expiresOn": "2026-01-23T02:15:00.000Z", "isValid": true, "tokenDetails": { "aud": "https://graph.microsoft.com", "iss": "https://sts.windows.net/tenant-id", "scp": "..." } } ``` ### POST `/api/auth/validate-pb-token` Validates a PocketBase user token and retrieves user information. **Request:** ```json { "pbToken": "user_token_string" } ``` **Response:** ```json { "valid": true, "user": { "id": "user_id", "email": "user@example.com", "name": "User Name" } } ``` ### POST `/api/auth/refresh-graph` Clears the cached Graph token and acquires a new one. **Response:** ```json { "success": true, "refreshed": true, "expiresOn": "2026-01-23T02:15:00.000Z" } ``` ### POST `/api/auth/compare-tokens` Compares Graph token (backend) and PocketBase token (user) to demonstrate their differences. **Request:** ```json { "pbToken": "user_token_string" } ``` **Response:** ```json { "success": true, "comparison": { "graph_token": { "issuer": "https://sts.windows.net/tenant", "audience": "https://graph.microsoft.com", "app": "App Name", "scopes": "...", "issued_at": "2026-01-23T01:15:00.000Z", "expires_at": "2026-01-23T02:15:00.000Z", "type": "Microsoft Graph Token (Backend/App-only)", "source": "@azure/msal-node", "purpose": "Backend API calls to Microsoft Graph" }, "pocketbase_token": { "type": "PocketBase User Token (Frontend/User)", "source": "PocketBase OAuth2 flow", "authenticated_user": "user@example.com" }, "are_different": true } } ``` ## Authentication Flow ### Frontend (Browser) 1. User clicks "Login with Microsoft" 2. PocketBase initiates OAuth2 flow with Microsoft provider 3. Microsoft redirects back with authorization code 4. PocketBase exchanges code for user token 5. Token stored in PocketBase auth store 6. User dashboard updates with authenticated state ### Backend (Server) 1. Application starts with MSAL configuration 2. On first API request, acquires Graph token using client credentials 3. Token cached for 55 minutes (60-minute lifetime - 5-minute buffer) 4. Subsequent requests use cached token 5. Token automatically refreshed when expired ## Development Notes - **CORS**: Configured for `localhost:5173` and production URLs - **Token Caching**: Graph tokens cached in memory; refresh on demand with `/api/auth/refresh-graph` - **Error Handling**: Comprehensive error messages with specific failure reasons - **Type Safety**: Full TypeScript support throughout frontend and backend - **SvelteKit Routing**: File-based routing with `+page.svelte` and `+server.ts` files ## Comparison with Mode1 (Hono/Bun) | Feature | Mode1Svelte | Mode1 | |---------|-------------|--------| | Framework | SvelteKit 2 | SvelteKit 4 (old) | | Backend | Node.js Adapter | Hono + Bun | | Frontend | Svelte Components | HTML + Vanilla JS | | Styling | Tailwind CSS | CSS (custom) | | Build Tool | Vite | Vite | | API Routes | `/routes/api/` | `/routes/api/` | | Auth Module | `/lib/auth/` | `/routes/api/` | | Type Safety | Full TypeScript | TypeScript (partial) | | Production Ready | ✅ Yes | ⚠️ Experimental | ## Troubleshooting ### Token Acquisition Fails - Verify `CLIENT_ID`, `TENANT_ID`, and `CLIENT_SECRET` are correct - Ensure the Azure application is configured for client credentials flow - Check that the application has Graph API permissions ### PocketBase Token Validation Fails - Verify `PB_URL` and `PB_DB` are correct - Ensure the user is properly logged in via OAuth - Check that PocketBase is running and accessible ### Login Button Not Appearing - Ensure JavaScript is enabled - Check browser console for errors - Verify that `loginBtn` HTML element ID matches configuration ## Links - [SvelteKit Documentation](https://svelte.dev/docs/kit) - [Azure MSAL Node](https://github.com/AzureAD/microsoft-authentication-library-for-js) - [PocketBase Documentation](https://pocketbase.io/docs/) - [Tailwind CSS](https://tailwindcss.com/) ## License Private - Job Info Testing Suite ## Developing Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: ```sh npm run dev # or start the server and open the app in a new browser tab npm run dev -- --open ``` ## Building To create a production version of your app: ```sh npm run build ``` You can preview the production build with `npm run preview`. > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.