Rebuild Mode1Svelte with SvelteKit + Node.js adapter

- Migrated from Bun/Hono to modern SvelteKit tech stack
- Implemented complete authentication module (Azure MSAL + PocketBase)
- Created 5 API endpoints for auth operations (config, graph token, validate, refresh, compare)
- Built interactive Svelte dashboard with mobile optimization (iPhone 16)
- Added Node.js adapter (@sveltejs/adapter-node) for production deployment
- Integrated Tailwind CSS with responsive design
- Fixed orchestrator to spawn Mode1Svelte with Node.js on port 3005
- Updated systemd service (job-info-test.service) to start orchestrator on port 3006
- Port configuration locked: 3005 = Mode1Svelte, 3006 = Orchestrator
- Full TypeScript type safety throughout application
- Services auto-managed by orchestrator with systemd integration
This commit is contained in:
2026-01-23 02:18:34 +00:00
parent d8d53ece93
commit 7b997dc354
33 changed files with 3793 additions and 1462 deletions
+275 -120
View File
@@ -1,158 +1,313 @@
# Mode1Svelte - Auth Module Test Suite
# Mode1Svelte - SvelteKit Auth Testing Suite
Self-contained test environment for the auth-module. This version is identical to Mode1 currently, serving as a foundation for future Svelte integration.
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.
## Structure
## Tech Stack
```
Mode1Svelte/
├── auth-module/ # Local copy of auth-module (not linked to root)
├── backend/ # Backend server with auth endpoints
└── server.ts # Hono app with Graph token and PB validation APIs
├── frontend/ # Frontend test interface
│ └── index.html # Interactive test dashboard
├── logs/ # Application logs
├── package.json # Dependencies (auth module + Hono + PocketBase)
└── bun.lock # Locked dependencies
```
- **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 Auth (PocketBaseAuth)**
- OAuth2 login initialization
- Auth state retrieval
- Token refresh
- Logout
### ✅ 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 Auth (GraphTokenManager)**
- Microsoft Graph token acquisition
- Token caching (with 60s expiration buffer)
- Cache validity checking
- Cache refresh
### ✅ 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
**PocketBase Validation (PocketBaseValidator)**
- User token validation
- User record retrieval
- Token comparison (Graph vs PocketBase)
### ✅ Token Validation & Comparison
- PocketBase user token validation
- User record retrieval from tokens
- Side-by-side token comparison (Graph vs PocketBase)
- Token payload analysis
## Running Mode1Svelte
### ✅ Interactive Testing Dashboard
- Real-time authentication status
- Visual token testing interface
- API endpoint testing
- Response inspection
### Via Orchestrator (recommended)
## Project Structure
```bash
# Switch to Mode1Svelte
curl -X POST http://localhost:3006/switch/Mode1Svelte
# Check status
curl http://localhost:3006/status
```
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
```
### Direct
## Installation
```bash
cd Mode1Svelte
bun install
PORT=3005 bun run backend/server.ts
npm install
```
Then visit: `http://localhost:3005`
## Environment Setup
## Future: Svelte Integration
This project is set up as an independent Mode to eventually convert to SvelteKit while maintaining the same API endpoints and auth-module integration.
## Structure
```
Mode1/
├── auth-module/ # Local copy of auth-module (not linked to root)
├── backend/ # Backend server with auth endpoints
│ └── server.ts # Hono app with Graph token and PB validation APIs
├── frontend/ # Frontend test interface
│ └── index.html # Interactive test dashboard
├── logs/ # Application logs
├── package.json # Dependencies (auth module + Hono + PocketBase)
└── bun.lock # Locked dependencies
```
## Features Tested
**Frontend Auth (PocketBaseAuth)**
- OAuth2 login initialization
- Auth state retrieval
- Token refresh
- Logout
**Backend Auth (GraphTokenManager)**
- Microsoft Graph token acquisition
- Token caching (with 60s expiration buffer)
- Cache validity checking
- Cache refresh
**PocketBase Validation (PocketBaseValidator)**
- User token validation
- User record retrieval
## Running Mode1
### Via Orchestrator (recommended)
Ensure your `.env` file or environment variables are set:
```bash
# Switch to Mode1
curl -X POST http://localhost:3006/switch/Mode1
# Check status
curl http://localhost:3006/status
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
```
### Direct
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
# Install dependencies (already done)
bun install
# Start server
bun run backend/server.ts
# Access dashboard
open http://localhost:3005
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
### Configuration
- `GET /api/auth/config` - Get frontend configuration
### GET `/api/auth/config`
Returns frontend-safe configuration for PocketBase OAuth setup.
### Graph Token Management
- `GET /api/auth/graph/token` - Get current Graph token (with expiration)
- `POST /api/auth/refresh-graph` - Force refresh Graph token
**Response:**
```json
{
"pbUrl": "https://pocketbase.example.com",
"provider": "microsoft",
"collection": "Users"
}
```
### PocketBase Validation
- `POST /api/auth/validate-pb-token` - Validate a PocketBase token
### GET `/api/auth/graph/token`
Fetches a Microsoft Graph token for backend API access.
### Health
- `GET /health` - Health check
**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": "..."
}
}
```
## Environment Variables
### POST `/api/auth/validate-pb-token`
Validates a PocketBase user token and retrieves user information.
Uses `/home/admin/secrets/.env` via auth-module:
- `CLIENT_ID` - Microsoft application ID
- `TENANT_ID` - Azure tenant ID
- `CLIENT_SECRET` - Microsoft client secret
- `PB_URL` - PocketBase frontend URL
- `PB_DB` - PocketBase backend URL
**Request:**
```json
{
"pbToken": "user_token_string"
}
```
## Dependencies
**Response:**
```json
{
"valid": true,
"user": {
"id": "user_id",
"email": "user@example.com",
"name": "User Name"
}
}
```
All dependencies are installed locally in `node_modules/`:
- `hono` - Web framework
- `pocketbase` - PocketBase client
- `@azure/msal-node` - Microsoft authentication
- `dotenv` - Environment variable loading
### POST `/api/auth/refresh-graph`
Clears the cached Graph token and acquires a new one.
## Notes
**Response:**
```json
{
"success": true,
"refreshed": true,
"expiresOn": "2026-01-23T02:15:00.000Z"
}
```
- This Mode1 is **completely self-contained** with its own auth-module copy
- No dependencies on root auth-module
- Safe to modify and test independently
- All secrets come from `/home/admin/secrets/.env`
### 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.