├── .nvmrc
├── services
├── pds
│ ├── .gitignore
│ └── package.json
├── bsync
│ └── package.json
├── ozone
│ └── package.json
└── bsky
│ └── package.json
├── packages
├── oauth
│ ├── oauth-client-browser-example
│ │ ├── .gitignore
│ │ ├── .postcssrc.yml
│ │ ├── src
│ │ │ ├── index.css
│ │ │ ├── lib
│ │ │ │ ├── util.ts
│ │ │ │ ├── use-bsky-client.ts
│ │ │ │ └── use-escape-key.ts
│ │ │ ├── index.tsx
│ │ │ └── queries
│ │ │ │ ├── use-get-token-info-query.ts
│ │ │ │ └── use-get-session-query.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.tools.json
│ │ ├── tsconfig.build.json
│ │ └── tailwind.config.mjs
│ ├── oauth-client-expo
│ │ ├── .gitignore
│ │ ├── src
│ │ │ ├── polyfill.d.ts
│ │ │ ├── polyfill.web.ts
│ │ │ ├── ExpoAtprotoOAuthClientModule.types.ts
│ │ │ ├── polyfill.native.ts
│ │ │ ├── index.ts
│ │ │ ├── expo-oauth-client.d.ts
│ │ │ └── expo-oauth-client-interface.ts
│ │ ├── android
│ │ │ ├── .editorconfig
│ │ │ └── src
│ │ │ │ └── main
│ │ │ │ └── AndroidManifest.xml
│ │ ├── tsconfig.json
│ │ ├── tsconfig.build.json
│ │ └── expo-module.config.json
│ ├── jwk-jose
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── oauth-provider-ui
│ │ ├── src
│ │ │ ├── hydration-data.d.ts
│ │ │ ├── hooks
│ │ │ │ ├── use-bound-dispatch.ts
│ │ │ │ └── use-escape-key.ts
│ │ │ ├── locales
│ │ │ │ └── load.ts
│ │ │ └── lib
│ │ │ │ └── ref.ts
│ │ ├── .gitignore
│ │ ├── tsconfig.json
│ │ ├── tsconfig.tools.json
│ │ ├── CONTRIBUTING.md
│ │ ├── tsconfig.src.json
│ │ └── index.html
│ ├── jwk-webcrypto
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── oauth-provider-frontend
│ │ ├── src
│ │ │ ├── hydration-data.d.ts
│ │ │ ├── components
│ │ │ │ ├── Divider.tsx
│ │ │ │ └── forms
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── Item.tsx
│ │ │ │ │ └── Fieldset.tsx
│ │ │ ├── util
│ │ │ │ ├── sleep.ts
│ │ │ │ ├── wait.ts
│ │ │ │ ├── format2FACode.ts
│ │ │ │ ├── getAccountName.ts
│ │ │ │ ├── sanitizeHandle.ts
│ │ │ │ └── upsert.ts
│ │ │ ├── locales
│ │ │ │ ├── setup.ts
│ │ │ │ └── activateLocale.ts
│ │ │ ├── data
│ │ │ │ ├── useCustomizationData.ts
│ │ │ │ ├── useHasAccounts.ts
│ │ │ │ ├── useHydrationData.ts
│ │ │ │ └── usePasswordConfirmMutation.ts
│ │ │ └── api
│ │ │ │ └── index.ts
│ │ ├── .gitignore
│ │ ├── tsconfig.json
│ │ ├── tsconfig.tools.json
│ │ ├── index.html
│ │ ├── tsconfig.src.json
│ │ └── hydration-data.d.ts
│ ├── jwk
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── oauth-scopes
│ │ ├── src
│ │ │ ├── lib
│ │ │ │ ├── lexicon.ts
│ │ │ │ ├── nsid.ts
│ │ │ │ └── resource-permission.ts
│ │ │ └── scope-missing-error.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.tests.json
│ │ ├── jest.config.js
│ │ └── tsconfig.build.json
│ ├── oauth-client
│ │ ├── tsconfig.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── auth-method-unsatisfiable-error.ts
│ │ │ │ ├── token-refresh-error.ts
│ │ │ │ ├── token-invalid-error.ts
│ │ │ │ └── token-revoked-error.ts
│ │ │ ├── constants.ts
│ │ │ └── state-store.ts
│ │ └── tsconfig.build.json
│ ├── oauth-provider
│ │ ├── src
│ │ │ ├── oauth-dpop.ts
│ │ │ ├── types
│ │ │ │ ├── email-otp.ts
│ │ │ │ ├── color-hue.ts
│ │ │ │ ├── invite-code.ts
│ │ │ │ └── password.ts
│ │ │ ├── access-token
│ │ │ │ └── access-token-mode.ts
│ │ │ ├── dpop
│ │ │ │ └── dpop-proof.ts
│ │ │ ├── oidc
│ │ │ │ └── sub.ts
│ │ │ ├── lib
│ │ │ │ ├── html
│ │ │ │ │ └── index.ts
│ │ │ │ ├── nsid.ts
│ │ │ │ ├── util
│ │ │ │ │ ├── date.ts
│ │ │ │ │ ├── error.ts
│ │ │ │ │ ├── well-known.ts
│ │ │ │ │ ├── locale.ts
│ │ │ │ │ ├── ui8.ts
│ │ │ │ │ └── cast.ts
│ │ │ │ └── http
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── headers.ts
│ │ │ │ │ └── types.ts
│ │ │ ├── oauth-client.ts
│ │ │ ├── client
│ │ │ │ ├── client-id.ts
│ │ │ │ ├── client-data.ts
│ │ │ │ └── client-info.ts
│ │ │ ├── lexicon
│ │ │ │ └── lexicon-data.ts
│ │ │ ├── router
│ │ │ │ ├── error-handler.ts
│ │ │ │ └── middleware-options.ts
│ │ │ ├── device
│ │ │ │ └── device-data.ts
│ │ │ ├── errors
│ │ │ │ ├── invalid-invite-code-error.ts
│ │ │ │ ├── invalid-dpop-proof-error.ts
│ │ │ │ ├── access-denied-error.ts
│ │ │ │ ├── login-required-error.ts
│ │ │ │ └── consent-required-error.ts
│ │ │ ├── result
│ │ │ │ └── authorization-result-redirect.ts
│ │ │ ├── customization
│ │ │ │ ├── links.ts
│ │ │ │ └── branding.ts
│ │ │ └── oauth-store.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── oauth-types
│ │ ├── tsconfig.json
│ │ ├── src
│ │ │ ├── constants.ts
│ │ │ ├── oauth-code-challenge-method.ts
│ │ │ ├── oauth-client-id.ts
│ │ │ ├── atproto-loopback-client-redirect-uris.ts
│ │ │ ├── oauth-request-uri.ts
│ │ │ ├── oauth-access-token.ts
│ │ │ ├── oauth-refresh-token.ts
│ │ │ ├── oidc-entity-type.ts
│ │ │ ├── oauth-endpoint-name.ts
│ │ │ ├── oauth-response-mode.ts
│ │ │ ├── oauth-par-response.ts
│ │ │ ├── oauth-client-credentials-grant-token-request.ts
│ │ │ ├── oauth-password-grant-token-request.ts
│ │ │ ├── oauth-authorization-request-uri.ts
│ │ │ ├── oauth-endpoint-auth-method.ts
│ │ │ ├── oauth-grant-type.ts
│ │ │ ├── oauth-token-type.ts
│ │ │ ├── oidc-claims-properties.ts
│ │ │ └── oauth-refresh-token-grant-token-request.ts
│ │ ├── README.md
│ │ └── tsconfig.build.json
│ ├── oauth-client-node
│ │ ├── tsconfig.json
│ │ ├── src
│ │ │ ├── util.ts
│ │ │ └── index.ts
│ │ └── tsconfig.build.json
│ ├── oauth-provider-api
│ │ ├── tsconfig.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── contants.ts
│ │ └── tsconfig.build.json
│ └── oauth-client-browser
│ │ ├── tsconfig.json
│ │ ├── src
│ │ ├── indexed-db
│ │ │ ├── schema.ts
│ │ │ ├── index.ts
│ │ │ └── README.md
│ │ ├── index.ts
│ │ └── errors.ts
│ │ └── tsconfig.build.json
├── pds
│ ├── test.env
│ ├── src
│ │ ├── repo
│ │ │ └── index.ts
│ │ ├── config
│ │ │ └── index.ts
│ │ ├── read-after-write
│ │ │ └── index.ts
│ │ ├── sequencer
│ │ │ ├── index.ts
│ │ │ └── db
│ │ │ │ └── migrations
│ │ │ │ └── index.ts
│ │ ├── db
│ │ │ └── index.ts
│ │ ├── actor-store
│ │ │ ├── db
│ │ │ │ ├── migrations
│ │ │ │ │ └── index.ts
│ │ │ │ └── schema
│ │ │ │ │ ├── record-blob.ts
│ │ │ │ │ ├── backlink.ts
│ │ │ │ │ ├── repo-root.ts
│ │ │ │ │ ├── repo-block.ts
│ │ │ │ │ ├── account-pref.ts
│ │ │ │ │ ├── blob.ts
│ │ │ │ │ └── record.ts
│ │ │ ├── actor-store-resources.ts
│ │ │ └── preference
│ │ │ │ └── util.ts
│ │ ├── mailer
│ │ │ ├── templates
│ │ │ │ ├── update-email.d.ts
│ │ │ │ ├── confirm-email.d.ts
│ │ │ │ ├── delete-account.d.ts
│ │ │ │ ├── plc-operation.d.ts
│ │ │ │ └── reset-password.d.ts
│ │ │ └── templates.ts
│ │ ├── util
│ │ │ ├── types.ts
│ │ │ ├── debug.ts
│ │ │ ├── params.ts
│ │ │ └── compression.ts
│ │ ├── did-cache
│ │ │ └── db
│ │ │ │ └── schema.ts
│ │ ├── scripts
│ │ │ └── util.ts
│ │ ├── account-manager
│ │ │ └── db
│ │ │ │ ├── schema
│ │ │ │ ├── repo-root.ts
│ │ │ │ ├── app-password.ts
│ │ │ │ ├── refresh-token.ts
│ │ │ │ ├── account-device.ts
│ │ │ │ ├── account.ts
│ │ │ │ ├── actor.ts
│ │ │ │ ├── email-token.ts
│ │ │ │ ├── used-refresh-token.ts
│ │ │ │ ├── lexicon.ts
│ │ │ │ └── device.ts
│ │ │ │ └── migrations
│ │ │ │ └── 003-privileged-app-passwords.ts
│ │ └── api
│ │ │ ├── app
│ │ │ └── bsky
│ │ │ │ ├── notification
│ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── actor
│ │ │ │ └── index.ts
│ │ │ ├── com
│ │ │ └── atproto
│ │ │ │ ├── moderation
│ │ │ │ └── index.ts
│ │ │ │ └── temp
│ │ │ │ └── index.ts
│ │ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── tests
│ │ └── seeds
│ │ │ └── likes.ts
│ └── jest.config.js
├── bsky
│ ├── test.env
│ ├── src
│ │ ├── image
│ │ │ ├── index.ts
│ │ │ └── logger.ts
│ │ ├── data-plane
│ │ │ ├── index.ts
│ │ │ └── server
│ │ │ │ └── db
│ │ │ │ ├── index.ts
│ │ │ │ ├── tables
│ │ │ │ ├── mute.ts
│ │ │ │ ├── list-mute.ts
│ │ │ │ ├── suggested-feed.ts
│ │ │ │ ├── actor-sync.ts
│ │ │ │ ├── subscription.ts
│ │ │ │ ├── suggested-follow.ts
│ │ │ │ ├── blob-takedown.ts
│ │ │ │ ├── thread-mute.ts
│ │ │ │ ├── tagged-suggestion.ts
│ │ │ │ ├── algo.ts
│ │ │ │ ├── bookmark.ts
│ │ │ │ ├── duplicate-record.ts
│ │ │ │ ├── label.ts
│ │ │ │ ├── post-gate.ts
│ │ │ │ ├── thread-gate.ts
│ │ │ │ ├── actor-state.ts
│ │ │ │ ├── did-cache.ts
│ │ │ │ ├── feed-item.ts
│ │ │ │ ├── notification-push-token.ts
│ │ │ │ ├── private-data.ts
│ │ │ │ ├── profile-agg.ts
│ │ │ │ ├── labeler.ts
│ │ │ │ ├── quote.ts
│ │ │ │ ├── activity-subscription.ts
│ │ │ │ ├── follow.ts
│ │ │ │ ├── actor-block.ts
│ │ │ │ ├── list-block.ts
│ │ │ │ ├── record.ts
│ │ │ │ ├── starter-pack.ts
│ │ │ │ ├── list-item.ts
│ │ │ │ ├── notification.ts
│ │ │ │ ├── post-agg.ts
│ │ │ │ ├── view-param.ts
│ │ │ │ ├── like.ts
│ │ │ │ ├── repost.ts
│ │ │ │ ├── actor.ts
│ │ │ │ ├── verification.ts
│ │ │ │ ├── list.ts
│ │ │ │ └── profile.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── migrations
│ │ │ │ ├── 20230620T161134972Z-post-langs.ts
│ │ │ │ ├── 20230920T213858047Z-add-tags-to-post.ts
│ │ │ │ ├── 20250207T174822012Z-add-label-exp.ts
│ │ │ │ ├── 20250528T221913281Z-add-record-tags.ts
│ │ │ │ ├── 20230808T172902639Z-repo-rev.ts
│ │ │ │ ├── 20240530T170337073Z-account-deactivation.ts
│ │ │ │ ├── 20240723T220700077Z-quotes-post-aggs.ts
│ │ │ │ ├── 20250813T174955711Z-add-post-agg-bookmarks.ts
│ │ │ │ ├── 20230627T212437895Z-optional-handle.ts
│ │ │ │ ├── 20230427T194702079Z-notif-record-index.ts
│ │ │ │ ├── 20230807T035309811Z-feed-item-delete-invite-for-user-idx.ts
│ │ │ │ ├── 20230611T215300060Z-actor-state.ts
│ │ │ │ ├── 20230830T205507322Z-suggested-feeds.ts
│ │ │ │ └── 20230610T203555962Z-suggested-follows.ts
│ │ ├── util
│ │ │ ├── debug.ts
│ │ │ └── retry.ts
│ │ ├── api
│ │ │ ├── external.ts
│ │ │ ├── com
│ │ │ │ └── atproto
│ │ │ │ │ └── temp
│ │ │ │ │ └── fetchLabels.ts
│ │ │ └── app
│ │ │ │ └── bsky
│ │ │ │ └── bookmark
│ │ │ │ └── util.ts
│ │ └── error.ts
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── buf.gen.yaml
│ └── jest.config.js
├── identity
│ ├── test.env
│ ├── src
│ │ ├── index.ts
│ │ └── did
│ │ │ ├── index.ts
│ │ │ └── util.ts
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ └── jest.config.js
├── internal
│ ├── xrpc-utils
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── identity-resolver
│ │ ├── src
│ │ │ ├── constants.ts
│ │ │ ├── identity-resolver-error.ts
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── handle-resolver-node
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── pipe
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── type.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── did-resolver
│ │ ├── src
│ │ │ ├── methods.ts
│ │ │ ├── util.ts
│ │ │ ├── index.ts
│ │ │ ├── did-method.ts
│ │ │ └── did-resolver.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── fetch
│ │ ├── tsconfig.json
│ │ ├── tsconfig.build.json
│ │ └── src
│ │ │ ├── index.ts
│ │ │ └── fetch-error.ts
│ ├── fetch-node
│ │ ├── tsconfig.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.build.json
│ ├── handle-resolver
│ │ ├── tsconfig.json
│ │ ├── src
│ │ │ ├── handle-resolver-error.ts
│ │ │ └── index.ts
│ │ └── tsconfig.build.json
│ ├── simple-store
│ │ ├── tsconfig.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── util.ts
│ │ └── tsconfig.build.json
│ ├── simple-store-memory
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
│ ├── simple-store-redis
│ │ ├── tsconfig.json
│ │ ├── tsconfig.build.json
│ │ └── CHANGELOG.md
│ └── rollup-plugin-bundle-manifest
│ │ ├── tsconfig.json
│ │ └── tsconfig.build.json
├── ozone
│ ├── test.env
│ ├── src
│ │ ├── sequencer
│ │ │ └── index.ts
│ │ ├── config
│ │ │ ├── index.ts
│ │ │ └── secrets.ts
│ │ ├── setting
│ │ │ ├── types.ts
│ │ │ └── constants.ts
│ │ ├── db
│ │ │ ├── schema
│ │ │ │ ├── signing_key.ts
│ │ │ │ ├── job_cursor.ts
│ │ │ │ ├── firehose_cursor.ts
│ │ │ │ └── account_strike.ts
│ │ │ └── migrations
│ │ │ │ ├── 20240903T205730722Z-add-template-lang.ts
│ │ │ │ ├── 20240814T003647759Z-event-created-at-index.ts
│ │ │ │ ├── 20240904T205730722Z-add-subject-did-index.ts
│ │ │ │ ├── 20240201T051104136Z-mod-event-blobs.ts
│ │ │ │ ├── 20250715T000000000Z-add-mod-event-external-id.ts
│ │ │ │ └── 20240408T192432676Z-mute-reporting.ts
│ │ ├── api
│ │ │ └── chat
│ │ │ │ └── index.ts
│ │ ├── communication-service
│ │ │ └── util.ts
│ │ ├── scheduled-action
│ │ │ └── types.ts
│ │ ├── image-invalidator.ts
│ │ ├── error.ts
│ │ └── tag-service
│ │ │ └── util.ts
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── jest.config.js
│ └── tests
│ │ └── __snapshots__
│ │ └── report-reason.test.ts.snap
├── api
│ ├── scripts
│ │ └── generate-code.mjs
│ ├── src
│ │ ├── const.ts
│ │ ├── session-manager.ts
│ │ └── bsky-agent.ts
│ ├── tsconfig.json
│ ├── tsconfig.build.json
│ ├── tsconfig.tests.json
│ └── jest.config.js
├── aws
│ ├── README.md
│ ├── tsconfig.json
│ ├── src
│ │ ├── index.ts
│ │ ├── types.ts
│ │ └── util.ts
│ └── tsconfig.build.json
├── repo
│ ├── src
│ │ ├── sync
│ │ │ └── index.ts
│ │ ├── mst
│ │ │ └── index.ts
│ │ ├── storage
│ │ │ └── index.ts
│ │ ├── logger.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ └── jest.config.js
├── crypto
│ ├── tests
│ │ └── signature-fixtures.json
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── src
│ │ ├── plugins.ts
│ │ ├── const.ts
│ │ ├── index.ts
│ │ ├── p256
│ │ │ └── plugin.ts
│ │ └── secp256k1
│ │ │ └── plugin.ts
│ ├── tsconfig.build.json
│ └── jest.config.js
├── did
│ ├── src
│ │ ├── methods.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsconfig.build.json
│ └── jest.config.js
├── lexicon-resolver
│ ├── src
│ │ ├── index.ts
│ │ └── util.ts
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ └── jest.config.js
├── dev-env
│ ├── assets
│ │ ├── at.png
│ │ ├── hd-key.jpg
│ │ ├── key-alt.jpg
│ │ ├── key-landscape-large.jpg
│ │ ├── key-landscape-small.jpg
│ │ ├── key-portrait-large.jpg
│ │ └── key-portrait-small.jpg
│ ├── tsconfig.json
│ ├── src
│ │ ├── const.ts
│ │ ├── env.ts
│ │ └── index.ts
│ └── tsconfig.build.json
├── sync
│ ├── src
│ │ ├── index.ts
│ │ ├── runner
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── util.ts
│ ├── tsconfig.json
│ ├── tsconfig.build.json
│ └── jest.config.js
├── syntax
│ ├── tests
│ │ └── interop-files
│ │ │ ├── aturi_syntax_valid.txt
│ │ │ ├── did_syntax_invalid.txt
│ │ │ ├── did_syntax_valid.txt
│ │ │ ├── nsid_syntax_valid.txt
│ │ │ ├── tid_syntax_invalid.txt
│ │ │ ├── tid_syntax_valid.txt
│ │ │ ├── aturi_syntax_invalid.txt
│ │ │ ├── handle_syntax_valid.txt
│ │ │ ├── nsid_syntax_invalid.txt
│ │ │ ├── datetime_parse_invalid.txt
│ │ │ ├── datetime_syntax_invalid.txt
│ │ │ ├── datetime_syntax_valid.txt
│ │ │ ├── handle_syntax_invalid.txt
│ │ │ ├── recordkey_syntax_valid.txt
│ │ │ └── recordkey_syntax_invalid.txt
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── src
│ │ └── index.ts
│ └── jest.config.js
├── xrpc
│ ├── tsconfig.json
│ ├── tsconfig.build.json
│ └── src
│ │ └── index.ts
├── lex-cli
│ ├── tsconfig.json
│ ├── tsconfig.build.json
│ └── src
│ │ └── types.ts
├── lexicon
│ ├── src
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ └── jest.config.js
├── bsync
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── buf.gen.yaml
│ ├── jest.config.js
│ └── src
│ │ └── db
│ │ ├── migrations
│ │ └── provider.ts
│ │ ├── schema
│ │ ├── notif_item.ts
│ │ ├── mute_item.ts
│ │ ├── notif_op.ts
│ │ └── index.ts
│ │ └── types.ts
├── common
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── jest.config.js
│ └── src
│ │ ├── index.ts
│ │ └── buffers.ts
├── common-web
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── jest.config.js
│ └── src
│ │ └── index.ts
├── xrpc-server
│ ├── tsconfig.json
│ ├── tsconfig.tests.json
│ ├── tsconfig.build.json
│ ├── src
│ │ ├── stream
│ │ │ ├── index.ts
│ │ │ └── logger.ts
│ │ ├── logger.ts
│ │ └── index.ts
│ └── jest.config.js
└── dev-infra
│ ├── with-test-db.sh
│ └── with-test-redis-and-db.sh
├── .dockerignore
├── .npmrc
├── jest.setup.ts
├── pnpm-workspace.yaml
├── jest.config.js
├── interop-test-files
├── syntax
│ ├── tid_syntax_valid.txt
│ ├── datetime_parse_invalid.txt
│ ├── atidentifier_syntax_valid.txt
│ ├── tid_syntax_invalid.txt
│ └── atidentifier_syntax_invalid.txt
├── crypto
│ └── w3c_didkey_P256.json
└── README.md
├── tsconfig
├── node.json
├── browser.json
├── tests.json
├── nodenext.json
├── bundler.json
└── expo.json
├── .gitignore
├── .vscode
└── extensions.json
├── lexicons
├── com
│ └── atproto
│ │ ├── sync
│ │ └── defs.json
│ │ ├── server
│ │ ├── deleteSession.json
│ │ ├── requestAccountDelete.json
│ │ ├── requestEmailConfirmation.json
│ │ ├── activateAccount.json
│ │ └── revokeAppPassword.json
│ │ ├── identity
│ │ └── requestPlcOperationSignature.json
│ │ └── repo
│ │ ├── defs.json
│ │ ├── importRepo.json
│ │ └── strongRef.json
├── chat
│ └── bsky
│ │ └── actor
│ │ ├── exportAccountData.json
│ │ └── deleteAccount.json
├── tools
│ └── ozone
│ │ └── signature
│ │ └── defs.json
└── app
│ └── bsky
│ └── embed
│ └── defs.json
├── .changeset
├── config.json
└── README.md
├── .eslintignore
├── .prettierrc
├── .gitattributes
└── LICENSE.txt
/.nvmrc:
--------------------------------------------------------------------------------
1 | 22
2 |
--------------------------------------------------------------------------------
/services/pds/.gitignore:
--------------------------------------------------------------------------------
1 | data/*
2 | blobs/*
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/.gitignore:
--------------------------------------------------------------------------------
1 | /android/build
2 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/src/polyfill.d.ts:
--------------------------------------------------------------------------------
1 | export {}
2 |
--------------------------------------------------------------------------------
/packages/pds/test.env:
--------------------------------------------------------------------------------
1 | LOG_ENABLED=true
2 | LOG_DESTINATION=test.log
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | **/dist
3 | .DS_Store
4 | Dockerfile
5 |
--------------------------------------------------------------------------------
/packages/bsky/test.env:
--------------------------------------------------------------------------------
1 | LOG_ENABLED=true
2 | LOG_DESTINATION=test.log
3 |
--------------------------------------------------------------------------------
/packages/identity/test.env:
--------------------------------------------------------------------------------
1 | LOG_ENABLED=true
2 | LOG_DESTINATION=test.log
--------------------------------------------------------------------------------
/packages/internal/xrpc-utils/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './accept.js'
2 |
--------------------------------------------------------------------------------
/packages/oauth/jwk-jose/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './jose-key.js'
2 |
--------------------------------------------------------------------------------
/packages/ozone/test.env:
--------------------------------------------------------------------------------
1 | LOG_ENABLED=true
2 | LOG_DESTINATION=test.log
3 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | enable-pre-post-scripts = true
2 | include-workspace-root = true
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/src/hydration-data.d.ts:
--------------------------------------------------------------------------------
1 | ../hydration-data.d.ts
--------------------------------------------------------------------------------
/packages/oauth/jwk-webcrypto/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './webcrypto-key.js'
2 |
--------------------------------------------------------------------------------
/packages/api/scripts/generate-code.mjs:
--------------------------------------------------------------------------------
1 | import './code/labels.mjs'
2 |
3 | export {}
4 |
--------------------------------------------------------------------------------
/packages/aws/README.md:
--------------------------------------------------------------------------------
1 | # AWS KMS
2 |
3 | A Keypair-compatible wrapper for AWS KMS.
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/hydration-data.d.ts:
--------------------------------------------------------------------------------
1 | ../hydration-data.d.ts
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/.gitignore:
--------------------------------------------------------------------------------
1 | src/locales/*/*.ts
2 | .swc
3 | dist
4 |
--------------------------------------------------------------------------------
/packages/pds/src/repo/index.ts:
--------------------------------------------------------------------------------
1 | export * from './prepare'
2 | export * from './types'
3 |
--------------------------------------------------------------------------------
/jest.setup.ts:
--------------------------------------------------------------------------------
1 | import dotenv from 'dotenv'
2 |
3 | dotenv.config({ path: './test.env' })
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/android/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{kt,kts}]
2 | indent_size=2
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/.gitignore:
--------------------------------------------------------------------------------
1 | src/locales/*/*.ts
2 | .swc
3 | dist
4 |
--------------------------------------------------------------------------------
/packages/repo/src/sync/index.ts:
--------------------------------------------------------------------------------
1 | export * from './consumer'
2 | export * from './provider'
3 |
--------------------------------------------------------------------------------
/packages/api/src/const.ts:
--------------------------------------------------------------------------------
1 | export const BSKY_LABELER_DID = 'did:plc:ar7c4by46qjdydhdevvrndac'
2 |
--------------------------------------------------------------------------------
/packages/ozone/src/sequencer/index.ts:
--------------------------------------------------------------------------------
1 | export * from './sequencer'
2 | export * from './outbox'
3 |
--------------------------------------------------------------------------------
/packages/crypto/tests/signature-fixtures.json:
--------------------------------------------------------------------------------
1 | ../../../interop-test-files/crypto/signature-fixtures.json
--------------------------------------------------------------------------------
/packages/did/src/methods.ts:
--------------------------------------------------------------------------------
1 | export * from './methods/plc.js'
2 | export * from './methods/web.js'
3 |
--------------------------------------------------------------------------------
/packages/internal/identity-resolver/src/constants.ts:
--------------------------------------------------------------------------------
1 | export const HANDLE_INVALID = 'handle.invalid'
2 |
--------------------------------------------------------------------------------
/packages/lexicon-resolver/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './record.js'
2 | export * from './lexicon.js'
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/packages/internal/handle-resolver-node/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './atproto-handle-resolver-node.js'
2 |
--------------------------------------------------------------------------------
/packages/bsky/src/image/index.ts:
--------------------------------------------------------------------------------
1 | export * from './sharp'
2 | export type { ImageInfo, Options } from './util'
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/src/polyfill.web.ts:
--------------------------------------------------------------------------------
1 | import 'core-js/proposals/explicit-resource-management'
2 |
--------------------------------------------------------------------------------
/packages/aws/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/dev-env/assets/at.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistydemeo/atproto/main/packages/dev-env/assets/at.png
--------------------------------------------------------------------------------
/packages/did/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/pipe/src/index.ts:
--------------------------------------------------------------------------------
1 | export { pipe, pipeTwo } from './pipe.js'
2 | export type * from './type.js'
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/.postcssrc.yml:
--------------------------------------------------------------------------------
1 | plugins:
2 | tailwindcss: {}
3 | autoprefixer: {}
4 |
--------------------------------------------------------------------------------
/packages/pds/src/config/index.ts:
--------------------------------------------------------------------------------
1 | export * from './config'
2 | export * from './env'
3 | export * from './secrets'
4 |
--------------------------------------------------------------------------------
/packages/sync/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './runner'
2 | export * from './firehose'
3 | export * from './events'
4 |
--------------------------------------------------------------------------------
/packages/sync/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/aturi_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/aturi_syntax_valid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/did_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/did_syntax_invalid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/did_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/did_syntax_valid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/nsid_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/nsid_syntax_valid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/tid_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/tid_syntax_invalid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/tid_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/tid_syntax_valid.txt
--------------------------------------------------------------------------------
/packages/xrpc/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/index.ts:
--------------------------------------------------------------------------------
1 | export * from './server'
2 | export * from './client'
3 | export * from './bsync'
4 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/index.ts:
--------------------------------------------------------------------------------
1 | export * from './db'
2 | export type { DatabaseSchema } from './db'
3 |
--------------------------------------------------------------------------------
/packages/dev-env/assets/hd-key.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistydemeo/atproto/main/packages/dev-env/assets/hd-key.jpg
--------------------------------------------------------------------------------
/packages/dev-env/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/did-resolver/src/methods.ts:
--------------------------------------------------------------------------------
1 | export * from './methods/plc.js'
2 | export * from './methods/web.js'
3 |
--------------------------------------------------------------------------------
/packages/internal/did-resolver/src/util.ts:
--------------------------------------------------------------------------------
1 | export type Simplify = { [K in keyof T]: T[K] } & NonNullable
2 |
--------------------------------------------------------------------------------
/packages/lex-cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/jwk/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/src/lib/lexicon.ts:
--------------------------------------------------------------------------------
1 | export type { LexPermission, LexPermissionSet } from '@atproto/lexicon'
2 |
--------------------------------------------------------------------------------
/packages/ozone/src/config/index.ts:
--------------------------------------------------------------------------------
1 | export * from './config'
2 | export * from './env'
3 | export * from './secrets'
4 |
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/aturi_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/aturi_syntax_invalid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/handle_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/handle_syntax_valid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/nsid_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/nsid_syntax_invalid.txt
--------------------------------------------------------------------------------
/packages/dev-env/assets/key-alt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistydemeo/atproto/main/packages/dev-env/assets/key-alt.jpg
--------------------------------------------------------------------------------
/packages/internal/fetch/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/pipe/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/jwk-jose/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/packages/pds/src/read-after-write/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | export * from './util'
3 | export * from './viewer'
4 |
--------------------------------------------------------------------------------
/packages/pds/src/sequencer/index.ts:
--------------------------------------------------------------------------------
1 | export * from './sequencer'
2 | export * from './outbox'
3 | export * from './events'
4 |
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/datetime_parse_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/datetime_parse_invalid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/datetime_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/datetime_syntax_invalid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/datetime_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/datetime_syntax_valid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/handle_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/handle_syntax_invalid.txt
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/recordkey_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/recordkey_syntax_valid.txt
--------------------------------------------------------------------------------
/packages/internal/fetch-node/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/xrpc-utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/jwk-webcrypto/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/oauth-dpop.ts:
--------------------------------------------------------------------------------
1 | export * from './dpop/dpop-nonce.js'
2 | export * from './dpop/dpop-manager.js'
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/syntax/tests/interop-files/recordkey_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 | ../../../../interop-test-files/syntax/recordkey_syntax_invalid.txt
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'services/*'
3 | - 'packages/*'
4 | - 'packages/oauth/*'
5 | - 'packages/internal/*'
6 |
--------------------------------------------------------------------------------
/packages/internal/did-resolver/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/handle-resolver/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/simple-store/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-node/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/src/errors/auth-method-unsatisfiable-error.ts:
--------------------------------------------------------------------------------
1 | export class AuthMethodUnsatisfiableError extends Error {}
2 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/types/email-otp.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const emailOtpSchema = z.string().min(1)
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/pds/src/db/index.ts:
--------------------------------------------------------------------------------
1 | export * from './db'
2 | export * from './cast'
3 | export * from './migrator'
4 | export * from './util'
5 |
--------------------------------------------------------------------------------
/packages/sync/src/runner/index.ts:
--------------------------------------------------------------------------------
1 | export * from './consecutive-list'
2 | export * from './memory-runner'
3 | export * from './types'
4 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | projects: ['/packages/*/jest.config.js'],
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/handle-resolver-node/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/identity-resolver/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/simple-store-memory/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/simple-store-redis/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/migrations/index.ts:
--------------------------------------------------------------------------------
1 | import * as init from './001-init'
2 |
3 | export default {
4 | '001': init,
5 | }
6 |
--------------------------------------------------------------------------------
/packages/pds/src/sequencer/db/migrations/index.ts:
--------------------------------------------------------------------------------
1 | import * as init from './001-init'
2 |
3 | export default {
4 | '001': init,
5 | }
6 |
--------------------------------------------------------------------------------
/packages/dev-env/assets/key-landscape-large.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistydemeo/atproto/main/packages/dev-env/assets/key-landscape-large.jpg
--------------------------------------------------------------------------------
/packages/dev-env/assets/key-landscape-small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistydemeo/atproto/main/packages/dev-env/assets/key-landscape-small.jpg
--------------------------------------------------------------------------------
/packages/dev-env/assets/key-portrait-large.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistydemeo/atproto/main/packages/dev-env/assets/key-portrait-large.jpg
--------------------------------------------------------------------------------
/packages/dev-env/assets/key-portrait-small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistydemeo/atproto/main/packages/dev-env/assets/key-portrait-small.jpg
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/src/constants.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Per ATProto spec (OpenID uses RS256)
3 | */
4 | export const FALLBACK_ALG = 'ES256'
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/types/color-hue.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const colorHueSchema = z.number().min(0).max(360)
4 |
--------------------------------------------------------------------------------
/packages/ozone/src/setting/types.ts:
--------------------------------------------------------------------------------
1 | export type ProtectedTagSetting = {
2 | [key: string]: { roles?: string[]; moderators?: string[] }
3 | }
4 |
--------------------------------------------------------------------------------
/packages/internal/rollup-plugin-bundle-manifest/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [{ "path": "./tsconfig.build.json" }]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/internal/simple-store/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './cached-getter.js'
2 | export * from './simple-store.js'
3 | export * from './util.js'
4 |
--------------------------------------------------------------------------------
/packages/lexicon/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | export * from './lexicons'
3 | export * from './blob-refs'
4 | export * from './serialize'
5 |
--------------------------------------------------------------------------------
/packages/repo/src/mst/index.ts:
--------------------------------------------------------------------------------
1 | export * from './mst'
2 | export * from './diff'
3 | export * from './walker'
4 | export * as mstUtil from './util'
5 |
--------------------------------------------------------------------------------
/packages/internal/handle-resolver/src/handle-resolver-error.ts:
--------------------------------------------------------------------------------
1 | export class HandleResolverError extends Error {
2 | name = 'HandleResolverError'
3 | }
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/constants.ts:
--------------------------------------------------------------------------------
1 | export const CLIENT_ASSERTION_TYPE_JWT_BEARER =
2 | 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
3 |
--------------------------------------------------------------------------------
/interop-test-files/syntax/tid_syntax_valid.txt:
--------------------------------------------------------------------------------
1 | # 13 digits
2 | # 234567abcdefghijklmnopqrstuvwxyz
3 |
4 | 3jzfcijpj2z2a
5 | 7777777777777
6 | 3zzzzzzzzzzzz
7 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/README.md:
--------------------------------------------------------------------------------
1 | # @atproto/oauth-types
2 |
3 | This library exposes utilities for typing and validating OAuth related data structures.
4 |
--------------------------------------------------------------------------------
/packages/internal/identity-resolver/src/identity-resolver-error.ts:
--------------------------------------------------------------------------------
1 | export class IdentityResolverError extends Error {
2 | name = 'IdentityResolverError'
3 | }
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/access-token/access-token-mode.ts:
--------------------------------------------------------------------------------
1 | export enum AccessTokenMode {
2 | stateless = 'stateless',
3 | stateful = 'stateful',
4 | }
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/dpop/dpop-proof.ts:
--------------------------------------------------------------------------------
1 | export type DpopProof = Readonly<{
2 | jti: string
3 | jkt: string
4 | htm: string
5 | htu: string
6 | }>
7 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/oidc/sub.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const subSchema = z.string().min(1)
4 | export type Sub = z.infer
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-code-challenge-method.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthCodeChallengeMethodSchema = z.enum(['S256', 'plain'])
4 |
--------------------------------------------------------------------------------
/packages/api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/dev-env/src/const.ts:
--------------------------------------------------------------------------------
1 | export const ADMIN_PASSWORD = 'admin-pass'
2 | export const JWT_SECRET = 'jwt-secret'
3 | export const EXAMPLE_LABELER = 'did:example:labeler'
4 |
--------------------------------------------------------------------------------
/packages/identity/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './did'
2 | export * from './handle'
3 | export * from './id-resolver'
4 | export * from './errors'
5 | export * from './types'
6 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/components/Divider.tsx:
--------------------------------------------------------------------------------
1 | export function Divider() {
2 | return
3 | }
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/html/index.ts:
--------------------------------------------------------------------------------
1 | export * from './html.js'
2 | export * from './tags.js'
3 |
4 | // Extra util
5 | export * from './build-document.js'
6 |
--------------------------------------------------------------------------------
/packages/pds/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/bsky/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/bsync/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/bsync/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/common/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/common/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/crypto/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/crypto/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/identity/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/identity/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/internal/fetch-node/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@atproto-labs/fetch'
2 |
3 | export * from './safe.js'
4 | export * from './unicast.js'
5 | export * from './util.js'
6 |
--------------------------------------------------------------------------------
/packages/lexicon/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/lexicon/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/src/lib/util.ts:
--------------------------------------------------------------------------------
1 | export const ifString = (value: unknown): string | undefined =>
2 | typeof value === 'string' ? value : undefined
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/oauth-client.ts:
--------------------------------------------------------------------------------
1 | export * from '@atproto/oauth-types'
2 | export type * from './client/client.js'
3 | export * from './client/client-utils.js'
4 |
--------------------------------------------------------------------------------
/packages/ozone/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/repo/src/storage/index.ts:
--------------------------------------------------------------------------------
1 | export * from './readable-blockstore'
2 | export * from './memory-blockstore'
3 | export * from './sync-storage'
4 | export * from './types'
5 |
--------------------------------------------------------------------------------
/packages/repo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/repo/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/syntax/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/syntax/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/common-web/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/common-web/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser/src/indexed-db/schema.ts:
--------------------------------------------------------------------------------
1 | export type ObjectStoreSchema = NonNullable
2 | export type DatabaseSchema = Record
3 |
--------------------------------------------------------------------------------
/packages/xrpc-server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/xrpc-server/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "."
5 | },
6 | "include": ["./tests"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/aws/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './kms'
2 | export * from './s3'
3 | export * from './cloudfront'
4 | export * from './bunny'
5 | export * from './util'
6 | export * from './types'
7 |
--------------------------------------------------------------------------------
/packages/did/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './atproto.js'
2 | export * from './did-document.js'
3 | export * from './did-error.js'
4 | export * from './did.js'
5 | export * from './methods.js'
6 |
--------------------------------------------------------------------------------
/packages/lexicon-resolver/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/src/ExpoAtprotoOAuthClientModule.types.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/ban-types
2 | export type ExpoAtprotoOAuthClientModuleEvents = {}
3 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/util/sleep.ts:
--------------------------------------------------------------------------------
1 | export async function sleep(delay: number): Promise {
2 | return new Promise((resolve) => setTimeout(resolve, delay))
3 | }
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tests.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/api/src/session-manager.ts:
--------------------------------------------------------------------------------
1 | import { FetchHandlerObject } from '@atproto/xrpc'
2 |
3 | export interface SessionManager extends FetchHandlerObject {
4 | readonly did?: string
5 | }
6 |
--------------------------------------------------------------------------------
/packages/crypto/src/plugins.ts:
--------------------------------------------------------------------------------
1 | import { p256Plugin } from './p256/plugin'
2 | import { secp256k1Plugin } from './secp256k1/plugin'
3 |
4 | export const plugins = [p256Plugin, secp256k1Plugin]
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/src/polyfill.native.ts:
--------------------------------------------------------------------------------
1 | import 'core-js/proposals/explicit-resource-management'
2 | import 'event-target-polyfill'
3 | import 'react-native-url-polyfill/auto'
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.src.json" },
5 | { "path": "./tsconfig.tools.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": "src"
5 | },
6 | "include": ["src"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/pds/src/mailer/templates/update-email.d.ts:
--------------------------------------------------------------------------------
1 | import { TemplateDelegate } from 'handlebars'
2 |
3 | declare const template: TemplateDelegate<{ token: string }>
4 | export default template
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser/src/indexed-db/index.ts:
--------------------------------------------------------------------------------
1 | export * from './db.js'
2 | export * from './db-index.js'
3 | export * from './db-object-store.js'
4 | export * from './db-transaction.js'
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/locales/setup.ts:
--------------------------------------------------------------------------------
1 | import { i18n } from '@lingui/core'
2 | import { messages } from './en/messages'
3 |
4 | i18n.load('en', messages)
5 | i18n.activate('en')
6 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.src.json" },
5 | { "path": "./tsconfig.tools.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/types/invite-code.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const inviteCodeSchema = z.string().min(1)
4 | export type InviteCode = z.infer
5 |
--------------------------------------------------------------------------------
/packages/pds/src/mailer/templates/confirm-email.d.ts:
--------------------------------------------------------------------------------
1 | import { TemplateDelegate } from 'handlebars'
2 |
3 | declare const template: TemplateDelegate<{ token: string }>
4 | export default template
5 |
--------------------------------------------------------------------------------
/packages/pds/src/mailer/templates/delete-account.d.ts:
--------------------------------------------------------------------------------
1 | import { TemplateDelegate } from 'handlebars'
2 |
3 | declare const template: TemplateDelegate<{ token: string }>
4 | export default template
5 |
--------------------------------------------------------------------------------
/packages/pds/src/mailer/templates/plc-operation.d.ts:
--------------------------------------------------------------------------------
1 | import { TemplateDelegate } from 'handlebars'
2 |
3 | declare const template: TemplateDelegate<{ token: string }>
4 | export default template
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-client-id.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthClientIdSchema = z.string().min(1)
4 | export type OAuthClientId = z.infer
5 |
--------------------------------------------------------------------------------
/packages/repo/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/sync/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/aws/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bsky/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "noUnusedLocals": false
6 | },
7 | "include": ["./tests"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bsync/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/common/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/dev-env/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/did/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/identity/src/did/index.ts:
--------------------------------------------------------------------------------
1 | export * from './web-resolver'
2 | export * from './plc-resolver'
3 | export * from './did-resolver'
4 | export * from './atproto-data'
5 | export * from './memory-cache'
6 |
--------------------------------------------------------------------------------
/packages/lex-cli/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [],
3 | "references": [
4 | { "path": "./tsconfig.build.json" },
5 | { "path": "./tsconfig.tools.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/types/password.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oldPasswordSchema = z.string().min(1).max(512)
4 | export const newPasswordSchema = z.string().min(8).max(256)
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/atproto-loopback-client-redirect-uris.ts:
--------------------------------------------------------------------------------
1 | export const DEFAULT_LOOPBACK_CLIENT_REDIRECT_URIS = Object.freeze([
2 | `http://127.0.0.1/`,
3 | `http://[::1]/`,
4 | ] as const)
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-request-uri.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthRequestUriSchema = z.string()
4 |
5 | export type OAuthRequestUri = z.infer
6 |
--------------------------------------------------------------------------------
/packages/ozone/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "noUnusedLocals": false
6 | },
7 | "include": ["./tests"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/pds/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "noUnusedLocals": false
6 | },
7 | "include": ["./tests"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/repo/src/logger.ts:
--------------------------------------------------------------------------------
1 | import { subsystemLogger } from '@atproto/common'
2 |
3 | export const logger: ReturnType =
4 | subsystemLogger('repo')
5 |
6 | export default logger
7 |
--------------------------------------------------------------------------------
/packages/crypto/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/identity/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/simple-store/src/util.ts:
--------------------------------------------------------------------------------
1 | export type Awaitable = V | PromiseLike
2 |
3 | export type ContextOptions = C extends void | undefined
4 | ? { context?: undefined }
5 | : { context: C }
6 |
--------------------------------------------------------------------------------
/packages/lexicon/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/jwk/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-api/src/index.ts:
--------------------------------------------------------------------------------
1 | export type * from './api-endpoints.js'
2 | export type * from './customization-data.js'
3 | export type * from './types.js'
4 |
5 | export * from './contants.js'
6 |
--------------------------------------------------------------------------------
/packages/pds/src/mailer/templates/reset-password.d.ts:
--------------------------------------------------------------------------------
1 | import { TemplateDelegate } from 'handlebars'
2 |
3 | declare const template: TemplateDelegate<{ token: string; handle: string }>
4 | export default template
5 |
--------------------------------------------------------------------------------
/packages/syntax/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/xrpc-server/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/xrpc/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bsky/src/image/logger.ts:
--------------------------------------------------------------------------------
1 | import { subsystemLogger } from '@atproto/common'
2 |
3 | export const logger: ReturnType =
4 | subsystemLogger('bsky:image')
5 |
6 | export default logger
7 |
--------------------------------------------------------------------------------
/packages/common-web/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/fetch-node/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/node.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/fetch/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/pipe/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/xrpc-utils/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/node.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/jwk-jose/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/nodenext.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-access-token.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthAccessTokenSchema = z.string().min(1)
4 | export type OAuthAccessToken = z.infer
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-refresh-token.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthRefreshTokenSchema = z.string().min(1)
4 | export type OAuthRefreshToken = z.infer
5 |
--------------------------------------------------------------------------------
/tsconfig/node.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "./base.json",
4 | "compilerOptions": {
5 | "lib": ["ES2023", "ScriptHost"],
6 | "types": ["node"]
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/lexicon-resolver/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "noUnusedLocals": false
6 | },
7 | "include": ["./tests"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-api/src/contants.ts:
--------------------------------------------------------------------------------
1 | export const CSRF_COOKIE_NAME = 'csrf-token'
2 | export const CSRF_HEADER_NAME = 'x-csrf-token'
3 |
4 | export const API_ENDPOINT_PREFIX = '/@atproto/oauth-provider/~api'
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/nodenext.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/syntax/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './handle'
2 | export * from './did'
3 | export * from './nsid'
4 | export * from './aturi'
5 | export * from './tid'
6 | export * from './recordkey'
7 | export * from './datetime'
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/expo.json"],
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-node/src/util.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/ban-types
2 | export type Simplify = { [K in keyof T]: T[K] } & {}
3 | export type Override = Simplify>
4 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-node/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/client/client-id.ts:
--------------------------------------------------------------------------------
1 | import { OAuthClientId, oauthClientIdSchema } from '@atproto/oauth-types'
2 |
3 | export type ClientId = OAuthClientId
4 | export const clientIdSchema = oauthClientIdSchema
5 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oidc-entity-type.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oidcEntityTypeSchema = z.enum(['userinfo', 'id_token'])
4 |
5 | export type OidcEntityType = z.infer
6 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/pds/src/util/types.ts:
--------------------------------------------------------------------------------
1 | export type Simplify = {
2 | [K in keyof T]: T[K]
3 | } & NonNullable
4 |
5 | export type WithRequired = Simplify<
6 | Omit & Required>
7 | >
8 |
--------------------------------------------------------------------------------
/packages/xrpc-server/src/stream/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | export * from './frames'
3 | export * from './stream'
4 | export * from './subscription'
5 | export * from './server'
6 | export * from './websocket-keepalive'
7 |
--------------------------------------------------------------------------------
/packages/xrpc-server/src/stream/logger.ts:
--------------------------------------------------------------------------------
1 | import { subsystemLogger } from '@atproto/common'
2 |
3 | export const logger: ReturnType =
4 | subsystemLogger('xrpc-stream')
5 |
6 | export default logger
7 |
--------------------------------------------------------------------------------
/packages/internal/handle-resolver-node/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/node.json"],
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/handle-resolver/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/identity-resolver/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/simple-store-redis/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/simple-store/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/jwk-webcrypto/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-api/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/data/useCustomizationData.ts:
--------------------------------------------------------------------------------
1 | import { useHydrationData } from './useHydrationData'
2 |
3 | export function useCustomizationData() {
4 | return useHydrationData('__customizationData')
5 | }
6 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
4 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
5 | }
6 |
--------------------------------------------------------------------------------
/interop-test-files/crypto/w3c_didkey_P256.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "privateKeyBytesBase58": "9p4VRzdmhsnq869vQjVCTrRry7u4TtfRxhvBFJTGU2Cp",
4 | "publicDidKey": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb"
5 | }
6 | ]
7 |
--------------------------------------------------------------------------------
/packages/internal/rollup-plugin-bundle-manifest/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/node.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/simple-store-memory/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/sync/src/runner/types.ts:
--------------------------------------------------------------------------------
1 | export interface EventRunner {
2 | getCursor(): Awaited
3 | trackEvent(
4 | did: string,
5 | seq: number,
6 | handler: () => Promise,
7 | ): Promise
8 | }
9 |
--------------------------------------------------------------------------------
/packages/internal/did-resolver/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist"
6 | },
7 | "include": ["./src/**/*.ts"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/schema/record-blob.ts:
--------------------------------------------------------------------------------
1 | export interface RecordBlob {
2 | blobCid: string
3 | recordUri: string
4 | }
5 |
6 | export const tableName = 'record_blob'
7 |
8 | export type PartialDB = { [tableName]: RecordBlob }
9 |
--------------------------------------------------------------------------------
/services/bsync/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bsync-service",
3 | "private": true,
4 | "packageManager": "pnpm@8.15.9",
5 | "dependencies": {
6 | "@atproto/bsync": "workspace:^",
7 | "dd-trace": "3.13.2"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bsky/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist",
6 | "noUnusedLocals": false
7 | },
8 | "include": ["./src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/internal/fetch/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './fetch-error.js'
2 | export * from './fetch-request.js'
3 | export * from './fetch-response.js'
4 | export * from './fetch-wrap.js'
5 | export * from './fetch.js'
6 | export * from './util.js'
7 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/util/wait.ts:
--------------------------------------------------------------------------------
1 | import { sleep } from './sleep'
2 |
3 | export async function wait(delay: number, promise: T) {
4 | const [result] = await Promise.all([promise, sleep(delay)])
5 | return result
6 | }
7 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/src/lib/nsid.ts:
--------------------------------------------------------------------------------
1 | import { isValidNsid } from '@atproto/syntax'
2 |
3 | export type Nsid = `${string}.${string}.${string}`
4 | export const isNsid = (v: unknown): v is Nsid =>
5 | typeof v === 'string' && isValidNsid(v)
6 |
--------------------------------------------------------------------------------
/packages/ozone/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist",
6 | "noUnusedLocals": false
7 | },
8 | "include": ["./src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/pds/src/did-cache/db/schema.ts:
--------------------------------------------------------------------------------
1 | export interface DidDoc {
2 | did: string
3 | doc: string // json representation of DidDocument
4 | updatedAt: number
5 | }
6 |
7 | export type DidCacheSchema = {
8 | did_doc: DidDoc
9 | }
10 |
--------------------------------------------------------------------------------
/packages/pds/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist",
6 | "noUnusedLocals": false
7 | },
8 | "include": ["./src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/api/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/isomorphic.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./dist",
6 | "noUnusedLocals": false
7 | },
8 | "include": ["./src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/internal/identity-resolver/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './atproto-identity-resolver.js'
2 | export * from './constants.js'
3 | export * from './identity-resolver-error.js'
4 | export * from './identity-resolver.js'
5 | export * from './util.js'
6 |
--------------------------------------------------------------------------------
/packages/pds/src/scripts/util.ts:
--------------------------------------------------------------------------------
1 | export const parseIntArg = (arg: string): number => {
2 | const parsed = parseInt(arg, 10)
3 | if (isNaN(parsed)) {
4 | throw new Error(`Invalid arg, expected number: ${arg}`)
5 | }
6 | return parsed
7 | }
8 |
--------------------------------------------------------------------------------
/tsconfig/browser.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "./base.json",
4 | "compilerOptions": {
5 | "lib": ["ES2023", "DOM", "DOM.Iterable", "ESNext.Disposable"],
6 | "jsx": "react-jsx"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/lexicon-resolver/src/util.ts:
--------------------------------------------------------------------------------
1 | import { ensureValidDid } from '@atproto/syntax'
2 |
3 | export function isValidDid(did: string) {
4 | try {
5 | ensureValidDid(did)
6 | return true
7 | } catch {
8 | return false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/lexicon-resolver/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../tsconfig/node.json"],
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "rootDir": "./src",
6 | "noUnusedLocals": false
7 | },
8 | "include": ["src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/schema/backlink.ts:
--------------------------------------------------------------------------------
1 | export interface Backlink {
2 | uri: string
3 | path: string
4 | linkTo: string
5 | }
6 |
7 | export const tableName = 'backlink'
8 |
9 | export type PartialDB = { [tableName]: Backlink }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/mute.ts:
--------------------------------------------------------------------------------
1 | export interface Mute {
2 | subjectDid: string
3 | mutedByDid: string
4 | createdAt: string
5 | }
6 |
7 | export const tableName = 'mute'
8 |
9 | export type PartialDB = { [tableName]: Mute }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/src/hooks/use-bound-dispatch.ts:
--------------------------------------------------------------------------------
1 | import { Dispatch, useCallback } from 'react'
2 |
3 | export function useBoundDispatch(dispatch: Dispatch, value: A) {
4 | return useCallback(() => dispatch(value), [dispatch, value])
5 | }
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | lerna-debug.log
3 | npm-debug.log
4 | yarn-error.log
5 | packages/**/dist
6 | .idea
7 | packages/*/coverage
8 | test.sqlite
9 | .DS_Store
10 | *.log
11 | *.tsbuildinfo
12 | .*.env
13 | .env.*
14 | .env
15 | \#*\#
16 | *~
17 | *.swp
18 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "dbaeumer.vscode-eslint",
4 | "expo.vscode-expo-tools",
5 | "wengerk.highlight-bad-chars",
6 | "esbenp.prettier-vscode",
7 | "streetsidesoftware.code-spell-checker"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-node/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@atproto-labs/handle-resolver-node'
2 | export * from '@atproto/jwk-webcrypto'
3 | export * from '@atproto/oauth-client'
4 | export * from '@atproto/jwk-jose'
5 |
6 | export * from './node-oauth-client.js'
7 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/isomorphic.json"],
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src"],
8 | "exclude": ["**/*.test.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/ozone/src/setting/constants.ts:
--------------------------------------------------------------------------------
1 | export const ProtectedTagSettingKey = 'tools.ozone.setting.protectedTags'
2 | export const PolicyListSettingKey = 'tools.ozone.setting.policyList'
3 | export const SeverityLevelSettingKey = 'tools.ozone.setting.severityLevels'
4 |
--------------------------------------------------------------------------------
/packages/xrpc-server/src/logger.ts:
--------------------------------------------------------------------------------
1 | import { subsystemLogger } from '@atproto/common'
2 |
3 | export const LOGGER_NAME = 'xrpc-server'
4 |
5 | export const logger: ReturnType =
6 | subsystemLogger(LOGGER_NAME)
7 |
8 | export default logger
9 |
--------------------------------------------------------------------------------
/packages/dev-infra/with-test-db.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # Example usage:
4 | # ./with-test-db.sh psql postgresql://pg:password@localhost:5433/postgres -c 'select 1;'
5 |
6 | dir=$(dirname $0)
7 | . ${dir}/_common.sh
8 |
9 | SERVICES="db_test" main "$@"
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig/node.json",
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "noEmit": true
6 | },
7 | "include": ["./*.js", "./*.ts"],
8 | "exclude": []
9 | }
10 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/schema/repo-root.ts:
--------------------------------------------------------------------------------
1 | export interface RepoRoot {
2 | did: string
3 | cid: string
4 | rev: string
5 | indexedAt: string
6 | }
7 |
8 | const tableName = 'repo_root'
9 |
10 | export type PartialDB = { [tableName]: RepoRoot }
11 |
--------------------------------------------------------------------------------
/tsconfig/tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "./node.json",
4 | "compilerOptions": {
5 | "types": ["node", "jest"],
6 | "lib": ["ES2023", "DOM", "DOM.Iterable"],
7 | "noEmit": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/sync/defs.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.sync.defs",
4 | "defs": {
5 | "hostStatus": {
6 | "type": "string",
7 | "knownValues": ["active", "idle", "offline", "throttled", "banned"]
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/aws/src/types.ts:
--------------------------------------------------------------------------------
1 | // @NOTE keep in sync with same interface in bsky/src/image/invalidator.ts
2 | // this is separate to avoid the dependency on @atproto/bsky.
3 | export interface ImageInvalidator {
4 | invalidate(subject: string, paths: string[]): Promise
5 | }
6 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/list-mute.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'list_mute'
2 |
3 | export interface ListMute {
4 | listUri: string
5 | mutedByDid: string
6 | createdAt: string
7 | }
8 |
9 | export type PartialDB = { [tableName]: ListMute }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/suggested-feed.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'suggested_feed'
2 |
3 | export interface SuggestedFeed {
4 | uri: string
5 | order: number
6 | }
7 |
8 | export type PartialDB = {
9 | [tableName]: SuggestedFeed
10 | }
11 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/types.ts:
--------------------------------------------------------------------------------
1 | import { Pool as PgPool } from 'pg'
2 |
3 | export type PgOptions = {
4 | url: string
5 | pool?: PgPool
6 | schema?: string
7 | poolSize?: number
8 | poolMaxUses?: number
9 | poolIdleTimeoutMs?: number
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/data/useHasAccounts.ts:
--------------------------------------------------------------------------------
1 | import { useDeviceSessionsQuery } from '#/data/useDeviceSessionsQuery'
2 |
3 | export function useHasAccounts() {
4 | const { data: accounts } = useDeviceSessionsQuery()
5 | return accounts?.length > 0
6 | }
7 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/nodenext.json"],
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "noEmit": true
6 | },
7 | "include": ["./*.js", "./*.cjs", "./*.mjs", "./*.ts", "./*.cts", "./*.mts"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/nsid.ts:
--------------------------------------------------------------------------------
1 | import { NSID } from '@atproto/syntax'
2 | export { NSID }
3 |
4 | export function parseNSID(value: string): NSID | null {
5 | try {
6 | return NSID.parse(value)
7 | } catch {
8 | return null
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/api/tsconfig.tests.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig/tests.json",
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "types": ["jest", "./jest.d.ts"],
6 | "noEmit": true,
7 | "noUnusedLocals": false
8 | },
9 | "include": ["./tests"]
10 | }
11 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/actor-sync.ts:
--------------------------------------------------------------------------------
1 | export interface ActorSync {
2 | did: string
3 | commitCid: string
4 | repoRev: string | null
5 | }
6 |
7 | export const tableName = 'actor_sync'
8 |
9 | export type PartialDB = { [tableName]: ActorSync }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/subscription.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'subscription'
2 |
3 | export interface Subscription {
4 | service: string
5 | method: string
6 | state: string
7 | }
8 |
9 | export type PartialDB = { [tableName]: Subscription }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/suggested-follow.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'suggested_follow'
2 |
3 | export interface SuggestedFollow {
4 | did: string
5 | order: number
6 | }
7 |
8 | export type PartialDB = {
9 | [tableName]: SuggestedFollow
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-endpoint-name.ts:
--------------------------------------------------------------------------------
1 | export const OAUTH_ENDPOINT_NAMES = [
2 | 'token',
3 | 'revocation',
4 | 'introspection',
5 | 'pushed_authorization_request',
6 | ] as const
7 |
8 | export type OAuthEndpointName = (typeof OAUTH_ENDPOINT_NAMES)[number]
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-response-mode.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthResponseModeSchema = z.enum([
4 | 'query',
5 | 'fragment',
6 | 'form_post',
7 | ])
8 |
9 | export type OAuthResponseMode = z.infer
10 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/repo-root.ts:
--------------------------------------------------------------------------------
1 | export interface RepoRoot {
2 | did: string
3 | cid: string
4 | rev: string
5 | indexedAt: string
6 | }
7 |
8 | export const tableName = 'repo_root'
9 |
10 | export type PartialDB = { [tableName]: RepoRoot }
11 |
--------------------------------------------------------------------------------
/services/ozone/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ozone-service",
3 | "private": true,
4 | "packageManager": "pnpm@8.15.9",
5 | "dependencies": {
6 | "@atproto/aws": "workspace:^",
7 | "@atproto/ozone": "workspace:^",
8 | "dd-trace": "3.13.2"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/server/deleteSession.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.server.deleteSession",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "description": "Delete the current session. Requires auth."
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/bsky/buf.gen.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | plugins:
3 | - plugin: es
4 | opt:
5 | - target=ts
6 | - import_extension=
7 | out: src/proto
8 | - plugin: connect-es
9 | opt:
10 | - target=ts
11 | - import_extension=
12 | out: src/proto
13 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/blob-takedown.ts:
--------------------------------------------------------------------------------
1 | export interface BlobTakedown {
2 | did: string
3 | cid: string
4 | takedownRef: string
5 | }
6 |
7 | export const tableName = 'blob_takedown'
8 |
9 | export type PartialDB = { [tableName]: BlobTakedown }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/thread-mute.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'thread_mute'
2 |
3 | export interface ThreadMute {
4 | rootUri: string
5 | mutedByDid: string
6 | createdAt: string
7 | }
8 |
9 | export type PartialDB = { [tableName]: ThreadMute }
10 |
--------------------------------------------------------------------------------
/packages/bsync/buf.gen.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | plugins:
3 | - plugin: es
4 | opt:
5 | - target=ts
6 | - import_extension=
7 | out: src/proto
8 | - plugin: connect-es
9 | opt:
10 | - target=ts
11 | - import_extension=
12 | out: src/proto
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../tsconfig/nodenext.json"],
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "noEmit": true
6 | },
7 | "include": ["./*.js", "./*.cjs", "./*.mjs", "./*.ts", "./*.cts", "./*.mts"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/util/date.ts:
--------------------------------------------------------------------------------
1 | export function dateToEpoch(date: Date = new Date()) {
2 | return Math.floor(date.getTime() / 1000)
3 | }
4 |
5 | export function dateToRelativeSeconds(date: Date) {
6 | return Math.floor((date.getTime() - Date.now()) / 1000)
7 | }
8 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/schema/signing_key.ts:
--------------------------------------------------------------------------------
1 | import { Generated } from 'kysely'
2 |
3 | export const tableName = 'signing_key'
4 |
5 | export interface SigningKey {
6 | id: Generated
7 | key: string
8 | }
9 |
10 | export type PartialDB = { [tableName]: SigningKey }
11 |
--------------------------------------------------------------------------------
/services/bsky/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bsky-app-view-service",
3 | "private": true,
4 | "packageManager": "pnpm@8.15.9",
5 | "dependencies": {
6 | "@atproto/bsky": "workspace:^",
7 | "@atproto/crypto": "workspace:^",
8 | "dd-trace": "3.13.2"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/lexicons/chat/bsky/actor/exportAccountData.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "chat.bsky.actor.exportAccountData",
4 | "defs": {
5 | "main": {
6 | "type": "query",
7 | "output": {
8 | "encoding": "application/jsonl"
9 | }
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/src/errors/token-refresh-error.ts:
--------------------------------------------------------------------------------
1 | export class TokenRefreshError extends Error {
2 | constructor(
3 | public readonly sub: string,
4 | message: string,
5 | options?: { cause?: unknown },
6 | ) {
7 | super(message, options)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lexicon/lexicon-data.ts:
--------------------------------------------------------------------------------
1 | import { LexiconDoc } from '@atproto/lexicon'
2 |
3 | export type LexiconData = {
4 | createdAt: Date
5 | updatedAt: Date
6 | lastSucceededAt: null | Date
7 | uri: null | string
8 | lexicon: null | LexiconDoc
9 | }
10 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/schema/repo-block.ts:
--------------------------------------------------------------------------------
1 | export interface RepoBlock {
2 | cid: string
3 | repoRev: string
4 | size: number
5 | content: Uint8Array
6 | }
7 |
8 | export const tableName = 'repo_block'
9 |
10 | export type PartialDB = { [tableName]: RepoBlock }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-par-response.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthParResponseSchema = z.object({
4 | request_uri: z.string(),
5 | expires_in: z.number().int().positive(),
6 | })
7 |
8 | export type OAuthParResponse = z.infer
9 |
--------------------------------------------------------------------------------
/packages/repo/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Repo',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/server/requestAccountDelete.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.server.requestAccountDelete",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "description": "Initiate a user account deletion via email."
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/bsync/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Bsync',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/packages/common/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Common',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/packages/crypto/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Crypto',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/packages/lexicon/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Lexicon',
4 | transform: { '^.+\\.ts$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/packages/pds/src/api/app/bsky/notification/index.ts:
--------------------------------------------------------------------------------
1 | import { AppContext } from '../../../../context'
2 | import { Server } from '../../../../lexicon'
3 | import registerPush from './registerPush'
4 |
5 | export default function (server: Server, ctx: AppContext) {
6 | registerPush(server, ctx)
7 | }
8 |
--------------------------------------------------------------------------------
/packages/pds/src/api/com/atproto/moderation/index.ts:
--------------------------------------------------------------------------------
1 | import { AppContext } from '../../../../context'
2 | import { Server } from '../../../../lexicon'
3 | import createReport from './createReport'
4 |
5 | export default function (server: Server, ctx: AppContext) {
6 | createReport(server, ctx)
7 | }
8 |
--------------------------------------------------------------------------------
/packages/syntax/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Syntax',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/packages/internal/did-resolver/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@atproto/did'
2 |
3 | export * from './did-cache-memory.js'
4 | export * from './did-cache.js'
5 | export * from './did-method.js'
6 | export * from './did-resolver-common.js'
7 | export * from './did-resolver.js'
8 | export * from './methods.js'
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/util/format2FACode.ts:
--------------------------------------------------------------------------------
1 | export function format2FACode(value: string) {
2 | const normalized = value.toUpperCase().replace(/[^A-Z2-7]/g, '')
3 | if (normalized.length <= 5) return normalized
4 | return `${normalized.slice(0, 5)}-${normalized.slice(5, 10)}`
5 | }
6 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/client/client-data.ts:
--------------------------------------------------------------------------------
1 | import { Jwks } from '@atproto/jwk'
2 | import { OAuthClientMetadata } from '@atproto/oauth-types'
3 |
4 | export type { OAuthClientMetadata }
5 |
6 | export type ClientData = {
7 | metadata: OAuthClientMetadata
8 | jwks?: Jwks
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/util/error.ts:
--------------------------------------------------------------------------------
1 | import { ZodError } from 'zod'
2 | import { formatZodError } from './zod-error.js'
3 |
4 | export function formatError(err: unknown, prefix: string): string {
5 | if (err instanceof ZodError) return formatZodError(err, prefix)
6 | return prefix
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/util/well-known.ts:
--------------------------------------------------------------------------------
1 | export function buildWellknownUrl(url: URL, name: string): URL {
2 | const path =
3 | url.pathname === '/'
4 | ? `/.well-known/${name}`
5 | : `${url.pathname.replace(/\/+$/, '')}/${name}`
6 |
7 | return new URL(path, url)
8 | }
9 |
--------------------------------------------------------------------------------
/packages/pds/src/api/com/atproto/temp/index.ts:
--------------------------------------------------------------------------------
1 | import { AppContext } from '../../../../context'
2 | import { Server } from '../../../../lexicon'
3 | import checkSignupQueue from './checkSignupQueue'
4 |
5 | export default function (server: Server, ctx: AppContext) {
6 | checkSignupQueue(server, ctx)
7 | }
8 |
--------------------------------------------------------------------------------
/packages/common-web/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Common Web',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/expo-module.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "platforms": ["apple", "android", "web"],
3 | "apple": {
4 | "modules": ["ExpoAtprotoOAuthClientModule"]
5 | },
6 | "android": {
7 | "modules": ["expo.modules.atprotooauthclient.ExpoAtprotoOAuthClientModule"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/actor-store-resources.ts:
--------------------------------------------------------------------------------
1 | import { BlobStore } from '@atproto/repo'
2 | import { BackgroundQueue } from '../background'
3 |
4 | export type ActorStoreResources = {
5 | blobstore: (did: string) => BlobStore
6 | backgroundQueue: BackgroundQueue
7 | reservedKeyDir?: string
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/tagged-suggestion.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'tagged_suggestion'
2 |
3 | export interface TaggedSuggestion {
4 | tag: string
5 | subject: string
6 | subjectType: string
7 | }
8 |
9 | export type PartialDB = {
10 | [tableName]: TaggedSuggestion
11 | }
12 |
--------------------------------------------------------------------------------
/packages/lex-cli/src/types.ts:
--------------------------------------------------------------------------------
1 | export interface GeneratedFile {
2 | path: string
3 | content: string
4 | }
5 |
6 | export interface GeneratedAPI {
7 | files: GeneratedFile[]
8 | }
9 |
10 | export interface FileDiff {
11 | act: 'add' | 'mod' | 'del'
12 | path: string
13 | content?: string
14 | }
15 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/algo.ts:
--------------------------------------------------------------------------------
1 | export const whatsHotViewTableName = 'algo_whats_hot_view'
2 |
3 | export interface AlgoWhatsHotView {
4 | uri: string
5 | cid: string
6 | score: number
7 | }
8 |
9 | export type PartialDB = {
10 | [whatsHotViewTableName]: AlgoWhatsHotView
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/bookmark.ts:
--------------------------------------------------------------------------------
1 | export interface Bookmark {
2 | creator: string
3 | key: string
4 | subjectUri: string
5 | subjectCid: string
6 | indexedAt: string
7 | }
8 |
9 | export const tableName = 'bookmark'
10 |
11 | export type PartialDB = { [tableName]: Bookmark }
12 |
--------------------------------------------------------------------------------
/packages/lexicon-resolver/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Lexicon Resolver',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | setupFiles: ['/../../jest.setup.ts'],
6 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
7 | }
8 |
--------------------------------------------------------------------------------
/packages/sync/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Sync',
4 | transform: { '^.+\\.ts$': '@swc/jest' },
5 | testTimeout: 60000,
6 | setupFiles: ['/../../jest.setup.ts'],
7 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
8 | }
9 |
--------------------------------------------------------------------------------
/interop-test-files/syntax/datetime_parse_invalid.txt:
--------------------------------------------------------------------------------
1 | # superficial syntax parses ok, but are not valid datetimes for semantic reasons (eg, "month zero")
2 | 1985-00-12T23:20:50.123Z
3 | 1985-04-00T23:20:50.123Z
4 | 1985-13-12T23:20:50.123Z
5 | 1985-04-12T25:20:50.123Z
6 | 1985-04-12T23:99:50.123Z
7 | 1985-04-12T23:20:61.123Z
8 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/server/requestEmailConfirmation.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.server.requestEmailConfirmation",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "description": "Request an email with a code to confirm ownership of email."
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/src/errors/token-invalid-error.ts:
--------------------------------------------------------------------------------
1 | export class TokenInvalidError extends Error {
2 | constructor(
3 | public readonly sub: string,
4 | message = `The session for "${sub}" is invalid`,
5 | options?: { cause?: unknown },
6 | ) {
7 | super(message, options)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/router/error-handler.ts:
--------------------------------------------------------------------------------
1 | import type { IncomingMessage, ServerResponse } from 'node:http'
2 |
3 | export type ErrorHandler<
4 | Req extends IncomingMessage = IncomingMessage,
5 | Res extends ServerResponse = ServerResponse,
6 | > = (req: Req, res: Res, err: unknown, message: string) => void
7 |
--------------------------------------------------------------------------------
/tsconfig/nodenext.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "./base.json",
4 | "compilerOptions": {
5 | "lib": ["ES2023", "ScriptHost"],
6 | "types": ["node"],
7 | "module": "Node16",
8 | "target": "ES2023",
9 | "moduleResolution": "Node16"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/duplicate-record.ts:
--------------------------------------------------------------------------------
1 | export interface DuplicateRecord {
2 | uri: string
3 | cid: string
4 | duplicateOf: string
5 | indexedAt: string
6 | }
7 |
8 | export const tableName = 'duplicate_record'
9 |
10 | export type PartialDB = {
11 | [tableName]: DuplicateRecord
12 | }
13 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/label.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'label'
2 |
3 | export interface Label {
4 | src: string
5 | uri: string
6 | cid: string
7 | val: string
8 | neg: boolean
9 | cts: string
10 | exp: string | null
11 | }
12 |
13 | export type PartialDB = { [tableName]: Label }
14 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/post-gate.ts:
--------------------------------------------------------------------------------
1 | const tableName = 'post_gate'
2 |
3 | export interface Postgate {
4 | uri: string
5 | cid: string
6 | creator: string
7 | postUri: string
8 | createdAt: string
9 | indexedAt: string
10 | }
11 |
12 | export type PartialDB = { [tableName]: Postgate }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | In dev, use `pnpm dev:ui` to start a mock ui server. This will serve the ui through Vite at `http://localhost:5173`.
2 |
3 | Use the following urls to live-preview the various ui pages:
4 |
5 | http://localhost:5173/authorization-page.html
6 | http://localhost:5173/error-page.html
7 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/app-password.ts:
--------------------------------------------------------------------------------
1 | export interface AppPassword {
2 | did: string
3 | name: string
4 | passwordScrypt: string
5 | createdAt: string
6 | privileged: 0 | 1
7 | }
8 |
9 | export const tableName = 'app_password'
10 |
11 | export type PartialDB = { [tableName]: AppPassword }
12 |
--------------------------------------------------------------------------------
/tsconfig/bundler.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "compilerOptions": {
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "allowImportingTsExtensions": true,
7 | "declaration": false,
8 | "declarationMap": false,
9 | "noEmit": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/interop-test-files/syntax/atidentifier_syntax_valid.txt:
--------------------------------------------------------------------------------
1 |
2 | # allows valid handles
3 | XX.LCS.MIT.EDU
4 | john.test
5 | jan.test
6 | a234567890123456789.test
7 | john2.test
8 | john-john.test
9 |
10 | # allows valid DIDs
11 | did:method:val
12 | did:method:VAL
13 | did:method:val123
14 | did:method:123
15 | did:method:val-two
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/thread-gate.ts:
--------------------------------------------------------------------------------
1 | const tableName = 'thread_gate'
2 |
3 | export interface ThreadGate {
4 | uri: string
5 | cid: string
6 | creator: string
7 | postUri: string
8 | createdAt: string
9 | indexedAt: string
10 | }
11 |
12 | export type PartialDB = { [tableName]: ThreadGate }
13 |
--------------------------------------------------------------------------------
/packages/common/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@atproto/common-web'
2 | export * from './buffers'
3 | export * from './dates'
4 | export * from './env'
5 | export * from './fs'
6 | export * from './ipld'
7 | export * from './ipld-multi'
8 | export * from './logger'
9 | export * from './obfuscate'
10 | export * from './streams'
11 |
--------------------------------------------------------------------------------
/packages/internal/fetch/src/fetch-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class FetchError extends Error {
2 | constructor(
3 | public readonly statusCode: number,
4 | message?: string,
5 | options?: ErrorOptions,
6 | ) {
7 | super(message, options)
8 | }
9 |
10 | get expose() {
11 | return true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "../../../tsconfig/browser.json",
4 | "../../../tsconfig/bundler.json"
5 | ],
6 | "compilerOptions": {
7 | "rootDir": "./src",
8 | "outDir": "./dist"
9 | },
10 | "include": ["./src/**/*.ts", "./src/**/*.tsx"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/util/getAccountName.ts:
--------------------------------------------------------------------------------
1 | import { Account } from '#/api'
2 | import { sanitizeHandle } from '#/util/sanitizeHandle'
3 |
4 | export function getAccountName(account: Account): string {
5 | return (
6 | account.name || sanitizeHandle(account.preferred_username) || account.sub
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/interop-test-files/syntax/tid_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 |
2 | # not base32
3 | 3jzfcijpj2z21
4 | 0000000000000
5 |
6 | # too long/short
7 | 3jzfcijpj2z2aa
8 | 3jzfcijpj2z2
9 |
10 | # old dashes syntax not actually supported (TTTT-TTT-TTTT-CC)
11 | 3jzf-cij-pj2z-2a
12 |
13 | # high bit can't be high
14 | zzzzzzzzzzzzz
15 | kjzfcijpj2z2a
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/actor-state.ts:
--------------------------------------------------------------------------------
1 | export interface ActorState {
2 | did: string
3 | lastSeenNotifs: string
4 | priorityNotifs: boolean
5 | lastSeenPriorityNotifs: string | undefined
6 | }
7 |
8 | export const tableName = 'actor_state'
9 |
10 | export type PartialDB = { [tableName]: ActorState }
11 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/did-cache.ts:
--------------------------------------------------------------------------------
1 | import { DidDocument } from '@atproto/identity'
2 |
3 | export interface DidCache {
4 | did: string
5 | doc: DidDocument
6 | updatedAt: number
7 | }
8 |
9 | export const tableName = 'did_cache'
10 |
11 | export type PartialDB = {
12 | [tableName]: DidCache
13 | }
14 |
--------------------------------------------------------------------------------
/packages/crypto/src/const.ts:
--------------------------------------------------------------------------------
1 | export const P256_DID_PREFIX = new Uint8Array([0x80, 0x24])
2 | export const SECP256K1_DID_PREFIX = new Uint8Array([0xe7, 0x01])
3 | export const BASE58_MULTIBASE_PREFIX = 'z'
4 | export const DID_KEY_PREFIX = 'did:key:'
5 |
6 | export const P256_JWT_ALG = 'ES256'
7 | export const SECP256K1_JWT_ALG = 'ES256K'
8 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/src/index.ts:
--------------------------------------------------------------------------------
1 | import './polyfill'
2 |
3 | export * from '@atproto/oauth-client'
4 |
5 | export type { ExpoOAuthClientInterface } from './expo-oauth-client-interface'
6 | export type { ExpoOAuthClientOptions } from './expo-oauth-client-options'
7 |
8 | export { ExpoOAuthClient } from './expo-oauth-client'
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/src/errors/token-revoked-error.ts:
--------------------------------------------------------------------------------
1 | export class TokenRevokedError extends Error {
2 | constructor(
3 | public readonly sub: string,
4 | message = `The session for "${sub}" was successfully revoked`,
5 | options?: { cause?: unknown },
6 | ) {
7 | super(message, options)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/api/index.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react'
2 | import { Api } from '#/api/api'
3 |
4 | export type * from '@atproto/oauth-provider-api'
5 | export * from '#/api/api'
6 | export * from '#/api/json-client'
7 |
8 | export function useApi() {
9 | return useMemo(() => new Api(), [])
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/components/forms/index.tsx:
--------------------------------------------------------------------------------
1 | export * from '#/components/forms/Fieldset'
2 | export * from '#/components/forms/Item'
3 | export * from '#/components/forms/Label'
4 | export * from '#/components/forms/Text'
5 | export * from '#/components/forms/Errors'
6 | export * from '#/components/forms/Checkbox'
7 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/feed-item.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'feed_item'
2 |
3 | export interface FeedItem {
4 | uri: string
5 | cid: string
6 | type: 'post' | 'repost'
7 | postUri: string
8 | originatorDid: string
9 | sortAt: string
10 | }
11 |
12 | export type PartialDB = { [tableName]: FeedItem }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/src/index.tsx:
--------------------------------------------------------------------------------
1 | import './index.css'
2 |
3 | import { StrictMode } from 'react'
4 | import { createRoot } from 'react-dom/client'
5 | import { App } from './_app.tsx'
6 |
7 | createRoot(document.getElementById('root')!).render(
8 |
9 |
10 | ,
11 | )
12 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/src/expo-oauth-client.d.ts:
--------------------------------------------------------------------------------
1 | import { ExpoOAuthClientInterface } from './expo-oauth-client-interface'
2 | import { ExpoOAuthClientOptions } from './expo-oauth-client-options'
3 |
4 | export declare class ExpoOAuthClient implements ExpoOAuthClientInterface {
5 | constructor(options: ExpoOAuthClientOptions)
6 | }
7 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/refresh-token.ts:
--------------------------------------------------------------------------------
1 | export interface RefreshToken {
2 | id: string
3 | did: string
4 | expiresAt: string
5 | appPasswordName: string | null
6 | nextId: string | null
7 | }
8 |
9 | export const tableName = 'refresh_token'
10 |
11 | export type PartialDB = { [tableName]: RefreshToken }
12 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/schema/account-pref.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export interface AccountPref {
4 | id: GeneratedAlways
5 | name: string
6 | valueJson: string // json
7 | }
8 |
9 | export const tableName = 'account_pref'
10 |
11 | export type PartialDB = { [tableName]: AccountPref }
12 |
--------------------------------------------------------------------------------
/packages/repo/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './block-map'
2 | export * from './cid-set'
3 | export * from './repo'
4 | export * from './mst'
5 | export * from './parse'
6 | export * from './storage'
7 | export * from './sync'
8 | export * from './types'
9 | export * from './data-diff'
10 | export * from './car'
11 | export * from './util'
12 |
--------------------------------------------------------------------------------
/services/pds/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plc-service",
3 | "private": true,
4 | "packageManager": "pnpm@8.15.9",
5 | "dependencies": {
6 | "@atproto/pds": "workspace:^",
7 | "@opentelemetry/instrumentation": "^0.45.0",
8 | "dd-trace": "^4.18.0",
9 | "opentelemetry-plugin-better-sqlite3": "^1.1.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bsky/src/util/debug.ts:
--------------------------------------------------------------------------------
1 | export const debugCatch = any>(fn: Func) => {
2 | return async (...args: Parameters) => {
3 | try {
4 | return (await fn(...args)) as Awaited>
5 | } catch (err) {
6 | console.error(err)
7 | throw err
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/bsync/src/db/migrations/provider.ts:
--------------------------------------------------------------------------------
1 | import { Migration, MigrationProvider } from 'kysely'
2 |
3 | export class DbMigrationProvider implements MigrationProvider {
4 | constructor(private migrations: Record) {}
5 | async getMigrations(): Promise> {
6 | return this.migrations
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/src/locales/load.ts:
--------------------------------------------------------------------------------
1 | import { Messages } from '@lingui/core'
2 |
3 | // @NOTE run "pnpm run po:compile" to compile the messages from the PO files
4 |
5 | export async function loadMessages(locale: string): Promise {
6 | const { messages } = await import(`./${locale}/messages.ts`)
7 | return messages
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/tsconfig.src.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "../../../tsconfig/browser.json",
4 | "../../../tsconfig/bundler.json"
5 | ],
6 | "compilerOptions": {
7 | "rootDir": "src",
8 | "paths": {
9 | "#/*": ["./src/*"]
10 | }
11 | },
12 | "include": ["src/**/*.ts", "src/**/*.tsx"]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/schema/job_cursor.ts:
--------------------------------------------------------------------------------
1 | import { Generated } from 'kysely'
2 |
3 | export const jobCursorTableName = 'job_cursor'
4 |
5 | export interface JobCursor {
6 | job: string
7 | cursor: string | null
8 | updatedAt: Generated
9 | }
10 |
11 | export type PartialDB = {
12 | [jobCursorTableName]: JobCursor
13 | }
14 |
--------------------------------------------------------------------------------
/packages/pds/src/api/index.ts:
--------------------------------------------------------------------------------
1 | import { AppContext } from '../context'
2 | import { Server } from '../lexicon'
3 | import appBsky from './app/bsky'
4 | import comAtproto from './com/atproto'
5 |
6 | export default function (server: Server, ctx: AppContext) {
7 | comAtproto(server, ctx)
8 | appBsky(server, ctx)
9 | return server
10 | }
11 |
--------------------------------------------------------------------------------
/packages/pds/src/util/debug.ts:
--------------------------------------------------------------------------------
1 | export const debugCatch = any>(fn: Func) => {
2 | return async (...args: Parameters) => {
3 | try {
4 | return (await fn(...args)) as Awaited>
5 | } catch (err) {
6 | console.error(err)
7 | throw err
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/src/lib/use-bsky-client.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react'
2 | import { Agent } from '@atproto/api'
3 | import { useOAuthSession } from '../providers/OAuthProvider.tsx'
4 |
5 | export function useBskyClient() {
6 | const session = useOAuthSession()
7 | return useMemo(() => new Agent(session), [session])
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | OAuth mock pages
7 |
8 |
9 | My Account
10 |
11 |
12 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/tsconfig.src.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "../../../tsconfig/browser.json",
4 | "../../../tsconfig/bundler.json"
5 | ],
6 | "compilerOptions": {
7 | "rootDir": "src",
8 | "paths": {
9 | "#/*": ["./src/*"]
10 | }
11 | },
12 | "include": ["src/**/*.ts", "src/**/*.tsx"]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/notification-push-token.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'notification_push_token'
2 |
3 | export interface NotificationPushToken {
4 | did: string
5 | platform: 'ios' | 'android' | 'web'
6 | token: string
7 | appId: string
8 | }
9 |
10 | export type PartialDB = { [tableName]: NotificationPushToken }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/components/forms/Item.tsx:
--------------------------------------------------------------------------------
1 | import { clsx } from 'clsx'
2 | import { ReactNode } from 'react'
3 |
4 | export function Item({
5 | children,
6 | className,
7 | }: {
8 | children: ReactNode
9 | className?: string
10 | }) {
11 | return {children}
12 | }
13 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/identity/requestPlcOperationSignature.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.identity.requestPlcOperationSignature",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "description": "Request an email with a code to in order to request a signed PLC operation. Requires Auth."
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/bsync/src/db/schema/notif_item.ts:
--------------------------------------------------------------------------------
1 | import { Selectable } from 'kysely'
2 |
3 | export interface NotifItem {
4 | actorDid: string
5 | priority: boolean
6 | fromId: number
7 | }
8 |
9 | export type NotifItemEntry = Selectable
10 |
11 | export const tableName = 'notif_item'
12 |
13 | export type PartialDB = { [tableName]: NotifItem }
14 |
--------------------------------------------------------------------------------
/packages/common/src/buffers.ts:
--------------------------------------------------------------------------------
1 | export function ui8ToBuffer(bytes: Uint8Array): Buffer {
2 | return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)
3 | }
4 |
5 | export function ui8ToArrayBuffer(bytes: Uint8Array): ArrayBuffer {
6 | return bytes.buffer.slice(
7 | bytes.byteOffset,
8 | bytes.byteLength + bytes.byteOffset,
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/packages/dev-env/src/env.ts:
--------------------------------------------------------------------------------
1 | // NOTE: this file should be imported first, particularly before `@atproto/common` (for logging), to ensure that environment variables are respected in library code
2 | import dotenv from 'dotenv'
3 |
4 | const env = process.env.ENV
5 | if (env) {
6 | dotenv.config({ path: `./.${env}.env` })
7 | } else {
8 | dotenv.config()
9 | }
10 |
--------------------------------------------------------------------------------
/packages/dev-infra/with-test-redis-and-db.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # Example usage:
4 | # ./with-test-redis-and-db.sh psql postgresql://pg:password@localhost:5433/postgres -c 'select 1;'
5 | # ./with-test-redis-and-db.sh redis-cli -h localhost -p 6380 ping
6 |
7 | dir=$(dirname $0)
8 | . ${dir}/_common.sh
9 |
10 | SERVICES="db_test redis_test" main "$@"
11 |
--------------------------------------------------------------------------------
/packages/identity/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Identity',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | transformIgnorePatterns: ['/node_modules/.pnpm/(?!(get-port)@)'],
6 | setupFiles: ['/../../jest.setup.ts'],
7 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
8 | }
9 |
--------------------------------------------------------------------------------
/lexicons/tools/ozone/signature/defs.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "tools.ozone.signature.defs",
4 | "defs": {
5 | "sigDetail": {
6 | "type": "object",
7 | "required": ["property", "value"],
8 | "properties": {
9 | "property": { "type": "string" },
10 | "value": { "type": "string" }
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/api/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'API',
4 | transform: { '^.+\\.ts$': '@swc/jest' },
5 | testTimeout: 60000,
6 | setupFiles: ['/../../jest.setup.ts'],
7 | setupFilesAfterEnv: ['/jest.setup.ts'],
8 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/api/external.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'express'
2 | import { AppContext } from '../context'
3 | import * as kwsApi from './kws'
4 |
5 | export const createRouter = (ctx: AppContext): Router => {
6 | const router = Router()
7 |
8 | if (ctx.kwsClient) {
9 | router.use('/kws', kwsApi.createRouter(ctx))
10 | }
11 |
12 | return router
13 | }
14 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/private-data.ts:
--------------------------------------------------------------------------------
1 | export interface PrivateData {
2 | actorDid: string
3 | namespace: string
4 | key: string
5 | // JSON-encoded
6 | payload: string
7 | indexedAt: string
8 | updatedAt: string
9 | }
10 |
11 | export const tableName = 'private_data'
12 |
13 | export type PartialDB = { [tableName]: PrivateData }
14 |
--------------------------------------------------------------------------------
/packages/xrpc-server/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'XRPC Server',
4 | transform: { '^.+\\.(j|t)s$': '@swc/jest' },
5 | transformIgnorePatterns: ['/node_modules/.pnpm/(?!(get-port)@)'],
6 | setupFiles: ['/../../jest.setup.ts'],
7 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
8 | }
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
3 | "changelog": ["@changesets/changelog-github", { "repo": "bluesky-social/atproto" }],
4 | "commit": false,
5 | "fixed": [],
6 | "linked": [],
7 | "access": "public",
8 | "baseBranch": "main",
9 | "updateInternalDependencies": "patch",
10 | "ignore": []
11 | }
12 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/server/activateAccount.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.server.activateAccount",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "description": "Activates a currently deactivated account. Used to finalize account migration after the account's repo is imported and identity is setup."
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/bsync/src/db/schema/mute_item.ts:
--------------------------------------------------------------------------------
1 | import { Selectable } from 'kysely'
2 |
3 | export interface MuteItem {
4 | actorDid: string
5 | subject: string // did or aturi for list
6 | fromId: number
7 | }
8 |
9 | export type MuteItemEntry = Selectable
10 |
11 | export const tableName = 'mute_item'
12 |
13 | export type PartialDB = { [tableName]: MuteItem }
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser/src/index.ts:
--------------------------------------------------------------------------------
1 | import 'core-js/modules/esnext.symbol.async-dispose'
2 | import 'core-js/modules/esnext.symbol.dispose'
3 |
4 | export * from '@atproto/jwk-webcrypto'
5 | export * from '@atproto/oauth-client'
6 |
7 | export * from './browser-oauth-client.js'
8 | export * from './errors.js'
9 | export { buildLoopbackClientId } from './util.js'
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/http/index.ts:
--------------------------------------------------------------------------------
1 | export * from './accept.js'
2 | export * from './context.js'
3 | export * from './headers.js'
4 | export * from './middleware.js'
5 | export * from './parser.js'
6 | export * from './request.js'
7 | export * from './response.js'
8 | export * from './router.js'
9 | export * from './stream.js'
10 | export * from './types.js'
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-client-credentials-grant-token-request.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthClientCredentialsGrantTokenRequestSchema = z.object({
4 | grant_type: z.literal('client_credentials'),
5 | })
6 |
7 | export type OAuthClientCredentialsGrantTokenRequest = z.infer<
8 | typeof oauthClientCredentialsGrantTokenRequestSchema
9 | >
10 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/schema/firehose_cursor.ts:
--------------------------------------------------------------------------------
1 | import { Generated } from 'kysely'
2 |
3 | export const firehoseCursorTableName = 'firehose_cursor'
4 |
5 | export interface FirehoseCursor {
6 | service: string
7 | cursor: number | null
8 | updatedAt: Generated
9 | }
10 |
11 | export type PartialDB = {
12 | [firehoseCursorTableName]: FirehoseCursor
13 | }
14 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/schema/blob.ts:
--------------------------------------------------------------------------------
1 | export interface Blob {
2 | cid: string
3 | mimeType: string
4 | size: number
5 | tempKey: string | null
6 | width: number | null
7 | height: number | null
8 | createdAt: string
9 | takedownRef: string | null
10 | }
11 |
12 | export const tableName = 'blob'
13 |
14 | export type PartialDB = { [tableName]: Blob }
15 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/repo/defs.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.repo.defs",
4 | "defs": {
5 | "commitMeta": {
6 | "type": "object",
7 | "required": ["cid", "rev"],
8 | "properties": {
9 | "cid": { "type": "string", "format": "cid" },
10 | "rev": { "type": "string", "format": "tid" }
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/tailwind.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ['./src/**/*.{js,ts,jsx,tsx}'],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | // See rollup.config.js for classes used in the HTML template
9 | safelist: ['bg-slate-100', 'dark:bg-slate-800', 'min-h-screen'],
10 | }
11 |
--------------------------------------------------------------------------------
/packages/pds/src/mailer/templates.ts:
--------------------------------------------------------------------------------
1 | export { default as resetPassword } from './templates/reset-password'
2 | export { default as deleteAccount } from './templates/delete-account'
3 | export { default as confirmEmail } from './templates/confirm-email'
4 | export { default as updateEmail } from './templates/update-email'
5 | export { default as plcOperation } from './templates/plc-operation'
6 |
--------------------------------------------------------------------------------
/lexicons/chat/bsky/actor/deleteAccount.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "chat.bsky.actor.deleteAccount",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "output": {
8 | "encoding": "application/json",
9 | "schema": {
10 | "type": "object",
11 | "properties": {}
12 | }
13 | }
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/router/middleware-options.ts:
--------------------------------------------------------------------------------
1 | import type { IncomingMessage, ServerResponse } from 'node:http'
2 | import type { ErrorHandler } from './error-handler.js'
3 |
4 | export type MiddlewareOptions<
5 | Req extends IncomingMessage = IncomingMessage,
6 | Res extends ServerResponse = ServerResponse,
7 | > = {
8 | onError?: ErrorHandler
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-password-grant-token-request.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthPasswordGrantTokenRequestSchema = z.object({
4 | grant_type: z.literal('password'),
5 | username: z.string(),
6 | password: z.string(),
7 | })
8 |
9 | export type OAuthPasswordGrantTokenRequest = z.infer<
10 | typeof oauthPasswordGrantTokenRequestSchema
11 | >
12 |
--------------------------------------------------------------------------------
/packages/xrpc-server/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './auth'
2 | export * from './errors'
3 | export * from './rate-limiter'
4 | export * from './server'
5 | export * from './stream'
6 | export * from './types'
7 |
8 | export {
9 | ServerTimer,
10 | parseReqEncoding,
11 | parseReqNsid,
12 | serverTimingHeader,
13 | } from './util'
14 | export type { ServerTiming } from './util'
15 |
--------------------------------------------------------------------------------
/packages/common-web/src/index.ts:
--------------------------------------------------------------------------------
1 | export * as check from './check'
2 | export * as util from './util'
3 |
4 | export * from './arrays'
5 | export * from './async'
6 | export * from './util'
7 | export * from './tid'
8 | export * from './ipld'
9 | export * from './retry'
10 | export * from './types'
11 | export * from './times'
12 | export * from './strings'
13 | export * from './did-doc'
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/device/device-data.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 | import { sessionIdSchema } from './session-id.js'
3 |
4 | export const deviceDataSchema = z.object({
5 | sessionId: sessionIdSchema,
6 | lastSeenAt: z.date(),
7 | userAgent: z.string().nullable(),
8 | ipAddress: z.string(),
9 | })
10 |
11 | export type DeviceData = z.infer
12 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/errors/invalid-invite-code-error.ts:
--------------------------------------------------------------------------------
1 | import { InvalidRequestError } from './invalid-request-error'
2 |
3 | export class InvalidInviteCodeError extends InvalidRequestError {
4 | constructor(details?: string, cause?: unknown) {
5 | super(
6 | 'This invite code is invalid.' + (details ? ` ${details}` : ''),
7 | cause,
8 | )
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-authorization-request-uri.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 | import { oauthRequestUriSchema } from './oauth-request-uri.js'
3 |
4 | export const oauthAuthorizationRequestUriSchema = z.object({
5 | request_uri: oauthRequestUriSchema,
6 | })
7 |
8 | export type OAuthAuthorizationRequestUri = z.infer<
9 | typeof oauthAuthorizationRequestUriSchema
10 | >
11 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/db/schema/record.ts:
--------------------------------------------------------------------------------
1 | // @NOTE also used by app-view (moderation)
2 | export interface Record {
3 | uri: string
4 | cid: string
5 | collection: string
6 | rkey: string
7 | repoRev: string
8 | indexedAt: string
9 | takedownRef: string | null
10 | }
11 |
12 | export const tableName = 'record'
13 |
14 | export type PartialDB = { [tableName]: Record }
15 |
--------------------------------------------------------------------------------
/tsconfig/expo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": ["./browser.json"],
4 | "compilerOptions": {
5 | "jsx": "react-native",
6 | "target": "ES2023",
7 | "module": "ESNext",
8 | "moduleResolution": "Bundler",
9 | "moduleDetection": "force",
10 | "esModuleInterop": true,
11 |
12 | "skipLibCheck": true
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/repo/importRepo.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.repo.importRepo",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "description": "Import a repo in the form of a CAR file. Requires Content-Length HTTP header to be set.",
8 | "input": {
9 | "encoding": "application/vnd.ipld.car"
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/profile-agg.ts:
--------------------------------------------------------------------------------
1 | import { Generated } from 'kysely'
2 |
3 | export const tableName = 'profile_agg'
4 |
5 | export interface ProfileAgg {
6 | did: string
7 | followersCount: Generated
8 | followsCount: Generated
9 | postsCount: Generated
10 | }
11 |
12 | export type PartialDB = {
13 | [tableName]: ProfileAgg
14 | }
15 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/data/useHydrationData.ts:
--------------------------------------------------------------------------------
1 | import type { HydrationData } from '../hydration-data.d.ts'
2 |
3 | const hydrationData = window as typeof window & HydrationData['account-page']
4 |
5 | export function useHydrationData(
6 | key: T,
7 | ): HydrationData['account-page'][T] {
8 | return hydrationData[key]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/util/sanitizeHandle.ts:
--------------------------------------------------------------------------------
1 | export function isInvalidHandle(handle: string): boolean {
2 | return handle === 'handle.invalid'
3 | }
4 |
5 | export function sanitizeHandle(handle?: string): string | undefined {
6 | if (!handle) return undefined
7 | return isInvalidHandle(handle)
8 | ? '⚠Invalid Handle'
9 | : `@${handle.replace(/^@/, '')}`
10 | }
11 |
--------------------------------------------------------------------------------
/packages/pds/src/api/app/bsky/index.ts:
--------------------------------------------------------------------------------
1 | import { AppContext } from '../../../context'
2 | import { Server } from '../../../lexicon'
3 | import actor from './actor'
4 | import feed from './feed'
5 | import notification from './notification'
6 |
7 | export default function (server: Server, ctx: AppContext) {
8 | actor(server, ctx)
9 | feed(server, ctx)
10 | notification(server, ctx)
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/labeler.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'labeler'
4 |
5 | export interface Labeler {
6 | uri: string
7 | cid: string
8 | creator: string
9 | createdAt: string
10 | indexedAt: string
11 | sortAt: GeneratedAlways
12 | }
13 |
14 | export type PartialDB = {
15 | [tableName]: Labeler
16 | }
17 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/quote.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | const tableName = 'quote'
4 |
5 | export interface Quote {
6 | uri: string
7 | cid: string
8 | subject: string
9 | subjectCid: string
10 | createdAt: string
11 | indexedAt: string
12 | sortAt: GeneratedAlways
13 | }
14 |
15 | export type PartialDB = { [tableName]: Quote }
16 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-expo/src/expo-oauth-client-interface.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | AuthorizeOptions,
3 | OAuthClient,
4 | OAuthSession,
5 | } from '@atproto/oauth-client'
6 |
7 | export interface ExpoOAuthClientInterface extends OAuthClient, Disposable {
8 | signIn(input: string, options?: AuthorizeOptions): Promise
9 | handleCallback(): Promise
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/client/client-info.ts:
--------------------------------------------------------------------------------
1 | export type ClientInfo = {
2 | /**
3 | * Defaults to `false`
4 | */
5 | isFirstParty: boolean
6 |
7 | /**
8 | * Defaults to `true` if the client is isFirstParty, or if the client was
9 | * loaded from the store. (i.e. false in case of "loopback" & "discoverable"
10 | * clients)
11 | */
12 | isTrusted: boolean
13 | }
14 |
--------------------------------------------------------------------------------
/packages/ozone/src/api/chat/index.ts:
--------------------------------------------------------------------------------
1 | import { AppContext } from '../../context'
2 | import { Server } from '../../lexicon'
3 | import getActorMetadata from './getActorMetadata'
4 | import getMessageContext from './getMessageContext'
5 |
6 | export default function (server: Server, ctx: AppContext) {
7 | getActorMetadata(server, ctx)
8 | getMessageContext(server, ctx)
9 | return server
10 | }
11 |
--------------------------------------------------------------------------------
/packages/pds/src/util/params.ts:
--------------------------------------------------------------------------------
1 | import { CID } from 'multiformats/cid'
2 | import { InvalidRequestError } from '@atproto/xrpc-server'
3 |
4 | export const parseCidParam = (cid: string): CID => {
5 | try {
6 | return CID.parse(cid)
7 | } catch (err) {
8 | if (err instanceof SyntaxError) {
9 | throw new InvalidRequestError('Invalid cid')
10 | }
11 | throw err
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/bsky/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Bsky App View',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | transformIgnorePatterns: ['/node_modules/.pnpm/(?!(get-port)@)'],
6 | testTimeout: 60000,
7 | setupFiles: ['/../../jest.setup.ts'],
8 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/activity-subscription.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'activity_subscription'
2 | export interface ActivitySubscription {
3 | creator: string
4 | subjectDid: string
5 | // key from the bsync stash.
6 | key: string
7 | indexedAt: string
8 | post: boolean
9 | reply: boolean
10 | }
11 |
12 | export type PartialDB = { [tableName]: ActivitySubscription }
13 |
--------------------------------------------------------------------------------
/packages/internal/handle-resolver/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './handle-resolver-error.js'
2 | export * from './types.js'
3 |
4 | // Main Handle Resolvers strategies
5 | export * from './xrpc-handle-resolver.js'
6 | export * from './atproto-doh-handle-resolver.js'
7 | export * from './atproto-handle-resolver.js'
8 |
9 | // Handle Resolver Caching utility
10 | export * from './cached-handle-resolver.js'
11 |
--------------------------------------------------------------------------------
/packages/internal/pipe/src/type.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Generic, potentially async, function. Parametrized for convenience reasons.
3 | */
4 | export type Fn = (
5 | ...args: A
6 | ) => O | PromiseLike
7 |
8 | /**
9 | * Single input, single output, potentially async transformer function.
10 | */
11 | export type Transformer = (...args: [I]) => O | PromiseLike
12 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/components/forms/Fieldset.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react'
2 |
3 | export function Fieldset({
4 | children,
5 | label,
6 | }: {
7 | children: ReactNode
8 | label: string
9 | }) {
10 | return (
11 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/schema/account_strike.ts:
--------------------------------------------------------------------------------
1 | export const accountStrikeTableName = 'account_strike'
2 |
3 | export interface AccountStrike {
4 | did: string // Primary key
5 | firstStrikeAt: string | null
6 | lastStrikeAt: string | null
7 | activeStrikeCount: number
8 | totalStrikeCount: number
9 | }
10 |
11 | export type PartialDB = {
12 | [accountStrikeTableName]: AccountStrike
13 | }
14 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/follow.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'follow'
4 |
5 | export interface Follow {
6 | uri: string
7 | cid: string
8 | creator: string
9 | subjectDid: string
10 | createdAt: string
11 | indexedAt: string
12 | sortAt: GeneratedAlways
13 | }
14 |
15 | export type PartialDB = { [tableName]: Follow }
16 |
--------------------------------------------------------------------------------
/packages/crypto/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './const'
2 | export * from './did'
3 | export * from './multibase'
4 | export * from './random'
5 | export * from './sha'
6 | export * from './types'
7 | export * from './verify'
8 | export * from './utils'
9 |
10 | export * from './p256/keypair'
11 | export * from './p256/plugin'
12 |
13 | export * from './secp256k1/keypair'
14 | export * from './secp256k1/plugin'
15 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/result/authorization-result-redirect.ts:
--------------------------------------------------------------------------------
1 | import { OAuthAuthorizationRequestParameters } from '@atproto/oauth-types'
2 | import { AuthorizationRedirectParameters } from './authorization-redirect-parameters.js'
3 |
4 | export type AuthorizationResultRedirect = {
5 | issuer: string
6 | parameters: OAuthAuthorizationRequestParameters
7 | redirect: AuthorizationRedirectParameters
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/util/upsert.ts:
--------------------------------------------------------------------------------
1 | export function upsert(
2 | arr: undefined | readonly T[],
3 | item: T,
4 | predicate: (value: T, index: number, obj: readonly T[]) => boolean,
5 | ): T[] {
6 | if (!arr) return [item]
7 | const idx = arr.findIndex(predicate)
8 | return idx === -1
9 | ? [...arr, item]
10 | : [...arr.slice(0, idx), item, ...arr.slice(idx + 1)]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/src/lib/resource-permission.ts:
--------------------------------------------------------------------------------
1 | import { ScopeStringFor } from './syntax.js'
2 | import { Matchable } from './util.js'
3 |
4 | /**
5 | * Interface destined to provide consistency across parsed permission scopes for
6 | * resources (blob, repo, etc.).
7 | */
8 | export interface ResourcePermission extends Matchable {
9 | toString(): ScopeStringFor
10 | }
11 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/account-device.ts:
--------------------------------------------------------------------------------
1 | import { DeviceId } from '@atproto/oauth-provider'
2 | import { DateISO } from '../../../db'
3 |
4 | export interface AccountDevice {
5 | did: string
6 | deviceId: DeviceId
7 |
8 | createdAt: DateISO
9 | updatedAt: DateISO
10 | }
11 |
12 | export const tableName = 'account_device'
13 |
14 | export type PartialDB = { [tableName]: AccountDevice }
15 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230620T161134972Z-post-langs.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema.alterTable('post').addColumn('langs', 'jsonb').execute()
5 | }
6 |
7 | export async function down(db: Kysely): Promise {
8 | await db.schema.alterTable('post').dropColumn('langs').execute()
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/actor-block.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'actor_block'
4 | export interface ActorBlock {
5 | uri: string
6 | cid: string
7 | creator: string
8 | subjectDid: string
9 | createdAt: string
10 | indexedAt: string
11 | sortAt: GeneratedAlways
12 | }
13 |
14 | export type PartialDB = { [tableName]: ActorBlock }
15 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | OAuth mock pages
7 |
8 |
9 | authorization-page
10 |
11 | error-page
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-endpoint-auth-method.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthEndpointAuthMethod = z.enum([
4 | 'client_secret_basic',
5 | 'client_secret_jwt',
6 | 'client_secret_post',
7 | 'none',
8 | 'private_key_jwt',
9 | 'self_signed_tls_client_auth',
10 | 'tls_client_auth',
11 | ])
12 |
13 | export type OauthEndpointAuthMethod = z.infer
14 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230920T213858047Z-add-tags-to-post.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema.alterTable('post').addColumn('tags', 'jsonb').execute()
5 | }
6 |
7 | export async function down(db: Kysely): Promise {
8 | await db.schema.alterTable('post').dropColumn('tags').execute()
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20250207T174822012Z-add-label-exp.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema.alterTable('label').addColumn('exp', 'varchar').execute()
5 | }
6 |
7 | export async function down(db: Kysely): Promise {
8 | await db.schema.alterTable('label').dropColumn('exp').execute()
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/list-block.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'list_block'
4 |
5 | export interface ListBlock {
6 | uri: string
7 | cid: string
8 | creator: string
9 | subjectUri: string
10 | createdAt: string
11 | indexedAt: string
12 | sortAt: GeneratedAlways
13 | }
14 |
15 | export type PartialDB = { [tableName]: ListBlock }
16 |
--------------------------------------------------------------------------------
/packages/internal/simple-store-redis/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @atproto-labs/simple-store-redis
2 |
3 | ## 0.0.1
4 |
5 | ### Patch Changes
6 |
7 | - [#4149](https://github.com/bluesky-social/atproto/pull/4149) [`8914f9abd`](https://github.com/bluesky-social/atproto/commit/8914f9abde2059c551d7e4c8d104227986098b82) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Initial implementation of redis based `SimpleStore` implementation
8 |
--------------------------------------------------------------------------------
/packages/bsky/src/api/com/atproto/temp/fetchLabels.ts:
--------------------------------------------------------------------------------
1 | import { InvalidRequestError } from '@atproto/xrpc-server'
2 | import { AppContext } from '../../../../context'
3 | import { Server } from '../../../../lexicon'
4 |
5 | export default function (server: Server, _ctx: AppContext) {
6 | server.com.atproto.temp.fetchLabels(async (_reqCtx) => {
7 | throw new InvalidRequestError('not implemented on dataplane')
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20250528T221913281Z-add-record-tags.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema.alterTable('record').addColumn('tags', 'jsonb').execute()
5 | }
6 |
7 | export async function down(db: Kysely): Promise {
8 | await db.schema.alterTable('record').dropColumn('tags').execute()
9 | }
10 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/src/queries/use-get-token-info-query.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import { useOAuthSession } from '../providers/OAuthProvider.tsx'
3 |
4 | export function useGetTokenInfoQuery() {
5 | const session = useOAuthSession()
6 | return useQuery({
7 | queryKey: ['tokenInfo', session.did],
8 | queryFn: async () => session.getTokenInfo(true),
9 | })
10 | }
11 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/util/locale.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const localeSchema = z
4 | .string()
5 | .regex(/^[a-z]{2,3}(-[A-Z]{2})?$/, 'Invalid locale')
6 | export type Locale = z.infer
7 |
8 | export const multiLangStringSchema = z.record(
9 | localeSchema,
10 | z.string().optional(),
11 | )
12 | export type MultiLangString = z.infer
13 |
--------------------------------------------------------------------------------
/packages/ozone/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'Ozone',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | transformIgnorePatterns: [
6 | `/node_modules/.pnpm/(?!(get-port|lande|toygrad)@)`,
7 | ],
8 | testTimeout: 60000,
9 | setupFiles: ['/../../jest.setup.ts'],
10 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
11 | }
12 |
--------------------------------------------------------------------------------
/packages/ozone/src/communication-service/util.ts:
--------------------------------------------------------------------------------
1 | // Postgresql will throw a specific error code with the constraint when trying to create a template with duplicate name
2 | // see https://www.postgresql.org/docs/current/errcodes-appendix.html
3 | export const isDuplicateTemplateNameError = (err: any) => {
4 | return (
5 | err?.['code'] === '23505' &&
6 | err?.['constraint'] === 'communication_template_unique_name'
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser/src/errors.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Special error class destined to be thrown when the login process was
3 | * performed in a popup and should be continued in the parent/initiating window.
4 | */
5 | export class LoginContinuedInParentWindowError extends Error {
6 | code = 'LOGIN_CONTINUED_IN_PARENT_WINDOW'
7 | constructor() {
8 | super('Login complete, please close the popup window.')
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/ozone/src/scheduled-action/types.ts:
--------------------------------------------------------------------------------
1 | import { ScheduledActionType } from '../api/util'
2 |
3 | export type ExecutionSchedule =
4 | | {
5 | executeAt: Date
6 | }
7 | | {
8 | executeAfter: Date
9 | executeUntil?: Date
10 | }
11 |
12 | export type SchedulingParams = {
13 | action: ScheduledActionType
14 | eventData: unknown
15 | did: string
16 | createdBy: string
17 | } & ExecutionSchedule
18 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/record.ts:
--------------------------------------------------------------------------------
1 | import { ColumnType } from 'kysely'
2 |
3 | export interface Record {
4 | uri: string
5 | cid: string
6 | did: string
7 | json: string
8 | indexedAt: string
9 | takedownRef: string | null
10 | tags: ColumnType | null
11 | }
12 |
13 | export const tableName = 'record'
14 |
15 | export type PartialDB = { [tableName]: Record }
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/starter-pack.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'starter_pack'
4 |
5 | export interface StarterPack {
6 | uri: string
7 | cid: string
8 | creator: string
9 | name: string
10 | createdAt: string
11 | indexedAt: string
12 | sortAt: GeneratedAlways
13 | }
14 |
15 | export type PartialDB = {
16 | [tableName]: StarterPack
17 | }
18 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser/src/indexed-db/README.md:
--------------------------------------------------------------------------------
1 | # IndexedDB utilities
2 |
3 | This is a small wrapper around the IndexedDB API that provides a simple way to
4 | store and retrieve data from an IndexedDB database.
5 |
6 | This _could_ be used as a standalone library, but the Bluesky dev team does not
7 | want to maintain it as such. As it is currently only used by the
8 | `@atproto/oauth-client-browser` package, it is included here.
9 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/list-item.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'list_item'
4 |
5 | export interface ListItem {
6 | uri: string
7 | cid: string
8 | creator: string
9 | subjectDid: string
10 | listUri: string
11 | createdAt: string
12 | indexedAt: string
13 | sortAt: GeneratedAlways
14 | }
15 |
16 | export type PartialDB = { [tableName]: ListItem }
17 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/util/ui8.ts:
--------------------------------------------------------------------------------
1 | export function parseUi8Hex(v: string) {
2 | return asUi8(parseInt(v, 16))
3 | }
4 |
5 | export function parseUi8Dec(v: string) {
6 | return asUi8(parseInt(v, 10))
7 | }
8 |
9 | export function asUi8(v: number) {
10 | if (v >= 0 && v <= 255 && Number.isInteger(v)) return v
11 | throw new TypeError(
12 | `Invalid value "${v}" (expected an integer between 0 and 255)`,
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/repo/strongRef.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.repo.strongRef",
4 | "description": "A URI with a content-hash fingerprint.",
5 | "defs": {
6 | "main": {
7 | "type": "object",
8 | "required": ["uri", "cid"],
9 | "properties": {
10 | "uri": { "type": "string", "format": "at-uri" },
11 | "cid": { "type": "string", "format": "cid" }
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/notification.ts:
--------------------------------------------------------------------------------
1 | import { Generated } from 'kysely'
2 |
3 | export const tableName = 'notification'
4 |
5 | export interface Notification {
6 | id: Generated
7 | did: string
8 | recordUri: string
9 | recordCid: string
10 | author: string
11 | reason: string
12 | reasonSubject: string | null
13 | sortAt: string
14 | }
15 |
16 | export type PartialDB = { [tableName]: Notification }
17 |
--------------------------------------------------------------------------------
/packages/ozone/src/image-invalidator.ts:
--------------------------------------------------------------------------------
1 | // Invalidation is a general interface for propagating an image blob
2 | // takedown through any caches where a representation of it may be stored.
3 | // @NOTE this does not remove the blob from storage: just invalidates it from caches.
4 | // @NOTE keep in sync with same interface in aws/src/cloudfront.ts
5 | export interface ImageInvalidator {
6 | invalidate(subject: string, paths: string[]): Promise
7 | }
8 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/account.ts:
--------------------------------------------------------------------------------
1 | import { Generated, Selectable } from 'kysely'
2 |
3 | export interface Account {
4 | did: string
5 | email: string
6 | passwordScrypt: string
7 | emailConfirmedAt: string | null
8 | invitesDisabled: Generated<0 | 1>
9 | }
10 |
11 | export type AccountEntry = Selectable
12 |
13 | export const tableName = 'account'
14 |
15 | export type PartialDB = { [tableName]: Account }
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/post-agg.ts:
--------------------------------------------------------------------------------
1 | import { Generated } from 'kysely'
2 |
3 | export const tableName = 'post_agg'
4 |
5 | export interface PostAgg {
6 | uri: string
7 | likeCount: Generated
8 | replyCount: Generated
9 | repostCount: Generated
10 | quoteCount: Generated
11 | bookmarkCount: Generated
12 | }
13 |
14 | export type PartialDB = {
15 | [tableName]: PostAgg
16 | }
17 |
--------------------------------------------------------------------------------
/packages/crypto/src/p256/plugin.ts:
--------------------------------------------------------------------------------
1 | import { P256_DID_PREFIX, P256_JWT_ALG } from '../const'
2 | import { DidKeyPlugin } from '../types'
3 | import { compressPubkey, decompressPubkey } from './encoding'
4 | import { verifyDidSig } from './operations'
5 |
6 | export const p256Plugin: DidKeyPlugin = {
7 | prefix: P256_DID_PREFIX,
8 | jwtAlg: P256_JWT_ALG,
9 | verifySignature: verifyDidSig,
10 |
11 | compressPubkey,
12 | decompressPubkey,
13 | }
14 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/actor.ts:
--------------------------------------------------------------------------------
1 | import { Selectable } from 'kysely'
2 |
3 | export interface Actor {
4 | did: string
5 | handle: string | null
6 | createdAt: string
7 | takedownRef: string | null
8 | deactivatedAt: string | null
9 | deleteAfter: string | null
10 | }
11 |
12 | export type ActorEntry = Selectable
13 |
14 | export const tableName = 'actor'
15 |
16 | export type PartialDB = { [tableName]: Actor }
17 |
--------------------------------------------------------------------------------
/packages/xrpc/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './client'
2 | export * from './fetch-handler'
3 | export * from './types'
4 | export * from './util'
5 | export * from './xrpc-client'
6 |
7 | /* eslint-disable import/no-deprecated */
8 | import { Client } from './client'
9 | /** @deprecated create a local {@link XrpcClient} instance instead */
10 | const defaultInst = new Client()
11 | export default defaultInst
12 | /* eslint-enable import/no-deprecated */
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-grant-type.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | export const oauthGrantTypeSchema = z.enum([
4 | 'authorization_code',
5 | 'implicit',
6 | 'refresh_token',
7 | 'password', // Not part of OAuth 2.1
8 | 'client_credentials',
9 | 'urn:ietf:params:oauth:grant-type:jwt-bearer',
10 | 'urn:ietf:params:oauth:grant-type:saml2-bearer',
11 | ])
12 |
13 | export type OAuthGrantType = z.infer
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-token-type.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | // Case insensitive input, normalized output
4 | export const oauthTokenTypeSchema = z.union([
5 | z
6 | .string()
7 | .regex(/^DPoP$/i)
8 | .transform(() => 'DPoP' as const),
9 | z
10 | .string()
11 | .regex(/^Bearer$/i)
12 | .transform(() => 'Bearer' as const),
13 | ])
14 |
15 | export type OAuthTokenType = z.infer
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230808T172902639Z-repo-rev.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('actor_sync')
6 | .addColumn('repoRev', 'varchar')
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema.alterTable('actor_sync').dropColumn('repoRev').execute()
12 | }
13 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/view-param.ts:
--------------------------------------------------------------------------------
1 | // @NOTE postgres-only
2 | export const tableName = 'view_param'
3 |
4 | // materialized views are difficult to change,
5 | // so we parameterize them at runtime with contents of this table.
6 | // its contents are set in migrations, available param names are static.
7 | export interface ViewParam {
8 | name: string
9 | value: string
10 | }
11 |
12 | export type PartialDB = { [tableName]: ViewParam }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oidc-claims-properties.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | const oidcClaimsValueSchema = z.union([z.string(), z.number(), z.boolean()])
4 |
5 | export const oidcClaimsPropertiesSchema = z.object({
6 | essential: z.boolean().optional(),
7 | value: oidcClaimsValueSchema.optional(),
8 | values: z.array(oidcClaimsValueSchema).optional(),
9 | })
10 |
11 | export type OidcClaimsProperties = z.infer
12 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/email-token.ts:
--------------------------------------------------------------------------------
1 | export type EmailTokenPurpose =
2 | | 'confirm_email'
3 | | 'update_email'
4 | | 'reset_password'
5 | | 'delete_account'
6 | | 'plc_operation'
7 |
8 | export interface EmailToken {
9 | purpose: EmailTokenPurpose
10 | did: string
11 | token: string
12 | requestedAt: string
13 | }
14 |
15 | export const tableName = 'email_token'
16 |
17 | export type PartialDB = { [tableName]: EmailToken }
18 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/used-refresh-token.ts:
--------------------------------------------------------------------------------
1 | import { Selectable } from 'kysely'
2 | import { RefreshToken } from '@atproto/oauth-provider'
3 |
4 | export interface UsedRefreshToken {
5 | tokenId: number
6 | refreshToken: RefreshToken
7 | }
8 |
9 | export type UsedRefreshTokenEntry = Selectable
10 |
11 | export const tableName = 'used_refresh_token'
12 |
13 | export type PartialDB = { [tableName]: UsedRefreshToken }
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 |
4 | # buf
5 | packages/bsky/src/proto
6 | packages/bsync/src/proto
7 |
8 | # codegen
9 | packages/api/src/client
10 | packages/lexicon-resolver/src/client
11 | packages/bsky/src/lexicon
12 | packages/pds/src/lexicon
13 | packages/ozone/src/lexicon
14 |
15 | # others
16 | packages/oauth/*/src/locales/*/messages.ts
17 | packages/oauth/oauth-provider-frontend/src/routeTree.gen.ts
18 | packages/oauth/oauth-client-expo/android/build
19 |
--------------------------------------------------------------------------------
/packages/bsync/src/db/types.ts:
--------------------------------------------------------------------------------
1 | import { DynamicModule, RawBuilder, SelectQueryBuilder } from 'kysely'
2 | import { Pool as PgPool } from 'pg'
3 |
4 | export type DbRef = RawBuilder | ReturnType
5 |
6 | export type AnyQb = SelectQueryBuilder
7 |
8 | export type PgOptions = {
9 | url: string
10 | pool?: PgPool
11 | schema?: string
12 | poolSize?: number
13 | poolMaxUses?: number
14 | poolIdleTimeoutMs?: number
15 | }
16 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/errors/invalid-dpop-proof-error.ts:
--------------------------------------------------------------------------------
1 | import { WWWAuthenticateError } from './www-authenticate-error.js'
2 |
3 | export class InvalidDpopProofError extends WWWAuthenticateError {
4 | constructor(error_description: string, cause?: unknown) {
5 | const error = 'invalid_dpop_proof'
6 | super(
7 | error,
8 | error_description,
9 | { DPoP: { error, error_description } },
10 | cause,
11 | )
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-types/src/oauth-refresh-token-grant-token-request.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 | import { oauthRefreshTokenSchema } from './oauth-refresh-token.js'
3 |
4 | export const oauthRefreshTokenGrantTokenRequestSchema = z.object({
5 | grant_type: z.literal('refresh_token'),
6 | refresh_token: oauthRefreshTokenSchema,
7 | })
8 |
9 | export type OAuthRefreshTokenGrantTokenRequest = z.infer<
10 | typeof oauthRefreshTokenGrantTokenRequestSchema
11 | >
12 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/migrations/20240903T205730722Z-add-template-lang.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('communication_template')
6 | .addColumn('lang', 'varchar')
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema.alterTable('moderation_event').dropColumn('lang').execute()
12 | }
13 |
--------------------------------------------------------------------------------
/packages/pds/src/util/compression.ts:
--------------------------------------------------------------------------------
1 | import compression from 'compression'
2 | import express from 'express'
3 |
4 | export default function () {
5 | return compression({
6 | filter,
7 | })
8 | }
9 |
10 | function filter(_req: express.Request, res: express.Response) {
11 | const contentType = res.getHeader('Content-type')
12 | if (contentType === 'application/vnd.ipld.car') {
13 | return true
14 | }
15 | return compression.filter(_req, res)
16 | }
17 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/like.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | const tableName = 'like'
4 |
5 | export interface Like {
6 | uri: string
7 | cid: string
8 | creator: string
9 | subject: string
10 | subjectCid: string
11 | via: string | null
12 | viaCid: string | null
13 | createdAt: string
14 | indexedAt: string
15 | sortAt: GeneratedAlways
16 | }
17 |
18 | export type PartialDB = { [tableName]: Like }
19 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/customization/links.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 | import { isLinkRel } from '../lib/html/build-document.js'
3 | import { multiLangStringSchema } from '../lib/util/locale.js'
4 |
5 | export const linksSchema = z.object({
6 | title: z.union([z.string(), multiLangStringSchema]),
7 | href: z.string().url(),
8 | rel: z.string().refine(isLinkRel, 'Invalid link rel').optional(),
9 | })
10 | export type Links = z.infer
11 |
--------------------------------------------------------------------------------
/packages/sync/src/util.ts:
--------------------------------------------------------------------------------
1 | import {
2 | RepoEvent,
3 | isAccount,
4 | isCommit,
5 | isIdentity,
6 | isSync,
7 | } from './firehose/lexicons'
8 |
9 | export const didAndSeqForEvt = (
10 | evt: RepoEvent,
11 | ): { did: string; seq: number } | undefined => {
12 | if (isCommit(evt)) return { seq: evt.seq, did: evt.repo }
13 | else if (isAccount(evt) || isIdentity(evt) || isSync(evt))
14 | return { seq: evt.seq, did: evt.did }
15 | return undefined
16 | }
17 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "tabWidth": 2,
4 | "semi": false,
5 | "singleQuote": true,
6 | "plugins": ["prettier-plugin-tailwindcss"],
7 | "overrides": [
8 | {
9 | "files": "*.hbs",
10 | "options": {
11 | "singleQuote": false
12 | }
13 | },
14 | {
15 | "files": [".eslintrc"],
16 | "options": {
17 | "parser": "json",
18 | "trailingComma": "none"
19 | }
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/packages/aws/src/util.ts:
--------------------------------------------------------------------------------
1 | import { allFulfilled } from '@atproto/common'
2 | import { ImageInvalidator } from './types'
3 |
4 | export class MultiImageInvalidator implements ImageInvalidator {
5 | constructor(public invalidators: ImageInvalidator[]) {}
6 | async invalidate(subject: string, paths: string[]) {
7 | await allFulfilled(
8 | this.invalidators.map((invalidator) =>
9 | invalidator.invalidate(subject, paths),
10 | ),
11 | )
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/ozone/src/config/secrets.ts:
--------------------------------------------------------------------------------
1 | import assert from 'node:assert'
2 | import { OzoneEnvironment } from './env'
3 |
4 | export const envToSecrets = (env: OzoneEnvironment): OzoneSecrets => {
5 | assert(env.adminPassword)
6 | assert(env.signingKeyHex)
7 |
8 | return {
9 | adminPassword: env.adminPassword,
10 | signingKeyHex: env.signingKeyHex,
11 | }
12 | }
13 |
14 | export type OzoneSecrets = {
15 | adminPassword: string
16 | signingKeyHex: string
17 | }
18 |
--------------------------------------------------------------------------------
/packages/pds/src/actor-store/preference/util.ts:
--------------------------------------------------------------------------------
1 | const FULL_ACCESS_ONLY_PREFS = new Set([
2 | 'app.bsky.actor.defs#personalDetailsPref',
3 | ])
4 |
5 | export type PrefAllowedOptions = {
6 | hasAccessFull?: boolean
7 | }
8 |
9 | export function prefAllowed(
10 | prefType: string,
11 | options?: PrefAllowedOptions,
12 | ): boolean {
13 | if (options?.hasAccessFull === true) {
14 | return true
15 | }
16 |
17 | return !FULL_ACCESS_ONLY_PREFS.has(prefType)
18 | }
19 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20240530T170337073Z-account-deactivation.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('actor')
6 | .addColumn('upstreamStatus', 'varchar')
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema.alterTable('actor').dropColumn('upstreamStatus').execute()
12 | }
13 |
--------------------------------------------------------------------------------
/packages/crypto/src/secp256k1/plugin.ts:
--------------------------------------------------------------------------------
1 | import { SECP256K1_DID_PREFIX, SECP256K1_JWT_ALG } from '../const'
2 | import { DidKeyPlugin } from '../types'
3 | import { compressPubkey, decompressPubkey } from './encoding'
4 | import { verifyDidSig } from './operations'
5 |
6 | export const secp256k1Plugin: DidKeyPlugin = {
7 | prefix: SECP256K1_DID_PREFIX,
8 | jwtAlg: SECP256K1_JWT_ALG,
9 | verifySignature: verifyDidSig,
10 |
11 | compressPubkey,
12 | decompressPubkey,
13 | }
14 |
--------------------------------------------------------------------------------
/packages/pds/tests/seeds/likes.ts:
--------------------------------------------------------------------------------
1 | import { SeedClient } from '@atproto/dev-env'
2 | import basicSeed from './basic'
3 |
4 | export default async (sc: SeedClient) => {
5 | await basicSeed(sc)
6 | await sc.createAccount('eve', {
7 | email: 'eve@test.com',
8 | handle: 'eve.test',
9 | password: 'eve-pass',
10 | })
11 | await sc.like(sc.dids.eve, sc.posts[sc.dids.alice][1].ref)
12 | await sc.like(sc.dids.carol, sc.replies[sc.dids.bob][0].ref)
13 | return sc
14 | }
15 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/repost.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'repost'
4 |
5 | export interface Repost {
6 | uri: string
7 | cid: string
8 | creator: string
9 | subject: string
10 | subjectCid: string
11 | via: string | null
12 | viaCid: string | null
13 | createdAt: string
14 | indexedAt: string
15 | sortAt: GeneratedAlways
16 | }
17 |
18 | export type PartialDB = { [tableName]: Repost }
19 |
--------------------------------------------------------------------------------
/packages/internal/did-resolver/src/did-method.ts:
--------------------------------------------------------------------------------
1 | import { Did, DidDocument } from '@atproto/did'
2 |
3 | export type ResolveDidOptions = {
4 | signal?: AbortSignal
5 | noCache?: boolean
6 | }
7 |
8 | export interface DidMethod {
9 | resolve: (
10 | did: Did,
11 | options?: ResolveDidOptions,
12 | ) => DidDocument | PromiseLike
13 | }
14 |
15 | export type DidMethods = {
16 | [K in M]: DidMethod
17 | }
18 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/hydration-data.d.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ActiveDeviceSession,
3 | CustomizationData,
4 | } from '@atproto/oauth-provider-api'
5 |
6 | export type HydrationData = {
7 | 'account-page': {
8 | /**
9 | * needed by `useCustomizationData.ts`
10 | */
11 | __customizationData: CustomizationData
12 | /**
13 | * needed by `useDeviceSessionsQuery.ts`
14 | */
15 | __deviceSessions: readonly ActiveDeviceSession[]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/locales/activateLocale.ts:
--------------------------------------------------------------------------------
1 | import { i18n } from '@lingui/core'
2 | import * as en from '#/locales/en/messages'
3 | import { Locale } from './locales'
4 |
5 | export async function activateLocale(locale: Locale) {
6 | const { messages } = await import(`./${locale}/messages.ts`).catch((e) => {
7 | console.error('Error loading locale', e)
8 | return en
9 | })
10 |
11 | i18n.load(locale, messages)
12 | i18n.activate(locale)
13 | }
14 |
--------------------------------------------------------------------------------
/packages/api/src/bsky-agent.ts:
--------------------------------------------------------------------------------
1 | import { AtpAgent } from './atp-agent'
2 |
3 | /** @deprecated use {@link AtpAgent} instead */
4 | export class BskyAgent extends AtpAgent {
5 | clone(): this {
6 | if (this.constructor === BskyAgent) {
7 | const agent = new BskyAgent(this.sessionManager)
8 | return this.copyInto(agent as this)
9 | }
10 |
11 | // sub-classes should override this method
12 | throw new TypeError('Cannot clone a subclass of BskyAgent')
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/bsky/src/error.ts:
--------------------------------------------------------------------------------
1 | import { ErrorRequestHandler } from 'express'
2 | import { XRPCError } from '@atproto/xrpc-server'
3 | import { httpLogger as log } from './logger'
4 |
5 | export const handler: ErrorRequestHandler = (err, _req, res, next) => {
6 | log.error({ err }, 'unexpected internal server error')
7 | if (res.headersSent) {
8 | return next(err)
9 | }
10 | const serverError = XRPCError.fromError(err)
11 | res.status(serverError.type).json(serverError.payload)
12 | }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client/src/state-store.ts:
--------------------------------------------------------------------------------
1 | import { Key } from '@atproto/jwk'
2 | import { SimpleStore } from '@atproto-labs/simple-store'
3 | import { ClientAuthMethod } from './oauth-client-auth.js'
4 |
5 | export type InternalStateData = {
6 | iss: string
7 | dpopKey: Key
8 | /** @note optional for legacy reasons */
9 | authMethod?: ClientAuthMethod
10 | verifier?: string
11 | appState?: string
12 | }
13 |
14 | export type StateStore = SimpleStore
15 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-scopes/src/scope-missing-error.ts:
--------------------------------------------------------------------------------
1 | export class ScopeMissingError extends Error {
2 | name = 'ScopeMissingError'
3 |
4 | // compatibility layer with http-errors package. The goal if to make
5 | // isHttpError(new ScopeMissingError) return true.
6 | status = 403
7 | expose = true
8 | get statusCode() {
9 | return this.status
10 | }
11 |
12 | constructor(public readonly scope: string) {
13 | super(`Missing required scope "${scope}"`)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/ozone/tests/__snapshots__/report-reason.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`report reason createReport only passes for allowed reason types 1`] = `
4 | Object {
5 | "createdAt": "1970-01-01T00:00:00.000Z",
6 | "id": 1,
7 | "reasonType": "tools.ozone.report.defs#reasonHarassmentTroll",
8 | "reportedBy": "user(0)",
9 | "subject": Object {
10 | "$type": "com.atproto.admin.defs#repoRef",
11 | "did": "user(1)",
12 | },
13 | }
14 | `;
15 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/lexicon.ts:
--------------------------------------------------------------------------------
1 | import type { LexiconDoc } from '@atproto/oauth-provider'
2 | import { DateISO, JsonEncoded } from '../../../db/cast'
3 |
4 | export interface Lexicon {
5 | nsid: string
6 | createdAt: DateISO
7 | updatedAt: DateISO
8 | lastSucceededAt: null | DateISO
9 | uri: null | string
10 | lexicon: null | JsonEncoded
11 | }
12 |
13 | export const tableName = 'lexicon'
14 |
15 | export type PartialDB = { [tableName]: Lexicon }
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/actor.ts:
--------------------------------------------------------------------------------
1 | import { Generated } from 'kysely'
2 |
3 | export interface Actor {
4 | did: string
5 | handle: string | null
6 | indexedAt: string
7 | takedownRef: string | null
8 | upstreamStatus: string | null
9 | trustedVerifier: Generated
10 | ageAssuranceStatus: string | null
11 | ageAssuranceLastInitiatedAt: string | null
12 | }
13 |
14 | export const tableName = 'actor'
15 |
16 | export type PartialDB = { [tableName]: Actor }
17 |
--------------------------------------------------------------------------------
/packages/ozone/src/error.ts:
--------------------------------------------------------------------------------
1 | import { ErrorRequestHandler } from 'express'
2 | import { XRPCError } from '@atproto/xrpc-server'
3 | import { httpLogger as log } from './logger'
4 |
5 | export const handler: ErrorRequestHandler = (err, _req, res, next) => {
6 | log.error({ err }, 'unexpected internal server error')
7 | if (res.headersSent) {
8 | return next(err)
9 | }
10 | const serverError = XRPCError.fromError(err)
11 | res.status(serverError.type).json(serverError.payload)
12 | }
13 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/migrations/20240814T003647759Z-event-created-at-index.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .createIndex('moderation_event_created_at_idx')
6 | .on('moderation_event')
7 | .column('createdAt')
8 | .execute()
9 | }
10 |
11 | export async function down(db: Kysely): Promise {
12 | await db.schema.dropIndex('moderation_event_created_at_idx').execute()
13 | }
14 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/migrations/20240904T205730722Z-add-subject-did-index.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .createIndex('moderation_event_subject_did_idx')
6 | .on('moderation_event')
7 | .column('subjectDid')
8 | .execute()
9 | }
10 |
11 | export async function down(db: Kysely): Promise {
12 | await db.schema.dropIndex('moderation_event_subject_did_idx').execute()
13 | }
14 |
--------------------------------------------------------------------------------
/packages/ozone/src/tag-service/util.ts:
--------------------------------------------------------------------------------
1 | import { ReasonType } from '../lexicon/types/com/atproto/moderation/defs'
2 |
3 | export const getTagForReport = (reasonType: ReasonType) => {
4 | const reasonWithoutPrefix = reasonType
5 | .replace('com.atproto.moderation.defs#reason', '')
6 | .replace('tools.ozone.report.defs#reason', '')
7 |
8 | const kebabCase = reasonWithoutPrefix
9 | .replace(/([a-z])([A-Z])/g, '$1-$2')
10 | .toLowerCase()
11 |
12 | return `report:${kebabCase}`
13 | }
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/src/queries/use-get-session-query.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import { useBskyClient } from '../lib/use-bsky-client.ts'
3 |
4 | export function useGetSessionQuery() {
5 | const client = useBskyClient()
6 |
7 | return useQuery({
8 | queryKey: ['session', client.assertDid],
9 | queryFn: async () => {
10 | const { data } = await client.com.atproto.server.getSession()
11 | return data
12 | },
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/migrations/003-privileged-app-passwords.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('app_password')
6 | .addColumn('privileged', 'integer', (col) => col.notNull().defaultTo(0))
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema.alterTable('app_password').dropColumn('privileged').execute()
12 | }
13 |
--------------------------------------------------------------------------------
/interop-test-files/syntax/atidentifier_syntax_invalid.txt:
--------------------------------------------------------------------------------
1 |
2 | # invalid handles
3 | did:thing.test
4 | did:thing
5 | john-.test
6 | john.0
7 | john.-
8 | xn--bcher-.tld
9 | john..test
10 | jo_hn.test
11 |
12 | # invalid DIDs
13 | did
14 | didmethodval
15 | method:did:val
16 | did:method:
17 | didmethod:val
18 | did:methodval)
19 | :did:method:val
20 | did:method:val:
21 | did:method:val%
22 | DID:method:val
23 |
24 | # other invalid stuff
25 | email@example.com
26 | @handle@example.com
27 | @handle
28 | blah
29 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('post_agg')
6 | .addColumn('quoteCount', 'bigint', (col) => col.notNull().defaultTo(0))
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema.alterTable('post_agg').dropColumn('quoteCount').execute()
12 | }
13 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/verification.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'verification'
4 |
5 | export interface Verification {
6 | uri: string
7 | cid: string
8 | rkey: string
9 | creator: string
10 | subject: string
11 | handle: string
12 | displayName: string
13 | createdAt: string
14 | indexedAt: string
15 | sortedAt: GeneratedAlways
16 | }
17 |
18 | export type PartialDB = {
19 | [tableName]: Verification
20 | }
21 |
--------------------------------------------------------------------------------
/packages/bsync/src/db/schema/notif_op.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways, Selectable } from 'kysely'
2 |
3 | export interface NotifOp {
4 | id: GeneratedAlways
5 | actorDid: string
6 | priority: boolean | null
7 | createdAt: GeneratedAlways
8 | }
9 |
10 | export type NotifOpEntry = Selectable
11 |
12 | export const tableName = 'notif_op'
13 |
14 | export type PartialDB = { [tableName]: NotifOp }
15 |
16 | export const createNotifOpChannel = 'notif_op_create' // used with listen/notify
17 |
--------------------------------------------------------------------------------
/packages/identity/src/did/util.ts:
--------------------------------------------------------------------------------
1 | export async function timed unknown>(
2 | ms: number,
3 | fn: F,
4 | ): Promise>> {
5 | const abortController = new AbortController()
6 | const timer = setTimeout(() => abortController.abort(), ms)
7 | const signal = abortController.signal
8 |
9 | try {
10 | return (await fn(signal)) as Awaited>
11 | } finally {
12 | clearTimeout(timer)
13 | abortController.abort()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/src/lib/ref.ts:
--------------------------------------------------------------------------------
1 | import { ForwardedRef } from 'react'
2 |
3 | export function updateRef(ref: ForwardedRef, value: T | null) {
4 | if (typeof ref === 'function') {
5 | ref(value)
6 | } else if (ref) {
7 | ref.current = value
8 | }
9 | }
10 |
11 | export function mergeRefs(refs: readonly (ForwardedRef | undefined)[]) {
12 | return (value: T | null) => {
13 | for (const ref of refs) {
14 | if (ref) updateRef(ref, value)
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/customization/branding.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 | import { colorsSchema } from './colors.js'
3 | import { linksSchema } from './links.js'
4 |
5 | export const brandingSchema = z.object({
6 | name: z.string().optional(),
7 | logo: z.string().url().optional(),
8 | colors: colorsSchema.optional(),
9 | links: z.array(linksSchema).optional(),
10 | })
11 | export type BrandingInput = z.input
12 | export type Branding = z.infer
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/errors/access-denied-error.ts:
--------------------------------------------------------------------------------
1 | import { OAuthAuthorizationRequestParameters } from '@atproto/oauth-types'
2 | import { AuthorizationError } from './authorization-error.js'
3 |
4 | export class AccessDeniedError extends AuthorizationError {
5 | constructor(
6 | parameters: OAuthAuthorizationRequestParameters,
7 | error_description = 'Access denied',
8 | cause?: unknown,
9 | ) {
10 | super(parameters, error_description, 'access_denied', cause)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/http/headers.ts:
--------------------------------------------------------------------------------
1 | import type { ServerResponse } from 'node:http'
2 |
3 | export function appendHeader(
4 | res: ServerResponse,
5 | header: string,
6 | value: string | readonly string[],
7 | ): void {
8 | const existing = res.getHeader(header)
9 | if (existing == null) {
10 | res.setHeader(header, value)
11 | } else {
12 | const arr = Array.isArray(existing) ? existing : [String(existing)]
13 | res.setHeader(header, arr.concat(value))
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/migrations/20240201T051104136Z-mod-event-blobs.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('moderation_event')
6 | .addColumn('subjectBlobCids', 'jsonb')
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema
12 | .alterTable('moderation_event')
13 | .dropColumn('subjectBlobCids')
14 | .execute()
15 | }
16 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/migrations/20250715T000000000Z-add-mod-event-external-id.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('moderation_event')
6 | .addColumn('externalId', 'varchar')
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema
12 | .alterTable('moderation_event')
13 | .dropColumn('externalId')
14 | .execute()
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/api/app/bsky/bookmark/util.ts:
--------------------------------------------------------------------------------
1 | import { AtUri } from '@atproto/syntax'
2 | import { InvalidRequestError } from '@atproto/xrpc-server'
3 | import { ids } from '../../../../lexicon/lexicons'
4 |
5 | export const validateUri = (uri: string) => {
6 | const atUri = new AtUri(uri)
7 | if (atUri.collection !== ids.AppBskyFeedPost) {
8 | throw new InvalidRequestError(
9 | `Only '${ids.AppBskyFeedPost}' records can be bookmarked`,
10 | 'UnsupportedCollection',
11 | )
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/errors/login-required-error.ts:
--------------------------------------------------------------------------------
1 | import { OAuthAuthorizationRequestParameters } from '@atproto/oauth-types'
2 | import { AuthorizationError } from './authorization-error.js'
3 |
4 | export class LoginRequiredError extends AuthorizationError {
5 | constructor(
6 | parameters: OAuthAuthorizationRequestParameters,
7 | error_description = 'Login is required',
8 | cause?: unknown,
9 | ) {
10 | super(parameters, error_description, 'login_required', cause)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/util/cast.ts:
--------------------------------------------------------------------------------
1 | export function asArray(value: T | T[]): T[] {
2 | if (value == null) return []
3 | return Array.isArray(value) ? value : [value]
4 | }
5 |
6 | export function asURL(value: string | { toString: () => string }): URL {
7 | return new URL(value)
8 | }
9 |
10 | export function ifURL(
11 | value: string | { toString: () => string },
12 | ): URL | undefined {
13 | try {
14 | return asURL(value)
15 | } catch {
16 | return undefined
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20250813T174955711Z-add-post-agg-bookmarks.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('post_agg')
6 | .addColumn('bookmarkCount', 'bigint', (col) => col.notNull().defaultTo(0))
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema.alterTable('post_agg').dropColumn('bookmarkCount').execute()
12 | }
13 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/list.ts:
--------------------------------------------------------------------------------
1 | import { GeneratedAlways } from 'kysely'
2 |
3 | export const tableName = 'list'
4 |
5 | export interface List {
6 | uri: string
7 | cid: string
8 | creator: string
9 | name: string
10 | purpose: string
11 | description: string | null
12 | descriptionFacets: string | null
13 | avatarCid: string | null
14 | createdAt: string
15 | indexedAt: string
16 | sortAt: GeneratedAlways
17 | }
18 |
19 | export type PartialDB = { [tableName]: List }
20 |
--------------------------------------------------------------------------------
/packages/bsky/src/util/retry.ts:
--------------------------------------------------------------------------------
1 | import { createRetryable } from '@atproto/common'
2 | import { ResponseType, XRPCError } from '@atproto/xrpc'
3 |
4 | export const RETRYABLE_HTTP_STATUS_CODES = new Set([
5 | 408, 425, 429, 500, 502, 503, 504, 522, 524,
6 | ])
7 |
8 | export const retryXrpc = createRetryable((err: unknown) => {
9 | if (err instanceof XRPCError) {
10 | if (err.status === ResponseType.Unknown) return true
11 | return RETRYABLE_HTTP_STATUS_CODES.has(err.status)
12 | }
13 | return false
14 | })
15 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230627T212437895Z-optional-handle.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('actor')
6 | .alterColumn('handle')
7 | .dropNotNull()
8 | .execute()
9 | }
10 |
11 | export async function down(db: Kysely): Promise {
12 | await db.schema
13 | .alterTable('actor')
14 | .alterColumn('handle')
15 | .setNotNull()
16 | .execute()
17 | }
18 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/errors/consent-required-error.ts:
--------------------------------------------------------------------------------
1 | import { OAuthAuthorizationRequestParameters } from '@atproto/oauth-types'
2 | import { AuthorizationError } from './authorization-error.js'
3 |
4 | export class ConsentRequiredError extends AuthorizationError {
5 | constructor(
6 | parameters: OAuthAuthorizationRequestParameters,
7 | error_description = 'User consent required',
8 | cause?: unknown,
9 | ) {
10 | super(parameters, error_description, 'consent_required', cause)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/lib/http/types.ts:
--------------------------------------------------------------------------------
1 | import type { IncomingMessage, ServerResponse } from 'node:http'
2 |
3 | export type NextFunction = (err?: unknown) => void
4 |
5 | export type Middleware<
6 | T = void,
7 | Req = IncomingMessage,
8 | Res = ServerResponse,
9 | > = (this: T, req: Req, res: Res, next: NextFunction) => void
10 |
11 | export type Handler = (
12 | this: T,
13 | req: Req,
14 | res: Res,
15 | next?: NextFunction,
16 | ) => void
17 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider/src/oauth-store.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Every store file exports all the types needed to implement that store. This
3 | * files re-exports all the types from the x-store files.
4 | */
5 |
6 | export * from './account/account-store.js'
7 | export * from './client/client-store.js'
8 | export * from './device/device-store.js'
9 | export * from './lexicon/lexicon-store.js'
10 | export * from './replay/replay-store.js'
11 | export * from './request/request-store.js'
12 | export * from './token/token-store.js'
13 |
--------------------------------------------------------------------------------
/packages/pds/src/account-manager/db/schema/device.ts:
--------------------------------------------------------------------------------
1 | import { Selectable } from 'kysely'
2 | import { DeviceId, SessionId } from '@atproto/oauth-provider'
3 | import { DateISO } from '../../../db'
4 |
5 | export interface Device {
6 | id: DeviceId
7 | sessionId: SessionId
8 |
9 | userAgent: string | null
10 | ipAddress: string
11 | lastSeenAt: DateISO
12 | }
13 |
14 | export type DeviceEntry = Selectable
15 |
16 | export const tableName = 'device'
17 |
18 | export type PartialDB = { [tableName]: Device }
19 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230427T194702079Z-notif-record-index.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | // Supports record deletion
5 | await db.schema
6 | .createIndex('notification_record_idx')
7 | .on('notification')
8 | .column('recordUri')
9 | .execute()
10 | }
11 |
12 | export async function down(db: Kysely): Promise {
13 | await db.schema.dropIndex('notification_record_idx').execute()
14 | }
15 |
--------------------------------------------------------------------------------
/packages/dev-env/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './bsky'
2 | export * from './bsync'
3 | export * from './network'
4 | export * from './network-no-appview'
5 | export * from './ozone'
6 | export * from './pds'
7 | export * from './plc'
8 | export * from './ozone'
9 | export * from './feed-gen'
10 | export * from './seed'
11 | export * from './moderator-client'
12 | export * from './types'
13 | export * from './util'
14 | export * from './const'
15 |
16 | import * as seedThreadV2 from './seed/thread-v2.js'
17 | export { seedThreadV2 }
18 |
--------------------------------------------------------------------------------
/packages/pds/src/api/app/bsky/actor/index.ts:
--------------------------------------------------------------------------------
1 | import { AppContext } from '../../../../context'
2 | import { Server } from '../../../../lexicon'
3 | import getPreferences from './getPreferences'
4 | import getProfile from './getProfile'
5 | import getProfiles from './getProfiles'
6 | import putPreferences from './putPreferences'
7 |
8 | export default function (server: Server, ctx: AppContext) {
9 | getPreferences(server, ctx)
10 | getProfile(server, ctx)
11 | getProfiles(server, ctx)
12 | putPreferences(server, ctx)
13 | }
14 |
--------------------------------------------------------------------------------
/lexicons/app/bsky/embed/defs.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "app.bsky.embed.defs",
4 | "defs": {
5 | "aspectRatio": {
6 | "type": "object",
7 | "description": "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.",
8 | "required": ["width", "height"],
9 | "properties": {
10 | "width": { "type": "integer", "minimum": 1 },
11 | "height": { "type": "integer", "minimum": 1 }
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230807T035309811Z-feed-item-delete-invite-for-user-idx.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | // supports post deletion
5 | await db.schema
6 | .createIndex('feed_item_post_uri_idx')
7 | .on('feed_item')
8 | .column('postUri')
9 | .execute()
10 | }
11 |
12 | export async function down(db: Kysely): Promise {
13 | await db.schema.dropIndex('feed_item_post_uri_idx').execute()
14 | }
15 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/tables/profile.ts:
--------------------------------------------------------------------------------
1 | export const tableName = 'profile'
2 |
3 | export interface Profile {
4 | uri: string
5 | cid: string
6 | creator: string
7 | displayName: string | null
8 | description: string | null
9 | avatarCid: string | null
10 | bannerCid: string | null
11 | joinedViaStarterPackUri: string | null
12 | pinnedPost: string | null
13 | pinnedPostCid: string | null
14 | createdAt: string
15 | indexedAt: string
16 | }
17 | export type PartialDB = { [tableName]: Profile }
18 |
--------------------------------------------------------------------------------
/packages/did/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'PDS',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | // Jest requires all ESM dependencies to be transpiled (even if they are
6 | // dynamically import()ed).
7 | transformIgnorePatterns: [
8 | `/node_modules/.pnpm/(?!(get-port|lande|toygrad)@)`,
9 | ],
10 | testTimeout: 60000,
11 | setupFiles: ['/../../jest.setup.ts'],
12 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
13 | }
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-frontend/src/data/usePasswordConfirmMutation.ts:
--------------------------------------------------------------------------------
1 | import { useMutation } from '@tanstack/react-query'
2 | import { ConfirmResetPasswordInput, useApi } from '#/api'
3 |
4 | export type PasswordConfirmMutationInput = ConfirmResetPasswordInput
5 |
6 | export function usePasswordConfirmMutation() {
7 | const api = useApi()
8 |
9 | return useMutation({
10 | async mutationFn(input: ConfirmResetPasswordInput) {
11 | await api.fetch('POST', '/reset-password-confirm', input)
12 | },
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-provider-ui/src/hooks/use-escape-key.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 |
3 | export function useEscapeKey(callback: () => void) {
4 | const handleKeyDown = (event: KeyboardEvent) => {
5 | if (event.key === 'Escape') {
6 | event.preventDefault()
7 | callback()
8 | }
9 | }
10 |
11 | useEffect(() => {
12 | window.addEventListener('keydown', handleKeyDown)
13 | return () => {
14 | window.removeEventListener('keydown', handleKeyDown)
15 | }
16 | }, [callback])
17 | }
18 |
--------------------------------------------------------------------------------
/packages/ozone/src/db/migrations/20240408T192432676Z-mute-reporting.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .alterTable('moderation_subject_status')
6 | .addColumn('muteReportingUntil', 'varchar')
7 | .execute()
8 | }
9 |
10 | export async function down(db: Kysely): Promise {
11 | await db.schema
12 | .alterTable('moderation_subject_status')
13 | .dropColumn('muteReportingUntil')
14 | .execute()
15 | }
16 |
--------------------------------------------------------------------------------
/packages/pds/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('jest').Config} */
2 | module.exports = {
3 | displayName: 'PDS',
4 | transform: { '^.+\\.(t|j)s$': '@swc/jest' },
5 | // Jest requires all ESM dependencies to be transpiled (even if they are
6 | // dynamically import()ed).
7 | transformIgnorePatterns: [
8 | `/node_modules/.pnpm/(?!(get-port|lande|toygrad)@)`,
9 | ],
10 | testTimeout: 60000,
11 | setupFiles: ['/../../jest.setup.ts'],
12 | moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
13 | }
14 |
--------------------------------------------------------------------------------
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230611T215300060Z-actor-state.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .createTable('actor_state')
6 | .addColumn('did', 'varchar', (col) => col.primaryKey())
7 | .addColumn('lastSeenNotifs', 'varchar', (col) => col.notNull())
8 | .execute()
9 | }
10 |
11 | export async function down(db: Kysely): Promise {
12 | await db.schema.dropTable('actor_state').execute()
13 | }
14 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230830T205507322Z-suggested-feeds.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .createTable('suggested_feed')
6 | .addColumn('uri', 'varchar', (col) => col.primaryKey())
7 | .addColumn('order', 'integer', (col) => col.notNull())
8 | .execute()
9 | }
10 |
11 | export async function down(db: Kysely): Promise {
12 | await db.schema.dropTable('suggested_feed').execute()
13 | }
14 |
--------------------------------------------------------------------------------
/packages/oauth/oauth-client-browser-example/src/lib/use-escape-key.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 |
3 | export function useEscapeKey(callback: () => void) {
4 | const handleKeyDown = (event: KeyboardEvent) => {
5 | if (event.key === 'Escape') {
6 | event.preventDefault()
7 | callback()
8 | }
9 | }
10 |
11 | useEffect(() => {
12 | window.addEventListener('keydown', handleKeyDown)
13 | return () => {
14 | window.removeEventListener('keydown', handleKeyDown)
15 | }
16 | }, [callback])
17 | }
18 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # buf
2 | packages/bsky/src/proto/** linguist-generated=true
3 | packages/bsync/src/proto/** linguist-generated=true
4 |
5 | # codegen
6 | packages/api/src/client/** linguist-generated=true
7 | packages/lexicon-resolver/src/client/** linguist-generated=true
8 | packages/bsky/src/lexicon/** linguist-generated=true
9 | packages/pds/src/lexicon/** linguist-generated=true
10 | packages/ozone/src/lexicon/** linguist-generated=true
11 |
12 | # i18n
13 | packages/oauth/oauth-provider-ui/src/locales/**/messages.po linguist-generated=true
14 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Dual MIT/Apache-2.0 License
2 |
3 | Copyright (c) 2022-2025 Bluesky Social PBC, and Contributors
4 |
5 | Except as otherwise noted in individual files, this software is licensed under the MIT license (), or the Apache License, Version 2.0 ().
6 |
7 | Downstream projects and end users may chose either license individually, or both together, at their discretion. The motivation for this dual-licensing is the additional software patent assurance provided by Apache 2.0.
8 |
--------------------------------------------------------------------------------
/packages/bsync/src/db/schema/index.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 | import * as muteItem from './mute_item'
3 | import * as muteOp from './mute_op'
4 | import * as notifItem from './notif_item'
5 | import * as notifOp from './notif_op'
6 | import * as op from './operation'
7 |
8 | export type DatabaseSchemaType = muteItem.PartialDB &
9 | muteOp.PartialDB &
10 | notifItem.PartialDB &
11 | notifOp.PartialDB &
12 | op.PartialDB
13 |
14 | export type DatabaseSchema = Kysely
15 |
16 | export default DatabaseSchema
17 |
--------------------------------------------------------------------------------
/packages/internal/did-resolver/src/did-resolver.ts:
--------------------------------------------------------------------------------
1 | import { Did, DidDocument } from '@atproto/did'
2 | import { ResolveDidOptions } from './did-method.js'
3 |
4 | export type ResolvedDocument =
5 | D extends Did
6 | ? DidDocument
7 | : never
8 |
9 | export interface DidResolver {
10 | resolve(
11 | did: D,
12 | options?: ResolveDidOptions,
13 | ): Promise>
14 | }
15 |
--------------------------------------------------------------------------------
/interop-test-files/README.md:
--------------------------------------------------------------------------------
1 |
2 | atproto Interop Test Files
3 | ==========================
4 |
5 | This directory contains reusable files for testing interoperability and specification compliance for atproto (AT Protocol).
6 |
7 | The protocol itself is documented at . If there are conflicts or ambiguity between these test files and the specs, the specs are the authority, and these test files should usually be corrected.
8 |
9 | These files are intended to be simple (JSON, text files, etc) and mostly self-documenting.
10 |
--------------------------------------------------------------------------------
/lexicons/com/atproto/server/revokeAppPassword.json:
--------------------------------------------------------------------------------
1 | {
2 | "lexicon": 1,
3 | "id": "com.atproto.server.revokeAppPassword",
4 | "defs": {
5 | "main": {
6 | "type": "procedure",
7 | "description": "Revoke an App Password by name.",
8 | "input": {
9 | "encoding": "application/json",
10 | "schema": {
11 | "type": "object",
12 | "required": ["name"],
13 | "properties": {
14 | "name": { "type": "string" }
15 | }
16 | }
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/bsky/src/data-plane/server/db/migrations/20230610T203555962Z-suggested-follows.ts:
--------------------------------------------------------------------------------
1 | import { Kysely } from 'kysely'
2 |
3 | export async function up(db: Kysely): Promise {
4 | await db.schema
5 | .createTable('suggested_follow')
6 | .addColumn('did', 'varchar', (col) => col.primaryKey())
7 | .addColumn('order', 'integer', (col) => col.notNull())
8 | .execute()
9 | }
10 |
11 | export async function down(db: Kysely): Promise {
12 | await db.schema.dropTable('suggested_follow').execute()
13 | }
14 |
--------------------------------------------------------------------------------