@getcirrus/pds 0.9.0 → 0.10.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 +29 -0
- package/dist/cli.js +71 -5
- package/dist/index.d.ts +36 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +77 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -343,6 +343,7 @@ The PDS uses environment variables for configuration. Public values go in `wrang
|
|
|
343
343
|
| `HANDLE` | Account handle |
|
|
344
344
|
| `SIGNING_KEY_PUBLIC` | Public key for DID document (multibase) |
|
|
345
345
|
| `INITIAL_ACTIVE` | Whether account starts active (true/false) |
|
|
346
|
+
| `DATA_LOCATION` | Data placement (optional, see below) |
|
|
346
347
|
|
|
347
348
|
### Secrets
|
|
348
349
|
|
|
@@ -353,6 +354,31 @@ The PDS uses environment variables for configuration. Public values go in `wrang
|
|
|
353
354
|
| `JWT_SECRET` | Secret for signing session JWTs |
|
|
354
355
|
| `PASSWORD_HASH` | Bcrypt hash of password for app login |
|
|
355
356
|
|
|
357
|
+
### Data Placement
|
|
358
|
+
|
|
359
|
+
Cirrus supports Cloudflare's Durable Object [data placement features](https://developers.cloudflare.com/durable-objects/reference/data-location/) for users who need control over where their data is stored. By default a durable object is created near to the first location it is accessed from. This is likely to be correct for most users. However, if you have specific data residency requirements, you can set the `DATA_LOCATION` environment variable to control where your Durable Object is placed. This only affects the location of the Durable Object instance that stores your PDS data. ATProto data is globally distributed via relays, so this does not limit access to your data from other regions.
|
|
360
|
+
|
|
361
|
+
> [!WARNING]
|
|
362
|
+
> Once a Durable Object is created, its location cannot be changed. Therefore, you should set `DATA_LOCATION` before the first deployment of your PDS. Changing this value after deployment will break your installation, as existing data will not be migrated.
|
|
363
|
+
|
|
364
|
+
Supported values for `DATA_LOCATION`:
|
|
365
|
+
|
|
366
|
+
- **Auto** (`auto`): Default behaviour. Cloudflare places the DO near the first access location.
|
|
367
|
+
- **Jurisdiction** (`eu`): Hard guarantee that data never leaves the region. Use this for compliance requirements.
|
|
368
|
+
- **Hints** (`wnam`, `enam`, `weur`, `eeur`, `apac`, `oc`). Best-effort suggestions for initial placement region. Cloudflare may place the DO elsewhere based on availability. See [supported locations](https://developers.cloudflare.com/durable-objects/reference/data-location/#supported-locations-1) for more details)
|
|
369
|
+
|
|
370
|
+
Example in `wrangler.jsonc`:
|
|
371
|
+
|
|
372
|
+
```jsonc
|
|
373
|
+
{
|
|
374
|
+
"vars": {
|
|
375
|
+
"DATA_LOCATION": "eu",
|
|
376
|
+
},
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
See [Cloudflare's data location documentation](https://developers.cloudflare.com/durable-objects/reference/data-location/) for more details.
|
|
381
|
+
|
|
356
382
|
## API Endpoints
|
|
357
383
|
|
|
358
384
|
### Identity
|
|
@@ -473,6 +499,7 @@ npx pds migrate
|
|
|
473
499
|
```
|
|
474
500
|
|
|
475
501
|
The migrate command:
|
|
502
|
+
|
|
476
503
|
- Resolves your DID to find the current PDS
|
|
477
504
|
- Authenticates with your source PDS
|
|
478
505
|
- Downloads the repository (posts, follows, likes, etc.)
|
|
@@ -488,6 +515,7 @@ npx pds identity
|
|
|
488
515
|
```
|
|
489
516
|
|
|
490
517
|
This updates your DID document to point to your new PDS. The command:
|
|
518
|
+
|
|
491
519
|
1. Authenticates with your source PDS (requires password)
|
|
492
520
|
2. Requests an email confirmation token
|
|
493
521
|
3. Gets the source PDS to sign a PLC operation with your new endpoint
|
|
@@ -510,6 +538,7 @@ npx pds status
|
|
|
510
538
|
```
|
|
511
539
|
|
|
512
540
|
Check that:
|
|
541
|
+
|
|
513
542
|
- The account is active
|
|
514
543
|
- The repository has the expected number of records
|
|
515
544
|
- Your handle resolves correctly
|
package/dist/cli.js
CHANGED
|
@@ -1768,7 +1768,8 @@ const initCommand = defineCommand({
|
|
|
1768
1768
|
try {
|
|
1769
1769
|
cfSecrets = await listSecrets();
|
|
1770
1770
|
} catch {}
|
|
1771
|
-
|
|
1771
|
+
const signingKeyInCloudflare = cfSecrets.includes("SIGNING_KEY");
|
|
1772
|
+
if (signingKeyInCloudflare && !devVars.SIGNING_KEY) {
|
|
1772
1773
|
p.log.error("⚠️ Signing key exists in Cloudflare but not locally!");
|
|
1773
1774
|
p.note([
|
|
1774
1775
|
"Your PDS has a signing key deployed to Cloudflare, but you don't have",
|
|
@@ -1948,6 +1949,55 @@ const initCommand = defineCommand({
|
|
|
1948
1949
|
` containing: ${did}`
|
|
1949
1950
|
].join("\n"), "Identity Setup 🪪");
|
|
1950
1951
|
}
|
|
1952
|
+
let dataLocation;
|
|
1953
|
+
if (currentVars.DATA_LOCATION) dataLocation = currentVars.DATA_LOCATION;
|
|
1954
|
+
else {
|
|
1955
|
+
dataLocation = await promptSelect({
|
|
1956
|
+
message: "Where should your data be stored?",
|
|
1957
|
+
options: [
|
|
1958
|
+
{
|
|
1959
|
+
value: "auto",
|
|
1960
|
+
label: "Auto (Recommended)",
|
|
1961
|
+
hint: "Cloudflare chooses optimal location"
|
|
1962
|
+
},
|
|
1963
|
+
{
|
|
1964
|
+
value: "eu",
|
|
1965
|
+
label: "European Union",
|
|
1966
|
+
hint: "GDPR jurisdiction guarantee"
|
|
1967
|
+
},
|
|
1968
|
+
{
|
|
1969
|
+
value: "wnam",
|
|
1970
|
+
label: "Western North America",
|
|
1971
|
+
hint: "Location hint"
|
|
1972
|
+
},
|
|
1973
|
+
{
|
|
1974
|
+
value: "enam",
|
|
1975
|
+
label: "Eastern North America",
|
|
1976
|
+
hint: "Location hint"
|
|
1977
|
+
},
|
|
1978
|
+
{
|
|
1979
|
+
value: "apac",
|
|
1980
|
+
label: "Asia-Pacific",
|
|
1981
|
+
hint: "Location hint"
|
|
1982
|
+
},
|
|
1983
|
+
{
|
|
1984
|
+
value: "oc",
|
|
1985
|
+
label: "Oceania",
|
|
1986
|
+
hint: "Location hint"
|
|
1987
|
+
}
|
|
1988
|
+
]
|
|
1989
|
+
});
|
|
1990
|
+
if (dataLocation && dataLocation !== "auto") {
|
|
1991
|
+
p.log.warn("⚠️ Data location cannot be changed after deployment!");
|
|
1992
|
+
p.note([
|
|
1993
|
+
"Durable Objects cannot be relocated once created.",
|
|
1994
|
+
"If you deploy with this setting and later change it,",
|
|
1995
|
+
"existing data will become inaccessible.",
|
|
1996
|
+
"",
|
|
1997
|
+
`You selected: ${dataLocation}`
|
|
1998
|
+
].join("\n"), "Important");
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
1951
2001
|
const spinner = p.spinner();
|
|
1952
2002
|
const authToken = await getOrGenerateSecret("AUTH_TOKEN", devVars, async () => {
|
|
1953
2003
|
spinner.start("Generating auth token...");
|
|
@@ -2070,7 +2120,8 @@ const initCommand = defineCommand({
|
|
|
2070
2120
|
DID: did,
|
|
2071
2121
|
HANDLE: handle,
|
|
2072
2122
|
SIGNING_KEY_PUBLIC: signingKeyPublic,
|
|
2073
|
-
INITIAL_ACTIVE: initialActive
|
|
2123
|
+
INITIAL_ACTIVE: initialActive,
|
|
2124
|
+
DATA_LOCATION: dataLocation
|
|
2074
2125
|
});
|
|
2075
2126
|
setCustomDomains([hostname]);
|
|
2076
2127
|
spinner.stop("wrangler.jsonc updated");
|
|
@@ -2102,12 +2153,12 @@ const initCommand = defineCommand({
|
|
|
2102
2153
|
if (!isProduction) {
|
|
2103
2154
|
const deployNow = await p.confirm({
|
|
2104
2155
|
message: "Push secrets to Cloudflare now?",
|
|
2105
|
-
initialValue:
|
|
2156
|
+
initialValue: true
|
|
2106
2157
|
});
|
|
2107
2158
|
if (!p.isCancel(deployNow) && deployNow) {
|
|
2108
2159
|
spinner.start("Deploying secrets to Cloudflare...");
|
|
2109
2160
|
await setSecretValue("AUTH_TOKEN", authToken, false);
|
|
2110
|
-
if (
|
|
2161
|
+
if (!signingKeyInCloudflare) await setSecretValue("SIGNING_KEY", signingKey, false);
|
|
2111
2162
|
await setSecretValue("JWT_SECRET", jwtSecret, false);
|
|
2112
2163
|
await setSecretValue("PASSWORD_HASH", passwordHash, false);
|
|
2113
2164
|
spinner.stop("Secrets deployed to Cloudflare");
|
|
@@ -2158,7 +2209,22 @@ const initCommand = defineCommand({
|
|
|
2158
2209
|
}
|
|
2159
2210
|
if (deployed) p.outro(`Your PDS is live at https://${hostname}! 🚀`);
|
|
2160
2211
|
else if (deployedSecrets) p.outro(`Run '${formatCommand(pm, "deploy")}' to launch your PDS! 🚀`);
|
|
2161
|
-
else
|
|
2212
|
+
else {
|
|
2213
|
+
p.note([
|
|
2214
|
+
"To deploy your PDS, first push your secrets to Cloudflare:",
|
|
2215
|
+
"",
|
|
2216
|
+
` ${formatCommand(pm, "pds", "init")}`,
|
|
2217
|
+
"",
|
|
2218
|
+
"Then deploy:",
|
|
2219
|
+
"",
|
|
2220
|
+
` ${formatCommand(pm, "deploy")}`,
|
|
2221
|
+
"",
|
|
2222
|
+
"Or to test locally first:",
|
|
2223
|
+
"",
|
|
2224
|
+
` ${formatCommand(pm, "dev")}`
|
|
2225
|
+
].join("\n"), "Next Steps");
|
|
2226
|
+
p.outro("Configuration saved to .dev.vars");
|
|
2227
|
+
}
|
|
2162
2228
|
}
|
|
2163
2229
|
});
|
|
2164
2230
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -250,6 +250,27 @@ interface BlobRef {
|
|
|
250
250
|
}
|
|
251
251
|
//#endregion
|
|
252
252
|
//#region src/types.d.ts
|
|
253
|
+
/**
|
|
254
|
+
* Data location options for Durable Object placement.
|
|
255
|
+
*
|
|
256
|
+
* - "auto": No location constraint (default, recommended)
|
|
257
|
+
* - "eu": European Union - hard guarantee data never leaves EU
|
|
258
|
+
* - Location hints (best-effort, not guaranteed):
|
|
259
|
+
* - "wnam": Western North America
|
|
260
|
+
* - "enam": Eastern North America
|
|
261
|
+
* - "sam": South America
|
|
262
|
+
* - "weur": Western Europe
|
|
263
|
+
* - "eeur": Eastern Europe
|
|
264
|
+
* - "apac": Asia-Pacific
|
|
265
|
+
* - "oc": Oceania
|
|
266
|
+
* - "afr": Africa
|
|
267
|
+
* - "me": Middle East
|
|
268
|
+
*
|
|
269
|
+
* IMPORTANT: This setting only affects newly-created Durable Objects.
|
|
270
|
+
* Changing this after initial deployment will NOT migrate existing data.
|
|
271
|
+
* To relocate data, you must export and re-import to a new PDS.
|
|
272
|
+
*/
|
|
273
|
+
type DataLocation = "auto" | "eu" | "wnam" | "enam" | "sam" | "weur" | "eeur" | "apac" | "oc" | "afr" | "me";
|
|
253
274
|
/**
|
|
254
275
|
* Environment bindings required by the PDS worker.
|
|
255
276
|
* Consumers must provide these bindings in their wrangler config.
|
|
@@ -277,6 +298,20 @@ interface PDSEnv {
|
|
|
277
298
|
BLOBS?: R2Bucket;
|
|
278
299
|
/** Initial activation state for new accounts (default: true) */
|
|
279
300
|
INITIAL_ACTIVE?: string;
|
|
301
|
+
/**
|
|
302
|
+
* Data location for Durable Object placement.
|
|
303
|
+
*
|
|
304
|
+
* WARNING: DO NOT CHANGE THIS AFTER INITIAL DEPLOYMENT.
|
|
305
|
+
* This setting only affects newly-created DOs. Changing it will NOT
|
|
306
|
+
* migrate existing data and may cause issues.
|
|
307
|
+
*
|
|
308
|
+
* Options:
|
|
309
|
+
* - "auto" or unset: No location constraint (default, recommended)
|
|
310
|
+
* - "eu": European Union - hard guarantee data never leaves EU
|
|
311
|
+
* - Location hints (best-effort, not guaranteed):
|
|
312
|
+
* "wnam", "enam", "sam", "weur", "eeur", "apac", "oc", "afr", "me"
|
|
313
|
+
*/
|
|
314
|
+
DATA_LOCATION?: DataLocation;
|
|
280
315
|
}
|
|
281
316
|
//#endregion
|
|
282
317
|
//#region src/account-do.d.ts
|
|
@@ -659,5 +694,5 @@ declare const app: Hono<{
|
|
|
659
694
|
Bindings: PDSEnv;
|
|
660
695
|
}, hono_types0.BlankSchema, "/">;
|
|
661
696
|
//#endregion
|
|
662
|
-
export { AccountDurableObject, type PDSEnv, app as default };
|
|
697
|
+
export { AccountDurableObject, type DataLocation, type PDSEnv, app as default };
|
|
663
698
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/storage.ts","../src/oauth-storage.ts","../src/blobs.ts","../src/types.ts","../src/account-do.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;cAUa,iBAAA,SACJ,kBAAA,YACG;EAFC,QAAA,GAAA;EAIa,WAAA,CAAA,GAAA,EAAA,UAAA;EA2FA;;;;EAiCR,UAAA,CAAA,aAAA,CAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAQG;;;EAcL,OAAA,CAAA,CAAA,EAvDE,OAuDF,CAvDU,GAuDV,GAAA,IAAA,CAAA;EAAM;;;EAU8C,MAAA,CAAA,CAAA,EApDnD,OAoDmD,CAAA,MAAA,GAAA,IAAA,CAAA;EAArC;;;EAmB4B,MAAA,CAAA,CAAA,EA7D1C,OA6D0C,CAAA,MAAA,CAAA;EAYpC;;;EAoBmB,OAAA,CAAA,CAAA,EAnFxB,OAmFwB,CAAA,MAAA,CAAA;EAWf;;;EA6CT,QAAA,CAAA,GAAA,EAnIG,GAmIH,CAAA,EAnIS,OAmIT,CAnIiB,UAmIjB,GAAA,IAAA,CAAA;EAUI;;;EAoCF,GAAA,CAAA,GAAA,EAnKJ,GAmKI,CAAA,EAnKE,OAmKF,CAAA,OAAA,CAAA;EAUe;;;EA2JtB,SAAA,CAAA,IAAA,EA9TU,GA8TV,EAAA,CAAA,EA9TkB,OA8TlB,CAAA;IA8BI,MAAA,EA5VgC,QA4VhC;IA3fR,OAAA,EA+J2D,GA/J3D,EAAA;EACG,CAAA,CAAA;EAAW;;;gBAiLF,YAAY,0BAA0B;EC/K9C;;;EAuG0C,OAAA,CAAA,MAAA,EDoFhC,QCpFgC,EAAA,GAAA,EAAA,MAAA,CAAA,EDoFR,OCpFQ,CAAA,IAAA,CAAA;EAgBb;;;EAsClB,UAAA,CAAA,GAAA,EDkDD,GClDC,EAAA,GAAA,EAAA,MAAA,CAAA,EDkDkB,OClDlB,CAAA,IAAA,CAAA;EAAY;;;EAiDoB,WAAA,CAAA,MAAA,EDY7B,UCZ6B,CAAA,EDYhB,OCZgB,CAAA,IAAA,CAAA;EAAR;;;EA4CF,WAAA,CAAA,CAAA,EDGxB,OCHwB,CAAA,MAAA,CAAA;EAAiB;;;EAwCtB,OAAA,CAAA,CAAA,ED3BvB,OC2BuB,CAAA,IAAA,CAAA;EAAU;;;EAuCb,WAAA,CAAA,CAAA,EDxDhB,OCwDgB,CAAA,MAAA,CAAA;EAWG;;;oBDzDhB;;;AEvSzB;0CFyT+C;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/storage.ts","../src/oauth-storage.ts","../src/blobs.ts","../src/types.ts","../src/account-do.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { CODEC_RAW, create, fromString, toString } from "@atcute/cid";
|
|
|
8
8
|
import { Hono } from "hono";
|
|
9
9
|
import { cors } from "hono/cors";
|
|
10
10
|
import { isDid, isHandle, isNsid, isRecordKey } from "@atcute/lexicons/syntax";
|
|
11
|
-
import { SignJWT, base64url, jwtVerify } from "jose";
|
|
11
|
+
import { SignJWT, base64url, errors, jwtVerify } from "jose";
|
|
12
12
|
import { compare, compare as compare$1 } from "bcryptjs";
|
|
13
13
|
import { ATProtoOAuthProvider } from "@getcirrus/oauth-provider";
|
|
14
14
|
import { generateAuthenticationOptions, generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse } from "@simplewebauthn/server";
|
|
@@ -1917,7 +1917,17 @@ async function verifyServiceJwt(token, signingKey, expectedAudience, expectedIss
|
|
|
1917
1917
|
|
|
1918
1918
|
//#endregion
|
|
1919
1919
|
//#region src/session.ts
|
|
1920
|
-
|
|
1920
|
+
/**
|
|
1921
|
+
* Error thrown when a JWT has expired.
|
|
1922
|
+
* Callers should return HTTP 400 with error code 'ExpiredToken'.
|
|
1923
|
+
*/
|
|
1924
|
+
var TokenExpiredError = class extends Error {
|
|
1925
|
+
constructor(message = "Token has expired") {
|
|
1926
|
+
super(message);
|
|
1927
|
+
this.name = "TokenExpiredError";
|
|
1928
|
+
}
|
|
1929
|
+
};
|
|
1930
|
+
const ACCESS_TOKEN_LIFETIME = "120m";
|
|
1921
1931
|
const REFRESH_TOKEN_LIFETIME = "90d";
|
|
1922
1932
|
/**
|
|
1923
1933
|
* Create a secret key from string for HS256 signing
|
|
@@ -1930,44 +1940,58 @@ function createSecretKey(secret) {
|
|
|
1930
1940
|
*/
|
|
1931
1941
|
async function createAccessToken(jwtSecret, userDid, serviceDid) {
|
|
1932
1942
|
const secret = createSecretKey(jwtSecret);
|
|
1933
|
-
return new SignJWT({ scope: "atproto" }).setProtectedHeader({
|
|
1943
|
+
return new SignJWT({ scope: "com.atproto.access" }).setProtectedHeader({
|
|
1934
1944
|
alg: "HS256",
|
|
1935
1945
|
typ: "at+jwt"
|
|
1936
|
-
}).setIssuedAt().
|
|
1946
|
+
}).setIssuedAt().setAudience(serviceDid).setSubject(userDid).setExpirationTime(ACCESS_TOKEN_LIFETIME).sign(secret);
|
|
1937
1947
|
}
|
|
1938
1948
|
/**
|
|
1939
1949
|
* Create a refresh token (long-lived, 90 days)
|
|
1940
1950
|
*/
|
|
1941
1951
|
async function createRefreshToken(jwtSecret, userDid, serviceDid) {
|
|
1942
1952
|
const secret = createSecretKey(jwtSecret);
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
jti: crypto.randomUUID()
|
|
1946
|
-
}).setProtectedHeader({
|
|
1953
|
+
const jti = crypto.randomUUID();
|
|
1954
|
+
return new SignJWT({ scope: "com.atproto.refresh" }).setProtectedHeader({
|
|
1947
1955
|
alg: "HS256",
|
|
1948
1956
|
typ: "refresh+jwt"
|
|
1949
|
-
}).setIssuedAt().
|
|
1957
|
+
}).setIssuedAt().setAudience(serviceDid).setSubject(userDid).setJti(jti).setExpirationTime(REFRESH_TOKEN_LIFETIME).sign(secret);
|
|
1950
1958
|
}
|
|
1951
1959
|
/**
|
|
1952
|
-
* Verify an access token and return the payload
|
|
1960
|
+
* Verify an access token and return the payload.
|
|
1961
|
+
* Throws TokenExpiredError if the token has expired.
|
|
1953
1962
|
*/
|
|
1954
1963
|
async function verifyAccessToken(token, jwtSecret, serviceDid) {
|
|
1955
|
-
const
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1964
|
+
const secret = createSecretKey(jwtSecret);
|
|
1965
|
+
let payload;
|
|
1966
|
+
let protectedHeader;
|
|
1967
|
+
try {
|
|
1968
|
+
const result = await jwtVerify(token, secret, { audience: serviceDid });
|
|
1969
|
+
payload = result.payload;
|
|
1970
|
+
protectedHeader = result.protectedHeader;
|
|
1971
|
+
} catch (err) {
|
|
1972
|
+
if (err instanceof errors.JWTExpired) throw new TokenExpiredError();
|
|
1973
|
+
throw err;
|
|
1974
|
+
}
|
|
1959
1975
|
if (protectedHeader.typ !== "at+jwt") throw new Error("Invalid token type");
|
|
1960
|
-
if (payload.scope !== "atproto") throw new Error("Invalid scope");
|
|
1976
|
+
if (payload.scope !== "com.atproto.access") throw new Error("Invalid scope");
|
|
1961
1977
|
return payload;
|
|
1962
1978
|
}
|
|
1963
1979
|
/**
|
|
1964
|
-
* Verify a refresh token and return the payload
|
|
1980
|
+
* Verify a refresh token and return the payload.
|
|
1981
|
+
* Throws TokenExpiredError if the token has expired.
|
|
1965
1982
|
*/
|
|
1966
1983
|
async function verifyRefreshToken(token, jwtSecret, serviceDid) {
|
|
1967
|
-
const
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1984
|
+
const secret = createSecretKey(jwtSecret);
|
|
1985
|
+
let payload;
|
|
1986
|
+
let protectedHeader;
|
|
1987
|
+
try {
|
|
1988
|
+
const result = await jwtVerify(token, secret, { audience: serviceDid });
|
|
1989
|
+
payload = result.payload;
|
|
1990
|
+
protectedHeader = result.protectedHeader;
|
|
1991
|
+
} catch (err) {
|
|
1992
|
+
if (err instanceof errors.JWTExpired) throw new TokenExpiredError();
|
|
1993
|
+
throw err;
|
|
1994
|
+
}
|
|
1971
1995
|
if (protectedHeader.typ !== "refresh+jwt") throw new Error("Invalid token type");
|
|
1972
1996
|
if (payload.scope !== "com.atproto.refresh") throw new Error("Invalid scope");
|
|
1973
1997
|
if (!payload.jti) throw new Error("Missing token ID");
|
|
@@ -2372,7 +2396,7 @@ async function requireAuth(c, next) {
|
|
|
2372
2396
|
if (token === c.env.AUTH_TOKEN) {
|
|
2373
2397
|
c.set("auth", {
|
|
2374
2398
|
did: c.env.DID,
|
|
2375
|
-
scope: "atproto"
|
|
2399
|
+
scope: "com.atproto.access"
|
|
2376
2400
|
});
|
|
2377
2401
|
return next();
|
|
2378
2402
|
}
|
|
@@ -2388,7 +2412,12 @@ async function requireAuth(c, next) {
|
|
|
2388
2412
|
scope: payload.scope
|
|
2389
2413
|
});
|
|
2390
2414
|
return next();
|
|
2391
|
-
} catch {
|
|
2415
|
+
} catch (err) {
|
|
2416
|
+
if (err instanceof TokenExpiredError) return c.json({
|
|
2417
|
+
error: "ExpiredToken",
|
|
2418
|
+
message: err.message
|
|
2419
|
+
}, 400);
|
|
2420
|
+
}
|
|
2392
2421
|
try {
|
|
2393
2422
|
const payload = await verifyServiceJwt(token, c.env.SIGNING_KEY, serviceDid, c.env.DID);
|
|
2394
2423
|
c.set("auth", {
|
|
@@ -2601,7 +2630,12 @@ async function handleXrpcProxy(c, didResolver$1, getKeypair$1) {
|
|
|
2601
2630
|
const payload = await verifyAccessToken(token, c.env.JWT_SECRET, serviceDid);
|
|
2602
2631
|
if (payload.sub) userDid = payload.sub;
|
|
2603
2632
|
}
|
|
2604
|
-
} catch {
|
|
2633
|
+
} catch (err) {
|
|
2634
|
+
if (err instanceof TokenExpiredError) return c.json({
|
|
2635
|
+
error: "ExpiredToken",
|
|
2636
|
+
message: err.message
|
|
2637
|
+
}, 400);
|
|
2638
|
+
}
|
|
2605
2639
|
}
|
|
2606
2640
|
if (userDid) try {
|
|
2607
2641
|
const keypair = await getKeypair$1();
|
|
@@ -3223,6 +3257,7 @@ async function createSession(c) {
|
|
|
3223
3257
|
refreshJwt,
|
|
3224
3258
|
handle: c.env.HANDLE,
|
|
3225
3259
|
did: c.env.DID,
|
|
3260
|
+
emailConfirmed: false,
|
|
3226
3261
|
active: true
|
|
3227
3262
|
});
|
|
3228
3263
|
}
|
|
@@ -3249,11 +3284,16 @@ async function refreshSession(c) {
|
|
|
3249
3284
|
refreshJwt,
|
|
3250
3285
|
handle: c.env.HANDLE,
|
|
3251
3286
|
did: c.env.DID,
|
|
3287
|
+
emailConfirmed: false,
|
|
3252
3288
|
active: true
|
|
3253
3289
|
});
|
|
3254
3290
|
} catch (err) {
|
|
3255
|
-
return c.json({
|
|
3291
|
+
if (err instanceof TokenExpiredError) return c.json({
|
|
3256
3292
|
error: "ExpiredToken",
|
|
3293
|
+
message: err.message
|
|
3294
|
+
}, 400);
|
|
3295
|
+
return c.json({
|
|
3296
|
+
error: "InvalidToken",
|
|
3257
3297
|
message: err instanceof Error ? err.message : "Invalid refresh token"
|
|
3258
3298
|
}, 400);
|
|
3259
3299
|
}
|
|
@@ -3272,6 +3312,7 @@ async function getSession(c) {
|
|
|
3272
3312
|
if (token === c.env.AUTH_TOKEN) return c.json({
|
|
3273
3313
|
handle: c.env.HANDLE,
|
|
3274
3314
|
did: c.env.DID,
|
|
3315
|
+
emailConfirmed: false,
|
|
3275
3316
|
active: true
|
|
3276
3317
|
});
|
|
3277
3318
|
try {
|
|
@@ -3282,9 +3323,14 @@ async function getSession(c) {
|
|
|
3282
3323
|
return c.json({
|
|
3283
3324
|
handle: c.env.HANDLE,
|
|
3284
3325
|
did: c.env.DID,
|
|
3326
|
+
emailConfirmed: false,
|
|
3285
3327
|
active: true
|
|
3286
3328
|
});
|
|
3287
3329
|
} catch (err) {
|
|
3330
|
+
if (err instanceof TokenExpiredError) return c.json({
|
|
3331
|
+
error: "ExpiredToken",
|
|
3332
|
+
message: err.message
|
|
3333
|
+
}, 400);
|
|
3288
3334
|
return c.json({
|
|
3289
3335
|
error: "InvalidToken",
|
|
3290
3336
|
message: err instanceof Error ? err.message : "Invalid access token"
|
|
@@ -3998,7 +4044,7 @@ function renderPasskeyErrorPage(error, description) {
|
|
|
3998
4044
|
|
|
3999
4045
|
//#endregion
|
|
4000
4046
|
//#region package.json
|
|
4001
|
-
var version = "0.
|
|
4047
|
+
var version = "0.10.0";
|
|
4002
4048
|
|
|
4003
4049
|
//#endregion
|
|
4004
4050
|
//#region src/index.ts
|
|
@@ -4040,7 +4086,13 @@ app.use("*", cors({
|
|
|
4040
4086
|
maxAge: 86400
|
|
4041
4087
|
}));
|
|
4042
4088
|
function getAccountDO(env$2) {
|
|
4089
|
+
const location = env$2.DATA_LOCATION;
|
|
4090
|
+
if (location === "eu") {
|
|
4091
|
+
const namespace = env$2.ACCOUNT.jurisdiction("eu");
|
|
4092
|
+
return namespace.get(namespace.idFromName("account"));
|
|
4093
|
+
}
|
|
4043
4094
|
const id = env$2.ACCOUNT.idFromName("account");
|
|
4095
|
+
if (location && location !== "auto") return env$2.ACCOUNT.get(id, { locationHint: location });
|
|
4044
4096
|
return env$2.ACCOUNT.get(id);
|
|
4045
4097
|
}
|
|
4046
4098
|
app.get("/.well-known/did.json", (c) => {
|