@atproto/pds 0.5.5 → 0.5.6

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 (147) hide show
  1. package/CHANGELOG.md +15 -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/config/config.d.ts +2 -1
  83. package/dist/config/config.d.ts.map +1 -1
  84. package/dist/config/config.js +4 -1
  85. package/dist/config/config.js.map +1 -1
  86. package/dist/context.d.ts.map +1 -1
  87. package/dist/context.js +1 -1
  88. package/dist/context.js.map +1 -1
  89. package/dist/db/migrator.d.ts +4 -3
  90. package/dist/db/migrator.d.ts.map +1 -1
  91. package/dist/db/migrator.js +1 -1
  92. package/dist/db/migrator.js.map +1 -1
  93. package/dist/db/pagination.d.ts +2 -1
  94. package/dist/db/pagination.d.ts.map +1 -1
  95. package/dist/db/pagination.js +2 -2
  96. package/dist/db/pagination.js.map +1 -1
  97. package/dist/db/util.d.ts +3 -3
  98. package/dist/db/util.d.ts.map +1 -1
  99. package/dist/db/util.js.map +1 -1
  100. package/dist/mailer/index.d.ts +2 -0
  101. package/dist/mailer/index.d.ts.map +1 -1
  102. package/dist/mailer/index.js +2 -0
  103. package/dist/mailer/index.js.map +1 -1
  104. package/dist/scripts/sequencer-recovery/recovery-db.js.map +1 -1
  105. package/dist/sequencer/events.d.ts.map +1 -1
  106. package/dist/sequencer/events.js +6 -13
  107. package/dist/sequencer/events.js.map +1 -1
  108. package/dist/sequencer/sequencer.d.ts +1 -1
  109. package/dist/sequencer/sequencer.d.ts.map +1 -1
  110. package/dist/sequencer/sequencer.js.map +1 -1
  111. package/package.json +13 -13
  112. package/src/account-manager/account-manager.ts +135 -36
  113. package/src/account-manager/db/migrations/005-oauth-account-management.ts +6 -5
  114. package/src/account-manager/db/schema/authorization-request.ts +2 -1
  115. package/src/account-manager/db/schema/authorized-client.ts +6 -2
  116. package/src/account-manager/db/schema/token.ts +2 -2
  117. package/src/account-manager/helpers/account-device.ts +5 -11
  118. package/src/account-manager/helpers/account.ts +39 -16
  119. package/src/account-manager/helpers/auth.ts +2 -2
  120. package/src/account-manager/helpers/authorization-request.ts +12 -8
  121. package/src/account-manager/helpers/authorized-client.ts +12 -6
  122. package/src/account-manager/helpers/device.ts +4 -4
  123. package/src/account-manager/helpers/lexicon.ts +8 -3
  124. package/src/account-manager/helpers/password.ts +6 -0
  125. package/src/account-manager/helpers/token.ts +17 -11
  126. package/src/account-manager/oauth-store.ts +129 -61
  127. package/src/actor-store/blob/reader.ts +8 -5
  128. package/src/actor-store/record/reader.ts +3 -3
  129. package/src/actor-store/repo/sql-repo-reader.ts +1 -1
  130. package/src/api/com/atproto/admin/updateSubjectStatus.ts +16 -4
  131. package/src/api/com/atproto/server/activateAccount.ts +27 -49
  132. package/src/api/com/atproto/server/deactivateAccount.ts +3 -7
  133. package/src/api/com/atproto/server/deleteAccount.ts +60 -43
  134. package/src/api/com/atproto/server/util.ts +24 -7
  135. package/src/config/config.ts +7 -2
  136. package/src/context.ts +2 -3
  137. package/src/db/migrator.ts +2 -1
  138. package/src/db/pagination.ts +7 -7
  139. package/src/db/util.ts +5 -2
  140. package/src/mailer/index.ts +4 -2
  141. package/src/scripts/sequencer-recovery/recovery-db.ts +1 -1
  142. package/src/sequencer/events.ts +8 -13
  143. package/src/sequencer/sequencer.ts +1 -3
  144. package/tests/account-manager.test.ts +79 -0
  145. package/tests/account-status.test.ts +206 -0
  146. package/tests/db.test.ts +3 -3
  147. package/tests/oauth.test.ts +91 -0
@@ -1,39 +1,33 @@
1
- import { INVALID_HANDLE } from '@atproto/syntax';
2
- import { ForbiddenError, InvalidRequestError, } from '@atproto/xrpc-server';
1
+ import { ForbiddenError } from '@atproto/xrpc-server';
3
2
  import { ACCESS_FULL } from '../../../../auth-scope.js';
4
3
  import { com } from '../../../../lexicons/index.js';
