Add ModeTemplate with Svelte 5 frontend and components
- Create reusable components: auth, api-client, shared-types - ModeTemplate with Hono backend and SvelteKit frontend - Auth store refactored to class-based Svelte 5 pattern - SSR-safe hydrate() pattern for localStorage access - Frontend builds successfully with Svelte 5 runes
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# Auth Component
|
||||
|
||||
Microsoft OAuth authentication that returns user info and a PocketBase token.
|
||||
|
||||
**Users must already exist in PocketBase - no user creation. Access denied if user not found.**
|
||||
|
||||
## What it does
|
||||
|
||||
1. Redirects user to Microsoft login
|
||||
2. Exchanges auth code for access token
|
||||
3. Gets user's email and display name from Microsoft Graph
|
||||
4. Checks if user exists in PocketBase (denies access if not)
|
||||
5. Returns PocketBase auth token
|
||||
|
||||
## Environment Variables Used
|
||||
|
||||
These variables exist in `/home/admin/secrets/.env`:
|
||||
|
||||
```
|
||||
MICROSOFT_CLIENT_ID
|
||||
MICROSOFT_CLIENT_SECRET
|
||||
MICROSOFT_TENANT_ID
|
||||
MICROSOFT_REDIRECT_URI
|
||||
MICROSOFT_SCOPES
|
||||
PB_URL
|
||||
```
|
||||
|
||||
## Usage in Hono Backend
|
||||
|
||||
```typescript
|
||||
import { Hono } from 'hono';
|
||||
import { getAuthUrl, handleCallback, getConfigFromEnv } from './components/auth';
|
||||
|
||||
const app = new Hono();
|
||||
const config = getConfigFromEnv();
|
||||
|
||||
// Redirect to Microsoft login
|
||||
app.get('/auth/login', (c) => {
|
||||
return c.redirect(getAuthUrl(config));
|
||||
});
|
||||
|
||||
// Handle callback from Microsoft
|
||||
app.get('/auth/callback', async (c) => {
|
||||
const code = c.req.query('code');
|
||||
|
||||
if (!code) {
|
||||
return c.json({ error: 'No authorization code' }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await handleCallback(code, config);
|
||||
|
||||
// result contains:
|
||||
// - email: string
|
||||
// - displayName: string
|
||||
// - pocketbaseToken: string
|
||||
|
||||
return c.json(result);
|
||||
} catch (err) {
|
||||
// User doesn't exist or auth failed
|
||||
return c.json({ error: String(err) }, 403);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Copying to a Mode
|
||||
|
||||
1. Copy the entire `components/auth/` folder to your mode's `backend/modules/auth/`
|
||||
2. Update imports in your server
|
||||
3. Environment variables are loaded from secrets at runtime
|
||||
|
||||
## Dependencies
|
||||
|
||||
None - uses native fetch API (Bun/Node 18+). No package.json needed - inherits from consuming project.
|
||||
|
||||
## Returns
|
||||
|
||||
```typescript
|
||||
interface AuthResult {
|
||||
email: string; // User's email from Microsoft
|
||||
displayName: string; // User's display name from Microsoft
|
||||
pocketbaseToken: string; // Auth token for PocketBase API calls
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user