@atproto/pds 0.5.4 → 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.
- package/CHANGELOG.md +43 -0
- package/dist/account-manager/account-manager.d.ts +52 -14
- package/dist/account-manager/account-manager.d.ts.map +1 -1
- package/dist/account-manager/account-manager.js +86 -26
- package/dist/account-manager/account-manager.js.map +1 -1
- package/dist/account-manager/db/index.d.ts.map +1 -1
- package/dist/account-manager/db/migrations/005-oauth-account-management.d.ts.map +1 -1
- package/dist/account-manager/db/migrations/005-oauth-account-management.js +3 -4
- package/dist/account-manager/db/migrations/005-oauth-account-management.js.map +1 -1
- package/dist/account-manager/db/migrations/index.d.ts.map +1 -1
- package/dist/account-manager/db/schema/authorization-request.d.ts +2 -2
- package/dist/account-manager/db/schema/authorization-request.d.ts.map +1 -1
- package/dist/account-manager/db/schema/authorization-request.js.map +1 -1
- package/dist/account-manager/db/schema/authorized-client.d.ts +2 -2
- package/dist/account-manager/db/schema/authorized-client.d.ts.map +1 -1
- package/dist/account-manager/db/schema/authorized-client.js.map +1 -1
- package/dist/account-manager/db/schema/token.d.ts +2 -2
- package/dist/account-manager/db/schema/token.d.ts.map +1 -1
- package/dist/account-manager/db/schema/token.js.map +1 -1
- package/dist/account-manager/helpers/account-device.d.ts +23 -196
- package/dist/account-manager/helpers/account-device.d.ts.map +1 -1
- package/dist/account-manager/helpers/account-device.js +3 -3
- package/dist/account-manager/helpers/account-device.js.map +1 -1
- package/dist/account-manager/helpers/account.d.ts +20 -10
- package/dist/account-manager/helpers/account.d.ts.map +1 -1
- package/dist/account-manager/helpers/account.js +17 -11
- package/dist/account-manager/helpers/account.js.map +1 -1
- package/dist/account-manager/helpers/auth.d.ts.map +1 -1
- package/dist/account-manager/helpers/auth.js +1 -1
- package/dist/account-manager/helpers/auth.js.map +1 -1
- package/dist/account-manager/helpers/authorization-request.d.ts +83 -5
- package/dist/account-manager/helpers/authorization-request.d.ts.map +1 -1
- package/dist/account-manager/helpers/authorization-request.js +8 -8
- package/dist/account-manager/helpers/authorization-request.js.map +1 -1
- package/dist/account-manager/helpers/authorized-client.d.ts +5 -4
- package/dist/account-manager/helpers/authorized-client.d.ts.map +1 -1
- package/dist/account-manager/helpers/authorized-client.js +3 -0
- package/dist/account-manager/helpers/authorized-client.js.map +1 -1
- package/dist/account-manager/helpers/device.d.ts +10 -4
- package/dist/account-manager/helpers/device.d.ts.map +1 -1
- package/dist/account-manager/helpers/device.js +4 -4
- package/dist/account-manager/helpers/device.js.map +1 -1
- package/dist/account-manager/helpers/email-token.d.ts.map +1 -1
- package/dist/account-manager/helpers/invite.d.ts +35 -2
- package/dist/account-manager/helpers/invite.d.ts.map +1 -1
- package/dist/account-manager/helpers/lexicon.d.ts.map +1 -1
- package/dist/account-manager/helpers/lexicon.js +6 -0
- package/dist/account-manager/helpers/lexicon.js.map +1 -1
- package/dist/account-manager/helpers/password.d.ts +1 -0
- package/dist/account-manager/helpers/password.d.ts.map +1 -1
- package/dist/account-manager/helpers/password.js +3 -0
- package/dist/account-manager/helpers/password.js.map +1 -1
- package/dist/account-manager/helpers/repo.d.ts.map +1 -1
- package/dist/account-manager/helpers/scrypt.d.ts.map +1 -1
- package/dist/account-manager/helpers/token.d.ts +72 -1031
- package/dist/account-manager/helpers/token.d.ts.map +1 -1
- package/dist/account-manager/helpers/token.js +13 -10
- package/dist/account-manager/helpers/token.js.map +1 -1
- package/dist/account-manager/helpers/used-refresh-token.d.ts +6 -2
- package/dist/account-manager/helpers/used-refresh-token.d.ts.map +1 -1
- package/dist/account-manager/oauth-store.d.ts +17 -13
- package/dist/account-manager/oauth-store.d.ts.map +1 -1
- package/dist/account-manager/oauth-store.js +89 -39
- package/dist/account-manager/oauth-store.js.map +1 -1
- package/dist/account-manager/scope-reference-getter.d.ts.map +1 -1
- package/dist/account-manager/scope-reference-getter.js.map +1 -1
- package/dist/actor-store/actor-store-reader.d.ts.map +1 -1
- package/dist/actor-store/actor-store-reader.js.map +1 -1
- package/dist/actor-store/actor-store-transactor.d.ts.map +1 -1
- package/dist/actor-store/actor-store-transactor.js.map +1 -1
- package/dist/actor-store/actor-store-writer.d.ts.map +1 -1
- package/dist/actor-store/actor-store.d.ts.map +1 -1
- package/dist/actor-store/actor-store.js.map +1 -1
- package/dist/actor-store/blob/reader.d.ts.map +1 -1
- package/dist/actor-store/blob/reader.js +2 -3
- package/dist/actor-store/blob/reader.js.map +1 -1
- package/dist/actor-store/blob/transactor.d.ts.map +1 -1
- package/dist/actor-store/blob/transactor.js.map +1 -1
- package/dist/actor-store/db/index.d.ts.map +1 -1
- package/dist/actor-store/db/migrations/index.d.ts.map +1 -1
- package/dist/actor-store/migrate.d.ts.map +1 -1
- package/dist/actor-store/preference/reader.d.ts.map +1 -1
- package/dist/actor-store/preference/reader.js.map +1 -1
- package/dist/actor-store/preference/transactor.d.ts.map +1 -1
- package/dist/actor-store/record/reader.d.ts +3 -3
- package/dist/actor-store/record/reader.d.ts.map +1 -1
- package/dist/actor-store/record/reader.js +3 -3
- package/dist/actor-store/record/reader.js.map +1 -1
- package/dist/actor-store/record/transactor.d.ts.map +1 -1
- package/dist/actor-store/record/transactor.js.map +1 -1
- package/dist/actor-store/repo/reader.d.ts.map +1 -1
- package/dist/actor-store/repo/reader.js.map +1 -1
- package/dist/actor-store/repo/sql-repo-reader.d.ts +5 -1
- package/dist/actor-store/repo/sql-repo-reader.d.ts.map +1 -1
- package/dist/actor-store/repo/sql-repo-reader.js.map +1 -1
- package/dist/actor-store/repo/sql-repo-transactor.d.ts.map +1 -1
- package/dist/actor-store/repo/transactor.d.ts.map +1 -1
- package/dist/actor-store/repo/transactor.js.map +1 -1
- package/dist/api/app/bsky/util/resolver.d.ts +4 -4
- package/dist/api/app/bsky/util/resolver.d.ts.map +1 -1
- package/dist/api/com/atproto/admin/getInviteCodes.d.ts.map +1 -1
- package/dist/api/com/atproto/admin/updateSubjectStatus.d.ts.map +1 -1
- package/dist/api/com/atproto/admin/updateSubjectStatus.js +12 -4
- package/dist/api/com/atproto/admin/updateSubjectStatus.js.map +1 -1
- package/dist/api/com/atproto/server/activateAccount.d.ts.map +1 -1
- package/dist/api/com/atproto/server/activateAccount.js +25 -31
- package/dist/api/com/atproto/server/activateAccount.js.map +1 -1
- package/dist/api/com/atproto/server/deactivateAccount.d.ts.map +1 -1
- package/dist/api/com/atproto/server/deactivateAccount.js +3 -4
- package/dist/api/com/atproto/server/deactivateAccount.js.map +1 -1
- package/dist/api/com/atproto/server/deleteAccount.d.ts.map +1 -1
- package/dist/api/com/atproto/server/deleteAccount.js +51 -37
- package/dist/api/com/atproto/server/deleteAccount.js.map +1 -1
- package/dist/api/com/atproto/server/util.d.ts +25 -6
- package/dist/api/com/atproto/server/util.d.ts.map +1 -1
- package/dist/api/com/atproto/server/util.js.map +1 -1
- package/dist/api/com/atproto/sync/getRepo.d.ts.map +1 -1
- package/dist/api/com/atproto/sync/listRepos.d.ts.map +1 -1
- package/dist/api/com/atproto/sync/util.d.ts.map +1 -1
- package/dist/api/proxy.d.ts.map +1 -1
- package/dist/app-view.d.ts.map +1 -1
- package/dist/auth-routes.d.ts.map +1 -1
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/background.d.ts.map +1 -1
- package/dist/basic-routes.d.ts.map +1 -1
- package/dist/bsky-app-view.d.ts.map +1 -1
- package/dist/config/config.d.ts +2 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +4 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/secrets.d.ts.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -1
- package/dist/context.js.map +1 -1
- package/dist/crawlers.d.ts.map +1 -1
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/migrator.d.ts +4 -3
- package/dist/db/migrator.d.ts.map +1 -1
- package/dist/db/migrator.js +1 -1
- package/dist/db/migrator.js.map +1 -1
- package/dist/db/pagination.d.ts +3 -2
- package/dist/db/pagination.d.ts.map +1 -1
- package/dist/db/pagination.js +2 -2
- package/dist/db/pagination.js.map +1 -1
- package/dist/db/util.d.ts +3 -3
- package/dist/db/util.d.ts.map +1 -1
- package/dist/db/util.js.map +1 -1
- package/dist/did-cache/db/index.d.ts.map +1 -1
- package/dist/did-cache/db/migrations.d.ts.map +1 -1
- package/dist/did-cache/index.d.ts.map +1 -1
- package/dist/did-cache/index.js.map +1 -1
- package/dist/disk-blobstore.d.ts.map +1 -1
- package/dist/disk-blobstore.js.map +1 -1
- package/dist/handle/explicit-slurs.d.ts.map +1 -1
- package/dist/handle/index.d.ts.map +1 -1
- package/dist/image/image-url-builder.d.ts.map +1 -1
- package/dist/image/image-url-builder.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +75 -155
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/profile.defs.d.ts +100 -300
- package/dist/lexicons/app/bsky/actor/profile.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/status.defs.d.ts +40 -40
- package/dist/lexicons/app/bsky/actor/status.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/authCreatePosts.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authDeleteContent.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authFullApp.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authManageFeedDeclarations.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authManageLabelerService.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authManageModeration.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authManageNotifications.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authManageProfile.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/authViewAll.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/draft/defs.defs.d.ts +4 -4
- package/dist/lexicons/app/bsky/draft/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/external.defs.d.ts +10 -10
- package/dist/lexicons/app/bsky/embed/gallery.defs.d.ts +10 -42
- package/dist/lexicons/app/bsky/embed/gallery.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/images.defs.d.ts +10 -10
- package/dist/lexicons/app/bsky/embed/record.defs.d.ts +10 -10
- package/dist/lexicons/app/bsky/embed/recordWithMedia.defs.d.ts +10 -10
- package/dist/lexicons/app/bsky/embed/video.defs.d.ts +50 -162
- package/dist/lexicons/app/bsky/embed/video.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/feed/generator.defs.d.ts +80 -160
- package/dist/lexicons/app/bsky/feed/generator.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/feed/like.defs.d.ts +30 -30
- package/dist/lexicons/app/bsky/feed/like.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/feed/post.defs.d.ts +80 -200
- package/dist/lexicons/app/bsky/feed/post.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/feed/postgate.defs.d.ts +40 -80
- package/dist/lexicons/app/bsky/feed/postgate.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/feed/repost.defs.d.ts +30 -30
- package/dist/lexicons/app/bsky/feed/repost.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/feed/threadgate.defs.d.ts +30 -30
- package/dist/lexicons/app/bsky/feed/threadgate.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/block.defs.d.ts +20 -20
- package/dist/lexicons/app/bsky/graph/block.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/follow.defs.d.ts +30 -30
- package/dist/lexicons/app/bsky/graph/follow.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/list.defs.d.ts +60 -60
- package/dist/lexicons/app/bsky/graph/list.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/listblock.defs.d.ts +20 -20
- package/dist/lexicons/app/bsky/graph/listblock.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/listitem.defs.d.ts +20 -20
- package/dist/lexicons/app/bsky/graph/listitem.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/starterpack.defs.d.ts +50 -90
- package/dist/lexicons/app/bsky/graph/starterpack.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/verification.defs.d.ts +30 -30
- package/dist/lexicons/app/bsky/graph/verification.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/labeler/service.defs.d.ts +50 -130
- package/dist/lexicons/app/bsky/labeler/service.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/notification/declaration.defs.d.ts +10 -10
- package/dist/lexicons/app/bsky/notification/declaration.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/richtext/facet.defs.d.ts +10 -10
- package/dist/lexicons/chat/bsky/actor/declaration.defs.d.ts +20 -20
- package/dist/lexicons/chat/bsky/actor/declaration.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/authFullChatClient.defs.d.ts +1 -1
- package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts +17 -0
- package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/defs.defs.js +11 -0
- package/dist/lexicons/chat/bsky/convo/defs.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.d.ts +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.js +1 -0
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.d.ts +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.js +1 -0
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/embed/joinLink.defs.d.ts +10 -42
- package/dist/lexicons/chat/bsky/embed/joinLink.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/lexicon/schema.defs.d.ts +10 -10
- package/dist/lexicons/com/atproto/lexicon/schema.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/strongRef.defs.d.ts +10 -10
- package/dist/lexicons/com/germnetwork/declaration.defs.d.ts +40 -120
- package/dist/lexicons/com/germnetwork/declaration.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/document.defs.d.ts +130 -450
- package/dist/lexicons/site/standard/document.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/graph/recommend.defs.d.ts +10 -10
- package/dist/lexicons/site/standard/graph/recommend.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/graph/subscription.defs.d.ts +20 -60
- package/dist/lexicons/site/standard/graph/subscription.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/publication.defs.d.ts +60 -220
- package/dist/lexicons/site/standard/publication.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/theme/basic.defs.d.ts +10 -10
- package/dist/lexicons/site/standard/theme/basic.defs.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/moderation/queryStatuses.defs.d.ts +2 -2
- package/dist/lexicons/tools/ozone/set/querySets.defs.d.ts +2 -2
- package/dist/logger.d.ts +14 -14
- package/dist/logger.d.ts.map +1 -1
- package/dist/mailer/index.d.ts +2 -0
- package/dist/mailer/index.d.ts.map +1 -1
- package/dist/mailer/index.js +2 -0
- package/dist/mailer/index.js.map +1 -1
- package/dist/mailer/moderation.d.ts.map +1 -1
- package/dist/pipethrough.d.ts +1 -1
- package/dist/pipethrough.d.ts.map +1 -1
- package/dist/pipethrough.js.map +1 -1
- package/dist/rate-limits.d.ts.map +1 -1
- package/dist/read-after-write/util.d.ts.map +1 -1
- package/dist/read-after-write/viewer.d.ts +8 -8
- package/dist/read-after-write/viewer.d.ts.map +1 -1
- package/dist/read-after-write/viewer.js.map +1 -1
- package/dist/redis.d.ts.map +1 -1
- package/dist/repo/prepare.d.ts.map +1 -1
- package/dist/repo/types.d.ts.map +1 -1
- package/dist/repo/types.js.map +1 -1
- package/dist/scripts/index.d.ts.map +1 -1
- package/dist/scripts/publish-identity.d.ts.map +1 -1
- package/dist/scripts/rebuild-repo.d.ts.map +1 -1
- package/dist/scripts/rotate-keys.d.ts.map +1 -1
- package/dist/scripts/sequencer-recovery/index.d.ts.map +1 -1
- package/dist/scripts/sequencer-recovery/recoverer.d.ts.map +1 -1
- package/dist/scripts/sequencer-recovery/recoverer.js.map +1 -1
- package/dist/scripts/sequencer-recovery/recovery-db.d.ts.map +1 -1
- package/dist/scripts/sequencer-recovery/recovery-db.js.map +1 -1
- package/dist/scripts/sequencer-recovery/repair-repos.d.ts.map +1 -1
- package/dist/scripts/sequencer-recovery/user-queues.d.ts.map +1 -1
- package/dist/scripts/util.d.ts.map +1 -1
- package/dist/sequencer/db/index.d.ts.map +1 -1
- package/dist/sequencer/db/migrations/index.d.ts.map +1 -1
- package/dist/sequencer/events.d.ts +19 -19
- package/dist/sequencer/events.d.ts.map +1 -1
- package/dist/sequencer/events.js +6 -13
- package/dist/sequencer/events.js.map +1 -1
- package/dist/sequencer/outbox.d.ts.map +1 -1
- package/dist/sequencer/outbox.js.map +1 -1
- package/dist/sequencer/sequencer.d.ts +1 -1
- package/dist/sequencer/sequencer.d.ts.map +1 -1
- package/dist/sequencer/sequencer.js.map +1 -1
- package/dist/util/debug.d.ts.map +1 -1
- package/dist/well-known.d.ts.map +1 -1
- package/package.json +26 -27
- package/src/account-manager/account-manager.ts +135 -36
- package/src/account-manager/db/migrations/005-oauth-account-management.ts +6 -5
- package/src/account-manager/db/schema/authorization-request.ts +2 -1
- package/src/account-manager/db/schema/authorized-client.ts +6 -2
- package/src/account-manager/db/schema/token.ts +2 -2
- package/src/account-manager/helpers/account-device.ts +5 -11
- package/src/account-manager/helpers/account.ts +39 -16
- package/src/account-manager/helpers/auth.ts +2 -2
- package/src/account-manager/helpers/authorization-request.ts +12 -8
- package/src/account-manager/helpers/authorized-client.ts +12 -6
- package/src/account-manager/helpers/device.ts +4 -4
- package/src/account-manager/helpers/lexicon.ts +8 -3
- package/src/account-manager/helpers/password.ts +6 -0
- package/src/account-manager/helpers/token.ts +17 -11
- package/src/account-manager/oauth-store.ts +129 -61
- package/src/actor-store/blob/reader.ts +8 -5
- package/src/actor-store/record/reader.ts +3 -3
- package/src/actor-store/repo/sql-repo-reader.ts +1 -1
- package/src/api/com/atproto/admin/updateSubjectStatus.ts +16 -4
- package/src/api/com/atproto/server/activateAccount.ts +27 -49
- package/src/api/com/atproto/server/deactivateAccount.ts +3 -7
- package/src/api/com/atproto/server/deleteAccount.ts +60 -43
- package/src/api/com/atproto/server/util.ts +24 -7
- package/src/config/config.ts +7 -2
- package/src/context.ts +2 -3
- package/src/db/migrator.ts +2 -1
- package/src/db/pagination.ts +7 -7
- package/src/db/util.ts +5 -2
- package/src/mailer/index.ts +4 -2
- package/src/scripts/sequencer-recovery/recovery-db.ts +1 -1
- package/src/sequencer/events.ts +8 -13
- package/src/sequencer/sequencer.ts +1 -3
- package/tests/account-manager.test.ts +79 -0
- package/tests/account-status.test.ts +206 -0
- package/tests/oauth.test.ts +91 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1,59 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
ForbiddenError,
|
|
4
|
-
InvalidRequestError,
|
|
5
|
-
Server,
|
|
6
|
-
} from '@atproto/xrpc-server'
|
|
1
|
+
import { ForbiddenError, Server } from '@atproto/xrpc-server'
|
|
7
2
|
import { ACCESS_FULL } from '../../../../auth-scope.js'
|
|
8
3
|
import { AppContext } from '../../../../context.js'
|
|
9
4
|
import { com } from '../../../../lexicons/index.js'
|
|
10
|
-
import { assertValidDidDocumentForService } from './util.js'
|
|
11
5
|
|
|
12
6
|
export default function (server: Server, ctx: AppContext) {
|
|
13
|
-
|
|
14
|
-
auth: ctx.authVerifier.authorization({
|
|
15
|
-
scopes: ACCESS_FULL,
|
|
16
|
-
authorize: () => {
|
|
17
|
-
throw new ForbiddenError(
|
|
18
|
-
'OAuth credentials are not supported for this endpoint',
|
|
19
|
-
)
|
|
20
|
-
},
|
|
21
|
-
}),
|
|
22
|
-
handler: async ({ req, auth }) => {
|
|
23
|
-
// in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)
|
|
24
|
-
if (ctx.entrywayClient) {
|
|
25
|
-
const { headers } = ctx.entrywayPassthruHeaders(req)
|
|
26
|
-
await ctx.entrywayClient.xrpc(com.atproto.server.activateAccount, {
|
|
27
|
-
headers,
|
|
28
|
-
})
|
|
29
|
-
return
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const requester = auth.credentials.did
|
|
33
|
-
|
|
34
|
-
await assertValidDidDocumentForService(ctx, requester)
|
|
35
|
-
|
|
36
|
-
const account = await ctx.accountManager.getAccount(requester, {
|
|
37
|
-
includeDeactivated: true,
|
|
38
|
-
})
|
|
39
|
-
if (!account) {
|
|
40
|
-
throw new InvalidRequestError('user not found', 'AccountNotFound')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
await ctx.accountManager.activateAccount(requester)
|
|
7
|
+
const { entrywayClient } = ctx
|
|
44
8
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const status = await ctx.accountManager.getAccountStatus(requester)
|
|
51
|
-
await ctx.sequencer.sequenceAccountActivation(
|
|
52
|
-
requester,
|
|
53
|
-
account.handle ?? INVALID_HANDLE,
|
|
54
|
-
status,
|
|
55
|
-
syncData,
|
|
9
|
+
const auth = ctx.authVerifier.authorization({
|
|
10
|
+
scopes: ACCESS_FULL,
|
|
11
|
+
authorize: () => {
|
|
12
|
+
throw new ForbiddenError(
|
|
13
|
+
'OAuth credentials are not supported for this endpoint',
|
|
56
14
|
)
|
|
57
15
|
},
|
|
58
16
|
})
|
|
17
|
+
|
|
18
|
+
if (entrywayClient) {
|
|
19
|
+
// in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)
|
|
20
|
+
server.add(com.atproto.server.activateAccount, {
|
|
21
|
+
auth,
|
|
22
|
+
handler: async ({ req }) => {
|
|
23
|
+
const { headers } = ctx.entrywayPassthruHeaders(req)
|
|
24
|
+
await entrywayClient.xrpc(com.atproto.server.activateAccount, {
|
|
25
|
+
headers,
|
|
26
|
+
})
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
} else {
|
|
30
|
+
server.add(com.atproto.server.activateAccount, {
|
|
31
|
+
auth,
|
|
32
|
+
handler: async ({ auth }) => {
|
|
33
|
+
await ctx.accountManager.activateAccount(auth.credentials.did)
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
}
|
|
59
37
|
}
|
|
@@ -32,13 +32,9 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
32
32
|
server.add(com.atproto.server.deactivateAccount, {
|
|
33
33
|
auth,
|
|
34
34
|
handler: async ({ input: { body }, auth }) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
body.deleteAfter ?? null,
|
|
39
|
-
)
|
|
40
|
-
const status = await ctx.accountManager.getAccountStatus(requester)
|
|
41
|
-
await ctx.sequencer.sequenceAccount(requester, status)
|
|
35
|
+
await ctx.accountManager.deactivateAccount(auth.credentials.did, {
|
|
36
|
+
deleteAfter: body.deleteAfter ?? null,
|
|
37
|
+
})
|
|
42
38
|
},
|
|
43
39
|
})
|
|
44
40
|
}
|
|
@@ -2,6 +2,7 @@ import { MINUTE } from '@atproto/common'
|
|
|
2
2
|
import {
|
|
3
3
|
AuthRequiredError,
|
|
4
4
|
InvalidRequestError,
|
|
5
|
+
MethodRateLimit,
|
|
5
6
|
Server,
|
|
6
7
|
} from '@atproto/xrpc-server'
|
|
7
8
|
import { OLD_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scrypt.js'
|
|
@@ -11,58 +12,74 @@ import { com } from '../../../../lexicons/index.js'
|
|
|
11
12
|
export default function (server: Server, ctx: AppContext) {
|
|
12
13
|
const { entrywayClient } = ctx
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
handler: async ({ input: { body }, req }) => {
|
|
20
|
-
const { did, password, token } = body
|
|
15
|
+
const rateLimit: MethodRateLimit = {
|
|
16
|
+
durationMs: 5 * MINUTE,
|
|
17
|
+
points: 50,
|
|
18
|
+
}
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
if (entrywayClient) {
|
|
21
|
+
server.add(com.atproto.server.deleteAccount, {
|
|
22
|
+
rateLimit,
|
|
23
|
+
handler: async ({ input: { body }, req }) => {
|
|
24
|
+
const account = await ctx.accountManager.getAccount(body.did, {
|
|
25
|
+
includeDeactivated: true,
|
|
26
|
+
includeTakenDown: true,
|
|
27
|
+
})
|
|
28
|
+
if (!account) {
|
|
29
|
+
throw new InvalidRequestError('account not found')
|
|
30
|
+
}
|
|
29
31
|
|
|
30
|
-
if (entrywayClient) {
|
|
31
32
|
const { headers } = ctx.entrywayPassthruHeaders(req)
|
|
32
33
|
await entrywayClient.xrpc(com.atproto.server.deleteAccount, {
|
|
33
34
|
body,
|
|
34
35
|
headers,
|
|
35
36
|
})
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
} else {
|
|
40
|
+
server.add(com.atproto.server.deleteAccount, {
|
|
41
|
+
rateLimit,
|
|
42
|
+
handler: async ({ input: { body } }) => {
|
|
43
|
+
const { did, password, token } = body
|
|
44
|
+
|
|
45
|
+
if (password.length > OLD_PASSWORD_MAX_LENGTH) {
|
|
46
|
+
throw new AuthRequiredError(
|
|
47
|
+
'Password too long. Consider resetting your password.',
|
|
48
|
+
)
|
|
49
|
+
}
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
const account = await ctx.accountManager.getAccount(did, {
|
|
52
|
+
includeDeactivated: true,
|
|
53
|
+
includeTakenDown: true,
|
|
54
|
+
})
|
|
55
|
+
if (!account) {
|
|
56
|
+
throw new InvalidRequestError('account not found')
|
|
57
|
+
}
|
|
42
58
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
const validPass = await ctx.accountManager.verifyAccountPassword(
|
|
60
|
+
did,
|
|
61
|
+
password,
|
|
62
|
+
)
|
|
63
|
+
if (!validPass) {
|
|
64
|
+
throw new AuthRequiredError('Invalid did or password')
|
|
65
|
+
}
|
|
50
66
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
67
|
+
await ctx.accountManager.assertValidEmailToken(
|
|
68
|
+
did,
|
|
69
|
+
'delete_account',
|
|
70
|
+
token,
|
|
71
|
+
)
|
|
56
72
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
// @NOTE Order matters here: first "unlink" the account by removing it
|
|
74
|
+
// from the account manager database ("source of truth"), then notify the
|
|
75
|
+
// sequencer, and finally cleanup files from the file system.
|
|
76
|
+
await ctx.accountManager.deleteAccount(did)
|
|
77
|
+
try {
|
|
78
|
+
await ctx.sequencer.sequenceAccountDeletion(did)
|
|
79
|
+
} finally {
|
|
80
|
+
await ctx.actorStore.destroy(did)
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
}
|
|
68
85
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import * as plc from '@did-plc/lib'
|
|
1
2
|
import { getPdsEndpoint, getSigningDidKey } from '@atproto/common'
|
|
2
3
|
import * as crypto from '@atproto/crypto'
|
|
3
|
-
import { DidDocument } from '@atproto/identity'
|
|
4
|
+
import { DidDocument, IdResolver } from '@atproto/identity'
|
|
4
5
|
import { InvalidRequestError } from '@atproto/xrpc-server'
|
|
6
|
+
import { ActorStore } from '../../../../actor-store/actor-store.js'
|
|
5
7
|
import { ServerConfig } from '../../../../config/index.js'
|
|
6
|
-
import { AppContext } from '../../../../context.js'
|
|
7
8
|
import { httpLogger } from '../../../../logger.js'
|
|
8
9
|
|
|
9
10
|
// generate an invite code preceded by the hostname
|
|
@@ -29,7 +30,7 @@ export const getRandomToken = () => {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export const safeResolveDidDoc = async (
|
|
32
|
-
ctx:
|
|
33
|
+
ctx: { idResolver: IdResolver },
|
|
33
34
|
did: string,
|
|
34
35
|
forceRefresh?: boolean,
|
|
35
36
|
): Promise<DidDocument | undefined> => {
|
|
@@ -42,7 +43,7 @@ export const safeResolveDidDoc = async (
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export const didDocForSession = async (
|
|
45
|
-
ctx:
|
|
46
|
+
ctx: { idResolver: IdResolver; cfg: ServerConfig },
|
|
46
47
|
did: string,
|
|
47
48
|
forceRefresh?: boolean,
|
|
48
49
|
): Promise<DidDocument | undefined> => {
|
|
@@ -51,7 +52,13 @@ export const didDocForSession = async (
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
export const isValidDidDocForService = async (
|
|
54
|
-
ctx:
|
|
55
|
+
ctx: {
|
|
56
|
+
plcClient: plc.Client
|
|
57
|
+
idResolver: IdResolver
|
|
58
|
+
cfg: ServerConfig
|
|
59
|
+
plcRotationKey: crypto.Keypair
|
|
60
|
+
actorStore: ActorStore
|
|
61
|
+
},
|
|
55
62
|
did: string,
|
|
56
63
|
): Promise<boolean> => {
|
|
57
64
|
try {
|
|
@@ -63,7 +70,13 @@ export const isValidDidDocForService = async (
|
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
export const assertValidDidDocumentForService = async (
|
|
66
|
-
ctx:
|
|
73
|
+
ctx: {
|
|
74
|
+
plcClient: plc.Client
|
|
75
|
+
idResolver: IdResolver
|
|
76
|
+
cfg: ServerConfig
|
|
77
|
+
plcRotationKey: crypto.Keypair
|
|
78
|
+
actorStore: ActorStore
|
|
79
|
+
},
|
|
67
80
|
did: string,
|
|
68
81
|
) => {
|
|
69
82
|
if (did.startsWith('did:plc')) {
|
|
@@ -86,7 +99,11 @@ export const assertValidDidDocumentForService = async (
|
|
|
86
99
|
}
|
|
87
100
|
|
|
88
101
|
const assertValidDocContents = async (
|
|
89
|
-
ctx:
|
|
102
|
+
ctx: {
|
|
103
|
+
cfg: ServerConfig
|
|
104
|
+
plcRotationKey: crypto.Keypair
|
|
105
|
+
actorStore: ActorStore
|
|
106
|
+
},
|
|
90
107
|
did: string,
|
|
91
108
|
contents: {
|
|
92
109
|
signingKey?: string
|
package/src/config/config.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
BrandingInput as BrandingConfig,
|
|
6
6
|
HcaptchaConfig,
|
|
7
7
|
} from '@atproto/oauth-provider'
|
|
8
|
-
import { ensureValidDid } from '@atproto/syntax'
|
|
8
|
+
import { DidString, ensureValidDid, isValidDid } from '@atproto/syntax'
|
|
9
9
|
import { ServerEnvironment } from './env.js'
|
|
10
10
|
|
|
11
11
|
export type { BrandingConfig }
|
|
@@ -21,6 +21,11 @@ export const envToCfg = (env: ServerEnvironment): ServerConfig => {
|
|
|
21
21
|
? `http://localhost:${port}`
|
|
22
22
|
: `https://${hostname}`
|
|
23
23
|
const did = env.serviceDid ?? `did:web:${hostname}`
|
|
24
|
+
|
|
25
|
+
if (!isValidDid(did)) {
|
|
26
|
+
throw new Error(`Invalid service DID: ${did}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
24
29
|
const serviceCfg: ServerConfig['service'] = {
|
|
25
30
|
port,
|
|
26
31
|
hostname,
|
|
@@ -400,7 +405,7 @@ export type ServiceConfig = {
|
|
|
400
405
|
port: number
|
|
401
406
|
hostname: string
|
|
402
407
|
publicUrl: string
|
|
403
|
-
did:
|
|
408
|
+
did: DidString
|
|
404
409
|
version?: string
|
|
405
410
|
privacyPolicyUrl?: string
|
|
406
411
|
termsOfServiceUrl?: string
|
package/src/context.ts
CHANGED
|
@@ -277,15 +277,14 @@ export class AppContext {
|
|
|
277
277
|
)
|
|
278
278
|
|
|
279
279
|
const accountManager = new AccountManager(
|
|
280
|
+
cfg,
|
|
281
|
+
actorStore,
|
|
280
282
|
idResolver,
|
|
281
283
|
jwtSecretKey,
|
|
282
284
|
mailer,
|
|
283
285
|
sequencer,
|
|
284
286
|
plcClient,
|
|
285
287
|
plcRotationKey,
|
|
286
|
-
cfg.service.did,
|
|
287
|
-
cfg.identity.serviceHandleDomains,
|
|
288
|
-
cfg.db,
|
|
289
288
|
)
|
|
290
289
|
await accountManager.migrateOrThrow()
|
|
291
290
|
|
package/src/db/migrator.ts
CHANGED
package/src/db/pagination.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sql } from 'kysely'
|
|
1
|
+
import { SqlBool, sql } from 'kysely'
|
|
2
2
|
import { InvalidRequestError } from '@atproto/xrpc-server'
|
|
3
3
|
import { AnyQb, DbRef } from './util.js'
|
|
4
4
|
|
|
@@ -66,16 +66,16 @@ export abstract class GenericKeyset<R, LR extends LabeledResult> {
|
|
|
66
66
|
if (tryIndex) {
|
|
67
67
|
// The tryIndex param will likely disappear and become the default implementation: here for now for gradual rollout query-by-query.
|
|
68
68
|
if (direction === 'asc') {
|
|
69
|
-
return sql
|
|
69
|
+
return sql<SqlBool>`((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}))`
|
|
70
70
|
} else {
|
|
71
|
-
return sql
|
|
71
|
+
return sql<SqlBool>`((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}))`
|
|
72
72
|
}
|
|
73
73
|
} else {
|
|
74
74
|
// @NOTE this implementation can struggle to use an index on (primary, secondary) for pagination due to the "or" usage.
|
|
75
75
|
if (direction === 'asc') {
|
|
76
|
-
return sql
|
|
76
|
+
return sql<SqlBool>`((${this.primary} > ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} > ${labeled.secondary}))`
|
|
77
77
|
} else {
|
|
78
|
-
return sql
|
|
78
|
+
return sql<SqlBool>`((${this.primary} < ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} < ${labeled.secondary}))`
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -125,8 +125,8 @@ export const paginate = <
|
|
|
125
125
|
const { limit, cursor, keyset, direction = 'desc', tryIndex } = opts
|
|
126
126
|
const keysetSql = keyset.getSql(keyset.unpack(cursor), direction, tryIndex)
|
|
127
127
|
return qb
|
|
128
|
-
|
|
128
|
+
.$if(!!limit, (q) => q.limit(limit as number))
|
|
129
129
|
.orderBy(keyset.primary, direction)
|
|
130
130
|
.orderBy(keyset.secondary, direction)
|
|
131
|
-
|
|
131
|
+
.$if(!!keysetSql, (qb) => (keysetSql ? qb.where(keysetSql) : qb)) as QB
|
|
132
132
|
}
|
package/src/db/util.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
RawBuilder,
|
|
6
6
|
ReferenceExpression,
|
|
7
7
|
SelectQueryBuilder,
|
|
8
|
+
SqlBool,
|
|
8
9
|
SqliteAdapter,
|
|
9
10
|
SqliteIntrospector,
|
|
10
11
|
SqliteQueryCompiler,
|
|
@@ -14,7 +15,7 @@ import { retry } from '@atproto/common'
|
|
|
14
15
|
|
|
15
16
|
// Applies to repo_root or record table
|
|
16
17
|
export const notSoftDeletedClause = (alias: DbRef) => {
|
|
17
|
-
return sql
|
|
18
|
+
return sql<SqlBool>`${alias}."takedownRef" is null`
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export const softDeleted = (repoOrRecord: { takedownRef: string | null }) => {
|
|
@@ -92,7 +93,9 @@ const RETRY_ERRORS = new Set([
|
|
|
92
93
|
|
|
93
94
|
export type Ref = ReferenceExpression<any, any>
|
|
94
95
|
|
|
95
|
-
export type DbRef =
|
|
96
|
+
export type DbRef =
|
|
97
|
+
| RawBuilder<unknown>
|
|
98
|
+
| ReturnType<DynamicModule<unknown>['ref']>
|
|
96
99
|
|
|
97
100
|
export type AnyQb = SelectQueryBuilder<any, any, any>
|
|
98
101
|
|
package/src/mailer/index.ts
CHANGED
|
@@ -36,9 +36,10 @@ export class ServerMailer {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async sendResetPassword(
|
|
39
|
-
params: { handle: string; token: string },
|
|
39
|
+
params: { handle: string; token: string; locale?: string },
|
|
40
40
|
mailOpts: SendMailOptions,
|
|
41
41
|
) {
|
|
42
|
+
// @TODO (later) handle locale in the template
|
|
42
43
|
await this.sendTemplate('resetPassword', params, {
|
|
43
44
|
subject: 'Password Reset Requested',
|
|
44
45
|
...mailOpts,
|
|
@@ -46,9 +47,10 @@ export class ServerMailer {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
async sendAccountDelete(
|
|
49
|
-
params: { token: string },
|
|
50
|
+
params: { token: string; locale?: string },
|
|
50
51
|
mailOpts: SendMailOptions,
|
|
51
52
|
) {
|
|
53
|
+
// @TODO (later) handle locale in the template
|
|
52
54
|
await this.sendTemplate('deleteAccount', params, {
|
|
53
55
|
subject: 'Account Deletion Requested',
|
|
54
56
|
...mailOpts,
|
|
@@ -35,7 +35,7 @@ export const getAndMigrateRecoveryDb = async (
|
|
|
35
35
|
const pragmas: Record<string, string> = disableWalAutoCheckpoint
|
|
36
36
|
? { wal_autocheckpoint: '0' }
|
|
37
37
|
: {}
|
|
38
|
-
const db = Database.sqlite(location, pragmas)
|
|
38
|
+
const db = Database.sqlite<RecoveryDbSchema>(location, pragmas)
|
|
39
39
|
const migrator = new Migrator(db.db, migrations)
|
|
40
40
|
await migrator.migrateToLatestOrThrow()
|
|
41
41
|
return db
|
package/src/sequencer/events.ts
CHANGED
|
@@ -83,12 +83,10 @@ export const formatSeqIdentityEvt = async (
|
|
|
83
83
|
did: DidString,
|
|
84
84
|
handle?: HandleString,
|
|
85
85
|
): Promise<RepoSeqInsert> => {
|
|
86
|
-
const evt: IdentityEvt =
|
|
87
|
-
did,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
evt.handle = handle
|
|
91
|
-
}
|
|
86
|
+
const evt: IdentityEvt = handle //
|
|
87
|
+
? { did, handle }
|
|
88
|
+
: { did }
|
|
89
|
+
|
|
92
90
|
return {
|
|
93
91
|
did,
|
|
94
92
|
eventType: 'identity',
|
|
@@ -101,13 +99,10 @@ export const formatSeqAccountEvt = async (
|
|
|
101
99
|
did: DidString,
|
|
102
100
|
status: AccountStatus,
|
|
103
101
|
): Promise<RepoSeqInsert> => {
|
|
104
|
-
const evt: AccountEvt =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (status !== AccountStatus.Active) {
|
|
109
|
-
evt.status = status
|
|
110
|
-
}
|
|
102
|
+
const evt: AccountEvt =
|
|
103
|
+
status === AccountStatus.Active
|
|
104
|
+
? { did, active: true }
|
|
105
|
+
: { did, active: false, status }
|
|
111
106
|
|
|
112
107
|
return {
|
|
113
108
|
did,
|
|
@@ -162,9 +162,7 @@ export class Sequencer extends (EventEmitter as new () => SequencerEmitter) {
|
|
|
162
162
|
await wait(waitTime)
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
events: readonly RepoSeqInsert[],
|
|
167
|
-
): Promise<number[]> {
|
|
165
|
+
async sequenceEvts(events: readonly RepoSeqInsert[]): Promise<number[]> {
|
|
168
166
|
if (!events.length) return []
|
|
169
167
|
const rows = await this.db.executeWithRetry(
|
|
170
168
|
this.db.db.insertInto('repo_seq').values(events).returning('seq'),
|
|
@@ -134,6 +134,7 @@ describe('account manager', () => {
|
|
|
134
134
|
const [params] = sendResetPasswordMock.mock.lastCall!
|
|
135
135
|
expect(params).toEqual({
|
|
136
136
|
handle: 'bob.test',
|
|
137
|
+
locale: 'fr',
|
|
137
138
|
token: expect.any(String),
|
|
138
139
|
})
|
|
139
140
|
|
|
@@ -380,4 +381,82 @@ describe('account manager', () => {
|
|
|
380
381
|
await page.clickOnText('Retour')
|
|
381
382
|
await page.ensureTextVisibility('bob-renamed.test', 'span')
|
|
382
383
|
})
|
|
384
|
+
|
|
385
|
+
it('allows deactivating & reactivating the account', async () => {
|
|
386
|
+
await using page = await PageHelper.from(browser, { languages })
|
|
387
|
+
|
|
388
|
+
await page.goto(new URL('/account', network.pds.url))
|
|
389
|
+
|
|
390
|
+
await page.assertTitle('Mon compte Atmosphère')
|
|
391
|
+
|
|
392
|
+
await page.clickOnText('Compte utilisateur', 'a')
|
|
393
|
+
|
|
394
|
+
await page.clickOnText('Désactiver le compte')
|
|
395
|
+
|
|
396
|
+
await page.ensureTextVisibility(
|
|
397
|
+
'limite de temps pour la désactivation du compte',
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
await page.clickOnText('Oui, désactiver')
|
|
401
|
+
|
|
402
|
+
await page.waitForNetworkIdle()
|
|
403
|
+
|
|
404
|
+
// The row should now offer re-activation
|
|
405
|
+
await page.ensureTextVisibility('Réactiver le compte', 'span')
|
|
406
|
+
|
|
407
|
+
await page.clickOnText('Réactiver le compte')
|
|
408
|
+
|
|
409
|
+
// @NOTE The dialog's submit label ("Réactiver") is a substring of the
|
|
410
|
+
// trigger row ("Réactiver le compte"), which comes first in DOM order, so
|
|
411
|
+
// we target the dialog's submit button instead of using its text.
|
|
412
|
+
await page.clickOn('[role="dialog"] button[type="submit"]')
|
|
413
|
+
|
|
414
|
+
await page.waitForNetworkIdle()
|
|
415
|
+
|
|
416
|
+
await page.ensureTextVisibility('Désactiver le compte', 'span')
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
it('allows deleting the account', async () => {
|
|
420
|
+
await using page = await PageHelper.from(browser, { languages })
|
|
421
|
+
|
|
422
|
+
await page.goto(new URL('/account', network.pds.url))
|
|
423
|
+
|
|
424
|
+
await page.assertTitle('Mon compte Atmosphère')
|
|
425
|
+
|
|
426
|
+
await page.clickOnText('Compte utilisateur', 'a')
|
|
427
|
+
|
|
428
|
+
await page.clickOnText('Supprimer le compte')
|
|
429
|
+
|
|
430
|
+
using sendAccountDeleteMock = jest
|
|
431
|
+
.spyOn(network.pds.ctx.mailer, 'sendAccountDelete')
|
|
432
|
+
.mockImplementation(async () => {
|
|
433
|
+
// noop
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
await page.clickOnText("Envoyer l'email")
|
|
437
|
+
|
|
438
|
+
await page.waitForNetworkIdle()
|
|
439
|
+
|
|
440
|
+
expect(sendAccountDeleteMock).toHaveBeenCalledTimes(1)
|
|
441
|
+
|
|
442
|
+
const [params] = sendAccountDeleteMock.mock.lastCall!
|
|
443
|
+
expect(params).toEqual({
|
|
444
|
+
locale: 'fr',
|
|
445
|
+
token: expect.any(String),
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
await page.typeInInput('code', params.token)
|
|
449
|
+
await page.typeInInput('password', 'bob-new-pass')
|
|
450
|
+
|
|
451
|
+
await page.clickOnText('Supprimer mon compte')
|
|
452
|
+
|
|
453
|
+
// A final confirmation step is displayed
|
|
454
|
+
await page.ensureTextVisibility('Êtes-vous vraiment, vraiment sûr ?', 'h2')
|
|
455
|
+
|
|
456
|
+
await page.clickOnText('Oui, supprimer mon compte')
|
|
457
|
+
|
|
458
|
+
// Once the account is deleted, the session is gone and the user is
|
|
459
|
+
// brought back to the sign-in page.
|
|
460
|
+
await page.assertTitle('Se connecter')
|
|
461
|
+
})
|
|
383
462
|
})
|