+12
jsconfig.json
+12
jsconfig.json
+14
-10
src/pds.js
+14
-10
src/pds.js
···
1
+
// @ts-check
1
2
/**
2
3
* Minimal AT Protocol Personal Data Server (PDS)
3
4
*
···
290
291
291
292
/**
292
293
* Create a CIDv1 (dag-cbor + sha-256) from raw bytes
293
-
* @param {Uint8Array} bytes - Content to hash
294
+
* @param {Uint8Array<ArrayBuffer>} bytes - Content to hash
294
295
* @returns {Promise<Uint8Array>} CID bytes (36 bytes: version + codec + multihash)
295
296
*/
296
297
export async function createCid(bytes) {
···
449
450
/**
450
451
* Sign data with ECDSA P-256, returning low-S normalized signature
451
452
* @param {CryptoKey} privateKey - Web Crypto key from importPrivateKey
452
-
* @param {Uint8Array} data - Data to sign
453
+
* @param {Uint8Array<ArrayBuffer>} data - Data to sign
453
454
* @returns {Promise<Uint8Array>} 64-byte signature (r || s)
454
455
*/
455
456
export async function sign(privateKey, data) {
···
1001
1002
* Build a CAR (Content Addressable aRchive) file
1002
1003
* @param {string} rootCid - Root CID string
1003
1004
* @param {Array<{cid: string, data: Uint8Array}>} blocks - Blocks to include
1004
-
* @returns {Uint8Array} CAR file bytes
1005
+
* @returns {Uint8Array<ArrayBuffer>} CAR file bytes
1005
1006
*/
1006
1007
export function buildCarFile(rootCid, blocks) {
1007
1008
const parts = [];
···
1086
1087
handler: (pds, _req, _url) => pds.handleRepoInfo(),
1087
1088
},
1088
1089
'/xrpc/com.atproto.server.describeServer': {
1089
-
handler: (pds, req, _url) => pds.handleDescribeServer(req),
1090
+
handler: async (pds, req, _url) => pds.handleDescribeServer(req),
1090
1091
},
1091
1092
'/xrpc/com.atproto.server.createSession': {
1092
1093
method: 'POST',
···
1135
1136
handler: (pds, _req, url) => pds.handleListRecords(url),
1136
1137
},
1137
1138
'/xrpc/com.atproto.sync.getLatestCommit': {
1138
-
handler: (pds, _req, _url) => pds.handleGetLatestCommit(),
1139
+
handler: async (pds, _req, _url) => pds.handleGetLatestCommit(),
1139
1140
},
1140
1141
'/xrpc/com.atproto.sync.getRepoStatus': {
1141
1142
handler: (pds, _req, _url) => pds.handleGetRepoStatus(),
1142
1143
},
1143
1144
'/xrpc/com.atproto.sync.getRepo': {
1144
-
handler: (pds, _req, _url) => pds.handleGetRepo(),
1145
+
handler: async (pds, _req, _url) => pds.handleGetRepo(),
1145
1146
},
1146
1147
'/xrpc/com.atproto.sync.getRecord': {
1147
1148
handler: (pds, _req, url) => pds.handleSyncGetRecord(url),
1148
1149
},
1149
1150
'/xrpc/com.atproto.sync.subscribeRepos': {
1150
-
handler: (pds, req, url) => pds.handleSubscribeRepos(req, url),
1151
+
handler: async (pds, req, url) => pds.handleSubscribeRepos(req, url),
1151
1152
},
1152
1153
};
1153
1154
···
2386
2387
* Verify auth and return DID from token
2387
2388
* @param {Request} request - HTTP request with Authorization header
2388
2389
* @param {Object} env - Environment with JWT_SECRET
2389
-
* @returns {Promise<{did: string} | {error: Response}>} DID or error response
2390
+
* @returns {Promise<{did:string|null, error:Response|null}>} DID or error response
2390
2391
*/
2391
-
async function requireAuth(request, env) {
2392
+
async function requireAuth (request, env) {
2392
2393
const authHeader = request.headers.get('Authorization');
2393
2394
if (!authHeader || !authHeader.startsWith('Bearer ')) {
2394
2395
return {
2396
+
did: null,
2395
2397
error: Response.json(
2396
2398
{
2397
2399
error: 'AuthRequired',
···
2406
2408
const jwtSecret = env?.JWT_SECRET;
2407
2409
if (!jwtSecret) {
2408
2410
return {
2411
+
did: null,
2409
2412
error: Response.json(
2410
2413
{
2411
2414
error: 'InternalServerError',
···
2418
2421
2419
2422
try {
2420
2423
const payload = await verifyAccessJwt(token, jwtSecret);
2421
-
return { did: payload.sub };
2424
+
return { did: payload.sub, error: null };
2422
2425
} catch (err) {
2423
2426
return {
2427
+
did: null,
2424
2428
error: Response.json(
2425
2429
{
2426
2430
error: 'InvalidToken',