@atproto/identity 0.2.1 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @atproto/identity
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1773](https://github.com/bluesky-social/atproto/pull/1773) [`bb039d8e`](https://github.com/bluesky-social/atproto/commit/bb039d8e4ce5b7f70c4f3e86d1327e210ef24dc3) Thanks [@dholms](https://github.com/dholms)! - Pass stale did doc into refresh cache functions
8
+
9
+ ### Patch Changes
10
+
11
+ - [`35d108ce`](https://github.com/bluesky-social/atproto/commit/35d108ce94866ce1b3d147cd0620a0ba1c4ebcd7) Thanks [@devinivy](https://github.com/devinivy)! - Allow pds to serve did doc with credentials, API client to respect PDS listed in the did doc.
12
+
13
+ - Updated dependencies [[`35d108ce`](https://github.com/bluesky-social/atproto/commit/35d108ce94866ce1b3d147cd0620a0ba1c4ebcd7)]:
14
+ - @atproto/common-web@0.2.2
15
+
3
16
  ## 0.2.1
4
17
 
5
18
  ### Patch Changes
@@ -1,9 +1,6 @@
1
1
  import { DidDocument, AtprotoData } from '../types';
2
- export declare const getDid: (doc: DidDocument) => string;
2
+ import { getDid, getHandle, getPdsEndpoint, getFeedGenEndpoint, getNotifEndpoint } from '@atproto/common-web';
3
+ export { getDid, getHandle, getPdsEndpoint as getPds, getFeedGenEndpoint as getFeedGen, getNotifEndpoint as getNotif, };
3
4
  export declare const getKey: (doc: DidDocument) => string | undefined;
4
- export declare const getHandle: (doc: DidDocument) => string | undefined;
5
- export declare const getPds: (doc: DidDocument) => string | undefined;
6
- export declare const getFeedGen: (doc: DidDocument) => string | undefined;
7
- export declare const getNotif: (doc: DidDocument) => string | undefined;
8
5
  export declare const parseToAtprotoDocument: (doc: DidDocument) => Partial<AtprotoData>;
9
6
  export declare const ensureAtpDocument: (doc: DidDocument) => AtprotoData;
@@ -1,11 +1,11 @@
1
- import { DidCache, AtprotoData, DidDocument } from '../types';
1
+ import { DidCache, AtprotoData, DidDocument, CacheResult } from '../types';
2
2
  export declare abstract class BaseResolver {
3
3
  cache?: DidCache | undefined;
4
4
  constructor(cache?: DidCache | undefined);
5
5
  abstract resolveNoCheck(did: string): Promise<unknown | null>;
6
6
  validateDidDoc(did: string, val: unknown): DidDocument;
7
7
  resolveNoCache(did: string): Promise<DidDocument | null>;
8
- refreshCache(did: string): Promise<void>;
8
+ refreshCache(did: string, prevResult?: CacheResult): Promise<void>;
9
9
  resolve(did: string, forceRefresh?: boolean): Promise<DidDocument | null>;
10
10
  ensureResolve(did: string, forceRefresh?: boolean): Promise<DidDocument>;
11
11
  resolveAtprotoData(did: string, forceRefresh?: boolean): Promise<AtprotoData>;
package/dist/index.js CHANGED
@@ -21171,14 +21171,12 @@ __export(src_exports3, {
21171
21171
  didDocument: () => didDocument,
21172
21172
  ensureAtpDocument: () => ensureAtpDocument,
21173
21173
  getDid: () => getDid,
21174
- getFeedGen: () => getFeedGen,
21174
+ getFeedGen: () => getFeedGenEndpoint,
21175
21175
  getHandle: () => getHandle,
21176
21176
  getKey: () => getKey,
21177
- getNotif: () => getNotif,
21178
- getPds: () => getPds,
21179
- parseToAtprotoDocument: () => parseToAtprotoDocument,
21180
- service: () => service,
21181
- verificationMethod: () => verificationMethod
21177
+ getNotif: () => getNotifEndpoint,
21178
+ getPds: () => getPdsEndpoint,
21179
+ parseToAtprotoDocument: () => parseToAtprotoDocument
21182
21180
  });
21183
21181
  module.exports = __toCommonJS(src_exports3);
21184
21182
 
@@ -27950,26 +27948,7 @@ var DAY = HOUR * 24;
27950
27948
  // ../common-web/src/strings.ts
27951
27949
  var import_graphemer = __toESM(require_lib());
27952
27950
 
27953
- // src/types.ts
27954
- var verificationMethod = objectType({
27955
- id: stringType(),
27956
- type: stringType(),
27957
- controller: stringType(),
27958
- publicKeyMultibase: stringType().optional()
27959
- });
27960
- var service = objectType({
27961
- id: stringType(),
27962
- type: stringType(),
27963
- serviceEndpoint: unionType([stringType(), recordType(unknownType())])
27964
- });
27965
- var didDocument = objectType({
27966
- id: stringType(),
27967
- alsoKnownAs: arrayType(stringType()).optional(),
27968
- verificationMethod: arrayType(verificationMethod).optional(),
27969
- service: arrayType(service).optional()
27970
- });
27971
-
27972
- // src/did/atproto-data.ts
27951
+ // ../common-web/src/did-doc.ts
27973
27952
  var getDid = (doc) => {
27974
27953
  const id = doc.id;
27975
27954
  if (typeof id !== "string") {
@@ -27977,7 +27956,16 @@ var getDid = (doc) => {
27977
27956
  }
27978
27957
  return id;
27979
27958
  };
27980
- var getKey = (doc) => {
27959
+ var getHandle = (doc) => {
27960
+ const aka = doc.alsoKnownAs;
27961
+ if (!aka)
27962
+ return void 0;
27963
+ const found = aka.find((name2) => name2.startsWith("at://"));
27964
+ if (!found)
27965
+ return void 0;
27966
+ return found.slice(5);
27967
+ };
27968
+ var getSigningKey = (doc) => {
27981
27969
  const did = getDid(doc);
27982
27970
  let keys = doc.verificationMethod;
27983
27971
  if (!keys)
@@ -27988,56 +27976,109 @@ var getKey = (doc) => {
27988
27976
  keys = [keys];
27989
27977
  }
27990
27978
  const found = keys.find((key) => key.id === "#atproto" || key.id === `${did}#atproto`);
27991
- if (!found)
27992
- return void 0;
27993
- if (!found.publicKeyMultibase)
27979
+ if (!found?.publicKeyMultibase)
27994
27980
  return void 0;
27995
- const keyBytes = multibaseToBytes(found.publicKeyMultibase);
27996
- let didKey = void 0;
27997
- if (found.type === "EcdsaSecp256r1VerificationKey2019") {
27998
- didKey = formatDidKey(P256_JWT_ALG, keyBytes);
27999
- } else if (found.type === "EcdsaSecp256k1VerificationKey2019") {
28000
- didKey = formatDidKey(SECP256K1_JWT_ALG, keyBytes);
28001
- } else if (found.type === "Multikey") {
28002
- const parsed = parseMultikey(found.publicKeyMultibase);
28003
- didKey = formatDidKey(parsed.jwtAlg, parsed.keyBytes);
28004
- }
28005
- return didKey;
28006
- };
28007
- var getHandle = (doc) => {
28008
- const aka = doc.alsoKnownAs;
28009
- if (!aka)
28010
- return void 0;
28011
- const found = aka.find((name2) => name2.startsWith("at://"));
28012
- if (!found)
28013
- return void 0;
28014
- return found.slice(5);
27981
+ return {
27982
+ type: found.type,
27983
+ publicKeyMultibase: found.publicKeyMultibase
27984
+ };
28015
27985
  };
28016
- var getPds = (doc) => {
27986
+ var getPdsEndpoint = (doc) => {
28017
27987
  return getServiceEndpoint(doc, {
28018
27988
  id: "#atproto_pds",
28019
27989
  type: "AtprotoPersonalDataServer"
28020
27990
  });
28021
27991
  };
28022
- var getFeedGen = (doc) => {
27992
+ var getFeedGenEndpoint = (doc) => {
28023
27993
  return getServiceEndpoint(doc, {
28024
27994
  id: "#bsky_fg",
28025
27995
  type: "BskyFeedGenerator"
28026
27996
  });
28027
27997
  };
28028
- var getNotif = (doc) => {
27998
+ var getNotifEndpoint = (doc) => {
28029
27999
  return getServiceEndpoint(doc, {
28030
28000
  id: "#bsky_notif",
28031
28001
  type: "BskyNotificationService"
28032
28002
  });
28033
28003
  };
28004
+ var getServiceEndpoint = (doc, opts) => {
28005
+ const did = getDid(doc);
28006
+ let services = doc.service;
28007
+ if (!services)
28008
+ return void 0;
28009
+ if (typeof services !== "object")
28010
+ return void 0;
28011
+ if (!Array.isArray(services)) {
28012
+ services = [services];
28013
+ }
28014
+ const found = services.find((service2) => service2.id === opts.id || service2.id === `${did}${opts.id}`);
28015
+ if (!found)
28016
+ return void 0;
28017
+ if (found.type !== opts.type) {
28018
+ return void 0;
28019
+ }
28020
+ if (typeof found.serviceEndpoint !== "string") {
28021
+ return void 0;
28022
+ }
28023
+ return validateUrl(found.serviceEndpoint);
28024
+ };
28025
+ var validateUrl = (urlStr) => {
28026
+ let url;
28027
+ try {
28028
+ url = new URL(urlStr);
28029
+ } catch {
28030
+ return void 0;
28031
+ }
28032
+ if (!["http:", "https:"].includes(url.protocol)) {
28033
+ return void 0;
28034
+ } else if (!url.hostname) {
28035
+ return void 0;
28036
+ } else {
28037
+ return urlStr;
28038
+ }
28039
+ };
28040
+ var verificationMethod = z.object({
28041
+ id: z.string(),
28042
+ type: z.string(),
28043
+ controller: z.string(),
28044
+ publicKeyMultibase: z.string().optional()
28045
+ });
28046
+ var service = z.object({
28047
+ id: z.string(),
28048
+ type: z.string(),
28049
+ serviceEndpoint: z.union([z.string(), z.record(z.unknown())])
28050
+ });
28051
+ var didDocument = z.object({
28052
+ id: z.string(),
28053
+ alsoKnownAs: z.array(z.string()).optional(),
28054
+ verificationMethod: z.array(verificationMethod).optional(),
28055
+ service: z.array(service).optional()
28056
+ });
28057
+
28058
+ // src/did/atproto-data.ts
28059
+ var getKey = (doc) => {
28060
+ const key = getSigningKey(doc);
28061
+ if (!key)
28062
+ return void 0;
28063
+ const keyBytes = multibaseToBytes(key.publicKeyMultibase);
28064
+ let didKey = void 0;
28065
+ if (key.type === "EcdsaSecp256r1VerificationKey2019") {
28066
+ didKey = formatDidKey(P256_JWT_ALG, keyBytes);
28067
+ } else if (key.type === "EcdsaSecp256k1VerificationKey2019") {
28068
+ didKey = formatDidKey(SECP256K1_JWT_ALG, keyBytes);
28069
+ } else if (key.type === "Multikey") {
28070
+ const parsed = parseMultikey(key.publicKeyMultibase);
28071
+ didKey = formatDidKey(parsed.jwtAlg, parsed.keyBytes);
28072
+ }
28073
+ return didKey;
28074
+ };
28034
28075
  var parseToAtprotoDocument = (doc) => {
28035
28076
  const did = getDid(doc);
28036
28077
  return {
28037
28078
  did,
28038
28079
  signingKey: getKey(doc),
28039
28080
  handle: getHandle(doc),
28040
- pds: getPds(doc)
28081
+ pds: getPdsEndpoint(doc)
28041
28082
  };
28042
28083
  };
28043
28084
  var ensureAtpDocument = (doc) => {
@@ -28056,37 +28097,6 @@ var ensureAtpDocument = (doc) => {
28056
28097
  }
28057
28098
  return { did, signingKey, handle, pds };
28058
28099
  };
28059
- var validateUrl = (url) => {
28060
- const { hostname, protocol } = new URL(url);
28061
- if (!["http:", "https:"].includes(protocol)) {
28062
- throw new Error("Invalid pds protocol");
28063
- }
28064
- if (!hostname) {
28065
- throw new Error("Invalid pds hostname");
28066
- }
28067
- };
28068
- var getServiceEndpoint = (doc, opts) => {
28069
- const did = getDid(doc);
28070
- let services = doc.service;
28071
- if (!services)
28072
- return void 0;
28073
- if (typeof services !== "object")
28074
- return void 0;
28075
- if (!Array.isArray(services)) {
28076
- services = [services];
28077
- }
28078
- const found = services.find((service2) => service2.id === opts.id || service2.id === `${did}${opts.id}`);
28079
- if (!found)
28080
- return void 0;
28081
- if (found.type !== opts.type) {
28082
- return void 0;
28083
- }
28084
- if (typeof found.serviceEndpoint !== "string") {
28085
- return void 0;
28086
- }
28087
- validateUrl(found.serviceEndpoint);
28088
- return found.serviceEndpoint;
28089
- };
28090
28100
 
28091
28101
  // src/errors.ts
28092
28102
  var DidNotFoundError = class extends Error {
@@ -28141,16 +28151,17 @@ var BaseResolver = class {
28141
28151
  return null;
28142
28152
  return this.validateDidDoc(did, got);
28143
28153
  }
28144
- async refreshCache(did) {
28145
- await this.cache?.refreshCache(did, () => this.resolveNoCache(did));
28154
+ async refreshCache(did, prevResult) {
28155
+ await this.cache?.refreshCache(did, () => this.resolveNoCache(did), prevResult);
28146
28156
  }
28147
28157
  async resolve(did, forceRefresh = false) {
28158
+ let fromCache = null;
28148
28159
  if (this.cache && !forceRefresh) {
28149
- const fromCache = await this.cache.checkCache(did);
28150
- if (fromCache?.stale) {
28151
- await this.refreshCache(did);
28152
- }
28153
- if (fromCache) {
28160
+ fromCache = await this.cache.checkCache(did);
28161
+ if (fromCache && !fromCache.expired) {
28162
+ if (fromCache?.stale) {
28163
+ await this.refreshCache(did, fromCache);
28164
+ }
28154
28165
  return fromCache.doc;
28155
28166
  }
28156
28167
  }
@@ -28159,7 +28170,7 @@ var BaseResolver = class {
28159
28170
  await this.cache?.clearEntry(did);
28160
28171
  return null;
28161
28172
  }
28162
- await this.cache?.cacheDid(did, got);
28173
+ await this.cache?.cacheDid(did, got, fromCache ?? void 0);
28163
28174
  return got;
28164
28175
  }
28165
28176
  async ensureResolve(did, forceRefresh = false) {
@@ -28296,13 +28307,12 @@ var MemoryCache = class {
28296
28307
  return null;
28297
28308
  const now = Date.now();
28298
28309
  const expired = now > val.updatedAt + this.maxTTL;
28299
- if (expired)
28300
- return null;
28301
28310
  const stale = now > val.updatedAt + this.staleTTL;
28302
28311
  return {
28303
28312
  ...val,
28304
28313
  did,
28305
- stale
28314
+ stale,
28315
+ expired
28306
28316
  };
28307
28317
  }
28308
28318
  async clearEntry(did) {
@@ -28350,7 +28360,7 @@ var HandleResolver = class {
28350
28360
  const url = new URL("/.well-known/atproto-did", `https://${handle}`);
28351
28361
  try {
28352
28362
  const res = await fetch(url, { signal });
28353
- const did = await res.text();
28363
+ const did = (await res.text()).split("\n")[0].trim();
28354
28364
  if (typeof did === "string" && did.startsWith("did:")) {
28355
28365
  return did;
28356
28366
  }
@@ -28430,9 +28440,7 @@ var IdResolver = class {
28430
28440
  getKey,
28431
28441
  getNotif,
28432
28442
  getPds,
28433
- parseToAtprotoDocument,
28434
- service,
28435
- verificationMethod
28443
+ parseToAtprotoDocument
28436
28444
  });
28437
28445
  /*!
28438
28446
  * mime-db