@atproto/ozone 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/LICENSE.txt +7 -0
- package/README.md +15 -0
- package/babel.config.js +3 -0
- package/bin/migration-create.ts +38 -0
- package/build.js +18 -0
- package/dist/api/admin/emitModerationEvent.d.ts +3 -0
- package/dist/api/admin/getModerationEvent.d.ts +3 -0
- package/dist/api/admin/getRecord.d.ts +3 -0
- package/dist/api/admin/getRepo.d.ts +3 -0
- package/dist/api/admin/queryModerationEvents.d.ts +3 -0
- package/dist/api/admin/queryModerationStatuses.d.ts +3 -0
- package/dist/api/admin/searchRepos.d.ts +3 -0
- package/dist/api/admin/util.d.ts +5 -0
- package/dist/api/com/atproto/admin/emitModerationEvent.d.ts +3 -0
- package/dist/api/com/atproto/admin/getModerationEvent.d.ts +3 -0
- package/dist/api/com/atproto/admin/getRecord.d.ts +3 -0
- package/dist/api/com/atproto/admin/getRepo.d.ts +3 -0
- package/dist/api/com/atproto/admin/queryModerationEvents.d.ts +3 -0
- package/dist/api/com/atproto/admin/queryModerationStatuses.d.ts +3 -0
- package/dist/api/com/atproto/admin/searchRepos.d.ts +3 -0
- package/dist/api/com/atproto/admin/util.d.ts +5 -0
- package/dist/api/com/atproto/moderation/createReport.d.ts +3 -0
- package/dist/api/com/atproto/moderation/util.d.ts +4 -0
- package/dist/api/com/atproto/temp/fetchLabels.d.ts +3 -0
- package/dist/api/health.d.ts +3 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/label/queryLabels.d.ts +3 -0
- package/dist/api/label/subscribeLabels.d.ts +3 -0
- package/dist/api/moderation/createReport.d.ts +3 -0
- package/dist/api/moderation/util.d.ts +4 -0
- package/dist/api/temp/fetchLabels.d.ts +3 -0
- package/dist/api/util.d.ts +2 -0
- package/dist/api/well-known.d.ts +3 -0
- package/dist/auth-verifier.d.ts +47 -0
- package/dist/auth.d.ts +81 -0
- package/dist/background.d.ts +13 -0
- package/dist/config/config.d.ts +30 -0
- package/dist/config/env.d.ts +19 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/secrets.d.ts +8 -0
- package/dist/config.d.ts +42 -0
- package/dist/context.d.ts +140 -0
- package/dist/daemon/config.d.ts +23 -0
- package/dist/daemon/context.d.ts +25 -0
- package/dist/daemon/event-pusher.d.ts +48 -0
- package/dist/daemon/event-reverser.d.ts +16 -0
- package/dist/daemon/index.d.ts +13 -0
- package/dist/db/index.d.ts +32 -0
- package/dist/db/index.js +33707 -0
- package/dist/db/index.js.map +7 -0
- package/dist/db/migrations/20231219T205730722Z-init.d.ts +3 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/db/migrations/provider.d.ts +11 -0
- package/dist/db/pagination.d.ts +66 -0
- package/dist/db/schema/blob_push_event.d.ts +17 -0
- package/dist/db/schema/index.d.ts +10 -0
- package/dist/db/schema/label.d.ts +12 -0
- package/dist/db/schema/moderation_event.d.ts +22 -0
- package/dist/db/schema/moderation_subject_status.d.ts +25 -0
- package/dist/db/schema/record_push_event.d.ts +17 -0
- package/dist/db/schema/repo_push_event.d.ts +15 -0
- package/dist/db/types.d.ts +12 -0
- package/dist/error.d.ts +2 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +131818 -0
- package/dist/index.js.map +7 -0
- package/dist/lexicon/index.d.ts +372 -0
- package/dist/lexicon/lexicons.d.ts +7553 -0
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +104 -0
- package/dist/lexicon/types/app/bsky/actor/getPreferences.d.ts +31 -0
- package/dist/lexicon/types/app/bsky/actor/getProfile.d.ts +29 -0
- package/dist/lexicon/types/app/bsky/actor/getProfiles.d.ts +32 -0
- package/dist/lexicon/types/app/bsky/actor/getSuggestions.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/actor/profile.d.ts +15 -0
- package/dist/lexicon/types/app/bsky/actor/putPreferences.d.ts +26 -0
- package/dist/lexicon/types/app/bsky/actor/searchActors.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/actor/searchActorsTypeahead.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/embed/external.d.ts +31 -0
- package/dist/lexicon/types/app/bsky/embed/images.d.ts +37 -0
- package/dist/lexicon/types/app/bsky/embed/record.d.ts +54 -0
- package/dist/lexicon/types/app/bsky/embed/recordWithMedia.d.ts +24 -0
- package/dist/lexicon/types/app/bsky/feed/defs.d.ts +151 -0
- package/dist/lexicon/types/app/bsky/feed/describeFeedGenerator.d.ts +46 -0
- package/dist/lexicon/types/app/bsky/feed/generator.d.ts +18 -0
- package/dist/lexicon/types/app/bsky/feed/getActorFeeds.d.ts +35 -0
- package/dist/lexicon/types/app/bsky/feed/getActorLikes.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/feed/getAuthorFeed.d.ts +37 -0
- package/dist/lexicon/types/app/bsky/feed/getFeed.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/feed/getFeedGenerator.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/feed/getFeedGenerators.d.ts +32 -0
- package/dist/lexicon/types/app/bsky/feed/getFeedSkeleton.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/feed/getLikes.d.ts +47 -0
- package/dist/lexicon/types/app/bsky/feed/getListFeed.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/feed/getPostThread.d.ts +38 -0
- package/dist/lexicon/types/app/bsky/feed/getPosts.d.ts +32 -0
- package/dist/lexicon/types/app/bsky/feed/getRepostedBy.d.ts +38 -0
- package/dist/lexicon/types/app/bsky/feed/getSuggestedFeeds.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/feed/getTimeline.d.ts +35 -0
- package/dist/lexicon/types/app/bsky/feed/like.d.ts +9 -0
- package/dist/lexicon/types/app/bsky/feed/post.d.ts +50 -0
- package/dist/lexicon/types/app/bsky/feed/repost.d.ts +9 -0
- package/dist/lexicon/types/app/bsky/feed/searchPosts.d.ts +37 -0
- package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts +28 -0
- package/dist/lexicon/types/app/bsky/graph/block.d.ts +8 -0
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts +47 -0
- package/dist/lexicon/types/app/bsky/graph/follow.d.ts +8 -0
- package/dist/lexicon/types/app/bsky/graph/getBlocks.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/graph/getFollowers.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/graph/getFollows.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/graph/getList.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/graph/getListBlocks.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/graph/getListMutes.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/graph/getLists.d.ts +35 -0
- package/dist/lexicon/types/app/bsky/graph/getMutes.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.d.ts +32 -0
- package/dist/lexicon/types/app/bsky/graph/list.d.ts +19 -0
- package/dist/lexicon/types/app/bsky/graph/listblock.d.ts +8 -0
- package/dist/lexicon/types/app/bsky/graph/listitem.d.ts +9 -0
- package/dist/lexicon/types/app/bsky/graph/muteActor.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/graph/muteActorList.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/graph/unmuteActor.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/graph/unmuteActorList.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/moderation/defs.d.ts +49 -0
- package/dist/lexicon/types/app/bsky/moderation/getService.d.ts +29 -0
- package/dist/lexicon/types/app/bsky/moderation/getServices.d.ts +32 -0
- package/dist/lexicon/types/app/bsky/moderation/service.d.ts +17 -0
- package/dist/lexicon/types/app/bsky/notification/getUnreadCount.d.ts +31 -0
- package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +52 -0
- package/dist/lexicon/types/app/bsky/notification/registerPush.d.ts +28 -0
- package/dist/lexicon/types/app/bsky/notification/updateSeen.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/richtext/facet.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts +13 -0
- package/dist/lexicon/types/app/bsky/unspecced/getPopular.d.ts +35 -0
- package/dist/lexicon/types/app/bsky/unspecced/getPopularFeedGenerators.d.ts +35 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTimelineSkeleton.d.ts +35 -0
- package/dist/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.d.ts +38 -0
- package/dist/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.d.ts +37 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +319 -0
- package/dist/lexicon/types/com/atproto/admin/deleteAccount.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/admin/disableAccountInvites.d.ts +26 -0
- package/dist/lexicon/types/com/atproto/admin/disableInviteCodes.d.ts +26 -0
- package/dist/lexicon/types/com/atproto/admin/emitModerationEvent.d.ts +45 -0
- package/dist/lexicon/types/com/atproto/admin/enableAccountInvites.d.ts +26 -0
- package/dist/lexicon/types/com/atproto/admin/getAccountInfo.d.ts +29 -0
- package/dist/lexicon/types/com/atproto/admin/getAccountInfos.d.ts +32 -0
- package/dist/lexicon/types/com/atproto/admin/getInviteCodes.d.ts +35 -0
- package/dist/lexicon/types/com/atproto/admin/getModerationEvent.d.ts +29 -0
- package/dist/lexicon/types/com/atproto/admin/getRecord.d.ts +31 -0
- package/dist/lexicon/types/com/atproto/admin/getRepo.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/admin/getSubjectStatus.d.ts +39 -0
- package/dist/lexicon/types/com/atproto/admin/queryModerationEvents.d.ts +39 -0
- package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +48 -0
- package/dist/lexicon/types/com/atproto/admin/searchRepos.d.ts +36 -0
- package/dist/lexicon/types/com/atproto/admin/sendEmail.d.ts +40 -0
- package/dist/lexicon/types/com/atproto/admin/updateAccountEmail.d.ts +26 -0
- package/dist/lexicon/types/com/atproto/admin/updateAccountHandle.d.ts +26 -0
- package/dist/lexicon/types/com/atproto/admin/updateSubjectStatus.d.ts +46 -0
- package/dist/lexicon/types/com/atproto/identity/resolveHandle.d.ts +31 -0
- package/dist/lexicon/types/com/atproto/identity/updateHandle.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/label/defs.d.ts +24 -0
- package/dist/lexicon/types/com/atproto/label/queryLabels.d.ts +36 -0
- package/dist/lexicon/types/com/atproto/label/subscribeLabels.d.ts +36 -0
- package/dist/lexicon/types/com/atproto/moderation/createReport.d.ts +52 -0
- package/dist/lexicon/types/com/atproto/moderation/defs.d.ts +8 -0
- package/dist/lexicon/types/com/atproto/repo/applyWrites.d.ts +53 -0
- package/dist/lexicon/types/com/atproto/repo/createRecord.d.ts +43 -0
- package/dist/lexicon/types/com/atproto/repo/deleteRecord.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/repo/describeRepo.d.ts +35 -0
- package/dist/lexicon/types/com/atproto/repo/getRecord.d.ts +36 -0
- package/dist/lexicon/types/com/atproto/repo/listRecords.d.ts +47 -0
- package/dist/lexicon/types/com/atproto/repo/putRecord.d.ts +44 -0
- package/dist/lexicon/types/com/atproto/repo/strongRef.d.ts +8 -0
- package/dist/lexicon/types/com/atproto/repo/uploadBlob.d.ts +36 -0
- package/dist/lexicon/types/com/atproto/server/confirmEmail.d.ts +27 -0
- package/dist/lexicon/types/com/atproto/server/createAccount.d.ts +49 -0
- package/dist/lexicon/types/com/atproto/server/createAppPassword.d.ts +43 -0
- package/dist/lexicon/types/com/atproto/server/createInviteCode.d.ts +37 -0
- package/dist/lexicon/types/com/atproto/server/createInviteCodes.d.ts +46 -0
- package/dist/lexicon/types/com/atproto/server/createSession.d.ts +44 -0
- package/dist/lexicon/types/com/atproto/server/defs.d.ts +20 -0
- package/dist/lexicon/types/com/atproto/server/deleteAccount.d.ts +28 -0
- package/dist/lexicon/types/com/atproto/server/deleteSession.d.ts +19 -0
- package/dist/lexicon/types/com/atproto/server/describeServer.d.ts +41 -0
- package/dist/lexicon/types/com/atproto/server/getAccountInviteCodes.d.ts +34 -0
- package/dist/lexicon/types/com/atproto/server/getSession.d.ts +34 -0
- package/dist/lexicon/types/com/atproto/server/listAppPasswords.d.ts +39 -0
- package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts +35 -0
- package/dist/lexicon/types/com/atproto/server/requestAccountDelete.d.ts +19 -0
- package/dist/lexicon/types/com/atproto/server/requestEmailConfirmation.d.ts +19 -0
- package/dist/lexicon/types/com/atproto/server/requestEmailUpdate.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/server/requestPasswordReset.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/server/reserveSigningKey.d.ts +36 -0
- package/dist/lexicon/types/com/atproto/server/resetPassword.d.ts +27 -0
- package/dist/lexicon/types/com/atproto/server/revokeAppPassword.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/server/updateEmail.d.ts +27 -0
- package/dist/lexicon/types/com/atproto/sync/getBlob.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/sync/getBlocks.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/sync/getCheckout.d.ts +29 -0
- package/dist/lexicon/types/com/atproto/sync/getHead.d.ts +32 -0
- package/dist/lexicon/types/com/atproto/sync/getLatestCommit.d.ts +33 -0
- package/dist/lexicon/types/com/atproto/sync/getRecord.d.ts +32 -0
- package/dist/lexicon/types/com/atproto/sync/getRepo.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/sync/listBlobs.d.ts +35 -0
- package/dist/lexicon/types/com/atproto/sync/listRepos.d.ts +42 -0
- package/dist/lexicon/types/com/atproto/sync/notifyOfUpdate.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/sync/requestCrawl.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/sync/subscribeRepos.d.ts +80 -0
- package/dist/lexicon/types/com/atproto/temp/fetchLabels.d.ts +33 -0
- package/dist/lexicon/types/com/atproto/temp/importRepo.d.ts +32 -0
- package/dist/lexicon/types/com/atproto/temp/pushBlob.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/temp/requestPhoneVerification.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/temp/transferAccount.d.ts +42 -0
- package/dist/lexicon/util.d.ts +2 -0
- package/dist/logger.d.ts +4 -0
- package/dist/mod-service/index.d.ts +155 -0
- package/dist/mod-service/status.d.ts +12 -0
- package/dist/mod-service/subject.d.ts +59 -0
- package/dist/mod-service/types.d.ts +19 -0
- package/dist/mod-service/views.d.ts +49 -0
- package/dist/sequencer/index.d.ts +2 -0
- package/dist/sequencer/outbox.d.ts +16 -0
- package/dist/sequencer/sequencer.d.ts +35 -0
- package/dist/services/index.d.ts +7 -0
- package/dist/services/moderation/index.d.ts +144 -0
- package/dist/services/moderation/status.d.ts +12 -0
- package/dist/services/moderation/subject.d.ts +60 -0
- package/dist/services/moderation/types.d.ts +19 -0
- package/dist/services/moderation/views.d.ts +42 -0
- package/dist/services/types.d.ts +2 -0
- package/dist/util/date.d.ts +1 -0
- package/dist/util/debug.d.ts +1 -0
- package/dist/util/retry.d.ts +3 -0
- package/dist/util.d.ts +3 -0
- package/jest.config.js +6 -0
- package/package.json +67 -0
- package/src/api/admin/emitModerationEvent.ts +130 -0
- package/src/api/admin/getModerationEvent.ts +19 -0
- package/src/api/admin/getRecord.ts +34 -0
- package/src/api/admin/getRepo.ts +31 -0
- package/src/api/admin/queryModerationEvents.ts +40 -0
- package/src/api/admin/queryModerationStatuses.ts +57 -0
- package/src/api/admin/searchRepos.ts +42 -0
- package/src/api/admin/util.ts +54 -0
- package/src/api/health.ts +20 -0
- package/src/api/index.ts +28 -0
- package/src/api/moderation/createReport.ts +41 -0
- package/src/api/moderation/util.ts +65 -0
- package/src/api/temp/fetchLabels.ts +29 -0
- package/src/api/well-known.ts +35 -0
- package/src/auth.ts +147 -0
- package/src/background.ts +35 -0
- package/src/config/config.ts +84 -0
- package/src/config/env.ts +41 -0
- package/src/config/index.ts +3 -0
- package/src/config/secrets.ts +23 -0
- package/src/context.ts +180 -0
- package/src/daemon/context.ts +90 -0
- package/src/daemon/event-pusher.ts +296 -0
- package/src/daemon/event-reverser.ts +74 -0
- package/src/daemon/index.ts +33 -0
- package/src/db/index.ts +197 -0
- package/src/db/migrations/20231219T205730722Z-init.ts +164 -0
- package/src/db/migrations/index.ts +5 -0
- package/src/db/migrations/provider.ts +25 -0
- package/src/db/pagination.ts +216 -0
- package/src/db/schema/blob_push_event.ts +21 -0
- package/src/db/schema/index.ts +18 -0
- package/src/db/schema/label.ts +12 -0
- package/src/db/schema/moderation_event.ts +35 -0
- package/src/db/schema/moderation_subject_status.ts +32 -0
- package/src/db/schema/record_push_event.ts +21 -0
- package/src/db/schema/repo_push_event.ts +19 -0
- package/src/db/types.ts +15 -0
- package/src/error.ts +12 -0
- package/src/index.ts +102 -0
- package/src/lexicon/index.ts +1626 -0
- package/src/lexicon/lexicons.ts +8050 -0
- package/src/lexicon/types/app/bsky/actor/defs.ts +235 -0
- package/src/lexicon/types/app/bsky/actor/getPreferences.ts +44 -0
- package/src/lexicon/types/app/bsky/actor/getProfile.ts +41 -0
- package/src/lexicon/types/app/bsky/actor/getProfiles.ts +46 -0
- package/src/lexicon/types/app/bsky/actor/getSuggestions.ts +48 -0
- package/src/lexicon/types/app/bsky/actor/profile.ts +32 -0
- package/src/lexicon/types/app/bsky/actor/putPreferences.ts +39 -0
- package/src/lexicon/types/app/bsky/actor/searchActors.ts +52 -0
- package/src/lexicon/types/app/bsky/actor/searchActorsTypeahead.ts +50 -0
- package/src/lexicon/types/app/bsky/embed/external.ts +82 -0
- package/src/lexicon/types/app/bsky/embed/images.ts +96 -0
- package/src/lexicon/types/app/bsky/embed/record.ts +120 -0
- package/src/lexicon/types/app/bsky/embed/recordWithMedia.ts +53 -0
- package/src/lexicon/types/app/bsky/feed/defs.ts +308 -0
- package/src/lexicon/types/app/bsky/feed/describeFeedGenerator.ts +80 -0
- package/src/lexicon/types/app/bsky/feed/generator.ts +35 -0
- package/src/lexicon/types/app/bsky/feed/getActorFeeds.ts +49 -0
- package/src/lexicon/types/app/bsky/feed/getActorLikes.ts +50 -0
- package/src/lexicon/types/app/bsky/feed/getAuthorFeed.ts +56 -0
- package/src/lexicon/types/app/bsky/feed/getFeed.ts +50 -0
- package/src/lexicon/types/app/bsky/feed/getFeedGenerator.ts +48 -0
- package/src/lexicon/types/app/bsky/feed/getFeedGenerators.ts +46 -0
- package/src/lexicon/types/app/bsky/feed/getFeedSkeleton.ts +50 -0
- package/src/lexicon/types/app/bsky/feed/getLikes.ts +69 -0
- package/src/lexicon/types/app/bsky/feed/getListFeed.ts +50 -0
- package/src/lexicon/types/app/bsky/feed/getPostThread.ts +53 -0
- package/src/lexicon/types/app/bsky/feed/getPosts.ts +46 -0
- package/src/lexicon/types/app/bsky/feed/getRepostedBy.ts +52 -0
- package/src/lexicon/types/app/bsky/feed/getSuggestedFeeds.ts +48 -0
- package/src/lexicon/types/app/bsky/feed/getTimeline.ts +49 -0
- package/src/lexicon/types/app/bsky/feed/like.ts +26 -0
- package/src/lexicon/types/app/bsky/feed/post.ts +102 -0
- package/src/lexicon/types/app/bsky/feed/repost.ts +27 -0
- package/src/lexicon/types/app/bsky/feed/searchPosts.ts +54 -0
- package/src/lexicon/types/app/bsky/feed/threadgate.ts +84 -0
- package/src/lexicon/types/app/bsky/graph/block.ts +26 -0
- package/src/lexicon/types/app/bsky/graph/defs.ts +104 -0
- package/src/lexicon/types/app/bsky/graph/follow.ts +26 -0
- package/src/lexicon/types/app/bsky/graph/getBlocks.ts +48 -0
- package/src/lexicon/types/app/bsky/graph/getFollowers.ts +50 -0
- package/src/lexicon/types/app/bsky/graph/getFollows.ts +50 -0
- package/src/lexicon/types/app/bsky/graph/getList.ts +50 -0
- package/src/lexicon/types/app/bsky/graph/getListBlocks.ts +48 -0
- package/src/lexicon/types/app/bsky/graph/getListMutes.ts +48 -0
- package/src/lexicon/types/app/bsky/graph/getLists.ts +49 -0
- package/src/lexicon/types/app/bsky/graph/getMutes.ts +48 -0
- package/src/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.ts +46 -0
- package/src/lexicon/types/app/bsky/graph/list.ts +36 -0
- package/src/lexicon/types/app/bsky/graph/listblock.ts +26 -0
- package/src/lexicon/types/app/bsky/graph/listitem.ts +27 -0
- package/src/lexicon/types/app/bsky/graph/muteActor.ts +38 -0
- package/src/lexicon/types/app/bsky/graph/muteActorList.ts +38 -0
- package/src/lexicon/types/app/bsky/graph/unmuteActor.ts +38 -0
- package/src/lexicon/types/app/bsky/graph/unmuteActorList.ts +38 -0
- package/src/lexicon/types/app/bsky/notification/getUnreadCount.ts +45 -0
- package/src/lexicon/types/app/bsky/notification/listNotifications.ts +87 -0
- package/src/lexicon/types/app/bsky/notification/registerPush.ts +41 -0
- package/src/lexicon/types/app/bsky/notification/updateSeen.ts +38 -0
- package/src/lexicon/types/app/bsky/richtext/facet.ts +97 -0
- package/src/lexicon/types/app/bsky/unspecced/defs.ts +41 -0
- package/src/lexicon/types/app/bsky/unspecced/getPopularFeedGenerators.ts +49 -0
- package/src/lexicon/types/app/bsky/unspecced/getTimelineSkeleton.ts +49 -0
- package/src/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.ts +56 -0
- package/src/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.ts +54 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +719 -0
- package/src/lexicon/types/com/atproto/admin/deleteAccount.ts +38 -0
- package/src/lexicon/types/com/atproto/admin/disableAccountInvites.ts +40 -0
- package/src/lexicon/types/com/atproto/admin/disableInviteCodes.ts +39 -0
- package/src/lexicon/types/com/atproto/admin/emitModerationEvent.ts +66 -0
- package/src/lexicon/types/com/atproto/admin/enableAccountInvites.ts +40 -0
- package/src/lexicon/types/com/atproto/admin/getAccountInfo.ts +41 -0
- package/src/lexicon/types/com/atproto/admin/getAccountInfos.ts +46 -0
- package/src/lexicon/types/com/atproto/admin/getInviteCodes.ts +49 -0
- package/src/lexicon/types/com/atproto/admin/getModerationEvent.ts +41 -0
- package/src/lexicon/types/com/atproto/admin/getRecord.ts +43 -0
- package/src/lexicon/types/com/atproto/admin/getRepo.ts +42 -0
- package/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts +54 -0
- package/src/lexicon/types/com/atproto/admin/queryModerationEvents.ts +56 -0
- package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +72 -0
- package/src/lexicon/types/com/atproto/admin/searchRepos.ts +51 -0
- package/src/lexicon/types/com/atproto/admin/sendEmail.ts +54 -0
- package/src/lexicon/types/com/atproto/admin/updateAccountEmail.ts +40 -0
- package/src/lexicon/types/com/atproto/admin/updateAccountHandle.ts +39 -0
- package/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts +61 -0
- package/src/lexicon/types/com/atproto/identity/resolveHandle.ts +46 -0
- package/src/lexicon/types/com/atproto/identity/updateHandle.ts +38 -0
- package/src/lexicon/types/com/atproto/label/defs.ts +73 -0
- package/src/lexicon/types/com/atproto/label/queryLabels.ts +52 -0
- package/src/lexicon/types/com/atproto/label/subscribeLabels.ts +67 -0
- package/src/lexicon/types/com/atproto/moderation/createReport.ts +65 -0
- package/src/lexicon/types/com/atproto/moderation/defs.ts +32 -0
- package/src/lexicon/types/com/atproto/repo/applyWrites.ts +103 -0
- package/src/lexicon/types/com/atproto/repo/createRecord.ts +62 -0
- package/src/lexicon/types/com/atproto/repo/deleteRecord.ts +48 -0
- package/src/lexicon/types/com/atproto/repo/describeRepo.ts +50 -0
- package/src/lexicon/types/com/atproto/repo/getRecord.ts +54 -0
- package/src/lexicon/types/com/atproto/repo/listRecords.ts +77 -0
- package/src/lexicon/types/com/atproto/repo/putRecord.ts +64 -0
- package/src/lexicon/types/com/atproto/repo/strongRef.ts +26 -0
- package/src/lexicon/types/com/atproto/repo/uploadBlob.ts +47 -0
- package/src/lexicon/types/com/atproto/server/confirmEmail.ts +40 -0
- package/src/lexicon/types/com/atproto/server/createAccount.ts +69 -0
- package/src/lexicon/types/com/atproto/server/createAppPassword.ts +69 -0
- package/src/lexicon/types/com/atproto/server/createInviteCode.ts +50 -0
- package/src/lexicon/types/com/atproto/server/createInviteCodes.ts +72 -0
- package/src/lexicon/types/com/atproto/server/createSession.ts +58 -0
- package/src/lexicon/types/com/atproto/server/defs.ts +48 -0
- package/src/lexicon/types/com/atproto/server/deleteAccount.ts +41 -0
- package/src/lexicon/types/com/atproto/server/deleteSession.ts +31 -0
- package/src/lexicon/types/com/atproto/server/describeServer.ts +64 -0
- package/src/lexicon/types/com/atproto/server/getAccountInviteCodes.ts +48 -0
- package/src/lexicon/types/com/atproto/server/getSession.ts +47 -0
- package/src/lexicon/types/com/atproto/server/listAppPasswords.ts +62 -0
- package/src/lexicon/types/com/atproto/server/refreshSession.ts +48 -0
- package/src/lexicon/types/com/atproto/server/requestAccountDelete.ts +31 -0
- package/src/lexicon/types/com/atproto/server/requestEmailConfirmation.ts +31 -0
- package/src/lexicon/types/com/atproto/server/requestEmailUpdate.ts +43 -0
- package/src/lexicon/types/com/atproto/server/requestPasswordReset.ts +38 -0
- package/src/lexicon/types/com/atproto/server/reserveSigningKey.ts +51 -0
- package/src/lexicon/types/com/atproto/server/resetPassword.ts +40 -0
- package/src/lexicon/types/com/atproto/server/revokeAppPassword.ts +38 -0
- package/src/lexicon/types/com/atproto/server/updateEmail.ts +41 -0
- package/src/lexicon/types/com/atproto/sync/getBlob.ts +43 -0
- package/src/lexicon/types/com/atproto/sync/getBlocks.ts +42 -0
- package/src/lexicon/types/com/atproto/sync/getCheckout.ts +41 -0
- package/src/lexicon/types/com/atproto/sync/getHead.ts +47 -0
- package/src/lexicon/types/com/atproto/sync/getLatestCommit.ts +48 -0
- package/src/lexicon/types/com/atproto/sync/getRecord.ts +45 -0
- package/src/lexicon/types/com/atproto/sync/getRepo.ts +43 -0
- package/src/lexicon/types/com/atproto/sync/listBlobs.ts +51 -0
- package/src/lexicon/types/com/atproto/sync/listRepos.ts +66 -0
- package/src/lexicon/types/com/atproto/sync/notifyOfUpdate.ts +39 -0
- package/src/lexicon/types/com/atproto/sync/requestCrawl.ts +39 -0
- package/src/lexicon/types/com/atproto/sync/subscribeRepos.ts +161 -0
- package/src/lexicon/types/com/atproto/temp/fetchLabels.ts +47 -0
- package/src/lexicon/types/com/atproto/temp/importRepo.ts +45 -0
- package/src/lexicon/types/com/atproto/temp/pushBlob.ts +39 -0
- package/src/lexicon/types/com/atproto/temp/requestPhoneVerification.ts +38 -0
- package/src/lexicon/types/com/atproto/temp/transferAccount.ts +62 -0
- package/src/lexicon/util.ts +13 -0
- package/src/logger.ts +19 -0
- package/src/mod-service/index.ts +758 -0
- package/src/mod-service/status.ts +264 -0
- package/src/mod-service/subject.ts +136 -0
- package/src/mod-service/types.ts +32 -0
- package/src/mod-service/views.ts +531 -0
- package/src/util.ts +26 -0
- package/test.env +2 -0
- package/test.log +0 -0
- package/tests/__snapshots__/get-record.test.ts.snap +173 -0
- package/tests/__snapshots__/get-repo.test.ts.snap +57 -0
- package/tests/__snapshots__/moderation-events.test.ts.snap +168 -0
- package/tests/__snapshots__/moderation-statuses.test.ts.snap +64 -0
- package/tests/__snapshots__/moderation.test.ts.snap +55 -0
- package/tests/_util.ts +192 -0
- package/tests/db.test.ts +184 -0
- package/tests/get-record.test.ts +110 -0
- package/tests/get-repo.test.ts +131 -0
- package/tests/moderation-appeals.test.ts +269 -0
- package/tests/moderation-events.test.ts +220 -0
- package/tests/moderation-statuses.test.ts +144 -0
- package/tests/moderation.test.ts +961 -0
- package/tests/repo-search.test.ts +123 -0
- package/tests/server.test.ts +76 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +21 -0
package/tests/_util.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { AtUri } from '@atproto/syntax'
|
|
2
|
+
import { lexToJson } from '@atproto/lexicon'
|
|
3
|
+
import { CID } from 'multiformats/cid'
|
|
4
|
+
import {
|
|
5
|
+
FeedViewPost,
|
|
6
|
+
PostView,
|
|
7
|
+
isPostView,
|
|
8
|
+
isThreadViewPost,
|
|
9
|
+
} from '../src/lexicon/types/app/bsky/feed/defs'
|
|
10
|
+
import { isViewRecord } from '../src/lexicon/types/app/bsky/embed/record'
|
|
11
|
+
|
|
12
|
+
// Swap out identifiers and dates with stable
|
|
13
|
+
// values for the purpose of snapshot testing
|
|
14
|
+
export const forSnapshot = (obj: unknown) => {
|
|
15
|
+
const records = { [kTake]: 'record' }
|
|
16
|
+
const collections = { [kTake]: 'collection' }
|
|
17
|
+
const users = { [kTake]: 'user' }
|
|
18
|
+
const cids = { [kTake]: 'cids' }
|
|
19
|
+
const unknown = { [kTake]: 'unknown' }
|
|
20
|
+
const toWalk = lexToJson(obj as any) // remove any blobrefs/cids
|
|
21
|
+
return mapLeafValues(toWalk, (item) => {
|
|
22
|
+
const asCid = CID.asCID(item)
|
|
23
|
+
if (asCid !== null) {
|
|
24
|
+
return take(cids, asCid.toString())
|
|
25
|
+
}
|
|
26
|
+
if (typeof item !== 'string') {
|
|
27
|
+
return item
|
|
28
|
+
}
|
|
29
|
+
const str = item.startsWith('did:plc:') ? `at://${item}` : item
|
|
30
|
+
if (str.startsWith('at://')) {
|
|
31
|
+
const uri = new AtUri(str)
|
|
32
|
+
if (uri.rkey) {
|
|
33
|
+
return take(records, str)
|
|
34
|
+
}
|
|
35
|
+
if (uri.collection) {
|
|
36
|
+
return take(collections, str)
|
|
37
|
+
}
|
|
38
|
+
if (uri.hostname) {
|
|
39
|
+
return take(users, str)
|
|
40
|
+
}
|
|
41
|
+
return take(unknown, str)
|
|
42
|
+
}
|
|
43
|
+
if (str.match(/^\d{4}-\d{2}-\d{2}T/)) {
|
|
44
|
+
if (str.match(/\d{6}Z$/)) {
|
|
45
|
+
return constantDate.replace('Z', '000Z') // e.g. microseconds in record createdAt
|
|
46
|
+
} else if (str.endsWith('+00:00')) {
|
|
47
|
+
return constantDate.replace('Z', '+00:00') // e.g. timezone in record createdAt
|
|
48
|
+
} else {
|
|
49
|
+
return constantDate
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (str.match(/^\d+::bafy/)) {
|
|
53
|
+
return constantKeysetCursor
|
|
54
|
+
}
|
|
55
|
+
if (str.match(/\/img\/[^/]+\/.+\/did:plc:[^/]+\/[^/]+@[\w]+$/)) {
|
|
56
|
+
// Match image urls
|
|
57
|
+
const match = str.match(
|
|
58
|
+
/\/img\/[^/]+\/.+\/(did:plc:[^/]+)\/([^/]+)@[\w]+$/,
|
|
59
|
+
)
|
|
60
|
+
if (!match) return str
|
|
61
|
+
const [, did, cid] = match
|
|
62
|
+
return str.replace(did, take(users, did)).replace(cid, take(cids, cid))
|
|
63
|
+
}
|
|
64
|
+
let isCid: boolean
|
|
65
|
+
try {
|
|
66
|
+
CID.parse(str)
|
|
67
|
+
isCid = true
|
|
68
|
+
} catch (_err) {
|
|
69
|
+
isCid = false
|
|
70
|
+
}
|
|
71
|
+
if (isCid) {
|
|
72
|
+
return take(cids, str)
|
|
73
|
+
}
|
|
74
|
+
return item
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Feed testing utils
|
|
79
|
+
|
|
80
|
+
export const getOriginator = (item: FeedViewPost) => {
|
|
81
|
+
if (!item.reason) {
|
|
82
|
+
return item.post.author.did
|
|
83
|
+
} else {
|
|
84
|
+
return (item.reason.by as { [did: string]: string }).did
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Useful for remapping ids in snapshot testing, to make snapshots deterministic.
|
|
89
|
+
// E.g. you may use this to map this:
|
|
90
|
+
// [{ uri: 'did://rad'}, { uri: 'did://bad' }, { uri: 'did://rad'}]
|
|
91
|
+
// to this:
|
|
92
|
+
// [{ uri: '0'}, { uri: '1' }, { uri: '0'}]
|
|
93
|
+
const kTake = Symbol('take')
|
|
94
|
+
export function take(obj, value: string): string
|
|
95
|
+
export function take(obj, value: string | undefined): string | undefined
|
|
96
|
+
export function take(
|
|
97
|
+
obj: { [s: string]: number; [kTake]?: string },
|
|
98
|
+
value: string | undefined,
|
|
99
|
+
): string | undefined {
|
|
100
|
+
if (value === undefined) {
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
if (!(value in obj)) {
|
|
104
|
+
obj[value] = Object.keys(obj).length
|
|
105
|
+
}
|
|
106
|
+
const kind = obj[kTake]
|
|
107
|
+
return typeof kind === 'string'
|
|
108
|
+
? `${kind}(${obj[value]})`
|
|
109
|
+
: String(obj[value])
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export const constantDate = new Date(0).toISOString()
|
|
113
|
+
export const constantKeysetCursor = '0000000000000::bafycid'
|
|
114
|
+
|
|
115
|
+
const mapLeafValues = (obj: unknown, fn: (val: unknown) => unknown) => {
|
|
116
|
+
if (Array.isArray(obj)) {
|
|
117
|
+
return obj.map((item) => mapLeafValues(item, fn))
|
|
118
|
+
}
|
|
119
|
+
if (obj && typeof obj === 'object') {
|
|
120
|
+
return Object.entries(obj).reduce(
|
|
121
|
+
(collect, [name, value]) =>
|
|
122
|
+
Object.assign(collect, { [name]: mapLeafValues(value, fn) }),
|
|
123
|
+
{},
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
return fn(obj)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export const paginateAll = async <T extends { cursor?: string }>(
|
|
130
|
+
fn: (cursor?: string) => Promise<T>,
|
|
131
|
+
limit = Infinity,
|
|
132
|
+
): Promise<T[]> => {
|
|
133
|
+
const results: T[] = []
|
|
134
|
+
let cursor
|
|
135
|
+
do {
|
|
136
|
+
const res = await fn(cursor)
|
|
137
|
+
results.push(res)
|
|
138
|
+
cursor = res.cursor
|
|
139
|
+
} while (cursor && results.length < limit)
|
|
140
|
+
return results
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// @NOTE mutates
|
|
144
|
+
export const stripViewer = <T extends { viewer?: Record<string, unknown> }>(
|
|
145
|
+
val: T,
|
|
146
|
+
): T => {
|
|
147
|
+
delete val.viewer
|
|
148
|
+
return val
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// @NOTE mutates
|
|
152
|
+
export const stripViewerFromPost = (postUnknown: unknown): PostView => {
|
|
153
|
+
if (postUnknown?.['$type'] && !isPostView(postUnknown)) {
|
|
154
|
+
throw new Error('Expected post view')
|
|
155
|
+
}
|
|
156
|
+
const post = postUnknown as PostView
|
|
157
|
+
post.author = stripViewer(post.author)
|
|
158
|
+
const recordEmbed =
|
|
159
|
+
post.embed && isViewRecord(post.embed.record)
|
|
160
|
+
? post.embed.record // Record from record embed
|
|
161
|
+
: post.embed?.['record'] && isViewRecord(post.embed['record']['record'])
|
|
162
|
+
? post.embed['record']['record'] // Record from record-with-media embed
|
|
163
|
+
: undefined
|
|
164
|
+
if (recordEmbed) {
|
|
165
|
+
recordEmbed.author = stripViewer(recordEmbed.author)
|
|
166
|
+
recordEmbed.embeds?.forEach((deepEmbed) => {
|
|
167
|
+
const deepRecordEmbed = isViewRecord(deepEmbed.record)
|
|
168
|
+
? deepEmbed.record // Record from record embed
|
|
169
|
+
: deepEmbed['record'] && isViewRecord(deepEmbed['record']['record'])
|
|
170
|
+
? deepEmbed['record']['record'] // Record from record-with-media embed
|
|
171
|
+
: undefined
|
|
172
|
+
if (deepRecordEmbed) {
|
|
173
|
+
deepRecordEmbed.author = stripViewer(deepRecordEmbed.author)
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
return stripViewer(post)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// @NOTE mutates
|
|
181
|
+
export const stripViewerFromThread = <T>(thread: T): T => {
|
|
182
|
+
if (!isThreadViewPost(thread)) return thread
|
|
183
|
+
delete thread.viewer
|
|
184
|
+
thread.post = stripViewerFromPost(thread.post)
|
|
185
|
+
if (isThreadViewPost(thread.parent)) {
|
|
186
|
+
thread.parent = stripViewerFromThread(thread.parent)
|
|
187
|
+
}
|
|
188
|
+
if (thread.replies) {
|
|
189
|
+
thread.replies = thread.replies.map(stripViewerFromThread)
|
|
190
|
+
}
|
|
191
|
+
return thread
|
|
192
|
+
}
|
package/tests/db.test.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { sql } from 'kysely'
|
|
2
|
+
import { wait } from '@atproto/common'
|
|
3
|
+
import { TestNetwork } from '@atproto/dev-env'
|
|
4
|
+
import { Database } from '../src'
|
|
5
|
+
|
|
6
|
+
describe('db', () => {
|
|
7
|
+
let network: TestNetwork
|
|
8
|
+
let db: Database
|
|
9
|
+
|
|
10
|
+
beforeAll(async () => {
|
|
11
|
+
network = await TestNetwork.create({
|
|
12
|
+
dbPostgresSchema: 'ozone_db',
|
|
13
|
+
})
|
|
14
|
+
db = network.ozone.ctx.db
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
afterAll(async () => {
|
|
18
|
+
await network.close()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('handles client errors without crashing.', async () => {
|
|
22
|
+
const tryKillConnection = db.transaction(async (dbTxn) => {
|
|
23
|
+
const result = await sql`select pg_backend_pid() as pid;`.execute(
|
|
24
|
+
dbTxn.db,
|
|
25
|
+
)
|
|
26
|
+
const pid = result.rows[0]?.['pid'] as number
|
|
27
|
+
await sql`select pg_terminate_backend(${pid});`.execute(db.db)
|
|
28
|
+
await sql`select 1;`.execute(dbTxn.db)
|
|
29
|
+
})
|
|
30
|
+
// This should throw, but no unhandled error
|
|
31
|
+
await expect(tryKillConnection).rejects.toThrow()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('handles pool errors without crashing.', async () => {
|
|
35
|
+
const conn1 = await db.pool.connect()
|
|
36
|
+
const conn2 = await db.pool.connect()
|
|
37
|
+
const result = await conn1.query('select pg_backend_pid() as pid;')
|
|
38
|
+
const conn1pid: number = result.rows[0].pid
|
|
39
|
+
conn1.release()
|
|
40
|
+
await wait(100) // let release apply, conn is now idle on pool.
|
|
41
|
+
await conn2.query(`select pg_terminate_backend(${conn1pid});`)
|
|
42
|
+
conn2.release()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
describe('transaction()', () => {
|
|
46
|
+
it('commits changes', async () => {
|
|
47
|
+
const result = await db.transaction(async (dbTxn) => {
|
|
48
|
+
return await dbTxn.db
|
|
49
|
+
.insertInto('repo_push_event')
|
|
50
|
+
.values({
|
|
51
|
+
eventType: 'takedown',
|
|
52
|
+
subjectDid: 'x',
|
|
53
|
+
})
|
|
54
|
+
.returning('subjectDid')
|
|
55
|
+
.executeTakeFirst()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
if (!result) {
|
|
59
|
+
return expect(result).toBeTruthy()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
expect(result.subjectDid).toEqual('x')
|
|
63
|
+
|
|
64
|
+
const row = await db.db
|
|
65
|
+
.selectFrom('repo_push_event')
|
|
66
|
+
.selectAll()
|
|
67
|
+
.where('subjectDid', '=', 'x')
|
|
68
|
+
.executeTakeFirst()
|
|
69
|
+
|
|
70
|
+
expect(row).toMatchObject({
|
|
71
|
+
eventType: 'takedown',
|
|
72
|
+
subjectDid: 'x',
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('rolls-back changes on failure', async () => {
|
|
77
|
+
const promise = db.transaction(async (dbTxn) => {
|
|
78
|
+
await dbTxn.db
|
|
79
|
+
.insertInto('repo_push_event')
|
|
80
|
+
.values({
|
|
81
|
+
eventType: 'takedown',
|
|
82
|
+
subjectDid: 'y',
|
|
83
|
+
})
|
|
84
|
+
.returning('subjectDid')
|
|
85
|
+
.executeTakeFirst()
|
|
86
|
+
|
|
87
|
+
throw new Error('Oops!')
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
await expect(promise).rejects.toThrow('Oops!')
|
|
91
|
+
|
|
92
|
+
const row = await db.db
|
|
93
|
+
.selectFrom('repo_push_event')
|
|
94
|
+
.selectAll()
|
|
95
|
+
.where('subjectDid', '=', 'y')
|
|
96
|
+
.executeTakeFirst()
|
|
97
|
+
|
|
98
|
+
expect(row).toBeUndefined()
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('indicates isTransaction', async () => {
|
|
102
|
+
expect(db.isTransaction).toEqual(false)
|
|
103
|
+
|
|
104
|
+
await db.transaction(async (dbTxn) => {
|
|
105
|
+
expect(db.isTransaction).toEqual(false)
|
|
106
|
+
expect(dbTxn.isTransaction).toEqual(true)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
expect(db.isTransaction).toEqual(false)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('asserts transaction', async () => {
|
|
113
|
+
expect(() => db.assertTransaction()).toThrow('Transaction required')
|
|
114
|
+
|
|
115
|
+
await db.transaction(async (dbTxn) => {
|
|
116
|
+
expect(() => dbTxn.assertTransaction()).not.toThrow()
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('does not allow leaky transactions', async () => {
|
|
121
|
+
let leakedTx: Database | undefined
|
|
122
|
+
|
|
123
|
+
const tx = db.transaction(async (dbTxn) => {
|
|
124
|
+
leakedTx = dbTxn
|
|
125
|
+
await dbTxn.db
|
|
126
|
+
.insertInto('repo_push_event')
|
|
127
|
+
.values({ eventType: 'takedown', subjectDid: 'a' })
|
|
128
|
+
.execute()
|
|
129
|
+
throw new Error('test tx failed')
|
|
130
|
+
})
|
|
131
|
+
await expect(tx).rejects.toThrow('test tx failed')
|
|
132
|
+
|
|
133
|
+
const attempt = leakedTx?.db
|
|
134
|
+
.insertInto('repo_push_event')
|
|
135
|
+
.values({ eventType: 'takedown', subjectDid: 'b' })
|
|
136
|
+
.execute()
|
|
137
|
+
await expect(attempt).rejects.toThrow('tx already failed')
|
|
138
|
+
|
|
139
|
+
const res = await db.db
|
|
140
|
+
.selectFrom('repo_push_event')
|
|
141
|
+
.selectAll()
|
|
142
|
+
.where('subjectDid', 'in', ['a', 'b'])
|
|
143
|
+
.execute()
|
|
144
|
+
|
|
145
|
+
expect(res.length).toBe(0)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('ensures all inflight queries are rolled back', async () => {
|
|
149
|
+
let promise: Promise<unknown> | undefined = undefined
|
|
150
|
+
const names: string[] = []
|
|
151
|
+
try {
|
|
152
|
+
await db.transaction(async (dbTxn) => {
|
|
153
|
+
const queries: Promise<unknown>[] = []
|
|
154
|
+
for (let i = 0; i < 20; i++) {
|
|
155
|
+
const name = `user${i}`
|
|
156
|
+
const query = dbTxn.db
|
|
157
|
+
.insertInto('repo_push_event')
|
|
158
|
+
.values({
|
|
159
|
+
eventType: 'takedown',
|
|
160
|
+
subjectDid: name,
|
|
161
|
+
})
|
|
162
|
+
.execute()
|
|
163
|
+
names.push(name)
|
|
164
|
+
queries.push(query)
|
|
165
|
+
}
|
|
166
|
+
promise = Promise.allSettled(queries)
|
|
167
|
+
throw new Error()
|
|
168
|
+
})
|
|
169
|
+
} catch (err) {
|
|
170
|
+
expect(err).toBeDefined()
|
|
171
|
+
}
|
|
172
|
+
if (promise) {
|
|
173
|
+
await promise
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const res = await db.db
|
|
177
|
+
.selectFrom('repo_push_event')
|
|
178
|
+
.selectAll()
|
|
179
|
+
.where('subjectDid', 'in', names)
|
|
180
|
+
.execute()
|
|
181
|
+
expect(res.length).toBe(0)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
})
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
|
2
|
+
import AtpAgent from '@atproto/api'
|
|
3
|
+
import { AtUri } from '@atproto/syntax'
|
|
4
|
+
import {
|
|
5
|
+
REASONOTHER,
|
|
6
|
+
REASONSPAM,
|
|
7
|
+
} from '../src/lexicon/types/com/atproto/moderation/defs'
|
|
8
|
+
import { forSnapshot } from './_util'
|
|
9
|
+
|
|
10
|
+
describe('admin get record view', () => {
|
|
11
|
+
let network: TestNetwork
|
|
12
|
+
let agent: AtpAgent
|
|
13
|
+
let sc: SeedClient
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
network = await TestNetwork.create({
|
|
17
|
+
dbPostgresSchema: 'ozone_admin_get_record',
|
|
18
|
+
})
|
|
19
|
+
agent = network.pds.getClient()
|
|
20
|
+
sc = network.getSeedClient()
|
|
21
|
+
await basicSeed(sc)
|
|
22
|
+
await network.processAll()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
afterAll(async () => {
|
|
26
|
+
await network.close()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
beforeAll(async () => {
|
|
30
|
+
await sc.emitModerationEvent({
|
|
31
|
+
event: { $type: 'com.atproto.admin.defs#modEventFlag' },
|
|
32
|
+
subject: {
|
|
33
|
+
$type: 'com.atproto.repo.strongRef',
|
|
34
|
+
uri: sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
35
|
+
cid: sc.posts[sc.dids.alice][0].ref.cidStr,
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
await sc.createReport({
|
|
39
|
+
reportedBy: sc.dids.bob,
|
|
40
|
+
reasonType: REASONSPAM,
|
|
41
|
+
subject: {
|
|
42
|
+
$type: 'com.atproto.repo.strongRef',
|
|
43
|
+
uri: sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
44
|
+
cid: sc.posts[sc.dids.alice][0].ref.cidStr,
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
await sc.createReport({
|
|
48
|
+
reportedBy: sc.dids.carol,
|
|
49
|
+
reasonType: REASONOTHER,
|
|
50
|
+
reason: 'defamation',
|
|
51
|
+
subject: {
|
|
52
|
+
$type: 'com.atproto.repo.strongRef',
|
|
53
|
+
uri: sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
54
|
+
cid: sc.posts[sc.dids.alice][0].ref.cidStr,
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
await sc.emitModerationEvent({
|
|
58
|
+
event: { $type: 'com.atproto.admin.defs#modEventTakedown' },
|
|
59
|
+
subject: {
|
|
60
|
+
$type: 'com.atproto.repo.strongRef',
|
|
61
|
+
uri: sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
62
|
+
cid: sc.posts[sc.dids.alice][0].ref.cidStr,
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('gets a record by uri, even when taken down.', async () => {
|
|
68
|
+
const result = await agent.api.com.atproto.admin.getRecord(
|
|
69
|
+
{ uri: sc.posts[sc.dids.alice][0].ref.uriStr },
|
|
70
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
71
|
+
)
|
|
72
|
+
expect(forSnapshot(result.data)).toMatchSnapshot()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('gets a record by uri and cid.', async () => {
|
|
76
|
+
const result = await agent.api.com.atproto.admin.getRecord(
|
|
77
|
+
{
|
|
78
|
+
uri: sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
79
|
+
cid: sc.posts[sc.dids.alice][0].ref.cidStr,
|
|
80
|
+
},
|
|
81
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
82
|
+
)
|
|
83
|
+
expect(forSnapshot(result.data)).toMatchSnapshot()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('fails when record does not exist.', async () => {
|
|
87
|
+
const promise = agent.api.com.atproto.admin.getRecord(
|
|
88
|
+
{
|
|
89
|
+
uri: AtUri.make(
|
|
90
|
+
sc.dids.alice,
|
|
91
|
+
'app.bsky.feed.post',
|
|
92
|
+
'badrkey',
|
|
93
|
+
).toString(),
|
|
94
|
+
},
|
|
95
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
96
|
+
)
|
|
97
|
+
await expect(promise).rejects.toThrow('Record not found')
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('fails when record cid does not exist.', async () => {
|
|
101
|
+
const promise = agent.api.com.atproto.admin.getRecord(
|
|
102
|
+
{
|
|
103
|
+
uri: sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
104
|
+
cid: sc.posts[sc.dids.alice][1].ref.cidStr, // Mismatching cid
|
|
105
|
+
},
|
|
106
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
107
|
+
)
|
|
108
|
+
await expect(promise).rejects.toThrow('Record not found')
|
|
109
|
+
})
|
|
110
|
+
})
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
|
2
|
+
import AtpAgent from '@atproto/api'
|
|
3
|
+
import {
|
|
4
|
+
REASONOTHER,
|
|
5
|
+
REASONSPAM,
|
|
6
|
+
} from '../src/lexicon/types/com/atproto/moderation/defs'
|
|
7
|
+
import { forSnapshot } from './_util'
|
|
8
|
+
|
|
9
|
+
describe('admin get repo view', () => {
|
|
10
|
+
let network: TestNetwork
|
|
11
|
+
let agent: AtpAgent
|
|
12
|
+
let sc: SeedClient
|
|
13
|
+
|
|
14
|
+
beforeAll(async () => {
|
|
15
|
+
network = await TestNetwork.create({
|
|
16
|
+
dbPostgresSchema: 'ozone_admin_get_repo',
|
|
17
|
+
})
|
|
18
|
+
agent = network.pds.getClient()
|
|
19
|
+
sc = network.getSeedClient()
|
|
20
|
+
await basicSeed(sc)
|
|
21
|
+
await network.processAll()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
afterAll(async () => {
|
|
25
|
+
await network.close()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
beforeAll(async () => {
|
|
29
|
+
await sc.emitModerationEvent({
|
|
30
|
+
event: { $type: 'com.atproto.admin.defs#modEventAcknowledge' },
|
|
31
|
+
subject: {
|
|
32
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
33
|
+
did: sc.dids.alice,
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
await sc.createReport({
|
|
37
|
+
reportedBy: sc.dids.bob,
|
|
38
|
+
reasonType: REASONSPAM,
|
|
39
|
+
subject: {
|
|
40
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
41
|
+
did: sc.dids.alice,
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
await sc.createReport({
|
|
45
|
+
reportedBy: sc.dids.carol,
|
|
46
|
+
reasonType: REASONOTHER,
|
|
47
|
+
reason: 'defamation',
|
|
48
|
+
subject: {
|
|
49
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
50
|
+
did: sc.dids.alice,
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
await sc.emitModerationEvent({
|
|
54
|
+
event: { $type: 'com.atproto.admin.defs#modEventTakedown' },
|
|
55
|
+
subject: {
|
|
56
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
57
|
+
did: sc.dids.alice,
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('gets a repo by did, even when taken down.', async () => {
|
|
63
|
+
const result = await agent.api.com.atproto.admin.getRepo(
|
|
64
|
+
{ did: sc.dids.alice },
|
|
65
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
66
|
+
)
|
|
67
|
+
expect(forSnapshot(result.data)).toMatchSnapshot()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('does not include account emails for triage mods.', async () => {
|
|
71
|
+
const { data: admin } = await agent.api.com.atproto.admin.getRepo(
|
|
72
|
+
{ did: sc.dids.bob },
|
|
73
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
74
|
+
)
|
|
75
|
+
const { data: moderator } = await agent.api.com.atproto.admin.getRepo(
|
|
76
|
+
{ did: sc.dids.bob },
|
|
77
|
+
{ headers: network.pds.adminAuthHeaders('moderator') },
|
|
78
|
+
)
|
|
79
|
+
const { data: triage } = await agent.api.com.atproto.admin.getRepo(
|
|
80
|
+
{ did: sc.dids.bob },
|
|
81
|
+
{ headers: network.pds.adminAuthHeaders('triage') },
|
|
82
|
+
)
|
|
83
|
+
expect(admin.email).toEqual('bob@test.com')
|
|
84
|
+
expect(moderator.email).toEqual('bob@test.com')
|
|
85
|
+
expect(triage.email).toBeUndefined()
|
|
86
|
+
expect(triage).toEqual({ ...admin, email: undefined })
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('includes emailConfirmedAt timestamp', async () => {
|
|
90
|
+
const { data: beforeEmailVerification } =
|
|
91
|
+
await agent.api.com.atproto.admin.getRepo(
|
|
92
|
+
{ did: sc.dids.bob },
|
|
93
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
expect(beforeEmailVerification.emailConfirmedAt).toBeUndefined()
|
|
97
|
+
const timestampBeforeVerification = Date.now()
|
|
98
|
+
const bobsAccount = sc.accounts[sc.dids.bob]
|
|
99
|
+
const verificationToken =
|
|
100
|
+
await network.pds.ctx.accountManager.createEmailToken(
|
|
101
|
+
sc.dids.bob,
|
|
102
|
+
'confirm_email',
|
|
103
|
+
)
|
|
104
|
+
await agent.api.com.atproto.server.confirmEmail(
|
|
105
|
+
{ email: bobsAccount.email, token: verificationToken },
|
|
106
|
+
{
|
|
107
|
+
encoding: 'application/json',
|
|
108
|
+
|
|
109
|
+
headers: sc.getHeaders(sc.dids.bob),
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
const { data: afterEmailVerification } =
|
|
113
|
+
await agent.api.com.atproto.admin.getRepo(
|
|
114
|
+
{ did: sc.dids.bob },
|
|
115
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
expect(afterEmailVerification.emailConfirmedAt).toBeTruthy()
|
|
119
|
+
expect(
|
|
120
|
+
new Date(afterEmailVerification.emailConfirmedAt as string).getTime(),
|
|
121
|
+
).toBeGreaterThan(timestampBeforeVerification)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('fails when repo does not exist.', async () => {
|
|
125
|
+
const promise = agent.api.com.atproto.admin.getRepo(
|
|
126
|
+
{ did: 'did:plc:doesnotexist' },
|
|
127
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
128
|
+
)
|
|
129
|
+
await expect(promise).rejects.toThrow('Repo not found')
|
|
130
|
+
})
|
|
131
|
+
})
|