feat: Implement OAuth with DPoP using @atproto/oauth-client-node
Replace manual OAuth implementation with official @atproto/oauth-client-node library to properly support DPoP (Demonstrating Proof of Possession) authentication. Changes: - Added @atproto/oauth-client-node dependency - Created OAuth state store (SurrealDB-backed) for CSRF protection - Created OAuth session store (SurrealDB-backed) for token persistence - Created OAuth client singleton with localhost exception for development - Rewrote /api/auth/login to use client.authorize() - Rewrote /api/auth/callback to use client.callback() with DPoP - Updated lib/auth/session.ts with getAuthenticatedAgent() for ATproto API calls - Updated db/schema.surql with oauth_state and oauth_session tables - Added scripts/apply-schema.js for database schema management - Created plans/oauth-dpop-implementation.md with detailed implementation plan - Removed legacy lib/auth/atproto.ts and lib/auth/oauth-state.ts - Updated .env to use localhost exception (removed BLUESKY_CLIENT_ID) The OAuth client now handles: - PKCE code generation and verification - DPoP proof generation and signing - Automatic token refresh - Session persistence across server restarts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
182
pnpm-lock.yaml
generated
182
pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ importers:
|
||||
'@atproto/api':
|
||||
specifier: latest
|
||||
version: 0.18.0
|
||||
'@atproto/oauth-client-node':
|
||||
specifier: ^0.3.10
|
||||
version: 0.3.10
|
||||
'@deepgram/sdk':
|
||||
specifier: latest
|
||||
version: 4.11.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
@@ -146,15 +149,66 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
'@atproto-labs/did-resolver@0.2.2':
|
||||
resolution: {integrity: sha512-ca2B7xR43tVoQ8XxBvha58DXwIH8cIyKQl6lpOKGkPUrJuFoO4iCLlDiSDi2Ueh+yE1rMDPP/qveHdajgDX3WQ==}
|
||||
|
||||
'@atproto-labs/fetch-node@0.2.0':
|
||||
resolution: {integrity: sha512-Krq09nH/aeoiU2s9xdHA0FjTEFWG9B5FFenipv1iRixCcPc7V3DhTNDawxG9gI8Ny0k4dBVS9WTRN/IDzBx86Q==}
|
||||
engines: {node: '>=18.7.0'}
|
||||
|
||||
'@atproto-labs/fetch@0.2.3':
|
||||
resolution: {integrity: sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==}
|
||||
|
||||
'@atproto-labs/handle-resolver-node@0.1.21':
|
||||
resolution: {integrity: sha512-fuJy5Px5pGF3lJX/ATdurbT8tbmaFWtf+PPxAQDFy7ot2no3t+iaAgymhyxYymrssOuWs6BwOP8tyF3VrfdwtQ==}
|
||||
engines: {node: '>=18.7.0'}
|
||||
|
||||
'@atproto-labs/handle-resolver@0.3.2':
|
||||
resolution: {integrity: sha512-KIerCzh3qb+zZoqWbIvTlvBY0XPq0r56kwViaJY/LTe/3oPO2JaqlYKS/F4dByWBhHK6YoUOJ0sWrh6PMJl40A==}
|
||||
|
||||
'@atproto-labs/identity-resolver@0.3.2':
|
||||
resolution: {integrity: sha512-MYxO9pe0WsFyi5HFdKAwqIqHfiF2kBPoVhAIuH/4PYHzGr799ED47xLhNMxR3ZUYrJm5+TQzWXypGZ0Btw1Ffw==}
|
||||
|
||||
'@atproto-labs/pipe@0.1.1':
|
||||
resolution: {integrity: sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg==}
|
||||
|
||||
'@atproto-labs/simple-store-memory@0.1.4':
|
||||
resolution: {integrity: sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw==}
|
||||
|
||||
'@atproto-labs/simple-store@0.3.0':
|
||||
resolution: {integrity: sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ==}
|
||||
|
||||
'@atproto/api@0.18.0':
|
||||
resolution: {integrity: sha512-2GxKPhhvMocDjRU7VpNj+cvCdmCHVAmRwyfNgRLMrJtPZvrosFoi9VATX+7eKN0FZvYvy8KdLSkCcpP2owH3IA==}
|
||||
|
||||
'@atproto/common-web@0.4.3':
|
||||
resolution: {integrity: sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg==}
|
||||
|
||||
'@atproto/did@0.2.1':
|
||||
resolution: {integrity: sha512-1i5BTU2GnBaaeYWhxUOnuEKFVq9euT5+dQPFabHpa927BlJ54PmLGyBBaOI7/NbLmN5HWwBa18SBkMpg3jGZRA==}
|
||||
|
||||
'@atproto/jwk-jose@0.1.11':
|
||||
resolution: {integrity: sha512-i4Fnr2sTBYmMmHXl7NJh8GrCH+tDQEVWrcDMDnV5DjJfkgT17wIqvojIw9SNbSL4Uf0OtfEv6AgG0A+mgh8b5Q==}
|
||||
|
||||
'@atproto/jwk-webcrypto@0.2.0':
|
||||
resolution: {integrity: sha512-UmgRrrEAkWvxwhlwe30UmDOdTEFidlIzBC7C3cCbeJMcBN1x8B3KH+crXrsTqfWQBG58mXgt8wgSK3Kxs2LhFg==}
|
||||
|
||||
'@atproto/jwk@0.6.0':
|
||||
resolution: {integrity: sha512-bDoJPvt7TrQVi/rBfBrSSpGykhtIriKxeYCYQTiPRKFfyRhbgpElF0wPXADjIswnbzZdOwbY63az4E/CFVT3Tw==}
|
||||
|
||||
'@atproto/lexicon@0.5.1':
|
||||
resolution: {integrity: sha512-y8AEtYmfgVl4fqFxqXAeGvhesiGkxiy3CWoJIfsFDDdTlZUC8DFnZrYhcqkIop3OlCkkljvpSJi1hbeC1tbi8A==}
|
||||
|
||||
'@atproto/oauth-client-node@0.3.10':
|
||||
resolution: {integrity: sha512-6khKlJqu1Ed5rt3rzcTD5hymB6JUjKdOHWYXwiphw4inkAIo6GxLCighI4eGOqZorYk2j8ueeTNB6KsgH0kcRw==}
|
||||
engines: {node: '>=18.7.0'}
|
||||
|
||||
'@atproto/oauth-client@0.5.8':
|
||||
resolution: {integrity: sha512-7YEym6d97+Dd73qGdkQTXi5La8xvCQxwRUDzzlR/NVAARa9a4YP7MCmqBJVeP2anT0By+DSAPyPDLTsxcjIcCg==}
|
||||
|
||||
'@atproto/oauth-types@0.5.0':
|
||||
resolution: {integrity: sha512-33xz7HcXhbl+XRqbIMVu3GE02iK1nKe2oMWENASsfZEYbCz2b9ZOarOFuwi7g4LKqpGowGp0iRKsQHFcq4SDaQ==}
|
||||
|
||||
'@atproto/syntax@0.4.1':
|
||||
resolution: {integrity: sha512-CJdImtLAiFO+0z3BWTtxwk6aY5w4t8orHTMVJgkf++QRJWTxPbIFko/0hrkADB7n2EruDxDSeAgfUGehpH6ngw==}
|
||||
|
||||
@@ -1460,6 +1514,9 @@ packages:
|
||||
convert-source-map@2.0.0:
|
||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
|
||||
core-js@3.46.0:
|
||||
resolution: {integrity: sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==}
|
||||
|
||||
cross-env@7.0.3:
|
||||
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
|
||||
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
|
||||
@@ -2028,6 +2085,10 @@ packages:
|
||||
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
ipaddr.js@2.2.0:
|
||||
resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
is-any-array@0.1.1:
|
||||
resolution: {integrity: sha512-qTiELO+kpTKqPgxPYbshMERlzaFu29JDnpB8s3bjg+JkxBpw29/qqSaOdKv2pCdaG92rLGeG/zG2GauX58hfoA==}
|
||||
|
||||
@@ -2182,6 +2243,9 @@ packages:
|
||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||
hasBin: true
|
||||
|
||||
jose@5.10.0:
|
||||
resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==}
|
||||
|
||||
jose@6.1.0:
|
||||
resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==}
|
||||
|
||||
@@ -2293,6 +2357,9 @@ packages:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
|
||||
lru-cache@10.4.3:
|
||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||
|
||||
lru-cache@11.2.2:
|
||||
resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==}
|
||||
engines: {node: 20 || >=22}
|
||||
@@ -3126,6 +3193,10 @@ packages:
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
undici@6.22.0:
|
||||
resolution: {integrity: sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==}
|
||||
engines: {node: '>=18.17'}
|
||||
|
||||
undici@7.16.0:
|
||||
resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==}
|
||||
engines: {node: '>=20.18.1'}
|
||||
@@ -3378,6 +3449,53 @@ snapshots:
|
||||
optionalDependencies:
|
||||
zod: 4.1.12
|
||||
|
||||
'@atproto-labs/did-resolver@0.2.2':
|
||||
dependencies:
|
||||
'@atproto-labs/fetch': 0.2.3
|
||||
'@atproto-labs/pipe': 0.1.1
|
||||
'@atproto-labs/simple-store': 0.3.0
|
||||
'@atproto-labs/simple-store-memory': 0.1.4
|
||||
'@atproto/did': 0.2.1
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto-labs/fetch-node@0.2.0':
|
||||
dependencies:
|
||||
'@atproto-labs/fetch': 0.2.3
|
||||
'@atproto-labs/pipe': 0.1.1
|
||||
ipaddr.js: 2.2.0
|
||||
undici: 6.22.0
|
||||
|
||||
'@atproto-labs/fetch@0.2.3':
|
||||
dependencies:
|
||||
'@atproto-labs/pipe': 0.1.1
|
||||
|
||||
'@atproto-labs/handle-resolver-node@0.1.21':
|
||||
dependencies:
|
||||
'@atproto-labs/fetch-node': 0.2.0
|
||||
'@atproto-labs/handle-resolver': 0.3.2
|
||||
'@atproto/did': 0.2.1
|
||||
|
||||
'@atproto-labs/handle-resolver@0.3.2':
|
||||
dependencies:
|
||||
'@atproto-labs/simple-store': 0.3.0
|
||||
'@atproto-labs/simple-store-memory': 0.1.4
|
||||
'@atproto/did': 0.2.1
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto-labs/identity-resolver@0.3.2':
|
||||
dependencies:
|
||||
'@atproto-labs/did-resolver': 0.2.2
|
||||
'@atproto-labs/handle-resolver': 0.3.2
|
||||
|
||||
'@atproto-labs/pipe@0.1.1': {}
|
||||
|
||||
'@atproto-labs/simple-store-memory@0.1.4':
|
||||
dependencies:
|
||||
'@atproto-labs/simple-store': 0.3.0
|
||||
lru-cache: 10.4.3
|
||||
|
||||
'@atproto-labs/simple-store@0.3.0': {}
|
||||
|
||||
'@atproto/api@0.18.0':
|
||||
dependencies:
|
||||
'@atproto/common-web': 0.4.3
|
||||
@@ -3396,6 +3514,26 @@ snapshots:
|
||||
uint8arrays: 3.0.0
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto/did@0.2.1':
|
||||
dependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto/jwk-jose@0.1.11':
|
||||
dependencies:
|
||||
'@atproto/jwk': 0.6.0
|
||||
jose: 5.10.0
|
||||
|
||||
'@atproto/jwk-webcrypto@0.2.0':
|
||||
dependencies:
|
||||
'@atproto/jwk': 0.6.0
|
||||
'@atproto/jwk-jose': 0.1.11
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto/jwk@0.6.0':
|
||||
dependencies:
|
||||
multiformats: 9.9.0
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto/lexicon@0.5.1':
|
||||
dependencies:
|
||||
'@atproto/common-web': 0.4.3
|
||||
@@ -3404,6 +3542,40 @@ snapshots:
|
||||
multiformats: 9.9.0
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto/oauth-client-node@0.3.10':
|
||||
dependencies:
|
||||
'@atproto-labs/did-resolver': 0.2.2
|
||||
'@atproto-labs/handle-resolver-node': 0.1.21
|
||||
'@atproto-labs/simple-store': 0.3.0
|
||||
'@atproto/did': 0.2.1
|
||||
'@atproto/jwk': 0.6.0
|
||||
'@atproto/jwk-jose': 0.1.11
|
||||
'@atproto/jwk-webcrypto': 0.2.0
|
||||
'@atproto/oauth-client': 0.5.8
|
||||
'@atproto/oauth-types': 0.5.0
|
||||
|
||||
'@atproto/oauth-client@0.5.8':
|
||||
dependencies:
|
||||
'@atproto-labs/did-resolver': 0.2.2
|
||||
'@atproto-labs/fetch': 0.2.3
|
||||
'@atproto-labs/handle-resolver': 0.3.2
|
||||
'@atproto-labs/identity-resolver': 0.3.2
|
||||
'@atproto-labs/simple-store': 0.3.0
|
||||
'@atproto-labs/simple-store-memory': 0.1.4
|
||||
'@atproto/did': 0.2.1
|
||||
'@atproto/jwk': 0.6.0
|
||||
'@atproto/oauth-types': 0.5.0
|
||||
'@atproto/xrpc': 0.7.5
|
||||
core-js: 3.46.0
|
||||
multiformats: 9.9.0
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto/oauth-types@0.5.0':
|
||||
dependencies:
|
||||
'@atproto/did': 0.2.1
|
||||
'@atproto/jwk': 0.6.0
|
||||
zod: 3.25.76
|
||||
|
||||
'@atproto/syntax@0.4.1': {}
|
||||
|
||||
'@atproto/xrpc@0.7.5':
|
||||
@@ -4626,6 +4798,8 @@ snapshots:
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
|
||||
core-js@3.46.0: {}
|
||||
|
||||
cross-env@7.0.3:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
@@ -5345,6 +5519,8 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
side-channel: 1.1.0
|
||||
|
||||
ipaddr.js@2.2.0: {}
|
||||
|
||||
is-any-array@0.1.1: {}
|
||||
|
||||
is-any-array@2.0.1: {}
|
||||
@@ -5503,6 +5679,8 @@ snapshots:
|
||||
|
||||
jiti@2.6.1: {}
|
||||
|
||||
jose@5.10.0: {}
|
||||
|
||||
jose@6.1.0: {}
|
||||
|
||||
joycon@3.1.1: {}
|
||||
@@ -5613,6 +5791,8 @@ snapshots:
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
|
||||
lru-cache@11.2.2: {}
|
||||
|
||||
lru-cache@5.1.1:
|
||||
@@ -6594,6 +6774,8 @@ snapshots:
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
undici@6.22.0: {}
|
||||
|
||||
undici@7.16.0: {}
|
||||
|
||||
unrs-resolver@1.11.1:
|
||||
|
||||
Reference in New Issue
Block a user