@atproto/pds 0.5.5 → 0.5.7

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 (256) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/account-manager/account-manager.d.ts +51 -13
  3. package/dist/account-manager/account-manager.d.ts.map +1 -1
  4. package/dist/account-manager/account-manager.js +86 -26
  5. package/dist/account-manager/account-manager.js.map +1 -1
  6. package/dist/account-manager/db/migrations/005-oauth-account-management.d.ts.map +1 -1
  7. package/dist/account-manager/db/migrations/005-oauth-account-management.js +3 -4
  8. package/dist/account-manager/db/migrations/005-oauth-account-management.js.map +1 -1
  9. package/dist/account-manager/db/schema/authorization-request.d.ts +2 -2
  10. package/dist/account-manager/db/schema/authorization-request.d.ts.map +1 -1
  11. package/dist/account-manager/db/schema/authorization-request.js.map +1 -1
  12. package/dist/account-manager/db/schema/authorized-client.d.ts +2 -2
  13. package/dist/account-manager/db/schema/authorized-client.d.ts.map +1 -1
  14. package/dist/account-manager/db/schema/authorized-client.js.map +1 -1
  15. package/dist/account-manager/db/schema/token.d.ts +2 -2
  16. package/dist/account-manager/db/schema/token.d.ts.map +1 -1
  17. package/dist/account-manager/db/schema/token.js.map +1 -1
  18. package/dist/account-manager/helpers/account-device.d.ts +23 -196
  19. package/dist/account-manager/helpers/account-device.d.ts.map +1 -1
  20. package/dist/account-manager/helpers/account-device.js +3 -3
  21. package/dist/account-manager/helpers/account-device.js.map +1 -1
  22. package/dist/account-manager/helpers/account.d.ts +14 -4
  23. package/dist/account-manager/helpers/account.d.ts.map +1 -1
  24. package/dist/account-manager/helpers/account.js +17 -11
  25. package/dist/account-manager/helpers/account.js.map +1 -1
  26. package/dist/account-manager/helpers/auth.js +1 -1
  27. package/dist/account-manager/helpers/auth.js.map +1 -1
  28. package/dist/account-manager/helpers/authorization-request.d.ts +83 -5
  29. package/dist/account-manager/helpers/authorization-request.d.ts.map +1 -1
  30. package/dist/account-manager/helpers/authorization-request.js +8 -8
  31. package/dist/account-manager/helpers/authorization-request.js.map +1 -1
  32. package/dist/account-manager/helpers/authorized-client.d.ts +5 -4
  33. package/dist/account-manager/helpers/authorized-client.d.ts.map +1 -1
  34. package/dist/account-manager/helpers/authorized-client.js +3 -0
  35. package/dist/account-manager/helpers/authorized-client.js.map +1 -1
  36. package/dist/account-manager/helpers/device.d.ts +9 -3
  37. package/dist/account-manager/helpers/device.d.ts.map +1 -1
  38. package/dist/account-manager/helpers/device.js +4 -4
  39. package/dist/account-manager/helpers/device.js.map +1 -1
  40. package/dist/account-manager/helpers/invite.d.ts +35 -2
  41. package/dist/account-manager/helpers/invite.d.ts.map +1 -1
  42. package/dist/account-manager/helpers/lexicon.d.ts.map +1 -1
  43. package/dist/account-manager/helpers/lexicon.js +6 -0
  44. package/dist/account-manager/helpers/lexicon.js.map +1 -1
  45. package/dist/account-manager/helpers/password.d.ts +1 -0
  46. package/dist/account-manager/helpers/password.d.ts.map +1 -1
  47. package/dist/account-manager/helpers/password.js +3 -0
  48. package/dist/account-manager/helpers/password.js.map +1 -1
  49. package/dist/account-manager/helpers/token.d.ts +72 -1031
  50. package/dist/account-manager/helpers/token.d.ts.map +1 -1
  51. package/dist/account-manager/helpers/token.js +13 -10
  52. package/dist/account-manager/helpers/token.js.map +1 -1
  53. package/dist/account-manager/helpers/used-refresh-token.d.ts +6 -2
  54. package/dist/account-manager/helpers/used-refresh-token.d.ts.map +1 -1
  55. package/dist/account-manager/oauth-store.d.ts +17 -13
  56. package/dist/account-manager/oauth-store.d.ts.map +1 -1
  57. package/dist/account-manager/oauth-store.js +89 -39
  58. package/dist/account-manager/oauth-store.js.map +1 -1
  59. package/dist/actor-store/blob/reader.d.ts.map +1 -1
  60. package/dist/actor-store/blob/reader.js +2 -3
  61. package/dist/actor-store/blob/reader.js.map +1 -1
  62. package/dist/actor-store/record/reader.js +3 -3
  63. package/dist/actor-store/record/reader.js.map +1 -1
  64. package/dist/actor-store/repo/sql-repo-reader.d.ts +5 -1
  65. package/dist/actor-store/repo/sql-repo-reader.d.ts.map +1 -1
  66. package/dist/actor-store/repo/sql-repo-reader.js.map +1 -1
  67. package/dist/api/com/atproto/admin/updateSubjectStatus.d.ts.map +1 -1
  68. package/dist/api/com/atproto/admin/updateSubjectStatus.js +12 -4
  69. package/dist/api/com/atproto/admin/updateSubjectStatus.js.map +1 -1
  70. package/dist/api/com/atproto/server/activateAccount.d.ts.map +1 -1
  71. package/dist/api/com/atproto/server/activateAccount.js +25 -31
  72. package/dist/api/com/atproto/server/activateAccount.js.map +1 -1
  73. package/dist/api/com/atproto/server/deactivateAccount.d.ts.map +1 -1
  74. package/dist/api/com/atproto/server/deactivateAccount.js +3 -4
  75. package/dist/api/com/atproto/server/deactivateAccount.js.map +1 -1
  76. package/dist/api/com/atproto/server/deleteAccount.d.ts.map +1 -1
  77. package/dist/api/com/atproto/server/deleteAccount.js +51 -37
  78. package/dist/api/com/atproto/server/deleteAccount.js.map +1 -1
  79. package/dist/api/com/atproto/server/util.d.ts +25 -6
  80. package/dist/api/com/atproto/server/util.d.ts.map +1 -1
  81. package/dist/api/com/atproto/server/util.js.map +1 -1
  82. package/dist/background.d.ts +12 -6
  83. package/dist/background.d.ts.map +1 -1
  84. package/dist/background.js +32 -13
  85. package/dist/background.js.map +1 -1
  86. package/dist/config/config.d.ts +2 -1
  87. package/dist/config/config.d.ts.map +1 -1
  88. package/dist/config/config.js +4 -1
  89. package/dist/config/config.js.map +1 -1
  90. package/dist/context.d.ts.map +1 -1
  91. package/dist/context.js +5 -32
  92. package/dist/context.js.map +1 -1
  93. package/dist/db/migrator.d.ts +4 -3
  94. package/dist/db/migrator.d.ts.map +1 -1
  95. package/dist/db/migrator.js +1 -1
  96. package/dist/db/migrator.js.map +1 -1
  97. package/dist/db/pagination.d.ts +2 -1
  98. package/dist/db/pagination.d.ts.map +1 -1
  99. package/dist/db/pagination.js +2 -2
  100. package/dist/db/pagination.js.map +1 -1
  101. package/dist/db/util.d.ts +3 -3
  102. package/dist/db/util.d.ts.map +1 -1
  103. package/dist/db/util.js.map +1 -1
  104. package/dist/index.d.ts +1 -0
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +33 -11
  107. package/dist/index.js.map +1 -1
  108. package/dist/lexicons/app/bsky/notification/defs.defs.d.ts +5 -0
  109. package/dist/lexicons/app/bsky/notification/defs.defs.d.ts.map +1 -1
  110. package/dist/lexicons/app/bsky/notification/defs.defs.js +1 -0
  111. package/dist/lexicons/app/bsky/notification/defs.defs.js.map +1 -1
  112. package/dist/lexicons/chat/bsky/notification/defs.d.ts +2 -0
  113. package/dist/lexicons/chat/bsky/notification/defs.d.ts.map +1 -0
  114. package/dist/lexicons/chat/bsky/notification/defs.defs.d.ts +20 -0
  115. package/dist/lexicons/chat/bsky/notification/defs.defs.d.ts.map +1 -0
  116. package/dist/lexicons/chat/bsky/notification/defs.defs.js +19 -0
  117. package/dist/lexicons/chat/bsky/notification/defs.defs.js.map +1 -0
  118. package/dist/lexicons/chat/bsky/notification/defs.js +5 -0
  119. package/dist/lexicons/chat/bsky/notification/defs.js.map +1 -0
  120. package/dist/lexicons/chat/bsky/notification/getPreferences.d.ts +3 -0
  121. package/dist/lexicons/chat/bsky/notification/getPreferences.d.ts.map +1 -0
  122. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.d.ts +18 -0
  123. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.d.ts.map +1 -0
  124. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.js +16 -0
  125. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.js.map +1 -0
  126. package/dist/lexicons/chat/bsky/notification/getPreferences.js +6 -0
  127. package/dist/lexicons/chat/bsky/notification/getPreferences.js.map +1 -0
  128. package/dist/lexicons/chat/bsky/notification/putPreferences.d.ts +3 -0
  129. package/dist/lexicons/chat/bsky/notification/putPreferences.d.ts.map +1 -0
  130. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.d.ts +27 -0
  131. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.d.ts.map +1 -0
  132. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.js +22 -0
  133. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.js.map +1 -0
  134. package/dist/lexicons/chat/bsky/notification/putPreferences.js +6 -0
  135. package/dist/lexicons/chat/bsky/notification/putPreferences.js.map +1 -0
  136. package/dist/lexicons/chat/bsky/notification.d.ts +4 -0
  137. package/dist/lexicons/chat/bsky/notification.d.ts.map +1 -0
  138. package/dist/lexicons/chat/bsky/notification.js +7 -0
  139. package/dist/lexicons/chat/bsky/notification.js.map +1 -0
  140. package/dist/lexicons/chat/bsky.d.ts +1 -0
  141. package/dist/lexicons/chat/bsky.d.ts.map +1 -1
  142. package/dist/lexicons/chat/bsky.js +1 -0
  143. package/dist/lexicons/chat/bsky.js.map +1 -1
  144. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts +4 -0
  145. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts.map +1 -1
  146. package/dist/lexicons/tools/ozone/report/defs.defs.js +2 -0
  147. package/dist/lexicons/tools/ozone/report/defs.defs.js.map +1 -1
  148. package/dist/lexicons/tools/ozone/report/queryActivities.d.ts +3 -0
  149. package/dist/lexicons/tools/ozone/report/queryActivities.d.ts.map +1 -0
  150. package/dist/lexicons/tools/ozone/report/queryActivities.defs.d.ts +42 -0
  151. package/dist/lexicons/tools/ozone/report/queryActivities.defs.d.ts.map +1 -0
  152. package/dist/lexicons/tools/ozone/report/queryActivities.defs.js +31 -0
  153. package/dist/lexicons/tools/ozone/report/queryActivities.defs.js.map +1 -0
  154. package/dist/lexicons/tools/ozone/report/queryActivities.js +6 -0
  155. package/dist/lexicons/tools/ozone/report/queryActivities.js.map +1 -0
  156. package/dist/lexicons/tools/ozone/report.d.ts +1 -0
  157. package/dist/lexicons/tools/ozone/report.d.ts.map +1 -1
  158. package/dist/lexicons/tools/ozone/report.js +1 -0
  159. package/dist/lexicons/tools/ozone/report.js.map +1 -1
  160. package/dist/mailer/index.d.ts +2 -0
  161. package/dist/mailer/index.d.ts.map +1 -1
  162. package/dist/mailer/index.js +2 -0
  163. package/dist/mailer/index.js.map +1 -1
  164. package/dist/pipethrough.d.ts +3 -0
  165. package/dist/pipethrough.d.ts.map +1 -1
  166. package/dist/pipethrough.js +32 -0
  167. package/dist/pipethrough.js.map +1 -1
  168. package/dist/scripts/sequencer-recovery/recovery-db.js.map +1 -1
  169. package/dist/sequencer/events.d.ts.map +1 -1
  170. package/dist/sequencer/events.js +6 -13
  171. package/dist/sequencer/events.js.map +1 -1
  172. package/dist/sequencer/sequencer.d.ts +1 -1
  173. package/dist/sequencer/sequencer.d.ts.map +1 -1
  174. package/dist/sequencer/sequencer.js.map +1 -1
  175. package/package.json +14 -14
  176. package/src/account-manager/account-manager.ts +135 -36
  177. package/src/account-manager/db/migrations/005-oauth-account-management.ts +6 -5
  178. package/src/account-manager/db/schema/authorization-request.ts +2 -1
  179. package/src/account-manager/db/schema/authorized-client.ts +6 -2
  180. package/src/account-manager/db/schema/token.ts +2 -2
  181. package/src/account-manager/helpers/account-device.ts +5 -11
  182. package/src/account-manager/helpers/account.ts +39 -16
  183. package/src/account-manager/helpers/auth.ts +2 -2
  184. package/src/account-manager/helpers/authorization-request.ts +12 -8
  185. package/src/account-manager/helpers/authorized-client.ts +12 -6
  186. package/src/account-manager/helpers/device.ts +4 -4
  187. package/src/account-manager/helpers/lexicon.ts +8 -3
  188. package/src/account-manager/helpers/password.ts +6 -0
  189. package/src/account-manager/helpers/token.ts +17 -11
  190. package/src/account-manager/oauth-store.ts +129 -61
  191. package/src/actor-store/blob/reader.ts +8 -5
  192. package/src/actor-store/record/reader.ts +3 -3
  193. package/src/actor-store/repo/sql-repo-reader.ts +1 -1
  194. package/src/api/com/atproto/admin/updateSubjectStatus.ts +16 -4
  195. package/src/api/com/atproto/server/activateAccount.ts +27 -49
  196. package/src/api/com/atproto/server/deactivateAccount.ts +3 -7
  197. package/src/api/com/atproto/server/deleteAccount.ts +60 -43
  198. package/src/api/com/atproto/server/util.ts +24 -7
  199. package/src/background.ts +49 -18
  200. package/src/config/config.ts +7 -2
  201. package/src/context.ts +6 -40
  202. package/src/db/migrator.ts +2 -1
  203. package/src/db/pagination.ts +7 -7
  204. package/src/db/util.ts +5 -2
  205. package/src/index.ts +31 -13
  206. package/src/mailer/index.ts +4 -2
  207. package/src/pipethrough.ts +38 -1
  208. package/src/scripts/sequencer-recovery/recovery-db.ts +1 -1
  209. package/src/sequencer/events.ts +8 -13
  210. package/src/sequencer/sequencer.ts +1 -3
  211. package/tests/_util.ts +8 -25
  212. package/tests/account-deactivation.test.ts +1 -1
  213. package/tests/account-deletion.test.ts +1 -1
  214. package/tests/account-manager.test.ts +79 -0
  215. package/tests/account-migration.test.ts +2 -2
  216. package/tests/account-status.test.ts +206 -0
  217. package/tests/account.test.ts +1 -1
  218. package/tests/app-passwords.test.ts +1 -1
  219. package/tests/auth.test.ts +1 -1
  220. package/tests/blob-deletes.test.ts +1 -1
  221. package/tests/create-post.test.ts +1 -1
  222. package/tests/crud.test.ts +1 -1
  223. package/tests/db.test.ts +4 -4
  224. package/tests/email-confirmation.test.ts +1 -1
  225. package/tests/file-uploads.test.ts +2 -2
  226. package/tests/get-service-auth.test.ts +1 -1
  227. package/tests/handles.test.ts +1 -1
  228. package/tests/invite-codes.test.ts +1 -1
  229. package/tests/invites-admin.test.ts +1 -1
  230. package/tests/moderation.test.ts +1 -1
  231. package/tests/moderator-auth.test.ts +1 -1
  232. package/tests/oauth.test.ts +91 -0
  233. package/tests/plc-operations.test.ts +1 -1
  234. package/tests/preferences.test.ts +1 -1
  235. package/tests/proxied/admin.test.ts +1 -1
  236. package/tests/proxied/feedgen.test.ts +1 -1
  237. package/tests/proxied/notif.test.ts +6 -13
  238. package/tests/proxied/procedures.test.ts +1 -1
  239. package/tests/proxied/proxy-catchall.test.ts +9 -8
  240. package/tests/proxied/proxy-header.test.ts +12 -8
  241. package/tests/proxied/proxy-oauth-aud.test.ts +17 -10
  242. package/tests/proxied/read-after-write.test.ts +4 -5
  243. package/tests/proxied/views.test.ts +1 -1
  244. package/tests/races.test.ts +1 -1
  245. package/tests/rate-limits.test.ts +1 -1
  246. package/tests/recovery.test.ts +1 -1
  247. package/tests/seeds/basic.ts +2 -2
  248. package/tests/seeds/users.ts +4 -1
  249. package/tests/sequencer.test.ts +1 -1
  250. package/tests/server.test.ts +9 -12
  251. package/tests/sync/invertible-ops.test.ts +1 -1
  252. package/tests/sync/list.test.ts +1 -1
  253. package/tests/sync/subscribe-repos.test.ts +1 -1
  254. package/tests/sync/sync.test.ts +1 -1
  255. package/tests/takedown-appeal.test.ts +1 -1
  256. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-store.js","sourceRoot":"","sources":["../../src/account-manager/oauth-store.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { Client, createOp as createPlcOp } from '@did-plc/lib'\nimport { Selectable } from 'kysely'\nimport { Keypair, Secp256k1Keypair } from '@atproto/crypto'\nimport {\n DidString,\n HandleString,\n asAtIdentifierString,\n getBlobCidString,\n isDidString,\n isHandleString,\n} from '@atproto/lex'\nimport {\n Account,\n AccountStore,\n AuthenticateAccountData,\n AuthorizedClientData,\n AuthorizedClients,\n ClientId,\n Code,\n DeviceAccount,\n DeviceData,\n DeviceId,\n DeviceStore,\n FoundRequestResult,\n HandleUnavailableError,\n HandleUnavailableReason,\n InvalidCredentialsError,\n InvalidInviteCodeError,\n InvalidRequestError,\n LexiconData,\n LexiconStore,\n NewTokenData,\n RefreshToken,\n RequestData,\n RequestId,\n RequestStore,\n ResetPasswordConfirmInput,\n ResetPasswordRequestInput,\n SignUpData,\n Sub,\n TokenData,\n TokenId,\n TokenInfo,\n TokenStore,\n UpdateEmailConfirmInput,\n UpdateEmailRequestInput,\n UpdateEmailRequestOutput,\n UpdateHandleData,\n UpdateRequestData,\n VerifyEmailConfirmInput,\n VerifyEmailRequestInput,\n} from '@atproto/oauth-provider'\nimport {\n AuthRequiredError as XrpcAuthRequiredError,\n InvalidRequestError as XrpcInvalidRequestError,\n} from '@atproto/xrpc-server'\nimport { ActorStore } from '../actor-store/actor-store.js'\nimport { BackgroundQueue } from '../background.js'\nimport { fromDateISO } from '../db/index.js'\nimport { ImageUrlBuilder } from '../image/image-url-builder.js'\nimport { dbLogger } from '../logger.js'\nimport { ServerMailer } from '../mailer/index.js'\nimport { Sequencer } from '../sequencer/index.js'\nimport { AccountManager, InvalidPasswordError } from './account-manager.js'\nimport * as schemas from './db/schema/index.js'\nimport * as accountDeviceHelper from './helpers/account-device.js'\nimport { ActorAccount, UserAlreadyExistsError } from './helpers/account.js'\nimport * as authRequestHelper from './helpers/authorization-request.js'\nimport * as authorizedClientHelper from './helpers/authorized-client.js'\nimport * as deviceHelper from './helpers/device.js'\nimport * as lexiconHelper from './helpers/lexicon.js'\nimport * as tokenHelper from './helpers/token.js'\nimport * as usedRefreshTokenHelper from './helpers/used-refresh-token.js'\n\n/**\n * This class' purpose is to implement the interface needed by the OAuthProvider\n * to interact with the account database (through the {@link AccountManager}).\n *\n * @note The use of this class assumes that there is no entryway.\n */\nexport class OAuthStore\n implements AccountStore, RequestStore, DeviceStore, LexiconStore, TokenStore\n{\n constructor(\n private readonly accountManager: AccountManager,\n private readonly actorStore: ActorStore,\n private readonly imageUrlBuilder: ImageUrlBuilder,\n private readonly backgroundQueue: BackgroundQueue,\n private readonly mailer: ServerMailer,\n private readonly sequencer: Sequencer,\n private readonly plcClient: Client,\n private readonly plcRotationKey: Keypair,\n private readonly publicUrl: string,\n private readonly recoveryDidKey: string | null,\n ) {}\n\n private get db() {\n const { db } = this.accountManager\n if (db.destroyed) throw new Error('Database connection is closed')\n return db\n }\n\n private get serviceDid() {\n return this.accountManager.serviceDid\n }\n\n private async verifyEmailAvailability(email: string): Promise<void> {\n // @NOTE Email validity & disposability check performed by the OAuthProvider\n\n const account = await this.accountManager.getAccountByEmail(email, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (account) {\n throw new InvalidRequestError(`Email already taken`)\n }\n }\n\n private async verifyInviteCode(code: string) {\n try {\n await this.accountManager.ensureInviteIsAvailable(code)\n } catch (err) {\n const message =\n err instanceof XrpcInvalidRequestError ? err.message : undefined\n throw new InvalidInviteCodeError(message, err)\n }\n }\n\n // AccountStore\n\n async createAccount({\n locale: _locale,\n inviteCode,\n handle,\n email,\n password,\n }: SignUpData): Promise<Account> {\n // @TODO Send an account creation confirmation email (+verification link) to the user (in their locale)\n // @NOTE Password strength & length already enforced by the OAuthProvider\n\n assert(isHandleString(handle), 'Handle must be a valid HandleString')\n\n await Promise.all([\n this.verifyEmailAvailability(email),\n this.verifyHandleAvailability(handle),\n !inviteCode || this.verifyInviteCode(inviteCode),\n ])\n\n // @TODO The code bellow should probably be refactored to be common with the\n // code of the `com.atproto.server.createAccount` XRPC endpoint.\n\n const signingKey = await Secp256k1Keypair.create({ exportable: true })\n const signingKeyDid = signingKey.did()\n\n const canTombstone =\n // @NOTE IMPORTANT We don't support \"bring your own DID\" here (yet?). If\n // we ever do, make sure to update the computation of canTombstone so that\n // the user's did don't get tombstoned.\n true\n\n const plc = await createPlcOp({\n signingKey: signingKeyDid,\n rotationKeys: this.recoveryDidKey\n ? [this.recoveryDidKey, this.plcRotationKey.did()]\n : [this.plcRotationKey.did()],\n handle,\n pds: this.publicUrl,\n signer: this.plcRotationKey,\n })\n\n const did = plc.did as DidString\n\n try {\n await this.actorStore.create(did, signingKey)\n\n try {\n const commit = await this.actorStore.transact(did, (actorTxn) => {\n return actorTxn.repo.createRepo([])\n })\n\n await this.plcClient.sendOperation(did, plc.op)\n\n try {\n await this.accountManager.createAccount({\n did,\n handle,\n email,\n password,\n inviteCode,\n repoCid: commit.cid,\n repoRev: commit.rev,\n })\n\n try {\n await this.sequencer.sequenceAccountCreation(did, handle, commit)\n\n try {\n await this.actorStore\n .clearReservedKeypair(signingKeyDid, did)\n .catch((err) => {\n // @NOTE This is a cleanup operation so we won't fail the\n // whole flow if it fails, but we log it just in case\n dbLogger.error(\n { did, signingKeyDid, err },\n 'Failed to clear reserved keypair',\n )\n })\n\n const account = await this.accountManager.getAccount(did)\n assert(account, 'Account not found after creation')\n\n return await this.buildAccount(account)\n } catch (err) {\n await this.sequencer.sequenceAccountDeletion(did)\n throw err\n }\n } catch (err) {\n await this.accountManager.deleteAccount(did)\n throw err\n }\n } catch (err) {\n if (canTombstone) {\n await this.plcClient.tombstone(did, this.plcRotationKey)\n }\n throw err\n }\n } catch (err) {\n await this.actorStore.destroy(did)\n throw err\n }\n } catch (err) {\n // XrpcError => OAuthError\n if (err instanceof XrpcInvalidRequestError) {\n throw new InvalidRequestError(err.message, err)\n }\n throw err\n }\n }\n\n async authenticateAccount({\n locale: _locale,\n username: identifier,\n password,\n // Not supported by the PDS (yet?)\n emailOtp = undefined,\n }: AuthenticateAccountData): Promise<Account> {\n // @TODO (?) Send an email to the user to notify them of the login attempt\n try {\n // Should never happen\n if (emailOtp != null) {\n throw new Error('Email OTP is not supported')\n }\n\n const { user, appPassword, isSoftDeleted } =\n await this.accountManager.login({ identifier, password })\n\n if (isSoftDeleted) {\n throw new InvalidRequestError('Account was taken down')\n }\n\n if (appPassword) {\n throw new InvalidRequestError('App passwords are not allowed')\n }\n\n return this.buildAccount(user)\n } catch (err) {\n // `InvalidPasswordError` is a subclass of `XrpcAuthRequiredError`,\n // so it must be checked first. Surfacing the matched `did` as the\n // `sub` lets the oauth-provider's `onSignInFailed` hook distinguish\n // \"identifier known, credentials wrong\" from \"identifier unknown\".\n if (err instanceof InvalidPasswordError) {\n throw new InvalidCredentialsError(err.message, err.did, err)\n }\n if (err instanceof XrpcAuthRequiredError) {\n throw new InvalidCredentialsError(err.message, undefined, err)\n }\n throw err\n }\n }\n\n async setAuthorizedClient(\n sub: Sub,\n clientId: ClientId,\n data: AuthorizedClientData,\n ): Promise<void> {\n await authorizedClientHelper.upsert(this.db, sub, clientId, data)\n }\n\n async getAccount(sub: Sub): Promise<{\n account: Account\n authorizedClients: AuthorizedClients\n }> {\n const accountRow = await this.accountManager.getAccount(\n // @TODO @atproto/oauth-provider should strongly type `Sub` as `DidString`\n asAtIdentifierString(sub),\n {\n includeDeactivated: true,\n includeTakenDown: false,\n },\n )\n\n assert(accountRow, 'Account not found')\n\n const account = await this.buildAccount(accountRow)\n const authorizedClients = await authorizedClientHelper.getAuthorizedClients(\n this.db,\n sub,\n )\n\n return { account, authorizedClients }\n }\n\n async upsertDeviceAccount(deviceId: DeviceId, sub: string): Promise<void> {\n await this.db.executeWithRetry(\n accountDeviceHelper.upsertQB(this.db, deviceId, sub),\n )\n }\n\n async getDeviceAccount(\n deviceId: DeviceId,\n sub: string,\n ): Promise<DeviceAccount | null> {\n const row = await accountDeviceHelper\n .selectQB(this.db, { deviceId, sub })\n .executeTakeFirst()\n\n if (!row) return null\n\n return {\n deviceId,\n deviceData: deviceHelper.rowToDeviceData(row),\n account: await this.buildAccount(row),\n authorizedClients: await authorizedClientHelper.getAuthorizedClients(\n this.db,\n sub,\n ),\n createdAt: fromDateISO(row.adCreatedAt),\n updatedAt: fromDateISO(row.adUpdatedAt),\n }\n }\n\n async removeDeviceAccount(deviceId: DeviceId, sub: Sub): Promise<void> {\n await this.db.executeWithRetry(\n accountDeviceHelper.removeQB(this.db, deviceId, sub),\n )\n }\n\n async listDeviceAccounts(\n filter: { sub: Sub } | { deviceId: DeviceId },\n ): Promise<DeviceAccount[]> {\n const rows = await accountDeviceHelper.selectQB(this.db, filter).execute()\n\n const uniqueDids: string[] = [...new Set(rows.map((row) => row.did))]\n\n // Enrich all distinct account with their profile data\n const accounts = new Map(\n await Promise.all(\n Array.from(uniqueDids, async (did): Promise<[Sub, Account]> => {\n const row = rows.find((r) => r.did === did)!\n return [did, await this.buildAccount(row)]\n }),\n ),\n )\n\n const authorizedClientsMap =\n await authorizedClientHelper.getAuthorizedClientsMulti(\n this.db,\n uniqueDids,\n )\n\n return rows.map((row) => ({\n deviceId: row.deviceId,\n deviceData: deviceHelper.rowToDeviceData(row),\n account: accounts.get(row.did)!,\n authorizedClients: authorizedClientsMap.get(row.did)!,\n createdAt: fromDateISO(row.adCreatedAt),\n updatedAt: fromDateISO(row.adUpdatedAt),\n }))\n }\n\n async resetPasswordRequest({\n locale: _locale,\n email,\n }: ResetPasswordRequestInput): Promise<Account | null> {\n const account = await this.accountManager.getAccountByEmail(email, {\n includeDeactivated: true,\n includeTakenDown: false,\n })\n\n if (!account?.email || !account?.handle) return null\n\n const { handle } = account\n const token = await this.accountManager.createEmailToken(\n account.did,\n 'reset_password',\n )\n\n // @TODO Use the locale to send the email in the right language\n await this.mailer.sendResetPassword(\n { handle, token },\n { to: account.email },\n )\n\n return this.buildAccount(account)\n }\n\n async resetPasswordConfirm(\n data: ResetPasswordConfirmInput,\n ): Promise<Account | null> {\n try {\n const did = await this.accountManager.resetPassword(data)\n const account = await this.accountManager.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: false,\n })\n\n return account ? this.buildAccount(account) : null\n } catch (err) {\n if (err instanceof XrpcInvalidRequestError) {\n return null\n }\n\n throw err\n }\n }\n\n async verifyHandleAvailability(handle: HandleString): Promise<void> {\n // @NOTE Handle validity & normalization already enforced by the OAuthProvider\n try {\n const normalized =\n await this.accountManager.normalizeAndValidateHandle(handle)\n\n // Should never happen (OAuthProvider should have already validated the\n // handle) This check is just a safeguard against future normalization\n // changes.\n if (normalized !== handle) {\n throw new HandleUnavailableError('syntax', 'Invalid handle')\n }\n\n const account = await this.accountManager.getAccount(normalized, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (account) {\n throw new HandleUnavailableError('taken')\n }\n } catch (err) {\n throw toHandleUnavailableError(err)\n }\n }\n\n // RequestStore\n\n async createRequest(id: RequestId, data: RequestData): Promise<void> {\n await this.db.executeWithRetry(\n authRequestHelper.createQB(this.db, id, data),\n )\n }\n\n async readRequest(id: RequestId): Promise<RequestData | null> {\n try {\n const row = await authRequestHelper.readQB(this.db, id).executeTakeFirst()\n if (!row) return null\n return authRequestHelper.rowToRequestData(row)\n } finally {\n // Take the opportunity to clean up expired requests. Do this after we got\n // the current (potentially expired) request data to allow the provider to\n // handle expired requests.\n this.backgroundQueue.add(async () => {\n await this.db.executeWithRetry(\n authRequestHelper.removeOldExpiredQB(this.db),\n )\n })\n }\n }\n\n async updateRequest(id: RequestId, data: UpdateRequestData): Promise<void> {\n await this.db.executeWithRetry(\n authRequestHelper.updateQB(this.db, id, data),\n )\n }\n\n async deleteRequest(id: RequestId): Promise<void> {\n await this.db.executeWithRetry(authRequestHelper.removeByIdQB(this.db, id))\n }\n\n async consumeRequestCode(code: Code): Promise<FoundRequestResult | null> {\n const row = await authRequestHelper\n .consumeByCodeQB(this.db, code)\n .executeTakeFirst()\n return row ? authRequestHelper.rowToFoundRequestResult(row) : null\n }\n\n // DeviceStore\n\n async createDevice(deviceId: DeviceId, data: DeviceData): Promise<void> {\n await this.db.executeWithRetry(\n deviceHelper.createQB(this.db, deviceId, data),\n )\n }\n\n async readDevice(deviceId: DeviceId): Promise<null | DeviceData> {\n const row = await deviceHelper.readQB(this.db, deviceId).executeTakeFirst()\n return row ? deviceHelper.rowToDeviceData(row) : null\n }\n\n async updateDevice(\n deviceId: DeviceId,\n data: Partial<DeviceData>,\n ): Promise<void> {\n await this.db.executeWithRetry(\n deviceHelper.updateQB(this.db, deviceId, data),\n )\n }\n\n async deleteDevice(deviceId: DeviceId): Promise<void> {\n // Will cascade to device_account (device_account_device_id_fk)\n await this.db.executeWithRetry(deviceHelper.removeQB(this.db, deviceId))\n }\n\n // LexiconStore\n\n async findLexicon(nsid: string): Promise<LexiconData | null> {\n return lexiconHelper.find(this.db, nsid)\n }\n\n async storeLexicon(nsid: string, data: LexiconData): Promise<void> {\n return lexiconHelper.upsert(this.db, nsid, data)\n }\n\n async deleteLexicon(nsid: string): Promise<void> {\n return lexiconHelper.remove(this.db, nsid)\n }\n\n // TokenStore\n\n async createToken(\n id: TokenId,\n data: TokenData,\n refreshToken?: RefreshToken,\n ): Promise<void> {\n await this.db.transaction(async (dbTxn) => {\n if (refreshToken) {\n const { count } = await usedRefreshTokenHelper\n .countQB(dbTxn, refreshToken)\n .executeTakeFirstOrThrow()\n\n if (count > 0) {\n throw new Error('Refresh token already in use')\n }\n }\n\n return tokenHelper.createQB(dbTxn, id, data, refreshToken).execute()\n })\n }\n\n async listAccountTokens(sub: Sub): Promise<TokenInfo[]> {\n const rows = await tokenHelper.findByQB(this.db, { did: sub }).execute()\n return Promise.all(rows.map((row) => this.toTokenInfo(row)))\n }\n\n async readToken(tokenId: TokenId): Promise<TokenInfo | null> {\n const row = await tokenHelper\n .findByQB(this.db, { tokenId })\n .executeTakeFirst()\n return row ? this.toTokenInfo(row) : null\n }\n\n async deleteToken(tokenId: TokenId): Promise<void> {\n // Will cascade to used_refresh_token (used_refresh_token_fk)\n await this.db.executeWithRetry(tokenHelper.removeQB(this.db, tokenId))\n }\n\n async rotateToken(\n tokenId: TokenId,\n newTokenId: TokenId,\n newRefreshToken: RefreshToken,\n newData: NewTokenData,\n ): Promise<void> {\n const err = await this.db.transaction(async (dbTxn) => {\n const { id, currentRefreshToken } = await tokenHelper\n .forRotateQB(dbTxn, tokenId)\n .executeTakeFirstOrThrow()\n\n if (currentRefreshToken) {\n await usedRefreshTokenHelper\n .insertQB(dbTxn, id, currentRefreshToken)\n .execute()\n }\n\n const { count } = await usedRefreshTokenHelper\n .countQB(dbTxn, newRefreshToken)\n .executeTakeFirstOrThrow()\n\n if (count > 0) {\n // Do NOT throw (we don't want the transaction to be rolled back)\n return new Error('New refresh token already in use')\n }\n\n await tokenHelper\n .rotateQB(dbTxn, id, newTokenId, newRefreshToken, newData)\n .execute()\n })\n\n if (err) throw err\n }\n\n async findTokenByRefreshToken(\n refreshToken: RefreshToken,\n ): Promise<TokenInfo | null> {\n const used = await usedRefreshTokenHelper\n .findByTokenQB(this.db, refreshToken)\n .executeTakeFirst()\n\n const search = used\n ? { id: used.tokenId }\n : { currentRefreshToken: refreshToken }\n\n const row = await tokenHelper.findByQB(this.db, search).executeTakeFirst()\n return row ? this.toTokenInfo(row) : null\n }\n\n async findTokenByCode(code: Code): Promise<TokenInfo | null> {\n const row = await tokenHelper.findByQB(this.db, { code }).executeTakeFirst()\n return row ? this.toTokenInfo(row) : null\n }\n\n async verifyEmailRequest({\n sub: did,\n locale,\n }: VerifyEmailRequestInput): Promise<void> {\n // @TODO @atproto/oauth-provider should strongly type `Sub` as `DidString`\n assert(isDidString(did), 'sub must be a valid DID string')\n\n try {\n await this.accountManager.requestEmailConfirmation(did, { locale })\n } catch (err) {\n if (err instanceof XrpcAuthRequiredError) {\n throw new InvalidRequestError(err.message, err)\n }\n\n throw err\n }\n }\n\n async verifyEmailConfirm({\n sub: did,\n email,\n token,\n }: VerifyEmailConfirmInput): Promise<Account | null> {\n // @TODO @atproto/oauth-provider should strongly type `Sub` as `DidString`\n assert(isDidString(did), 'sub must be a valid DID string')\n\n try {\n const account = await this.accountManager.confirmEmail(did, email, token)\n\n return this.buildAccount(account)\n } catch (err) {\n if (err instanceof XrpcInvalidRequestError) {\n return null\n }\n\n throw err\n }\n }\n\n async updateEmailRequest({\n sub: did,\n locale,\n }: UpdateEmailRequestInput): Promise<UpdateEmailRequestOutput> {\n // @TODO @atproto/oauth-provider should strongly type `Sub` as `DidString`\n assert(isDidString(did), 'sub must be a valid DID string')\n\n return this.accountManager.requestEmailUpdate(did, { locale })\n }\n\n async updateEmailConfirm({\n sub: did,\n token,\n email,\n locale,\n }: UpdateEmailConfirmInput): Promise<Account | null> {\n // @TODO @atproto/oauth-provider should strongly type `Sub` as `DidString`\n assert(isDidString(did), 'sub must be a valid DID string')\n\n try {\n const account = await this.accountManager.updateEmail(did, email, token, {\n sendConfirmationEmail: true,\n locale,\n })\n\n return this.buildAccount(account)\n } catch (cause) {\n if (cause instanceof UserAlreadyExistsError) {\n throw new InvalidRequestError(cause.message, cause)\n }\n\n throw cause\n }\n }\n\n async updateHandle({ sub: did, handle }: UpdateHandleData): Promise<Account> {\n // @TODO @atproto/oauth-provider should strongly type `Sub` as `DidString`\n assert(isDidString(did), 'sub must be a valid DID string')\n\n try {\n const account = await this.accountManager.updateHandle(did, handle)\n\n return this.buildAccount(account)\n } catch (err) {\n throw toHandleUnavailableError(err)\n }\n }\n\n private async toTokenInfo(\n row: ActorAccount & Selectable<schemas.Token>,\n ): Promise<TokenInfo> {\n return {\n id: row.tokenId,\n data: tokenHelper.toTokenData(row),\n account: await this.buildAccount(row),\n currentRefreshToken: row.currentRefreshToken,\n }\n }\n\n private async buildAccount(row: ActorAccount): Promise<Account> {\n const account: Account = {\n sub: row.did,\n aud: this.serviceDid,\n email: row.email || undefined,\n email_verified: row.email ? row.emailConfirmedAt != null : undefined,\n preferred_username: row.handle || undefined,\n }\n\n if (!account.name || !account.picture) {\n const did = account.sub\n\n const profile = await this.actorStore\n .read(did, async (store) => {\n return store.record.getProfileRecord()\n })\n .catch((err) => {\n dbLogger.error({ err }, 'Failed to get profile record')\n return null // No need to propagate\n })\n\n if (profile) {\n const { avatar, displayName } = profile\n\n account.name ||= displayName\n account.picture ||= avatar\n ? this.imageUrlBuilder.build('avatar', did, getBlobCidString(avatar))\n : undefined\n }\n }\n\n return account\n }\n}\n\nfunction toHandleUnavailableError(err: unknown): unknown {\n if (err instanceof XrpcInvalidRequestError) {\n const reason = toHandleUnavailableReason(err)\n if (reason) throw new HandleUnavailableError(reason, err.message, err)\n\n return new InvalidRequestError(err.message, err)\n }\n\n return err\n}\n\n/**\n * This function maps specific `XrpcInvalidRequestError`, thrown by the\n * `AccountManager` when validating a handle, to a more specific\n * `HandleUnavailableError` with a reason. This allows the OAuthProvider to\n * provide properly localized and specific error messages to the user when a\n * handle is not available.\n */\nfunction toHandleUnavailableReason(\n err: XrpcInvalidRequestError,\n): HandleUnavailableReason | undefined {\n switch (err.error) {\n case 'HandleNotAvailable': {\n if (err.message === 'Reserved handle') return 'reserved'\n return 'taken'\n }\n\n case 'UnsupportedDomain': {\n return 'unsupported'\n }\n\n case 'InvalidHandle': {\n if (err.message === 'Inappropriate language in handle') return 'slur'\n if (err.message === 'Handle TLD is invalid or disallowed') return 'domain'\n return 'syntax'\n }\n\n case 'InvalidRequest': {\n if (err.message === 'External handle did not resolve to DID') {\n return 'resolution'\n }\n return undefined\n }\n }\n}\n"]}
1
+ {"version":3,"file":"oauth-store.js","sourceRoot":"","sources":["../../src/account-manager/oauth-store.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { Client, createOp as createPlcOp } from '@did-plc/lib'\nimport { Selectable } from 'kysely'\nimport { Keypair, Secp256k1Keypair } from '@atproto/crypto'\nimport { DidString, HandleString, getBlobCidString } from '@atproto/lex'\nimport {\n Account,\n AccountStore,\n AuthenticateAccountData,\n AuthorizedClientData,\n AuthorizedClients,\n ClientId,\n Code,\n DeactivateAccountData,\n DeleteAccountConfirmInput,\n DeleteAccountRequestInput,\n DeviceAccount,\n DeviceData,\n DeviceId,\n DeviceStore,\n Did,\n FoundRequestResult,\n HandleUnavailableError,\n HandleUnavailableReason,\n InvalidCredentialsError,\n InvalidInviteCodeError,\n InvalidRequestError,\n LexiconData,\n LexiconStore,\n NewTokenData,\n ReactivateAccountData,\n RefreshToken,\n RequestData,\n RequestId,\n RequestStore,\n ResetPasswordConfirmInput,\n ResetPasswordRequestInput,\n SignUpData,\n TokenData,\n TokenId,\n TokenInfo,\n TokenStore,\n UpdateEmailConfirmInput,\n UpdateEmailRequestInput,\n UpdateEmailRequestOutput,\n UpdateHandleData,\n UpdateRequestData,\n VerifyEmailConfirmInput,\n VerifyEmailRequestInput,\n} from '@atproto/oauth-provider'\nimport {\n AuthRequiredError as XrpcAuthRequiredError,\n InvalidRequestError as XrpcInvalidRequestError,\n} from '@atproto/xrpc-server'\nimport { ActorStore } from '../actor-store/actor-store.js'\nimport { BackgroundQueue } from '../background.js'\nimport { fromDateISO } from '../db/index.js'\nimport { ImageUrlBuilder } from '../image/image-url-builder.js'\nimport { dbLogger } from '../logger.js'\nimport { ServerMailer } from '../mailer/index.js'\nimport { Sequencer } from '../sequencer/index.js'\nimport { AccountManager, InvalidPasswordError } from './account-manager.js'\nimport * as schemas from './db/schema/index.js'\nimport * as accountDeviceHelper from './helpers/account-device.js'\nimport { ActorAccount, UserAlreadyExistsError } from './helpers/account.js'\nimport * as authRequestHelper from './helpers/authorization-request.js'\nimport * as authorizedClientHelper from './helpers/authorized-client.js'\nimport * as deviceHelper from './helpers/device.js'\nimport * as lexiconHelper from './helpers/lexicon.js'\nimport * as tokenHelper from './helpers/token.js'\nimport * as usedRefreshTokenHelper from './helpers/used-refresh-token.js'\n\n/**\n * This class' purpose is to implement the interface needed by the OAuthProvider\n * to interact with the account database (through the {@link AccountManager}).\n *\n * @note The use of this class assumes that there is no entryway.\n */\nexport class OAuthStore\n implements AccountStore, RequestStore, DeviceStore, LexiconStore, TokenStore\n{\n constructor(\n private readonly accountManager: AccountManager,\n private readonly actorStore: ActorStore,\n private readonly imageUrlBuilder: ImageUrlBuilder,\n private readonly backgroundQueue: BackgroundQueue,\n private readonly mailer: ServerMailer,\n private readonly sequencer: Sequencer,\n private readonly plcClient: Client,\n private readonly plcRotationKey: Keypair,\n private readonly publicUrl: string,\n private readonly recoveryDidKey: string | null,\n ) {}\n\n private get db() {\n const { db } = this.accountManager\n if (db.destroyed) throw new Error('Database connection is closed')\n return db\n }\n\n private get serviceDid() {\n return this.accountManager.serviceDid\n }\n\n private async verifyEmailAvailability(email: string): Promise<void> {\n // @NOTE Email validity & disposability check performed by the OAuthProvider\n\n const account = await this.accountManager.getAccountByEmail(email, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (account) {\n throw new InvalidRequestError(`Email already taken`)\n }\n }\n\n private async verifyInviteCode(code: string) {\n try {\n await this.accountManager.ensureInviteIsAvailable(code)\n } catch (err) {\n const message =\n err instanceof XrpcInvalidRequestError ? err.message : undefined\n throw new InvalidInviteCodeError(message, err)\n }\n }\n\n // AccountStore\n\n async createAccount({\n locale: _locale,\n inviteCode,\n handle,\n email,\n password,\n }: SignUpData): Promise<Account> {\n // @TODO Send an account creation confirmation email (+verification link) to the user (in their locale)\n // @NOTE Password strength & length already enforced by the OAuthProvider\n\n await Promise.all([\n this.verifyEmailAvailability(email),\n this.verifyHandleAvailability(handle),\n !inviteCode || this.verifyInviteCode(inviteCode),\n ])\n\n // @TODO The code bellow should probably be refactored to be common with the\n // code of the `com.atproto.server.createAccount` XRPC endpoint.\n\n const signingKey = await Secp256k1Keypair.create({ exportable: true })\n const signingKeyDid = signingKey.did()\n\n const canTombstone =\n // @NOTE IMPORTANT We don't support \"bring your own DID\" here (yet?). If\n // we ever do, make sure to update the computation of canTombstone so that\n // the user's did don't get tombstoned.\n true\n\n const plc = await createPlcOp({\n signingKey: signingKeyDid,\n rotationKeys: this.recoveryDidKey\n ? [this.recoveryDidKey, this.plcRotationKey.did()]\n : [this.plcRotationKey.did()],\n handle,\n pds: this.publicUrl,\n signer: this.plcRotationKey,\n })\n\n const did = plc.did as DidString\n\n try {\n await this.actorStore.create(did, signingKey)\n\n try {\n const commit = await this.actorStore.transact(did, (actorTxn) => {\n return actorTxn.repo.createRepo([])\n })\n\n await this.plcClient.sendOperation(did, plc.op)\n\n try {\n await this.accountManager.createAccount({\n did,\n handle,\n email,\n password,\n inviteCode,\n repoCid: commit.cid,\n repoRev: commit.rev,\n })\n\n try {\n await this.sequencer.sequenceAccountCreation(did, handle, commit)\n\n try {\n await this.actorStore\n .clearReservedKeypair(signingKeyDid, did)\n .catch((err) => {\n // @NOTE This is a cleanup operation so we won't fail the\n // whole flow if it fails, but we log it just in case\n dbLogger.error(\n { did, signingKeyDid, err },\n 'Failed to clear reserved keypair',\n )\n })\n\n const account = await this.accountManager.getAccount(did)\n assert(account, 'Account not found after creation')\n\n return await this.buildAccount(account)\n } catch (err) {\n await this.sequencer.sequenceAccountDeletion(did)\n throw err\n }\n } catch (err) {\n await this.accountManager.deleteAccount(did)\n throw err\n }\n } catch (err) {\n if (canTombstone) {\n await this.plcClient.tombstone(did, this.plcRotationKey)\n }\n throw err\n }\n } catch (err) {\n await this.actorStore.destroy(did)\n throw err\n }\n } catch (err) {\n // XrpcError => OAuthError\n if (err instanceof XrpcInvalidRequestError) {\n throw new InvalidRequestError(err.message, err)\n }\n throw err\n }\n }\n\n async authenticateAccount({\n locale: _locale,\n username: identifier,\n password,\n // Not supported by the PDS (yet?)\n emailOtp = undefined,\n }: AuthenticateAccountData): Promise<Account> {\n // @TODO (?) Send an email to the user to notify them of the login attempt\n try {\n // Should never happen\n if (emailOtp != null) {\n throw new Error('Email OTP is not supported')\n }\n\n const { user, appPassword, isSoftDeleted } =\n await this.accountManager.login({ identifier, password })\n\n if (isSoftDeleted) {\n throw new InvalidRequestError('Account was taken down')\n }\n\n if (appPassword) {\n throw new InvalidRequestError('App passwords are not allowed')\n }\n\n return this.buildAccount(user)\n } catch (err) {\n // `InvalidPasswordError` is a subclass of `XrpcAuthRequiredError`,\n // so it must be checked first. Surfacing the matched `did` as the\n // `sub` lets the oauth-provider's `onSignInFailed` hook distinguish\n // \"identifier known, credentials wrong\" from \"identifier unknown\".\n if (err instanceof InvalidPasswordError) {\n throw new InvalidCredentialsError(err.message, err.did, err)\n }\n if (err instanceof XrpcAuthRequiredError) {\n throw new InvalidCredentialsError(err.message, undefined, err)\n }\n throw err\n }\n }\n\n async setAuthorizedClient(\n did: Did,\n clientId: ClientId,\n data: AuthorizedClientData,\n ): Promise<void> {\n await authorizedClientHelper.upsert(this.db, did, clientId, data)\n }\n\n async getAccount(did: Did): Promise<{\n account: Account\n authorizedClients: AuthorizedClients\n }> {\n const accountRow = await this.accountManager.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: false,\n })\n\n assert(accountRow, 'Account not found')\n\n const account = await this.buildAccount(accountRow)\n const authorizedClients = await authorizedClientHelper.getAuthorizedClients(\n this.db,\n did,\n )\n\n return { account, authorizedClients }\n }\n\n async upsertDeviceAccount(deviceId: DeviceId, sub: string): Promise<void> {\n await this.db.executeWithRetry(\n accountDeviceHelper.upsertQB(this.db, deviceId, sub),\n )\n }\n\n async getDeviceAccount(\n deviceId: DeviceId,\n did: Did,\n ): Promise<DeviceAccount | null> {\n const row = await accountDeviceHelper\n .selectQB(this.db, { deviceId, did })\n .executeTakeFirst()\n\n if (!row) return null\n\n return {\n deviceId,\n deviceData: deviceHelper.rowToDeviceData(row),\n account: await this.buildAccount(row),\n authorizedClients: await authorizedClientHelper.getAuthorizedClients(\n this.db,\n did,\n ),\n createdAt: fromDateISO(row.adCreatedAt),\n updatedAt: fromDateISO(row.adUpdatedAt),\n }\n }\n\n async removeDeviceAccount(deviceId: DeviceId, did: Did): Promise<void> {\n await this.db.executeWithRetry(\n accountDeviceHelper.removeQB(this.db, deviceId, did),\n )\n }\n\n async listDeviceAccounts(\n filter: { did: Did } | { deviceId: DeviceId },\n ): Promise<DeviceAccount[]> {\n const rows = await accountDeviceHelper.selectQB(this.db, filter).execute()\n\n const uniqueDids = [...new Set(rows.map((row) => row.did))]\n\n // Enrich all distinct account with their profile data\n const accounts = new Map(\n await Promise.all(\n Array.from(uniqueDids, async (did): Promise<[Did, Account]> => {\n const row = rows.find((r) => r.did === did)!\n return [did, await this.buildAccount(row)]\n }),\n ),\n )\n\n const authorizedClientsMap =\n await authorizedClientHelper.getAuthorizedClientsMulti(\n this.db,\n uniqueDids,\n )\n\n return rows.map((row) => ({\n deviceId: row.deviceId,\n deviceData: deviceHelper.rowToDeviceData(row),\n account: accounts.get(row.did)!,\n authorizedClients: authorizedClientsMap.get(row.did)!,\n createdAt: fromDateISO(row.adCreatedAt),\n updatedAt: fromDateISO(row.adUpdatedAt),\n }))\n }\n\n async resetPasswordRequest({\n email,\n locale,\n }: ResetPasswordRequestInput): Promise<Account | null> {\n const account = await this.accountManager.getAccountByEmail(email, {\n includeDeactivated: true,\n includeTakenDown: false,\n })\n\n if (!account?.email || !account?.handle) return null\n\n const { handle } = account\n const token = await this.accountManager.createEmailToken(\n account.did,\n 'reset_password',\n )\n\n await this.mailer.sendResetPassword(\n { handle, token, locale },\n { to: account.email },\n )\n\n return this.buildAccount(account)\n }\n\n async resetPasswordConfirm(\n data: ResetPasswordConfirmInput,\n ): Promise<Account | null> {\n try {\n const did = await this.accountManager.resetPassword(data)\n const account = await this.accountManager.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: false,\n })\n\n return account ? this.buildAccount(account) : null\n } catch (err) {\n if (err instanceof XrpcInvalidRequestError) {\n return null\n }\n\n throw err\n }\n }\n\n async verifyHandleAvailability(handle: HandleString): Promise<void> {\n // @NOTE Handle validity & normalization already enforced by the OAuthProvider\n try {\n const normalized =\n await this.accountManager.normalizeAndValidateHandle(handle)\n\n // Should never happen (OAuthProvider should have already validated the\n // handle) This check is just a safeguard against future normalization\n // changes.\n if (normalized !== handle) {\n throw new HandleUnavailableError('syntax', 'Invalid handle')\n }\n\n const account = await this.accountManager.getAccount(normalized, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n\n if (account) {\n throw new HandleUnavailableError('taken')\n }\n } catch (err) {\n throw toHandleUnavailableError(err)\n }\n }\n\n // RequestStore\n\n async createRequest(id: RequestId, data: RequestData): Promise<void> {\n await this.db.executeWithRetry(\n authRequestHelper.createQB(this.db, id, data),\n )\n }\n\n async readRequest(id: RequestId): Promise<RequestData | null> {\n try {\n const row = await authRequestHelper.readQB(this.db, id).executeTakeFirst()\n if (!row) return null\n return authRequestHelper.rowToRequestData(row)\n } finally {\n // Take the opportunity to clean up expired requests. Do this after we got\n // the current (potentially expired) request data to allow the provider to\n // handle expired requests.\n this.backgroundQueue.add(async () => {\n await this.db.executeWithRetry(\n authRequestHelper.removeOldExpiredQB(this.db),\n )\n })\n }\n }\n\n async updateRequest(id: RequestId, data: UpdateRequestData): Promise<void> {\n await this.db.executeWithRetry(\n authRequestHelper.updateQB(this.db, id, data),\n )\n }\n\n async deleteRequest(id: RequestId): Promise<void> {\n await this.db.executeWithRetry(authRequestHelper.removeByIdQB(this.db, id))\n }\n\n async consumeRequestCode(code: Code): Promise<FoundRequestResult | null> {\n const row = await authRequestHelper\n .consumeByCodeQB(this.db, code)\n .executeTakeFirst()\n return row ? authRequestHelper.rowToFoundRequestResult(row) : null\n }\n\n // DeviceStore\n\n async createDevice(deviceId: DeviceId, data: DeviceData): Promise<void> {\n await this.db.executeWithRetry(\n deviceHelper.createQB(this.db, deviceId, data),\n )\n }\n\n async readDevice(deviceId: DeviceId): Promise<null | DeviceData> {\n const row = await deviceHelper.readQB(this.db, deviceId).executeTakeFirst()\n return row ? deviceHelper.rowToDeviceData(row) : null\n }\n\n async updateDevice(\n deviceId: DeviceId,\n data: Partial<DeviceData>,\n ): Promise<void> {\n await this.db.executeWithRetry(\n deviceHelper.updateQB(this.db, deviceId, data),\n )\n }\n\n async deleteDevice(deviceId: DeviceId): Promise<void> {\n // Will cascade to device_account (device_account_device_id_fk)\n await this.db.executeWithRetry(deviceHelper.removeQB(this.db, deviceId))\n }\n\n // LexiconStore\n\n async findLexicon(nsid: string): Promise<LexiconData | null> {\n return lexiconHelper.find(this.db, nsid)\n }\n\n async storeLexicon(nsid: string, data: LexiconData): Promise<void> {\n return lexiconHelper.upsert(this.db, nsid, data)\n }\n\n async deleteLexicon(nsid: string): Promise<void> {\n return lexiconHelper.remove(this.db, nsid)\n }\n\n // TokenStore\n\n async createToken(\n id: TokenId,\n data: TokenData,\n refreshToken?: RefreshToken,\n ): Promise<void> {\n await this.db.transaction(async (dbTxn) => {\n if (refreshToken) {\n const { count } = await usedRefreshTokenHelper\n .countQB(dbTxn, refreshToken)\n .executeTakeFirstOrThrow()\n\n if (count > 0) {\n throw new Error('Refresh token already in use')\n }\n }\n\n return tokenHelper.createQB(dbTxn, id, data, refreshToken).execute()\n })\n }\n\n async listAccountTokens(did: Did): Promise<TokenInfo[]> {\n const rows = await tokenHelper.findByQB(this.db, { did }).execute()\n return Promise.all(rows.map((row) => this.toTokenInfo(row)))\n }\n\n async readToken(tokenId: TokenId): Promise<TokenInfo | null> {\n const row = await tokenHelper\n .findByQB(this.db, { tokenId })\n .executeTakeFirst()\n return row ? this.toTokenInfo(row) : null\n }\n\n async deleteToken(tokenId: TokenId): Promise<void> {\n // Will cascade to used_refresh_token (used_refresh_token_fk)\n await this.db.executeWithRetry(tokenHelper.removeQB(this.db, tokenId))\n }\n\n async rotateToken(\n tokenId: TokenId,\n newTokenId: TokenId,\n newRefreshToken: RefreshToken,\n newData: NewTokenData,\n ): Promise<void> {\n const err = await this.db.transaction(async (dbTxn) => {\n const { id, currentRefreshToken } = await tokenHelper\n .forRotateQB(dbTxn, tokenId)\n .executeTakeFirstOrThrow()\n\n if (currentRefreshToken) {\n await usedRefreshTokenHelper\n .insertQB(dbTxn, id, currentRefreshToken)\n .execute()\n }\n\n const { count } = await usedRefreshTokenHelper\n .countQB(dbTxn, newRefreshToken)\n .executeTakeFirstOrThrow()\n\n if (count > 0) {\n // Do NOT throw (we don't want the transaction to be rolled back)\n return new Error('New refresh token already in use')\n }\n\n await tokenHelper\n .rotateQB(dbTxn, id, newTokenId, newRefreshToken, newData)\n .execute()\n })\n\n if (err) throw err\n }\n\n async findTokenByRefreshToken(\n refreshToken: RefreshToken,\n ): Promise<TokenInfo | null> {\n const used = await usedRefreshTokenHelper\n .findByTokenQB(this.db, refreshToken)\n .executeTakeFirst()\n\n const search = used\n ? { id: used.tokenId }\n : { currentRefreshToken: refreshToken }\n\n const row = await tokenHelper.findByQB(this.db, search).executeTakeFirst()\n return row ? this.toTokenInfo(row) : null\n }\n\n async findTokenByCode(code: Code): Promise<TokenInfo | null> {\n const row = await tokenHelper.findByQB(this.db, { code }).executeTakeFirst()\n return row ? this.toTokenInfo(row) : null\n }\n\n async verifyEmailRequest({\n did,\n locale,\n }: VerifyEmailRequestInput): Promise<void> {\n try {\n await this.accountManager.requestEmailConfirmation(did, { locale })\n } catch (err) {\n if (err instanceof XrpcAuthRequiredError) {\n throw new InvalidRequestError(err.message, err)\n }\n\n throw err\n }\n }\n\n async verifyEmailConfirm({\n did,\n email,\n token,\n }: VerifyEmailConfirmInput): Promise<Account | null> {\n try {\n const account = await this.accountManager.confirmEmail(did, email, token)\n\n return this.buildAccount(account)\n } catch (err) {\n if (err instanceof XrpcInvalidRequestError) {\n return null\n }\n\n throw err\n }\n }\n\n async updateEmailRequest({\n did,\n locale,\n }: UpdateEmailRequestInput): Promise<UpdateEmailRequestOutput> {\n return this.accountManager.requestEmailUpdate(did, { locale })\n }\n\n async updateEmailConfirm({\n did,\n token,\n email,\n locale,\n }: UpdateEmailConfirmInput): Promise<Account | null> {\n try {\n const account = await this.accountManager.updateEmail(did, email, token, {\n sendConfirmationEmail: true,\n locale,\n })\n\n return this.buildAccount(account)\n } catch (cause) {\n if (cause instanceof UserAlreadyExistsError) {\n throw new InvalidRequestError(cause.message, cause)\n }\n\n throw cause\n }\n }\n\n async updateHandle({ did, handle }: UpdateHandleData): Promise<Account> {\n try {\n const account = await this.accountManager.updateHandle(did, handle)\n\n return this.buildAccount(account)\n } catch (err) {\n throw toHandleUnavailableError(err)\n }\n }\n\n async deactivateAccount({ did }: DeactivateAccountData): Promise<Account> {\n const { account } = await this.accountManager.deactivateAccount(did, {\n deleteCredentials: true,\n })\n\n return this.buildAccount(account)\n }\n\n async reactivateAccount({ did }: ReactivateAccountData): Promise<Account> {\n try {\n const { account } = await this.accountManager.activateAccount(did)\n\n return this.buildAccount(account)\n } catch (err) {\n if (err instanceof XrpcInvalidRequestError) {\n throw new InvalidRequestError(err.message, err)\n }\n\n throw err\n }\n }\n\n async deleteAccountRequest({\n did,\n locale,\n }: DeleteAccountRequestInput): Promise<void> {\n // Mirror the XRPC `com.atproto.server.requestAccountDelete` flow\n // (no-entryway path): generate an email confirmation token and dispatch\n // it to the account's email address.\n const account = await this.accountManager.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n if (!account) {\n throw new InvalidRequestError('Account not found')\n }\n if (!account.email) {\n throw new InvalidRequestError('Account does not have an email address')\n }\n\n const token = await this.accountManager.createEmailToken(\n did,\n 'delete_account',\n )\n await this.mailer.sendAccountDelete(\n { token, locale },\n { to: account.email },\n )\n }\n\n async deleteAccountConfirm({\n did,\n token,\n password,\n }: DeleteAccountConfirmInput): Promise<void> {\n // Mirror the XRPC `com.atproto.server.deleteAccount` flow (no-entryway\n // path): verify the password, validate the email confirmation token,\n // destroy the actor store, delete the account row, and emit the\n // tombstone account event.\n const account = await this.accountManager.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n if (!account) {\n throw new InvalidRequestError('Account not found')\n }\n\n const validPass = await this.accountManager.verifyAccountPassword(\n did,\n password,\n )\n if (!validPass) {\n throw new InvalidCredentialsError('Invalid did or password', did)\n }\n\n await this.accountManager.assertValidEmailToken(\n did,\n 'delete_account',\n token,\n )\n\n // @NOTE Order matters here: first \"unlink\" the account by removing it\n // from the account manager database (\"source of truth\"), then notify the\n // sequencer, and finally cleanup files from the file system.\n await this.accountManager.deleteAccount(did)\n try {\n await this.sequencer.sequenceAccountDeletion(did)\n } finally {\n await this.actorStore.destroy(did)\n }\n }\n\n private async toTokenInfo(\n row: ActorAccount & Selectable<schemas.Token>,\n ): Promise<TokenInfo> {\n return {\n id: row.tokenId,\n data: tokenHelper.toTokenData(row),\n account: await this.buildAccount(row),\n currentRefreshToken: row.currentRefreshToken,\n }\n }\n\n private async buildAccount(row: ActorAccount): Promise<Account> {\n const account: Account = {\n did: row.did,\n pds: this.serviceDid,\n email: row.email || undefined,\n emailVerified: row.email ? row.emailConfirmedAt != null : undefined,\n handle: row.handle || undefined,\n deactivated: row.deactivatedAt != null,\n }\n\n if (!account.name || !account.picture) {\n const { did } = account\n\n const profile = await this.actorStore\n .read(did, async (store) => {\n return store.record.getProfileRecord()\n })\n .catch((err) => {\n dbLogger.error({ err }, 'Failed to get profile record')\n return null // No need to propagate\n })\n\n if (profile) {\n const { avatar, displayName } = profile\n\n account.name ||= displayName\n account.picture ||= avatar\n ? this.imageUrlBuilder.build('avatar', did, getBlobCidString(avatar))\n : undefined\n }\n }\n\n return account\n }\n}\n\nfunction toHandleUnavailableError(err: unknown): unknown {\n if (err instanceof XrpcInvalidRequestError) {\n const reason = toHandleUnavailableReason(err)\n if (reason) throw new HandleUnavailableError(reason, err.message, err)\n\n return new InvalidRequestError(err.message, err)\n }\n\n return err\n}\n\n/**\n * This function maps specific `XrpcInvalidRequestError`, thrown by the\n * `AccountManager` when validating a handle, to a more specific\n * `HandleUnavailableError` with a reason. This allows the OAuthProvider to\n * provide properly localized and specific error messages to the user when a\n * handle is not available.\n */\nfunction toHandleUnavailableReason(\n err: XrpcInvalidRequestError,\n): HandleUnavailableReason | undefined {\n switch (err.error) {\n case 'HandleNotAvailable': {\n if (err.message === 'Reserved handle') return 'reserved'\n return 'taken'\n }\n\n case 'UnsupportedDomain': {\n return 'unsupported'\n }\n\n case 'InvalidHandle': {\n if (err.message === 'Inappropriate language in handle') return 'slur'\n if (err.message === 'Handle TLD is invalid or disallowed') return 'domain'\n return 'syntax'\n }\n\n case 'InvalidRequest': {\n if (err.message === 'External handle did not resolve to DID') {\n return 'resolution'\n }\n return undefined\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../../src/actor-store/blob/reader.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,GAAG,EAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAqB,SAAS,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,qBAAa,UAAU;IAEZ,EAAE,EAAE,OAAO;IACX,SAAS,EAAE,SAAS;IAF7B,YACS,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,SAAS,EACzB;IAEE,eAAe,CACnB,GAAG,EAAE,GAAG,GACP,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAA;KAAE,CAAC,CAe7D;IAEK,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;QAC/B,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAA;QAChC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAA;KACxB,CAAC,CAUD;IAEK,SAAS,CAAC,IAAI,EAAE;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;KACd,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBpB;IAEK,qBAAqB,CACzB,GAAG,EAAE,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAUnD;IAEK,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlD;IAEK,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ5D;IAEK,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAMjC;IAEK,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAOvC;IAEK,gBAAgB,CAAC,IAAI,EAAE;QAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;KACd,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC,CAsBrD;IAEK,WAAW,0CAGhB;CACF"}
1
+ {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../../src/actor-store/blob/reader.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,GAAG,EAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAqB,SAAS,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,qBAAa,UAAU;IAEZ,EAAE,EAAE,OAAO;IACX,SAAS,EAAE,SAAS;IAF7B,YACS,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,SAAS,EACzB;IAEE,eAAe,CACnB,GAAG,EAAE,GAAG,GACP,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAA;KAAE,CAAC,CAe7D;IAEK,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;QAC/B,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAA;QAChC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAA;KACxB,CAAC,CAUD;IAEK,SAAS,CAAC,IAAI,EAAE;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;KACd,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBpB;IAEK,qBAAqB,CACzB,GAAG,EAAE,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAUnD;IAEK,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlD;IAEK,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ5D;IAEK,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAMjC;IAEK,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAOvC;IAEK,gBAAgB,CAAC,IAAI,EAAE;QAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;KACd,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC,CAyBrD;IAEK,WAAW,0CAGhB;CACF"}
@@ -101,10 +101,9 @@ export class BlobReader {
101
101
  const { cursor, limit } = opts;
102
102
  let builder = this.db.db
103
103
  .selectFrom('record_blob')
104
- .whereNotExists((qb) => qb
105
- .selectFrom('blob')
104
+ .where(({ not, exists, selectFrom }) => not(exists(selectFrom('blob')
106
105
  .selectAll()
107
- .whereRef('blob.cid', '=', 'record_blob.blobCid'))
106
+ .whereRef('blob.cid', '=', 'record_blob.blobCid'))))
108
107
  .selectAll()
109
108
  .orderBy('blobCid', 'asc')
110
109
  .groupBy('blobCid')
@@ -1 +1 @@
1
- {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/actor-store/blob/reader.ts"],"names":[],"mappings":"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","sourcesContent":["import stream from 'node:stream'\nimport { Cid, parseCid } from '@atproto/lex-data'\nimport { BlobNotFoundError, BlobStore } from '@atproto/repo'\nimport { AtUriString } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { countAll, countDistinct, notSoftDeletedClause } from '../../db/util.js'\nimport { com } from '../../lexicons/index.js'\nimport { ActorDb } from '../db/index.js'\n\nexport class BlobReader {\n constructor(\n public db: ActorDb,\n public blobstore: BlobStore,\n ) {}\n\n async getBlobMetadata(\n cid: Cid,\n ): Promise<{ size: number; mimeType?: `${string}/${string}` }> {\n const { ref } = this.db.db.dynamic\n const found = await this.db.db\n .selectFrom('blob')\n .selectAll()\n .where('blob.cid', '=', cid.toString())\n .where(notSoftDeletedClause(ref('blob')))\n .executeTakeFirst()\n if (!found) {\n throw new InvalidRequestError('Blob not found')\n }\n return {\n size: found.size,\n mimeType: found.mimeType as `${string}/${string}` | undefined,\n }\n }\n\n async getBlob(cid: Cid): Promise<{\n size: number\n mimeType?: `${string}/${string}`\n stream: stream.Readable\n }> {\n const metadata = await this.getBlobMetadata(cid)\n const stream = await this.blobstore.getStream(cid).catch((err) => {\n if (err instanceof BlobNotFoundError) {\n throw new InvalidRequestError('Blob not found')\n }\n throw err\n })\n\n return { ...metadata, stream }\n }\n\n async listBlobs(opts: {\n since?: string\n cursor?: string\n limit: number\n }): Promise<string[]> {\n const { since, cursor, limit } = opts\n let builder = this.db.db\n .selectFrom('record_blob')\n .select('blobCid')\n .orderBy('blobCid', 'asc')\n .groupBy('blobCid')\n .limit(limit)\n if (since) {\n builder = builder\n .innerJoin('record', 'record.uri', 'record_blob.recordUri')\n .where('record.repoRev', '>', since)\n }\n if (cursor) {\n builder = builder.where('blobCid', '>', cursor)\n }\n const res = await builder.execute()\n return res.map((row) => row.blobCid)\n }\n\n async getBlobTakedownStatus(\n cid: Cid,\n ): Promise<com.atproto.admin.defs.StatusAttr | null> {\n const res = await this.db.db\n .selectFrom('blob')\n .select('takedownRef')\n .where('cid', '=', cid.toString())\n .executeTakeFirst()\n if (!res) return null\n return res.takedownRef\n ? { applied: true, ref: res.takedownRef }\n : { applied: false }\n }\n\n async hasRecordsForBlob(cid: Cid): Promise<boolean> {\n const res = await this.db.db\n .selectFrom('record_blob')\n .where('blobCid', '=', cid.toString())\n .select('blobCid')\n .limit(1)\n .executeTakeFirst()\n return res != null\n }\n\n async getBlobsForRecord(recordUri: string): Promise<string[]> {\n const res = await this.db.db\n .selectFrom('blob')\n .innerJoin('record_blob', 'record_blob.blobCid', 'blob.cid')\n .where('recordUri', '=', recordUri)\n .select('blob.cid')\n .execute()\n return res.map((row) => row.cid)\n }\n\n async blobCount(): Promise<number> {\n const res = await this.db.db\n .selectFrom('blob')\n .select(countAll.as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async recordBlobCount(): Promise<number> {\n const { ref } = this.db.db.dynamic\n const res = await this.db.db\n .selectFrom('record_blob')\n .select(countDistinct(ref('blobCid')).as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async listMissingBlobs(opts: {\n cursor?: string\n limit: number\n }): Promise<{ cid: string; recordUri: AtUriString }[]> {\n const { cursor, limit } = opts\n let builder = this.db.db\n .selectFrom('record_blob')\n .whereNotExists((qb) =>\n qb\n .selectFrom('blob')\n .selectAll()\n .whereRef('blob.cid', '=', 'record_blob.blobCid'),\n )\n .selectAll()\n .orderBy('blobCid', 'asc')\n .groupBy('blobCid')\n .limit(limit)\n if (cursor) {\n builder = builder.where('blobCid', '>', cursor)\n }\n const res = await builder.execute()\n return res.map((row) => ({\n cid: row.blobCid,\n recordUri: row.recordUri as AtUriString,\n }))\n }\n\n async getBlobCids() {\n const blobRows = await this.db.db.selectFrom('blob').select('cid').execute()\n return blobRows.map((row) => parseCid(row.cid))\n }\n}\n"]}
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/actor-store/blob/reader.ts"],"names":[],"mappings":"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","sourcesContent":["import stream from 'node:stream'\nimport { Cid, parseCid } from '@atproto/lex-data'\nimport { BlobNotFoundError, BlobStore } from '@atproto/repo'\nimport { AtUriString } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { countAll, countDistinct, notSoftDeletedClause } from '../../db/util.js'\nimport { com } from '../../lexicons/index.js'\nimport { ActorDb } from '../db/index.js'\n\nexport class BlobReader {\n constructor(\n public db: ActorDb,\n public blobstore: BlobStore,\n ) {}\n\n async getBlobMetadata(\n cid: Cid,\n ): Promise<{ size: number; mimeType?: `${string}/${string}` }> {\n const { ref } = this.db.db.dynamic\n const found = await this.db.db\n .selectFrom('blob')\n .selectAll()\n .where('blob.cid', '=', cid.toString())\n .where(notSoftDeletedClause(ref('blob')))\n .executeTakeFirst()\n if (!found) {\n throw new InvalidRequestError('Blob not found')\n }\n return {\n size: found.size,\n mimeType: found.mimeType as `${string}/${string}` | undefined,\n }\n }\n\n async getBlob(cid: Cid): Promise<{\n size: number\n mimeType?: `${string}/${string}`\n stream: stream.Readable\n }> {\n const metadata = await this.getBlobMetadata(cid)\n const stream = await this.blobstore.getStream(cid).catch((err) => {\n if (err instanceof BlobNotFoundError) {\n throw new InvalidRequestError('Blob not found')\n }\n throw err\n })\n\n return { ...metadata, stream }\n }\n\n async listBlobs(opts: {\n since?: string\n cursor?: string\n limit: number\n }): Promise<string[]> {\n const { since, cursor, limit } = opts\n let builder = this.db.db\n .selectFrom('record_blob')\n .select('blobCid')\n .orderBy('blobCid', 'asc')\n .groupBy('blobCid')\n .limit(limit)\n if (since) {\n builder = builder\n .innerJoin('record', 'record.uri', 'record_blob.recordUri')\n .where('record.repoRev', '>', since)\n }\n if (cursor) {\n builder = builder.where('blobCid', '>', cursor)\n }\n const res = await builder.execute()\n return res.map((row) => row.blobCid)\n }\n\n async getBlobTakedownStatus(\n cid: Cid,\n ): Promise<com.atproto.admin.defs.StatusAttr | null> {\n const res = await this.db.db\n .selectFrom('blob')\n .select('takedownRef')\n .where('cid', '=', cid.toString())\n .executeTakeFirst()\n if (!res) return null\n return res.takedownRef\n ? { applied: true, ref: res.takedownRef }\n : { applied: false }\n }\n\n async hasRecordsForBlob(cid: Cid): Promise<boolean> {\n const res = await this.db.db\n .selectFrom('record_blob')\n .where('blobCid', '=', cid.toString())\n .select('blobCid')\n .limit(1)\n .executeTakeFirst()\n return res != null\n }\n\n async getBlobsForRecord(recordUri: string): Promise<string[]> {\n const res = await this.db.db\n .selectFrom('blob')\n .innerJoin('record_blob', 'record_blob.blobCid', 'blob.cid')\n .where('recordUri', '=', recordUri)\n .select('blob.cid')\n .execute()\n return res.map((row) => row.cid)\n }\n\n async blobCount(): Promise<number> {\n const res = await this.db.db\n .selectFrom('blob')\n .select(countAll.as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async recordBlobCount(): Promise<number> {\n const { ref } = this.db.db.dynamic\n const res = await this.db.db\n .selectFrom('record_blob')\n .select(countDistinct(ref('blobCid')).as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async listMissingBlobs(opts: {\n cursor?: string\n limit: number\n }): Promise<{ cid: string; recordUri: AtUriString }[]> {\n const { cursor, limit } = opts\n let builder = this.db.db\n .selectFrom('record_blob')\n .where(({ not, exists, selectFrom }) =>\n not(\n exists(\n selectFrom('blob')\n .selectAll()\n .whereRef('blob.cid', '=', 'record_blob.blobCid'),\n ),\n ),\n )\n .selectAll()\n .orderBy('blobCid', 'asc')\n .groupBy('blobCid')\n .limit(limit)\n if (cursor) {\n builder = builder.where('blobCid', '>', cursor)\n }\n const res = await builder.execute()\n return res.map((row) => ({\n cid: row.blobCid,\n recordUri: row.recordUri as AtUriString,\n }))\n }\n\n async getBlobCids() {\n const blobRows = await this.db.db.selectFrom('blob').select('cid').execute()\n return blobRows.map((row) => parseCid(row.cid))\n }\n}\n"]}
@@ -52,7 +52,7 @@ export class RecordReader {
52
52
  .selectFrom('record')
53
53
  .innerJoin('repo_block', 'repo_block.cid', 'record.cid')
54
54
  .where('record.collection', '=', collection)
55
- .if(!includeSoftDeleted, (qb) => qb.where(notSoftDeletedClause(ref('record'))))
55
+ .$if(!includeSoftDeleted, (qb) => qb.where(notSoftDeletedClause(ref('record'))))
56
56
  .orderBy('record.rkey', reverse ? 'asc' : 'desc')
57
57
  .limit(limit)
58
58
  .selectAll();
@@ -87,7 +87,7 @@ export class RecordReader {
87
87
  .innerJoin('repo_block', 'repo_block.cid', 'record.cid')
88
88
  .where('record.uri', '=', uri.toString())
89
89
  .selectAll()
90
- .if(!includeSoftDeleted, (qb) => qb.where(notSoftDeletedClause(ref('record'))));
90
+ .$if(!includeSoftDeleted, (qb) => qb.where(notSoftDeletedClause(ref('record'))));
91
91
  if (cid) {
92
92
  builder = builder.where('record.cid', '=', cid);
93
93
  }
@@ -108,7 +108,7 @@ export class RecordReader {
108
108
  .selectFrom('record')
109
109
  .select('uri')
110
110
  .where('record.uri', '=', uri.toString())
111
- .if(!includeSoftDeleted, (qb) => qb.where(notSoftDeletedClause(ref('record'))));
111
+ .$if(!includeSoftDeleted, (qb) => qb.where(notSoftDeletedClause(ref('record'))));
112
112
  if (cid) {
113
113
  builder = builder.where('record.cid', '=', cid);
114
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/actor-store/record/reader.ts"],"names":[],"mappings":"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","sourcesContent":["import { Cid, LexMap, parseCid } from '@atproto/lex-data'\nimport { CidSet, cborToLexRecord, formatDataKey } from '@atproto/repo'\nimport {\n AtUri,\n AtUriString,\n DatetimeString,\n NsidString,\n ensureValidAtUri,\n ensureValidDid,\n} from '@atproto/syntax'\nimport { countAll, notSoftDeletedClause } from '../../db/util.js'\nimport { app, com } from '../../lexicons/index.js'\nimport { LocalRecords } from '../../read-after-write/types.js'\nimport { ActorDb, Backlink } from '../db/index.js'\n\nexport type RecordDescript = {\n uri: string\n path: string\n cid: Cid\n}\n\nexport class RecordReader {\n constructor(public db: ActorDb) {}\n\n async recordCount(): Promise<number> {\n const res = await this.db.db\n .selectFrom('record')\n .select(countAll.as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async listAll(): Promise<RecordDescript[]> {\n const records: RecordDescript[] = []\n let cursor: string | undefined = ''\n while (cursor !== undefined) {\n const res = await this.db.db\n .selectFrom('record')\n .select(['uri', 'cid'])\n .where('uri', '>', cursor)\n .orderBy('uri', 'asc')\n .limit(1000)\n .execute()\n for (const row of res) {\n const parsed = new AtUri(row.uri)\n records.push({\n uri: row.uri,\n path: formatDataKey(parsed.collection, parsed.rkey),\n cid: parseCid(row.cid),\n })\n }\n cursor = res.at(-1)?.uri\n }\n return records\n }\n\n async listCollections(): Promise<NsidString[]> {\n const collections = await this.db.db\n .selectFrom('record')\n .select('collection')\n .groupBy('collection')\n .execute()\n\n return collections.map((row) => row.collection as NsidString)\n }\n\n async listRecordsForCollection(opts: {\n collection: string\n limit: number\n reverse: boolean\n cursor?: string\n rkeyStart?: string\n rkeyEnd?: string\n includeSoftDeleted?: boolean\n }): Promise<{ uri: AtUriString; cid: string; value: LexMap }[]> {\n const {\n collection,\n limit,\n reverse,\n cursor,\n rkeyStart,\n rkeyEnd,\n includeSoftDeleted = false,\n } = opts\n\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('record')\n .innerJoin('repo_block', 'repo_block.cid', 'record.cid')\n .where('record.collection', '=', collection)\n .if(!includeSoftDeleted, (qb) =>\n qb.where(notSoftDeletedClause(ref('record'))),\n )\n .orderBy('record.rkey', reverse ? 'asc' : 'desc')\n .limit(limit)\n .selectAll()\n\n // prioritize cursor but fall back to soon-to-be-depcreated rkey start/end\n if (cursor !== undefined) {\n if (reverse) {\n builder = builder.where('record.rkey', '>', cursor)\n } else {\n builder = builder.where('record.rkey', '<', cursor)\n }\n } else {\n if (rkeyStart !== undefined) {\n builder = builder.where('record.rkey', '>', rkeyStart)\n }\n if (rkeyEnd !== undefined) {\n builder = builder.where('record.rkey', '<', rkeyEnd)\n }\n }\n const res = await builder.execute()\n return res.map((row) => ({\n uri: row.uri as AtUriString,\n cid: row.cid,\n value: cborToLexRecord(row.content),\n }))\n }\n\n async getRecord(\n uri: AtUri | AtUriString,\n cid: string | null,\n includeSoftDeleted = false,\n ): Promise<{\n uri: string\n cid: string\n value: LexMap\n indexedAt: string\n takedownRef: string | null\n } | null> {\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('record')\n .innerJoin('repo_block', 'repo_block.cid', 'record.cid')\n .where('record.uri', '=', uri.toString())\n .selectAll()\n .if(!includeSoftDeleted, (qb) =>\n qb.where(notSoftDeletedClause(ref('record'))),\n )\n if (cid) {\n builder = builder.where('record.cid', '=', cid)\n }\n const record = await builder.executeTakeFirst()\n if (!record) return null\n return {\n uri: record.uri,\n cid: record.cid,\n value: cborToLexRecord(record.content),\n indexedAt: record.indexedAt,\n takedownRef: record.takedownRef ? record.takedownRef.toString() : null,\n }\n }\n\n async hasRecord(\n uri: AtUri,\n cid: string | null,\n includeSoftDeleted = false,\n ): Promise<boolean> {\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('record')\n .select('uri')\n .where('record.uri', '=', uri.toString())\n .if(!includeSoftDeleted, (qb) =>\n qb.where(notSoftDeletedClause(ref('record'))),\n )\n if (cid) {\n builder = builder.where('record.cid', '=', cid)\n }\n const record = await builder.executeTakeFirst()\n return !!record\n }\n\n async getRecordTakedownStatus(\n uri: AtUri,\n ): Promise<com.atproto.admin.defs.StatusAttr | null> {\n const res = await this.db.db\n .selectFrom('record')\n .select('takedownRef')\n .where('uri', '=', uri.toString())\n .executeTakeFirst()\n if (!res) return null\n return res.takedownRef\n ? { applied: true, ref: res.takedownRef }\n : { applied: false }\n }\n\n async getCurrentRecordCid(uri: AtUri): Promise<Cid | null> {\n const res = await this.db.db\n .selectFrom('record')\n .select('cid')\n .where('uri', '=', uri.toString())\n .executeTakeFirst()\n return res ? parseCid(res.cid) : null\n }\n\n async getRecordBacklinks(opts: {\n collection: string\n path: string\n linkTo: string\n }) {\n const { collection, path, linkTo } = opts\n return await this.db.db\n .selectFrom('record')\n .innerJoin('backlink', 'backlink.uri', 'record.uri')\n .where('backlink.path', '=', path)\n .where('backlink.linkTo', '=', linkTo)\n .where('record.collection', '=', collection)\n .selectAll('record')\n .execute()\n }\n\n // @NOTE this logic is a placeholder until we allow users to specify these constraints themselves.\n // Ensures that we don't end-up with duplicate likes, reposts, and follows from race conditions.\n\n async getBacklinkConflicts(uri: AtUri, record: LexMap): Promise<AtUri[]> {\n const conflicts: AtUri[] = []\n\n for (const backlink of getBacklinks(uri, record)) {\n const backlinks = await this.getRecordBacklinks({\n collection: uri.collection,\n path: backlink.path,\n linkTo: backlink.linkTo,\n })\n\n for (const { rkey } of backlinks) {\n conflicts.push(AtUri.make(uri.hostname, uri.collection, rkey))\n }\n }\n\n return conflicts\n }\n\n async listExistingBlocks(): Promise<CidSet> {\n const cids = new CidSet()\n let cursor: string | undefined = ''\n while (cursor !== undefined) {\n const res = await this.db.db\n .selectFrom('repo_block')\n .select('cid')\n .where('cid', '>', cursor)\n .orderBy('cid', 'asc')\n .limit(1000)\n .execute()\n for (const row of res) {\n cids.add(parseCid(row.cid))\n }\n cursor = res.at(-1)?.cid\n }\n return cids\n }\n\n async getProfileRecord() {\n const row = await this.db.db\n .selectFrom('record')\n .leftJoin('repo_block', 'repo_block.cid', 'record.cid')\n .where('record.collection', '=', app.bsky.actor.profile.$type)\n .where('record.rkey', '=', 'self')\n .selectAll()\n .executeTakeFirst()\n\n if (!row?.content) return null\n\n return cborToLexRecord(row.content) as app.bsky.actor.profile.Main\n }\n\n async getRecordsSinceRev(rev: string): Promise<LocalRecords> {\n const result: LocalRecords = { count: 0, profile: null, posts: [] }\n\n const res = await this.db.db\n .selectFrom('record')\n .innerJoin('repo_block', 'repo_block.cid', 'record.cid')\n .select([\n 'repo_block.content',\n 'uri',\n 'repo_block.cid',\n 'record.indexedAt',\n ])\n .where('record.repoRev', '>', rev)\n .limit(10)\n .orderBy('record.repoRev', 'asc')\n .execute()\n\n // sanity check to ensure that the clock received is not before _all_ local records (for instance in case of account migration)\n if (res.length > 0) {\n const sanityCheckRes = await this.db.db\n .selectFrom('record')\n .selectAll()\n .where('record.repoRev', '<=', rev)\n .limit(1)\n .executeTakeFirst()\n\n if (!sanityCheckRes) {\n return result\n }\n }\n\n for (const cur of res) {\n result.count++\n\n const uri = new AtUri(cur.uri)\n if (\n uri.collection === app.bsky.actor.profile.$type &&\n uri.rkey === 'self'\n ) {\n result.profile = {\n uri,\n cid: parseCid(cur.cid),\n indexedAt: cur.indexedAt as DatetimeString,\n record: cborToLexRecord(cur.content) as app.bsky.actor.profile.Main,\n }\n } else if (uri.collection === app.bsky.feed.post.$type) {\n result.posts.push({\n uri,\n cid: parseCid(cur.cid),\n indexedAt: cur.indexedAt as DatetimeString,\n record: cborToLexRecord(cur.content) as app.bsky.feed.post.Main,\n })\n }\n }\n\n return result\n }\n}\n\n// @NOTE in the future this can be replaced with a more generic routine that pulls backlinks based on lex docs.\n// For now we just want to ensure we're tracking links from follows, blocks, likes, and reposts.\n\nexport const getBacklinks = (uri: AtUri, record: LexMap): Backlink[] => {\n if (\n record?.['$type'] === app.bsky.graph.follow.$type ||\n record?.['$type'] === app.bsky.graph.block.$type\n ) {\n const subject = record['subject']\n if (typeof subject !== 'string') {\n return []\n }\n try {\n ensureValidDid(subject)\n } catch {\n return []\n }\n return [\n {\n uri: uri.toString(),\n path: 'subject',\n linkTo: subject,\n },\n ]\n }\n if (\n record?.['$type'] === app.bsky.feed.like.$type ||\n record?.['$type'] === app.bsky.feed.repost.$type\n ) {\n const subject = record['subject']\n if (typeof subject?.['uri'] !== 'string') {\n return []\n }\n try {\n ensureValidAtUri(subject['uri'])\n } catch {\n return []\n }\n return [\n {\n uri: uri.toString(),\n path: 'subject.uri',\n linkTo: subject['uri'],\n },\n ]\n }\n return []\n}\n"]}
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/actor-store/record/reader.ts"],"names":[],"mappings":"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","sourcesContent":["import { Cid, LexMap, parseCid } from '@atproto/lex-data'\nimport { CidSet, cborToLexRecord, formatDataKey } from '@atproto/repo'\nimport {\n AtUri,\n AtUriString,\n DatetimeString,\n NsidString,\n ensureValidAtUri,\n ensureValidDid,\n} from '@atproto/syntax'\nimport { countAll, notSoftDeletedClause } from '../../db/util.js'\nimport { app, com } from '../../lexicons/index.js'\nimport { LocalRecords } from '../../read-after-write/types.js'\nimport { ActorDb, Backlink } from '../db/index.js'\n\nexport type RecordDescript = {\n uri: string\n path: string\n cid: Cid\n}\n\nexport class RecordReader {\n constructor(public db: ActorDb) {}\n\n async recordCount(): Promise<number> {\n const res = await this.db.db\n .selectFrom('record')\n .select(countAll.as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async listAll(): Promise<RecordDescript[]> {\n const records: RecordDescript[] = []\n let cursor: string | undefined = ''\n while (cursor !== undefined) {\n const res = await this.db.db\n .selectFrom('record')\n .select(['uri', 'cid'])\n .where('uri', '>', cursor)\n .orderBy('uri', 'asc')\n .limit(1000)\n .execute()\n for (const row of res) {\n const parsed = new AtUri(row.uri)\n records.push({\n uri: row.uri,\n path: formatDataKey(parsed.collection, parsed.rkey),\n cid: parseCid(row.cid),\n })\n }\n cursor = res.at(-1)?.uri\n }\n return records\n }\n\n async listCollections(): Promise<NsidString[]> {\n const collections = await this.db.db\n .selectFrom('record')\n .select('collection')\n .groupBy('collection')\n .execute()\n\n return collections.map((row) => row.collection as NsidString)\n }\n\n async listRecordsForCollection(opts: {\n collection: string\n limit: number\n reverse: boolean\n cursor?: string\n rkeyStart?: string\n rkeyEnd?: string\n includeSoftDeleted?: boolean\n }): Promise<{ uri: AtUriString; cid: string; value: LexMap }[]> {\n const {\n collection,\n limit,\n reverse,\n cursor,\n rkeyStart,\n rkeyEnd,\n includeSoftDeleted = false,\n } = opts\n\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('record')\n .innerJoin('repo_block', 'repo_block.cid', 'record.cid')\n .where('record.collection', '=', collection)\n .$if(!includeSoftDeleted, (qb) =>\n qb.where(notSoftDeletedClause(ref('record'))),\n )\n .orderBy('record.rkey', reverse ? 'asc' : 'desc')\n .limit(limit)\n .selectAll()\n\n // prioritize cursor but fall back to soon-to-be-depcreated rkey start/end\n if (cursor !== undefined) {\n if (reverse) {\n builder = builder.where('record.rkey', '>', cursor)\n } else {\n builder = builder.where('record.rkey', '<', cursor)\n }\n } else {\n if (rkeyStart !== undefined) {\n builder = builder.where('record.rkey', '>', rkeyStart)\n }\n if (rkeyEnd !== undefined) {\n builder = builder.where('record.rkey', '<', rkeyEnd)\n }\n }\n const res = await builder.execute()\n return res.map((row) => ({\n uri: row.uri as AtUriString,\n cid: row.cid,\n value: cborToLexRecord(row.content),\n }))\n }\n\n async getRecord(\n uri: AtUri | AtUriString,\n cid: string | null,\n includeSoftDeleted = false,\n ): Promise<{\n uri: string\n cid: string\n value: LexMap\n indexedAt: string\n takedownRef: string | null\n } | null> {\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('record')\n .innerJoin('repo_block', 'repo_block.cid', 'record.cid')\n .where('record.uri', '=', uri.toString())\n .selectAll()\n .$if(!includeSoftDeleted, (qb) =>\n qb.where(notSoftDeletedClause(ref('record'))),\n )\n if (cid) {\n builder = builder.where('record.cid', '=', cid)\n }\n const record = await builder.executeTakeFirst()\n if (!record) return null\n return {\n uri: record.uri,\n cid: record.cid,\n value: cborToLexRecord(record.content),\n indexedAt: record.indexedAt,\n takedownRef: record.takedownRef ? record.takedownRef.toString() : null,\n }\n }\n\n async hasRecord(\n uri: AtUri,\n cid: string | null,\n includeSoftDeleted = false,\n ): Promise<boolean> {\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('record')\n .select('uri')\n .where('record.uri', '=', uri.toString())\n .$if(!includeSoftDeleted, (qb) =>\n qb.where(notSoftDeletedClause(ref('record'))),\n )\n if (cid) {\n builder = builder.where('record.cid', '=', cid)\n }\n const record = await builder.executeTakeFirst()\n return !!record\n }\n\n async getRecordTakedownStatus(\n uri: AtUri,\n ): Promise<com.atproto.admin.defs.StatusAttr | null> {\n const res = await this.db.db\n .selectFrom('record')\n .select('takedownRef')\n .where('uri', '=', uri.toString())\n .executeTakeFirst()\n if (!res) return null\n return res.takedownRef\n ? { applied: true, ref: res.takedownRef }\n : { applied: false }\n }\n\n async getCurrentRecordCid(uri: AtUri): Promise<Cid | null> {\n const res = await this.db.db\n .selectFrom('record')\n .select('cid')\n .where('uri', '=', uri.toString())\n .executeTakeFirst()\n return res ? parseCid(res.cid) : null\n }\n\n async getRecordBacklinks(opts: {\n collection: string\n path: string\n linkTo: string\n }) {\n const { collection, path, linkTo } = opts\n return await this.db.db\n .selectFrom('record')\n .innerJoin('backlink', 'backlink.uri', 'record.uri')\n .where('backlink.path', '=', path)\n .where('backlink.linkTo', '=', linkTo)\n .where('record.collection', '=', collection)\n .selectAll('record')\n .execute()\n }\n\n // @NOTE this logic is a placeholder until we allow users to specify these constraints themselves.\n // Ensures that we don't end-up with duplicate likes, reposts, and follows from race conditions.\n\n async getBacklinkConflicts(uri: AtUri, record: LexMap): Promise<AtUri[]> {\n const conflicts: AtUri[] = []\n\n for (const backlink of getBacklinks(uri, record)) {\n const backlinks = await this.getRecordBacklinks({\n collection: uri.collection,\n path: backlink.path,\n linkTo: backlink.linkTo,\n })\n\n for (const { rkey } of backlinks) {\n conflicts.push(AtUri.make(uri.hostname, uri.collection, rkey))\n }\n }\n\n return conflicts\n }\n\n async listExistingBlocks(): Promise<CidSet> {\n const cids = new CidSet()\n let cursor: string | undefined = ''\n while (cursor !== undefined) {\n const res = await this.db.db\n .selectFrom('repo_block')\n .select('cid')\n .where('cid', '>', cursor)\n .orderBy('cid', 'asc')\n .limit(1000)\n .execute()\n for (const row of res) {\n cids.add(parseCid(row.cid))\n }\n cursor = res.at(-1)?.cid\n }\n return cids\n }\n\n async getProfileRecord() {\n const row = await this.db.db\n .selectFrom('record')\n .leftJoin('repo_block', 'repo_block.cid', 'record.cid')\n .where('record.collection', '=', app.bsky.actor.profile.$type)\n .where('record.rkey', '=', 'self')\n .selectAll()\n .executeTakeFirst()\n\n if (!row?.content) return null\n\n return cborToLexRecord(row.content) as app.bsky.actor.profile.Main\n }\n\n async getRecordsSinceRev(rev: string): Promise<LocalRecords> {\n const result: LocalRecords = { count: 0, profile: null, posts: [] }\n\n const res = await this.db.db\n .selectFrom('record')\n .innerJoin('repo_block', 'repo_block.cid', 'record.cid')\n .select([\n 'repo_block.content',\n 'uri',\n 'repo_block.cid',\n 'record.indexedAt',\n ])\n .where('record.repoRev', '>', rev)\n .limit(10)\n .orderBy('record.repoRev', 'asc')\n .execute()\n\n // sanity check to ensure that the clock received is not before _all_ local records (for instance in case of account migration)\n if (res.length > 0) {\n const sanityCheckRes = await this.db.db\n .selectFrom('record')\n .selectAll()\n .where('record.repoRev', '<=', rev)\n .limit(1)\n .executeTakeFirst()\n\n if (!sanityCheckRes) {\n return result\n }\n }\n\n for (const cur of res) {\n result.count++\n\n const uri = new AtUri(cur.uri)\n if (\n uri.collection === app.bsky.actor.profile.$type &&\n uri.rkey === 'self'\n ) {\n result.profile = {\n uri,\n cid: parseCid(cur.cid),\n indexedAt: cur.indexedAt as DatetimeString,\n record: cborToLexRecord(cur.content) as app.bsky.actor.profile.Main,\n }\n } else if (uri.collection === app.bsky.feed.post.$type) {\n result.posts.push({\n uri,\n cid: parseCid(cur.cid),\n indexedAt: cur.indexedAt as DatetimeString,\n record: cborToLexRecord(cur.content) as app.bsky.feed.post.Main,\n })\n }\n }\n\n return result\n }\n}\n\n// @NOTE in the future this can be replaced with a more generic routine that pulls backlinks based on lex docs.\n// For now we just want to ensure we're tracking links from follows, blocks, likes, and reposts.\n\nexport const getBacklinks = (uri: AtUri, record: LexMap): Backlink[] => {\n if (\n record?.['$type'] === app.bsky.graph.follow.$type ||\n record?.['$type'] === app.bsky.graph.block.$type\n ) {\n const subject = record['subject']\n if (typeof subject !== 'string') {\n return []\n }\n try {\n ensureValidDid(subject)\n } catch {\n return []\n }\n return [\n {\n uri: uri.toString(),\n path: 'subject',\n linkTo: subject,\n },\n ]\n }\n if (\n record?.['$type'] === app.bsky.feed.like.$type ||\n record?.['$type'] === app.bsky.feed.repost.$type\n ) {\n const subject = record['subject']\n if (typeof subject?.['uri'] !== 'string') {\n return []\n }\n try {\n ensureValidAtUri(subject['uri'])\n } catch {\n return []\n }\n return [\n {\n uri: uri.toString(),\n path: 'subject.uri',\n linkTo: subject['uri'],\n },\n ]\n }\n return []\n}\n"]}
@@ -18,7 +18,11 @@ export declare class SqlRepoReader extends ReadableBlockstore {
18
18
  }>;
19
19
  getCarStream(since?: string): Promise<AsyncIterable<Uint8Array<ArrayBufferLike>>>;
20
20
  iterateCarBlocks(since?: string): AsyncIterable<CarBlock>;
21
- getBlockRange(since?: string, cursor?: RevCursor): Promise<import("kysely").Selection<import("kysely/dist/esm/parser/table-parser.js").From<import("../db/index.js").DatabaseSchema, "repo_block">, "repo_block", "cid" | "content" | "repoRev">[]>;
21
+ getBlockRange(since?: string, cursor?: RevCursor): Promise<{
22
+ cid: string;
23
+ content: Uint8Array<ArrayBufferLike>;
24
+ repoRev: string;
25
+ }[]>;
22
26
  countBlocks(): Promise<number>;
23
27
  destroy(): Promise<void>;
24
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sql-repo-reader.d.ts","sourceRoot":"","sources":["../../../src/actor-store/repo/sql-repo-reader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,EACL,QAAQ,EACR,QAAQ,EAER,kBAAkB,EAEnB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,qBAAa,aAAc,SAAQ,kBAAkB;IAGhC,EAAE,EAAE,OAAO;IAF9B,KAAK,EAAE,QAAQ,CAAiB;IAEhC,YAAmB,EAAE,EAAE,OAAO,EAE7B;IAEK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAG5B;IAEK,eAAe,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAU1D;IAEK,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAWnD;IAEK,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAGpC;IAEK,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAqB1E;IAEK,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,uDAMhC;IAEM,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAqB/D;IAEK,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,oMAoBrD;IAEK,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAMnC;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7B;CACF;AAED,KAAK,SAAS,GAAG;IACf,GAAG,EAAE,GAAG,CAAA;IACR,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,qBAAa,qBAAsB,SAAQ,KAAK;CAAG"}
1
+ {"version":3,"file":"sql-repo-reader.d.ts","sourceRoot":"","sources":["../../../src/actor-store/repo/sql-repo-reader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,EACL,QAAQ,EACR,QAAQ,EAER,kBAAkB,EAEnB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,qBAAa,aAAc,SAAQ,kBAAkB;IAGhC,EAAE,EAAE,OAAO;IAF9B,KAAK,EAAE,QAAQ,CAAiB;IAEhC,YAAmB,EAAE,EAAE,OAAO,EAE7B;IAEK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAG5B;IAEK,eAAe,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAU1D;IAEK,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAWnD;IAEK,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAGpC;IAEK,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAqB1E;IAEK,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,uDAMhC;IAEM,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAqB/D;IAEK,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS;;;;SAoBrD;IAEK,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAMnC;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7B;CACF;AAED,KAAK,SAAS,GAAG;IACf,GAAG,EAAE,GAAG,CAAA;IACR,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,qBAAa,qBAAsB,SAAQ,KAAK;CAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"sql-repo-reader.js","sourceRoot":"","sources":["../../../src/actor-store/repo/sql-repo-reader.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'kysely'\nimport { chunkArray } from '@atproto/common'\nimport { Cid, parseCid } from '@atproto/lex-data'\nimport {\n BlockMap,\n CarBlock,\n CidSet,\n ReadableBlockstore,\n writeCarStream,\n} from '@atproto/repo'\nimport { countAll } from '../../db/index.js'\nimport { ActorDb } from '../db/index.js'\n\nexport class SqlRepoReader extends ReadableBlockstore {\n cache: BlockMap = new BlockMap()\n\n constructor(public db: ActorDb) {\n super()\n }\n\n async getRoot(): Promise<Cid> {\n const root = await this.getRootDetailed()\n return root.cid\n }\n\n async getRootDetailed(): Promise<{ cid: Cid; rev: string }> {\n const res = await this.db.db\n .selectFrom('repo_root')\n .select(['cid', 'rev'])\n .limit(1)\n .executeTakeFirstOrThrow()\n return {\n cid: parseCid(res.cid),\n rev: res.rev,\n }\n }\n\n async getBytes(cid: Cid): Promise<Uint8Array | null> {\n const cached = this.cache.get(cid)\n if (cached) return cached\n const found = await this.db.db\n .selectFrom('repo_block')\n .where('repo_block.cid', '=', cid.toString())\n .select('content')\n .executeTakeFirst()\n if (!found) return null\n this.cache.set(cid, found.content)\n return found.content\n }\n\n async has(cid: Cid): Promise<boolean> {\n const got = await this.getBytes(cid)\n return !!got\n }\n\n async getBlocks(cids: Cid[]): Promise<{ blocks: BlockMap; missing: Cid[] }> {\n const cached = this.cache.getMany(cids)\n if (cached.missing.length < 1) return cached\n const missing = new CidSet(cached.missing)\n const missingStr = cached.missing.map((c) => c.toString())\n const blocks = new BlockMap()\n for (const batch of chunkArray(missingStr, 500)) {\n const res = await this.db.db\n .selectFrom('repo_block')\n .where('repo_block.cid', 'in', batch)\n .select(['repo_block.cid as cid', 'repo_block.content as content'])\n .execute()\n for (const row of res) {\n const cid = parseCid(row.cid)\n blocks.set(cid, row.content)\n missing.delete(cid)\n }\n }\n this.cache.addMap(blocks)\n blocks.addMap(cached.blocks)\n return { blocks, missing: missing.toList() }\n }\n\n async getCarStream(since?: string) {\n const root = await this.getRoot()\n if (!root) {\n throw new RepoRootNotFoundError()\n }\n return writeCarStream(root, this.iterateCarBlocks(since))\n }\n\n async *iterateCarBlocks(since?: string): AsyncIterable<CarBlock> {\n let cursor: RevCursor | undefined = undefined\n // allow us to write to car while fetching the next page\n do {\n const res = await this.getBlockRange(since, cursor)\n for (const row of res) {\n yield {\n cid: parseCid(row.cid),\n bytes: row.content,\n }\n }\n const lastRow = res.at(-1)\n if (lastRow && lastRow.repoRev) {\n cursor = {\n cid: parseCid(lastRow.cid),\n rev: lastRow.repoRev,\n }\n } else {\n cursor = undefined\n }\n } while (cursor)\n }\n\n async getBlockRange(since?: string, cursor?: RevCursor) {\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('repo_block')\n .select(['cid', 'repoRev', 'content'])\n .orderBy('repoRev', 'desc')\n .orderBy('cid', 'desc')\n .limit(500)\n if (cursor) {\n // use this syntax to ensure we hit the index\n builder = builder.where(\n sql`((${ref('repoRev')}, ${ref('cid')}) < (${\n cursor.rev\n }, ${cursor.cid.toString()}))`,\n )\n }\n if (since) {\n builder = builder.where('repoRev', '>', since)\n }\n return builder.execute()\n }\n\n async countBlocks(): Promise<number> {\n const res = await this.db.db\n .selectFrom('repo_block')\n .select(countAll.as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async destroy(): Promise<void> {\n throw new Error('Destruction of SQL repo storage not allowed at runtime')\n }\n}\n\ntype RevCursor = {\n cid: Cid\n rev: string\n}\n\nexport class RepoRootNotFoundError extends Error {}\n"]}
1
+ {"version":3,"file":"sql-repo-reader.js","sourceRoot":"","sources":["../../../src/actor-store/repo/sql-repo-reader.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'kysely'\nimport { chunkArray } from '@atproto/common'\nimport { Cid, parseCid } from '@atproto/lex-data'\nimport {\n BlockMap,\n CarBlock,\n CidSet,\n ReadableBlockstore,\n writeCarStream,\n} from '@atproto/repo'\nimport { countAll } from '../../db/index.js'\nimport { ActorDb } from '../db/index.js'\n\nexport class SqlRepoReader extends ReadableBlockstore {\n cache: BlockMap = new BlockMap()\n\n constructor(public db: ActorDb) {\n super()\n }\n\n async getRoot(): Promise<Cid> {\n const root = await this.getRootDetailed()\n return root.cid\n }\n\n async getRootDetailed(): Promise<{ cid: Cid; rev: string }> {\n const res = await this.db.db\n .selectFrom('repo_root')\n .select(['cid', 'rev'])\n .limit(1)\n .executeTakeFirstOrThrow()\n return {\n cid: parseCid(res.cid),\n rev: res.rev,\n }\n }\n\n async getBytes(cid: Cid): Promise<Uint8Array | null> {\n const cached = this.cache.get(cid)\n if (cached) return cached\n const found = await this.db.db\n .selectFrom('repo_block')\n .where('repo_block.cid', '=', cid.toString())\n .select('content')\n .executeTakeFirst()\n if (!found) return null\n this.cache.set(cid, found.content)\n return found.content\n }\n\n async has(cid: Cid): Promise<boolean> {\n const got = await this.getBytes(cid)\n return !!got\n }\n\n async getBlocks(cids: Cid[]): Promise<{ blocks: BlockMap; missing: Cid[] }> {\n const cached = this.cache.getMany(cids)\n if (cached.missing.length < 1) return cached\n const missing = new CidSet(cached.missing)\n const missingStr = cached.missing.map((c) => c.toString())\n const blocks = new BlockMap()\n for (const batch of chunkArray(missingStr, 500)) {\n const res = await this.db.db\n .selectFrom('repo_block')\n .where('repo_block.cid', 'in', batch)\n .select(['repo_block.cid as cid', 'repo_block.content as content'])\n .execute()\n for (const row of res) {\n const cid = parseCid(row.cid)\n blocks.set(cid, row.content)\n missing.delete(cid)\n }\n }\n this.cache.addMap(blocks)\n blocks.addMap(cached.blocks)\n return { blocks, missing: missing.toList() }\n }\n\n async getCarStream(since?: string) {\n const root = await this.getRoot()\n if (!root) {\n throw new RepoRootNotFoundError()\n }\n return writeCarStream(root, this.iterateCarBlocks(since))\n }\n\n async *iterateCarBlocks(since?: string): AsyncIterable<CarBlock> {\n let cursor: RevCursor | undefined = undefined\n // allow us to write to car while fetching the next page\n do {\n const res = await this.getBlockRange(since, cursor)\n for (const row of res) {\n yield {\n cid: parseCid(row.cid),\n bytes: row.content,\n }\n }\n const lastRow = res.at(-1)\n if (lastRow && lastRow.repoRev) {\n cursor = {\n cid: parseCid(lastRow.cid),\n rev: lastRow.repoRev,\n }\n } else {\n cursor = undefined\n }\n } while (cursor)\n }\n\n async getBlockRange(since?: string, cursor?: RevCursor) {\n const { ref } = this.db.db.dynamic\n let builder = this.db.db\n .selectFrom('repo_block')\n .select(['cid', 'repoRev', 'content'])\n .orderBy('repoRev', 'desc')\n .orderBy('cid', 'desc')\n .limit(500)\n if (cursor) {\n // use this syntax to ensure we hit the index\n builder = builder.where(\n sql<boolean>`((${ref('repoRev')}, ${ref('cid')}) < (${\n cursor.rev\n }, ${cursor.cid.toString()}))`,\n )\n }\n if (since) {\n builder = builder.where('repoRev', '>', since)\n }\n return builder.execute()\n }\n\n async countBlocks(): Promise<number> {\n const res = await this.db.db\n .selectFrom('repo_block')\n .select(countAll.as('count'))\n .executeTakeFirst()\n return res?.count ?? 0\n }\n\n async destroy(): Promise<void> {\n throw new Error('Destruction of SQL repo storage not allowed at runtime')\n }\n}\n\ntype RevCursor = {\n cid: Cid\n rev: string\n}\n\nexport class RepoRootNotFoundError extends Error {}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"updateSubjectStatus.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/admin/updateSubjectStatus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAiDvD"}
1
+ {"version":3,"file":"updateSubjectStatus.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/admin/updateSubjectStatus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA6DvD"}
@@ -7,6 +7,9 @@ export default function (server, ctx) {
7
7
  auth: ctx.authVerifier.moderator,
8
8
  handler: async ({ input }) => {
9
9
  const { subject, takedown, deactivated } = input.body;
10
+ if (takedown?.applied && deactivated != null && !deactivated.applied) {
11
+ throw new InvalidRequestError(`Cannot activate and takedown an account at the same time`);
12
+ }
10
13
  if (takedown) {
11
14
  if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {
12
15
  await ctx.accountManager.takedownAccount(subject.did, takedown);
@@ -29,16 +32,21 @@ export default function (server, ctx) {
29
32
  if (deactivated) {
30
33
  if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {
31
34
  if (deactivated.applied) {
32
- await ctx.accountManager.deactivateAccount(subject.did, null);
35
+ await ctx.accountManager.deactivateAccount(subject.did);
33
36
  }
34
37
  else {
35
38
  await ctx.accountManager.activateAccount(subject.did);
36
39
  }
37
40
  }
38
41
  }
39
- if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {
40
- const status = await ctx.accountManager.getAccountStatus(subject.did);
41
- await ctx.sequencer.sequenceAccount(subject.did, status);
42
+ // @NOTE accountManager will sequence an account status when updating the
43
+ // status, so we don't *need* to sequence the account status here.
44
+ // However, this endpoint historically has always sequenced the account
45
+ // status.
46
+ if (!takedown && !deactivated) {
47
+ if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {
48
+ await ctx.accountManager.sequenceAccountStatus(subject.did);
49
+ }
42
50
  }
43
51
  return {
44
52
  encoding: 'application/json',
@@ -1 +1 @@
1
- {"version":3,"file":"updateSubjectStatus.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/admin/updateSubjectStatus.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseCid } from '@atproto/lex-data'\nimport { AtUri } from '@atproto/syntax'\nimport { InvalidRequestError, Server } from '@atproto/xrpc-server'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(com.atproto.admin.updateSubjectStatus, {\n auth: ctx.authVerifier.moderator,\n handler: async ({ input }) => {\n const { subject, takedown, deactivated } = input.body\n if (takedown) {\n if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {\n await ctx.accountManager.takedownAccount(subject.did, takedown)\n } else if (com.atproto.repo.strongRef.$isTypeOf(subject)) {\n const uri = new AtUri(subject.uri)\n await ctx.actorStore.transact(uri.hostname, async (store) => {\n await store.record.updateRecordTakedownStatus(uri, takedown)\n })\n } else if (com.atproto.admin.defs.repoBlobRef.$isTypeOf(subject)) {\n await ctx.actorStore.transact(subject.did, async (store) => {\n await store.repo.blob.updateBlobTakedownStatus(\n parseCid(subject.cid),\n takedown,\n )\n })\n } else {\n throw new InvalidRequestError(`Invalid subject (${subject.$type})`)\n }\n }\n\n if (deactivated) {\n if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {\n if (deactivated.applied) {\n await ctx.accountManager.deactivateAccount(subject.did, null)\n } else {\n await ctx.accountManager.activateAccount(subject.did)\n }\n }\n }\n\n if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {\n const status = await ctx.accountManager.getAccountStatus(subject.did)\n await ctx.sequencer.sequenceAccount(subject.did, status)\n }\n\n return {\n encoding: 'application/json' as const,\n body: {\n subject,\n takedown,\n },\n }\n },\n })\n}\n"]}
1
+ {"version":3,"file":"updateSubjectStatus.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/admin/updateSubjectStatus.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseCid } from '@atproto/lex-data'\nimport { AtUri } from '@atproto/syntax'\nimport { InvalidRequestError, Server } from '@atproto/xrpc-server'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(com.atproto.admin.updateSubjectStatus, {\n auth: ctx.authVerifier.moderator,\n handler: async ({ input }) => {\n const { subject, takedown, deactivated } = input.body\n\n if (takedown?.applied && deactivated != null && !deactivated.applied) {\n throw new InvalidRequestError(\n `Cannot activate and takedown an account at the same time`,\n )\n }\n\n if (takedown) {\n if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {\n await ctx.accountManager.takedownAccount(subject.did, takedown)\n } else if (com.atproto.repo.strongRef.$isTypeOf(subject)) {\n const uri = new AtUri(subject.uri)\n await ctx.actorStore.transact(uri.hostname, async (store) => {\n await store.record.updateRecordTakedownStatus(uri, takedown)\n })\n } else if (com.atproto.admin.defs.repoBlobRef.$isTypeOf(subject)) {\n await ctx.actorStore.transact(subject.did, async (store) => {\n await store.repo.blob.updateBlobTakedownStatus(\n parseCid(subject.cid),\n takedown,\n )\n })\n } else {\n throw new InvalidRequestError(`Invalid subject (${subject.$type})`)\n }\n }\n\n if (deactivated) {\n if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {\n if (deactivated.applied) {\n await ctx.accountManager.deactivateAccount(subject.did)\n } else {\n await ctx.accountManager.activateAccount(subject.did)\n }\n }\n }\n\n // @NOTE accountManager will sequence an account status when updating the\n // status, so we don't *need* to sequence the account status here.\n // However, this endpoint historically has always sequenced the account\n // status.\n if (!takedown && !deactivated) {\n if (com.atproto.admin.defs.repoRef.$isTypeOf(subject)) {\n await ctx.accountManager.sequenceAccountStatus(subject.did)\n }\n }\n\n return {\n encoding: 'application/json' as const,\n body: {\n subject,\n takedown,\n },\n }\n },\n })\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"activateAccount.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/activateAccount.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,MAAM,EACP,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAInD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA+CvD"}
1
+ {"version":3,"file":"activateAccount.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/activateAccount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA+BvD"}