@atproto/pds 0.4.219 → 0.4.221
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 +18 -0
- package/dist/account-manager/account-manager.d.ts +17 -0
- package/dist/account-manager/account-manager.d.ts.map +1 -1
- package/dist/account-manager/account-manager.js +27 -3
- package/dist/account-manager/account-manager.js.map +1 -1
- package/dist/account-manager/oauth-store.d.ts.map +1 -1
- package/dist/account-manager/oauth-store.js +9 -1
- package/dist/account-manager/oauth-store.js.map +1 -1
- package/dist/auth-verifier.d.ts +1 -0
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/auth-verifier.js +7 -13
- package/dist/auth-verifier.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +1 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.js +1 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/actor/declaration.defs.d.ts +14 -0
- package/dist/lexicons/chat/bsky/actor/declaration.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/actor/declaration.defs.js +1 -0
- package/dist/lexicons/chat/bsky/actor/declaration.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/actor/defs.defs.d.ts +43 -0
- package/dist/lexicons/chat/bsky/actor/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/actor/defs.defs.js +21 -1
- package/dist/lexicons/chat/bsky/actor/defs.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/authFullChatClient.defs.js +1 -1
- package/dist/lexicons/chat/bsky/authFullChatClient.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/acceptConvo.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/acceptConvo.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/acceptConvo.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/acceptConvo.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/addReaction.defs.d.ts +1 -1
- package/dist/lexicons/chat/bsky/convo/addReaction.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/addReaction.defs.js +7 -1
- package/dist/lexicons/chat/bsky/convo/addReaction.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts +505 -3
- package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/defs.defs.js +244 -2
- package/dist/lexicons/chat/bsky/convo/defs.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/deleteMessageForSelf.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/deleteMessageForSelf.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/deleteMessageForSelf.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/deleteMessageForSelf.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvo.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/getConvo.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvo.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/getConvo.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvoAvailability.defs.d.ts +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvoAvailability.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvoAvailability.defs.js +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvoAvailability.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.js +8 -1
- package/dist/lexicons/chat/bsky/convo/getConvoForMembers.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.d.ts +3 -0
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.defs.d.ts +26 -0
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.defs.js +55 -0
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.js +45 -0
- package/dist/lexicons/chat/bsky/convo/getConvoMembers.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/getLog.defs.d.ts +2 -2
- package/dist/lexicons/chat/bsky/convo/getLog.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getLog.defs.js +17 -0
- package/dist/lexicons/chat/bsky/convo/getLog.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getMessages.defs.d.ts +7 -3
- package/dist/lexicons/chat/bsky/convo/getMessages.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/getMessages.defs.js +5 -1
- package/dist/lexicons/chat/bsky/convo/getMessages.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/leaveConvo.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/leaveConvo.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/leaveConvo.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/leaveConvo.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.d.ts +3 -0
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.d.ts +25 -0
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.js +58 -0
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.js +45 -0
- package/dist/lexicons/chat/bsky/convo/listConvoRequests.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/listConvos.defs.d.ts +7 -0
- package/dist/lexicons/chat/bsky/convo/listConvos.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/listConvos.defs.js +2 -0
- package/dist/lexicons/chat/bsky/convo/listConvos.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/lockConvo.d.ts +3 -0
- package/dist/lexicons/chat/bsky/convo/lockConvo.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/lockConvo.defs.d.ts +22 -0
- package/dist/lexicons/chat/bsky/convo/lockConvo.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/lockConvo.defs.js +50 -0
- package/dist/lexicons/chat/bsky/convo/lockConvo.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/lockConvo.js +45 -0
- package/dist/lexicons/chat/bsky/convo/lockConvo.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/muteConvo.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/muteConvo.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/muteConvo.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/muteConvo.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/removeReaction.defs.d.ts +1 -1
- package/dist/lexicons/chat/bsky/convo/removeReaction.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/removeReaction.defs.js +6 -1
- package/dist/lexicons/chat/bsky/convo/removeReaction.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/sendMessage.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/sendMessageBatch.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/unlockConvo.d.ts +3 -0
- package/dist/lexicons/chat/bsky/convo/unlockConvo.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.d.ts +22 -0
- package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.js +50 -0
- package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/unlockConvo.js +45 -0
- package/dist/lexicons/chat/bsky/convo/unlockConvo.js.map +1 -0
- package/dist/lexicons/chat/bsky/convo/unmuteConvo.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/unmuteConvo.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/unmuteConvo.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/unmuteConvo.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/updateAllRead.defs.d.ts +1 -0
- package/dist/lexicons/chat/bsky/convo/updateAllRead.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/updateAllRead.defs.js +1 -0
- package/dist/lexicons/chat/bsky/convo/updateAllRead.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo/updateRead.defs.d.ts +2 -1
- package/dist/lexicons/chat/bsky/convo/updateRead.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo/updateRead.defs.js +2 -1
- package/dist/lexicons/chat/bsky/convo/updateRead.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/convo.d.ts +4 -0
- package/dist/lexicons/chat/bsky/convo.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/convo.js +5 -1
- package/dist/lexicons/chat/bsky/convo.js.map +1 -1
- package/dist/lexicons/chat/bsky/group/addMembers.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/addMembers.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts +31 -0
- package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/addMembers.defs.js +65 -0
- package/dist/lexicons/chat/bsky/group/addMembers.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/addMembers.js +45 -0
- package/dist/lexicons/chat/bsky/group/addMembers.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.d.ts +28 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.js +50 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.js +45 -0
- package/dist/lexicons/chat/bsky/group/approveJoinRequest.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/createGroup.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/createGroup.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts +36 -0
- package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/createGroup.defs.js +59 -0
- package/dist/lexicons/chat/bsky/group/createGroup.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/createGroup.js +45 -0
- package/dist/lexicons/chat/bsky/group/createGroup.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.defs.d.ts +26 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.defs.js +54 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.js +45 -0
- package/dist/lexicons/chat/bsky/group/createJoinLink.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/defs.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/defs.defs.d.ts +47 -0
- package/dist/lexicons/chat/bsky/group/defs.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/defs.defs.js +69 -0
- package/dist/lexicons/chat/bsky/group/defs.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/defs.js +45 -0
- package/dist/lexicons/chat/bsky/group/defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.d.ts +22 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.js +50 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.js +45 -0
- package/dist/lexicons/chat/bsky/group/disableJoinLink.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/editGroup.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/editGroup.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/editGroup.defs.d.ts +32 -0
- package/dist/lexicons/chat/bsky/group/editGroup.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/editGroup.defs.js +53 -0
- package/dist/lexicons/chat/bsky/group/editGroup.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/editGroup.js +45 -0
- package/dist/lexicons/chat/bsky/group/editGroup.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.defs.d.ts +26 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.defs.js +54 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.js +45 -0
- package/dist/lexicons/chat/bsky/group/editJoinLink.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.d.ts +22 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.js +50 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.js +45 -0
- package/dist/lexicons/chat/bsky/group/enableJoinLink.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.defs.d.ts +20 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.defs.js +50 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.js +45 -0
- package/dist/lexicons/chat/bsky/group/getGroupPublicInfo.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.d.ts +26 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.js +55 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.js +45 -0
- package/dist/lexicons/chat/bsky/group/listJoinRequests.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.d.ts +23 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.js +14 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.js +45 -0
- package/dist/lexicons/chat/bsky/group/rejectJoinRequest.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.defs.d.ts +28 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.defs.js +53 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.js +45 -0
- package/dist/lexicons/chat/bsky/group/removeMembers.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.d.ts +3 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.defs.d.ts +28 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.defs.js +58 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.js +45 -0
- package/dist/lexicons/chat/bsky/group/requestJoin.js.map +1 -0
- package/dist/lexicons/chat/bsky/group.d.ts +15 -0
- package/dist/lexicons/chat/bsky/group.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/group.js +54 -0
- package/dist/lexicons/chat/bsky/group.js.map +1 -0
- package/dist/lexicons/chat/bsky/moderation/getMessageContext.defs.d.ts +2 -2
- package/dist/lexicons/chat/bsky/moderation/getMessageContext.defs.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/moderation/getMessageContext.defs.js +1 -0
- package/dist/lexicons/chat/bsky/moderation/getMessageContext.defs.js.map +1 -1
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.d.ts +3 -0
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.d.ts +32 -0
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.d.ts.map +1 -0
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.js +23 -0
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.defs.js.map +1 -0
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.js +45 -0
- package/dist/lexicons/chat/bsky/moderation/subscribeModEvents.js.map +1 -0
- package/dist/lexicons/chat/bsky/moderation.d.ts +1 -0
- package/dist/lexicons/chat/bsky/moderation.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky/moderation.js +2 -1
- package/dist/lexicons/chat/bsky/moderation.js.map +1 -1
- package/dist/lexicons/chat/bsky.d.ts +1 -0
- package/dist/lexicons/chat/bsky.d.ts.map +1 -1
- package/dist/lexicons/chat/bsky.js +2 -1
- package/dist/lexicons/chat/bsky.js.map +1 -1
- package/package.json +4 -5
- package/src/account-manager/account-manager.ts +23 -2
- package/src/account-manager/oauth-store.ts +10 -2
- package/src/auth-verifier.ts +3 -11
- package/src/index.ts +5 -1
- package/tests/auth.test.ts +92 -1
- package/tests/entryway-mock.ts +317 -0
- package/tests/entryway.test.ts +18 -100
- package/tsconfig.build.tsbuildinfo +1 -1
package/tests/auth.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as jose from 'jose'
|
|
2
|
+
import { request as undiciRequest } from 'undici'
|
|
2
3
|
import { AtpAgent } from '@atproto/api'
|
|
3
4
|
import { SeedClient, TestNetworkNoAppView } from '@atproto/dev-env'
|
|
4
5
|
import { createRefreshToken } from '../src/account-manager/helpers/auth'
|
|
@@ -121,6 +122,94 @@ describe('auth', () => {
|
|
|
121
122
|
)
|
|
122
123
|
})
|
|
123
124
|
|
|
125
|
+
it('returns identical error responses for unknown identifier and known-identifier-with-wrong-password.', async () => {
|
|
126
|
+
const probe = async (info: { identifier: string; password: string }) => {
|
|
127
|
+
const res = await fetch(
|
|
128
|
+
`${network.pds.url}/xrpc/com.atproto.server.createSession`,
|
|
129
|
+
{
|
|
130
|
+
method: 'POST',
|
|
131
|
+
headers: { 'content-type': 'application/json' },
|
|
132
|
+
body: JSON.stringify(info),
|
|
133
|
+
},
|
|
134
|
+
)
|
|
135
|
+
return { status: res.status, body: await res.json() }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// bob.test was created above with password 'password'.
|
|
139
|
+
const unknownIdentifier = await probe({
|
|
140
|
+
identifier: 'no-such-user.test',
|
|
141
|
+
password: 'any-password',
|
|
142
|
+
})
|
|
143
|
+
const knownIdentifierWrongPassword = await probe({
|
|
144
|
+
identifier: 'bob.test',
|
|
145
|
+
password: 'wrong-password',
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
expect(knownIdentifierWrongPassword).toEqual(unknownIdentifier)
|
|
149
|
+
expect(unknownIdentifier).toEqual({
|
|
150
|
+
status: 401,
|
|
151
|
+
body: {
|
|
152
|
+
error: 'AuthenticationRequired',
|
|
153
|
+
message: 'Invalid identifier or password',
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('returns identical error responses for unknown identifier and known-identifier-with-wrong-password in the OAuth sign-in flow.', async () => {
|
|
159
|
+
const issuer = new URL(network.pds.url)
|
|
160
|
+
const csrfToken = 'a'.repeat(24)
|
|
161
|
+
const probe = async (credentials: {
|
|
162
|
+
username: string
|
|
163
|
+
password: string
|
|
164
|
+
}) => {
|
|
165
|
+
// @NOTE We use undici's low-level `request` rather than fetch(),
|
|
166
|
+
// because the WHATWG fetch API treats `sec-fetch-*` as forbidden
|
|
167
|
+
// request headers and silently overwrites them with its own values
|
|
168
|
+
// (notably `sec-fetch-mode: cors` in Node). The endpoint requires
|
|
169
|
+
// `same-origin` here, so we need raw header control.
|
|
170
|
+
const res = await undiciRequest(
|
|
171
|
+
`${issuer.origin}/@atproto/oauth-provider/~api/sign-in`,
|
|
172
|
+
{
|
|
173
|
+
method: 'POST',
|
|
174
|
+
headers: {
|
|
175
|
+
'content-type': 'application/json',
|
|
176
|
+
// The endpoint restricts fetches to same-origin navigations
|
|
177
|
+
// from either `/oauth/authorize` or `/account[/*]`. Use the
|
|
178
|
+
// first-party `/account` path so we don't need a live OAuth
|
|
179
|
+
// authorization request to exist in the request store.
|
|
180
|
+
'sec-fetch-mode': 'same-origin',
|
|
181
|
+
'sec-fetch-site': 'same-origin',
|
|
182
|
+
origin: issuer.origin,
|
|
183
|
+
referer: `${issuer.origin}/account`,
|
|
184
|
+
'x-csrf-token': csrfToken,
|
|
185
|
+
cookie: `csrf-token=${csrfToken}`,
|
|
186
|
+
},
|
|
187
|
+
body: JSON.stringify({ locale: 'en', ...credentials }),
|
|
188
|
+
},
|
|
189
|
+
)
|
|
190
|
+
return { status: res.statusCode, body: await res.body.json() }
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// bob.test was created above with password 'password'.
|
|
194
|
+
const unknownIdentifier = await probe({
|
|
195
|
+
username: 'no-such-user.test',
|
|
196
|
+
password: 'any-password',
|
|
197
|
+
})
|
|
198
|
+
const knownIdentifierWrongPassword = await probe({
|
|
199
|
+
username: 'bob.test',
|
|
200
|
+
password: 'wrong-password',
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
expect(knownIdentifierWrongPassword).toEqual(unknownIdentifier)
|
|
204
|
+
expect(unknownIdentifier).toEqual({
|
|
205
|
+
status: 400,
|
|
206
|
+
body: {
|
|
207
|
+
error: 'invalid_request',
|
|
208
|
+
error_description: 'Invalid identifier or password',
|
|
209
|
+
},
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
|
|
124
213
|
it('provides valid access and refresh token on session refresh.', async () => {
|
|
125
214
|
const email = 'carol@test.com'
|
|
126
215
|
const account = await createAccount({
|
|
@@ -242,7 +331,9 @@ describe('auth', () => {
|
|
|
242
331
|
password: 'password',
|
|
243
332
|
})
|
|
244
333
|
const refreshWithAccess = refreshSession(account.accessJwt)
|
|
245
|
-
await expect(refreshWithAccess).rejects.toThrow(
|
|
334
|
+
await expect(refreshWithAccess).rejects.toThrow(
|
|
335
|
+
'Token could not be verified',
|
|
336
|
+
)
|
|
246
337
|
})
|
|
247
338
|
|
|
248
339
|
it('expired refresh token cannot be used to refresh a session.', async () => {
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { createPrivateKey } from 'node:crypto'
|
|
2
|
+
import * as http from 'node:http'
|
|
3
|
+
import * as plcLib from '@did-plc/lib'
|
|
4
|
+
import { HttpTerminator, createHttpTerminator } from 'http-terminator'
|
|
5
|
+
import * as jose from 'jose'
|
|
6
|
+
import KeyEncoder from 'key-encoder'
|
|
7
|
+
import * as ui8 from 'uint8arrays'
|
|
8
|
+
import { AtpAgent } from '@atproto/api'
|
|
9
|
+
import { getVerificationMaterial } from '@atproto/common'
|
|
10
|
+
import { Secp256k1Keypair, randomStr } from '@atproto/crypto'
|
|
11
|
+
import { IdResolver, getDidKeyFromMultibase } from '@atproto/identity'
|
|
12
|
+
import { DidString, HandleString } from '@atproto/syntax'
|
|
13
|
+
import {
|
|
14
|
+
AuthRequiredError,
|
|
15
|
+
createServer,
|
|
16
|
+
parseReqNsid,
|
|
17
|
+
verifyJwt as verifyServiceJwt,
|
|
18
|
+
} from '@atproto/xrpc-server'
|
|
19
|
+
import { bearerTokenFromReq, createPublicKeyObject } from '../src/auth-verifier'
|
|
20
|
+
import { com } from '../src/lexicons/index.js'
|
|
21
|
+
|
|
22
|
+
interface Account {
|
|
23
|
+
did: DidString
|
|
24
|
+
handle: HandleString
|
|
25
|
+
email?: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface MockEntrywayOpts {
|
|
29
|
+
port: number
|
|
30
|
+
serviceDid: string
|
|
31
|
+
plcUrl: string
|
|
32
|
+
pdsUrl: string
|
|
33
|
+
pdsDid: string
|
|
34
|
+
adminPassword: string
|
|
35
|
+
jwtSigningKey: Secp256k1Keypair
|
|
36
|
+
plcRotationKey: Secp256k1Keypair
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type AccessAuthResult = { credentials: { did: string; type: 'access' } }
|
|
40
|
+
type ServiceAuthResult = { credentials: { did: string; type: 'service' } }
|
|
41
|
+
|
|
42
|
+
export class MockEntryway {
|
|
43
|
+
public url: string
|
|
44
|
+
public serviceDid: string
|
|
45
|
+
public plcRotationKey: Secp256k1Keypair
|
|
46
|
+
public idResolver: IdResolver
|
|
47
|
+
|
|
48
|
+
private server: http.Server
|
|
49
|
+
private terminator: HttpTerminator
|
|
50
|
+
private accounts = new Map<string, Account>()
|
|
51
|
+
|
|
52
|
+
private constructor(
|
|
53
|
+
server: http.Server,
|
|
54
|
+
terminator: HttpTerminator,
|
|
55
|
+
idResolver: IdResolver,
|
|
56
|
+
opts: MockEntrywayOpts,
|
|
57
|
+
) {
|
|
58
|
+
this.server = server
|
|
59
|
+
this.terminator = terminator
|
|
60
|
+
this.url = `http://localhost:${opts.port}`
|
|
61
|
+
this.serviceDid = opts.serviceDid
|
|
62
|
+
this.plcRotationKey = opts.plcRotationKey
|
|
63
|
+
this.idResolver = idResolver
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static async create(opts: MockEntrywayOpts): Promise<MockEntryway> {
|
|
67
|
+
const keyEncoder = new KeyEncoder('secp256k1')
|
|
68
|
+
const privateKeyHex = ui8.toString(await opts.jwtSigningKey.export(), 'hex')
|
|
69
|
+
const privatePem = keyEncoder.encodePrivate(privateKeyHex, 'raw', 'pem')
|
|
70
|
+
const jwtPrivateKey = createPrivateKey({ format: 'pem', key: privatePem })
|
|
71
|
+
const jwtPublicKey = createPublicKeyObject(
|
|
72
|
+
opts.jwtSigningKey.publicKeyStr('hex'),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
const plcClient = new plcLib.Client(opts.plcUrl)
|
|
76
|
+
const pdsAgent = new AtpAgent({ service: opts.pdsUrl })
|
|
77
|
+
const idResolver = new IdResolver({ plcUrl: opts.plcUrl })
|
|
78
|
+
|
|
79
|
+
const accounts = new Map<string, Account>()
|
|
80
|
+
|
|
81
|
+
const getSigningKey = async (
|
|
82
|
+
iss: string,
|
|
83
|
+
forceRefresh: boolean,
|
|
84
|
+
): Promise<string> => {
|
|
85
|
+
const [did, serviceId] = iss.split('#')
|
|
86
|
+
if (serviceId) {
|
|
87
|
+
throw new AuthRequiredError('no service id expected in iss claim')
|
|
88
|
+
}
|
|
89
|
+
const didDoc = await idResolver.did.resolve(did, forceRefresh)
|
|
90
|
+
if (!didDoc) {
|
|
91
|
+
throw new AuthRequiredError(`could not resolve did: ${did}`)
|
|
92
|
+
}
|
|
93
|
+
const parsedKey = getVerificationMaterial(didDoc, 'atproto')
|
|
94
|
+
if (!parsedKey) {
|
|
95
|
+
throw new AuthRequiredError('missing or bad key in did doc')
|
|
96
|
+
}
|
|
97
|
+
const didKey = getDidKeyFromMultibase(parsedKey)
|
|
98
|
+
if (!didKey) {
|
|
99
|
+
throw new AuthRequiredError('missing or bad key in did doc')
|
|
100
|
+
}
|
|
101
|
+
return didKey
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const bearerToken = (req: http.IncomingMessage): string => {
|
|
105
|
+
const token = bearerTokenFromReq(req)
|
|
106
|
+
if (!token) {
|
|
107
|
+
throw new AuthRequiredError('missing bearer token')
|
|
108
|
+
}
|
|
109
|
+
return token
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Auth: verify user access token (typ: 'at+jwt') signed by entryway
|
|
113
|
+
const accessAuth = async ({
|
|
114
|
+
req,
|
|
115
|
+
}: {
|
|
116
|
+
req: http.IncomingMessage
|
|
117
|
+
}): Promise<AccessAuthResult> => {
|
|
118
|
+
try {
|
|
119
|
+
const token = bearerToken(req)
|
|
120
|
+
const { protectedHeader, payload } = await jose.jwtVerify(
|
|
121
|
+
token,
|
|
122
|
+
jwtPublicKey,
|
|
123
|
+
)
|
|
124
|
+
if (protectedHeader.typ !== 'at+jwt') {
|
|
125
|
+
throw new AuthRequiredError('expected typ: at+jwt')
|
|
126
|
+
}
|
|
127
|
+
if (!payload.sub) {
|
|
128
|
+
throw new AuthRequiredError('missing sub in token')
|
|
129
|
+
}
|
|
130
|
+
return { credentials: { did: payload.sub, type: 'access' } }
|
|
131
|
+
} catch (err) {
|
|
132
|
+
console.log(err)
|
|
133
|
+
throw err
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Auth: verify service auth token from PDS (no typ / typ !== 'at+jwt')
|
|
138
|
+
const serviceAuth = async ({
|
|
139
|
+
req,
|
|
140
|
+
}: {
|
|
141
|
+
req: http.IncomingMessage
|
|
142
|
+
}): Promise<ServiceAuthResult> => {
|
|
143
|
+
try {
|
|
144
|
+
const token = bearerToken(req)
|
|
145
|
+
const { typ } = jose.decodeProtectedHeader(token)
|
|
146
|
+
if (typ === 'at+jwt') {
|
|
147
|
+
throw new AuthRequiredError(
|
|
148
|
+
'expected service auth: typ must not be at+jwt',
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
const nsid = parseReqNsid(req)
|
|
152
|
+
const payload = await verifyServiceJwt(
|
|
153
|
+
token,
|
|
154
|
+
opts.serviceDid,
|
|
155
|
+
nsid,
|
|
156
|
+
getSigningKey,
|
|
157
|
+
)
|
|
158
|
+
return { credentials: { did: payload.iss, type: 'service' } }
|
|
159
|
+
} catch (err) {
|
|
160
|
+
console.log(err)
|
|
161
|
+
throw err
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Auth: accept either access token or service auth
|
|
166
|
+
const accessOrServiceAuth = async ({
|
|
167
|
+
req,
|
|
168
|
+
}: {
|
|
169
|
+
req: http.IncomingMessage
|
|
170
|
+
}): Promise<AccessAuthResult | ServiceAuthResult> => {
|
|
171
|
+
const token = bearerToken(req)
|
|
172
|
+
const { typ } = jose.decodeProtectedHeader(token)
|
|
173
|
+
if (typ === 'at+jwt') {
|
|
174
|
+
return accessAuth({ req })
|
|
175
|
+
}
|
|
176
|
+
return serviceAuth({ req })
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const server = createServer()
|
|
180
|
+
|
|
181
|
+
server.add(com.atproto.server.createAccount, {
|
|
182
|
+
handler: async ({ input }) => {
|
|
183
|
+
const { email, handle } = input.body
|
|
184
|
+
|
|
185
|
+
// Reserve a signing key on the PDS
|
|
186
|
+
const {
|
|
187
|
+
data: { signingKey },
|
|
188
|
+
} = await pdsAgent.com.atproto.server.reserveSigningKey({})
|
|
189
|
+
|
|
190
|
+
// Create PLC operation
|
|
191
|
+
const plcCreate = await plcLib.createOp({
|
|
192
|
+
signingKey,
|
|
193
|
+
rotationKeys: [opts.plcRotationKey.did()],
|
|
194
|
+
handle,
|
|
195
|
+
pds: opts.pdsUrl,
|
|
196
|
+
signer: opts.plcRotationKey,
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
// Create account on PDS (no auth needed — userServiceAuthOptional)
|
|
200
|
+
await pdsAgent.com.atproto.server.createAccount({
|
|
201
|
+
did: plcCreate.did,
|
|
202
|
+
handle,
|
|
203
|
+
plcOp: plcCreate.op,
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
// Store account in memory
|
|
207
|
+
accounts.set(plcCreate.did, {
|
|
208
|
+
did: plcCreate.did as DidString,
|
|
209
|
+
handle,
|
|
210
|
+
email,
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
// Sign access + refresh JWTs
|
|
214
|
+
const now = Math.floor(Date.now() / 1000)
|
|
215
|
+
const accessJwt = await new jose.SignJWT({
|
|
216
|
+
scope: 'com.atproto.access',
|
|
217
|
+
})
|
|
218
|
+
.setProtectedHeader({ alg: 'ES256K', typ: 'at+jwt' })
|
|
219
|
+
.setSubject(plcCreate.did)
|
|
220
|
+
.setAudience(opts.pdsDid)
|
|
221
|
+
.setIssuedAt(now)
|
|
222
|
+
.setExpirationTime(now + 60 * 60)
|
|
223
|
+
.setJti(randomStr(16, 'base32'))
|
|
224
|
+
.sign(jwtPrivateKey)
|
|
225
|
+
|
|
226
|
+
const refreshJwt = await new jose.SignJWT({
|
|
227
|
+
scope: 'com.atproto.refresh',
|
|
228
|
+
})
|
|
229
|
+
.setProtectedHeader({ alg: 'ES256K', typ: 'at+jwt' })
|
|
230
|
+
.setSubject(plcCreate.did)
|
|
231
|
+
.setAudience(opts.pdsDid)
|
|
232
|
+
.setIssuedAt(now)
|
|
233
|
+
.setExpirationTime(now + 90 * 24 * 60 * 60)
|
|
234
|
+
.setJti(randomStr(16, 'base32'))
|
|
235
|
+
.sign(jwtPrivateKey)
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
encoding: 'application/json' as const,
|
|
239
|
+
body: {
|
|
240
|
+
did: plcCreate.did as DidString,
|
|
241
|
+
handle,
|
|
242
|
+
accessJwt,
|
|
243
|
+
refreshJwt,
|
|
244
|
+
},
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
server.add(com.atproto.server.getSession, {
|
|
250
|
+
auth: accessOrServiceAuth,
|
|
251
|
+
handler: async ({ auth }) => {
|
|
252
|
+
const account = accounts.get(auth.credentials.did)
|
|
253
|
+
if (!account) {
|
|
254
|
+
throw new Error(
|
|
255
|
+
`Could not find account for DID: ${auth.credentials.did}`,
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
encoding: 'application/json' as const,
|
|
260
|
+
body: {
|
|
261
|
+
did: account.did,
|
|
262
|
+
handle: account.handle,
|
|
263
|
+
email: account.email,
|
|
264
|
+
emailConfirmed: false,
|
|
265
|
+
},
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
server.add(com.atproto.identity.updateHandle, {
|
|
271
|
+
auth: serviceAuth,
|
|
272
|
+
handler: async ({ auth, input }) => {
|
|
273
|
+
// The PDS sends { did, handle } where did is the target user
|
|
274
|
+
const body = input.body as typeof input.body & { did?: string }
|
|
275
|
+
const targetDid = body.did || auth.credentials.did
|
|
276
|
+
const newHandle = body.handle
|
|
277
|
+
|
|
278
|
+
// Update handle in PLC
|
|
279
|
+
await plcClient.updateHandle(targetDid, opts.plcRotationKey, newHandle)
|
|
280
|
+
|
|
281
|
+
// Update in-memory account
|
|
282
|
+
const account = accounts.get(targetDid)
|
|
283
|
+
if (account) {
|
|
284
|
+
account.handle = newHandle
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Notify PDS via admin endpoint
|
|
288
|
+
const adminAuth = Buffer.from(`admin:${opts.adminPassword}`).toString(
|
|
289
|
+
'base64',
|
|
290
|
+
)
|
|
291
|
+
await pdsAgent.com.atproto.admin.updateAccountHandle(
|
|
292
|
+
{ did: targetDid, handle: newHandle },
|
|
293
|
+
{
|
|
294
|
+
headers: { authorization: `Basic ${adminAuth}` },
|
|
295
|
+
encoding: 'application/json',
|
|
296
|
+
},
|
|
297
|
+
)
|
|
298
|
+
},
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
const httpServer = server.listen(opts.port)
|
|
302
|
+
const terminator = createHttpTerminator({ server: httpServer })
|
|
303
|
+
|
|
304
|
+
const instance = new MockEntryway(httpServer, terminator, idResolver, opts)
|
|
305
|
+
instance.accounts = accounts
|
|
306
|
+
|
|
307
|
+
return instance
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
getAccount(did: string): Account | undefined {
|
|
311
|
+
return this.accounts.get(did)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async destroy(): Promise<void> {
|
|
315
|
+
await this.terminator.terminate()
|
|
316
|
+
}
|
|
317
|
+
}
|
package/tests/entryway.test.ts
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
|
-
import * as os from 'node:os'
|
|
3
|
-
import * as path from 'node:path'
|
|
4
2
|
import * as plcLib from '@did-plc/lib'
|
|
5
3
|
import getPort from 'get-port'
|
|
6
|
-
import { decodeJwt } from 'jose'
|
|
7
|
-
import * as ui8 from 'uint8arrays'
|
|
8
4
|
import { AtpAgent } from '@atproto/api'
|
|
9
|
-
import { Secp256k1Keypair
|
|
5
|
+
import { Secp256k1Keypair } from '@atproto/crypto'
|
|
10
6
|
import { SeedClient, TestPds, TestPlc, mockResolvers } from '@atproto/dev-env'
|
|
11
7
|
import { isDidString } from '@atproto/lex'
|
|
12
|
-
import * as pdsEntryway from '@atproto/pds-entryway'
|
|
13
8
|
import { DidString } from '@atproto/syntax'
|
|
14
|
-
import {
|
|
9
|
+
import { MockEntryway } from './entryway-mock'
|
|
15
10
|
|
|
16
11
|
describe('entryway', () => {
|
|
17
12
|
let plc: TestPlc
|
|
18
13
|
let pds: TestPds
|
|
19
|
-
let entryway:
|
|
14
|
+
let entryway: MockEntryway
|
|
20
15
|
let pdsAgent: AtpAgent
|
|
21
16
|
let entrywayAgent: AtpAgent
|
|
22
17
|
let alice: DidString
|
|
@@ -30,7 +25,7 @@ describe('entryway', () => {
|
|
|
30
25
|
pds = await TestPds.create({
|
|
31
26
|
entrywayUrl: `http://localhost:${entrywayPort}`,
|
|
32
27
|
entrywayDid: 'did:example:entryway',
|
|
33
|
-
entrywayJwtVerifyKeyK256PublicKeyHex:
|
|
28
|
+
entrywayJwtVerifyKeyK256PublicKeyHex: jwtSigningKey.publicKeyStr('hex'),
|
|
34
29
|
entrywayPlcRotationKey: plcRotationKey.did(),
|
|
35
30
|
adminPassword: 'admin-pass',
|
|
36
31
|
serviceHandleDomains: [],
|
|
@@ -38,29 +33,21 @@ describe('entryway', () => {
|
|
|
38
33
|
serviceDid: 'did:example:pds',
|
|
39
34
|
inviteRequired: false,
|
|
40
35
|
})
|
|
41
|
-
entryway = await
|
|
42
|
-
dbPostgresSchema: 'entryway',
|
|
36
|
+
entryway = await MockEntryway.create({
|
|
43
37
|
port: entrywayPort,
|
|
44
|
-
adminPassword: 'admin-pass',
|
|
45
|
-
jwtSigningKeyK256PrivateKeyHex: await getPrivateHex(jwtSigningKey),
|
|
46
|
-
plcRotationKeyK256PrivateKeyHex: await getPrivateHex(plcRotationKey),
|
|
47
|
-
inviteRequired: false,
|
|
48
38
|
serviceDid: 'did:example:entryway',
|
|
49
|
-
|
|
39
|
+
plcUrl: plc.url,
|
|
40
|
+
pdsUrl: pds.url,
|
|
41
|
+
pdsDid: 'did:example:pds',
|
|
42
|
+
adminPassword: 'admin-pass',
|
|
43
|
+
jwtSigningKey,
|
|
44
|
+
plcRotationKey,
|
|
50
45
|
})
|
|
51
46
|
mockResolvers(pds.ctx.idResolver, pds)
|
|
52
|
-
mockResolvers(entryway.
|
|
53
|
-
await entryway.ctx.db.db
|
|
54
|
-
.insertInto('pds')
|
|
55
|
-
.values({
|
|
56
|
-
did: pds.ctx.cfg.service.did,
|
|
57
|
-
host: new URL(pds.ctx.cfg.service.publicUrl).host,
|
|
58
|
-
weight: 1,
|
|
59
|
-
})
|
|
60
|
-
.execute()
|
|
47
|
+
mockResolvers(entryway.idResolver, pds)
|
|
61
48
|
pdsAgent = pds.getAgent()
|
|
62
49
|
entrywayAgent = new AtpAgent({
|
|
63
|
-
service: entryway.
|
|
50
|
+
service: entryway.url,
|
|
64
51
|
})
|
|
65
52
|
})
|
|
66
53
|
|
|
@@ -110,9 +97,7 @@ describe('entryway', () => {
|
|
|
110
97
|
const doc = await pds.ctx.idResolver.did.resolve(alice)
|
|
111
98
|
const handleToDid = await pds.ctx.idResolver.handle.resolve('alice2.test')
|
|
112
99
|
const accountFromPds = await pds.ctx.accountManager.getAccount(alice)
|
|
113
|
-
const accountFromEntryway =
|
|
114
|
-
.account(entryway.ctx.db)
|
|
115
|
-
.getAccount(alice)
|
|
100
|
+
const accountFromEntryway = entryway.getAccount(alice)
|
|
116
101
|
expect(doc?.alsoKnownAs).toEqual(['at://alice2.test'])
|
|
117
102
|
expect(handleToDid).toEqual(alice)
|
|
118
103
|
expect(accountFromPds?.handle).toEqual('alice2.test')
|
|
@@ -128,13 +113,10 @@ describe('entryway', () => {
|
|
|
128
113
|
'com.atproto.identity.updateHandle',
|
|
129
114
|
),
|
|
130
115
|
)
|
|
131
|
-
const doc = await entryway.
|
|
132
|
-
const handleToDid =
|
|
133
|
-
await entryway.ctx.idResolver.handle.resolve('alice3.test')
|
|
116
|
+
const doc = await entryway.idResolver.did.resolve(alice)
|
|
117
|
+
const handleToDid = await entryway.idResolver.handle.resolve('alice3.test')
|
|
134
118
|
const accountFromPds = await pds.ctx.accountManager.getAccount(alice)
|
|
135
|
-
const accountFromEntryway =
|
|
136
|
-
.account(entryway.ctx.db)
|
|
137
|
-
.getAccount(alice)
|
|
119
|
+
const accountFromEntryway = entryway.getAccount(alice)
|
|
138
120
|
expect(doc?.alsoKnownAs).toEqual(['at://alice3.test'])
|
|
139
121
|
expect(handleToDid).toEqual(alice)
|
|
140
122
|
expect(accountFromPds?.handle).toEqual('alice3.test')
|
|
@@ -148,7 +130,7 @@ describe('entryway', () => {
|
|
|
148
130
|
const rotationKey = await Secp256k1Keypair.create()
|
|
149
131
|
const plcCreate = await plcLib.createOp({
|
|
150
132
|
signingKey,
|
|
151
|
-
rotationKeys: [rotationKey.did(), entryway.
|
|
133
|
+
rotationKeys: [rotationKey.did(), entryway.plcRotationKey.did()],
|
|
152
134
|
handle: 'weirdalice.test',
|
|
153
135
|
pds: pds.ctx.cfg.service.publicUrl,
|
|
154
136
|
signer: rotationKey,
|
|
@@ -161,67 +143,3 @@ describe('entryway', () => {
|
|
|
161
143
|
await expect(tryCreateAccount).rejects.toThrow('invalid plc operation')
|
|
162
144
|
})
|
|
163
145
|
})
|
|
164
|
-
|
|
165
|
-
const createEntryway = async (
|
|
166
|
-
config: pdsEntryway.ServerEnvironment & {
|
|
167
|
-
adminPassword: string
|
|
168
|
-
jwtSigningKeyK256PrivateKeyHex: string
|
|
169
|
-
plcRotationKeyK256PrivateKeyHex: string
|
|
170
|
-
},
|
|
171
|
-
) => {
|
|
172
|
-
const signingKey = await Secp256k1Keypair.create({ exportable: true })
|
|
173
|
-
const recoveryKey = await Secp256k1Keypair.create({ exportable: true })
|
|
174
|
-
const env: pdsEntryway.ServerEnvironment = {
|
|
175
|
-
isEntryway: true,
|
|
176
|
-
recoveryDidKey: recoveryKey.did(),
|
|
177
|
-
serviceHandleDomains: ['.test'],
|
|
178
|
-
dbPostgresUrl: process.env.DB_POSTGRES_URL,
|
|
179
|
-
blobstoreDiskLocation: path.join(os.tmpdir(), randomStr(8, 'base32')),
|
|
180
|
-
bskyAppViewUrl: 'https://appview.invalid',
|
|
181
|
-
bskyAppViewDid: 'did:example:invalid',
|
|
182
|
-
bskyAppViewCdnUrlPattern: 'http://cdn.appview.com/%s/%s/%s',
|
|
183
|
-
jwtSecret: randomStr(8, 'base32'),
|
|
184
|
-
repoSigningKeyK256PrivateKeyHex: await getPrivateHex(signingKey),
|
|
185
|
-
modServiceUrl: 'https://mod.invalid',
|
|
186
|
-
modServiceDid: 'did:example:invalid',
|
|
187
|
-
...config,
|
|
188
|
-
}
|
|
189
|
-
const cfg = pdsEntryway.envToCfg(env)
|
|
190
|
-
const secrets = pdsEntryway.envToSecrets(env)
|
|
191
|
-
const server = await pdsEntryway.PDS.create(cfg, secrets)
|
|
192
|
-
await server.ctx.db.migrateToLatestOrThrow()
|
|
193
|
-
await server.start()
|
|
194
|
-
// patch entryway access token verification to handle internal service auth pds -> entryway
|
|
195
|
-
const origValidateAccessToken =
|
|
196
|
-
server.ctx.authVerifier.validateAccessToken.bind(server.ctx.authVerifier)
|
|
197
|
-
server.ctx.authVerifier.validateAccessToken = async (req, scopes) => {
|
|
198
|
-
const jwt = req.headers.authorization?.replace('Bearer ', '') ?? ''
|
|
199
|
-
const claims = decodeJwt(jwt)
|
|
200
|
-
if (claims.aud === 'did:example:entryway') {
|
|
201
|
-
assert(claims.lxm === parseReqNsid(req), 'bad lxm claim in service auth')
|
|
202
|
-
assert(claims.aud, 'missing aud claim in service auth')
|
|
203
|
-
assert(claims.iss, 'missing iss claim in service auth')
|
|
204
|
-
return {
|
|
205
|
-
artifacts: jwt,
|
|
206
|
-
credentials: {
|
|
207
|
-
type: 'access',
|
|
208
|
-
scope: 'com.atproto.access' as any,
|
|
209
|
-
audience: claims.aud,
|
|
210
|
-
did: claims.iss,
|
|
211
|
-
},
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return origValidateAccessToken(req, scopes)
|
|
215
|
-
}
|
|
216
|
-
// @TODO temp hack because entryway teardown calls signupActivator.run() by mistake
|
|
217
|
-
server.ctx.signupActivator.run = server.ctx.signupActivator.destroy
|
|
218
|
-
return server
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const getPublicHex = (key: Secp256k1Keypair) => {
|
|
222
|
-
return key.publicKeyStr('hex')
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const getPrivateHex = async (key: Secp256k1Keypair) => {
|
|
226
|
-
return ui8.toString(await key.export(), 'hex')
|
|
227
|
-
}
|