@atproto/pds 0.5.1 → 0.5.2

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.
Files changed (217) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/account-manager/account-manager.d.ts +35 -4
  3. package/dist/account-manager/account-manager.d.ts.map +1 -1
  4. package/dist/account-manager/account-manager.js +67 -6
  5. package/dist/account-manager/account-manager.js.map +1 -1
  6. package/dist/account-manager/helpers/account.d.ts +1 -1
  7. package/dist/account-manager/helpers/account.d.ts.map +1 -1
  8. package/dist/account-manager/helpers/account.js +10 -4
  9. package/dist/account-manager/helpers/account.js.map +1 -1
  10. package/dist/account-manager/oauth-store.d.ts +2 -1
  11. package/dist/account-manager/oauth-store.d.ts.map +1 -1
  12. package/dist/account-manager/oauth-store.js +61 -12
  13. package/dist/account-manager/oauth-store.js.map +1 -1
  14. package/dist/actor-store/record/reader.d.ts +1 -1
  15. package/dist/actor-store/record/reader.d.ts.map +1 -1
  16. package/dist/actor-store/record/reader.js.map +1 -1
  17. package/dist/api/com/atproto/admin/updateAccountHandle.d.ts.map +1 -1
  18. package/dist/api/com/atproto/admin/updateAccountHandle.js +33 -43
  19. package/dist/api/com/atproto/admin/updateAccountHandle.js.map +1 -1
  20. package/dist/api/com/atproto/identity/updateHandle.d.ts.map +1 -1
  21. package/dist/api/com/atproto/identity/updateHandle.js +39 -61
  22. package/dist/api/com/atproto/identity/updateHandle.js.map +1 -1
  23. package/dist/api/com/atproto/repo/getRecord.js +3 -3
  24. package/dist/api/com/atproto/repo/getRecord.js.map +1 -1
  25. package/dist/api/com/atproto/repo/putRecord.js +2 -2
  26. package/dist/api/com/atproto/repo/putRecord.js.map +1 -1
  27. package/dist/context.d.ts.map +1 -1
  28. package/dist/context.js +2 -2
  29. package/dist/context.js.map +1 -1
  30. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +8 -0
  31. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
  32. package/dist/lexicons/app/bsky/actor/defs.defs.js +3 -0
  33. package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
  34. package/dist/lexicons/app/bsky/actor/profile.defs.d.ts.map +1 -1
  35. package/dist/lexicons/app/bsky/actor/status.defs.d.ts.map +1 -1
  36. package/dist/lexicons/app/bsky/draft/defs.defs.d.ts +22 -0
  37. package/dist/lexicons/app/bsky/draft/defs.defs.d.ts.map +1 -1
  38. package/dist/lexicons/app/bsky/draft/defs.defs.js +11 -0
  39. package/dist/lexicons/app/bsky/draft/defs.defs.js.map +1 -1
  40. package/dist/lexicons/app/bsky/embed/gallery.d.ts +3 -0
  41. package/dist/lexicons/app/bsky/embed/gallery.d.ts.map +1 -0
  42. package/dist/lexicons/app/bsky/embed/gallery.defs.d.ts +130 -0
  43. package/dist/lexicons/app/bsky/embed/gallery.defs.d.ts.map +1 -0
  44. package/dist/lexicons/app/bsky/embed/gallery.defs.js +47 -0
  45. package/dist/lexicons/app/bsky/embed/gallery.defs.js.map +1 -0
  46. package/dist/lexicons/app/bsky/embed/gallery.js +6 -0
  47. package/dist/lexicons/app/bsky/embed/gallery.js.map +1 -0
  48. package/dist/lexicons/app/bsky/embed/record.defs.d.ts +2 -1
  49. package/dist/lexicons/app/bsky/embed/record.defs.d.ts.map +1 -1
  50. package/dist/lexicons/app/bsky/embed/record.defs.js +2 -0
  51. package/dist/lexicons/app/bsky/embed/record.defs.js.map +1 -1
  52. package/dist/lexicons/app/bsky/embed/recordWithMedia.defs.d.ts +13 -12
  53. package/dist/lexicons/app/bsky/embed/recordWithMedia.defs.d.ts.map +1 -1
  54. package/dist/lexicons/app/bsky/embed/recordWithMedia.defs.js +3 -0
  55. package/dist/lexicons/app/bsky/embed/recordWithMedia.defs.js.map +1 -1
  56. package/dist/lexicons/app/bsky/embed.d.ts +1 -0
  57. package/dist/lexicons/app/bsky/embed.d.ts.map +1 -1
  58. package/dist/lexicons/app/bsky/embed.js +1 -0
  59. package/dist/lexicons/app/bsky/embed.js.map +1 -1
  60. package/dist/lexicons/app/bsky/feed/defs.defs.d.ts +2 -1
  61. package/dist/lexicons/app/bsky/feed/defs.defs.d.ts.map +1 -1
  62. package/dist/lexicons/app/bsky/feed/defs.defs.js +2 -0
  63. package/dist/lexicons/app/bsky/feed/defs.defs.js.map +1 -1
  64. package/dist/lexicons/app/bsky/feed/generator.defs.d.ts.map +1 -1
  65. package/dist/lexicons/app/bsky/feed/like.defs.d.ts.map +1 -1
  66. package/dist/lexicons/app/bsky/feed/post.defs.d.ts +12 -11
  67. package/dist/lexicons/app/bsky/feed/post.defs.d.ts.map +1 -1
  68. package/dist/lexicons/app/bsky/feed/post.defs.js +2 -0
  69. package/dist/lexicons/app/bsky/feed/post.defs.js.map +1 -1
  70. package/dist/lexicons/app/bsky/feed/postgate.defs.d.ts.map +1 -1
  71. package/dist/lexicons/app/bsky/feed/repost.defs.d.ts.map +1 -1
  72. package/dist/lexicons/app/bsky/feed/threadgate.defs.d.ts.map +1 -1
  73. package/dist/lexicons/app/bsky/graph/block.defs.d.ts.map +1 -1
  74. package/dist/lexicons/app/bsky/graph/follow.defs.d.ts.map +1 -1
  75. package/dist/lexicons/app/bsky/graph/list.defs.d.ts.map +1 -1
  76. package/dist/lexicons/app/bsky/graph/listblock.defs.d.ts.map +1 -1
  77. package/dist/lexicons/app/bsky/graph/listitem.defs.d.ts.map +1 -1
  78. package/dist/lexicons/app/bsky/graph/starterpack.defs.d.ts.map +1 -1
  79. package/dist/lexicons/app/bsky/graph/verification.defs.d.ts.map +1 -1
  80. package/dist/lexicons/app/bsky/labeler/service.defs.d.ts.map +1 -1
  81. package/dist/lexicons/app/bsky/notification/declaration.defs.d.ts.map +1 -1
  82. package/dist/lexicons/chat/bsky/actor/declaration.defs.d.ts.map +1 -1
  83. package/dist/lexicons/chat/bsky/authFullChatClient.defs.d.ts.map +1 -1
  84. package/dist/lexicons/chat/bsky/authFullChatClient.defs.js +1 -0
  85. package/dist/lexicons/chat/bsky/authFullChatClient.defs.js.map +1 -1
  86. package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts +53 -14
  87. package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts.map +1 -1
  88. package/dist/lexicons/chat/bsky/convo/defs.defs.js +33 -5
  89. package/dist/lexicons/chat/bsky/convo/defs.defs.js.map +1 -1
  90. package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.d.ts +1 -1
  91. package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.d.ts.map +1 -1
  92. package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.js +1 -0
  93. package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.js.map +1 -1
  94. package/dist/lexicons/chat/bsky/convo/getLog.defs.d.ts +2 -2
  95. package/dist/lexicons/chat/bsky/convo/getLog.defs.d.ts.map +1 -1
  96. package/dist/lexicons/chat/bsky/convo/getLog.defs.js +3 -0
  97. package/dist/lexicons/chat/bsky/convo/getLog.defs.js.map +1 -1
  98. package/dist/lexicons/chat/bsky/embed/joinLink.d.ts +3 -0
  99. package/dist/lexicons/chat/bsky/embed/joinLink.d.ts.map +1 -0
  100. package/dist/lexicons/chat/bsky/embed/joinLink.defs.d.ts +99 -0
  101. package/dist/lexicons/chat/bsky/embed/joinLink.defs.d.ts.map +1 -0
  102. package/dist/lexicons/chat/bsky/embed/joinLink.defs.js +28 -0
  103. package/dist/lexicons/chat/bsky/embed/joinLink.defs.js.map +1 -0
  104. package/dist/lexicons/chat/bsky/embed/joinLink.js +6 -0
  105. package/dist/lexicons/chat/bsky/embed/joinLink.js.map +1 -0
  106. package/dist/lexicons/chat/bsky/embed.d.ts +2 -0
  107. package/dist/lexicons/chat/bsky/embed.d.ts.map +1 -0
  108. package/dist/lexicons/chat/bsky/embed.js +5 -0
  109. package/dist/lexicons/chat/bsky/embed.js.map +1 -0
  110. package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts +1 -1
  111. package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts.map +1 -1
  112. package/dist/lexicons/chat/bsky/group/addMembers.defs.js +1 -0
  113. package/dist/lexicons/chat/bsky/group/addMembers.defs.js.map +1 -1
  114. package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts +1 -1
  115. package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts.map +1 -1
  116. package/dist/lexicons/chat/bsky/group/createGroup.defs.js +1 -0
  117. package/dist/lexicons/chat/bsky/group/createGroup.defs.js.map +1 -1
  118. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.d.ts +1 -1
  119. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.d.ts.map +1 -1
  120. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.js +1 -1
  121. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.js.map +1 -1
  122. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.d.ts +3 -0
  123. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.d.ts.map +1 -0
  124. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.d.ts +20 -0
  125. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.d.ts.map +1 -0
  126. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.js +19 -0
  127. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.js.map +1 -0
  128. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.js +6 -0
  129. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.js.map +1 -0
  130. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.d.ts +3 -0
  131. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.d.ts.map +1 -0
  132. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.d.ts +20 -0
  133. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.d.ts.map +1 -0
  134. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.js +18 -0
  135. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.js.map +1 -0
  136. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.js +6 -0
  137. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.js.map +1 -0
  138. package/dist/lexicons/chat/bsky/group.d.ts +2 -0
  139. package/dist/lexicons/chat/bsky/group.d.ts.map +1 -1
  140. package/dist/lexicons/chat/bsky/group.js +2 -0
  141. package/dist/lexicons/chat/bsky/group.js.map +1 -1
  142. package/dist/lexicons/chat/bsky/moderation/defs.d.ts +2 -0
  143. package/dist/lexicons/chat/bsky/moderation/defs.d.ts.map +1 -0
  144. package/dist/lexicons/chat/bsky/moderation/defs.defs.d.ts +58 -0
  145. package/dist/lexicons/chat/bsky/moderation/defs.defs.d.ts.map +1 -0
  146. package/dist/lexicons/chat/bsky/moderation/defs.defs.js +38 -0
  147. package/dist/lexicons/chat/bsky/moderation/defs.defs.js.map +1 -0
  148. package/dist/lexicons/chat/bsky/moderation/defs.js +5 -0
  149. package/dist/lexicons/chat/bsky/moderation/defs.js.map +1 -0
  150. package/dist/lexicons/chat/bsky/moderation/getConvo.d.ts +3 -0
  151. package/dist/lexicons/chat/bsky/moderation/getConvo.d.ts.map +1 -0
  152. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.d.ts +22 -0
  153. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.d.ts.map +1 -0
  154. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.js +18 -0
  155. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.js.map +1 -0
  156. package/dist/lexicons/chat/bsky/moderation/getConvo.js +6 -0
  157. package/dist/lexicons/chat/bsky/moderation/getConvo.js.map +1 -0
  158. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.d.ts +3 -0
  159. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.d.ts.map +1 -0
  160. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.d.ts +28 -0
  161. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.d.ts.map +1 -0
  162. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.js +24 -0
  163. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.js.map +1 -0
  164. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.js +6 -0
  165. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.js.map +1 -0
  166. package/dist/lexicons/chat/bsky/moderation/getConvos.d.ts +3 -0
  167. package/dist/lexicons/chat/bsky/moderation/getConvos.d.ts.map +1 -0
  168. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.d.ts +22 -0
  169. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.d.ts.map +1 -0
  170. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.js +22 -0
  171. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.js.map +1 -0
  172. package/dist/lexicons/chat/bsky/moderation/getConvos.js +6 -0
  173. package/dist/lexicons/chat/bsky/moderation/getConvos.js.map +1 -0
  174. package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.d.ts +20 -2
  175. package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.d.ts.map +1 -1
  176. package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.js +11 -0
  177. package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.js.map +1 -1
  178. package/dist/lexicons/chat/bsky/moderation.d.ts +4 -0
  179. package/dist/lexicons/chat/bsky/moderation.d.ts.map +1 -1
  180. package/dist/lexicons/chat/bsky/moderation.js +4 -0
  181. package/dist/lexicons/chat/bsky/moderation.js.map +1 -1
  182. package/dist/lexicons/chat/bsky.d.ts +1 -0
  183. package/dist/lexicons/chat/bsky.d.ts.map +1 -1
  184. package/dist/lexicons/chat/bsky.js +1 -0
  185. package/dist/lexicons/chat/bsky.js.map +1 -1
  186. package/dist/lexicons/com/atproto/lexicon/schema.defs.d.ts.map +1 -1
  187. package/dist/lexicons/com/germnetwork/declaration.defs.d.ts.map +1 -1
  188. package/dist/lexicons/site/standard/document.defs.d.ts.map +1 -1
  189. package/dist/lexicons/site/standard/graph/recommend.defs.d.ts.map +1 -1
  190. package/dist/lexicons/site/standard/graph/subscription.defs.d.ts.map +1 -1
  191. package/dist/lexicons/site/standard/publication.defs.d.ts.map +1 -1
  192. package/dist/lexicons/site/standard/theme/basic.defs.d.ts.map +1 -1
  193. package/dist/lexicons/tools/ozone/moderation/defs.defs.d.ts +11 -3
  194. package/dist/lexicons/tools/ozone/moderation/defs.defs.d.ts.map +1 -1
  195. package/dist/lexicons/tools/ozone/moderation/defs.defs.js +9 -0
  196. package/dist/lexicons/tools/ozone/moderation/defs.defs.js.map +1 -1
  197. package/dist/lexicons/tools/ozone/moderation/queryEvents.defs.d.ts +2 -2
  198. package/dist/lexicons/tools/ozone/moderation/queryEvents.defs.d.ts.map +1 -1
  199. package/dist/lexicons/tools/ozone/moderation/queryEvents.defs.js.map +1 -1
  200. package/dist/lexicons/tools/ozone/moderation/queryStatuses.defs.d.ts +2 -2
  201. package/dist/lexicons/tools/ozone/moderation/queryStatuses.defs.d.ts.map +1 -1
  202. package/dist/lexicons/tools/ozone/moderation/queryStatuses.defs.js.map +1 -1
  203. package/dist/read-after-write/viewer.d.ts +2 -2
  204. package/package.json +10 -10
  205. package/src/account-manager/account-manager.ts +105 -7
  206. package/src/account-manager/helpers/account.ts +15 -7
  207. package/src/account-manager/oauth-store.ts +76 -18
  208. package/src/actor-store/record/reader.ts +1 -1
  209. package/src/api/com/atproto/admin/updateAccountHandle.ts +37 -46
  210. package/src/api/com/atproto/identity/updateHandle.ts +45 -76
  211. package/src/api/com/atproto/repo/getRecord.ts +3 -3
  212. package/src/api/com/atproto/repo/putRecord.ts +2 -2
  213. package/src/context.ts +12 -9
  214. package/tests/_puppeteer.ts +8 -2
  215. package/tests/account-manager.test.ts +123 -50
  216. package/tests/oauth.test.ts +5 -5
  217. package/tsconfig.build.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @atproto/pds
