Replace the Schulcloud token without a restart
A token lasts 30 days and only a browser login yields one — the account is federated, so the server cannot mint it. Replacing it meant editing .env and recreating the container, every month. `schulcloud token set` (a hidden prompt, or piped input) and a /token page both send it to PUT /api/token. The server checks it with Schulcloud first — well-formed, unexpired, still logged in, the same account — then swaps it into the config every request reads, restarts the keepalive and saves it in STATE_DIR, a new volume, with mode 0600. At startup the newer of the saved token and TSC_JWT_COOKIE wins, unless they belong to different accounts. A refused paste changes nothing, and the token is never logged. The keepalive's pings carry a generation, so a 401 for the old token that arrives after a swap cannot stop the new cycle. `schulcloud token`, whoami and the log report the expiry and warn a week ahead. Found on the way: a host that is off for more than two hours loses the session however long the token has left — this machine lost it overnight — which is what the always-on Pi is for. 174 tests. Smoke 72/72 on the local instance, and a real swap verified end to end there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { createServer } from '../mcp/server.ts';
|
||||
import type { Services } from '../services.ts';
|
||||
import { createApiRouter } from './api.ts';
|
||||
import { bearerAuth } from './auth.ts';
|
||||
import { tokenPage, tokenScript } from './token-page.ts';
|
||||
|
||||
/**
|
||||
* Streamable-HTTP front end, for use as a remote MCP connector.
|
||||
@@ -71,6 +72,10 @@ export function createHttpApp(config: Config, services?: Services): express.Expr
|
||||
|
||||
if (services) {
|
||||
app.use(API_PATH, createApiRouter(services));
|
||||
// The page to paste a fresh Schulcloud token into. It holds no secret: what
|
||||
// it sends goes to /api/token, behind the bearer check above.
|
||||
app.get('/token', tokenPage);
|
||||
app.get('/token.js', tokenScript);
|
||||
}
|
||||
|
||||
app.use(MCP_PATH, express.json({ limit: '4mb' }));
|
||||
|
||||
Reference in New Issue
Block a user