@alteran/astro 0.1.7 → 0.1.8
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 +38 -3
- package/migrations/0005_odd_bishop.sql +18 -0
- package/migrations/meta/0005_snapshot.json +429 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +3 -2
- package/src/db/dal.ts +33 -0
- package/src/db/schema.ts +7 -0
- package/src/lib/blob-refs.ts +99 -0
- package/src/lib/secrets.ts +47 -0
- package/src/pages/xrpc/com.atproto.identity.getRecommendedDidCredentials.ts +99 -0
- package/src/pages/xrpc/com.atproto.repo.applyWrites.ts +20 -0
- package/src/pages/xrpc/com.atproto.repo.importRepo.ts +142 -0
- package/src/pages/xrpc/com.atproto.repo.listMissingBlobs.ts +88 -0
- package/src/pages/xrpc/com.atproto.repo.uploadBlob.ts +16 -4
- package/src/pages/xrpc/com.atproto.server.activateAccount.ts +53 -0
- package/src/pages/xrpc/com.atproto.server.checkAccountStatus.ts +92 -0
- package/src/pages/xrpc/com.atproto.server.createAccount.ts +79 -0
- package/src/pages/xrpc/com.atproto.server.deactivateAccount.ts +53 -0
- package/src/pages/xrpc/com.atproto.sync.getBlob.ts +84 -0
- package/src/worker/runtime.ts +11 -6
- package/types/env.d.ts +18 -8
package/README.md
CHANGED
|
@@ -185,18 +185,45 @@ Set these secrets for each environment using `wrangler secret put <NAME> --env <
|
|
|
185
185
|
|
|
186
186
|
**Generate secrets:**
|
|
187
187
|
```bash
|
|
188
|
-
#
|
|
188
|
+
# One-shot bootstrap (recommended)
|
|
189
|
+
# Generates all required secrets and prints wrangler commands
|
|
190
|
+
bun run scripts/setup-secrets.ts --env production --did did:web:example.com --handle user.example.com
|
|
191
|
+
|
|
192
|
+
# Or generate only the repo signing key
|
|
189
193
|
bun run scripts/generate-signing-key.ts
|
|
190
194
|
|
|
191
|
-
#
|
|
195
|
+
# After generation, set secrets (example for production)
|
|
192
196
|
wrangler secret put PDS_DID --env production
|
|
193
197
|
wrangler secret put PDS_HANDLE --env production
|
|
194
198
|
wrangler secret put USER_PASSWORD --env production
|
|
195
199
|
wrangler secret put ACCESS_TOKEN_SECRET --env production
|
|
196
200
|
wrangler secret put REFRESH_TOKEN_SECRET --env production
|
|
197
201
|
wrangler secret put REPO_SIGNING_KEY --env production
|
|
202
|
+
# Optional: publish public key for DID document
|
|
203
|
+
wrangler secret put REPO_SIGNING_PUBLIC_KEY --env production
|
|
198
204
|
```
|
|
199
205
|
|
|
206
|
+
### Using Cloudflare Secret Store (optional)
|
|
207
|
+
|
|
208
|
+
Instead of Wrangler Secrets, you may bind secrets from Cloudflare Secret Store. This repo now supports both. Bind each secret you want to source from Secret Store via `secrets_store_secrets` in `wrangler.jsonc`:
|
|
209
|
+
|
|
210
|
+
```jsonc
|
|
211
|
+
{
|
|
212
|
+
// ...
|
|
213
|
+
"secrets_store_secrets": [
|
|
214
|
+
{ "binding": "USER_PASSWORD", "secret_name": "user_password", "store_id": "<your-store-id>" },
|
|
215
|
+
{ "binding": "ACCESS_TOKEN_SECRET", "secret_name": "access_token_secret", "store_id": "<your-store-id>" },
|
|
216
|
+
{ "binding": "REFRESH_TOKEN_SECRET", "secret_name": "refresh_token_secret", "store_id": "<your-store-id>" },
|
|
217
|
+
{ "binding": "PDS_DID", "secret_name": "pds_did", "store_id": "<your-store-id>" },
|
|
218
|
+
{ "binding": "PDS_HANDLE", "secret_name": "pds_handle", "store_id": "<your-store-id>" }
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Notes:
|
|
224
|
+
- Bindings can use the same names as the existing env vars. Only one source should be configured per secret (Wrangler Secret OR Secret Store binding).
|
|
225
|
+
- At runtime, the worker resolves Secret Store bindings via `await env.<BINDING>.get()` and passes them to the app as plain strings.
|
|
226
|
+
|
|
200
227
|
### Optional Configuration
|
|
201
228
|
|
|
202
229
|
These can be set as environment variables in [`wrangler.jsonc`](wrangler.jsonc:1) or as secrets:
|
|
@@ -326,8 +353,12 @@ This PDS now implements full AT Protocol core compliance with:
|
|
|
326
353
|
|
|
327
354
|
## Setup Instructions
|
|
328
355
|
|
|
329
|
-
### 1. Generate
|
|
356
|
+
### 1. Generate Secrets
|
|
330
357
|
```bash
|
|
358
|
+
# Recommended: bootstrap all secrets (prints wrangler commands)
|
|
359
|
+
bun run scripts/setup-secrets.ts --env production --did did:web:example.com --handle user.example.com
|
|
360
|
+
|
|
361
|
+
# Alternative: generate only the repo signing key
|
|
331
362
|
bun run scripts/generate-signing-key.ts
|
|
332
363
|
```
|
|
333
364
|
|
|
@@ -341,6 +372,8 @@ wrangler secret put PDS_HANDLE # Your handle
|
|
|
341
372
|
wrangler secret put USER_PASSWORD # Login password
|
|
342
373
|
wrangler secret put ACCESS_TOKEN_SECRET
|
|
343
374
|
wrangler secret put REFRESH_TOKEN_SECRET
|
|
375
|
+
# Optional: publish raw public key for DID document
|
|
376
|
+
wrangler secret put REPO_SIGNING_PUBLIC_KEY
|
|
344
377
|
```
|
|
345
378
|
|
|
346
379
|
**For Local Development (.dev.vars):**
|
|
@@ -348,6 +381,8 @@ wrangler secret put REFRESH_TOKEN_SECRET
|
|
|
348
381
|
PDS_DID=did:plc:your-did-here
|
|
349
382
|
PDS_HANDLE=your-handle.bsky.social
|
|
350
383
|
REPO_SIGNING_KEY=<base64-key-from-step-1>
|
|
384
|
+
# Optional: publish raw 32-byte public key in did.json
|
|
385
|
+
REPO_SIGNING_PUBLIC_KEY=<base64-raw-public-key>
|
|
351
386
|
USER_PASSWORD=your-password
|
|
352
387
|
ACCESS_TOKEN_SECRET=your-access-secret
|
|
353
388
|
REFRESH_TOKEN_SECRET=your-refresh-secret
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
CREATE TABLE `account_state` (
|
|
2
|
+
`did` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`active` integer DEFAULT false NOT NULL,
|
|
4
|
+
`created_at` integer NOT NULL
|
|
5
|
+
);
|
|
6
|
+
--> statement-breakpoint
|
|
7
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
8
|
+
CREATE TABLE `__new_blob_usage` (
|
|
9
|
+
`record_uri` text NOT NULL,
|
|
10
|
+
`key` text NOT NULL,
|
|
11
|
+
PRIMARY KEY(`record_uri`, `key`)
|
|
12
|
+
);
|
|
13
|
+
--> statement-breakpoint
|
|
14
|
+
INSERT INTO `__new_blob_usage`("record_uri", "key") SELECT "record_uri", "key" FROM `blob_usage`;--> statement-breakpoint
|
|
15
|
+
DROP TABLE `blob_usage`;--> statement-breakpoint
|
|
16
|
+
ALTER TABLE `__new_blob_usage` RENAME TO `blob_usage`;--> statement-breakpoint
|
|
17
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
18
|
+
CREATE INDEX `blob_usage_record_uri_idx` ON `blob_usage` (`record_uri`);
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "6",
|
|
3
|
+
"dialect": "sqlite",
|
|
4
|
+
"id": "cfdb4a96-9b33-41d2-9733-a44d61806a55",
|
|
5
|
+
"prevId": "cb70b8e1-d043-4b92-928a-ac332366391c",
|
|
6
|
+
"tables": {
|
|
7
|
+
"account_state": {
|
|
8
|
+
"name": "account_state",
|
|
9
|
+
"columns": {
|
|
10
|
+
"did": {
|
|
11
|
+
"name": "did",
|
|
12
|
+
"type": "text",
|
|
13
|
+
"primaryKey": true,
|
|
14
|
+
"notNull": true,
|
|
15
|
+
"autoincrement": false
|
|
16
|
+
},
|
|
17
|
+
"active": {
|
|
18
|
+
"name": "active",
|
|
19
|
+
"type": "integer",
|
|
20
|
+
"primaryKey": false,
|
|
21
|
+
"notNull": true,
|
|
22
|
+
"autoincrement": false,
|
|
23
|
+
"default": false
|
|
24
|
+
},
|
|
25
|
+
"created_at": {
|
|
26
|
+
"name": "created_at",
|
|
27
|
+
"type": "integer",
|
|
28
|
+
"primaryKey": false,
|
|
29
|
+
"notNull": true,
|
|
30
|
+
"autoincrement": false
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"indexes": {},
|
|
34
|
+
"foreignKeys": {},
|
|
35
|
+
"compositePrimaryKeys": {},
|
|
36
|
+
"uniqueConstraints": {},
|
|
37
|
+
"checkConstraints": {}
|
|
38
|
+
},
|
|
39
|
+
"blob_quota": {
|
|
40
|
+
"name": "blob_quota",
|
|
41
|
+
"columns": {
|
|
42
|
+
"did": {
|
|
43
|
+
"name": "did",
|
|
44
|
+
"type": "text",
|
|
45
|
+
"primaryKey": true,
|
|
46
|
+
"notNull": true,
|
|
47
|
+
"autoincrement": false
|
|
48
|
+
},
|
|
49
|
+
"total_bytes": {
|
|
50
|
+
"name": "total_bytes",
|
|
51
|
+
"type": "integer",
|
|
52
|
+
"primaryKey": false,
|
|
53
|
+
"notNull": true,
|
|
54
|
+
"autoincrement": false,
|
|
55
|
+
"default": 0
|
|
56
|
+
},
|
|
57
|
+
"blob_count": {
|
|
58
|
+
"name": "blob_count",
|
|
59
|
+
"type": "integer",
|
|
60
|
+
"primaryKey": false,
|
|
61
|
+
"notNull": true,
|
|
62
|
+
"autoincrement": false,
|
|
63
|
+
"default": 0
|
|
64
|
+
},
|
|
65
|
+
"updated_at": {
|
|
66
|
+
"name": "updated_at",
|
|
67
|
+
"type": "integer",
|
|
68
|
+
"primaryKey": false,
|
|
69
|
+
"notNull": true,
|
|
70
|
+
"autoincrement": false
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"indexes": {},
|
|
74
|
+
"foreignKeys": {},
|
|
75
|
+
"compositePrimaryKeys": {},
|
|
76
|
+
"uniqueConstraints": {},
|
|
77
|
+
"checkConstraints": {}
|
|
78
|
+
},
|
|
79
|
+
"blob": {
|
|
80
|
+
"name": "blob",
|
|
81
|
+
"columns": {
|
|
82
|
+
"cid": {
|
|
83
|
+
"name": "cid",
|
|
84
|
+
"type": "text",
|
|
85
|
+
"primaryKey": true,
|
|
86
|
+
"notNull": true,
|
|
87
|
+
"autoincrement": false
|
|
88
|
+
},
|
|
89
|
+
"did": {
|
|
90
|
+
"name": "did",
|
|
91
|
+
"type": "text",
|
|
92
|
+
"primaryKey": false,
|
|
93
|
+
"notNull": true,
|
|
94
|
+
"autoincrement": false
|
|
95
|
+
},
|
|
96
|
+
"key": {
|
|
97
|
+
"name": "key",
|
|
98
|
+
"type": "text",
|
|
99
|
+
"primaryKey": false,
|
|
100
|
+
"notNull": true,
|
|
101
|
+
"autoincrement": false
|
|
102
|
+
},
|
|
103
|
+
"mime": {
|
|
104
|
+
"name": "mime",
|
|
105
|
+
"type": "text",
|
|
106
|
+
"primaryKey": false,
|
|
107
|
+
"notNull": true,
|
|
108
|
+
"autoincrement": false
|
|
109
|
+
},
|
|
110
|
+
"size": {
|
|
111
|
+
"name": "size",
|
|
112
|
+
"type": "integer",
|
|
113
|
+
"primaryKey": false,
|
|
114
|
+
"notNull": true,
|
|
115
|
+
"autoincrement": false
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"indexes": {},
|
|
119
|
+
"foreignKeys": {},
|
|
120
|
+
"compositePrimaryKeys": {},
|
|
121
|
+
"uniqueConstraints": {},
|
|
122
|
+
"checkConstraints": {}
|
|
123
|
+
},
|
|
124
|
+
"blob_usage": {
|
|
125
|
+
"name": "blob_usage",
|
|
126
|
+
"columns": {
|
|
127
|
+
"record_uri": {
|
|
128
|
+
"name": "record_uri",
|
|
129
|
+
"type": "text",
|
|
130
|
+
"primaryKey": false,
|
|
131
|
+
"notNull": true,
|
|
132
|
+
"autoincrement": false
|
|
133
|
+
},
|
|
134
|
+
"key": {
|
|
135
|
+
"name": "key",
|
|
136
|
+
"type": "text",
|
|
137
|
+
"primaryKey": false,
|
|
138
|
+
"notNull": true,
|
|
139
|
+
"autoincrement": false
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"indexes": {
|
|
143
|
+
"blob_usage_record_uri_idx": {
|
|
144
|
+
"name": "blob_usage_record_uri_idx",
|
|
145
|
+
"columns": [
|
|
146
|
+
"record_uri"
|
|
147
|
+
],
|
|
148
|
+
"isUnique": false
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"foreignKeys": {},
|
|
152
|
+
"compositePrimaryKeys": {
|
|
153
|
+
"blob_usage_record_uri_key_pk": {
|
|
154
|
+
"columns": [
|
|
155
|
+
"record_uri",
|
|
156
|
+
"key"
|
|
157
|
+
],
|
|
158
|
+
"name": "blob_usage_record_uri_key_pk"
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"uniqueConstraints": {},
|
|
162
|
+
"checkConstraints": {}
|
|
163
|
+
},
|
|
164
|
+
"blockstore": {
|
|
165
|
+
"name": "blockstore",
|
|
166
|
+
"columns": {
|
|
167
|
+
"cid": {
|
|
168
|
+
"name": "cid",
|
|
169
|
+
"type": "text",
|
|
170
|
+
"primaryKey": true,
|
|
171
|
+
"notNull": true,
|
|
172
|
+
"autoincrement": false
|
|
173
|
+
},
|
|
174
|
+
"bytes": {
|
|
175
|
+
"name": "bytes",
|
|
176
|
+
"type": "text",
|
|
177
|
+
"primaryKey": false,
|
|
178
|
+
"notNull": false,
|
|
179
|
+
"autoincrement": false
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"indexes": {},
|
|
183
|
+
"foreignKeys": {},
|
|
184
|
+
"compositePrimaryKeys": {},
|
|
185
|
+
"uniqueConstraints": {},
|
|
186
|
+
"checkConstraints": {}
|
|
187
|
+
},
|
|
188
|
+
"commit_log": {
|
|
189
|
+
"name": "commit_log",
|
|
190
|
+
"columns": {
|
|
191
|
+
"seq": {
|
|
192
|
+
"name": "seq",
|
|
193
|
+
"type": "integer",
|
|
194
|
+
"primaryKey": true,
|
|
195
|
+
"notNull": true,
|
|
196
|
+
"autoincrement": false
|
|
197
|
+
},
|
|
198
|
+
"cid": {
|
|
199
|
+
"name": "cid",
|
|
200
|
+
"type": "text",
|
|
201
|
+
"primaryKey": false,
|
|
202
|
+
"notNull": true,
|
|
203
|
+
"autoincrement": false
|
|
204
|
+
},
|
|
205
|
+
"rev": {
|
|
206
|
+
"name": "rev",
|
|
207
|
+
"type": "text",
|
|
208
|
+
"primaryKey": false,
|
|
209
|
+
"notNull": true,
|
|
210
|
+
"autoincrement": false
|
|
211
|
+
},
|
|
212
|
+
"data": {
|
|
213
|
+
"name": "data",
|
|
214
|
+
"type": "text",
|
|
215
|
+
"primaryKey": false,
|
|
216
|
+
"notNull": true,
|
|
217
|
+
"autoincrement": false
|
|
218
|
+
},
|
|
219
|
+
"sig": {
|
|
220
|
+
"name": "sig",
|
|
221
|
+
"type": "text",
|
|
222
|
+
"primaryKey": false,
|
|
223
|
+
"notNull": true,
|
|
224
|
+
"autoincrement": false
|
|
225
|
+
},
|
|
226
|
+
"ts": {
|
|
227
|
+
"name": "ts",
|
|
228
|
+
"type": "integer",
|
|
229
|
+
"primaryKey": false,
|
|
230
|
+
"notNull": true,
|
|
231
|
+
"autoincrement": false
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"indexes": {
|
|
235
|
+
"commit_log_seq_idx": {
|
|
236
|
+
"name": "commit_log_seq_idx",
|
|
237
|
+
"columns": [
|
|
238
|
+
"seq"
|
|
239
|
+
],
|
|
240
|
+
"isUnique": false
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"foreignKeys": {},
|
|
244
|
+
"compositePrimaryKeys": {},
|
|
245
|
+
"uniqueConstraints": {},
|
|
246
|
+
"checkConstraints": {}
|
|
247
|
+
},
|
|
248
|
+
"login_attempts": {
|
|
249
|
+
"name": "login_attempts",
|
|
250
|
+
"columns": {
|
|
251
|
+
"ip": {
|
|
252
|
+
"name": "ip",
|
|
253
|
+
"type": "text",
|
|
254
|
+
"primaryKey": true,
|
|
255
|
+
"notNull": true,
|
|
256
|
+
"autoincrement": false
|
|
257
|
+
},
|
|
258
|
+
"attempts": {
|
|
259
|
+
"name": "attempts",
|
|
260
|
+
"type": "integer",
|
|
261
|
+
"primaryKey": false,
|
|
262
|
+
"notNull": true,
|
|
263
|
+
"autoincrement": false,
|
|
264
|
+
"default": 0
|
|
265
|
+
},
|
|
266
|
+
"locked_until": {
|
|
267
|
+
"name": "locked_until",
|
|
268
|
+
"type": "integer",
|
|
269
|
+
"primaryKey": false,
|
|
270
|
+
"notNull": false,
|
|
271
|
+
"autoincrement": false
|
|
272
|
+
},
|
|
273
|
+
"last_attempt": {
|
|
274
|
+
"name": "last_attempt",
|
|
275
|
+
"type": "integer",
|
|
276
|
+
"primaryKey": false,
|
|
277
|
+
"notNull": true,
|
|
278
|
+
"autoincrement": false
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
"indexes": {},
|
|
282
|
+
"foreignKeys": {},
|
|
283
|
+
"compositePrimaryKeys": {},
|
|
284
|
+
"uniqueConstraints": {},
|
|
285
|
+
"checkConstraints": {}
|
|
286
|
+
},
|
|
287
|
+
"record": {
|
|
288
|
+
"name": "record",
|
|
289
|
+
"columns": {
|
|
290
|
+
"uri": {
|
|
291
|
+
"name": "uri",
|
|
292
|
+
"type": "text",
|
|
293
|
+
"primaryKey": true,
|
|
294
|
+
"notNull": true,
|
|
295
|
+
"autoincrement": false
|
|
296
|
+
},
|
|
297
|
+
"did": {
|
|
298
|
+
"name": "did",
|
|
299
|
+
"type": "text",
|
|
300
|
+
"primaryKey": false,
|
|
301
|
+
"notNull": true,
|
|
302
|
+
"autoincrement": false
|
|
303
|
+
},
|
|
304
|
+
"cid": {
|
|
305
|
+
"name": "cid",
|
|
306
|
+
"type": "text",
|
|
307
|
+
"primaryKey": false,
|
|
308
|
+
"notNull": true,
|
|
309
|
+
"autoincrement": false
|
|
310
|
+
},
|
|
311
|
+
"json": {
|
|
312
|
+
"name": "json",
|
|
313
|
+
"type": "text",
|
|
314
|
+
"primaryKey": false,
|
|
315
|
+
"notNull": true,
|
|
316
|
+
"autoincrement": false
|
|
317
|
+
},
|
|
318
|
+
"created_at": {
|
|
319
|
+
"name": "created_at",
|
|
320
|
+
"type": "integer",
|
|
321
|
+
"primaryKey": false,
|
|
322
|
+
"notNull": false,
|
|
323
|
+
"autoincrement": false,
|
|
324
|
+
"default": 0
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
"indexes": {
|
|
328
|
+
"record_did_idx": {
|
|
329
|
+
"name": "record_did_idx",
|
|
330
|
+
"columns": [
|
|
331
|
+
"did"
|
|
332
|
+
],
|
|
333
|
+
"isUnique": false
|
|
334
|
+
},
|
|
335
|
+
"record_cid_idx": {
|
|
336
|
+
"name": "record_cid_idx",
|
|
337
|
+
"columns": [
|
|
338
|
+
"cid"
|
|
339
|
+
],
|
|
340
|
+
"isUnique": false
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
"foreignKeys": {},
|
|
344
|
+
"compositePrimaryKeys": {},
|
|
345
|
+
"uniqueConstraints": {},
|
|
346
|
+
"checkConstraints": {}
|
|
347
|
+
},
|
|
348
|
+
"repo_root": {
|
|
349
|
+
"name": "repo_root",
|
|
350
|
+
"columns": {
|
|
351
|
+
"did": {
|
|
352
|
+
"name": "did",
|
|
353
|
+
"type": "text",
|
|
354
|
+
"primaryKey": true,
|
|
355
|
+
"notNull": true,
|
|
356
|
+
"autoincrement": false
|
|
357
|
+
},
|
|
358
|
+
"commit_cid": {
|
|
359
|
+
"name": "commit_cid",
|
|
360
|
+
"type": "text",
|
|
361
|
+
"primaryKey": false,
|
|
362
|
+
"notNull": true,
|
|
363
|
+
"autoincrement": false
|
|
364
|
+
},
|
|
365
|
+
"rev": {
|
|
366
|
+
"name": "rev",
|
|
367
|
+
"type": "integer",
|
|
368
|
+
"primaryKey": false,
|
|
369
|
+
"notNull": true,
|
|
370
|
+
"autoincrement": false
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
"indexes": {},
|
|
374
|
+
"foreignKeys": {},
|
|
375
|
+
"compositePrimaryKeys": {},
|
|
376
|
+
"uniqueConstraints": {},
|
|
377
|
+
"checkConstraints": {}
|
|
378
|
+
},
|
|
379
|
+
"token_revocation": {
|
|
380
|
+
"name": "token_revocation",
|
|
381
|
+
"columns": {
|
|
382
|
+
"jti": {
|
|
383
|
+
"name": "jti",
|
|
384
|
+
"type": "text",
|
|
385
|
+
"primaryKey": true,
|
|
386
|
+
"notNull": true,
|
|
387
|
+
"autoincrement": false
|
|
388
|
+
},
|
|
389
|
+
"exp": {
|
|
390
|
+
"name": "exp",
|
|
391
|
+
"type": "integer",
|
|
392
|
+
"primaryKey": false,
|
|
393
|
+
"notNull": true,
|
|
394
|
+
"autoincrement": false
|
|
395
|
+
},
|
|
396
|
+
"revoked_at": {
|
|
397
|
+
"name": "revoked_at",
|
|
398
|
+
"type": "integer",
|
|
399
|
+
"primaryKey": false,
|
|
400
|
+
"notNull": true,
|
|
401
|
+
"autoincrement": false
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
"indexes": {
|
|
405
|
+
"token_revocation_exp_idx": {
|
|
406
|
+
"name": "token_revocation_exp_idx",
|
|
407
|
+
"columns": [
|
|
408
|
+
"exp"
|
|
409
|
+
],
|
|
410
|
+
"isUnique": false
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
"foreignKeys": {},
|
|
414
|
+
"compositePrimaryKeys": {},
|
|
415
|
+
"uniqueConstraints": {},
|
|
416
|
+
"checkConstraints": {}
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
"views": {},
|
|
420
|
+
"enums": {},
|
|
421
|
+
"_meta": {
|
|
422
|
+
"schemas": {},
|
|
423
|
+
"tables": {},
|
|
424
|
+
"columns": {}
|
|
425
|
+
},
|
|
426
|
+
"internal": {
|
|
427
|
+
"indexes": {}
|
|
428
|
+
}
|
|
429
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alteran/astro",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Astro integration for running a Cloudflare-hosted Bluesky PDS with Alteran.",
|
|
5
5
|
"module": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"db:apply": "wrangler d1 migrations apply pds",
|
|
38
38
|
"db:apply:local": "bunx wrangler d1 migrations apply pds --local",
|
|
39
39
|
"db:apply:local:direct": "wrangler d1 migrations apply pds --local",
|
|
40
|
-
"db:reset:local": "rm -rf .wrangler/state && rm -rf drizzle && bun run db:generate && bun run db:apply:local"
|
|
40
|
+
"db:reset:local": "rm -rf .wrangler/state && rm -rf drizzle && bun run db:generate && bun run db:apply:local",
|
|
41
|
+
"secrets:setup": "bun run scripts/setup-secrets.ts"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@astrojs/cloudflare": "^12.6.9",
|
package/src/db/dal.ts
CHANGED
|
@@ -95,3 +95,36 @@ export async function checkBlobQuota(env: Env, did: string, additionalBytes: num
|
|
|
95
95
|
|
|
96
96
|
return (quota.total_bytes + additionalBytes) <= maxBytes;
|
|
97
97
|
}
|
|
98
|
+
|
|
99
|
+
// Account state management for migration support
|
|
100
|
+
export async function getAccountState(env: Env, did: string) {
|
|
101
|
+
const db = getDb(env);
|
|
102
|
+
const { account_state } = await import('./schema');
|
|
103
|
+
const state = await db.select().from(account_state).where(eq(account_state.did, did)).get();
|
|
104
|
+
return state ?? null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function createAccountState(env: Env, did: string, active: boolean = false) {
|
|
108
|
+
const db = getDb(env);
|
|
109
|
+
const { account_state } = await import('./schema');
|
|
110
|
+
await db.insert(account_state).values({
|
|
111
|
+
did,
|
|
112
|
+
active,
|
|
113
|
+
created_at: Date.now(),
|
|
114
|
+
}).run();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function setAccountActive(env: Env, did: string, active: boolean) {
|
|
118
|
+
const db = getDb(env);
|
|
119
|
+
const { account_state } = await import('./schema');
|
|
120
|
+
await db.update(account_state)
|
|
121
|
+
.set({ active })
|
|
122
|
+
.where(eq(account_state.did, did))
|
|
123
|
+
.run();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export async function isAccountActive(env: Env, did: string): Promise<boolean> {
|
|
127
|
+
const state = await getAccountState(env, did);
|
|
128
|
+
// If no account state exists, assume active (backward compatibility)
|
|
129
|
+
return state?.active ?? true;
|
|
130
|
+
}
|
package/src/db/schema.ts
CHANGED
|
@@ -85,5 +85,12 @@ export const blob_quota = sqliteTable('blob_quota', {
|
|
|
85
85
|
updated_at: integer('updated_at').notNull(),
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
+
// Account state for migration support (single-user PDS)
|
|
89
|
+
export const account_state = sqliteTable('account_state', {
|
|
90
|
+
did: text('did').primaryKey().notNull(),
|
|
91
|
+
active: integer('active', { mode: 'boolean' }).notNull().default(false),
|
|
92
|
+
created_at: integer('created_at').notNull(),
|
|
93
|
+
});
|
|
94
|
+
|
|
88
95
|
export type RecordRow = typeof record.$inferSelect;
|
|
89
96
|
export type NewRecordRow = typeof record.$inferInsert;
|