- Created Mode2Svelte as a copy of Mode1Svelte - Updated branding (title, description) to distinguish from Mode1Svelte - Added Mode2Svelte support to orchestrator - Configured orchestrator to spawn Mode2Svelte with Node.js adapter - Set Mode2Svelte as active mode in activeMode.txt - Built production bundle for Mode2Svelte - Both Mode1Svelte and Mode2Svelte now managed by orchestrator on port 3005 - Orchestrator controls which mode runs via activeMode.txt configuration
Mode2Svelte - Advanced SvelteKit Auth Testing Suite
An enhanced SvelteKit-based testing environment for advanced authentication workflows with Microsoft Azure MSAL and PocketBase. This is an extended implementation of Mode1Svelte with additional testing capabilities.
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
cd Mode1Svelte
npm install
Environment Setup
Ensure your .env file or environment variables are set:
export CLIENT_ID="<Azure Client ID>"
export TENANT_ID="<Azure Tenant ID>"
export CLIENT_SECRET="<Azure Client Secret>"
export PB_URL="<PocketBase URL>"
export PB_DB="<PocketBase Database URL>"
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
npm run dev
Starts the dev server at http://localhost:5173 with hot reloading.
Production Build
npm run build
npm start
Builds the application and runs the Node.js server.
Type Checking
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:
{
"pbUrl": "https://pocketbase.example.com",
"provider": "microsoft",
"collection": "Users"
}
GET /api/auth/graph/token
Fetches a Microsoft Graph token for backend API access.
Response:
{
"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:
{
"pbToken": "user_token_string"
}
Response:
{
"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:
{
"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:
{
"pbToken": "user_token_string"
}
Response:
{
"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)
- User clicks "Login with Microsoft"
- PocketBase initiates OAuth2 flow with Microsoft provider
- Microsoft redirects back with authorization code
- PocketBase exchanges code for user token
- Token stored in PocketBase auth store
- User dashboard updates with authenticated state
Backend (Server)
- Application starts with MSAL configuration
- On first API request, acquires Graph token using client credentials
- Token cached for 55 minutes (60-minute lifetime - 5-minute buffer)
- Subsequent requests use cached token
- Token automatically refreshed when expired
Development Notes
- CORS: Configured for
localhost:5173and 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.svelteand+server.tsfiles
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, andCLIENT_SECRETare 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_URLandPB_DBare 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
loginBtnHTML element ID matches configuration
Links
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:
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:
npm run build
You can preview the production build with npm run preview.
To deploy your app, you may need to install an adapter for your target environment.