@geometra/auth
v1.0.1
Published
Token-based WebSocket authentication for Geometra server/client
Downloads
2,806
Maintainers
Readme
@geometra/auth
Token-based WebSocket authentication for Geometra server/client apps.
Live Demo | Source | Geometra auth contract | Token registry
Related packages:
- geometra —
createServer/createClient; seePLATFORM_AUTH.mdfor close codes 4001 (handshake rejected) and 4003 (forbidden message), refresh, and what stays out of core. - geometra-token-registry — HTTP
POST /verifyfor productionremoteVerifier(); mint/revoke tokens via admin API.
The demo client is hosted on GitHub Pages. To see it in action, run the example server locally with
npm run exampleand open the page.
Because Geometra's server computes all layout and streams pre-computed geometry to clients, auth lives at the protocol layer — the server controls what each connection can see and do at the frame level.
Install
bun add @geometra/authPeer dependencies: @geometra/server (required), @geometra/client (optional — only needed for the client helper).
Server Usage
createAuth() returns onConnection, onMessage, and onDisconnect hooks that spread directly into createServer() options.
import { createAuth, staticTokens } from '@geometra/auth'
import { createServer } from '@geometra/server'
const auth = createAuth({
verify: staticTokens({
'admin-secret': 'admin',
'viewer-secret': 'viewer',
}),
policies: {
viewer: { allow: ['resize'] }, // read-only — no input events
},
})
const server = await createServer(view, {
port: 3100,
...auth,
})Verifiers
| Verifier | Use case |
|---|---|
| staticTokens(map) | Dev / demos — maps token strings to roles |
| remoteVerifier(url) | Production — POSTs Bearer token to your auth endpoint, expects { role, claims? } |
| chainVerifiers(...fns) | Tries multiple verifiers in order, first match wins |
Lifecycle Hooks
createAuth({
verify: staticTokens({ ... }),
onAccept: (ctx) => console.log(`connected: ${ctx.role}`),
onReject: (reason, req) => console.log(`rejected: ${reason}`),
onBlock: (msgType, ctx) => console.log(`blocked ${msgType} from ${ctx.role}`),
onLeave: (ctx) => console.log(`disconnected: ${ctx.role}`),
})Custom Token Extraction
By default, the token is read from the ?token= query parameter. Override with extractToken:
createAuth({
verify: myVerifier,
extractToken: (req) => req.headers['x-api-key'] as string ?? null,
})Client Usage
import { connectWithAuth } from '@geometra/auth/client'
const client = await connectWithAuth({
token: 'admin-secret',
url: 'ws://localhost:3100',
renderer,
canvas,
onAuthRejected: () => console.log('invalid token'), // WebSocket closed with 4001
onForbidden: (err) => console.log('action blocked by server'),
})onAuthRejected runs when the server rejects the upgrade (4001). @geometra/client does not auto-reconnect after 4001. Token refresh: obtain a new token, then open a new connection (see Geometra PLATFORM_AUTH.md).
Role Policies
Policies control which message types each role can send:
policies: {
viewer: { allow: ['resize'] }, // whitelist
restricted: { deny: ['dangerous'] }, // blacklist
admin: {}, // no restrictions (default)
}allow— only these message types are permitted (whitelist)deny— these message types are blocked (blacklist, applied after allow)- No policy entry = all messages allowed
Development
bun install
bun run check # type check
bun test # run tests
bun run build # compile to dist/License
MIT
