@clioplaylists/clio 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.env +7 -0
- package/dist/api/com/clioplaylists/alpha/actor/getProfile.d.ts +0 -0
- package/dist/api/com/clioplaylists/alpha/actor/getProfile.js +37 -0
- package/dist/api/com/clioplaylists/alpha/feed/getSongs.d.ts +0 -0
- package/dist/api/com/clioplaylists/alpha/feed/getSongs.js +37 -0
- package/dist/api/health.d.ts +3 -0
- package/dist/api/health.js +25 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.js +6 -0
- package/dist/api/util.d.ts +9 -0
- package/dist/api/util.js +13 -0
- package/dist/auth-verifier.d.ts +92 -0
- package/dist/auth-verifier.js +365 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.js +33 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.js +49 -0
- package/dist/context.d.ts +11 -0
- package/dist/context.js +12 -0
- package/dist/dataplane/client.d.ts +27 -0
- package/dist/dataplane/client.js +120 -0
- package/dist/dataplane/index.d.ts +2 -0
- package/dist/dataplane/index.js +2 -0
- package/dist/dataplane/server/background.d.ts +13 -0
- package/dist/dataplane/server/background.js +30 -0
- package/dist/dataplane/server/db/database-schema.d.ts +13 -0
- package/dist/dataplane/server/db/database-schema.js +1 -0
- package/dist/dataplane/server/db/db.d.ts +32 -0
- package/dist/dataplane/server/db/db.js +152 -0
- package/dist/dataplane/server/db/index.d.ts +1 -0
- package/dist/dataplane/server/db/index.js +1 -0
- package/dist/dataplane/server/db/migrations/20230309T045948368Z-init.d.ts +3 -0
- package/dist/dataplane/server/db/migrations/20230309T045948368Z-init.js +113 -0
- package/dist/dataplane/server/db/migrations/20230420T211446071Z-did-cache.d.ts +3 -0
- package/dist/dataplane/server/db/migrations/20230420T211446071Z-did-cache.js +11 -0
- package/dist/dataplane/server/db/migrations/index.d.ts +2 -0
- package/dist/dataplane/server/db/migrations/index.js +5 -0
- package/dist/dataplane/server/db/migrations/provider.d.ts +11 -0
- package/dist/dataplane/server/db/migrations/provider.js +19 -0
- package/dist/dataplane/server/db/pagination.d.ts +86 -0
- package/dist/dataplane/server/db/pagination.js +128 -0
- package/dist/dataplane/server/db/tables/actor-sync.d.ts +9 -0
- package/dist/dataplane/server/db/tables/actor-sync.js +1 -0
- package/dist/dataplane/server/db/tables/actor.d.ts +11 -0
- package/dist/dataplane/server/db/tables/actor.js +1 -0
- package/dist/dataplane/server/db/tables/artist-list-item.d.ts +11 -0
- package/dist/dataplane/server/db/tables/artist-list-item.js +1 -0
- package/dist/dataplane/server/db/tables/artist.d.ts +10 -0
- package/dist/dataplane/server/db/tables/artist.js +1 -0
- package/dist/dataplane/server/db/tables/playlist-idea.d.ts +14 -0
- package/dist/dataplane/server/db/tables/playlist-idea.js +1 -0
- package/dist/dataplane/server/db/tables/playlist-item.d.ts +11 -0
- package/dist/dataplane/server/db/tables/playlist-item.js +1 -0
- package/dist/dataplane/server/db/tables/playlist.d.ts +10 -0
- package/dist/dataplane/server/db/tables/playlist.js +1 -0
- package/dist/dataplane/server/db/tables/profile.d.ts +15 -0
- package/dist/dataplane/server/db/tables/profile.js +1 -0
- package/dist/dataplane/server/db/tables/record.d.ts +12 -0
- package/dist/dataplane/server/db/tables/record.js +1 -0
- package/dist/dataplane/server/db/tables/song.d.ts +12 -0
- package/dist/dataplane/server/db/tables/song.js +1 -0
- package/dist/dataplane/server/db/types.d.ts +9 -0
- package/dist/dataplane/server/db/types.js +1 -0
- package/dist/dataplane/server/db/util.d.ts +20 -0
- package/dist/dataplane/server/db/util.js +40 -0
- package/dist/dataplane/server/index.d.ts +11 -0
- package/dist/dataplane/server/index.js +36 -0
- package/dist/dataplane/server/indexing/index.d.ts +32 -0
- package/dist/dataplane/server/indexing/index.js +271 -0
- package/dist/dataplane/server/indexing/plugins/playlist-idea.d.ts +14 -0
- package/dist/dataplane/server/indexing/plugins/playlist-idea.js +126 -0
- package/dist/dataplane/server/indexing/plugins/profile.d.ts +8 -0
- package/dist/dataplane/server/indexing/plugins/profile.js +44 -0
- package/dist/dataplane/server/indexing/processor.d.ts +22 -0
- package/dist/dataplane/server/indexing/processor.js +72 -0
- package/dist/dataplane/server/routes/identity.d.ts +6 -0
- package/dist/dataplane/server/routes/identity.js +54 -0
- package/dist/dataplane/server/routes/index.d.ts +5 -0
- package/dist/dataplane/server/routes/index.js +14 -0
- package/dist/dataplane/server/routes/profile.d.ts +5 -0
- package/dist/dataplane/server/routes/profile.js +59 -0
- package/dist/dataplane/server/routes/records.d.ts +11 -0
- package/dist/dataplane/server/routes/records.js +51 -0
- package/dist/dataplane/server/routes/sync.d.ts +5 -0
- package/dist/dataplane/server/routes/sync.js +12 -0
- package/dist/dataplane/server/subscription.d.ts +25 -0
- package/dist/dataplane/server/subscription.js +86 -0
- package/dist/error.d.ts +2 -0
- package/dist/error.js +10 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +55 -0
- package/dist/lexicons/index.d.ts +278 -0
- package/dist/lexicons/index.js +463 -0
- package/dist/lexicons/lexicons.d.ts +8466 -0
- package/dist/lexicons/lexicons.js +4548 -0
- package/dist/lexicons/types/com/atproto/admin/defs.d.ts +50 -0
- package/dist/lexicons/types/com/atproto/admin/defs.js +42 -0
- package/dist/lexicons/types/com/atproto/admin/deleteAccount.d.ts +29 -0
- package/dist/lexicons/types/com/atproto/admin/deleteAccount.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/disableAccountInvites.d.ts +31 -0
- package/dist/lexicons/types/com/atproto/admin/disableAccountInvites.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/disableInviteCodes.d.ts +30 -0
- package/dist/lexicons/types/com/atproto/admin/disableInviteCodes.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/enableAccountInvites.d.ts +31 -0
- package/dist/lexicons/types/com/atproto/admin/enableAccountInvites.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/getAccountInfo.d.ts +33 -0
- package/dist/lexicons/types/com/atproto/admin/getAccountInfo.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/getAccountInfos.d.ts +36 -0
- package/dist/lexicons/types/com/atproto/admin/getAccountInfos.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/getInviteCodes.d.ts +39 -0
- package/dist/lexicons/types/com/atproto/admin/getInviteCodes.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/getSubjectStatus.d.ts +44 -0
- package/dist/lexicons/types/com/atproto/admin/getSubjectStatus.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/searchAccounts.d.ts +39 -0
- package/dist/lexicons/types/com/atproto/admin/searchAccounts.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/sendEmail.d.ts +45 -0
- package/dist/lexicons/types/com/atproto/admin/sendEmail.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/updateAccountEmail.d.ts +31 -0
- package/dist/lexicons/types/com/atproto/admin/updateAccountEmail.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/updateAccountHandle.d.ts +30 -0
- package/dist/lexicons/types/com/atproto/admin/updateAccountHandle.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/updateAccountPassword.d.ts +30 -0
- package/dist/lexicons/types/com/atproto/admin/updateAccountPassword.js +1 -0
- package/dist/lexicons/types/com/atproto/admin/updateSubjectStatus.d.ts +51 -0
- package/dist/lexicons/types/com/atproto/admin/updateSubjectStatus.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/defs.d.ts +14 -0
- package/dist/lexicons/types/com/atproto/identity/defs.js +10 -0
- package/dist/lexicons/types/com/atproto/identity/getRecommendedDidCredentials.d.ts +38 -0
- package/dist/lexicons/types/com/atproto/identity/getRecommendedDidCredentials.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/refreshIdentity.d.ts +39 -0
- package/dist/lexicons/types/com/atproto/identity/refreshIdentity.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/requestPlcOperationSignature.d.ts +23 -0
- package/dist/lexicons/types/com/atproto/identity/requestPlcOperationSignature.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/resolveDid.d.ts +38 -0
- package/dist/lexicons/types/com/atproto/identity/resolveDid.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/resolveHandle.d.ts +37 -0
- package/dist/lexicons/types/com/atproto/identity/resolveHandle.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/resolveIdentity.d.ts +35 -0
- package/dist/lexicons/types/com/atproto/identity/resolveIdentity.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/signPlcOperation.d.ts +46 -0
- package/dist/lexicons/types/com/atproto/identity/signPlcOperation.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/submitPlcOperation.d.ts +29 -0
- package/dist/lexicons/types/com/atproto/identity/submitPlcOperation.js +1 -0
- package/dist/lexicons/types/com/atproto/identity/updateHandle.d.ts +30 -0
- package/dist/lexicons/types/com/atproto/identity/updateHandle.js +1 -0
- package/dist/lexicons/types/com/atproto/label/defs.d.ts +73 -0
- package/dist/lexicons/types/com/atproto/label/defs.js +42 -0
- package/dist/lexicons/types/com/atproto/label/queryLabels.d.ts +42 -0
- package/dist/lexicons/types/com/atproto/label/queryLabels.js +1 -0
- package/dist/lexicons/types/com/atproto/label/subscribeLabels.d.ts +38 -0
- package/dist/lexicons/types/com/atproto/label/subscribeLabels.js +18 -0
- package/dist/lexicons/types/com/atproto/lexicon/schema.d.ts +11 -0
- package/dist/lexicons/types/com/atproto/lexicon/schema.js +11 -0
- package/dist/lexicons/types/com/atproto/moderation/createReport.d.ts +57 -0
- package/dist/lexicons/types/com/atproto/moderation/createReport.js +1 -0
- package/dist/lexicons/types/com/atproto/moderation/defs.d.ts +20 -0
- package/dist/lexicons/types/com/atproto/moderation/defs.js +17 -0
- package/dist/lexicons/types/com/atproto/repo/applyWrites.d.ts +98 -0
- package/dist/lexicons/types/com/atproto/repo/applyWrites.js +50 -0
- package/dist/lexicons/types/com/atproto/repo/createRecord.d.ts +56 -0
- package/dist/lexicons/types/com/atproto/repo/createRecord.js +1 -0
- package/dist/lexicons/types/com/atproto/repo/defs.d.ts +11 -0
- package/dist/lexicons/types/com/atproto/repo/defs.js +10 -0
- package/dist/lexicons/types/com/atproto/repo/deleteRecord.d.ts +51 -0
- package/dist/lexicons/types/com/atproto/repo/deleteRecord.js +1 -0
- package/dist/lexicons/types/com/atproto/repo/describeRepo.d.ts +43 -0
- package/dist/lexicons/types/com/atproto/repo/describeRepo.js +1 -0
- package/dist/lexicons/types/com/atproto/repo/getRecord.d.ts +45 -0
- package/dist/lexicons/types/com/atproto/repo/getRecord.js +1 -0
- package/dist/lexicons/types/com/atproto/repo/importRepo.d.ts +27 -0
- package/dist/lexicons/types/com/atproto/repo/importRepo.js +1 -0
- package/dist/lexicons/types/com/atproto/repo/listMissingBlobs.d.ts +45 -0
- package/dist/lexicons/types/com/atproto/repo/listMissingBlobs.js +10 -0
- package/dist/lexicons/types/com/atproto/repo/listRecords.d.ts +53 -0
- package/dist/lexicons/types/com/atproto/repo/listRecords.js +10 -0
- package/dist/lexicons/types/com/atproto/repo/putRecord.d.ts +58 -0
- package/dist/lexicons/types/com/atproto/repo/putRecord.js +1 -0
- package/dist/lexicons/types/com/atproto/repo/strongRef.d.ts +11 -0
- package/dist/lexicons/types/com/atproto/repo/strongRef.js +11 -0
- package/dist/lexicons/types/com/atproto/repo/uploadBlob.d.ts +39 -0
- package/dist/lexicons/types/com/atproto/repo/uploadBlob.js +1 -0
- package/dist/lexicons/types/com/atproto/server/activateAccount.d.ts +23 -0
- package/dist/lexicons/types/com/atproto/server/activateAccount.js +1 -0
- package/dist/lexicons/types/com/atproto/server/checkAccountStatus.d.ts +42 -0
- package/dist/lexicons/types/com/atproto/server/checkAccountStatus.js +1 -0
- package/dist/lexicons/types/com/atproto/server/confirmEmail.d.ts +31 -0
- package/dist/lexicons/types/com/atproto/server/confirmEmail.js +1 -0
- package/dist/lexicons/types/com/atproto/server/createAccount.d.ts +61 -0
- package/dist/lexicons/types/com/atproto/server/createAccount.js +1 -0
- package/dist/lexicons/types/com/atproto/server/createAppPassword.d.ts +51 -0
- package/dist/lexicons/types/com/atproto/server/createAppPassword.js +10 -0
- package/dist/lexicons/types/com/atproto/server/createInviteCode.d.ts +41 -0
- package/dist/lexicons/types/com/atproto/server/createInviteCode.js +1 -0
- package/dist/lexicons/types/com/atproto/server/createInviteCodes.d.ts +50 -0
- package/dist/lexicons/types/com/atproto/server/createInviteCodes.js +10 -0
- package/dist/lexicons/types/com/atproto/server/createSession.d.ts +56 -0
- package/dist/lexicons/types/com/atproto/server/createSession.js +1 -0
- package/dist/lexicons/types/com/atproto/server/deactivateAccount.d.ts +30 -0
- package/dist/lexicons/types/com/atproto/server/deactivateAccount.js +1 -0
- package/dist/lexicons/types/com/atproto/server/defs.d.ts +23 -0
- package/dist/lexicons/types/com/atproto/server/defs.js +18 -0
- package/dist/lexicons/types/com/atproto/server/deleteAccount.d.ts +32 -0
- package/dist/lexicons/types/com/atproto/server/deleteAccount.js +1 -0
- package/dist/lexicons/types/com/atproto/server/deleteSession.d.ts +23 -0
- package/dist/lexicons/types/com/atproto/server/deleteSession.js +1 -0
- package/dist/lexicons/types/com/atproto/server/describeServer.d.ts +56 -0
- package/dist/lexicons/types/com/atproto/server/describeServer.js +18 -0
- package/dist/lexicons/types/com/atproto/server/getAccountInviteCodes.d.ts +39 -0
- package/dist/lexicons/types/com/atproto/server/getAccountInviteCodes.js +1 -0
- package/dist/lexicons/types/com/atproto/server/getServiceAuth.d.ts +41 -0
- package/dist/lexicons/types/com/atproto/server/getServiceAuth.js +1 -0
- package/dist/lexicons/types/com/atproto/server/getSession.d.ts +42 -0
- package/dist/lexicons/types/com/atproto/server/getSession.js +1 -0
- package/dist/lexicons/types/com/atproto/server/listAppPasswords.d.ts +44 -0
- package/dist/lexicons/types/com/atproto/server/listAppPasswords.js +10 -0
- package/dist/lexicons/types/com/atproto/server/refreshSession.d.ts +42 -0
- package/dist/lexicons/types/com/atproto/server/refreshSession.js +1 -0
- package/dist/lexicons/types/com/atproto/server/requestAccountDelete.d.ts +23 -0
- package/dist/lexicons/types/com/atproto/server/requestAccountDelete.js +1 -0
- package/dist/lexicons/types/com/atproto/server/requestEmailConfirmation.d.ts +23 -0
- package/dist/lexicons/types/com/atproto/server/requestEmailConfirmation.js +1 -0
- package/dist/lexicons/types/com/atproto/server/requestEmailUpdate.d.ts +34 -0
- package/dist/lexicons/types/com/atproto/server/requestEmailUpdate.js +1 -0
- package/dist/lexicons/types/com/atproto/server/requestPasswordReset.d.ts +29 -0
- package/dist/lexicons/types/com/atproto/server/requestPasswordReset.js +1 -0
- package/dist/lexicons/types/com/atproto/server/reserveSigningKey.d.ts +42 -0
- package/dist/lexicons/types/com/atproto/server/reserveSigningKey.js +1 -0
- package/dist/lexicons/types/com/atproto/server/resetPassword.d.ts +31 -0
- package/dist/lexicons/types/com/atproto/server/resetPassword.js +1 -0
- package/dist/lexicons/types/com/atproto/server/revokeAppPassword.d.ts +29 -0
- package/dist/lexicons/types/com/atproto/server/revokeAppPassword.js +1 -0
- package/dist/lexicons/types/com/atproto/server/updateEmail.d.ts +33 -0
- package/dist/lexicons/types/com/atproto/server/updateEmail.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getBlob.d.ts +36 -0
- package/dist/lexicons/types/com/atproto/sync/getBlob.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getBlocks.d.ts +35 -0
- package/dist/lexicons/types/com/atproto/sync/getBlocks.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getCheckout.d.ts +33 -0
- package/dist/lexicons/types/com/atproto/sync/getCheckout.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getHead.d.ts +37 -0
- package/dist/lexicons/types/com/atproto/sync/getHead.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getLatestCommit.d.ts +38 -0
- package/dist/lexicons/types/com/atproto/sync/getLatestCommit.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getRecord.d.ts +37 -0
- package/dist/lexicons/types/com/atproto/sync/getRecord.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getRepo.d.ts +36 -0
- package/dist/lexicons/types/com/atproto/sync/getRepo.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/getRepoStatus.d.ts +42 -0
- package/dist/lexicons/types/com/atproto/sync/getRepoStatus.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/listBlobs.d.ts +42 -0
- package/dist/lexicons/types/com/atproto/sync/listBlobs.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/listRepos.d.ts +50 -0
- package/dist/lexicons/types/com/atproto/sync/listRepos.js +10 -0
- package/dist/lexicons/types/com/atproto/sync/listReposByCollection.d.ts +46 -0
- package/dist/lexicons/types/com/atproto/sync/listReposByCollection.js +10 -0
- package/dist/lexicons/types/com/atproto/sync/notifyOfUpdate.d.ts +30 -0
- package/dist/lexicons/types/com/atproto/sync/notifyOfUpdate.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/requestCrawl.d.ts +30 -0
- package/dist/lexicons/types/com/atproto/sync/requestCrawl.js +1 -0
- package/dist/lexicons/types/com/atproto/sync/subscribeRepos.d.ts +111 -0
- package/dist/lexicons/types/com/atproto/sync/subscribeRepos.js +50 -0
- package/dist/lexicons/types/com/atproto/temp/addReservedHandle.d.ts +39 -0
- package/dist/lexicons/types/com/atproto/temp/addReservedHandle.js +1 -0
- package/dist/lexicons/types/com/atproto/temp/checkSignupQueue.d.ts +36 -0
- package/dist/lexicons/types/com/atproto/temp/checkSignupQueue.js +1 -0
- package/dist/lexicons/types/com/atproto/temp/fetchLabels.d.ts +37 -0
- package/dist/lexicons/types/com/atproto/temp/fetchLabels.js +1 -0
- package/dist/lexicons/types/com/atproto/temp/requestPhoneVerification.d.ts +29 -0
- package/dist/lexicons/types/com/atproto/temp/requestPhoneVerification.js +1 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/actor/profile.d.ts +19 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/actor/profile.js +11 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/defs.d.ts +32 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/defs.js +18 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/getSongs.d.ts +37 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/getSongs.js +1 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/playlistIdea.d.ts +32 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/playlistIdea.js +27 -0
- package/dist/lexicons/util.d.ts +5 -0
- package/dist/lexicons/util.js +9 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +20 -0
- package/dist/rpc/clio_connect.d.ts +103 -0
- package/dist/rpc/clio_connect.js +107 -0
- package/dist/rpc/clio_pb.d.ts +457 -0
- package/dist/rpc/clio_pb.js +811 -0
- package/dist/start.d.ts +1 -0
- package/dist/util/retry.d.ts +2 -0
- package/dist/util/retry.js +13 -0
- package/dist/util/uris.d.ts +1 -0
- package/dist/util/uris.js +4 -0
- package/dist/util.d.ts +23 -0
- package/dist/util.js +76 -0
- package/package.json +7 -7
- /package/{start.js → dist/start.js} +0 -0
package/dist/.env
ADDED
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import AppContext from '../../../../../context'
|
|
3
|
+
// import { Server } from '../../../../../lexicons'
|
|
4
|
+
// import { OutputSchema } from '../../../../../lexicons/types/com/clioplaylists/alpha/feed/getSongs'
|
|
5
|
+
// import { Record as SongRecord } from '../../../../../lexicons/types/com/clioplaylists/alpha/feed/song'
|
|
6
|
+
// import { parseRecord } from '../../../../../util'
|
|
7
|
+
// import { resHeaders } from '../../../../util'
|
|
8
|
+
// export default function (server: Server, ctx: AppContext) {
|
|
9
|
+
// server.com.clioplaylists.alpha.feed.getSongs({
|
|
10
|
+
// handler: async ({ params, auth, req }) => {
|
|
11
|
+
// const res = await ctx.dataplane.getSongRecords({})
|
|
12
|
+
// let results: OutputSchema = {
|
|
13
|
+
// songs: []
|
|
14
|
+
// }
|
|
15
|
+
// res.records.forEach((recordWrapper) => {
|
|
16
|
+
// const recordRes = parseRecord<SongRecord>(recordWrapper, false)
|
|
17
|
+
// if (!recordRes) {
|
|
18
|
+
// console.log("Could not deserialize SongRecord")
|
|
19
|
+
// return
|
|
20
|
+
// }
|
|
21
|
+
// results.songs.push({
|
|
22
|
+
// trackName: recordRes.record.trackName,
|
|
23
|
+
// trackMbId: recordRes.record.trackMbId,
|
|
24
|
+
// artistNames: recordRes.record.artistNames,
|
|
25
|
+
// artistMbIds: recordRes.record.artistMbIds,
|
|
26
|
+
// albumArtwork: recordRes.record.albumArtwork,
|
|
27
|
+
// createdAt: recordRes.record.createdAt
|
|
28
|
+
// })
|
|
29
|
+
// })
|
|
30
|
+
// return {
|
|
31
|
+
// encoding: 'application/json',
|
|
32
|
+
// body: results,
|
|
33
|
+
// headers: resHeaders({}),
|
|
34
|
+
// }
|
|
35
|
+
// }
|
|
36
|
+
// })
|
|
37
|
+
// }
|
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import AppContext from '../../../../../context'
|
|
3
|
+
// import { Server } from '../../../../../lexicons'
|
|
4
|
+
// import { OutputSchema } from '../../../../../lexicons/types/com/clioplaylists/alpha/feed/getSongs'
|
|
5
|
+
// import { Record as SongRecord } from '../../../../../lexicons/types/com/clioplaylists/alpha/feed/song'
|
|
6
|
+
// import { parseRecord } from '../../../../../util'
|
|
7
|
+
// import { resHeaders } from '../../../../util'
|
|
8
|
+
// export default function (server: Server, ctx: AppContext) {
|
|
9
|
+
// server.com.clioplaylists.alpha.feed.getSongs({
|
|
10
|
+
// handler: async ({ params, auth, req }) => {
|
|
11
|
+
// const res = await ctx.dataplane.getSongRecords({})
|
|
12
|
+
// let results: OutputSchema = {
|
|
13
|
+
// songs: []
|
|
14
|
+
// }
|
|
15
|
+
// res.records.forEach((recordWrapper) => {
|
|
16
|
+
// const recordRes = parseRecord<SongRecord>(recordWrapper, false)
|
|
17
|
+
// if (!recordRes) {
|
|
18
|
+
// console.log("Could not deserialize SongRecord")
|
|
19
|
+
// return
|
|
20
|
+
// }
|
|
21
|
+
// results.songs.push({
|
|
22
|
+
// trackName: recordRes.record.trackName,
|
|
23
|
+
// trackMbId: recordRes.record.trackMbId,
|
|
24
|
+
// artistNames: recordRes.record.artistNames,
|
|
25
|
+
// artistMbIds: recordRes.record.artistMbIds,
|
|
26
|
+
// albumArtwork: recordRes.record.albumArtwork,
|
|
27
|
+
// createdAt: recordRes.record.createdAt
|
|
28
|
+
// })
|
|
29
|
+
// })
|
|
30
|
+
// return {
|
|
31
|
+
// encoding: 'application/json',
|
|
32
|
+
// body: results,
|
|
33
|
+
// headers: resHeaders({}),
|
|
34
|
+
// }
|
|
35
|
+
// }
|
|
36
|
+
// })
|
|
37
|
+
// }
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
export const createRouter = (ctx) => {
|
|
3
|
+
const router = express.Router();
|
|
4
|
+
router.get('/', function (req, res) {
|
|
5
|
+
res.type('text/plain');
|
|
6
|
+
res.send(`
|
|
7
|
+
___ __ ____ _____
|
|
8
|
+
/ __)( ) (_ _)( _ )
|
|
9
|
+
( (__ )(__ _)(_ )(_)(
|
|
10
|
+
\___)(____)(____)(_____)
|
|
11
|
+
|
|
12
|
+
This is an AT Protocol Application View (AppView) for the "clioplaylists.com" application.
|
|
13
|
+
|
|
14
|
+
Most API routes are under /xrpc/
|
|
15
|
+
|
|
16
|
+
Code: https://github.com/Hoid/clio-api
|
|
17
|
+
Protocol: https://atproto.com
|
|
18
|
+
`);
|
|
19
|
+
});
|
|
20
|
+
router.get('/xrpc/_health', async function (req, res) {
|
|
21
|
+
const { version } = ctx.cfg;
|
|
22
|
+
res.send({ version });
|
|
23
|
+
});
|
|
24
|
+
return router;
|
|
25
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ParsedLabelers } from '../util';
|
|
2
|
+
export declare const ATPROTO_CONTENT_LABELERS = "Atproto-Content-Labelers";
|
|
3
|
+
export declare const ATPROTO_REPO_REV = "Atproto-Repo-Rev";
|
|
4
|
+
type ResHeaderOpts = {
|
|
5
|
+
labelers: ParsedLabelers;
|
|
6
|
+
repoRev: string | null;
|
|
7
|
+
};
|
|
8
|
+
export declare const resHeaders: (opts: Partial<ResHeaderOpts>) => Record<string, string>;
|
|
9
|
+
export {};
|
package/dist/api/util.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { formatLabelerHeader } from '../util';
|
|
2
|
+
export const ATPROTO_CONTENT_LABELERS = 'Atproto-Content-Labelers';
|
|
3
|
+
export const ATPROTO_REPO_REV = 'Atproto-Repo-Rev';
|
|
4
|
+
export const resHeaders = (opts) => {
|
|
5
|
+
const headers = {};
|
|
6
|
+
if (opts.labelers) {
|
|
7
|
+
headers[ATPROTO_CONTENT_LABELERS] = formatLabelerHeader(opts.labelers);
|
|
8
|
+
}
|
|
9
|
+
if (opts.repoRev) {
|
|
10
|
+
headers[ATPROTO_REPO_REV] = opts.repoRev;
|
|
11
|
+
}
|
|
12
|
+
return headers;
|
|
13
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { VerifySignatureWithKeyFn } from '@atproto/xrpc-server';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { KeyObject } from 'node:crypto';
|
|
4
|
+
import { DataPlaneClient } from './client';
|
|
5
|
+
type ReqCtx = {
|
|
6
|
+
req: express.Request;
|
|
7
|
+
};
|
|
8
|
+
type StandardAuthOpts = {
|
|
9
|
+
skipAudCheck?: boolean;
|
|
10
|
+
lxmCheck?: (method?: string) => boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare enum RoleStatus {
|
|
13
|
+
Valid = 0,
|
|
14
|
+
Invalid = 1,
|
|
15
|
+
Missing = 2
|
|
16
|
+
}
|
|
17
|
+
type NullOutput = {
|
|
18
|
+
credentials: {
|
|
19
|
+
type: 'none';
|
|
20
|
+
iss: null;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
type StandardOutput = {
|
|
24
|
+
credentials: {
|
|
25
|
+
type: 'standard';
|
|
26
|
+
aud: string;
|
|
27
|
+
iss: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
type RoleOutput = {
|
|
31
|
+
credentials: {
|
|
32
|
+
type: 'role';
|
|
33
|
+
admin: boolean;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
type ModServiceOutput = {
|
|
37
|
+
credentials: {
|
|
38
|
+
type: 'mod_service';
|
|
39
|
+
aud: string;
|
|
40
|
+
iss: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export type AuthVerifierOpts = {
|
|
44
|
+
ownDid: string;
|
|
45
|
+
alternateAudienceDids: string[];
|
|
46
|
+
modServiceDid: string;
|
|
47
|
+
adminPasses: string[];
|
|
48
|
+
entrywayJwtPublicKey?: KeyObject;
|
|
49
|
+
};
|
|
50
|
+
export declare class AuthVerifier {
|
|
51
|
+
dataplane: DataPlaneClient;
|
|
52
|
+
ownDid: string;
|
|
53
|
+
standardAudienceDids: Set<string>;
|
|
54
|
+
modServiceDid: string;
|
|
55
|
+
private adminPasses;
|
|
56
|
+
private entrywayJwtPublicKey?;
|
|
57
|
+
constructor(dataplane: DataPlaneClient, opts: AuthVerifierOpts);
|
|
58
|
+
standardOptionalParameterized: (opts: StandardAuthOpts) => (ctx: ReqCtx) => Promise<StandardOutput | NullOutput>;
|
|
59
|
+
standardOptional: (ctx: ReqCtx) => Promise<StandardOutput | NullOutput>;
|
|
60
|
+
standard: (ctx: ReqCtx) => Promise<StandardOutput>;
|
|
61
|
+
role: (ctx: ReqCtx) => RoleOutput;
|
|
62
|
+
standardOrRole: (ctx: ReqCtx) => Promise<StandardOutput | RoleOutput>;
|
|
63
|
+
optionalStandardOrRole: (ctx: ReqCtx) => Promise<StandardOutput | RoleOutput | NullOutput>;
|
|
64
|
+
entrywaySession: (reqCtx: ReqCtx) => Promise<StandardOutput>;
|
|
65
|
+
parseRoleCreds(req: express.Request): {
|
|
66
|
+
status: RoleStatus;
|
|
67
|
+
admin: boolean;
|
|
68
|
+
moderator: boolean;
|
|
69
|
+
triage: boolean;
|
|
70
|
+
} | {
|
|
71
|
+
status: RoleStatus;
|
|
72
|
+
admin: boolean;
|
|
73
|
+
moderator?: undefined;
|
|
74
|
+
triage?: undefined;
|
|
75
|
+
};
|
|
76
|
+
isModService(iss: string): boolean;
|
|
77
|
+
nullCreds(): NullOutput;
|
|
78
|
+
parseCreds(creds: StandardOutput | RoleOutput | ModServiceOutput | NullOutput): {
|
|
79
|
+
viewer: string | null;
|
|
80
|
+
includeTakedowns: boolean;
|
|
81
|
+
include3pBlocks: boolean;
|
|
82
|
+
canPerformTakedown: boolean;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export declare const parseBasicAuth: (token: string) => {
|
|
86
|
+
username: string;
|
|
87
|
+
password: string;
|
|
88
|
+
} | null;
|
|
89
|
+
export declare const buildBasicAuth: (username: string, password: string) => string;
|
|
90
|
+
export declare const createPublicKeyObject: (publicKeyHex: string) => KeyObject;
|
|
91
|
+
export declare const verifySignatureWithKey: VerifySignatureWithKeyFn;
|
|
92
|
+
export {};
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { AuthRequiredError, cryptoVerifySignatureWithKey, } from '@atproto/xrpc-server';
|
|
2
|
+
import * as jose from 'jose';
|
|
3
|
+
import KeyEncoder from 'key-encoder';
|
|
4
|
+
import crypto from 'node:crypto';
|
|
5
|
+
import * as ui8 from 'uint8arrays';
|
|
6
|
+
// import { GetIdentityByDidResponse } from './proto/bsky_pb'
|
|
7
|
+
import { parseDidKey, SECP256K1_JWT_ALG } from '@atproto/crypto';
|
|
8
|
+
export var RoleStatus;
|
|
9
|
+
(function (RoleStatus) {
|
|
10
|
+
RoleStatus[RoleStatus["Valid"] = 0] = "Valid";
|
|
11
|
+
RoleStatus[RoleStatus["Invalid"] = 1] = "Invalid";
|
|
12
|
+
RoleStatus[RoleStatus["Missing"] = 2] = "Missing";
|
|
13
|
+
})(RoleStatus || (RoleStatus = {}));
|
|
14
|
+
const ALLOWED_AUTH_SCOPES = new Set([
|
|
15
|
+
'com.atproto.access',
|
|
16
|
+
'com.atproto.appPass',
|
|
17
|
+
'com.atproto.appPassPrivileged',
|
|
18
|
+
]);
|
|
19
|
+
export class AuthVerifier {
|
|
20
|
+
dataplane;
|
|
21
|
+
ownDid;
|
|
22
|
+
standardAudienceDids;
|
|
23
|
+
modServiceDid;
|
|
24
|
+
adminPasses;
|
|
25
|
+
entrywayJwtPublicKey;
|
|
26
|
+
constructor(dataplane, opts) {
|
|
27
|
+
this.dataplane = dataplane;
|
|
28
|
+
this.ownDid = opts.ownDid;
|
|
29
|
+
this.standardAudienceDids = new Set([
|
|
30
|
+
opts.ownDid,
|
|
31
|
+
...opts.alternateAudienceDids,
|
|
32
|
+
]);
|
|
33
|
+
this.modServiceDid = opts.modServiceDid;
|
|
34
|
+
this.adminPasses = new Set(opts.adminPasses);
|
|
35
|
+
this.entrywayJwtPublicKey = opts.entrywayJwtPublicKey;
|
|
36
|
+
}
|
|
37
|
+
// verifiers (arrow fns to preserve scope)
|
|
38
|
+
standardOptionalParameterized = (opts) => async (ctx) => {
|
|
39
|
+
// @TODO remove! basic auth + did supported just for testing.
|
|
40
|
+
if (isBasicToken(ctx.req)) {
|
|
41
|
+
const aud = this.ownDid;
|
|
42
|
+
const iss = ctx.req.headers['appview-as-did'];
|
|
43
|
+
if (typeof iss !== 'string' || !iss.startsWith('did:')) {
|
|
44
|
+
throw new AuthRequiredError('bad issuer');
|
|
45
|
+
}
|
|
46
|
+
if (!this.parseRoleCreds(ctx.req).admin) {
|
|
47
|
+
throw new AuthRequiredError('bad credentials');
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
credentials: { type: 'standard', iss, aud },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
else if (isBearerToken(ctx.req)) {
|
|
54
|
+
// @NOTE temporarily accept entryway session tokens to shed load from PDS instances
|
|
55
|
+
const token = bearerTokenFromReq(ctx.req);
|
|
56
|
+
const header = token ? jose.decodeProtectedHeader(token) : undefined;
|
|
57
|
+
if (header?.typ === 'at+jwt') {
|
|
58
|
+
// we should never use entryway session tokens in the case of flexible auth audiences (namely in the case of getFeed)
|
|
59
|
+
if (opts.skipAudCheck) {
|
|
60
|
+
throw new AuthRequiredError('Malformed token', 'InvalidToken');
|
|
61
|
+
}
|
|
62
|
+
return this.entrywaySession(ctx);
|
|
63
|
+
}
|
|
64
|
+
// const { iss, aud } = await this.verifyServiceJwt(ctx, {
|
|
65
|
+
// lxmCheck: opts.lxmCheck,
|
|
66
|
+
// iss: null,
|
|
67
|
+
// aud: null,
|
|
68
|
+
// })
|
|
69
|
+
const { aud } = {
|
|
70
|
+
// iss: '',
|
|
71
|
+
aud: '',
|
|
72
|
+
};
|
|
73
|
+
if (!opts.skipAudCheck && !this.standardAudienceDids.has(aud)) {
|
|
74
|
+
throw new AuthRequiredError('jwt audience does not match service did', 'BadJwtAudience');
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
credentials: {
|
|
78
|
+
type: 'standard',
|
|
79
|
+
iss: '',
|
|
80
|
+
aud: '',
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return this.nullCreds();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
standardOptional = this.standardOptionalParameterized({});
|
|
89
|
+
standard = async (ctx) => {
|
|
90
|
+
const output = await this.standardOptional(ctx);
|
|
91
|
+
if (output.credentials.type === 'none') {
|
|
92
|
+
throw new AuthRequiredError(undefined, 'AuthMissing');
|
|
93
|
+
}
|
|
94
|
+
return output;
|
|
95
|
+
};
|
|
96
|
+
role = (ctx) => {
|
|
97
|
+
const creds = this.parseRoleCreds(ctx.req);
|
|
98
|
+
if (creds.status !== RoleStatus.Valid) {
|
|
99
|
+
throw new AuthRequiredError();
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
credentials: {
|
|
103
|
+
...creds,
|
|
104
|
+
type: 'role',
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
standardOrRole = async (ctx) => {
|
|
109
|
+
if (isBearerToken(ctx.req)) {
|
|
110
|
+
return this.standard(ctx);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
return this.role(ctx);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
optionalStandardOrRole = async (ctx) => {
|
|
117
|
+
if (isBearerToken(ctx.req)) {
|
|
118
|
+
return await this.standard(ctx);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
const creds = this.parseRoleCreds(ctx.req);
|
|
122
|
+
if (creds.status === RoleStatus.Valid) {
|
|
123
|
+
return {
|
|
124
|
+
credentials: {
|
|
125
|
+
...creds,
|
|
126
|
+
type: 'role',
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
else if (creds.status === RoleStatus.Missing) {
|
|
131
|
+
return this.nullCreds();
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
throw new AuthRequiredError();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
// @NOTE this auth verifier method is not recommended to be implemented by most appviews
|
|
139
|
+
// this is a short term fix to remove proxy load from Bluesky's PDS and in line with possible
|
|
140
|
+
// future plans to have the client talk directly with the appview
|
|
141
|
+
entrywaySession = async (reqCtx) => {
|
|
142
|
+
const token = bearerTokenFromReq(reqCtx.req);
|
|
143
|
+
if (!token) {
|
|
144
|
+
throw new AuthRequiredError(undefined, 'AuthMissing');
|
|
145
|
+
}
|
|
146
|
+
// if entryway jwt key not configured then do not parsed these tokens
|
|
147
|
+
if (!this.entrywayJwtPublicKey) {
|
|
148
|
+
throw new AuthRequiredError('Malformed token', 'InvalidToken');
|
|
149
|
+
}
|
|
150
|
+
const res = await jose
|
|
151
|
+
.jwtVerify(token, this.entrywayJwtPublicKey)
|
|
152
|
+
.catch((err) => {
|
|
153
|
+
if (err?.['code'] === 'ERR_JWT_EXPIRED') {
|
|
154
|
+
throw new AuthRequiredError('Token has expired', 'ExpiredToken');
|
|
155
|
+
}
|
|
156
|
+
throw new AuthRequiredError('Token could not be verified', 'InvalidToken');
|
|
157
|
+
});
|
|
158
|
+
const { sub, aud, scope } = res.payload;
|
|
159
|
+
if (typeof sub !== 'string' || !sub.startsWith('did:')) {
|
|
160
|
+
throw new AuthRequiredError('Malformed token', 'InvalidToken');
|
|
161
|
+
}
|
|
162
|
+
else if (typeof aud !== 'string' ||
|
|
163
|
+
!aud.startsWith('did:web:') ||
|
|
164
|
+
!aud.endsWith('.bsky.network')) {
|
|
165
|
+
throw new AuthRequiredError('Bad token aud', 'InvalidToken');
|
|
166
|
+
}
|
|
167
|
+
else if (typeof scope !== 'string' || !ALLOWED_AUTH_SCOPES.has(scope)) {
|
|
168
|
+
throw new AuthRequiredError('Bad token scope', 'InvalidToken');
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
credentials: {
|
|
172
|
+
type: 'standard',
|
|
173
|
+
aud: this.ownDid,
|
|
174
|
+
iss: sub,
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
// modService = async (reqCtx: ReqCtx): Promise<ModServiceOutput> => {
|
|
179
|
+
// const { iss, aud } = await this.verifyServiceJwt(reqCtx, {
|
|
180
|
+
// aud: this.ownDid,
|
|
181
|
+
// iss: [this.modServiceDid, `${this.modServiceDid}#atproto_labeler`],
|
|
182
|
+
// })
|
|
183
|
+
// return { credentials: { type: 'mod_service', aud, iss } }
|
|
184
|
+
// }
|
|
185
|
+
// roleOrModService = async (
|
|
186
|
+
// reqCtx: ReqCtx,
|
|
187
|
+
// ): Promise<RoleOutput | ModServiceOutput> => {
|
|
188
|
+
// if (isBearerToken(reqCtx.req)) {
|
|
189
|
+
// return this.modService(reqCtx)
|
|
190
|
+
// } else {
|
|
191
|
+
// return this.role(reqCtx)
|
|
192
|
+
// }
|
|
193
|
+
// }
|
|
194
|
+
parseRoleCreds(req) {
|
|
195
|
+
const parsed = parseBasicAuth(req.headers.authorization || '');
|
|
196
|
+
const { Missing, Valid, Invalid } = RoleStatus;
|
|
197
|
+
if (!parsed) {
|
|
198
|
+
return { status: Missing, admin: false, moderator: false, triage: false };
|
|
199
|
+
}
|
|
200
|
+
const { username, password } = parsed;
|
|
201
|
+
if (username === 'admin' && this.adminPasses.has(password)) {
|
|
202
|
+
return { status: Valid, admin: true };
|
|
203
|
+
}
|
|
204
|
+
return { status: Invalid, admin: false };
|
|
205
|
+
}
|
|
206
|
+
// async verifyServiceJwt(
|
|
207
|
+
// reqCtx: ReqCtx,
|
|
208
|
+
// opts: {
|
|
209
|
+
// iss: string[] | null
|
|
210
|
+
// aud: string | null
|
|
211
|
+
// lxmCheck?: (method?: string) => boolean
|
|
212
|
+
// },
|
|
213
|
+
// ) {
|
|
214
|
+
// const getSigningKey = async (
|
|
215
|
+
// iss: string,
|
|
216
|
+
// _forceRefresh: boolean, // @TODO consider propagating to dataplane
|
|
217
|
+
// ): Promise<string> => {
|
|
218
|
+
// if (opts.iss !== null && !opts.iss.includes(iss)) {
|
|
219
|
+
// throw new AuthRequiredError('Untrusted issuer', 'UntrustedIss')
|
|
220
|
+
// }
|
|
221
|
+
// const [did, serviceId] = iss.split('#')
|
|
222
|
+
// const keyId =
|
|
223
|
+
// serviceId === 'atproto_labeler' ? 'atproto_label' : 'atproto'
|
|
224
|
+
// let identity: GetIdentityByDidResponse
|
|
225
|
+
// try {
|
|
226
|
+
// identity = await this.dataplane.getIdentityByDid({ did })
|
|
227
|
+
// } catch (err) {
|
|
228
|
+
// if (isDataplaneError(err, Code.NotFound)) {
|
|
229
|
+
// throw new AuthRequiredError('identity unknown')
|
|
230
|
+
// }
|
|
231
|
+
// throw err
|
|
232
|
+
// }
|
|
233
|
+
// const keys = unpackIdentityKeys(identity.keys)
|
|
234
|
+
// const didKey = getKeyAsDidKey(keys, { id: keyId })
|
|
235
|
+
// if (!didKey) {
|
|
236
|
+
// throw new AuthRequiredError('missing or bad key')
|
|
237
|
+
// }
|
|
238
|
+
// return didKey
|
|
239
|
+
// }
|
|
240
|
+
// const assertLxmCheck = () => {
|
|
241
|
+
// const lxm = parseReqNsid(reqCtx.req)
|
|
242
|
+
// if (
|
|
243
|
+
// (opts.lxmCheck && !opts.lxmCheck(payload.lxm)) ||
|
|
244
|
+
// (!opts.lxmCheck && payload.lxm !== lxm)
|
|
245
|
+
// ) {
|
|
246
|
+
// throw new AuthRequiredError(
|
|
247
|
+
// payload.lxm !== undefined
|
|
248
|
+
// ? `bad jwt lexicon method ("lxm"). must match: ${lxm}`
|
|
249
|
+
// : `missing jwt lexicon method ("lxm"). must match: ${lxm}`,
|
|
250
|
+
// 'BadJwtLexiconMethod',
|
|
251
|
+
// )
|
|
252
|
+
// }
|
|
253
|
+
// }
|
|
254
|
+
// const jwtStr = bearerTokenFromReq(reqCtx.req)
|
|
255
|
+
// if (!jwtStr) {
|
|
256
|
+
// throw new AuthRequiredError('missing jwt', 'MissingJwt')
|
|
257
|
+
// }
|
|
258
|
+
// // if validating additional scopes, skip scope check in initial validation & follow up afterwards
|
|
259
|
+
// const payload = await verifyServiceJwt(
|
|
260
|
+
// jwtStr,
|
|
261
|
+
// opts.aud,
|
|
262
|
+
// null,
|
|
263
|
+
// getSigningKey,
|
|
264
|
+
// verifySignatureWithKey,
|
|
265
|
+
// )
|
|
266
|
+
// if (
|
|
267
|
+
// !payload.iss.endsWith('#atproto_labeler') ||
|
|
268
|
+
// payload.lxm !== undefined
|
|
269
|
+
// ) {
|
|
270
|
+
// // @TODO currently permissive of labelers who dont set lxm yet.
|
|
271
|
+
// // we'll allow ozone self-hosters to upgrade before removing this condition.
|
|
272
|
+
// assertLxmCheck()
|
|
273
|
+
// }
|
|
274
|
+
// return { iss: payload.iss, aud: payload.aud }
|
|
275
|
+
// }
|
|
276
|
+
isModService(iss) {
|
|
277
|
+
return [
|
|
278
|
+
this.modServiceDid,
|
|
279
|
+
`${this.modServiceDid}#atproto_labeler`,
|
|
280
|
+
].includes(iss);
|
|
281
|
+
}
|
|
282
|
+
nullCreds() {
|
|
283
|
+
return {
|
|
284
|
+
credentials: {
|
|
285
|
+
type: 'none',
|
|
286
|
+
iss: null,
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
parseCreds(creds) {
|
|
291
|
+
const viewer = creds.credentials.type === 'standard' ? creds.credentials.iss : null;
|
|
292
|
+
const includeTakedownsAnd3pBlocks = (creds.credentials.type === 'role' && creds.credentials.admin) ||
|
|
293
|
+
creds.credentials.type === 'mod_service' ||
|
|
294
|
+
(creds.credentials.type === 'standard' &&
|
|
295
|
+
this.isModService(creds.credentials.iss));
|
|
296
|
+
const canPerformTakedown = (creds.credentials.type === 'role' && creds.credentials.admin) ||
|
|
297
|
+
creds.credentials.type === 'mod_service';
|
|
298
|
+
return {
|
|
299
|
+
viewer,
|
|
300
|
+
includeTakedowns: includeTakedownsAnd3pBlocks,
|
|
301
|
+
include3pBlocks: includeTakedownsAnd3pBlocks,
|
|
302
|
+
canPerformTakedown,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
// HELPERS
|
|
307
|
+
// ---------
|
|
308
|
+
const BEARER = 'Bearer ';
|
|
309
|
+
const BASIC = 'Basic ';
|
|
310
|
+
const isBearerToken = (req) => {
|
|
311
|
+
return req.headers.authorization?.startsWith(BEARER) ?? false;
|
|
312
|
+
};
|
|
313
|
+
const isBasicToken = (req) => {
|
|
314
|
+
return req.headers.authorization?.startsWith(BASIC) ?? false;
|
|
315
|
+
};
|
|
316
|
+
const bearerTokenFromReq = (req) => {
|
|
317
|
+
const header = req.headers.authorization || '';
|
|
318
|
+
if (!header.startsWith(BEARER))
|
|
319
|
+
return null;
|
|
320
|
+
return header.slice(BEARER.length).trim();
|
|
321
|
+
};
|
|
322
|
+
export const parseBasicAuth = (token) => {
|
|
323
|
+
if (!token.startsWith(BASIC))
|
|
324
|
+
return null;
|
|
325
|
+
const b64 = token.slice(BASIC.length);
|
|
326
|
+
let parsed;
|
|
327
|
+
try {
|
|
328
|
+
parsed = ui8.toString(ui8.fromString(b64, 'base64pad'), 'utf8').split(':');
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
const [username, password] = parsed;
|
|
334
|
+
if (!username || !password)
|
|
335
|
+
return null;
|
|
336
|
+
return { username, password };
|
|
337
|
+
};
|
|
338
|
+
export const buildBasicAuth = (username, password) => {
|
|
339
|
+
return (BASIC +
|
|
340
|
+
ui8.toString(ui8.fromString(`${username}:${password}`, 'utf8'), 'base64pad'));
|
|
341
|
+
};
|
|
342
|
+
const keyEncoder = new KeyEncoder('secp256k1');
|
|
343
|
+
export const createPublicKeyObject = (publicKeyHex) => {
|
|
344
|
+
const key = keyEncoder.encodePublic(publicKeyHex, 'raw', 'pem');
|
|
345
|
+
return crypto.createPublicKey({ format: 'pem', key });
|
|
346
|
+
};
|
|
347
|
+
const verifySig = (publicKey, data, sig) => {
|
|
348
|
+
const keyEncoder = new KeyEncoder('secp256k1');
|
|
349
|
+
const pemKey = keyEncoder.encodePublic(ui8.toString(publicKey, 'hex'), 'raw', 'pem');
|
|
350
|
+
const key = crypto.createPublicKey({ format: 'pem', key: pemKey });
|
|
351
|
+
return crypto.verify('sha256', data, {
|
|
352
|
+
key,
|
|
353
|
+
dsaEncoding: 'ieee-p1363',
|
|
354
|
+
}, sig);
|
|
355
|
+
};
|
|
356
|
+
export const verifySignatureWithKey = async (didKey, msgBytes, sigBytes, alg) => {
|
|
357
|
+
if (alg === SECP256K1_JWT_ALG) {
|
|
358
|
+
const parsed = parseDidKey(didKey);
|
|
359
|
+
if (alg !== parsed.jwtAlg) {
|
|
360
|
+
throw new Error(`Expected key alg ${alg}, got ${parsed.jwtAlg}`);
|
|
361
|
+
}
|
|
362
|
+
return verifySig(parsed.keyBytes, msgBytes, sigBytes);
|
|
363
|
+
}
|
|
364
|
+
return cryptoVerifySignatureWithKey(didKey, msgBytes, sigBytes, alg);
|
|
365
|
+
};
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Client } from '@connectrpc/connect';
|
|
2
|
+
import { ClioService } from './rpc/clio_connect';
|
|
3
|
+
export type DataPlaneClient = Client<typeof ClioService>;
|
|
4
|
+
type HttpVersion = '1.1' | '2';
|
|
5
|
+
export declare const createBaseClient: (baseUrl: string, opts: {
|
|
6
|
+
httpVersion?: HttpVersion;
|
|
7
|
+
rejectUnauthorized?: boolean;
|
|
8
|
+
}) => DataPlaneClient;
|
|
9
|
+
export {};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createClient } from '@connectrpc/connect';
|
|
2
|
+
import { createGrpcTransport } from '@connectrpc/connect-node';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
import { ClioService } from './rpc/clio_connect';
|
|
5
|
+
export const createBaseClient = (baseUrl, opts) => {
|
|
6
|
+
const { httpVersion = '2', rejectUnauthorized = true } = opts;
|
|
7
|
+
const transport = createGrpcTransport({
|
|
8
|
+
baseUrl,
|
|
9
|
+
acceptCompression: [],
|
|
10
|
+
httpVersion,
|
|
11
|
+
nodeOptions: { rejectUnauthorized },
|
|
12
|
+
});
|
|
13
|
+
assert(validateUrl(baseUrl));
|
|
14
|
+
return createClient(ClioService, transport);
|
|
15
|
+
};
|
|
16
|
+
const validateUrl = (urlStr) => {
|
|
17
|
+
let url;
|
|
18
|
+
try {
|
|
19
|
+
url = new URL(urlStr);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (!['http:', 'https:'].includes(url.protocol)) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
else if (!url.hostname) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return urlStr;
|
|
32
|
+
}
|
|
33
|
+
};
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ServerConfigValues {
|
|
2
|
+
version?: string;
|
|
3
|
+
debugMode?: boolean;
|
|
4
|
+
port?: number;
|
|
5
|
+
serverDid: string;
|
|
6
|
+
didPlcUrl: string;
|
|
7
|
+
handleResolverNameservers?: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class ServerConfig {
|
|
10
|
+
private cfg;
|
|
11
|
+
private assignedPort?;
|
|
12
|
+
constructor(cfg: ServerConfigValues);
|
|
13
|
+
static readEnv(overrides?: Partial<ServerConfigValues>): ServerConfig;
|
|
14
|
+
assignPort(port: number): void;
|
|
15
|
+
get version(): string | undefined;
|
|
16
|
+
get debugMode(): boolean;
|
|
17
|
+
get port(): number | undefined;
|
|
18
|
+
get localUrl(): string;
|
|
19
|
+
get serverDid(): string;
|
|
20
|
+
get didPlcUrl(): string;
|
|
21
|
+
}
|