5
- import { assertValidDidDocumentForService } from './util.js';
6
4
  export default function (server, ctx) {
7
- server.add(com.atproto.server.activateAccount, {
8
- auth: ctx.authVerifier.authorization({
9
- scopes: ACCESS_FULL,
10
- authorize: () => {
11
- throw new ForbiddenError('OAuth credentials are not supported for this endpoint');
12
- },
13
- }),
14
- handler: async ({ req, auth }) => {
15
- // in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)
16
- if (ctx.entrywayClient) {
5
+ const { entrywayClient } = ctx;
6
+ const auth = ctx.authVerifier.authorization({
7
+ scopes: ACCESS_FULL,
8
+ authorize: () => {
9
+ throw new ForbiddenError('OAuth credentials are not supported for this endpoint');
10
+ },
11
+ });
12
+ if (entrywayClient) {
13
+ // in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)
14
+ server.add(com.atproto.server.activateAccount, {
15
+ auth,
16
+ handler: async ({ req }) => {
17
17
  const { headers } = ctx.entrywayPassthruHeaders(req);
18
- await ctx.entrywayClient.xrpc(com.atproto.server.activateAccount, {
18
+ await entrywayClient.xrpc(com.atproto.server.activateAccount, {
19
19
  headers,
20
20
  });
21
- return;
22
- }
23
- const requester = auth.credentials.did;
24
- await assertValidDidDocumentForService(ctx, requester);
25
- const account = await ctx.accountManager.getAccount(requester, {
26
- includeDeactivated: true,
27
- });
28
- if (!account) {
29
- throw new InvalidRequestError('user not found', 'AccountNotFound');
30
- }
31
- await ctx.accountManager.activateAccount(requester);
32
- const syncData = await ctx.actorStore.read(requester, (store) => store.repo.getSyncEventData());
33
- // @NOTE: we're over-emitting for now for backwards compatibility, can reduce this in the future
34
- const status = await ctx.accountManager.getAccountStatus(requester);
35
- await ctx.sequencer.sequenceAccountActivation(requester, account.handle ?? INVALID_HANDLE, status, syncData);
36
- },
37
- });
21
+ },
22
+ });
23
+ }
24
+ else {
25
+ server.add(com.atproto.server.activateAccount, {
26
+ auth,
27
+ handler: async ({ auth }) => {
28
+ await ctx.accountManager.activateAccount(auth.credentials.did);
29
+ },
30
+ });
31
+ }
38
32
  }
39
33
  //# sourceMappingURL=activateAccount.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"activateAccount.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/activateAccount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EACL,cAAc,EACd,mBAAmB,GAEpB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAEvD,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAAE,gCAAgC,EAAE,MAAM,WAAW,CAAA;AAE5D,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE;QAC7C,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC;YACnC,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,GAAG,EAAE;gBACd,MAAM,IAAI,cAAc,CACtB,uDAAuD,CACxD,CAAA;YACH,CAAC;SACF,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;YAC/B,4HAA4H;YAC5H,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;gBACpD,MAAM,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE;oBAChE,OAAO;iBACR,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YAEtC,MAAM,gCAAgC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;YAEtD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,SAAS,EAAE;gBAC7D,kBAAkB,EAAE,IAAI;aACzB,CAAC,CAAA;YACF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,mBAAmB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAA;YACpE,CAAC;YAED,MAAM,GAAG,CAAC,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;YAEnD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAC9D,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAC9B,CAAA;YAED,gGAAgG;YAChG,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAA;YACnE,MAAM,GAAG,CAAC,SAAS,CAAC,yBAAyB,CAC3C,SAAS,EACT,OAAO,CAAC,MAAM,IAAI,cAAc,EAChC,MAAM,EACN,QAAQ,CACT,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { INVALID_HANDLE } from '@atproto/syntax'\nimport {\n ForbiddenError,\n InvalidRequestError,\n Server,\n} from '@atproto/xrpc-server'\nimport { ACCESS_FULL } from '../../../../auth-scope.js'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\nimport { assertValidDidDocumentForService } from './util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(com.atproto.server.activateAccount, {\n auth: ctx.authVerifier.authorization({\n scopes: ACCESS_FULL,\n authorize: () => {\n throw new ForbiddenError(\n 'OAuth credentials are not supported for this endpoint',\n )\n },\n }),\n handler: async ({ req, auth }) => {\n // in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)\n if (ctx.entrywayClient) {\n const { headers } = ctx.entrywayPassthruHeaders(req)\n await ctx.entrywayClient.xrpc(com.atproto.server.activateAccount, {\n headers,\n })\n return\n }\n\n const requester = auth.credentials.did\n\n await assertValidDidDocumentForService(ctx, requester)\n\n const account = await ctx.accountManager.getAccount(requester, {\n includeDeactivated: true,\n })\n if (!account) {\n throw new InvalidRequestError('user not found', 'AccountNotFound')\n }\n\n await ctx.accountManager.activateAccount(requester)\n\n const syncData = await ctx.actorStore.read(requester, (store) =>\n store.repo.getSyncEventData(),\n )\n\n // @NOTE: we're over-emitting for now for backwards compatibility, can reduce this in the future\n const status = await ctx.accountManager.getAccountStatus(requester)\n await ctx.sequencer.sequenceAccountActivation(\n requester,\n account.handle ?? INVALID_HANDLE,\n status,\n syncData,\n )\n },\n })\n}\n"]}
1
+ {"version":3,"file":"activateAccount.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/activateAccount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAU,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAEvD,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,EAAE,cAAc,EAAE,GAAG,GAAG,CAAA;IAE9B,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC;QAC1C,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,GAAG,EAAE;YACd,MAAM,IAAI,cAAc,CACtB,uDAAuD,CACxD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;IAEF,IAAI,cAAc,EAAE,CAAC;QACnB,4HAA4H;QAC5H,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE;YAC7C,IAAI;YACJ,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBACzB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;gBACpD,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE;oBAC5D,OAAO;iBACR,CAAC,CAAA;YACJ,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE;YAC7C,IAAI;YACJ,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC1B,MAAM,GAAG,CAAC,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YAChE,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { ForbiddenError, Server } from '@atproto/xrpc-server'\nimport { ACCESS_FULL } from '../../../../auth-scope.js'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const { entrywayClient } = ctx\n\n const auth = ctx.authVerifier.authorization({\n scopes: ACCESS_FULL,\n authorize: () => {\n throw new ForbiddenError(\n 'OAuth credentials are not supported for this endpoint',\n )\n },\n })\n\n if (entrywayClient) {\n // in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)\n server.add(com.atproto.server.activateAccount, {\n auth,\n handler: async ({ req }) => {\n const { headers } = ctx.entrywayPassthruHeaders(req)\n await entrywayClient.xrpc(com.atproto.server.activateAccount, {\n headers,\n })\n },\n })\n } else {\n server.add(com.atproto.server.activateAccount, {\n auth,\n handler: async ({ auth }) => {\n await ctx.accountManager.activateAccount(auth.credentials.did)\n },\n })\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"deactivateAccount.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deactivateAccount.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,QAuCvD"}
1
+ {"version":3,"file":"deactivateAccount.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deactivateAccount.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,QAmCvD"}
@@ -27,10 +27,9 @@ export default function (server, ctx) {
27
27
  server.add(com.atproto.server.deactivateAccount, {
28
28
  auth,
29
29
  handler: async ({ input: { body }, auth }) => {
30
- const requester = auth.credentials.did;
31
- await ctx.accountManager.deactivateAccount(requester, body.deleteAfter ?? null);
32
- const status = await ctx.accountManager.getAccountStatus(requester);
33
- await ctx.sequencer.sequenceAccount(requester, status);
30
+ await ctx.accountManager.deactivateAccount(auth.credentials.did, {
31
+ deleteAfter: body.deleteAfter ?? null,
32
+ });
34
33
  },
35
34
  });
36
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deactivateAccount.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deactivateAccount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAU,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,EAAE,cAAc,EAAE,GAAG,GAAG,CAAA;IAE9B,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC;QAC1C,UAAU,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC;QACjC,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,GAAG,EAAE;YACd,MAAM,IAAI,cAAc,CACtB,uDAAuD,CACxD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;IAEF,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE;YAC/C,IAAI;YACJ,gIAAgI;YAChI,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC1C,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;gBACpD,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE;oBAC9D,OAAO;oBACP,IAAI;iBACL,CAAC,CAAA;YACJ,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE;YAC/C,IAAI;YACJ,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;gBACtC,MAAM,GAAG,CAAC,cAAc,CAAC,iBAAiB,CACxC,SAAS,EACT,IAAI,CAAC,WAAW,IAAI,IAAI,CACzB,CAAA;gBACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAA;gBACnE,MAAM,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;YACxD,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { ForbiddenError, Server } from '@atproto/xrpc-server'\nimport { ACCESS_FULL, AuthScope } from '../../../../auth-scope.js'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const { entrywayClient } = ctx\n\n const auth = ctx.authVerifier.authorization({\n additional: [AuthScope.Takendown],\n scopes: ACCESS_FULL,\n authorize: () => {\n throw new ForbiddenError(\n 'OAuth credentials are not supported for this endpoint',\n )\n },\n })\n\n if (entrywayClient) {\n server.add(com.atproto.server.deactivateAccount, {\n auth,\n // in the case of entryway, the full flow is deactivateAccount (PDS) -> deactivateAccount (Entryway) -> updateSubjectStatus(PDS)\n handler: async ({ input: { body }, req }) => {\n const { headers } = ctx.entrywayPassthruHeaders(req)\n await entrywayClient.xrpc(com.atproto.server.deactivateAccount, {\n headers,\n body,\n })\n },\n })\n } else {\n server.add(com.atproto.server.deactivateAccount, {\n auth,\n handler: async ({ input: { body }, auth }) => {\n const requester = auth.credentials.did\n await ctx.accountManager.deactivateAccount(\n requester,\n body.deleteAfter ?? null,\n )\n const status = await ctx.accountManager.getAccountStatus(requester)\n await ctx.sequencer.sequenceAccount(requester, status)\n },\n })\n }\n}\n"]}
1
+ {"version":3,"file":"deactivateAccount.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deactivateAccount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAU,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,EAAE,cAAc,EAAE,GAAG,GAAG,CAAA;IAE9B,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC;QAC1C,UAAU,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC;QACjC,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,GAAG,EAAE;YACd,MAAM,IAAI,cAAc,CACtB,uDAAuD,CACxD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;IAEF,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE;YAC/C,IAAI;YACJ,gIAAgI;YAChI,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC1C,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;gBACpD,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE;oBAC9D,OAAO;oBACP,IAAI;iBACL,CAAC,CAAA;YACJ,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE;YAC/C,IAAI;YACJ,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC3C,MAAM,GAAG,CAAC,cAAc,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE;oBAC/D,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;iBACtC,CAAC,CAAA;YACJ,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { ForbiddenError, Server } from '@atproto/xrpc-server'\nimport { ACCESS_FULL, AuthScope } from '../../../../auth-scope.js'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const { entrywayClient } = ctx\n\n const auth = ctx.authVerifier.authorization({\n additional: [AuthScope.Takendown],\n scopes: ACCESS_FULL,\n authorize: () => {\n throw new ForbiddenError(\n 'OAuth credentials are not supported for this endpoint',\n )\n },\n })\n\n if (entrywayClient) {\n server.add(com.atproto.server.deactivateAccount, {\n auth,\n // in the case of entryway, the full flow is deactivateAccount (PDS) -> deactivateAccount (Entryway) -> updateSubjectStatus(PDS)\n handler: async ({ input: { body }, req }) => {\n const { headers } = ctx.entrywayPassthruHeaders(req)\n await entrywayClient.xrpc(com.atproto.server.deactivateAccount, {\n headers,\n body,\n })\n },\n })\n } else {\n server.add(com.atproto.server.deactivateAccount, {\n auth,\n handler: async ({ input: { body }, auth }) => {\n await ctx.accountManager.deactivateAccount(auth.credentials.did, {\n deleteAfter: body.deleteAfter ?? null,\n })\n },\n })\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"deleteAccount.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deleteAccount.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,MAAM,EACP,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAyDvD"}
1
+ {"version":3,"file":"deleteAccount.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deleteAccount.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,MAAM,EACP,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAyEvD"}
@@ -4,47 +4,61 @@ import { OLD_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scr
4
4
  import { com } from '../../../../lexicons/index.js';
5
5
  export default function (server, ctx) {
6
6
  const { entrywayClient } = ctx;
7
- server.add(com.atproto.server.deleteAccount, {
8
- rateLimit: {
9
- durationMs: 5 * MINUTE,
10
- points: 50,
11
- },
12
- handler: async ({ input: { body }, req }) => {
13
- const { did, password, token } = body;
14
- const account = await ctx.accountManager.getAccount(did, {
15
- includeDeactivated: true,
16
- includeTakenDown: true,
17
- });
18
- if (!account) {
19
- throw new InvalidRequestError('account not found');
20
- }
21
- if (entrywayClient) {
7
+ const rateLimit = {
8
+ durationMs: 5 * MINUTE,
9
+ points: 50,
10
+ };
11
+ if (entrywayClient) {
12
+ server.add(com.atproto.server.deleteAccount, {
13
+ rateLimit,
14
+ handler: async ({ input: { body }, req }) => {
15
+ const account = await ctx.accountManager.getAccount(body.did, {
16
+ includeDeactivated: true,
17
+ includeTakenDown: true,
18
+ });
19
+ if (!account) {
20
+ throw new InvalidRequestError('account not found');
21
+ }
22
22
  const { headers } = ctx.entrywayPassthruHeaders(req);
23
23
  await entrywayClient.xrpc(com.atproto.server.deleteAccount, {
24
24
  body,
25
25
  headers,
26
26
  });
27
- return;
28
- }
29
- if (password.length > OLD_PASSWORD_MAX_LENGTH) {
30
- throw new InvalidRequestError('Invalid password length.');
31
- }
32
- const validPass = await ctx.accountManager.verifyAccountPassword(did, password);
33
- if (!validPass) {
34
- throw new AuthRequiredError('Invalid did or password');
35
- }
36
- await ctx.accountManager.assertValidEmailToken(did, 'delete_account', token);
37
- // @NOTE Order matters here: first "unlink" the account by removing it
38
- // from the account manager database ("source of truth"), then notify the
39
- // sequencer, and finally cleanup files from the file system.
40
- await ctx.accountManager.deleteAccount(did);
41
- try {
42
- await ctx.sequencer.sequenceAccountDeletion(did);
43
- }
44
- finally {
45
- await ctx.actorStore.destroy(did);
46
- }
47
- },
48
- });
27
+ },
28
+ });
29
+ }
30
+ else {
31
+ server.add(com.atproto.server.deleteAccount, {
32
+ rateLimit,
33
+ handler: async ({ input: { body } }) => {
34
+ const { did, password, token } = body;
35
+ if (password.length > OLD_PASSWORD_MAX_LENGTH) {
36
+ throw new AuthRequiredError('Password too long. Consider resetting your password.');
37
+ }
38
+ const account = await ctx.accountManager.getAccount(did, {
39
+ includeDeactivated: true,
40
+ includeTakenDown: true,
41
+ });
42
+ if (!account) {
43
+ throw new InvalidRequestError('account not found');
44
+ }
45
+ const validPass = await ctx.accountManager.verifyAccountPassword(did, password);
46
+ if (!validPass) {
47
+ throw new AuthRequiredError('Invalid did or password');
48
+ }
49
+ await ctx.accountManager.assertValidEmailToken(did, 'delete_account', token);
50
+ // @NOTE Order matters here: first "unlink" the account by removing it
51
+ // from the account manager database ("source of truth"), then notify the
52
+ // sequencer, and finally cleanup files from the file system.
53
+ await ctx.accountManager.deleteAccount(did);
54
+ try {
55
+ await ctx.sequencer.sequenceAccountDeletion(did);
56
+ }
57
+ finally {
58
+ await ctx.actorStore.destroy(did);
59
+ }
60
+ },
61
+ });
62
+ }
49
63
  }
50
64
  //# sourceMappingURL=deleteAccount.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"deleteAccount.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deleteAccount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GAEpB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAA;AAEvF,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,EAAE,cAAc,EAAE,GAAG,GAAG,CAAA;IAE9B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE;QAC3C,SAAS,EAAE;YACT,UAAU,EAAE,CAAC,GAAG,MAAM;YACtB,MAAM,EAAE,EAAE;SACX;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;YAC1C,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;YAErC,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,EAAE;gBACvD,kBAAkB,EAAE,IAAI;gBACxB,gBAAgB,EAAE,IAAI;aACvB,CAAC,CAAA;YACF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,mBAAmB,CAAC,mBAAmB,CAAC,CAAA;YACpD,CAAC;YAED,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;gBACpD,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE;oBAC1D,IAAI;oBACJ,OAAO;iBACR,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;gBAC9C,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,CAAC,CAAA;YAC3D,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,qBAAqB,CAC9D,GAAG,EACH,QAAQ,CACT,CAAA;YACD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,iBAAiB,CAAC,yBAAyB,CAAC,CAAA;YACxD,CAAC;YAED,MAAM,GAAG,CAAC,cAAc,CAAC,qBAAqB,CAC5C,GAAG,EACH,gBAAgB,EAChB,KAAK,CACN,CAAA;YAED,sEAAsE;YACtE,yEAAyE;YACzE,6DAA6D;YAC7D,MAAM,GAAG,CAAC,cAAc,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;YAC3C,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,SAAS,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;YAClD,CAAC;oBAAS,CAAC;gBACT,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACnC,CAAC;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { MINUTE } from '@atproto/common'\nimport {\n AuthRequiredError,\n InvalidRequestError,\n Server,\n} from '@atproto/xrpc-server'\nimport { OLD_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scrypt.js'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const { entrywayClient } = ctx\n\n server.add(com.atproto.server.deleteAccount, {\n rateLimit: {\n durationMs: 5 * MINUTE,\n points: 50,\n },\n handler: async ({ input: { body }, req }) => {\n const { did, password, token } = body\n\n const account = await ctx.accountManager.getAccount(did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n if (entrywayClient) {\n const { headers } = ctx.entrywayPassthruHeaders(req)\n await entrywayClient.xrpc(com.atproto.server.deleteAccount, {\n body,\n headers,\n })\n return\n }\n\n if (password.length > OLD_PASSWORD_MAX_LENGTH) {\n throw new InvalidRequestError('Invalid password length.')\n }\n\n const validPass = await ctx.accountManager.verifyAccountPassword(\n did,\n password,\n )\n if (!validPass) {\n throw new AuthRequiredError('Invalid did or password')\n }\n\n await ctx.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 ctx.accountManager.deleteAccount(did)\n try {\n await ctx.sequencer.sequenceAccountDeletion(did)\n } finally {\n await ctx.actorStore.destroy(did)\n }\n },\n })\n}\n"]}
1
+ {"version":3,"file":"deleteAccount.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/deleteAccount.ts"],"names":[],"mappings":"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","sourcesContent":["import { MINUTE } from '@atproto/common'\nimport {\n AuthRequiredError,\n InvalidRequestError,\n MethodRateLimit,\n Server,\n} from '@atproto/xrpc-server'\nimport { OLD_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scrypt.js'\nimport { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const { entrywayClient } = ctx\n\n const rateLimit: MethodRateLimit = {\n durationMs: 5 * MINUTE,\n points: 50,\n }\n\n if (entrywayClient) {\n server.add(com.atproto.server.deleteAccount, {\n rateLimit,\n handler: async ({ input: { body }, req }) => {\n const account = await ctx.accountManager.getAccount(body.did, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n if (!account) {\n throw new InvalidRequestError('account not found')\n }\n\n const { headers } = ctx.entrywayPassthruHeaders(req)\n await entrywayClient.xrpc(com.atproto.server.deleteAccount, {\n body,\n headers,\n })\n },\n })\n } else {\n server.add(com.atproto.server.deleteAccount, {\n rateLimit,\n handler: async ({ input: { body } }) => {\n const { did, password, token } = body\n\n if (password.length > OLD_PASSWORD_MAX_LENGTH) {\n throw new AuthRequiredError(\n 'Password too long. Consider resetting your password.',\n )\n }\n\n const account = await ctx.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 ctx.accountManager.verifyAccountPassword(\n did,\n password,\n )\n if (!validPass) {\n throw new AuthRequiredError('Invalid did or password')\n }\n\n await ctx.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 ctx.accountManager.deleteAccount(did)\n try {\n await ctx.sequencer.sequenceAccountDeletion(did)\n } finally {\n await ctx.actorStore.destroy(did)\n }\n },\n })\n }\n}\n"]}
@@ -1,11 +1,30 @@
1
- import { DidDocument } from '@atproto/identity';
1
+ import * as plc from '@did-plc/lib';
2
+ import * as crypto from '@atproto/crypto';
3
+ import { DidDocument, IdResolver } from '@atproto/identity';
4
+ import { ActorStore } from '../../../../actor-store/actor-store.js';
2
5
  import { ServerConfig } from '../../../../config/index.js';
3
- import { AppContext } from '../../../../context.js';
4
6
  export declare const genInvCode: (cfg: ServerConfig) => string;
5
7
  export declare const genInvCodes: (cfg: ServerConfig, count: number) => string[];
6
8
  export declare const getRandomToken: () => string;
7
- export declare const safeResolveDidDoc: (ctx: AppContext, did: string, forceRefresh?: boolean) => Promise<DidDocument | undefined>;
8
- export declare const didDocForSession: (ctx: AppContext, did: string, forceRefresh?: boolean) => Promise<DidDocument | undefined>;
9
- export declare const isValidDidDocForService: (ctx: AppContext, did: string) => Promise<boolean>;
10
- export declare const assertValidDidDocumentForService: (ctx: AppContext, did: string) => Promise<void>;
9
+ export declare const safeResolveDidDoc: (ctx: {
10
+ idResolver: IdResolver;
11
+ }, did: string, forceRefresh?: boolean) => Promise<DidDocument | undefined>;
12
+ export declare const didDocForSession: (ctx: {
13
+ idResolver: IdResolver;
14
+ cfg: ServerConfig;
15
+ }, did: string, forceRefresh?: boolean) => Promise<DidDocument | undefined>;
16
+ export declare const isValidDidDocForService: (ctx: {
17
+ plcClient: plc.Client;
18
+ idResolver: IdResolver;
19
+ cfg: ServerConfig;
20
+ plcRotationKey: crypto.Keypair;
21
+ actorStore: ActorStore;
22
+ }, did: string) => Promise<boolean>;
23
+ export declare const assertValidDidDocumentForService: (ctx: {
24
+ plcClient: plc.Client;
25
+ idResolver: IdResolver;
26
+ cfg: ServerConfig;
27
+ plcRotationKey: crypto.Keypair;
28
+ actorStore: ActorStore;
29
+ }, did: string) => Promise<void>;
11
30
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/util.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAOnD,eAAO,MAAM,UAAU,QAAS,YAAY,KAAG,MAE9C,CAAA;AAED,eAAO,MAAM,WAAW,QAAS,YAAY,SAAS,MAAM,KAAG,MAAM,EAMpE,CAAA;AAGD,eAAO,MAAM,cAAc,cAG1B,CAAA;AAED,eAAO,MAAM,iBAAiB,QACvB,UAAU,OACV,MAAM,iBACI,OAAO,KACrB,OAAO,CAAC,WAAW,GAAG,SAAS,CAOjC,CAAA;AAED,eAAO,MAAM,gBAAgB,QACtB,UAAU,OACV,MAAM,iBACI,OAAO,KACrB,OAAO,CAAC,WAAW,GAAG,SAAS,CAGjC,CAAA;AAED,eAAO,MAAM,uBAAuB,QAC7B,UAAU,OACV,MAAM,KACV,OAAO,CAAC,OAAO,CAOjB,CAAA;AAED,eAAO,MAAM,gCAAgC,QACtC,UAAU,OACV,MAAM,kBAmBZ,CAAA"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AAEnC,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAO1D,eAAO,MAAM,UAAU,QAAS,YAAY,KAAG,MAE9C,CAAA;AAED,eAAO,MAAM,WAAW,QAAS,YAAY,SAAS,MAAM,KAAG,MAAM,EAMpE,CAAA;AAGD,eAAO,MAAM,cAAc,cAG1B,CAAA;AAED,eAAO,MAAM,iBAAiB,QACvB;IAAE,UAAU,EAAE,UAAU,CAAA;CAAE,OAC1B,MAAM,iBACI,OAAO,KACrB,OAAO,CAAC,WAAW,GAAG,SAAS,CAOjC,CAAA;AAED,eAAO,MAAM,gBAAgB,QACtB;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,YAAY,CAAA;CAAE,OAC7C,MAAM,iBACI,OAAO,KACrB,OAAO,CAAC,WAAW,GAAG,SAAS,CAGjC,CAAA;AAED,eAAO,MAAM,uBAAuB,QAC7B;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,CAAA;IACrB,UAAU,EAAE,UAAU,CAAA;IACtB,GAAG,EAAE,YAAY,CAAA;IACjB,cAAc,EAAE,MAAM,CAAC,OAAO,CAAA;IAC9B,UAAU,EAAE,UAAU,CAAA;CACvB,OACI,MAAM,KACV,OAAO,CAAC,OAAO,CAOjB,CAAA;AAED,eAAO,MAAM,gCAAgC,QACtC;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,CAAA;IACrB,UAAU,EAAE,UAAU,CAAA;IACtB,GAAG,EAAE,YAAY,CAAA;IACjB,cAAc,EAAE,MAAM,CAAC,OAAO,CAAA;IAC9B,UAAU,EAAE,UAAU,CAAA;CACvB,OACI,MAAM,kBAmBZ,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAG1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAElD,mDAAmD;AACnD,gEAAgE;AAChE,2BAA2B;AAC3B,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAiB,EAAU,EAAE;IACtD,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,cAAc,EAAE,CAAA;AAC3E,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAiB,EAAE,KAAa,EAAY,EAAE;IACxE,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,mDAAmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACxD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACrD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,GAAe,EACf,GAAW,EACX,YAAsB,EACY,EAAE;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;QAClE,OAAO,MAAM,IAAI,SAAS,CAAA;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,2BAA2B,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,GAAe,EACf,GAAW,EACX,YAAsB,EACY,EAAE;IACpC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,uBAAuB;QAAE,OAAM;IACrD,OAAO,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,CAAC,CAAA;AAClD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,GAAe,EACf,GAAW,EACO,EAAE;IACpB,IAAI,CAAC;QACH,MAAM,gCAAgC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAChD,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gCAAgC,GAAG,KAAK,EACnD,GAAe,EACf,GAAW,EACX,EAAE;IACF,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;QACzD,MAAM,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE;YACrC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ;YACvD,UAAU,EAAE,QAAQ,CAAC,mBAAmB,CAAC,SAAS,CAAC;YACnD,YAAY,EAAE,QAAQ,CAAC,YAAY;SACpC,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,mBAAmB,CAAC,uBAAuB,CAAC,CAAA;QACxD,CAAC;QACD,MAAM,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE;YACrC,WAAW,EAAE,cAAc,CAAC,QAAQ,CAAC;YACrC,UAAU,EAAE,gBAAgB,CAAC,QAAQ,CAAC;SACvC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,KAAK,EAClC,GAAe,EACf,GAAW,EACX,QAIC,EACD,EAAE;IACF,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAA;IAE1D,MAAM,cAAc,GAClB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,EAAE,CAAA;IAC9D,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,mBAAmB,CAC3B,kDAAkD,CACnD,CAAA;IACH,CAAC;IAED,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC9D,MAAM,IAAI,mBAAmB,CAC3B,yEAAyE,CAC1E,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACjD,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;QAChD,MAAM,IAAI,mBAAmB,CAC3B,sEAAsE,CACvE,CAAA;IACH,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { getPdsEndpoint, getSigningDidKey } from '@atproto/common'\nimport * as crypto from '@atproto/crypto'\nimport { DidDocument } from '@atproto/identity'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { ServerConfig } from '../../../../config/index.js'\nimport { AppContext } from '../../../../context.js'\nimport { httpLogger } from '../../../../logger.js'\n\n// generate an invite code preceded by the hostname\n// with '.'s replaced by '-'s so it is not mistakable for a link\n// ex: bsky-app-abc23-567xy\n// regex: bsky-app-[a-z2-7]{5}-[a-z2-7]{5}\nexport const genInvCode = (cfg: ServerConfig): string => {\n return cfg.service.hostname.replaceAll('.', '-') + '-' + getRandomToken()\n}\n\nexport const genInvCodes = (cfg: ServerConfig, count: number): string[] => {\n const codes: string[] = []\n for (let i = 0; i < count; i++) {\n codes.push(genInvCode(cfg))\n }\n return codes\n}\n\n// Formatted xxxxx-xxxxx where digits are in base32\nexport const getRandomToken = () => {\n const token = crypto.randomStr(8, 'base32').slice(0, 10)\n return token.slice(0, 5) + '-' + token.slice(5, 10)\n}\n\nexport const safeResolveDidDoc = async (\n ctx: AppContext,\n did: string,\n forceRefresh?: boolean,\n): Promise<DidDocument | undefined> => {\n try {\n const didDoc = await ctx.idResolver.did.resolve(did, forceRefresh)\n return didDoc ?? undefined\n } catch (err) {\n httpLogger.warn({ err, did }, 'failed to resolve did doc')\n }\n}\n\nexport const didDocForSession = async (\n ctx: AppContext,\n did: string,\n forceRefresh?: boolean,\n): Promise<DidDocument | undefined> => {\n if (!ctx.cfg.identity.enableDidDocWithSession) return\n return safeResolveDidDoc(ctx, did, forceRefresh)\n}\n\nexport const isValidDidDocForService = async (\n ctx: AppContext,\n did: string,\n): Promise<boolean> => {\n try {\n await assertValidDidDocumentForService(ctx, did)\n return true\n } catch {\n return false\n }\n}\n\nexport const assertValidDidDocumentForService = async (\n ctx: AppContext,\n did: string,\n) => {\n if (did.startsWith('did:plc')) {\n const resolved = await ctx.plcClient.getDocumentData(did)\n await assertValidDocContents(ctx, did, {\n pdsEndpoint: resolved.services['atproto_pds']?.endpoint,\n signingKey: resolved.verificationMethods['atproto'],\n rotationKeys: resolved.rotationKeys,\n })\n } else {\n const resolved = await ctx.idResolver.did.resolve(did, true)\n if (!resolved) {\n throw new InvalidRequestError('Could not resolve DID')\n }\n await assertValidDocContents(ctx, did, {\n pdsEndpoint: getPdsEndpoint(resolved),\n signingKey: getSigningDidKey(resolved),\n })\n }\n}\n\nconst assertValidDocContents = async (\n ctx: AppContext,\n did: string,\n contents: {\n signingKey?: string\n pdsEndpoint?: string\n rotationKeys?: string[]\n },\n) => {\n const { signingKey, pdsEndpoint, rotationKeys } = contents\n\n const plcRotationKey =\n ctx.cfg.entryway?.plcRotationKey ?? ctx.plcRotationKey.did()\n if (rotationKeys !== undefined && !rotationKeys.includes(plcRotationKey)) {\n throw new InvalidRequestError(\n 'Server rotation key not included in PLC DID data',\n )\n }\n\n if (!pdsEndpoint || pdsEndpoint !== ctx.cfg.service.publicUrl) {\n throw new InvalidRequestError(\n 'DID document atproto_pds service endpoint does not match PDS public url',\n )\n }\n\n const keypair = await ctx.actorStore.keypair(did)\n if (!signingKey || signingKey !== keypair.did()) {\n throw new InvalidRequestError(\n 'DID document verification method does not match expected signing key',\n )\n }\n}\n"]}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/server/util.ts"],"names":[],"mappings":"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","sourcesContent":["import * as plc from '@did-plc/lib'\nimport { getPdsEndpoint, getSigningDidKey } from '@atproto/common'\nimport * as crypto from '@atproto/crypto'\nimport { DidDocument, IdResolver } from '@atproto/identity'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { ActorStore } from '../../../../actor-store/actor-store.js'\nimport { ServerConfig } from '../../../../config/index.js'\nimport { httpLogger } from '../../../../logger.js'\n\n// generate an invite code preceded by the hostname\n// with '.'s replaced by '-'s so it is not mistakable for a link\n// ex: bsky-app-abc23-567xy\n// regex: bsky-app-[a-z2-7]{5}-[a-z2-7]{5}\nexport const genInvCode = (cfg: ServerConfig): string => {\n return cfg.service.hostname.replaceAll('.', '-') + '-' + getRandomToken()\n}\n\nexport const genInvCodes = (cfg: ServerConfig, count: number): string[] => {\n const codes: string[] = []\n for (let i = 0; i < count; i++) {\n codes.push(genInvCode(cfg))\n }\n return codes\n}\n\n// Formatted xxxxx-xxxxx where digits are in base32\nexport const getRandomToken = () => {\n const token = crypto.randomStr(8, 'base32').slice(0, 10)\n return token.slice(0, 5) + '-' + token.slice(5, 10)\n}\n\nexport const safeResolveDidDoc = async (\n ctx: { idResolver: IdResolver },\n did: string,\n forceRefresh?: boolean,\n): Promise<DidDocument | undefined> => {\n try {\n const didDoc = await ctx.idResolver.did.resolve(did, forceRefresh)\n return didDoc ?? undefined\n } catch (err) {\n httpLogger.warn({ err, did }, 'failed to resolve did doc')\n }\n}\n\nexport const didDocForSession = async (\n ctx: { idResolver: IdResolver; cfg: ServerConfig },\n did: string,\n forceRefresh?: boolean,\n): Promise<DidDocument | undefined> => {\n if (!ctx.cfg.identity.enableDidDocWithSession) return\n return safeResolveDidDoc(ctx, did, forceRefresh)\n}\n\nexport const isValidDidDocForService = async (\n ctx: {\n plcClient: plc.Client\n idResolver: IdResolver\n cfg: ServerConfig\n plcRotationKey: crypto.Keypair\n actorStore: ActorStore\n },\n did: string,\n): Promise<boolean> => {\n try {\n await assertValidDidDocumentForService(ctx, did)\n return true\n } catch {\n return false\n }\n}\n\nexport const assertValidDidDocumentForService = async (\n ctx: {\n plcClient: plc.Client\n idResolver: IdResolver\n cfg: ServerConfig\n plcRotationKey: crypto.Keypair\n actorStore: ActorStore\n },\n did: string,\n) => {\n if (did.startsWith('did:plc')) {\n const resolved = await ctx.plcClient.getDocumentData(did)\n await assertValidDocContents(ctx, did, {\n pdsEndpoint: resolved.services['atproto_pds']?.endpoint,\n signingKey: resolved.verificationMethods['atproto'],\n rotationKeys: resolved.rotationKeys,\n })\n } else {\n const resolved = await ctx.idResolver.did.resolve(did, true)\n if (!resolved) {\n throw new InvalidRequestError('Could not resolve DID')\n }\n await assertValidDocContents(ctx, did, {\n pdsEndpoint: getPdsEndpoint(resolved),\n signingKey: getSigningDidKey(resolved),\n })\n }\n}\n\nconst assertValidDocContents = async (\n ctx: {\n cfg: ServerConfig\n plcRotationKey: crypto.Keypair\n actorStore: ActorStore\n },\n did: string,\n contents: {\n signingKey?: string\n pdsEndpoint?: string\n rotationKeys?: string[]\n },\n) => {\n const { signingKey, pdsEndpoint, rotationKeys } = contents\n\n const plcRotationKey =\n ctx.cfg.entryway?.plcRotationKey ?? ctx.plcRotationKey.did()\n if (rotationKeys !== undefined && !rotationKeys.includes(plcRotationKey)) {\n throw new InvalidRequestError(\n 'Server rotation key not included in PLC DID data',\n )\n }\n\n if (!pdsEndpoint || pdsEndpoint !== ctx.cfg.service.publicUrl) {\n throw new InvalidRequestError(\n 'DID document atproto_pds service endpoint does not match PDS public url',\n )\n }\n\n const keypair = await ctx.actorStore.keypair(did)\n if (!signingKey || signingKey !== keypair.did()) {\n throw new InvalidRequestError(\n 'DID document verification method does not match expected signing key',\n )\n }\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { BrandingInput as BrandingConfig, HcaptchaConfig } from '@atproto/oauth-provider';
2
+ import { DidString } from '@atproto/syntax';
2
3
  import { ServerEnvironment } from './env.js';
3
4
  export type { BrandingConfig };
4
5
  export declare const envToCfg: (env: ServerEnvironment) => ServerConfig;
@@ -29,7 +30,7 @@ export type ServiceConfig = {
29
30
  port: number;
30
31
  hostname: string;
31
32
  publicUrl: string;
32
- did: string;
33
+ did: DidString;
33
34
  version?: string;
34
35
  privacyPolicyUrl?: string;
35
36
  termsOfServiceUrl?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import assert from 'node:assert';
2
2
  import path from 'node:path';
3
3
  import { DAY, HOUR, SECOND } from '@atproto/common';
4
- import { ensureValidDid } from '@atproto/syntax';
4
+ import { ensureValidDid, isValidDid } from '@atproto/syntax';
5
5
  // off-config but still from env:
6
6
  // logging: LOG_LEVEL, LOG_SYSTEMS, LOG_ENABLED, LOG_DESTINATION
7
7
  export const envToCfg = (env) => {
@@ -11,6 +11,9 @@ export const envToCfg = (env) => {
11
11
  ? `http://localhost:${port}`
12
12
  : `https://${hostname}`;
13
13
  const did = env.serviceDid ?? `did:web:${hostname}`;
14
+ if (!isValidDid(did)) {
15
+ throw new Error(`Invalid service DID: ${did}`);
16
+ }
14
17
  const serviceCfg = {
15
18
  port,
16
19
  hostname,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport path from 'node:path'\nimport { DAY, HOUR, SECOND } from '@atproto/common'\nimport {\n BrandingInput as BrandingConfig,\n HcaptchaConfig,\n} from '@atproto/oauth-provider'\nimport { ensureValidDid } from '@atproto/syntax'\nimport { ServerEnvironment } from './env.js'\n\nexport type { BrandingConfig }\n\n// off-config but still from env:\n// logging: LOG_LEVEL, LOG_SYSTEMS, LOG_ENABLED, LOG_DESTINATION\n\nexport const envToCfg = (env: ServerEnvironment): ServerConfig => {\n const port = env.port ?? 2583\n const hostname = env.hostname ?? 'localhost'\n const publicUrl =\n hostname === 'localhost'\n ? `http://localhost:${port}`\n : `https://${hostname}`\n const did = env.serviceDid ?? `did:web:${hostname}`\n const serviceCfg: ServerConfig['service'] = {\n port,\n hostname,\n publicUrl,\n did,\n version: env.version, // default?\n privacyPolicyUrl: env.privacyPolicyUrl,\n termsOfServiceUrl: env.termsOfServiceUrl,\n contactEmailAddress: env.contactEmailAddress,\n acceptingImports: env.acceptingImports ?? true,\n maxImportSize: env.maxImportSize,\n blobUploadLimit: env.blobUploadLimit ?? 5 * 1024 * 1024, // 5mb\n devMode: env.devMode ?? false,\n }\n\n const dbLoc = (name: string) => {\n return env.dataDirectory ? path.join(env.dataDirectory, name) : name\n }\n\n const disableWalAutoCheckpoint = env.disableWalAutoCheckpoint ?? false\n\n const dbCfg: ServerConfig['db'] = {\n accountDbLoc: env.accountDbLocation ?? dbLoc('account.sqlite'),\n sequencerDbLoc: env.sequencerDbLocation ?? dbLoc('sequencer.sqlite'),\n didCacheDbLoc: env.didCacheDbLocation ?? dbLoc('did_cache.sqlite'),\n disableWalAutoCheckpoint,\n }\n\n const actorStoreCfg: ServerConfig['actorStore'] = {\n directory: env.actorStoreDirectory ?? dbLoc('actors'),\n cacheSize: env.actorStoreCacheSize ?? 100,\n disableWalAutoCheckpoint,\n }\n\n let blobstoreCfg: ServerConfig['blobstore']\n if (env.blobstoreS3Bucket && env.blobstoreDiskLocation) {\n throw new Error('Cannot set both S3 and disk blobstore env vars')\n }\n if (env.blobstoreS3Bucket) {\n blobstoreCfg = {\n provider: 's3',\n bucket: env.blobstoreS3Bucket,\n uploadTimeoutMs: env.blobstoreS3UploadTimeoutMs || 20000,\n region: env.blobstoreS3Region,\n endpoint: env.blobstoreS3Endpoint,\n forcePathStyle: env.blobstoreS3ForcePathStyle,\n }\n if (env.blobstoreS3AccessKeyId || env.blobstoreS3SecretAccessKey) {\n if (!env.blobstoreS3AccessKeyId || !env.blobstoreS3SecretAccessKey) {\n throw new Error(\n 'Must specify both S3 access key id and secret access key blobstore env vars',\n )\n }\n blobstoreCfg.credentials = {\n accessKeyId: env.blobstoreS3AccessKeyId,\n secretAccessKey: env.blobstoreS3SecretAccessKey,\n }\n }\n } else if (env.blobstoreDiskLocation) {\n blobstoreCfg = {\n provider: 'disk',\n location: env.blobstoreDiskLocation,\n tempLocation: env.blobstoreDiskTmpLocation,\n }\n } else {\n throw new Error('Must configure either S3 or disk blobstore')\n }\n\n let serviceHandleDomains: string[]\n if (env.serviceHandleDomains && env.serviceHandleDomains.length > 0) {\n serviceHandleDomains = env.serviceHandleDomains\n } else {\n if (hostname === 'localhost') {\n serviceHandleDomains = ['.test']\n } else {\n serviceHandleDomains = [`.${hostname}`]\n }\n }\n const invalidDomain = serviceHandleDomains.find(\n (domain) => domain.length < 1 || !domain.startsWith('.'),\n )\n if (invalidDomain) {\n throw new Error(`Invalid handle domain: ${invalidDomain}`)\n }\n\n const identityCfg: ServerConfig['identity'] = {\n plcUrl: env.didPlcUrl ?? 'https://plc.directory',\n cacheMaxTTL: env.didCacheMaxTTL ?? DAY,\n cacheStaleTTL: env.didCacheStaleTTL ?? HOUR,\n resolverTimeout: env.resolverTimeout ?? 3 * SECOND,\n recoveryDidKey: env.recoveryDidKey ?? null,\n serviceHandleDomains,\n handleBackupNameservers: env.handleBackupNameservers,\n enableDidDocWithSession: !!env.enableDidDocWithSession,\n }\n\n let entrywayCfg: ServerConfig['entryway'] = null\n if (env.entrywayUrl) {\n assert(\n env.entrywayJwtVerifyKeyK256PublicKeyHex &&\n env.entrywayPlcRotationKey &&\n env.entrywayDid,\n 'if entryway url is configured, must include all required entryway configuration',\n )\n entrywayCfg = {\n url: env.entrywayUrl,\n did: env.entrywayDid,\n jwtPublicKeyHex: env.entrywayJwtVerifyKeyK256PublicKeyHex,\n plcRotationKey: env.entrywayPlcRotationKey,\n }\n }\n\n // default to being required if left undefined\n const invitesCfg: ServerConfig['invites'] =\n env.inviteRequired === false\n ? {\n required: false,\n }\n : {\n required: true,\n interval: env.inviteInterval ?? null,\n epoch: env.inviteEpoch ?? 0,\n }\n\n let emailCfg: ServerConfig['email']\n if (!env.emailFromAddress && !env.emailSmtpUrl) {\n emailCfg = null\n } else {\n if (!env.emailFromAddress || !env.emailSmtpUrl) {\n throw new Error(\n 'Partial email config, must set both emailFromAddress and emailSmtpUrl',\n )\n }\n emailCfg = {\n smtpUrl: env.emailSmtpUrl,\n fromAddress: env.emailFromAddress,\n disableConfirmationLink: env.emailDisableConfirmationLink ?? false,\n }\n }\n\n let moderationEmailCfg: ServerConfig['moderationEmail']\n if (!env.moderationEmailAddress && !env.moderationEmailSmtpUrl) {\n moderationEmailCfg = null\n } else {\n if (!env.moderationEmailAddress || !env.moderationEmailSmtpUrl) {\n throw new Error(\n 'Partial moderation email config, must set both emailFromAddress and emailSmtpUrl',\n )\n }\n moderationEmailCfg = {\n smtpUrl: env.moderationEmailSmtpUrl,\n fromAddress: env.moderationEmailAddress,\n disableConfirmationLink: false,\n }\n }\n\n const subscriptionCfg: ServerConfig['subscription'] = {\n maxBuffer: env.maxSubscriptionBuffer ?? 500,\n repoBackfillLimitMs: env.repoBackfillLimitMs ?? DAY,\n }\n\n let bskyAppViewCfg: ServerConfig['bskyAppView'] = null\n if (env.bskyAppViewUrl) {\n assert(\n env.bskyAppViewDid,\n 'if bsky appview service url is configured, must configure its did as well.',\n )\n bskyAppViewCfg = {\n url: env.bskyAppViewUrl,\n did: env.bskyAppViewDid,\n cdnUrlPattern: env.bskyAppViewCdnUrlPattern,\n }\n }\n\n let modServiceCfg: ServerConfig['modService'] = null\n if (env.modServiceUrl) {\n assert(\n env.modServiceDid,\n 'if mod service url is configured, must configure its did as well.',\n )\n modServiceCfg = {\n url: env.modServiceUrl,\n did: env.modServiceDid,\n }\n }\n\n let reportServiceCfg: ServerConfig['reportService'] = null\n if (env.reportServiceUrl) {\n assert(\n env.reportServiceDid,\n 'if report service url is configured, must configure its did as well.',\n )\n reportServiceCfg = {\n url: env.reportServiceUrl,\n did: env.reportServiceDid,\n }\n }\n\n // if there's a mod service, default report service into it\n if (modServiceCfg && !reportServiceCfg) {\n reportServiceCfg = modServiceCfg\n }\n\n const redisCfg: ServerConfig['redis'] = env.redisScratchAddress\n ? {\n address: env.redisScratchAddress,\n password: env.redisScratchPassword,\n }\n : null\n\n const rateLimitsCfg: ServerConfig['rateLimits'] = env.rateLimitsEnabled\n ? {\n enabled: true,\n bypassKey: env.rateLimitBypassKey,\n bypassIps: env.rateLimitBypassIps?.map((ipOrCidr) =>\n ipOrCidr.split('/')[0]?.trim(),\n ),\n }\n : { enabled: false }\n\n const crawlersCfg: ServerConfig['crawlers'] = env.crawlers ?? []\n\n const fetchCfg: ServerConfig['fetch'] = {\n disableSsrfProtection: env.disableSsrfProtection ?? env.devMode ?? false,\n maxResponseSize: env.fetchMaxResponseSize ?? 512 * 1024, // 512kb\n }\n\n const proxyCfg: ServerConfig['proxy'] = {\n disableSsrfProtection: env.disableSsrfProtection ?? env.devMode ?? false,\n allowHTTP2: env.proxyAllowHTTP2 ?? false,\n headersTimeout: env.proxyHeadersTimeout ?? 10e3,\n bodyTimeout: env.proxyBodyTimeout ?? 30e3,\n maxResponseSize: env.proxyMaxResponseSize ?? 10 * 1024 * 1024, // 10mb\n maxRetries:\n env.proxyMaxRetries != null && env.proxyMaxRetries > 0\n ? env.proxyMaxRetries\n : 0,\n preferCompressed: env.proxyPreferCompressed ?? false,\n }\n\n const brandingCfg = {\n name: env.serviceName ?? `${hostname} PDS`,\n logo: env.logoUrl,\n colors: {\n light: env.lightColor,\n dark: env.darkColor,\n\n contrastSaturation: env.contrastSaturation,\n\n primary: env.primaryColor,\n primaryContrast: env.primaryColorContrast,\n primaryHue: env.primaryColorHue,\n\n error: env.errorColor,\n errorContrast: env.errorColorContrast,\n errorHue: env.errorColorHue,\n\n warning: env.warningColor,\n warningContrast: env.warningColorContrast,\n warningHue: env.warningColorHue,\n\n info: env.infoColor,\n infoContrast: env.infoColorContrast,\n infoHue: env.infoColorHue,\n\n success: env.successColor,\n successContrast: env.successColorContrast,\n successHue: env.successColorHue,\n },\n links: [\n {\n title: { en: 'Home', fr: 'Accueil' },\n href: env.homeUrl,\n rel: 'canonical' as const, // Prevents login page from being indexed\n },\n {\n title: { en: 'Terms of Service' },\n href: env.termsOfServiceUrl,\n rel: 'terms-of-service' as const,\n },\n {\n title: { en: 'Privacy Policy' },\n href: env.privacyPolicyUrl,\n rel: 'privacy-policy' as const,\n },\n {\n title: { en: 'Support' },\n href: env.supportUrl,\n rel: 'help' as const,\n },\n ].filter(\n <T extends { href?: string }>(f: T): f is T & { href: string } =>\n f.href != null && f.href !== '',\n ),\n }\n\n const oauthCfg: ServerConfig['oauth'] = entrywayCfg\n ? {\n issuer: entrywayCfg.url,\n provider: undefined,\n }\n : {\n issuer: serviceCfg.publicUrl,\n provider: {\n hcaptcha:\n env.hcaptchaSiteKey &&\n env.hcaptchaSecretKey &&\n env.hcaptchaTokenSalt\n ? {\n siteKey: env.hcaptchaSiteKey,\n secretKey: env.hcaptchaSecretKey,\n tokenSalt: env.hcaptchaTokenSalt,\n }\n : undefined,\n branding: brandingCfg,\n trustedClients: env.trustedOAuthClients,\n },\n }\n\n const lexiconCfg: LexiconResolverConfig = {}\n\n if (env.lexiconDidAuthority != null) {\n ensureValidDid(env.lexiconDidAuthority)\n lexiconCfg.didAuthority = env.lexiconDidAuthority\n }\n\n return {\n service: serviceCfg,\n db: dbCfg,\n actorStore: actorStoreCfg,\n blobstore: blobstoreCfg,\n identity: identityCfg,\n entryway: entrywayCfg,\n invites: invitesCfg,\n email: emailCfg,\n moderationEmail: moderationEmailCfg,\n subscription: subscriptionCfg,\n bskyAppView: bskyAppViewCfg,\n modService: modServiceCfg,\n reportService: reportServiceCfg,\n redis: redisCfg,\n rateLimits: rateLimitsCfg,\n crawlers: crawlersCfg,\n fetch: fetchCfg,\n lexicon: lexiconCfg,\n proxy: proxyCfg,\n branding: brandingCfg,\n oauth: oauthCfg,\n }\n}\n\nexport type ServerConfig = {\n service: ServiceConfig\n db: DatabaseConfig\n actorStore: ActorStoreConfig\n blobstore: S3BlobstoreConfig | DiskBlobstoreConfig\n identity: IdentityConfig\n entryway: EntrywayConfig | null\n invites: InvitesConfig\n email: EmailConfig | null\n moderationEmail: EmailConfig | null\n subscription: SubscriptionConfig\n bskyAppView: BksyAppViewConfig | null\n modService: ModServiceConfig | null\n reportService: ReportServiceConfig | null\n redis: RedisScratchConfig | null\n rateLimits: RateLimitsConfig\n crawlers: string[]\n fetch: FetchConfig\n proxy: ProxyConfig\n branding: BrandingConfig\n oauth: OAuthConfig\n lexicon: LexiconResolverConfig\n}\n\nexport type ServiceConfig = {\n port: number\n hostname: string\n publicUrl: string\n did: string\n version?: string\n privacyPolicyUrl?: string\n termsOfServiceUrl?: string\n acceptingImports: boolean\n maxImportSize?: number\n blobUploadLimit: number\n contactEmailAddress?: string\n devMode: boolean\n}\n\nexport type DatabaseConfig = {\n accountDbLoc: string\n sequencerDbLoc: string\n didCacheDbLoc: string\n disableWalAutoCheckpoint: boolean\n}\n\nexport type ActorStoreConfig = {\n directory: string\n cacheSize: number\n disableWalAutoCheckpoint: boolean\n}\n\nexport type S3BlobstoreConfig = {\n provider: 's3'\n bucket: string\n region?: string\n endpoint?: string\n forcePathStyle?: boolean\n uploadTimeoutMs?: number\n credentials?: {\n accessKeyId: string\n secretAccessKey: string\n }\n}\n\nexport type DiskBlobstoreConfig = {\n provider: 'disk'\n location: string\n tempLocation?: string\n}\n\nexport type IdentityConfig = {\n plcUrl: string\n resolverTimeout: number\n cacheStaleTTL: number\n cacheMaxTTL: number\n recoveryDidKey: string | null\n serviceHandleDomains: string[]\n handleBackupNameservers?: string[]\n enableDidDocWithSession: boolean\n}\n\nexport type EntrywayConfig = {\n url: string\n did: string\n jwtPublicKeyHex: string\n plcRotationKey: string\n}\n\nexport type FetchConfig = {\n disableSsrfProtection: boolean\n maxResponseSize: number\n}\n\nexport type ProxyConfig = {\n disableSsrfProtection: boolean\n allowHTTP2: boolean\n headersTimeout: number\n bodyTimeout: number\n maxResponseSize: number\n maxRetries: number\n\n /**\n * When proxying requests that might get intercepted (for read-after-write) we\n * negotiate the encoding based on the client's preferences. We will however\n * use or own weights in order to be able to better control if the PDS will\n * need to perform content decoding. This settings allows to prefer compressed\n * content over uncompressed one.\n */\n preferCompressed: boolean\n}\n\nexport type OAuthConfig = {\n issuer: string\n provider?: {\n hcaptcha?: HcaptchaConfig\n branding: BrandingConfig\n trustedClients?: string[]\n }\n}\n\nexport type LexiconResolverConfig = {\n didAuthority?: `did:${string}:${string}`\n}\n\nexport type InvitesConfig =\n | {\n required: true\n interval: number | null\n epoch: number\n }\n | {\n required: false\n }\n\nexport type EmailConfig = {\n smtpUrl: string\n fromAddress: string\n disableConfirmationLink: boolean\n}\n\nexport type SubscriptionConfig = {\n maxBuffer: number\n repoBackfillLimitMs: number\n}\n\nexport type RedisScratchConfig = {\n address: string\n password?: string\n}\n\nexport type RateLimitsConfig =\n | {\n enabled: true\n bypassKey?: string\n bypassIps?: string[]\n }\n | { enabled: false }\n\nexport type BksyAppViewConfig = {\n url: string\n did: string\n cdnUrlPattern?: string\n}\n\nexport type ModServiceConfig = {\n url: string\n did: string\n}\n\nexport type ReportServiceConfig = {\n url: string\n did: string\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport path from 'node:path'\nimport { DAY, HOUR, SECOND } from '@atproto/common'\nimport {\n BrandingInput as BrandingConfig,\n HcaptchaConfig,\n} from '@atproto/oauth-provider'\nimport { DidString, ensureValidDid, isValidDid } from '@atproto/syntax'\nimport { ServerEnvironment } from './env.js'\n\nexport type { BrandingConfig }\n\n// off-config but still from env:\n// logging: LOG_LEVEL, LOG_SYSTEMS, LOG_ENABLED, LOG_DESTINATION\n\nexport const envToCfg = (env: ServerEnvironment): ServerConfig => {\n const port = env.port ?? 2583\n const hostname = env.hostname ?? 'localhost'\n const publicUrl =\n hostname === 'localhost'\n ? `http://localhost:${port}`\n : `https://${hostname}`\n const did = env.serviceDid ?? `did:web:${hostname}`\n\n if (!isValidDid(did)) {\n throw new Error(`Invalid service DID: ${did}`)\n }\n\n const serviceCfg: ServerConfig['service'] = {\n port,\n hostname,\n publicUrl,\n did,\n version: env.version, // default?\n privacyPolicyUrl: env.privacyPolicyUrl,\n termsOfServiceUrl: env.termsOfServiceUrl,\n contactEmailAddress: env.contactEmailAddress,\n acceptingImports: env.acceptingImports ?? true,\n maxImportSize: env.maxImportSize,\n blobUploadLimit: env.blobUploadLimit ?? 5 * 1024 * 1024, // 5mb\n devMode: env.devMode ?? false,\n }\n\n const dbLoc = (name: string) => {\n return env.dataDirectory ? path.join(env.dataDirectory, name) : name\n }\n\n const disableWalAutoCheckpoint = env.disableWalAutoCheckpoint ?? false\n\n const dbCfg: ServerConfig['db'] = {\n accountDbLoc: env.accountDbLocation ?? dbLoc('account.sqlite'),\n sequencerDbLoc: env.sequencerDbLocation ?? dbLoc('sequencer.sqlite'),\n didCacheDbLoc: env.didCacheDbLocation ?? dbLoc('did_cache.sqlite'),\n disableWalAutoCheckpoint,\n }\n\n const actorStoreCfg: ServerConfig['actorStore'] = {\n directory: env.actorStoreDirectory ?? dbLoc('actors'),\n cacheSize: env.actorStoreCacheSize ?? 100,\n disableWalAutoCheckpoint,\n }\n\n let blobstoreCfg: ServerConfig['blobstore']\n if (env.blobstoreS3Bucket && env.blobstoreDiskLocation) {\n throw new Error('Cannot set both S3 and disk blobstore env vars')\n }\n if (env.blobstoreS3Bucket) {\n blobstoreCfg = {\n provider: 's3',\n bucket: env.blobstoreS3Bucket,\n uploadTimeoutMs: env.blobstoreS3UploadTimeoutMs || 20000,\n region: env.blobstoreS3Region,\n endpoint: env.blobstoreS3Endpoint,\n forcePathStyle: env.blobstoreS3ForcePathStyle,\n }\n if (env.blobstoreS3AccessKeyId || env.blobstoreS3SecretAccessKey) {\n if (!env.blobstoreS3AccessKeyId || !env.blobstoreS3SecretAccessKey) {\n throw new Error(\n 'Must specify both S3 access key id and secret access key blobstore env vars',\n )\n }\n blobstoreCfg.credentials = {\n accessKeyId: env.blobstoreS3AccessKeyId,\n secretAccessKey: env.blobstoreS3SecretAccessKey,\n }\n }\n } else if (env.blobstoreDiskLocation) {\n blobstoreCfg = {\n provider: 'disk',\n location: env.blobstoreDiskLocation,\n tempLocation: env.blobstoreDiskTmpLocation,\n }\n } else {\n throw new Error('Must configure either S3 or disk blobstore')\n }\n\n let serviceHandleDomains: string[]\n if (env.serviceHandleDomains && env.serviceHandleDomains.length > 0) {\n serviceHandleDomains = env.serviceHandleDomains\n } else {\n if (hostname === 'localhost') {\n serviceHandleDomains = ['.test']\n } else {\n serviceHandleDomains = [`.${hostname}`]\n }\n }\n const invalidDomain = serviceHandleDomains.find(\n (domain) => domain.length < 1 || !domain.startsWith('.'),\n )\n if (invalidDomain) {\n throw new Error(`Invalid handle domain: ${invalidDomain}`)\n }\n\n const identityCfg: ServerConfig['identity'] = {\n plcUrl: env.didPlcUrl ?? 'https://plc.directory',\n cacheMaxTTL: env.didCacheMaxTTL ?? DAY,\n cacheStaleTTL: env.didCacheStaleTTL ?? HOUR,\n resolverTimeout: env.resolverTimeout ?? 3 * SECOND,\n recoveryDidKey: env.recoveryDidKey ?? null,\n serviceHandleDomains,\n handleBackupNameservers: env.handleBackupNameservers,\n enableDidDocWithSession: !!env.enableDidDocWithSession,\n }\n\n let entrywayCfg: ServerConfig['entryway'] = null\n if (env.entrywayUrl) {\n assert(\n env.entrywayJwtVerifyKeyK256PublicKeyHex &&\n env.entrywayPlcRotationKey &&\n env.entrywayDid,\n 'if entryway url is configured, must include all required entryway configuration',\n )\n entrywayCfg = {\n url: env.entrywayUrl,\n did: env.entrywayDid,\n jwtPublicKeyHex: env.entrywayJwtVerifyKeyK256PublicKeyHex,\n plcRotationKey: env.entrywayPlcRotationKey,\n }\n }\n\n // default to being required if left undefined\n const invitesCfg: ServerConfig['invites'] =\n env.inviteRequired === false\n ? {\n required: false,\n }\n : {\n required: true,\n interval: env.inviteInterval ?? null,\n epoch: env.inviteEpoch ?? 0,\n }\n\n let emailCfg: ServerConfig['email']\n if (!env.emailFromAddress && !env.emailSmtpUrl) {\n emailCfg = null\n } else {\n if (!env.emailFromAddress || !env.emailSmtpUrl) {\n throw new Error(\n 'Partial email config, must set both emailFromAddress and emailSmtpUrl',\n )\n }\n emailCfg = {\n smtpUrl: env.emailSmtpUrl,\n fromAddress: env.emailFromAddress,\n disableConfirmationLink: env.emailDisableConfirmationLink ?? false,\n }\n }\n\n let moderationEmailCfg: ServerConfig['moderationEmail']\n if (!env.moderationEmailAddress && !env.moderationEmailSmtpUrl) {\n moderationEmailCfg = null\n } else {\n if (!env.moderationEmailAddress || !env.moderationEmailSmtpUrl) {\n throw new Error(\n 'Partial moderation email config, must set both emailFromAddress and emailSmtpUrl',\n )\n }\n moderationEmailCfg = {\n smtpUrl: env.moderationEmailSmtpUrl,\n fromAddress: env.moderationEmailAddress,\n disableConfirmationLink: false,\n }\n }\n\n const subscriptionCfg: ServerConfig['subscription'] = {\n maxBuffer: env.maxSubscriptionBuffer ?? 500,\n repoBackfillLimitMs: env.repoBackfillLimitMs ?? DAY,\n }\n\n let bskyAppViewCfg: ServerConfig['bskyAppView'] = null\n if (env.bskyAppViewUrl) {\n assert(\n env.bskyAppViewDid,\n 'if bsky appview service url is configured, must configure its did as well.',\n )\n bskyAppViewCfg = {\n url: env.bskyAppViewUrl,\n did: env.bskyAppViewDid,\n cdnUrlPattern: env.bskyAppViewCdnUrlPattern,\n }\n }\n\n let modServiceCfg: ServerConfig['modService'] = null\n if (env.modServiceUrl) {\n assert(\n env.modServiceDid,\n 'if mod service url is configured, must configure its did as well.',\n )\n modServiceCfg = {\n url: env.modServiceUrl,\n did: env.modServiceDid,\n }\n }\n\n let reportServiceCfg: ServerConfig['reportService'] = null\n if (env.reportServiceUrl) {\n assert(\n env.reportServiceDid,\n 'if report service url is configured, must configure its did as well.',\n )\n reportServiceCfg = {\n url: env.reportServiceUrl,\n did: env.reportServiceDid,\n }\n }\n\n // if there's a mod service, default report service into it\n if (modServiceCfg && !reportServiceCfg) {\n reportServiceCfg = modServiceCfg\n }\n\n const redisCfg: ServerConfig['redis'] = env.redisScratchAddress\n ? {\n address: env.redisScratchAddress,\n password: env.redisScratchPassword,\n }\n : null\n\n const rateLimitsCfg: ServerConfig['rateLimits'] = env.rateLimitsEnabled\n ? {\n enabled: true,\n bypassKey: env.rateLimitBypassKey,\n bypassIps: env.rateLimitBypassIps?.map((ipOrCidr) =>\n ipOrCidr.split('/')[0]?.trim(),\n ),\n }\n : { enabled: false }\n\n const crawlersCfg: ServerConfig['crawlers'] = env.crawlers ?? []\n\n const fetchCfg: ServerConfig['fetch'] = {\n disableSsrfProtection: env.disableSsrfProtection ?? env.devMode ?? false,\n maxResponseSize: env.fetchMaxResponseSize ?? 512 * 1024, // 512kb\n }\n\n const proxyCfg: ServerConfig['proxy'] = {\n disableSsrfProtection: env.disableSsrfProtection ?? env.devMode ?? false,\n allowHTTP2: env.proxyAllowHTTP2 ?? false,\n headersTimeout: env.proxyHeadersTimeout ?? 10e3,\n bodyTimeout: env.proxyBodyTimeout ?? 30e3,\n maxResponseSize: env.proxyMaxResponseSize ?? 10 * 1024 * 1024, // 10mb\n maxRetries:\n env.proxyMaxRetries != null && env.proxyMaxRetries > 0\n ? env.proxyMaxRetries\n : 0,\n preferCompressed: env.proxyPreferCompressed ?? false,\n }\n\n const brandingCfg = {\n name: env.serviceName ?? `${hostname} PDS`,\n logo: env.logoUrl,\n colors: {\n light: env.lightColor,\n dark: env.darkColor,\n\n contrastSaturation: env.contrastSaturation,\n\n primary: env.primaryColor,\n primaryContrast: env.primaryColorContrast,\n primaryHue: env.primaryColorHue,\n\n error: env.errorColor,\n errorContrast: env.errorColorContrast,\n errorHue: env.errorColorHue,\n\n warning: env.warningColor,\n warningContrast: env.warningColorContrast,\n warningHue: env.warningColorHue,\n\n info: env.infoColor,\n infoContrast: env.infoColorContrast,\n infoHue: env.infoColorHue,\n\n success: env.successColor,\n successContrast: env.successColorContrast,\n successHue: env.successColorHue,\n },\n links: [\n {\n title: { en: 'Home', fr: 'Accueil' },\n href: env.homeUrl,\n rel: 'canonical' as const, // Prevents login page from being indexed\n },\n {\n title: { en: 'Terms of Service' },\n href: env.termsOfServiceUrl,\n rel: 'terms-of-service' as const,\n },\n {\n title: { en: 'Privacy Policy' },\n href: env.privacyPolicyUrl,\n rel: 'privacy-policy' as const,\n },\n {\n title: { en: 'Support' },\n href: env.supportUrl,\n rel: 'help' as const,\n },\n ].filter(\n <T extends { href?: string }>(f: T): f is T & { href: string } =>\n f.href != null && f.href !== '',\n ),\n }\n\n const oauthCfg: ServerConfig['oauth'] = entrywayCfg\n ? {\n issuer: entrywayCfg.url,\n provider: undefined,\n }\n : {\n issuer: serviceCfg.publicUrl,\n provider: {\n hcaptcha:\n env.hcaptchaSiteKey &&\n env.hcaptchaSecretKey &&\n env.hcaptchaTokenSalt\n ? {\n siteKey: env.hcaptchaSiteKey,\n secretKey: env.hcaptchaSecretKey,\n tokenSalt: env.hcaptchaTokenSalt,\n }\n : undefined,\n branding: brandingCfg,\n trustedClients: env.trustedOAuthClients,\n },\n }\n\n const lexiconCfg: LexiconResolverConfig = {}\n\n if (env.lexiconDidAuthority != null) {\n ensureValidDid(env.lexiconDidAuthority)\n lexiconCfg.didAuthority = env.lexiconDidAuthority\n }\n\n return {\n service: serviceCfg,\n db: dbCfg,\n actorStore: actorStoreCfg,\n blobstore: blobstoreCfg,\n identity: identityCfg,\n entryway: entrywayCfg,\n invites: invitesCfg,\n email: emailCfg,\n moderationEmail: moderationEmailCfg,\n subscription: subscriptionCfg,\n bskyAppView: bskyAppViewCfg,\n modService: modServiceCfg,\n reportService: reportServiceCfg,\n redis: redisCfg,\n rateLimits: rateLimitsCfg,\n crawlers: crawlersCfg,\n fetch: fetchCfg,\n lexicon: lexiconCfg,\n proxy: proxyCfg,\n branding: brandingCfg,\n oauth: oauthCfg,\n }\n}\n\nexport type ServerConfig = {\n service: ServiceConfig\n db: DatabaseConfig\n actorStore: ActorStoreConfig\n blobstore: S3BlobstoreConfig | DiskBlobstoreConfig\n identity: IdentityConfig\n entryway: EntrywayConfig | null\n invites: InvitesConfig\n email: EmailConfig | null\n moderationEmail: EmailConfig | null\n subscription: SubscriptionConfig\n bskyAppView: BksyAppViewConfig | null\n modService: ModServiceConfig | null\n reportService: ReportServiceConfig | null\n redis: RedisScratchConfig | null\n rateLimits: RateLimitsConfig\n crawlers: string[]\n fetch: FetchConfig\n proxy: ProxyConfig\n branding: BrandingConfig\n oauth: OAuthConfig\n lexicon: LexiconResolverConfig\n}\n\nexport type ServiceConfig = {\n port: number\n hostname: string\n publicUrl: string\n did: DidString\n version?: string\n privacyPolicyUrl?: string\n termsOfServiceUrl?: string\n acceptingImports: boolean\n maxImportSize?: number\n blobUploadLimit: number\n contactEmailAddress?: string\n devMode: boolean\n}\n\nexport type DatabaseConfig = {\n accountDbLoc: string\n sequencerDbLoc: string\n didCacheDbLoc: string\n disableWalAutoCheckpoint: boolean\n}\n\nexport type ActorStoreConfig = {\n directory: string\n cacheSize: number\n disableWalAutoCheckpoint: boolean\n}\n\nexport type S3BlobstoreConfig = {\n provider: 's3'\n bucket: string\n region?: string\n endpoint?: string\n forcePathStyle?: boolean\n uploadTimeoutMs?: number\n credentials?: {\n accessKeyId: string\n secretAccessKey: string\n }\n}\n\nexport type DiskBlobstoreConfig = {\n provider: 'disk'\n location: string\n tempLocation?: string\n}\n\nexport type IdentityConfig = {\n plcUrl: string\n resolverTimeout: number\n cacheStaleTTL: number\n cacheMaxTTL: number\n recoveryDidKey: string | null\n serviceHandleDomains: string[]\n handleBackupNameservers?: string[]\n enableDidDocWithSession: boolean\n}\n\nexport type EntrywayConfig = {\n url: string\n did: string\n jwtPublicKeyHex: string\n plcRotationKey: string\n}\n\nexport type FetchConfig = {\n disableSsrfProtection: boolean\n maxResponseSize: number\n}\n\nexport type ProxyConfig = {\n disableSsrfProtection: boolean\n allowHTTP2: boolean\n headersTimeout: number\n bodyTimeout: number\n maxResponseSize: number\n maxRetries: number\n\n /**\n * When proxying requests that might get intercepted (for read-after-write) we\n * negotiate the encoding based on the client's preferences. We will however\n * use or own weights in order to be able to better control if the PDS will\n * need to perform content decoding. This settings allows to prefer compressed\n * content over uncompressed one.\n */\n preferCompressed: boolean\n}\n\nexport type OAuthConfig = {\n issuer: string\n provider?: {\n hcaptcha?: HcaptchaConfig\n branding: BrandingConfig\n trustedClients?: string[]\n }\n}\n\nexport type LexiconResolverConfig = {\n didAuthority?: `did:${string}:${string}`\n}\n\nexport type InvitesConfig =\n | {\n required: true\n interval: number | null\n epoch: number\n }\n | {\n required: false\n }\n\nexport type EmailConfig = {\n smtpUrl: string\n fromAddress: string\n disableConfirmationLink: boolean\n}\n\nexport type SubscriptionConfig = {\n maxBuffer: number\n repoBackfillLimitMs: number\n}\n\nexport type RedisScratchConfig = {\n address: string\n password?: string\n}\n\nexport type RateLimitsConfig =\n | {\n enabled: true\n bypassKey?: string\n bypassIps?: string[]\n }\n | { enabled: false }\n\nexport type BksyAppViewConfig = {\n url: string\n did: string\n cdnUrlPattern?: string\n}\n\nexport type ModServiceConfig = {\n url: string\n did: string\n}\n\nexport type ReportServiceConfig = {\n url: string\n did: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
package/dist/context.js CHANGED
@@ -140,7 +140,7 @@ export class AppContext {
140
140
  keyId: secrets.plcRotationKey.keyId,
141
141
  })
142
142
  : await crypto.Secp256k1Keypair.import(secrets.plcRotationKey.privateKeyHex);
143
- const accountManager = new AccountManager(idResolver, jwtSecretKey, mailer, sequencer, plcClient, plcRotationKey, cfg.service.did, cfg.identity.serviceHandleDomains, cfg.db);
143
+ const accountManager = new AccountManager(cfg, actorStore, idResolver, jwtSecretKey, mailer, sequencer, plcClient, plcRotationKey);
144
144
  await accountManager.migrateOrThrow();
145
145
  const localViewer = LocalViewer.creator(accountManager, imageUrlBuilder, bskyAppView);
146
146
  // An agent for performing HTTP requests based on user provided URLs.