@alteran/astro 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/index.js +8 -0
- package/migrations/0009_oauth_session_state.sql +31 -0
- package/migrations/meta/0009_snapshot.json +749 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +2 -1
- package/src/db/account.ts +134 -1
- package/src/db/schema.ts +31 -0
- package/src/handlers/root.ts +1 -1
- package/src/lib/appview/proxy.ts +11 -8
- package/src/lib/auth.ts +34 -3
- package/src/lib/jwt.ts +4 -0
- package/src/lib/oauth/as-keys.ts +29 -0
- package/src/lib/oauth/clients.ts +453 -24
- package/src/lib/oauth/consent.ts +180 -0
- package/src/lib/oauth/dpop.ts +39 -5
- package/src/lib/oauth/resource.ts +93 -21
- package/src/lib/oauth/store.ts +64 -7
- package/src/lib/refresh-session.ts +16 -0
- package/src/lib/session-tokens.ts +33 -5
- package/src/lib/token-cleanup.ts +4 -2
- package/src/lib/util.ts +0 -1
- package/src/pages/.well-known/oauth-authorization-server.ts +16 -3
- package/src/pages/.well-known/oauth-protected-resource.ts +8 -4
- package/src/pages/oauth/authorize.ts +31 -52
- package/src/pages/oauth/consent.ts +163 -66
- package/src/pages/oauth/jwks.ts +15 -0
- package/src/pages/oauth/par.ts +34 -56
- package/src/pages/oauth/revoke.ts +75 -0
- package/src/pages/oauth/token.ts +148 -89
- package/src/pages/xrpc/[...nsid].ts +7 -6
- package/src/pages/xrpc/app.bsky.actor.getPreferences.ts +3 -4
- package/src/pages/xrpc/app.bsky.actor.putPreferences.ts +3 -4
- package/src/pages/xrpc/app.bsky.unspecced.getAgeAssuranceState.ts +3 -4
- package/src/pages/xrpc/chat.bsky.convo.getLog.ts +3 -4
- package/src/pages/xrpc/chat.bsky.convo.listConvos.ts +3 -4
- package/src/pages/xrpc/com.atproto.identity.getRecommendedDidCredentials.ts +3 -4
- package/src/pages/xrpc/com.atproto.identity.requestPlcOperationSignature.ts +3 -4
- package/src/pages/xrpc/com.atproto.identity.signPlcOperation.ts +3 -4
- package/src/pages/xrpc/com.atproto.identity.submitPlcOperation.ts +3 -4
- package/src/pages/xrpc/com.atproto.repo.listMissingBlobs.ts +3 -4
- package/src/pages/xrpc/com.atproto.server.checkAccountStatus.ts +3 -4
- package/src/pages/xrpc/com.atproto.server.deleteSession.ts +28 -9
- package/src/pages/xrpc/com.atproto.server.getSession.ts +3 -4
- package/src/worker/runtime.ts +23 -1
- package/types/env.d.ts +1 -0
package/README.md
CHANGED
|
@@ -254,6 +254,18 @@ validateConfigOrThrow(env);
|
|
|
254
254
|
- Handle format is valid
|
|
255
255
|
- Numeric values are positive
|
|
256
256
|
|
|
257
|
+
### Cloudflare Security Rules
|
|
258
|
+
|
|
259
|
+
`com.atproto.server.refreshSession` is a valid bodyless `POST`. Production deployments must allow this request shape through to the XRPC handler:
|
|
260
|
+
|
|
261
|
+
```txt
|
|
262
|
+
(http.request.method eq "POST" and http.request.uri.path eq "/xrpc/com.atproto.server.refreshSession")
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Astro's SSR origin-check middleware rejects unsafe requests with no `Origin` header before project middleware runs. Alteran normalizes `/xrpc/*` requests at the Worker entrypoint so bearer-token XRPC clients can send bodyless POSTs without tripping Astro's form CSRF guard.
|
|
266
|
+
|
|
267
|
+
If Cloudflare WAF/API Shield also protects the deployment, keep any exception narrow to the expression above. This exception is not configured in `wrangler.jsonc`; Wrangler only manages the Worker deployment and bindings.
|
|
268
|
+
|
|
257
269
|
### Environment-Specific Settings
|
|
258
270
|
|
|
259
271
|
See [`wrangler.jsonc`](wrangler.jsonc:40) for environment-specific configurations:
|
|
@@ -380,14 +392,25 @@ USER_PASSWORD=your-password
|
|
|
380
392
|
REFRESH_TOKEN=your-access-secret
|
|
381
393
|
REFRESH_TOKEN_SECRET=your-refresh-secret
|
|
382
394
|
PDS_SEQ_WINDOW=512
|
|
395
|
+
PDS_OAUTH_CLIENT_HOSTS=client.example,another-client.example
|
|
383
396
|
```
|
|
384
397
|
|
|
398
|
+
`PDS_OAUTH_CLIENT_HOSTS` is required for OAuth clients that use dynamic
|
|
399
|
+
client metadata. It is a comma-separated allowlist of hostnames that this
|
|
400
|
+
single-user PDS may fetch for client metadata and JWKS documents.
|
|
401
|
+
|
|
385
402
|
### 3. Run Database Migration
|
|
386
403
|
```bash
|
|
387
404
|
bun run db:generate
|
|
388
405
|
bun run db:apply:local
|
|
389
406
|
```
|
|
390
407
|
|
|
408
|
+
Upgrade note: migration `0009_oauth_session_state` revokes existing refresh
|
|
409
|
+
tokens when adding OAuth session state. Existing clients may need to sign in
|
|
410
|
+
again after this migration. This is intentional because older refresh-token
|
|
411
|
+
rows cannot prove whether they came from legacy sessions or pre-hardening OAuth
|
|
412
|
+
flows.
|
|
413
|
+
|
|
391
414
|
### 4. Run Tests
|
|
392
415
|
```bash
|
|
393
416
|
bun test tests/mst.test.ts
|
package/index.js
CHANGED
|
@@ -5,7 +5,15 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
const CORE_ROUTES = [
|
|
6
6
|
{ pattern: '/.well-known/atproto-did', entrypoint: './src/pages/.well-known/atproto-did.ts' },
|
|
7
7
|
{ pattern: '/.well-known/did.json', entrypoint: './src/pages/.well-known/did.json.ts' },
|
|
8
|
+
{ pattern: '/.well-known/oauth-authorization-server', entrypoint: './src/pages/.well-known/oauth-authorization-server.ts' },
|
|
9
|
+
{ pattern: '/.well-known/oauth-protected-resource', entrypoint: './src/pages/.well-known/oauth-protected-resource.ts' },
|
|
8
10
|
{ pattern: '/health', entrypoint: './src/pages/health.ts' },
|
|
11
|
+
{ pattern: '/oauth/authorize', entrypoint: './src/pages/oauth/authorize.ts' },
|
|
12
|
+
{ pattern: '/oauth/consent', entrypoint: './src/pages/oauth/consent.ts' },
|
|
13
|
+
{ pattern: '/oauth/jwks', entrypoint: './src/pages/oauth/jwks.ts' },
|
|
14
|
+
{ pattern: '/oauth/par', entrypoint: './src/pages/oauth/par.ts' },
|
|
15
|
+
{ pattern: '/oauth/revoke', entrypoint: './src/pages/oauth/revoke.ts' },
|
|
16
|
+
{ pattern: '/oauth/token', entrypoint: './src/pages/oauth/token.ts' },
|
|
9
17
|
{ pattern: '/ready', entrypoint: './src/pages/ready.ts' },
|
|
10
18
|
{ pattern: '/xrpc/com.atproto.identity.getRecommendedDidCredentials', entrypoint: './src/pages/xrpc/com.atproto.identity.getRecommendedDidCredentials.ts' },
|
|
11
19
|
{ pattern: '/xrpc/com.atproto.identity.requestPlcOperationSignature', entrypoint: './src/pages/xrpc/com.atproto.identity.requestPlcOperationSignature.ts' },
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
CREATE TABLE `oauth_session` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`did` text NOT NULL,
|
|
4
|
+
`client_id` text NOT NULL,
|
|
5
|
+
`client_auth_method` text NOT NULL,
|
|
6
|
+
`client_auth_key_id` text,
|
|
7
|
+
`dpop_jkt` text NOT NULL,
|
|
8
|
+
`scope` text NOT NULL,
|
|
9
|
+
`current_refresh_token_id` text NOT NULL,
|
|
10
|
+
`access_jti` text NOT NULL,
|
|
11
|
+
`created_at` integer NOT NULL,
|
|
12
|
+
`updated_at` integer NOT NULL,
|
|
13
|
+
`expires_at` integer NOT NULL,
|
|
14
|
+
`revoked_at` integer
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
CREATE INDEX `oauth_session_client_idx` ON `oauth_session` (`client_id`);--> statement-breakpoint
|
|
18
|
+
CREATE INDEX `oauth_session_current_refresh_idx` ON `oauth_session` (`current_refresh_token_id`);--> statement-breakpoint
|
|
19
|
+
CREATE INDEX `oauth_session_access_jti_idx` ON `oauth_session` (`access_jti`);--> statement-breakpoint
|
|
20
|
+
ALTER TABLE `refresh_token` ADD `token_kind` text DEFAULT 'legacy' NOT NULL;--> statement-breakpoint
|
|
21
|
+
ALTER TABLE `refresh_token` ADD `oauth_session_id` text;--> statement-breakpoint
|
|
22
|
+
ALTER TABLE `refresh_token` ADD `client_id` text;--> statement-breakpoint
|
|
23
|
+
ALTER TABLE `refresh_token` ADD `client_auth_method` text;--> statement-breakpoint
|
|
24
|
+
ALTER TABLE `refresh_token` ADD `client_auth_key_id` text;--> statement-breakpoint
|
|
25
|
+
ALTER TABLE `refresh_token` ADD `dpop_jkt` text;--> statement-breakpoint
|
|
26
|
+
ALTER TABLE `refresh_token` ADD `oauth_scope` text;--> statement-breakpoint
|
|
27
|
+
ALTER TABLE `refresh_token` ADD `access_jti` text;--> statement-breakpoint
|
|
28
|
+
ALTER TABLE `refresh_token` ADD `revoked_at` integer;--> statement-breakpoint
|
|
29
|
+
UPDATE `refresh_token` SET `revoked_at` = CAST(strftime('%s','now') AS INTEGER) WHERE `revoked_at` IS NULL;--> statement-breakpoint
|
|
30
|
+
CREATE INDEX `refresh_token_oauth_session_idx` ON `refresh_token` (`oauth_session_id`);--> statement-breakpoint
|
|
31
|
+
CREATE INDEX `refresh_token_access_jti_idx` ON `refresh_token` (`access_jti`);
|