2
2
 
3
+ ## 0.5.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#5037](https://github.com/bluesky-social/atproto/pull/5037) [`7b8ca6e`](https://github.com/bluesky-social/atproto/commit/7b8ca6e0aace79cca38e880429317fde8268ba50) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Use the new `atUri()` helper from `@atproto/lex` for safer `AtUriString` construction.
8
+
9
+ - [#4986](https://github.com/bluesky-social/atproto/pull/4986) [`6c63f7d`](https://github.com/bluesky-social/atproto/commit/6c63f7dca6d37c22a8dd5d579ad6a72e532fc372) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add ability to change the user handle through the account manager interface
10
+
11
+ - Updated dependencies [[`6c63f7d`](https://github.com/bluesky-social/atproto/commit/6c63f7dca6d37c22a8dd5d579ad6a72e532fc372)]:
12
+ - @atproto/oauth-provider@0.18.2
13
+
3
14
  ## 0.5.1
4
15
 
5
16
  ### Patch Changes
@@ -1,10 +1,13 @@
1
1
  import { KeyObject } from 'node:crypto';
2
+ import { Client as PlcClient } from '@did-plc/lib';
3
+ import { Keypair } from '@atproto/crypto';
2
4
  import { IdResolver } from '@atproto/identity';
3
5
  import { AtIdentifierString, DidString, HandleString } from '@atproto/lex';
4
6
  import { Cid } from '@atproto/lex-data';
5
7
  import { AuthRequiredError } from '@atproto/xrpc-server';
6
8
  import { com } from '../lexicons/index.js';
7
9
  import { ServerMailer } from '../mailer/index.js';
10
+ import { Sequencer } from '../sequencer/index.js';
8
11
  import { AccountDb, EmailTokenPurpose } from './db/index.js';
9
12
  import * as account from './helpers/account.js';
10
13
  import { AccountStatus, ActorAccount } from './helpers/account.js';
@@ -34,17 +37,20 @@ export declare class AccountManager {
34
37
  readonly idResolver: IdResolver;
35
38
  readonly jwtKey: KeyObject;
36
39
  readonly mailer: ServerMailer;
40
+ readonly sequencer: Sequencer;
41
+ readonly plcClient: PlcClient;
42
+ readonly plcRotationKey: Keypair;
37
43
  readonly serviceDid: string;
38
44
  readonly serviceHandleDomains: string[];
39
45
  readonly db: AccountDb;
40
- constructor(idResolver: IdResolver, jwtKey: KeyObject, mailer: ServerMailer, serviceDid: string, serviceHandleDomains: string[], db: AccountManagerDbConfig);
46
+ constructor(idResolver: IdResolver, jwtKey: KeyObject, mailer: ServerMailer, sequencer: Sequencer, plcClient: PlcClient, plcRotationKey: Keypair, serviceDid: string, serviceHandleDomains: string[], db: AccountManagerDbConfig);
41
47
  migrateOrThrow(): Promise<void>;
42
48
  close(): void;
43
49
  getAccount(handleOrDid: AtIdentifierString, flags?: account.AvailabilityFlags): Promise<ActorAccount | null>;
44
50
  getAccounts(dids: DidString[], flags?: account.AvailabilityFlags): Promise<Map<string, ActorAccount>>;
45
51
  getAccountByEmail(email: string, flags?: account.AvailabilityFlags): Promise<ActorAccount | null>;
46
52
  isAccountActivated(did: DidString): Promise<boolean>;
47
- getDidForActor(handleOrDid: AtIdentifierString, flags?: account.AvailabilityFlags): Promise<string | null>;
53
+ getDidForActor(handleOrDid: AtIdentifierString, flags?: account.AvailabilityFlags): Promise<DidString | null>;
48
54
  getAccountStatus(handleOrDid: AtIdentifierString): Promise<AccountStatus>;
49
55
  normalizeAndValidateHandle(handle: string, { did, allowAnyValid, }?: {
50
56
  did?: string;
@@ -74,7 +80,32 @@ export declare class AccountManager {
74
80
  accessJwt: string;
75
81
  refreshJwt: string;
76
82
  }>;
77
- updateHandle(did: DidString, handle: HandleString): Promise<void>;
83
+ /**
84
+ * Validates the requested handle, updates the PLC document if needed, persists
85
+ * the new handle locally, and emits an identity event.
86
+ *
87
+ * @throws {InvalidRequestError} when the handle is invalid, taken by another
88
+ * account, or cannot be resolved for non-service domains.
89
+ *
90
+ * @see {@link AccountManager.updateAccountHandle} for behavior when the PLC update fails.
91
+ */
92
+ updateHandle(did: DidString, newHandle: string, options?: {
93
+ allowAnyValid?: boolean;
94
+ }): Promise<ActorAccount & {
95
+ handle: HandleString;
96
+ }>;
97
+ validateHandleUpdate(did: DidString, newHandle: string, options?: {
98
+ allowAnyValid?: boolean;
99
+ }): Promise<{
100
+ did: DidString;
101
+ handle: HandleString;
102
+ account: ActorAccount;
103
+ }>;
104
+ /**
105
+ * @note Failure to emit the identity event will silently be ignored. Users
106
+ * can emit the event again by updating their handle to the same value.
107
+ */
108
+ updateAccountHandle(did: DidString, handle: HandleString): Promise<void>;
78
109
  deleteAccount(did: DidString): Promise<void>;
79
110
  takedownAccount(did: DidString, takedown: com.atproto.admin.defs.StatusAttr): Promise<void>;
80
111
  getAccountAdminStatus(did: DidString): Promise<{
@@ -140,7 +171,7 @@ export declare class AccountManager {
140
171
  updateEmail(did: DidString, email: string, token?: string, opts?: {
141
172
  locale?: string;
142
173
  sendConfirmationEmail?: boolean;
143
- }): Promise<account.ActorAccount>;
174
+ }): Promise<ActorAccount>;
144
175
  updateAccountEmail(opts: {
145
176
  did: DidString;
146
177
  email: string;
@@ -1 +1 @@
1
- {"version":3,"file":"account-manager.d.ts","sourceRoot":"","sources":["../../src/account-manager/account-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAIvC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,YAAY,EAEb,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAEvC,OAAO,EAAE,iBAAiB,EAAuB,MAAM,sBAAsB,CAAA;AAS7E,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAsB,MAAM,eAAe,CAAA;AAChF,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAIlE,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AAKjD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAEzE;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAqB,SAAQ,iBAAiB;aAEvC,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM,EAC3B,YAAY,SAAmC;CAIlD;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,MAAM,CAAA;IACpB,wBAAwB,EAAE,OAAO,CAAA;CAClC,CAAA;AAED,qBAAa,cAAc;IAIvB,QAAQ,CAAC,UAAU,EAAE,UAAU;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,EAAE;IAPzC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAA;gBAGX,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,MAAM,EAAE,EACvC,EAAE,EAAE,sBAAsB;IAKtB,cAAc;IAKpB,KAAK;IAOC,UAAU,CACd,WAAW,EAAE,kBAAkB,EAC/B,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,GAChC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAIzB,WAAW,CACf,IAAI,EAAE,SAAS,EAAE,EACjB,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAI/B,iBAAiB,CACrB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,GAChC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAIzB,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAMpD,cAAc,CAClB,WAAW,EAAE,kBAAkB,EAC/B,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,GAChC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKnB,gBAAgB,CACpB,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,aAAa,CAAC;IAUnB,0BAA0B,CAC9B,MAAM,EAAE,MAAM,EACd,EACE,GAAG,EACH,aAAa,GACd,GAAE;QACD,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,aAAa,CAAC,EAAE,OAAO,CAAA;KACnB,GACL,OAAO,CAAC,YAAY,CAAC;IAyClB,aAAa,CAAC,EAClB,GAAG,EACH,MAAM,EACN,KAAK,EACL,QAAQ,EACR,OAAO,EACP,OAAO,EACP,UAAU,EACV,WAAW,EACX,UAAU,GACX,EAAE;QACD,GAAG,EAAE,SAAS,CAAA;QACd,MAAM,EAAE,YAAY,CAAA;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,GAAG,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB;IAmCK,uBAAuB,CAAC,IAAI,EAAE;QAClC,GAAG,EAAE,SAAS,CAAA;QACd,MAAM,EAAE,YAAY,CAAA;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,GAAG,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;KACtB;;;;IAeK,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY;IAIjD,aAAa,CAAC,GAAG,EAAE,SAAS;IAI5B,eAAe,CACnB,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU;IAWvC,qBAAqB,CAAC,GAAG,EAAE,SAAS;;;;IAIpC,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM;IAIpD,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAI5D,eAAe,CAAC,GAAG,EAAE,SAAS;IAO9B,aAAa,CACjB,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,QAAQ,CAAC,eAAe,GAAG,IAAI,EAC5C,aAAa,UAAQ;;;;IAgBjB,kBAAkB,CAAC,EAAE,EAAE,MAAM;IAwD7B,kBAAkB,CAAC,EAAE,EAAE,MAAM;IAO7B,KAAK,CAAC,EACV,UAAU,EACV,QAAQ,GACT,EAAE;QACD,UAAU,EAAE,MAAM,CAAA;QAClB,QAAQ,EAAE,MAAM,CAAA;KACjB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,YAAY,CAAA;QAClB,WAAW,EAAE,QAAQ,CAAC,eAAe,GAAG,IAAI,CAAA;QAC5C,aAAa,EAAE,OAAO,CAAA;KACvB,CAAC;IAgDI,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO;IAInE,gBAAgB,CAAC,GAAG,EAAE,SAAS;;;;;IAI/B,qBAAqB,CACzB,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC;IAIb,iBAAiB,CACrB,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,QAAQ,CAAC,eAAe,GAAG,IAAI,CAAC;IAIrC,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM;IAY9C,uBAAuB,CAAC,IAAI,EAAE,MAAM;IAIpC,iBAAiB,CACrB,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,EAChD,QAAQ,EAAE,MAAM;IAKZ,wBAAwB,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,CAAC,GAAG,CAAC;IAWX,sBAAsB,CAAC,GAAG,EAAE,SAAS;IAKrC,uBAAuB,CAAC,IAAI,EAAE,SAAS,EAAE;IAIzC,uBAAuB,CAAC,IAAI,EAAE,SAAS,EAAE;IAIzC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE;IAIlC,yBAAyB,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO;IAI3D,kBAAkB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE;IAOhE,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAiB;IAI3D,qBAAqB,CACzB,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM;IAKT,+BAA+B,CACnC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM;IAMT,wBAAwB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAoBnE,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IA0BzD,kBAAkB,CACtB,GAAG,EAAE,SAAS,EACd,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC;QAAE,aAAa,EAAE,OAAO,CAAA;KAAE,CAAC;IA4BtC;;OAEG;IACG,WAAW,CACf,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAE;IA+CvD,kBAAkB,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAQ1D,aAAa,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAWvD,qBAAqB,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,SAAS,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAWvE"}
1
+ {"version":3,"file":"account-manager.d.ts","sourceRoot":"","sources":["../../src/account-manager/account-manager.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ import { AuthScope } from '../auth-scope.js';
8
8
  import { softDeleted } from '../db/index.js';
9
9
  import { hasExplicitSlur } from '../handle/explicit-slurs.js';
10
10
  import { baseNormalizeAndValidate, ensureHandleServiceConstraints, isServiceDomain, } from '../handle/index.js';
11
+ import { httpLogger } from '../logger.js';
11
12
  import { getDb, getMigrator } from './db/index.js';
12
13
  import * as account from './helpers/account.js';
13
14
  import { AccountStatus } from './helpers/account.js';
@@ -38,10 +39,13 @@ export class InvalidPasswordError extends AuthRequiredError {
38
39
  }
39
40
  }
40
41
  export class AccountManager {
41
- constructor(idResolver, jwtKey, mailer, serviceDid, serviceHandleDomains, db) {
42
+ constructor(idResolver, jwtKey, mailer, sequencer, plcClient, plcRotationKey, serviceDid, serviceHandleDomains, db) {
42
43
  this.idResolver = idResolver;
43
44
  this.jwtKey = jwtKey;
44
45
  this.mailer = mailer;
46
+ this.sequencer = sequencer;
47
+ this.plcClient = plcClient;
48
+ this.plcRotationKey = plcRotationKey;
45
49
  this.serviceDid = serviceDid;
46
50
  this.serviceHandleDomains = serviceHandleDomains;
47
51
  this.db = getDb(db.accountDbLoc, db.disableWalAutoCheckpoint);
@@ -82,7 +86,7 @@ export class AccountManager {
82
86
  const res = account.formatAccountStatus(got);
83
87
  return res.active ? AccountStatus.Active : res.status;
84
88
  }
85
- async normalizeAndValidateHandle(handle, { did, allowAnyValid, } = {}) {
89
+ async normalizeAndValidateHandle(handle, { did, allowAnyValid = false, } = {}) {
86
90
  const normalized = baseNormalizeAndValidate(handle);
87
91
  // tld validation
88
92
  if (!isValidTld(normalized)) {
@@ -97,12 +101,16 @@ export class AccountManager {
97
101
  ensureHandleServiceConstraints(normalized, this.serviceHandleDomains, allowAnyValid);
98
102
  }
99
103
  else {
104
+ // When creating an account (no did yet), we require the handle to be a
105
+ // local service domain. Updating to a custom handle will be possible once
106
+ // the account was created.
100
107
  if (did == null) {
101
108
  throw new InvalidRequestError('Not a supported handle domain', 'UnsupportedDomain');
102
109
  }
103
110
  // verify resolution of a non-service domain
104
111
  const resolvedDid = await this.idResolver.handle.resolve(normalized);
105
112
  if (resolvedDid !== did) {
113
+ // @TODO This should use a distinct error code
106
114
  throw new InvalidRequestError('External handle did not resolve to DID');
107
115
  }
108
116
  }
@@ -146,10 +154,63 @@ export class AccountManager {
146
154
  await this.createAccount({ ...opts, refreshJwt });
147
155
  return { accessJwt, refreshJwt };
148
156
  }
149
- // @NOTE should always be paired with a sequenceHandle().
150
- // the token output from this method should be passed to sequenceHandle().
151
- async updateHandle(did, handle) {
152
- return account.updateHandle(this.db, did, handle);
157
+ /**
158
+ * Validates the requested handle, updates the PLC document if needed, persists
159
+ * the new handle locally, and emits an identity event.
160
+ *
161
+ * @throws {InvalidRequestError} when the handle is invalid, taken by another
162
+ * account, or cannot be resolved for non-service domains.
163
+ *
164
+ * @see {@link AccountManager.updateAccountHandle} for behavior when the PLC update fails.
165
+ */
166
+ async updateHandle(did, newHandle, options) {
167
+ const { account, handle } = await this.validateHandleUpdate(did, newHandle, options);
168
+ if (did.startsWith('did:plc:')) {
169
+ // @TODO We should verify the status before issuing a PLC update.
170
+ await this.plcClient.updateHandle(did, this.plcRotationKey, handle);
171
+ }
172
+ else {
173
+ const resolved = await this.idResolver.did.resolveAtprotoData(did, true);
174
+ if (resolved.handle !== handle) {
175
+ throw new InvalidRequestError('DID is not properly configured for handle');
176
+ }
177
+ }
178
+ // @NOTE If the next line fails (for any reason), we don't "rollback" the
179
+ // PLC update above. The caller can just call this method again.
180
+ await this.updateAccountHandle(did, handle);
181
+ return { ...account, handle };
182
+ }
183
+ async validateHandleUpdate(did, newHandle, options) {
184
+ const account = await this.getAccount(did, { includeDeactivated: true });
185
+ if (!account) {
186
+ throw new InvalidRequestError('Account not found');
187
+ }
188
+ const handle = await this.normalizeAndValidateHandle(newHandle, {
189
+ allowAnyValid: options?.allowAnyValid,
190
+ did,
191
+ });
192
+ // Pessimistic check to handle spam: also enforced by updateAccountHandle() and the db.
193
+ const existing = await this.getAccount(handle, {
194
+ includeDeactivated: true,
195
+ includeTakenDown: true,
196
+ });
197
+ if (existing && existing.did !== did) {
198
+ throw new InvalidRequestError(`Handle already taken: ${handle}`, 'HandleNotAvailable');
199
+ }
200
+ return { did, handle, account };
201
+ }
202
+ /**
203
+ * @note Failure to emit the identity event will silently be ignored. Users
204
+ * can emit the event again by updating their handle to the same value.
205
+ */
206
+ async updateAccountHandle(did, handle) {
207
+ await account.updateHandle(this.db, did, handle);
208
+ try {
209
+ await this.sequencer.sequenceIdentityEvt(did, handle);
210
+ }
211
+ catch (err) {
212
+ httpLogger.error({ err, did, handle }, 'failed to sequence handle update');
213
+ }
153
214
  }
154
215
  async deleteAccount(did) {
155
216
  return account.deleteAccount(this.db, did);
@@ -1 +1 @@
1
- {"version":3,"file":"account-manager.js","sourceRoot":"","sources":["../../src/account-manager/account-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyObject } from 'node:crypto'\nimport { isEmailValid } from '@hapi/address'\nimport { isDisposableEmail } from 'disposable-email-domains-js'\nimport { HOUR, wait } from '@atproto/common'\nimport { IdResolver } from '@atproto/identity'\nimport {\n AtIdentifierString,\n DidString,\n HandleString,\n isAtIdentifierString,\n} from '@atproto/lex'\nimport { Cid } from '@atproto/lex-data'\nimport { currentDatetimeString, isValidTld } from '@atproto/syntax'\nimport { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server'\nimport { AuthScope } from '../auth-scope.js'\nimport { softDeleted } from '../db/index.js'\nimport { hasExplicitSlur } from '../handle/explicit-slurs.js'\nimport {\n baseNormalizeAndValidate,\n ensureHandleServiceConstraints,\n isServiceDomain,\n} from '../handle/index.js'\nimport { com } from '../lexicons/index.js'\nimport { ServerMailer } from '../mailer/index.js'\nimport { AccountDb, EmailTokenPurpose, getDb, getMigrator } from './db/index.js'\nimport * as account from './helpers/account.js'\nimport { AccountStatus, ActorAccount } from './helpers/account.js'\nimport * as auth from './helpers/auth.js'\nimport * as emailToken from './helpers/email-token.js'\nimport * as invite from './helpers/invite.js'\nimport * as password from './helpers/password.js'\nimport * as repo from './helpers/repo.js'\nimport * as scrypt from './helpers/scrypt.js'\nimport * as token from './helpers/token.js'\n\nexport { AccountStatus, formatAccountStatus } from './helpers/account.js'\n\n/**\n * Thrown by {@link AccountManager.login} when the identifier resolved to a\n * known account but the supplied credentials (account password / app\n * password) did not match. The matched `did` is attached so downstream\n * callers can distinguish \"identifier known, credentials wrong\" from\n * \"identifier unknown\" (which continues to throw a plain\n * {@link AuthRequiredError}).\n *\n * Callers should take care that remote clients *cannot* distinguish the above,\n * to prevent enumeration attacks. (Tested for in\n * packages/pds/tests/auth.test.ts)\n */\nexport class InvalidPasswordError extends AuthRequiredError {\n constructor(\n public readonly did: string,\n errorMessage = 'Invalid identifier or password',\n ) {\n super(errorMessage)\n }\n}\n\nexport type AccountManagerDbConfig = {\n accountDbLoc: string\n disableWalAutoCheckpoint: boolean\n}\n\nexport class AccountManager {\n readonly db: AccountDb\n\n constructor(\n readonly idResolver: IdResolver,\n readonly jwtKey: KeyObject,\n readonly mailer: ServerMailer,\n readonly serviceDid: string,\n readonly serviceHandleDomains: string[],\n db: AccountManagerDbConfig,\n ) {\n this.db = getDb(db.accountDbLoc, db.disableWalAutoCheckpoint)\n }\n\n async migrateOrThrow() {\n await this.db.ensureWal()\n await getMigrator(this.db).migrateToLatestOrThrow()\n }\n\n close() {\n this.db.close()\n }\n\n // Account\n // ----------\n\n async getAccount(\n handleOrDid: AtIdentifierString,\n flags?: account.AvailabilityFlags,\n ): Promise<ActorAccount | null> {\n return account.getAccount(this.db, handleOrDid, flags)\n }\n\n async getAccounts(\n dids: DidString[],\n flags?: account.AvailabilityFlags,\n ): Promise<Map<string, ActorAccount>> {\n return account.getAccounts(this.db, dids, flags)\n }\n\n async getAccountByEmail(\n email: string,\n flags?: account.AvailabilityFlags,\n ): Promise<ActorAccount | null> {\n return account.getAccountByEmail(this.db, email, flags)\n }\n\n async isAccountActivated(did: DidString): Promise<boolean> {\n const account = await this.getAccount(did, { includeDeactivated: true })\n if (!account) return false\n return !account.deactivatedAt\n }\n\n async getDidForActor(\n handleOrDid: AtIdentifierString,\n flags?: account.AvailabilityFlags,\n ): Promise<string | null> {\n const got = await this.getAccount(handleOrDid, flags)\n return got?.did ?? null\n }\n\n async getAccountStatus(\n handleOrDid: AtIdentifierString,\n ): Promise<AccountStatus> {\n const got = await this.getAccount(handleOrDid, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n const res = account.formatAccountStatus(got)\n return res.active ? AccountStatus.Active : res.status\n }\n\n async normalizeAndValidateHandle(\n handle: string,\n {\n did,\n allowAnyValid,\n }: {\n did?: string\n allowAnyValid?: boolean\n } = {},\n ): Promise<HandleString> {\n const normalized = baseNormalizeAndValidate(handle)\n\n // tld validation\n if (!isValidTld(normalized)) {\n throw new InvalidRequestError(\n 'Handle TLD is invalid or disallowed',\n 'InvalidHandle',\n )\n }\n // slur check\n if (!allowAnyValid && hasExplicitSlur(normalized)) {\n throw new InvalidRequestError(\n 'Inappropriate language in handle',\n 'InvalidHandle',\n )\n }\n if (isServiceDomain(normalized, this.serviceHandleDomains)) {\n // verify constraints on a service domain\n ensureHandleServiceConstraints(\n normalized,\n this.serviceHandleDomains,\n allowAnyValid,\n )\n } else {\n if (did == null) {\n throw new InvalidRequestError(\n 'Not a supported handle domain',\n 'UnsupportedDomain',\n )\n }\n // verify resolution of a non-service domain\n const resolvedDid = await this.idResolver.handle.resolve(normalized)\n if (resolvedDid !== did) {\n throw new InvalidRequestError('External handle did not resolve to DID')\n }\n }\n\n return normalized\n }\n\n async createAccount({\n did,\n handle,\n email,\n password,\n repoCid,\n repoRev,\n inviteCode,\n deactivated,\n refreshJwt,\n }: {\n did: DidString\n handle: HandleString\n email?: string\n password?: string\n repoCid: Cid\n repoRev: string\n inviteCode?: string\n deactivated?: boolean\n refreshJwt?: string\n }) {\n if (password && password.length > scrypt.NEW_PASSWORD_MAX_LENGTH) {\n throw new InvalidRequestError('Password too long')\n }\n\n const passwordScrypt = password\n ? await scrypt.genSaltAndHash(password)\n : undefined\n\n const now = currentDatetimeString()\n await this.db.transaction(async (dbTxn) => {\n if (inviteCode) {\n await invite.ensureInviteIsAvailable(dbTxn, inviteCode)\n }\n await Promise.all([\n account.registerActor(dbTxn, { did, handle, deactivated }),\n email && passwordScrypt\n ? account.registerAccount(dbTxn, { did, email, passwordScrypt })\n : Promise.resolve(),\n invite.recordInviteUse(dbTxn, {\n did,\n inviteCode,\n now,\n }),\n refreshJwt &&\n auth.storeRefreshToken(\n dbTxn,\n auth.decodeRefreshToken(refreshJwt),\n null,\n ),\n repo.updateRoot(dbTxn, did, repoCid, repoRev),\n ])\n })\n }\n\n async createAccountAndSession(opts: {\n did: DidString\n handle: HandleString\n email?: string\n password?: string\n repoCid: Cid\n repoRev: string\n inviteCode?: string\n deactivated?: boolean\n }) {\n const { accessJwt, refreshJwt } = await auth.createTokens({\n did: opts.did,\n jwtKey: this.jwtKey,\n serviceDid: this.serviceDid,\n scope: AuthScope.Access,\n })\n\n await this.createAccount({ ...opts, refreshJwt })\n\n return { accessJwt, refreshJwt }\n }\n\n // @NOTE should always be paired with a sequenceHandle().\n // the token output from this method should be passed to sequenceHandle().\n async updateHandle(did: DidString, handle: HandleString) {\n return account.updateHandle(this.db, did, handle)\n }\n\n async deleteAccount(did: DidString) {\n return account.deleteAccount(this.db, did)\n }\n\n async takedownAccount(\n did: DidString,\n takedown: com.atproto.admin.defs.StatusAttr,\n ) {\n await this.db.transaction(async (dbTxn) =>\n Promise.all([\n account.updateAccountTakedownStatus(dbTxn, did, takedown),\n auth.revokeRefreshTokensByDid(dbTxn, did),\n token.removeByDidQB(dbTxn, did).execute(),\n ]),\n )\n }\n\n async getAccountAdminStatus(did: DidString) {\n return account.getAccountAdminStatus(this.db, did)\n }\n\n async updateRepoRoot(did: DidString, cid: Cid, rev: string) {\n return repo.updateRoot(this.db, did, cid, rev)\n }\n\n async deactivateAccount(did: DidString, deleteAfter: string | null) {\n return account.deactivateAccount(this.db, did, deleteAfter)\n }\n\n async activateAccount(did: DidString) {\n return account.activateAccount(this.db, did)\n }\n\n // Auth\n // ----------\n\n async createSession(\n did: DidString,\n appPassword: password.AppPassDescript | null,\n isSoftDeleted = false,\n ) {\n const { accessJwt, refreshJwt } = await auth.createTokens({\n did,\n jwtKey: this.jwtKey,\n serviceDid: this.serviceDid,\n scope: auth.formatScope(appPassword, isSoftDeleted),\n })\n // For soft deleted accounts don't store refresh token so that it can't be rotated.\n if (!isSoftDeleted) {\n const refreshPayload = auth.decodeRefreshToken(refreshJwt)\n await auth.storeRefreshToken(this.db, refreshPayload, appPassword)\n }\n return { accessJwt, refreshJwt }\n }\n\n async rotateRefreshToken(id: string) {\n const token = await auth.getRefreshToken(this.db, id)\n if (!token) return null\n\n const now = new Date()\n\n // take the chance to tidy all of a user's expired tokens\n // does not need to be transactional since this is just best-effort\n await auth.deleteExpiredRefreshTokens(this.db, token.did, now.toISOString())\n\n // Shorten the refresh token lifespan down from its\n // original expiration time to its revocation grace period.\n const prevExpiresAt = new Date(token.expiresAt)\n const REFRESH_GRACE_MS = 2 * HOUR\n const graceExpiresAt = new Date(now.getTime() + REFRESH_GRACE_MS)\n\n const expiresAt =\n graceExpiresAt < prevExpiresAt ? graceExpiresAt : prevExpiresAt\n\n if (expiresAt <= now) {\n return null\n }\n\n // Determine the next refresh token id: upon refresh token\n // reuse you always receive a refresh token with the same id.\n const nextId = token.nextId ?? auth.getRefreshTokenId()\n\n const { accessJwt, refreshJwt } = await auth.createTokens({\n did: token.did,\n jwtKey: this.jwtKey,\n serviceDid: this.serviceDid,\n scope: auth.formatScope(token.appPassword),\n jti: nextId,\n })\n\n const refreshPayload = auth.decodeRefreshToken(refreshJwt)\n try {\n await this.db.transaction((dbTxn) =>\n Promise.all([\n auth.addRefreshGracePeriod(dbTxn, {\n id,\n expiresAt: expiresAt.toISOString(),\n nextId,\n }),\n auth.storeRefreshToken(dbTxn, refreshPayload, token.appPassword),\n ]),\n )\n } catch (err) {\n if (err instanceof auth.ConcurrentRefreshError) {\n return this.rotateRefreshToken(id)\n }\n throw err\n }\n return { accessJwt, refreshJwt }\n }\n\n async revokeRefreshToken(id: string) {\n return auth.revokeRefreshToken(this.db, id)\n }\n\n // Login\n // ----------\n\n async login({\n identifier,\n password,\n }: {\n identifier: string\n password: string\n }): Promise<{\n user: ActorAccount\n appPassword: password.AppPassDescript | null\n isSoftDeleted: boolean\n }> {\n const start = Date.now()\n try {\n const identifierNormalized = identifier.toLowerCase()\n\n const user = identifierNormalized.includes('@')\n ? await this.getAccountByEmail(identifierNormalized, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n : isAtIdentifierString(identifierNormalized)\n ? await this.getAccount(identifierNormalized, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n : null\n\n if (!user) {\n throw new AuthRequiredError('Invalid identifier or password')\n }\n const isSoftDeleted = softDeleted(user)\n\n let appPassword: password.AppPassDescript | null = null\n const validAccountPass = await this.verifyAccountPassword(\n user.did,\n password,\n )\n if (!validAccountPass) {\n // takendown/suspended accounts cannot login with app password\n if (isSoftDeleted) {\n throw new InvalidPasswordError(user.did)\n }\n appPassword = await this.verifyAppPassword(user.did, password)\n if (appPassword === null) {\n throw new InvalidPasswordError(user.did)\n }\n }\n\n return { user, appPassword, isSoftDeleted }\n } finally {\n // Mitigate timing attacks\n await wait(350 - (Date.now() - start))\n }\n }\n\n // Passwords\n // ----------\n\n async createAppPassword(did: DidString, name: string, privileged: boolean) {\n return password.createAppPassword(this.db, did, name, privileged)\n }\n\n async listAppPasswords(did: DidString) {\n return password.listAppPasswords(this.db, did)\n }\n\n async verifyAccountPassword(\n did: DidString,\n passwordStr: string,\n ): Promise<boolean> {\n return password.verifyAccountPassword(this.db, did, passwordStr)\n }\n\n async verifyAppPassword(\n did: DidString,\n passwordStr: string,\n ): Promise<password.AppPassDescript | null> {\n return password.verifyAppPassword(this.db, did, passwordStr)\n }\n\n async revokeAppPassword(did: DidString, name: string) {\n await this.db.transaction(async (dbTxn) =>\n Promise.all([\n password.deleteAppPassword(dbTxn, did, name),\n auth.revokeAppPasswordRefreshToken(dbTxn, did, name),\n ]),\n )\n }\n\n // Invites\n // ----------\n\n async ensureInviteIsAvailable(code: string) {\n return invite.ensureInviteIsAvailable(this.db, code)\n }\n\n async createInviteCodes(\n toCreate: { account: string; codes: string[] }[],\n useCount: number,\n ) {\n return invite.createInviteCodes(this.db, toCreate, useCount)\n }\n\n async createAccountInviteCodes(\n forAccount: string,\n codes: string[],\n expectedTotal: number,\n disabled: 0 | 1,\n ) {\n return invite.createAccountInviteCodes(\n this.db,\n forAccount,\n codes,\n expectedTotal,\n disabled,\n )\n }\n\n async getAccountInvitesCodes(did: DidString) {\n const inviteCodes = await invite.getAccountsInviteCodes(this.db, [did])\n return inviteCodes.get(did) ?? []\n }\n\n async getAccountsInvitesCodes(dids: DidString[]) {\n return invite.getAccountsInviteCodes(this.db, dids)\n }\n\n async getInvitedByForAccounts(dids: DidString[]) {\n return invite.getInvitedByForAccounts(this.db, dids)\n }\n\n async getInviteCodesUses(codes: string[]) {\n return invite.getInviteCodesUses(this.db, codes)\n }\n\n async setAccountInvitesDisabled(did: DidString, disabled: boolean) {\n return invite.setAccountInvitesDisabled(this.db, did, disabled)\n }\n\n async disableInviteCodes(opts: { codes: string[]; accounts: string[] }) {\n return invite.disableInviteCodes(this.db, opts)\n }\n\n // Email Tokens\n // ----------\n\n async createEmailToken(did: DidString, purpose: EmailTokenPurpose) {\n return emailToken.createEmailToken(this.db, did, purpose)\n }\n\n async assertValidEmailToken(\n did: DidString,\n purpose: EmailTokenPurpose,\n token: string,\n ) {\n return emailToken.assertValidToken(this.db, did, purpose, token)\n }\n\n async assertValidEmailTokenAndCleanup(\n did: DidString,\n purpose: EmailTokenPurpose,\n token: string,\n ) {\n await emailToken.assertValidToken(this.db, did, purpose, token)\n await emailToken.deleteEmailToken(this.db, did, purpose)\n }\n\n async requestEmailConfirmation(did: DidString, opts?: { locale?: string }) {\n const account = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n if (!account.email) {\n throw new InvalidRequestError('account does not have an email address')\n }\n\n const locale = opts?.locale\n const token = await this.createEmailToken(did, 'confirm_email')\n\n await this.mailer.sendConfirmEmail({ token, locale }, { to: account.email })\n }\n\n async confirmEmail(did: DidString, email: string, token: string) {\n const user = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!user) {\n throw new InvalidRequestError('user not found', 'AccountNotFound')\n }\n\n if (user.email !== email.toLowerCase()) {\n throw new InvalidRequestError('invalid email', 'InvalidEmail')\n }\n\n await emailToken.assertValidToken(this.db, did, 'confirm_email', token)\n const now = currentDatetimeString()\n await this.db.transaction(async (dbTxn) => {\n await emailToken.deleteEmailToken(dbTxn, did, 'confirm_email')\n await account.setEmailConfirmedAt(dbTxn, did, now)\n })\n\n user.emailConfirmedAt = now\n\n return user\n }\n\n async requestEmailUpdate(\n did: DidString,\n opts?: { locale?: string },\n ): Promise<{ tokenRequired: boolean }> {\n const account = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n if (!account.email) {\n throw new InvalidRequestError('account does not have an email address')\n }\n\n const token = account.emailConfirmedAt\n ? await this.createEmailToken(did, 'update_email')\n : null\n\n if (token) {\n await this.mailer.sendUpdateEmail(\n { token, locale: opts?.locale },\n { to: account.email },\n )\n }\n\n return { tokenRequired: !!token }\n }\n\n /**\n * @throws UserAlreadyExistsError if the new email is already in use by another account\n */\n async updateEmail(\n did: DidString,\n email: string,\n token?: string,\n opts?: { locale?: string; sendConfirmationEmail?: boolean },\n ) {\n if (!isEmailValid(email) || isDisposableEmail(email)) {\n throw new InvalidRequestError(\n 'This email address is not supported, please use a different email.',\n )\n }\n\n const account = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n const tokenRequired = !!account.emailConfirmedAt\n\n // require a token if account email is confirmed\n if (!token && tokenRequired) {\n throw new InvalidRequestError(\n 'confirmation token required',\n 'TokenRequired',\n )\n }\n\n if (token) {\n await this.assertValidEmailToken(did, 'update_email', token)\n }\n\n await this.updateAccountEmail({ did, email })\n\n account.email = email\n account.emailConfirmedAt = null\n\n // Proactively send a confirmation email so that the user can confirm the\n // new email immediately.\n if (opts?.sendConfirmationEmail) {\n const token = await this.createEmailToken(did, 'confirm_email')\n const locale = opts.locale\n await this.mailer.sendConfirmEmail({ token, locale }, { to: email })\n }\n\n return account\n }\n\n async updateAccountEmail(opts: { did: DidString; email: string }) {\n const { did, email } = opts\n await this.db.transaction(async (dbTxn) => {\n await account.updateEmail(dbTxn, did, email)\n await emailToken.deleteAllEmailTokens(dbTxn, did)\n })\n }\n\n async resetPassword(opts: { password: string; token: string }) {\n const did = await emailToken.assertValidTokenAndFindDid(\n this.db,\n 'reset_password',\n opts.token,\n )\n await this.updateAccountPassword({ did, password: opts.password })\n\n return did\n }\n\n async updateAccountPassword(opts: { did: DidString; password: string }) {\n const { did } = opts\n const passwordScrypt = await scrypt.genSaltAndHash(opts.password)\n await this.db.transaction(async (dbTxn) =>\n Promise.all([\n password.updateUserPassword(dbTxn, { did, passwordScrypt }),\n emailToken.deleteEmailToken(dbTxn, did, 'reset_password'),\n auth.revokeRefreshTokensByDid(dbTxn, did),\n ]),\n )\n }\n}\n"]}
1
+ {"version":3,"file":"account-manager.js","sourceRoot":"","sources":["../../src/account-manager/account-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyObject } from 'node:crypto'\nimport { Client as PlcClient } from '@did-plc/lib'\nimport { isEmailValid } from '@hapi/address'\nimport { isDisposableEmail } from 'disposable-email-domains-js'\nimport { HOUR, wait } from '@atproto/common'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport {\n AtIdentifierString,\n DidString,\n HandleString,\n isAtIdentifierString,\n} from '@atproto/lex'\nimport { Cid } from '@atproto/lex-data'\nimport { currentDatetimeString, isValidTld } from '@atproto/syntax'\nimport { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server'\nimport { AuthScope } from '../auth-scope.js'\nimport { softDeleted } from '../db/index.js'\nimport { hasExplicitSlur } from '../handle/explicit-slurs.js'\nimport {\n baseNormalizeAndValidate,\n ensureHandleServiceConstraints,\n isServiceDomain,\n} from '../handle/index.js'\nimport { com } from '../lexicons/index.js'\nimport { httpLogger } from '../logger.js'\nimport { ServerMailer } from '../mailer/index.js'\nimport { Sequencer } from '../sequencer/index.js'\nimport { AccountDb, EmailTokenPurpose, getDb, getMigrator } from './db/index.js'\nimport * as account from './helpers/account.js'\nimport { AccountStatus, ActorAccount } from './helpers/account.js'\nimport * as auth from './helpers/auth.js'\nimport * as emailToken from './helpers/email-token.js'\nimport * as invite from './helpers/invite.js'\nimport * as password from './helpers/password.js'\nimport * as repo from './helpers/repo.js'\nimport * as scrypt from './helpers/scrypt.js'\nimport * as token from './helpers/token.js'\n\nexport { AccountStatus, formatAccountStatus } from './helpers/account.js'\n\n/**\n * Thrown by {@link AccountManager.login} when the identifier resolved to a\n * known account but the supplied credentials (account password / app\n * password) did not match. The matched `did` is attached so downstream\n * callers can distinguish \"identifier known, credentials wrong\" from\n * \"identifier unknown\" (which continues to throw a plain\n * {@link AuthRequiredError}).\n *\n * Callers should take care that remote clients *cannot* distinguish the above,\n * to prevent enumeration attacks. (Tested for in\n * packages/pds/tests/auth.test.ts)\n */\nexport class InvalidPasswordError extends AuthRequiredError {\n constructor(\n public readonly did: string,\n errorMessage = 'Invalid identifier or password',\n ) {\n super(errorMessage)\n }\n}\n\nexport type AccountManagerDbConfig = {\n accountDbLoc: string\n disableWalAutoCheckpoint: boolean\n}\n\nexport class AccountManager {\n readonly db: AccountDb\n\n constructor(\n readonly idResolver: IdResolver,\n readonly jwtKey: KeyObject,\n readonly mailer: ServerMailer,\n readonly sequencer: Sequencer,\n readonly plcClient: PlcClient,\n readonly plcRotationKey: Keypair,\n readonly serviceDid: string,\n readonly serviceHandleDomains: string[],\n db: AccountManagerDbConfig,\n ) {\n this.db = getDb(db.accountDbLoc, db.disableWalAutoCheckpoint)\n }\n\n async migrateOrThrow() {\n await this.db.ensureWal()\n await getMigrator(this.db).migrateToLatestOrThrow()\n }\n\n close() {\n this.db.close()\n }\n\n // Account\n // ----------\n\n async getAccount(\n handleOrDid: AtIdentifierString,\n flags?: account.AvailabilityFlags,\n ): Promise<ActorAccount | null> {\n return account.getAccount(this.db, handleOrDid, flags)\n }\n\n async getAccounts(\n dids: DidString[],\n flags?: account.AvailabilityFlags,\n ): Promise<Map<string, ActorAccount>> {\n return account.getAccounts(this.db, dids, flags)\n }\n\n async getAccountByEmail(\n email: string,\n flags?: account.AvailabilityFlags,\n ): Promise<ActorAccount | null> {\n return account.getAccountByEmail(this.db, email, flags)\n }\n\n async isAccountActivated(did: DidString): Promise<boolean> {\n const account = await this.getAccount(did, { includeDeactivated: true })\n if (!account) return false\n return !account.deactivatedAt\n }\n\n async getDidForActor(\n handleOrDid: AtIdentifierString,\n flags?: account.AvailabilityFlags,\n ): Promise<DidString | null> {\n const got = await this.getAccount(handleOrDid, flags)\n return got?.did ?? null\n }\n\n async getAccountStatus(\n handleOrDid: AtIdentifierString,\n ): Promise<AccountStatus> {\n const got = await this.getAccount(handleOrDid, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n const res = account.formatAccountStatus(got)\n return res.active ? AccountStatus.Active : res.status\n }\n\n async normalizeAndValidateHandle(\n handle: string,\n {\n did,\n allowAnyValid = false,\n }: {\n did?: string\n allowAnyValid?: boolean\n } = {},\n ): Promise<HandleString> {\n const normalized = baseNormalizeAndValidate(handle)\n\n // tld validation\n if (!isValidTld(normalized)) {\n throw new InvalidRequestError(\n 'Handle TLD is invalid or disallowed',\n 'InvalidHandle',\n )\n }\n // slur check\n if (!allowAnyValid && hasExplicitSlur(normalized)) {\n throw new InvalidRequestError(\n 'Inappropriate language in handle',\n 'InvalidHandle',\n )\n }\n if (isServiceDomain(normalized, this.serviceHandleDomains)) {\n // verify constraints on a service domain\n ensureHandleServiceConstraints(\n normalized,\n this.serviceHandleDomains,\n allowAnyValid,\n )\n } else {\n // When creating an account (no did yet), we require the handle to be a\n // local service domain. Updating to a custom handle will be possible once\n // the account was created.\n if (did == null) {\n throw new InvalidRequestError(\n 'Not a supported handle domain',\n 'UnsupportedDomain',\n )\n }\n\n // verify resolution of a non-service domain\n const resolvedDid = await this.idResolver.handle.resolve(normalized)\n if (resolvedDid !== did) {\n // @TODO This should use a distinct error code\n throw new InvalidRequestError('External handle did not resolve to DID')\n }\n }\n\n return normalized\n }\n\n async createAccount({\n did,\n handle,\n email,\n password,\n repoCid,\n repoRev,\n inviteCode,\n deactivated,\n refreshJwt,\n }: {\n did: DidString\n handle: HandleString\n email?: string\n password?: string\n repoCid: Cid\n repoRev: string\n inviteCode?: string\n deactivated?: boolean\n refreshJwt?: string\n }) {\n if (password && password.length > scrypt.NEW_PASSWORD_MAX_LENGTH) {\n throw new InvalidRequestError('Password too long')\n }\n\n const passwordScrypt = password\n ? await scrypt.genSaltAndHash(password)\n : undefined\n\n const now = currentDatetimeString()\n await this.db.transaction(async (dbTxn) => {\n if (inviteCode) {\n await invite.ensureInviteIsAvailable(dbTxn, inviteCode)\n }\n await Promise.all([\n account.registerActor(dbTxn, { did, handle, deactivated }),\n email && passwordScrypt\n ? account.registerAccount(dbTxn, { did, email, passwordScrypt })\n : Promise.resolve(),\n invite.recordInviteUse(dbTxn, {\n did,\n inviteCode,\n now,\n }),\n refreshJwt &&\n auth.storeRefreshToken(\n dbTxn,\n auth.decodeRefreshToken(refreshJwt),\n null,\n ),\n repo.updateRoot(dbTxn, did, repoCid, repoRev),\n ])\n })\n }\n\n async createAccountAndSession(opts: {\n did: DidString\n handle: HandleString\n email?: string\n password?: string\n repoCid: Cid\n repoRev: string\n inviteCode?: string\n deactivated?: boolean\n }) {\n const { accessJwt, refreshJwt } = await auth.createTokens({\n did: opts.did,\n jwtKey: this.jwtKey,\n serviceDid: this.serviceDid,\n scope: AuthScope.Access,\n })\n\n await this.createAccount({ ...opts, refreshJwt })\n\n return { accessJwt, refreshJwt }\n }\n\n /**\n * Validates the requested handle, updates the PLC document if needed, persists\n * the new handle locally, and emits an identity event.\n *\n * @throws {InvalidRequestError} when the handle is invalid, taken by another\n * account, or cannot be resolved for non-service domains.\n *\n * @see {@link AccountManager.updateAccountHandle} for behavior when the PLC update fails.\n */\n async updateHandle(\n did: DidString,\n newHandle: string,\n options?: { allowAnyValid?: boolean },\n ): Promise<ActorAccount & { handle: HandleString }> {\n const { account, handle } = await this.validateHandleUpdate(\n did,\n newHandle,\n options,\n )\n\n if (did.startsWith('did:plc:')) {\n // @TODO We should verify the status before issuing a PLC update.\n await this.plcClient.updateHandle(did, this.plcRotationKey, handle)\n } else {\n const resolved = await this.idResolver.did.resolveAtprotoData(did, true)\n if (resolved.handle !== handle) {\n throw new InvalidRequestError(\n 'DID is not properly configured for handle',\n )\n }\n }\n\n // @NOTE If the next line fails (for any reason), we don't \"rollback\" the\n // PLC update above. The caller can just call this method again.\n await this.updateAccountHandle(did, handle)\n\n return { ...account, handle }\n }\n\n async validateHandleUpdate(\n did: DidString,\n newHandle: string,\n options?: { allowAnyValid?: boolean },\n ): Promise<{\n did: DidString\n handle: HandleString\n // Returned for convenience\n account: ActorAccount\n }> {\n const account = await this.getAccount(did, { includeDeactivated: true })\n if (!account) {\n throw new InvalidRequestError('Account not found')\n }\n\n const handle = await this.normalizeAndValidateHandle(newHandle, {\n allowAnyValid: options?.allowAnyValid,\n did,\n })\n\n // Pessimistic check to handle spam: also enforced by updateAccountHandle() and the db.\n const existing = await this.getAccount(handle, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (existing && existing.did !== did) {\n throw new InvalidRequestError(\n `Handle already taken: ${handle}`,\n 'HandleNotAvailable',\n )\n }\n\n return { did, handle, account }\n }\n\n /**\n * @note Failure to emit the identity event will silently be ignored. Users\n * can emit the event again by updating their handle to the same value.\n */\n async updateAccountHandle(\n did: DidString,\n handle: HandleString,\n ): Promise<void> {\n await account.updateHandle(this.db, did, handle)\n\n try {\n await this.sequencer.sequenceIdentityEvt(did, handle)\n } catch (err) {\n httpLogger.error({ err, did, handle }, 'failed to sequence handle update')\n }\n }\n\n async deleteAccount(did: DidString) {\n return account.deleteAccount(this.db, did)\n }\n\n async takedownAccount(\n did: DidString,\n takedown: com.atproto.admin.defs.StatusAttr,\n ) {\n await this.db.transaction(async (dbTxn) =>\n Promise.all([\n account.updateAccountTakedownStatus(dbTxn, did, takedown),\n auth.revokeRefreshTokensByDid(dbTxn, did),\n token.removeByDidQB(dbTxn, did).execute(),\n ]),\n )\n }\n\n async getAccountAdminStatus(did: DidString) {\n return account.getAccountAdminStatus(this.db, did)\n }\n\n async updateRepoRoot(did: DidString, cid: Cid, rev: string) {\n return repo.updateRoot(this.db, did, cid, rev)\n }\n\n async deactivateAccount(did: DidString, deleteAfter: string | null) {\n return account.deactivateAccount(this.db, did, deleteAfter)\n }\n\n async activateAccount(did: DidString) {\n return account.activateAccount(this.db, did)\n }\n\n // Auth\n // ----------\n\n async createSession(\n did: DidString,\n appPassword: password.AppPassDescript | null,\n isSoftDeleted = false,\n ) {\n const { accessJwt, refreshJwt } = await auth.createTokens({\n did,\n jwtKey: this.jwtKey,\n serviceDid: this.serviceDid,\n scope: auth.formatScope(appPassword, isSoftDeleted),\n })\n // For soft deleted accounts don't store refresh token so that it can't be rotated.\n if (!isSoftDeleted) {\n const refreshPayload = auth.decodeRefreshToken(refreshJwt)\n await auth.storeRefreshToken(this.db, refreshPayload, appPassword)\n }\n return { accessJwt, refreshJwt }\n }\n\n async rotateRefreshToken(id: string) {\n const token = await auth.getRefreshToken(this.db, id)\n if (!token) return null\n\n const now = new Date()\n\n // take the chance to tidy all of a user's expired tokens\n // does not need to be transactional since this is just best-effort\n await auth.deleteExpiredRefreshTokens(this.db, token.did, now.toISOString())\n\n // Shorten the refresh token lifespan down from its\n // original expiration time to its revocation grace period.\n const prevExpiresAt = new Date(token.expiresAt)\n const REFRESH_GRACE_MS = 2 * HOUR\n const graceExpiresAt = new Date(now.getTime() + REFRESH_GRACE_MS)\n\n const expiresAt =\n graceExpiresAt < prevExpiresAt ? graceExpiresAt : prevExpiresAt\n\n if (expiresAt <= now) {\n return null\n }\n\n // Determine the next refresh token id: upon refresh token\n // reuse you always receive a refresh token with the same id.\n const nextId = token.nextId ?? auth.getRefreshTokenId()\n\n const { accessJwt, refreshJwt } = await auth.createTokens({\n did: token.did,\n jwtKey: this.jwtKey,\n serviceDid: this.serviceDid,\n scope: auth.formatScope(token.appPassword),\n jti: nextId,\n })\n\n const refreshPayload = auth.decodeRefreshToken(refreshJwt)\n try {\n await this.db.transaction((dbTxn) =>\n Promise.all([\n auth.addRefreshGracePeriod(dbTxn, {\n id,\n expiresAt: expiresAt.toISOString(),\n nextId,\n }),\n auth.storeRefreshToken(dbTxn, refreshPayload, token.appPassword),\n ]),\n )\n } catch (err) {\n if (err instanceof auth.ConcurrentRefreshError) {\n return this.rotateRefreshToken(id)\n }\n throw err\n }\n return { accessJwt, refreshJwt }\n }\n\n async revokeRefreshToken(id: string) {\n return auth.revokeRefreshToken(this.db, id)\n }\n\n // Login\n // ----------\n\n async login({\n identifier,\n password,\n }: {\n identifier: string\n password: string\n }): Promise<{\n user: ActorAccount\n appPassword: password.AppPassDescript | null\n isSoftDeleted: boolean\n }> {\n const start = Date.now()\n try {\n const identifierNormalized = identifier.toLowerCase()\n\n const user = identifierNormalized.includes('@')\n ? await this.getAccountByEmail(identifierNormalized, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n : isAtIdentifierString(identifierNormalized)\n ? await this.getAccount(identifierNormalized, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n : null\n\n if (!user) {\n throw new AuthRequiredError('Invalid identifier or password')\n }\n const isSoftDeleted = softDeleted(user)\n\n let appPassword: password.AppPassDescript | null = null\n const validAccountPass = await this.verifyAccountPassword(\n user.did,\n password,\n )\n if (!validAccountPass) {\n // takendown/suspended accounts cannot login with app password\n if (isSoftDeleted) {\n throw new InvalidPasswordError(user.did)\n }\n appPassword = await this.verifyAppPassword(user.did, password)\n if (appPassword === null) {\n throw new InvalidPasswordError(user.did)\n }\n }\n\n return { user, appPassword, isSoftDeleted }\n } finally {\n // Mitigate timing attacks\n await wait(350 - (Date.now() - start))\n }\n }\n\n // Passwords\n // ----------\n\n async createAppPassword(did: DidString, name: string, privileged: boolean) {\n return password.createAppPassword(this.db, did, name, privileged)\n }\n\n async listAppPasswords(did: DidString) {\n return password.listAppPasswords(this.db, did)\n }\n\n async verifyAccountPassword(\n did: DidString,\n passwordStr: string,\n ): Promise<boolean> {\n return password.verifyAccountPassword(this.db, did, passwordStr)\n }\n\n async verifyAppPassword(\n did: DidString,\n passwordStr: string,\n ): Promise<password.AppPassDescript | null> {\n return password.verifyAppPassword(this.db, did, passwordStr)\n }\n\n async revokeAppPassword(did: DidString, name: string) {\n await this.db.transaction(async (dbTxn) =>\n Promise.all([\n password.deleteAppPassword(dbTxn, did, name),\n auth.revokeAppPasswordRefreshToken(dbTxn, did, name),\n ]),\n )\n }\n\n // Invites\n // ----------\n\n async ensureInviteIsAvailable(code: string) {\n return invite.ensureInviteIsAvailable(this.db, code)\n }\n\n async createInviteCodes(\n toCreate: { account: string; codes: string[] }[],\n useCount: number,\n ) {\n return invite.createInviteCodes(this.db, toCreate, useCount)\n }\n\n async createAccountInviteCodes(\n forAccount: string,\n codes: string[],\n expectedTotal: number,\n disabled: 0 | 1,\n ) {\n return invite.createAccountInviteCodes(\n this.db,\n forAccount,\n codes,\n expectedTotal,\n disabled,\n )\n }\n\n async getAccountInvitesCodes(did: DidString) {\n const inviteCodes = await invite.getAccountsInviteCodes(this.db, [did])\n return inviteCodes.get(did) ?? []\n }\n\n async getAccountsInvitesCodes(dids: DidString[]) {\n return invite.getAccountsInviteCodes(this.db, dids)\n }\n\n async getInvitedByForAccounts(dids: DidString[]) {\n return invite.getInvitedByForAccounts(this.db, dids)\n }\n\n async getInviteCodesUses(codes: string[]) {\n return invite.getInviteCodesUses(this.db, codes)\n }\n\n async setAccountInvitesDisabled(did: DidString, disabled: boolean) {\n return invite.setAccountInvitesDisabled(this.db, did, disabled)\n }\n\n async disableInviteCodes(opts: { codes: string[]; accounts: string[] }) {\n return invite.disableInviteCodes(this.db, opts)\n }\n\n // Email Tokens\n // ----------\n\n async createEmailToken(did: DidString, purpose: EmailTokenPurpose) {\n return emailToken.createEmailToken(this.db, did, purpose)\n }\n\n async assertValidEmailToken(\n did: DidString,\n purpose: EmailTokenPurpose,\n token: string,\n ) {\n return emailToken.assertValidToken(this.db, did, purpose, token)\n }\n\n async assertValidEmailTokenAndCleanup(\n did: DidString,\n purpose: EmailTokenPurpose,\n token: string,\n ) {\n await emailToken.assertValidToken(this.db, did, purpose, token)\n await emailToken.deleteEmailToken(this.db, did, purpose)\n }\n\n async requestEmailConfirmation(did: DidString, opts?: { locale?: string }) {\n const account = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n if (!account.email) {\n throw new InvalidRequestError('account does not have an email address')\n }\n\n const locale = opts?.locale\n const token = await this.createEmailToken(did, 'confirm_email')\n\n await this.mailer.sendConfirmEmail({ token, locale }, { to: account.email })\n }\n\n async confirmEmail(did: DidString, email: string, token: string) {\n const user = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!user) {\n throw new InvalidRequestError('user not found', 'AccountNotFound')\n }\n\n if (user.email !== email.toLowerCase()) {\n throw new InvalidRequestError('invalid email', 'InvalidEmail')\n }\n\n await emailToken.assertValidToken(this.db, did, 'confirm_email', token)\n const now = currentDatetimeString()\n await this.db.transaction(async (dbTxn) => {\n await emailToken.deleteEmailToken(dbTxn, did, 'confirm_email')\n await account.setEmailConfirmedAt(dbTxn, did, now)\n })\n\n user.emailConfirmedAt = now\n\n return user\n }\n\n async requestEmailUpdate(\n did: DidString,\n opts?: { locale?: string },\n ): Promise<{ tokenRequired: boolean }> {\n const account = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n if (!account.email) {\n throw new InvalidRequestError('account does not have an email address')\n }\n\n const token = account.emailConfirmedAt\n ? await this.createEmailToken(did, 'update_email')\n : null\n\n if (token) {\n await this.mailer.sendUpdateEmail(\n { token, locale: opts?.locale },\n { to: account.email },\n )\n }\n\n return { tokenRequired: !!token }\n }\n\n /**\n * @throws UserAlreadyExistsError if the new email is already in use by another account\n */\n async updateEmail(\n did: DidString,\n email: string,\n token?: string,\n opts?: { locale?: string; sendConfirmationEmail?: boolean },\n ): Promise<ActorAccount> {\n if (!isEmailValid(email) || isDisposableEmail(email)) {\n throw new InvalidRequestError(\n 'This email address is not supported, please use a different email.',\n )\n }\n\n const account = await this.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n const tokenRequired = !!account.emailConfirmedAt\n\n // require a token if account email is confirmed\n if (!token && tokenRequired) {\n throw new InvalidRequestError(\n 'confirmation token required',\n 'TokenRequired',\n )\n }\n\n if (token) {\n await this.assertValidEmailToken(did, 'update_email', token)\n }\n\n await this.updateAccountEmail({ did, email })\n\n account.email = email\n account.emailConfirmedAt = null\n\n // Proactively send a confirmation email so that the user can confirm the\n // new email immediately.\n if (opts?.sendConfirmationEmail) {\n const token = await this.createEmailToken(did, 'confirm_email')\n const locale = opts.locale\n await this.mailer.sendConfirmEmail({ token, locale }, { to: email })\n }\n\n return account\n }\n\n async updateAccountEmail(opts: { did: DidString; email: string }) {\n const { did, email } = opts\n await this.db.transaction(async (dbTxn) => {\n await account.updateEmail(dbTxn, did, email)\n await emailToken.deleteAllEmailTokens(dbTxn, did)\n })\n }\n\n async resetPassword(opts: { password: string; token: string }) {\n const did = await emailToken.assertValidTokenAndFindDid(\n this.db,\n 'reset_password',\n opts.token,\n )\n await this.updateAccountPassword({ did, password: opts.password })\n\n return did\n }\n\n async updateAccountPassword(opts: { did: DidString; password: string }) {\n const { did } = opts\n const passwordScrypt = await scrypt.genSaltAndHash(opts.password)\n await this.db.transaction(async (dbTxn) =>\n Promise.all([\n password.updateUserPassword(dbTxn, { did, passwordScrypt }),\n emailToken.deleteEmailToken(dbTxn, did, 'reset_password'),\n auth.revokeRefreshTokensByDid(dbTxn, did),\n ]),\n )\n }\n}\n"]}
@@ -3,7 +3,7 @@ import { com } from '../../lexicons/index.js';
3
3
  import { AccountDb, ActorEntry } from '../db/index.js';
4
4
  export declare class UserAlreadyExistsError extends Error {
5
5
  name: string;
6
- constructor(options?: ErrorOptions);
6
+ constructor(message?: string, options?: ErrorOptions);
7
7
  }
8
8
  export type ActorAccount = ActorEntry & {
9
9
  email: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../src/account-manager/helpers/account.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,YAAY,EAGb,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEtD,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,IAAI,SAA2B;gBACnB,OAAO,CAAC,EAAE,YAAY;CAMnC;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,eAAe,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;AAED,oBAAY,aAAa;IACvB,MAAM,WAAW;IACjB,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,OAAO,YAAY;IACnB,WAAW,gBAAgB;CAC5B;AAED,eAAO,MAAM,eAAe,GAAI,IAAI,SAAS,EAAE,QAAQ,iBAAiB;;;;;;;;;;;;;;;;uUAqBvE,CAAA;AAED,eAAO,MAAM,UAAU,GACrB,IAAI,SAAS,EACb,aAAa,kBAAkB,EAC/B,QAAQ,iBAAiB,KACxB,OAAO,CAAC,YAAY,GAAG,IAAI,CAW7B,CAAA;AAED,eAAO,MAAM,WAAW,GACtB,IAAI,SAAS,EACb,MAAM,SAAS,EAAE,EACjB,QAAQ,iBAAiB,KACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAgBnC,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,IAAI,SAAS,EACb,OAAO,MAAM,EACb,QAAQ,iBAAiB,KACxB,OAAO,CAAC,YAAY,GAAG,IAAI,CAK7B,CAAA;AAED,eAAO,MAAM,aAAa,GACxB,IAAI,SAAS,EACb,MAAM;IACJ,GAAG,EAAE,SAAS,CAAA;IACd,MAAM,EAAE,YAAY,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,kBAqBF,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,IAAI,SAAS,EACb,MAAM;IACJ,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,MAAM,CAAA;CACvB,kBAiBF,CAAA;AAED,eAAO,MAAM,aAAa,GACxB,IAAI,SAAS,EACb,KAAK,SAAS,KACb,OAAO,CAAC,IAAI,CAkBd,CAAA;AAED,eAAO,MAAM,YAAY,GACvB,IAAI,SAAS,EACb,KAAK,SAAS,EACd,QAAQ,YAAY,kBAcrB,CAAA;AAED,eAAO,MAAM,WAAW,GACtB,IAAI,SAAS,EACb,KAAK,SAAS,EACd,OAAO,MAAM,kBAkBd,CAAA;AAED,eAAO,MAAM,mBAAmB,GAC9B,IAAI,SAAS,EACb,KAAK,SAAS,EACd,kBAAkB,cAAc,kBAQjC,CAAA;AAED,eAAO,MAAM,qBAAqB,GAChC,IAAI,SAAS,EACb,KAAK,SAAS,KACb,OAAO,CAAC;IACT,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAA;IAC3C,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAA;CAC/C,GAAG,IAAI,CAYP,CAAA;AAED,eAAO,MAAM,2BAA2B,GACtC,IAAI,SAAS,EACb,KAAK,SAAS,EACd,UAAU,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,kBAQ5C,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,IAAI,SAAS,EACb,KAAK,SAAS,EACd,aAAa,MAAM,GAAG,IAAI,kBAW3B,CAAA;AAED,eAAO,MAAM,eAAe,GAAU,IAAI,SAAS,EAAE,KAAK,SAAS,kBAUlE,CAAA;AAED,eAAO,MAAM,mBAAmB,GAC9B,SAAS,IAAI,GAAG;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;;;;;;;;;;;;CAWF,CAAA"}
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../src/account-manager/helpers/account.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,8 @@ import { DAY } from '@atproto/common';
2
2
  import { currentDatetimeString, isDidIdentifier, } from '@atproto/lex';
3
3
  import { isErrUniqueViolation, notSoftDeletedClause } from '../../db/index.js';
4
4
  export class UserAlreadyExistsError extends Error {
5
- constructor(options) {
6
- super('This email address is already in use, please use a different email.', options);
5
+ constructor(message = 'This email address is already in use, please use a different email.', options) {
6
+ super(message, options);
7
7
  this.name = 'UserAlreadyExistsError';
8
8
  }
9
9
  }
@@ -111,13 +111,19 @@ export const deleteAccount = async (db, did) => {
111
111
  await db.executeWithRetry(db.db.deleteFrom('actor').where('actor.did', '=', did));
112
112
  };
113
113
  export const updateHandle = async (db, did, handle) => {
114
+ // No-op if the handle is the same, but still returns 1 row affected, so that
115
+ // it can be used to check for existence of the account.
114
116
  const [res] = await db.executeWithRetry(db.db
115
117
  .updateTable('actor')
116
118
  .set({ handle })
117
119
  .where('did', '=', did)
118
- .whereNotExists(db.db.selectFrom('actor').where('handle', '=', handle).selectAll()));
120
+ .whereNotExists(db.db
121
+ .selectFrom('actor')
122
+ .where('handle', '=', handle)
123
+ .where('did', '!=', did)
124
+ .selectAll()));
119
125
  if (res.numUpdatedRows < 1) {
120
- throw new UserAlreadyExistsError();
126
+ throw new UserAlreadyExistsError('Handle is already in use, please choose a different handle.');
121
127
  }
122
128
  };
123
129
  export const updateEmail = async (db, did, email) => {
@@ -1 +1 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/account-manager/helpers/account.ts"],"names":[],"mappings":"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","sourcesContent":["import { DAY } from '@atproto/common'\nimport {\n AtIdentifierString,\n DatetimeString,\n DidString,\n HandleString,\n currentDatetimeString,\n isDidIdentifier,\n} from '@atproto/lex'\nimport { isErrUniqueViolation, notSoftDeletedClause } from '../../db/index.js'\nimport { com } from '../../lexicons/index.js'\nimport { AccountDb, ActorEntry } from '../db/index.js'\n\nexport class UserAlreadyExistsError extends Error {\n name = 'UserAlreadyExistsError'\n constructor(options?: ErrorOptions) {\n super(\n 'This email address is already in use, please use a different email.',\n options,\n )\n }\n}\n\nexport type ActorAccount = ActorEntry & {\n email: string | null\n emailConfirmedAt: string | null\n invitesDisabled: 0 | 1 | null\n}\n\nexport type AvailabilityFlags = {\n includeTakenDown?: boolean\n includeDeactivated?: boolean\n}\n\nexport enum AccountStatus {\n Active = 'active',\n Takendown = 'takendown',\n Suspended = 'suspended',\n Deleted = 'deleted',\n Deactivated = 'deactivated',\n}\n\nexport const selectAccountQB = (db: AccountDb, flags?: AvailabilityFlags) => {\n const { includeTakenDown = false, includeDeactivated = false } = flags ?? {}\n const { ref } = db.db.dynamic\n return db.db\n .selectFrom('actor')\n .leftJoin('account', 'actor.did', 'account.did')\n .if(!includeTakenDown, (qb) => qb.where(notSoftDeletedClause(ref('actor'))))\n .if(!includeDeactivated, (qb) =>\n qb.where('actor.deactivatedAt', 'is', null),\n )\n .select([\n 'actor.did',\n 'actor.handle',\n 'actor.createdAt',\n 'actor.takedownRef',\n 'actor.deactivatedAt',\n 'actor.deleteAfter',\n 'account.email',\n 'account.emailConfirmedAt',\n 'account.invitesDisabled',\n ])\n}\n\nexport const getAccount = async (\n db: AccountDb,\n handleOrDid: AtIdentifierString,\n flags?: AvailabilityFlags,\n): Promise<ActorAccount | null> => {\n const found = await selectAccountQB(db, flags)\n .where((qb) => {\n if (isDidIdentifier(handleOrDid)) {\n return qb.where('actor.did', '=', handleOrDid)\n } else {\n return qb.where('actor.handle', '=', handleOrDid)\n }\n })\n .executeTakeFirst()\n return found || null\n}\n\nexport const getAccounts = async (\n db: AccountDb,\n dids: DidString[],\n flags?: AvailabilityFlags,\n): Promise<Map<string, ActorAccount>> => {\n const results = new Map<string, ActorAccount>()\n\n if (!dids.length) {\n return results\n }\n\n const accounts = await selectAccountQB(db, flags)\n .where('actor.did', 'in', dids)\n .execute()\n\n accounts.forEach((account) => {\n results.set(account.did, account)\n })\n\n return results\n}\n\nexport const getAccountByEmail = async (\n db: AccountDb,\n email: string,\n flags?: AvailabilityFlags,\n): Promise<ActorAccount | null> => {\n const found = await selectAccountQB(db, flags)\n .where('email', '=', email.toLowerCase())\n .executeTakeFirst()\n return found || null\n}\n\nexport const registerActor = async (\n db: AccountDb,\n opts: {\n did: DidString\n handle: HandleString\n deactivated?: boolean\n },\n) => {\n const { did, handle, deactivated } = opts\n const now = Date.now()\n const createdAt = new Date(now).toISOString()\n const [registered] = await db.executeWithRetry(\n db.db\n .insertInto('actor')\n .values({\n did,\n handle,\n createdAt,\n deactivatedAt: deactivated ? createdAt : null,\n deleteAfter: deactivated ? new Date(now + 3 * DAY).toISOString() : null,\n })\n .onConflict((oc) => oc.doNothing())\n .returning('did'),\n )\n if (!registered) {\n throw new UserAlreadyExistsError()\n }\n}\n\nexport const registerAccount = async (\n db: AccountDb,\n opts: {\n did: string\n email: string\n passwordScrypt: string\n },\n) => {\n const { did, email, passwordScrypt } = opts\n const [registered] = await db.executeWithRetry(\n db.db\n .insertInto('account')\n .values({\n did,\n email: email.toLowerCase(),\n passwordScrypt,\n })\n .onConflict((oc) => oc.doNothing())\n .returning('did'),\n )\n if (!registered) {\n throw new UserAlreadyExistsError()\n }\n}\n\nexport const deleteAccount = async (\n db: AccountDb,\n did: DidString,\n): Promise<void> => {\n // Not done in transaction because it would be too long, prone to contention.\n // Also, this can safely be run multiple times if it fails.\n await db.executeWithRetry(\n db.db.deleteFrom('repo_root').where('did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('email_token').where('did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('refresh_token').where('did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('account').where('account.did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('actor').where('actor.did', '=', did),\n )\n}\n\nexport const updateHandle = async (\n db: AccountDb,\n did: DidString,\n handle: HandleString,\n) => {\n const [res] = await db.executeWithRetry(\n db.db\n .updateTable('actor')\n .set({ handle })\n .where('did', '=', did)\n .whereNotExists(\n db.db.selectFrom('actor').where('handle', '=', handle).selectAll(),\n ),\n )\n if (res.numUpdatedRows < 1) {\n throw new UserAlreadyExistsError()\n }\n}\n\nexport const updateEmail = async (\n db: AccountDb,\n did: DidString,\n email: string,\n) => {\n try {\n await db.executeWithRetry(\n db.db\n .updateTable('account')\n .set({\n email: email.toLowerCase(),\n emailConfirmedAt: null,\n })\n .where('did', '=', did),\n )\n } catch (err) {\n if (isErrUniqueViolation(err)) {\n throw new UserAlreadyExistsError()\n }\n throw err\n }\n}\n\nexport const setEmailConfirmedAt = async (\n db: AccountDb,\n did: DidString,\n emailConfirmedAt: DatetimeString,\n) => {\n await db.executeWithRetry(\n db.db\n .updateTable('account')\n .set({ emailConfirmedAt })\n .where('did', '=', did),\n )\n}\n\nexport const getAccountAdminStatus = async (\n db: AccountDb,\n did: DidString,\n): Promise<{\n takedown: com.atproto.admin.defs.StatusAttr\n deactivated: com.atproto.admin.defs.StatusAttr\n} | null> => {\n const res = await db.db\n .selectFrom('actor')\n .select(['takedownRef', 'deactivatedAt'])\n .where('did', '=', did)\n .executeTakeFirst()\n if (!res) return null\n const takedown = res.takedownRef\n ? { applied: true, ref: res.takedownRef }\n : { applied: false }\n const deactivated = res.deactivatedAt ? { applied: true } : { applied: false }\n return { takedown, deactivated }\n}\n\nexport const updateAccountTakedownStatus = async (\n db: AccountDb,\n did: DidString,\n takedown: com.atproto.admin.defs.StatusAttr,\n) => {\n const takedownRef = takedown.applied\n ? takedown.ref ?? currentDatetimeString()\n : null\n await db.executeWithRetry(\n db.db.updateTable('actor').set({ takedownRef }).where('did', '=', did),\n )\n}\n\nexport const deactivateAccount = async (\n db: AccountDb,\n did: DidString,\n deleteAfter: string | null,\n) => {\n await db.executeWithRetry(\n db.db\n .updateTable('actor')\n .set({\n deactivatedAt: currentDatetimeString(),\n deleteAfter,\n })\n .where('did', '=', did),\n )\n}\n\nexport const activateAccount = async (db: AccountDb, did: DidString) => {\n await db.executeWithRetry(\n db.db\n .updateTable('actor')\n .set({\n deactivatedAt: null,\n deleteAfter: null,\n })\n .where('did', '=', did),\n )\n}\n\nexport const formatAccountStatus = (\n account: null | {\n takedownRef: string | null\n deactivatedAt: string | null\n },\n) => {\n if (!account) {\n return { active: false, status: AccountStatus.Deleted } as const\n } else if (account.takedownRef) {\n return { active: false, status: AccountStatus.Takendown } as const\n } else if (account.deactivatedAt) {\n return { active: false, status: AccountStatus.Deactivated } as const\n } else {\n return { active: true, status: undefined } as const\n }\n}\n"]}
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/account-manager/helpers/account.ts"],"names":[],"mappings":"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","sourcesContent":["import { DAY } from '@atproto/common'\nimport {\n AtIdentifierString,\n DatetimeString,\n DidString,\n HandleString,\n currentDatetimeString,\n isDidIdentifier,\n} from '@atproto/lex'\nimport { isErrUniqueViolation, notSoftDeletedClause } from '../../db/index.js'\nimport { com } from '../../lexicons/index.js'\nimport { AccountDb, ActorEntry } from '../db/index.js'\n\nexport class UserAlreadyExistsError extends Error {\n name = 'UserAlreadyExistsError'\n constructor(\n message = 'This email address is already in use, please use a different email.',\n options?: ErrorOptions,\n ) {\n super(message, options)\n }\n}\n\nexport type ActorAccount = ActorEntry & {\n email: string | null\n emailConfirmedAt: string | null\n invitesDisabled: 0 | 1 | null\n}\n\nexport type AvailabilityFlags = {\n includeTakenDown?: boolean\n includeDeactivated?: boolean\n}\n\nexport enum AccountStatus {\n Active = 'active',\n Takendown = 'takendown',\n Suspended = 'suspended',\n Deleted = 'deleted',\n Deactivated = 'deactivated',\n}\n\nexport const selectAccountQB = (db: AccountDb, flags?: AvailabilityFlags) => {\n const { includeTakenDown = false, includeDeactivated = false } = flags ?? {}\n const { ref } = db.db.dynamic\n return db.db\n .selectFrom('actor')\n .leftJoin('account', 'actor.did', 'account.did')\n .if(!includeTakenDown, (qb) => qb.where(notSoftDeletedClause(ref('actor'))))\n .if(!includeDeactivated, (qb) =>\n qb.where('actor.deactivatedAt', 'is', null),\n )\n .select([\n 'actor.did',\n 'actor.handle',\n 'actor.createdAt',\n 'actor.takedownRef',\n 'actor.deactivatedAt',\n 'actor.deleteAfter',\n 'account.email',\n 'account.emailConfirmedAt',\n 'account.invitesDisabled',\n ])\n}\n\nexport const getAccount = async (\n db: AccountDb,\n handleOrDid: AtIdentifierString,\n flags?: AvailabilityFlags,\n): Promise<ActorAccount | null> => {\n const found = await selectAccountQB(db, flags)\n .where((qb) => {\n if (isDidIdentifier(handleOrDid)) {\n return qb.where('actor.did', '=', handleOrDid)\n } else {\n return qb.where('actor.handle', '=', handleOrDid)\n }\n })\n .executeTakeFirst()\n return found || null\n}\n\nexport const getAccounts = async (\n db: AccountDb,\n dids: DidString[],\n flags?: AvailabilityFlags,\n): Promise<Map<string, ActorAccount>> => {\n const results = new Map<string, ActorAccount>()\n\n if (!dids.length) {\n return results\n }\n\n const accounts = await selectAccountQB(db, flags)\n .where('actor.did', 'in', dids)\n .execute()\n\n accounts.forEach((account) => {\n results.set(account.did, account)\n })\n\n return results\n}\n\nexport const getAccountByEmail = async (\n db: AccountDb,\n email: string,\n flags?: AvailabilityFlags,\n): Promise<ActorAccount | null> => {\n const found = await selectAccountQB(db, flags)\n .where('email', '=', email.toLowerCase())\n .executeTakeFirst()\n return found || null\n}\n\nexport const registerActor = async (\n db: AccountDb,\n opts: {\n did: DidString\n handle: HandleString\n deactivated?: boolean\n },\n) => {\n const { did, handle, deactivated } = opts\n const now = Date.now()\n const createdAt = new Date(now).toISOString()\n const [registered] = await db.executeWithRetry(\n db.db\n .insertInto('actor')\n .values({\n did,\n handle,\n createdAt,\n deactivatedAt: deactivated ? createdAt : null,\n deleteAfter: deactivated ? new Date(now + 3 * DAY).toISOString() : null,\n })\n .onConflict((oc) => oc.doNothing())\n .returning('did'),\n )\n if (!registered) {\n throw new UserAlreadyExistsError()\n }\n}\n\nexport const registerAccount = async (\n db: AccountDb,\n opts: {\n did: string\n email: string\n passwordScrypt: string\n },\n) => {\n const { did, email, passwordScrypt } = opts\n const [registered] = await db.executeWithRetry(\n db.db\n .insertInto('account')\n .values({\n did,\n email: email.toLowerCase(),\n passwordScrypt,\n })\n .onConflict((oc) => oc.doNothing())\n .returning('did'),\n )\n if (!registered) {\n throw new UserAlreadyExistsError()\n }\n}\n\nexport const deleteAccount = async (\n db: AccountDb,\n did: DidString,\n): Promise<void> => {\n // Not done in transaction because it would be too long, prone to contention.\n // Also, this can safely be run multiple times if it fails.\n await db.executeWithRetry(\n db.db.deleteFrom('repo_root').where('did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('email_token').where('did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('refresh_token').where('did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('account').where('account.did', '=', did),\n )\n await db.executeWithRetry(\n db.db.deleteFrom('actor').where('actor.did', '=', did),\n )\n}\n\nexport const updateHandle = async (\n db: AccountDb,\n did: DidString,\n handle: HandleString,\n) => {\n // No-op if the handle is the same, but still returns 1 row affected, so that\n // it can be used to check for existence of the account.\n const [res] = await db.executeWithRetry(\n db.db\n .updateTable('actor')\n .set({ handle })\n .where('did', '=', did)\n .whereNotExists(\n db.db\n .selectFrom('actor')\n .where('handle', '=', handle)\n .where('did', '!=', did)\n .selectAll(),\n ),\n )\n if (res.numUpdatedRows < 1) {\n throw new UserAlreadyExistsError(\n 'Handle is already in use, please choose a different handle.',\n )\n }\n}\n\nexport const updateEmail = async (\n db: AccountDb,\n did: DidString,\n email: string,\n) => {\n try {\n await db.executeWithRetry(\n db.db\n .updateTable('account')\n .set({\n email: email.toLowerCase(),\n emailConfirmedAt: null,\n })\n .where('did', '=', did),\n )\n } catch (err) {\n if (isErrUniqueViolation(err)) {\n throw new UserAlreadyExistsError()\n }\n throw err\n }\n}\n\nexport const setEmailConfirmedAt = async (\n db: AccountDb,\n did: DidString,\n emailConfirmedAt: DatetimeString,\n) => {\n await db.executeWithRetry(\n db.db\n .updateTable('account')\n .set({ emailConfirmedAt })\n .where('did', '=', did),\n )\n}\n\nexport const getAccountAdminStatus = async (\n db: AccountDb,\n did: DidString,\n): Promise<{\n takedown: com.atproto.admin.defs.StatusAttr\n deactivated: com.atproto.admin.defs.StatusAttr\n} | null> => {\n const res = await db.db\n .selectFrom('actor')\n .select(['takedownRef', 'deactivatedAt'])\n .where('did', '=', did)\n .executeTakeFirst()\n if (!res) return null\n const takedown = res.takedownRef\n ? { applied: true, ref: res.takedownRef }\n : { applied: false }\n const deactivated = res.deactivatedAt ? { applied: true } : { applied: false }\n return { takedown, deactivated }\n}\n\nexport const updateAccountTakedownStatus = async (\n db: AccountDb,\n did: DidString,\n takedown: com.atproto.admin.defs.StatusAttr,\n) => {\n const takedownRef = takedown.applied\n ? takedown.ref ?? currentDatetimeString()\n : null\n await db.executeWithRetry(\n db.db.updateTable('actor').set({ takedownRef }).where('did', '=', did),\n )\n}\n\nexport const deactivateAccount = async (\n db: AccountDb,\n did: DidString,\n deleteAfter: string | null,\n) => {\n await db.executeWithRetry(\n db.db\n .updateTable('actor')\n .set({\n deactivatedAt: currentDatetimeString(),\n deleteAfter,\n })\n .where('did', '=', did),\n )\n}\n\nexport const activateAccount = async (db: AccountDb, did: DidString) => {\n await db.executeWithRetry(\n db.db\n .updateTable('actor')\n .set({\n deactivatedAt: null,\n deleteAfter: null,\n })\n .where('did', '=', did),\n )\n}\n\nexport const formatAccountStatus = (\n account: null | {\n takedownRef: string | null\n deactivatedAt: string | null\n },\n) => {\n if (!account) {\n return { active: false, status: AccountStatus.Deleted } as const\n } else if (account.takedownRef) {\n return { active: false, status: AccountStatus.Takendown } as const\n } else if (account.deactivatedAt) {\n return { active: false, status: AccountStatus.Deactivated } as const\n } else {\n return { active: true, status: undefined } as const\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { Client } from '@did-plc/lib';
2
2
  import { Keypair } from '@atproto/crypto';
3
3
  import { HandleString } from '@atproto/lex';
4
- import { Account, AccountStore, AuthenticateAccountData, AuthorizedClientData, AuthorizedClients, ClientId, Code, DeviceAccount, DeviceData, DeviceId, DeviceStore, FoundRequestResult, LexiconData, LexiconStore, NewTokenData, RefreshToken, RequestData, RequestId, RequestStore, ResetPasswordConfirmInput, ResetPasswordRequestInput, SignUpData, Sub, TokenData, TokenId, TokenInfo, TokenStore, UpdateEmailConfirmInput, UpdateEmailRequestInput, UpdateEmailRequestOutput, UpdateRequestData, VerifyEmailConfirmInput, VerifyEmailRequestInput } from '@atproto/oauth-provider';
4
+ import { Account, AccountStore, AuthenticateAccountData, AuthorizedClientData, AuthorizedClients, ClientId, Code, DeviceAccount, DeviceData, DeviceId, DeviceStore, FoundRequestResult, LexiconData, LexiconStore, NewTokenData, RefreshToken, RequestData, RequestId, RequestStore, ResetPasswordConfirmInput, ResetPasswordRequestInput, SignUpData, Sub, TokenData, TokenId, TokenInfo, TokenStore, UpdateEmailConfirmInput, UpdateEmailRequestInput, UpdateEmailRequestOutput, UpdateHandleData, UpdateRequestData, VerifyEmailConfirmInput, VerifyEmailRequestInput } from '@atproto/oauth-provider';
5
5
  import { ActorStore } from '../actor-store/actor-store.js';
6
6
  import { BackgroundQueue } from '../background.js';
7
7
  import { ImageUrlBuilder } from '../image/image-url-builder.js';
@@ -71,6 +71,7 @@ export declare class OAuthStore implements AccountStore, RequestStore, DeviceSto
71
71
  verifyEmailConfirm({ sub: did, email, token, }: VerifyEmailConfirmInput): Promise<Account | null>;
72
72
  updateEmailRequest({ sub: did, locale, }: UpdateEmailRequestInput): Promise<UpdateEmailRequestOutput>;
73
73
  updateEmailConfirm({ sub: did, token, email, locale, }: UpdateEmailConfirmInput): Promise<Account | null>;
74
+ updateHandle({ sub: did, handle }: UpdateHandleData): Promise<Account>;
74
75
  private toTokenInfo;
75
76
  private buildAccount;
76
77
  }