From 1c04dd9ba4c0f705a316acad6454fdf6fd7a308c Mon Sep 17 00:00:00 2001 From: zeudev Date: Mon, 26 Jan 2026 05:59:03 -0800 Subject: [PATCH 01/37] implement atproto oauth --- app/components/AppHeader.vue | 3 + app/components/AuthButton.vue | 19 ++ app/components/AuthModal.vue | 124 ++++++++++ nuxt.config.ts | 8 + package.json | 3 + pnpm-lock.yaml | 437 +++++++++++++++++++++++++++++++++ server/api/auth/atproto.get.ts | 12 + 7 files changed, 606 insertions(+) create mode 100644 app/components/AuthButton.vue create mode 100644 app/components/AuthModal.vue create mode 100644 server/api/auth/atproto.get.ts diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue index d3ab19aa..2f47b0c8 100644 --- a/app/components/AppHeader.vue +++ b/app/components/AppHeader.vue @@ -54,6 +54,9 @@ withDefaults( +
  • + +
  • diff --git a/app/components/AuthButton.vue b/app/components/AuthButton.vue new file mode 100644 index 00000000..aa6366cc --- /dev/null +++ b/app/components/AuthButton.vue @@ -0,0 +1,19 @@ + + + diff --git a/app/components/AuthModal.vue b/app/components/AuthModal.vue new file mode 100644 index 00000000..4fcd6d8e --- /dev/null +++ b/app/components/AuthModal.vue @@ -0,0 +1,124 @@ + + + diff --git a/nuxt.config.ts b/nuxt.config.ts index a7464448..e8a0e5e1 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -15,9 +15,13 @@ export default defineNuxtConfig({ 'nuxt-og-image', '@nuxt/test-utils', '@vite-pwa/nuxt', + 'nuxt-auth-utils', ], devtools: { enabled: true }, + devServer: { + host: '127.0.0.1', + }, app: { head: { @@ -129,4 +133,8 @@ export default defineNuxtConfig({ ], }, }, + + auth: { + atproto: true, + }, }) diff --git a/package.json b/package.json index 4465fca2..92ea1556 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "test:unit": "vitest --project unit" }, "dependencies": { + "@atproto/api": "^0.18.17", + "@atproto/oauth-client-node": "^0.3.15", "@iconify-json/simple-icons": "^1.2.67", "@iconify-json/vscode-icons": "^1.2.40", "@nuxt/a11y": "1.0.0-alpha.1", @@ -37,6 +39,7 @@ "@vueuse/core": "^14.1.0", "@vueuse/nuxt": "14.1.0", "nuxt": "^4.3.0", + "nuxt-auth-utils": "0.5.27", "nuxt-og-image": "^5.1.13", "perfect-debounce": "^2.1.0", "sanitize-html": "^2.17.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e01ccde..e0b4a0d8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,12 @@ importers: .: dependencies: + '@atproto/api': + specifier: ^0.18.17 + version: 0.18.17 + '@atproto/oauth-client-node': + specifier: ^0.3.15 + version: 0.3.15 '@iconify-json/simple-icons': specifier: ^1.2.67 version: 1.2.67 @@ -47,6 +53,9 @@ importers: nuxt: specifier: ^4.3.0 version: 4.3.0(@parcel/watcher@2.5.4)(@types/node@25.0.10)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(encoding@0.1.13)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(magicast@0.5.1)(optionator@0.9.4)(oxlint@1.41.0)(rolldown@1.0.0-rc.1)(rollup@4.56.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.2(typescript@5.9.3))(yaml@2.8.2) + nuxt-auth-utils: + specifier: 0.5.27 + version: 0.5.27(@atproto/api@0.18.17)(@atproto/oauth-client-node@0.3.15)(magicast@0.5.1) nuxt-og-image: specifier: ^5.1.13 version: 5.1.13(@unhead/vue@2.1.2(vue@3.5.27(typescript@5.9.3)))(magicast@0.5.1)(unstorage@1.17.4(db0@0.3.4)(ioredis@5.9.2))(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) @@ -208,6 +217,18 @@ packages: '@acemir/cssom@0.9.31': resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} + '@adonisjs/hash@9.1.1': + resolution: {integrity: sha512-ZkRguwjAp4skKvKDdRAfdJ2oqQ0N7p9l3sioyXO1E8o0WcsyDgEpsTQtuVNoIdMiw4sn4gJlmL3nyF4BcK1ZDQ==} + engines: {node: '>=20.6.0'} + peerDependencies: + argon2: ^0.31.2 || ^0.41.0 || ^0.43.0 + bcrypt: ^5.1.1 || ^6.0.0 + peerDependenciesMeta: + argon2: + optional: true + bcrypt: + optional: true + '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} @@ -226,6 +247,78 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@atproto-labs/did-resolver@0.2.5': + resolution: {integrity: sha512-he7EC6OMSifNs01a4RT9mta/yYitoKDzlK9ty2TFV5Uj/+HpB4vYMRdIDFrRW0Hcsehy90E2t/dw0t7361MEKQ==} + + '@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.24': + resolution: {integrity: sha512-w/zvktigmRQpOLQQclp48tbb2K/2XW8j1szoIpT8T8v6P5dZ8GGVDIEF142xQMX9vWToFqMTu1P2yOuz8e3Ilg==} + engines: {node: '>=18.7.0'} + + '@atproto-labs/handle-resolver@0.3.5': + resolution: {integrity: sha512-r3b+plCh/0arN535Aool9gL6yTSbAPDOyReURbA2TWAaeW4vrSJPwR6yYUx0k0vmVPjkZPIdUVd63bG/+VG5MA==} + + '@atproto-labs/identity-resolver@0.3.5': + resolution: {integrity: sha512-kSxnreUSPhKL77doUbSl/9I6Y9qpkpD7MMJoYFQVU/WG0PB90tzfIb6DNuWsjbU2I5Q91Nzc4Tm4VJMV+OPKGQ==} + + '@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.17': + resolution: {integrity: sha512-TeJkLGPkiK3jblwTDSNTH+CnS6WgaOiHDZeVVzywtxomyyF0FpQVSMz5eP3sDhxyHJqpI3E2AOYD7PO/JSbzJw==} + + '@atproto/common-web@0.4.13': + resolution: {integrity: sha512-TewRUyB/dVJ5PtI3QmJzEgT3wDsvpnLJ+48hPl+LuUueJPamZevXKJN6dFjtbKAMFRnl2bKfdsf79qwvdSaLKQ==} + + '@atproto/did@0.2.4': + resolution: {integrity: sha512-nxNiCgXeo7pfjojq9fpfZxCO0X0xUipNVKW+AHNZwQKiUDt6zYL0VXEfm8HBUwQOCmKvj2pRRSM1Cur+tUWk3g==} + + '@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/lex-data@0.0.9': + resolution: {integrity: sha512-1slwe4sG0cyWtsq16+rBoWIxNDqGPkkvN+PV6JuzA7dgUK9bjUmXBGQU4eZlUPSS43X1Nhmr/9VjgKmEzU9vDw==} + + '@atproto/lex-json@0.0.9': + resolution: {integrity: sha512-Q2v1EVZcnd+ndyZj1r2UlGikA7q6It24CFPLbxokcf5Ba4RBupH8IkkQX7mqUDSRWPgQdmZYIdW9wUln+MKDqw==} + + '@atproto/lexicon@0.6.1': + resolution: {integrity: sha512-/vI1kVlY50Si+5MXpvOucelnYwb0UJ6Qto5mCp+7Q5C+Jtp+SoSykAPVvjVtTnQUH2vrKOFOwpb3C375vSKzXw==} + + '@atproto/oauth-client-node@0.3.15': + resolution: {integrity: sha512-iuT7QrLli7IyB4px1+lHvm/YoIRfNRpbNG9seJRtu5eX4N5aLsBP6vpXs9rCygd1+/15LcLRAAGKVEcrLT9tXA==} + engines: {node: '>=18.7.0'} + + '@atproto/oauth-client@0.5.13': + resolution: {integrity: sha512-FLbqHkC7BAVZ90LHVzSxQf+s8ZNIQI4TsDuhYDyzi7lYtktFHDbgd88KuM2ClJFOtGCsSS17yR1Joy925tDSaA==} + + '@atproto/oauth-types@0.6.1': + resolution: {integrity: sha512-3z92GN/6zCq9E2GTTfZM27tWEbvi1qwFSA7KoS5+wqBC4kSsLvnLxmbKH402Z40DfWS4YWqw0DkHsgP0LNFDEA==} + + '@atproto/syntax@0.4.3': + resolution: {integrity: sha512-YoZUz40YAJr5nPwvCDWgodEOlt5IftZqPJvA0JDWjuZKD8yXddTwSzXSaKQAzGOpuM+/A3uXRtPzJJqlScc+iA==} + + '@atproto/xrpc@0.7.7': + resolution: {integrity: sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==} + '@babel/code-frame@7.28.6': resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} @@ -2160,6 +2253,10 @@ packages: resolution: {integrity: sha512-WYa2tUVV5HiArWPB3ydlOc4R2ivq0IDrlqhMi3l7mVsFEXNcTfxYFPIHXHXIh/ca/y/V5N4E1zecyxdIBjYnkQ==} engines: {node: '>= 10.0.0'} + '@phc/format@1.0.0': + resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} + engines: {node: '>=10'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2181,6 +2278,17 @@ packages: '@poppinss/exception@1.2.3': resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + '@poppinss/object-builder@1.1.0': + resolution: {integrity: sha512-FOrOq52l7u8goR5yncX14+k+Ewi5djnrt1JwXeS/FvnwAPOiveFhiczCDuvXdssAwamtrV2hp5Rw9v+n2T7hQg==} + engines: {node: '>=20.6.0'} + + '@poppinss/string@1.7.1': + resolution: {integrity: sha512-OrLzv/nGDU6l6dLXIQHe8nbNSWWfuSbpB/TW5nRpZFf49CLuQlIHlSPN9IdSUv2vG+59yGM6LoibsaHn8B8mDw==} + + '@poppinss/utils@6.10.1': + resolution: {integrity: sha512-da+MMyeXhBaKtxQiWPfy7+056wk3lVIhioJnXHXkJ2/OHDaZfFcyKHNl1R06sdYO8lIRXcXdoZ6LO2ARmkAREA==} + engines: {node: '>=18.16.0'} + '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} @@ -2673,6 +2781,9 @@ packages: resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. + '@types/pluralize@0.0.33': + resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -3186,6 +3297,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + await-lock@2.2.2: + resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} + axe-core@4.11.1: resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} engines: {node: '>=4'} @@ -3319,6 +3433,10 @@ packages: caniuse-lite@1.0.30001765: resolution: {integrity: sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==} + case-anything@3.1.2: + resolution: {integrity: sha512-wljhAjDDIv/hM2FzgJnYQg90AWmZMNtESCjTeLH680qTzdo0nErlCxOmgzgX4ZsZAtIvqHyD87ES8QyriXB+BQ==} + engines: {node: '>=18'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -3467,6 +3585,9 @@ packages: core-js-compat@3.48.0: resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} + core-js@3.48.0: + resolution: {integrity: sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -4018,6 +4139,10 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + fontaine@0.7.0: resolution: {integrity: sha512-vlaWLyoJrOnCBqycmFo/CA8ZmPzuyJHYmgu261KYKByZ4YLz9sTyHZ4qoHgWSYiDsZXhiLo2XndVMz0WOAyZ8Q==} engines: {node: '>=18.12.0'} @@ -4383,6 +4508,10 @@ packages: resolution: {integrity: sha512-tAAg/72/VxOUW7RQSX1pIxJVucYKcjFjfvj60L57jrZpYCHC3XN0WCQ3sNYL4Gmvv+7GPvTAjc+KSdeNuE8oWQ==} engines: {node: '>=12.22.0'} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} + iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -4590,6 +4719,9 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} + iso-datestring-validator@2.2.2: + resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -4622,6 +4754,12 @@ 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.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + js-beautify@1.15.4: resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} @@ -5006,6 +5144,9 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + nano-spawn@2.0.0: resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==} engines: {node: '>=20.17'} @@ -5093,6 +5234,23 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nuxt-auth-utils@0.5.27: + resolution: {integrity: sha512-nXV/479IaP+g8z3+OqTgv7SNcNqPn0zyhD1t8tBxtskt+LFX1nKCZ6ZbpBGLL2wFdobh+gvzNHQjIIzqigr5Bw==} + peerDependencies: + '@atproto/api': ^0.13.15 + '@atproto/oauth-client-node': ^0.2.0 + '@simplewebauthn/browser': ^11.0.0 + '@simplewebauthn/server': ^11.0.0 + peerDependenciesMeta: + '@atproto/api': + optional: true + '@atproto/oauth-client-node': + optional: true + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nuxt-og-image@5.1.13: resolution: {integrity: sha512-H9kqGlmcEb9agWURwT5iFQjbr7Ec7tcQHZZaYSpC/JXKq2/dFyRyAoo6oXTk6ob20dK9aNjkJDcX2XmgZy67+w==} engines: {node: '>=18.0.0'} @@ -5124,6 +5282,9 @@ packages: engines: {node: '>=18'} hasBin: true + oauth4webapi@3.8.3: + resolution: {integrity: sha512-pQ5BsX3QRTgnt5HxgHwgunIRaDXBdkT23tf8dfzmtTIL2LTpdmxgbpbBm0VgFWAIDlezQvQCTgnVIUmHupXHxw==} + object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -5175,6 +5336,9 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} + openid-client@6.8.1: + resolution: {integrity: sha512-VoYT6enBo6Vj2j3Q5Ec0AezS+9YGzQo1f5Xc42lreMGlfP4ljiXPKVDvCADh+XHCV/bqPu/wWSiCVXbJKvrODw==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -5331,6 +5495,10 @@ packages: engines: {node: '>=18'} hasBin: true + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + pngjs@7.0.0: resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} engines: {node: '>=14.19.0'} @@ -5761,6 +5929,10 @@ packages: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -5789,6 +5961,9 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + secure-json-parse@4.1.0: + resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -5903,6 +6078,10 @@ packages: resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} + slugify@1.6.6: + resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} + engines: {node: '>=8.0.0'} + smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} @@ -6154,6 +6333,10 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} + tlds@1.261.0: + resolution: {integrity: sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==} + hasBin: true + tldts-core@7.0.19: resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} @@ -6269,6 +6452,9 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + uint8arrays@3.0.0: + resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} + ultrahtml@1.6.0: resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} @@ -6291,6 +6477,10 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici@6.23.0: + resolution: {integrity: sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==} + engines: {node: '>=18.17'} + unenv@2.0.0-rc.24: resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} @@ -6316,6 +6506,9 @@ packages: resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} engines: {node: '>=4'} + unicode-segmenter@0.14.5: + resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==} + unicode-trie@2.0.0: resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} @@ -6954,6 +7147,9 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -6962,6 +7158,11 @@ snapshots: '@acemir/cssom@0.9.31': optional: true + '@adonisjs/hash@9.1.1': + dependencies: + '@phc/format': 1.0.0 + '@poppinss/utils': 6.10.1 + '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.6.0 @@ -6995,6 +7196,154 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': optional: true + '@atproto-labs/did-resolver@0.2.5': + 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.4 + 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.3.0 + undici: 6.23.0 + + '@atproto-labs/fetch@0.2.3': + dependencies: + '@atproto-labs/pipe': 0.1.1 + + '@atproto-labs/handle-resolver-node@0.1.24': + dependencies: + '@atproto-labs/fetch-node': 0.2.0 + '@atproto-labs/handle-resolver': 0.3.5 + '@atproto/did': 0.2.4 + + '@atproto-labs/handle-resolver@0.3.5': + dependencies: + '@atproto-labs/simple-store': 0.3.0 + '@atproto-labs/simple-store-memory': 0.1.4 + '@atproto/did': 0.2.4 + zod: 3.25.76 + + '@atproto-labs/identity-resolver@0.3.5': + dependencies: + '@atproto-labs/did-resolver': 0.2.5 + '@atproto-labs/handle-resolver': 0.3.5 + + '@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.17': + dependencies: + '@atproto/common-web': 0.4.13 + '@atproto/lexicon': 0.6.1 + '@atproto/syntax': 0.4.3 + '@atproto/xrpc': 0.7.7 + await-lock: 2.2.2 + multiformats: 9.9.0 + tlds: 1.261.0 + zod: 3.25.76 + + '@atproto/common-web@0.4.13': + dependencies: + '@atproto/lex-data': 0.0.9 + '@atproto/lex-json': 0.0.9 + '@atproto/syntax': 0.4.3 + zod: 3.25.76 + + '@atproto/did@0.2.4': + 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/lex-data@0.0.9': + dependencies: + multiformats: 9.9.0 + tslib: 2.8.1 + uint8arrays: 3.0.0 + unicode-segmenter: 0.14.5 + + '@atproto/lex-json@0.0.9': + dependencies: + '@atproto/lex-data': 0.0.9 + tslib: 2.8.1 + + '@atproto/lexicon@0.6.1': + dependencies: + '@atproto/common-web': 0.4.13 + '@atproto/syntax': 0.4.3 + iso-datestring-validator: 2.2.2 + multiformats: 9.9.0 + zod: 3.25.76 + + '@atproto/oauth-client-node@0.3.15': + dependencies: + '@atproto-labs/did-resolver': 0.2.5 + '@atproto-labs/handle-resolver-node': 0.1.24 + '@atproto-labs/simple-store': 0.3.0 + '@atproto/did': 0.2.4 + '@atproto/jwk': 0.6.0 + '@atproto/jwk-jose': 0.1.11 + '@atproto/jwk-webcrypto': 0.2.0 + '@atproto/oauth-client': 0.5.13 + '@atproto/oauth-types': 0.6.1 + + '@atproto/oauth-client@0.5.13': + dependencies: + '@atproto-labs/did-resolver': 0.2.5 + '@atproto-labs/fetch': 0.2.3 + '@atproto-labs/handle-resolver': 0.3.5 + '@atproto-labs/identity-resolver': 0.3.5 + '@atproto-labs/simple-store': 0.3.0 + '@atproto-labs/simple-store-memory': 0.1.4 + '@atproto/did': 0.2.4 + '@atproto/jwk': 0.6.0 + '@atproto/oauth-types': 0.6.1 + '@atproto/xrpc': 0.7.7 + core-js: 3.48.0 + multiformats: 9.9.0 + zod: 3.25.76 + + '@atproto/oauth-types@0.6.1': + dependencies: + '@atproto/did': 0.2.4 + '@atproto/jwk': 0.6.0 + zod: 3.25.76 + + '@atproto/syntax@0.4.3': + dependencies: + tslib: 2.8.1 + + '@atproto/xrpc@0.7.7': + dependencies: + '@atproto/lexicon': 0.6.1 + zod: 3.25.76 + '@babel/code-frame@7.28.6': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -9036,6 +9385,8 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.4 '@parcel/watcher-win32-x64': 2.5.4 + '@phc/format@1.0.0': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -9057,6 +9408,24 @@ snapshots: '@poppinss/exception@1.2.3': {} + '@poppinss/object-builder@1.1.0': {} + + '@poppinss/string@1.7.1': + dependencies: + '@types/pluralize': 0.0.33 + case-anything: 3.1.2 + pluralize: 8.0.0 + slugify: 1.6.6 + + '@poppinss/utils@6.10.1': + dependencies: + '@poppinss/exception': 1.2.3 + '@poppinss/object-builder': 1.1.0 + '@poppinss/string': 1.7.1 + flattie: 1.1.1 + safe-stable-stringify: 2.5.0 + secure-json-parse: 4.1.0 + '@quansync/fs@1.0.0': dependencies: quansync: 1.0.0 @@ -9460,6 +9829,8 @@ snapshots: dependencies: parse-path: 7.1.0 + '@types/pluralize@0.0.33': {} + '@types/resolve@1.20.2': {} '@types/sanitize-html@2.16.0': @@ -10232,6 +10603,8 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + await-lock@2.2.2: {} + axe-core@4.11.1: {} b4a@1.7.3: {} @@ -10374,6 +10747,8 @@ snapshots: caniuse-lite@1.0.30001765: {} + case-anything@3.1.2: {} + ccount@2.0.1: {} chai@6.2.2: {} @@ -10506,6 +10881,8 @@ snapshots: dependencies: browserslist: 4.28.1 + core-js@3.48.0: {} + core-util-is@1.0.3: {} crc-32@1.2.2: {} @@ -11158,6 +11535,8 @@ snapshots: flatted@3.3.3: optional: true + flattie@1.1.1: {} + fontaine@0.7.0: dependencies: '@capsizecss/unpack': 3.0.1 @@ -11614,6 +11993,8 @@ snapshots: transitivePeerDependencies: - supports-color + ipaddr.js@2.3.0: {} + iron-webcrypto@1.2.1: {} is-array-buffer@3.0.5: @@ -11796,6 +12177,8 @@ snapshots: isexe@3.1.1: {} + iso-datestring-validator@2.2.2: {} + istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: @@ -11833,6 +12216,10 @@ snapshots: jiti@2.6.1: {} + jose@5.10.0: {} + + jose@6.1.3: {} + js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -12231,6 +12618,8 @@ snapshots: muggle-string@0.4.1: {} + multiformats@9.9.0: {} + nano-spawn@2.0.0: {} nanoid@3.3.11: {} @@ -12387,6 +12776,27 @@ snapshots: dependencies: boolbase: 1.0.0 + nuxt-auth-utils@0.5.27(@atproto/api@0.18.17)(@atproto/oauth-client-node@0.3.15)(magicast@0.5.1): + dependencies: + '@adonisjs/hash': 9.1.1 + '@nuxt/kit': 4.3.0(magicast@0.5.1) + defu: 6.1.4 + h3: 1.15.5 + hookable: 6.0.1 + jose: 6.1.3 + ofetch: 1.5.1 + openid-client: 6.8.1 + pathe: 2.0.3 + scule: 1.3.0 + uncrypto: 0.1.3 + optionalDependencies: + '@atproto/api': 0.18.17 + '@atproto/oauth-client-node': 0.3.15 + transitivePeerDependencies: + - argon2 + - bcrypt + - magicast + nuxt-og-image@5.1.13(@unhead/vue@2.1.2(vue@3.5.27(typescript@5.9.3)))(magicast@0.5.1)(unstorage@1.17.4(db0@0.3.4)(ioredis@5.9.2))(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)): dependencies: '@nuxt/devtools-kit': 3.1.1(magicast@0.5.1)(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -12580,6 +12990,8 @@ snapshots: pathe: 2.0.3 tinyexec: 1.0.2 + oauth4webapi@3.8.3: {} + object-inspect@1.13.4: {} object-keys@1.1.1: {} @@ -12638,6 +13050,11 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 + openid-client@6.8.1: + dependencies: + jose: 6.1.3 + oauth4webapi: 3.8.3 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -12859,6 +13276,8 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + pluralize@8.0.0: {} + pngjs@7.0.0: {} possible-typed-array-names@1.1.0: {} @@ -13301,6 +13720,8 @@ snapshots: es-errors: 1.3.0 is-regex: 1.2.1 + safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} sanitize-html@2.17.0: @@ -13346,6 +13767,8 @@ snapshots: scule@1.3.0: {} + secure-json-parse@4.1.0: {} + semver@6.3.1: {} semver@7.7.3: {} @@ -13527,6 +13950,8 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 + slugify@1.6.6: {} + smob@1.5.0: {} source-map-js@1.2.1: {} @@ -13790,6 +14215,8 @@ snapshots: tinyrainbow@3.0.3: {} + tlds@1.261.0: {} + tldts-core@7.0.19: optional: true @@ -13915,6 +14342,10 @@ snapshots: ufo@1.6.3: {} + uint8arrays@3.0.0: + dependencies: + multiformats: 9.9.0 + ultrahtml@1.6.0: {} unbox-primitive@1.1.0: @@ -13948,6 +14379,8 @@ snapshots: undici-types@7.16.0: {} + undici@6.23.0: {} + unenv@2.0.0-rc.24: dependencies: pathe: 2.0.3 @@ -13972,6 +14405,8 @@ snapshots: unicode-property-aliases-ecmascript@2.2.0: {} + unicode-segmenter@0.14.5: {} + unicode-trie@2.0.0: dependencies: pako: 0.2.9 @@ -14708,4 +15143,6 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 + zod@3.25.76: {} + zwitch@2.0.4: {} diff --git a/server/api/auth/atproto.get.ts b/server/api/auth/atproto.get.ts new file mode 100644 index 00000000..10b12a16 --- /dev/null +++ b/server/api/auth/atproto.get.ts @@ -0,0 +1,12 @@ +export default defineOAuthBlueskyEventHandler({ + async onSuccess(event, { user }) { + await setUserSession(event, { + user: { + bluesky: user.did, + }, + loggedInAt: Date.now(), + }) + + return sendRedirect(event, '/') + }, +}) From 560f04dba122dded831c361c60b9c69fe1c1648e Mon Sep 17 00:00:00 2001 From: zeudev Date: Mon, 26 Jan 2026 19:17:28 -0800 Subject: [PATCH 02/37] Revert "implement atproto oauth" This reverts commit 1c04dd9ba4c0f705a316acad6454fdf6fd7a308c. --- app/components/AppHeader.vue | 3 - app/components/AuthButton.vue | 19 -- app/components/AuthModal.vue | 124 ---------- nuxt.config.ts | 8 - package.json | 3 - pnpm-lock.yaml | 437 --------------------------------- server/api/auth/atproto.get.ts | 12 - 7 files changed, 606 deletions(-) delete mode 100644 app/components/AuthButton.vue delete mode 100644 app/components/AuthModal.vue delete mode 100644 server/api/auth/atproto.get.ts diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue index 2f47b0c8..d3ab19aa 100644 --- a/app/components/AppHeader.vue +++ b/app/components/AppHeader.vue @@ -54,9 +54,6 @@ withDefaults( -
  • - -
  • diff --git a/app/components/AuthButton.vue b/app/components/AuthButton.vue deleted file mode 100644 index aa6366cc..00000000 --- a/app/components/AuthButton.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/app/components/AuthModal.vue b/app/components/AuthModal.vue deleted file mode 100644 index 4fcd6d8e..00000000 --- a/app/components/AuthModal.vue +++ /dev/null @@ -1,124 +0,0 @@ - - - diff --git a/nuxt.config.ts b/nuxt.config.ts index e8a0e5e1..a7464448 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -15,13 +15,9 @@ export default defineNuxtConfig({ 'nuxt-og-image', '@nuxt/test-utils', '@vite-pwa/nuxt', - 'nuxt-auth-utils', ], devtools: { enabled: true }, - devServer: { - host: '127.0.0.1', - }, app: { head: { @@ -133,8 +129,4 @@ export default defineNuxtConfig({ ], }, }, - - auth: { - atproto: true, - }, }) diff --git a/package.json b/package.json index 92ea1556..4465fca2 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,6 @@ "test:unit": "vitest --project unit" }, "dependencies": { - "@atproto/api": "^0.18.17", - "@atproto/oauth-client-node": "^0.3.15", "@iconify-json/simple-icons": "^1.2.67", "@iconify-json/vscode-icons": "^1.2.40", "@nuxt/a11y": "1.0.0-alpha.1", @@ -39,7 +37,6 @@ "@vueuse/core": "^14.1.0", "@vueuse/nuxt": "14.1.0", "nuxt": "^4.3.0", - "nuxt-auth-utils": "0.5.27", "nuxt-og-image": "^5.1.13", "perfect-debounce": "^2.1.0", "sanitize-html": "^2.17.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e0b4a0d8..2e01ccde 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,12 +14,6 @@ importers: .: dependencies: - '@atproto/api': - specifier: ^0.18.17 - version: 0.18.17 - '@atproto/oauth-client-node': - specifier: ^0.3.15 - version: 0.3.15 '@iconify-json/simple-icons': specifier: ^1.2.67 version: 1.2.67 @@ -53,9 +47,6 @@ importers: nuxt: specifier: ^4.3.0 version: 4.3.0(@parcel/watcher@2.5.4)(@types/node@25.0.10)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(encoding@0.1.13)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(magicast@0.5.1)(optionator@0.9.4)(oxlint@1.41.0)(rolldown@1.0.0-rc.1)(rollup@4.56.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.2(typescript@5.9.3))(yaml@2.8.2) - nuxt-auth-utils: - specifier: 0.5.27 - version: 0.5.27(@atproto/api@0.18.17)(@atproto/oauth-client-node@0.3.15)(magicast@0.5.1) nuxt-og-image: specifier: ^5.1.13 version: 5.1.13(@unhead/vue@2.1.2(vue@3.5.27(typescript@5.9.3)))(magicast@0.5.1)(unstorage@1.17.4(db0@0.3.4)(ioredis@5.9.2))(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) @@ -217,18 +208,6 @@ packages: '@acemir/cssom@0.9.31': resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} - '@adonisjs/hash@9.1.1': - resolution: {integrity: sha512-ZkRguwjAp4skKvKDdRAfdJ2oqQ0N7p9l3sioyXO1E8o0WcsyDgEpsTQtuVNoIdMiw4sn4gJlmL3nyF4BcK1ZDQ==} - engines: {node: '>=20.6.0'} - peerDependencies: - argon2: ^0.31.2 || ^0.41.0 || ^0.43.0 - bcrypt: ^5.1.1 || ^6.0.0 - peerDependenciesMeta: - argon2: - optional: true - bcrypt: - optional: true - '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} @@ -247,78 +226,6 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} - '@atproto-labs/did-resolver@0.2.5': - resolution: {integrity: sha512-he7EC6OMSifNs01a4RT9mta/yYitoKDzlK9ty2TFV5Uj/+HpB4vYMRdIDFrRW0Hcsehy90E2t/dw0t7361MEKQ==} - - '@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.24': - resolution: {integrity: sha512-w/zvktigmRQpOLQQclp48tbb2K/2XW8j1szoIpT8T8v6P5dZ8GGVDIEF142xQMX9vWToFqMTu1P2yOuz8e3Ilg==} - engines: {node: '>=18.7.0'} - - '@atproto-labs/handle-resolver@0.3.5': - resolution: {integrity: sha512-r3b+plCh/0arN535Aool9gL6yTSbAPDOyReURbA2TWAaeW4vrSJPwR6yYUx0k0vmVPjkZPIdUVd63bG/+VG5MA==} - - '@atproto-labs/identity-resolver@0.3.5': - resolution: {integrity: sha512-kSxnreUSPhKL77doUbSl/9I6Y9qpkpD7MMJoYFQVU/WG0PB90tzfIb6DNuWsjbU2I5Q91Nzc4Tm4VJMV+OPKGQ==} - - '@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.17': - resolution: {integrity: sha512-TeJkLGPkiK3jblwTDSNTH+CnS6WgaOiHDZeVVzywtxomyyF0FpQVSMz5eP3sDhxyHJqpI3E2AOYD7PO/JSbzJw==} - - '@atproto/common-web@0.4.13': - resolution: {integrity: sha512-TewRUyB/dVJ5PtI3QmJzEgT3wDsvpnLJ+48hPl+LuUueJPamZevXKJN6dFjtbKAMFRnl2bKfdsf79qwvdSaLKQ==} - - '@atproto/did@0.2.4': - resolution: {integrity: sha512-nxNiCgXeo7pfjojq9fpfZxCO0X0xUipNVKW+AHNZwQKiUDt6zYL0VXEfm8HBUwQOCmKvj2pRRSM1Cur+tUWk3g==} - - '@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/lex-data@0.0.9': - resolution: {integrity: sha512-1slwe4sG0cyWtsq16+rBoWIxNDqGPkkvN+PV6JuzA7dgUK9bjUmXBGQU4eZlUPSS43X1Nhmr/9VjgKmEzU9vDw==} - - '@atproto/lex-json@0.0.9': - resolution: {integrity: sha512-Q2v1EVZcnd+ndyZj1r2UlGikA7q6It24CFPLbxokcf5Ba4RBupH8IkkQX7mqUDSRWPgQdmZYIdW9wUln+MKDqw==} - - '@atproto/lexicon@0.6.1': - resolution: {integrity: sha512-/vI1kVlY50Si+5MXpvOucelnYwb0UJ6Qto5mCp+7Q5C+Jtp+SoSykAPVvjVtTnQUH2vrKOFOwpb3C375vSKzXw==} - - '@atproto/oauth-client-node@0.3.15': - resolution: {integrity: sha512-iuT7QrLli7IyB4px1+lHvm/YoIRfNRpbNG9seJRtu5eX4N5aLsBP6vpXs9rCygd1+/15LcLRAAGKVEcrLT9tXA==} - engines: {node: '>=18.7.0'} - - '@atproto/oauth-client@0.5.13': - resolution: {integrity: sha512-FLbqHkC7BAVZ90LHVzSxQf+s8ZNIQI4TsDuhYDyzi7lYtktFHDbgd88KuM2ClJFOtGCsSS17yR1Joy925tDSaA==} - - '@atproto/oauth-types@0.6.1': - resolution: {integrity: sha512-3z92GN/6zCq9E2GTTfZM27tWEbvi1qwFSA7KoS5+wqBC4kSsLvnLxmbKH402Z40DfWS4YWqw0DkHsgP0LNFDEA==} - - '@atproto/syntax@0.4.3': - resolution: {integrity: sha512-YoZUz40YAJr5nPwvCDWgodEOlt5IftZqPJvA0JDWjuZKD8yXddTwSzXSaKQAzGOpuM+/A3uXRtPzJJqlScc+iA==} - - '@atproto/xrpc@0.7.7': - resolution: {integrity: sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==} - '@babel/code-frame@7.28.6': resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} @@ -2253,10 +2160,6 @@ packages: resolution: {integrity: sha512-WYa2tUVV5HiArWPB3ydlOc4R2ivq0IDrlqhMi3l7mVsFEXNcTfxYFPIHXHXIh/ca/y/V5N4E1zecyxdIBjYnkQ==} engines: {node: '>= 10.0.0'} - '@phc/format@1.0.0': - resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} - engines: {node: '>=10'} - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2278,17 +2181,6 @@ packages: '@poppinss/exception@1.2.3': resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} - '@poppinss/object-builder@1.1.0': - resolution: {integrity: sha512-FOrOq52l7u8goR5yncX14+k+Ewi5djnrt1JwXeS/FvnwAPOiveFhiczCDuvXdssAwamtrV2hp5Rw9v+n2T7hQg==} - engines: {node: '>=20.6.0'} - - '@poppinss/string@1.7.1': - resolution: {integrity: sha512-OrLzv/nGDU6l6dLXIQHe8nbNSWWfuSbpB/TW5nRpZFf49CLuQlIHlSPN9IdSUv2vG+59yGM6LoibsaHn8B8mDw==} - - '@poppinss/utils@6.10.1': - resolution: {integrity: sha512-da+MMyeXhBaKtxQiWPfy7+056wk3lVIhioJnXHXkJ2/OHDaZfFcyKHNl1R06sdYO8lIRXcXdoZ6LO2ARmkAREA==} - engines: {node: '>=18.16.0'} - '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} @@ -2781,9 +2673,6 @@ packages: resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. - '@types/pluralize@0.0.33': - resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} - '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -3297,9 +3186,6 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - await-lock@2.2.2: - resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} - axe-core@4.11.1: resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} engines: {node: '>=4'} @@ -3433,10 +3319,6 @@ packages: caniuse-lite@1.0.30001765: resolution: {integrity: sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==} - case-anything@3.1.2: - resolution: {integrity: sha512-wljhAjDDIv/hM2FzgJnYQg90AWmZMNtESCjTeLH680qTzdo0nErlCxOmgzgX4ZsZAtIvqHyD87ES8QyriXB+BQ==} - engines: {node: '>=18'} - ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -3585,9 +3467,6 @@ packages: core-js-compat@3.48.0: resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} - core-js@3.48.0: - resolution: {integrity: sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==} - core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -4139,10 +4018,6 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - flattie@1.1.1: - resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} - engines: {node: '>=8'} - fontaine@0.7.0: resolution: {integrity: sha512-vlaWLyoJrOnCBqycmFo/CA8ZmPzuyJHYmgu261KYKByZ4YLz9sTyHZ4qoHgWSYiDsZXhiLo2XndVMz0WOAyZ8Q==} engines: {node: '>=18.12.0'} @@ -4508,10 +4383,6 @@ packages: resolution: {integrity: sha512-tAAg/72/VxOUW7RQSX1pIxJVucYKcjFjfvj60L57jrZpYCHC3XN0WCQ3sNYL4Gmvv+7GPvTAjc+KSdeNuE8oWQ==} engines: {node: '>=12.22.0'} - ipaddr.js@2.3.0: - resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} - engines: {node: '>= 10'} - iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -4719,9 +4590,6 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} - iso-datestring-validator@2.2.2: - resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} - istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -4754,12 +4622,6 @@ 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.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} - js-beautify@1.15.4: resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} @@ -5144,9 +5006,6 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - multiformats@9.9.0: - resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} - nano-spawn@2.0.0: resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==} engines: {node: '>=20.17'} @@ -5234,23 +5093,6 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nuxt-auth-utils@0.5.27: - resolution: {integrity: sha512-nXV/479IaP+g8z3+OqTgv7SNcNqPn0zyhD1t8tBxtskt+LFX1nKCZ6ZbpBGLL2wFdobh+gvzNHQjIIzqigr5Bw==} - peerDependencies: - '@atproto/api': ^0.13.15 - '@atproto/oauth-client-node': ^0.2.0 - '@simplewebauthn/browser': ^11.0.0 - '@simplewebauthn/server': ^11.0.0 - peerDependenciesMeta: - '@atproto/api': - optional: true - '@atproto/oauth-client-node': - optional: true - '@simplewebauthn/browser': - optional: true - '@simplewebauthn/server': - optional: true - nuxt-og-image@5.1.13: resolution: {integrity: sha512-H9kqGlmcEb9agWURwT5iFQjbr7Ec7tcQHZZaYSpC/JXKq2/dFyRyAoo6oXTk6ob20dK9aNjkJDcX2XmgZy67+w==} engines: {node: '>=18.0.0'} @@ -5282,9 +5124,6 @@ packages: engines: {node: '>=18'} hasBin: true - oauth4webapi@3.8.3: - resolution: {integrity: sha512-pQ5BsX3QRTgnt5HxgHwgunIRaDXBdkT23tf8dfzmtTIL2LTpdmxgbpbBm0VgFWAIDlezQvQCTgnVIUmHupXHxw==} - object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -5336,9 +5175,6 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - openid-client@6.8.1: - resolution: {integrity: sha512-VoYT6enBo6Vj2j3Q5Ec0AezS+9YGzQo1f5Xc42lreMGlfP4ljiXPKVDvCADh+XHCV/bqPu/wWSiCVXbJKvrODw==} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -5495,10 +5331,6 @@ packages: engines: {node: '>=18'} hasBin: true - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - pngjs@7.0.0: resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} engines: {node: '>=14.19.0'} @@ -5929,10 +5761,6 @@ packages: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} - safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -5961,9 +5789,6 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - secure-json-parse@4.1.0: - resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} - semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -6078,10 +5903,6 @@ packages: resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} - slugify@1.6.6: - resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} - engines: {node: '>=8.0.0'} - smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} @@ -6333,10 +6154,6 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} - tlds@1.261.0: - resolution: {integrity: sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==} - hasBin: true - tldts-core@7.0.19: resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} @@ -6452,9 +6269,6 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - uint8arrays@3.0.0: - resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} - ultrahtml@1.6.0: resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} @@ -6477,10 +6291,6 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici@6.23.0: - resolution: {integrity: sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==} - engines: {node: '>=18.17'} - unenv@2.0.0-rc.24: resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} @@ -6506,9 +6316,6 @@ packages: resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} engines: {node: '>=4'} - unicode-segmenter@0.14.5: - resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==} - unicode-trie@2.0.0: resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} @@ -7147,9 +6954,6 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -7158,11 +6962,6 @@ snapshots: '@acemir/cssom@0.9.31': optional: true - '@adonisjs/hash@9.1.1': - dependencies: - '@phc/format': 1.0.0 - '@poppinss/utils': 6.10.1 - '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.6.0 @@ -7196,154 +6995,6 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': optional: true - '@atproto-labs/did-resolver@0.2.5': - 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.4 - 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.3.0 - undici: 6.23.0 - - '@atproto-labs/fetch@0.2.3': - dependencies: - '@atproto-labs/pipe': 0.1.1 - - '@atproto-labs/handle-resolver-node@0.1.24': - dependencies: - '@atproto-labs/fetch-node': 0.2.0 - '@atproto-labs/handle-resolver': 0.3.5 - '@atproto/did': 0.2.4 - - '@atproto-labs/handle-resolver@0.3.5': - dependencies: - '@atproto-labs/simple-store': 0.3.0 - '@atproto-labs/simple-store-memory': 0.1.4 - '@atproto/did': 0.2.4 - zod: 3.25.76 - - '@atproto-labs/identity-resolver@0.3.5': - dependencies: - '@atproto-labs/did-resolver': 0.2.5 - '@atproto-labs/handle-resolver': 0.3.5 - - '@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.17': - dependencies: - '@atproto/common-web': 0.4.13 - '@atproto/lexicon': 0.6.1 - '@atproto/syntax': 0.4.3 - '@atproto/xrpc': 0.7.7 - await-lock: 2.2.2 - multiformats: 9.9.0 - tlds: 1.261.0 - zod: 3.25.76 - - '@atproto/common-web@0.4.13': - dependencies: - '@atproto/lex-data': 0.0.9 - '@atproto/lex-json': 0.0.9 - '@atproto/syntax': 0.4.3 - zod: 3.25.76 - - '@atproto/did@0.2.4': - 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/lex-data@0.0.9': - dependencies: - multiformats: 9.9.0 - tslib: 2.8.1 - uint8arrays: 3.0.0 - unicode-segmenter: 0.14.5 - - '@atproto/lex-json@0.0.9': - dependencies: - '@atproto/lex-data': 0.0.9 - tslib: 2.8.1 - - '@atproto/lexicon@0.6.1': - dependencies: - '@atproto/common-web': 0.4.13 - '@atproto/syntax': 0.4.3 - iso-datestring-validator: 2.2.2 - multiformats: 9.9.0 - zod: 3.25.76 - - '@atproto/oauth-client-node@0.3.15': - dependencies: - '@atproto-labs/did-resolver': 0.2.5 - '@atproto-labs/handle-resolver-node': 0.1.24 - '@atproto-labs/simple-store': 0.3.0 - '@atproto/did': 0.2.4 - '@atproto/jwk': 0.6.0 - '@atproto/jwk-jose': 0.1.11 - '@atproto/jwk-webcrypto': 0.2.0 - '@atproto/oauth-client': 0.5.13 - '@atproto/oauth-types': 0.6.1 - - '@atproto/oauth-client@0.5.13': - dependencies: - '@atproto-labs/did-resolver': 0.2.5 - '@atproto-labs/fetch': 0.2.3 - '@atproto-labs/handle-resolver': 0.3.5 - '@atproto-labs/identity-resolver': 0.3.5 - '@atproto-labs/simple-store': 0.3.0 - '@atproto-labs/simple-store-memory': 0.1.4 - '@atproto/did': 0.2.4 - '@atproto/jwk': 0.6.0 - '@atproto/oauth-types': 0.6.1 - '@atproto/xrpc': 0.7.7 - core-js: 3.48.0 - multiformats: 9.9.0 - zod: 3.25.76 - - '@atproto/oauth-types@0.6.1': - dependencies: - '@atproto/did': 0.2.4 - '@atproto/jwk': 0.6.0 - zod: 3.25.76 - - '@atproto/syntax@0.4.3': - dependencies: - tslib: 2.8.1 - - '@atproto/xrpc@0.7.7': - dependencies: - '@atproto/lexicon': 0.6.1 - zod: 3.25.76 - '@babel/code-frame@7.28.6': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -9385,8 +9036,6 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.4 '@parcel/watcher-win32-x64': 2.5.4 - '@phc/format@1.0.0': {} - '@pkgjs/parseargs@0.11.0': optional: true @@ -9408,24 +9057,6 @@ snapshots: '@poppinss/exception@1.2.3': {} - '@poppinss/object-builder@1.1.0': {} - - '@poppinss/string@1.7.1': - dependencies: - '@types/pluralize': 0.0.33 - case-anything: 3.1.2 - pluralize: 8.0.0 - slugify: 1.6.6 - - '@poppinss/utils@6.10.1': - dependencies: - '@poppinss/exception': 1.2.3 - '@poppinss/object-builder': 1.1.0 - '@poppinss/string': 1.7.1 - flattie: 1.1.1 - safe-stable-stringify: 2.5.0 - secure-json-parse: 4.1.0 - '@quansync/fs@1.0.0': dependencies: quansync: 1.0.0 @@ -9829,8 +9460,6 @@ snapshots: dependencies: parse-path: 7.1.0 - '@types/pluralize@0.0.33': {} - '@types/resolve@1.20.2': {} '@types/sanitize-html@2.16.0': @@ -10603,8 +10232,6 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - await-lock@2.2.2: {} - axe-core@4.11.1: {} b4a@1.7.3: {} @@ -10747,8 +10374,6 @@ snapshots: caniuse-lite@1.0.30001765: {} - case-anything@3.1.2: {} - ccount@2.0.1: {} chai@6.2.2: {} @@ -10881,8 +10506,6 @@ snapshots: dependencies: browserslist: 4.28.1 - core-js@3.48.0: {} - core-util-is@1.0.3: {} crc-32@1.2.2: {} @@ -11535,8 +11158,6 @@ snapshots: flatted@3.3.3: optional: true - flattie@1.1.1: {} - fontaine@0.7.0: dependencies: '@capsizecss/unpack': 3.0.1 @@ -11993,8 +11614,6 @@ snapshots: transitivePeerDependencies: - supports-color - ipaddr.js@2.3.0: {} - iron-webcrypto@1.2.1: {} is-array-buffer@3.0.5: @@ -12177,8 +11796,6 @@ snapshots: isexe@3.1.1: {} - iso-datestring-validator@2.2.2: {} - istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: @@ -12216,10 +11833,6 @@ snapshots: jiti@2.6.1: {} - jose@5.10.0: {} - - jose@6.1.3: {} - js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -12618,8 +12231,6 @@ snapshots: muggle-string@0.4.1: {} - multiformats@9.9.0: {} - nano-spawn@2.0.0: {} nanoid@3.3.11: {} @@ -12776,27 +12387,6 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt-auth-utils@0.5.27(@atproto/api@0.18.17)(@atproto/oauth-client-node@0.3.15)(magicast@0.5.1): - dependencies: - '@adonisjs/hash': 9.1.1 - '@nuxt/kit': 4.3.0(magicast@0.5.1) - defu: 6.1.4 - h3: 1.15.5 - hookable: 6.0.1 - jose: 6.1.3 - ofetch: 1.5.1 - openid-client: 6.8.1 - pathe: 2.0.3 - scule: 1.3.0 - uncrypto: 0.1.3 - optionalDependencies: - '@atproto/api': 0.18.17 - '@atproto/oauth-client-node': 0.3.15 - transitivePeerDependencies: - - argon2 - - bcrypt - - magicast - nuxt-og-image@5.1.13(@unhead/vue@2.1.2(vue@3.5.27(typescript@5.9.3)))(magicast@0.5.1)(unstorage@1.17.4(db0@0.3.4)(ioredis@5.9.2))(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)): dependencies: '@nuxt/devtools-kit': 3.1.1(magicast@0.5.1)(vite@8.0.0-beta.10(@types/node@25.0.10)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -12990,8 +12580,6 @@ snapshots: pathe: 2.0.3 tinyexec: 1.0.2 - oauth4webapi@3.8.3: {} - object-inspect@1.13.4: {} object-keys@1.1.1: {} @@ -13050,11 +12638,6 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openid-client@6.8.1: - dependencies: - jose: 6.1.3 - oauth4webapi: 3.8.3 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -13276,8 +12859,6 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - pluralize@8.0.0: {} - pngjs@7.0.0: {} possible-typed-array-names@1.1.0: {} @@ -13720,8 +13301,6 @@ snapshots: es-errors: 1.3.0 is-regex: 1.2.1 - safe-stable-stringify@2.5.0: {} - safer-buffer@2.1.2: {} sanitize-html@2.17.0: @@ -13767,8 +13346,6 @@ snapshots: scule@1.3.0: {} - secure-json-parse@4.1.0: {} - semver@6.3.1: {} semver@7.7.3: {} @@ -13950,8 +13527,6 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 - slugify@1.6.6: {} - smob@1.5.0: {} source-map-js@1.2.1: {} @@ -14215,8 +13790,6 @@ snapshots: tinyrainbow@3.0.3: {} - tlds@1.261.0: {} - tldts-core@7.0.19: optional: true @@ -14342,10 +13915,6 @@ snapshots: ufo@1.6.3: {} - uint8arrays@3.0.0: - dependencies: - multiformats: 9.9.0 - ultrahtml@1.6.0: {} unbox-primitive@1.1.0: @@ -14379,8 +13948,6 @@ snapshots: undici-types@7.16.0: {} - undici@6.23.0: {} - unenv@2.0.0-rc.24: dependencies: pathe: 2.0.3 @@ -14405,8 +13972,6 @@ snapshots: unicode-property-aliases-ecmascript@2.2.0: {} - unicode-segmenter@0.14.5: {} - unicode-trie@2.0.0: dependencies: pako: 0.2.9 @@ -15143,6 +14708,4 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 - zod@3.25.76: {} - zwitch@2.0.4: {} diff --git a/server/api/auth/atproto.get.ts b/server/api/auth/atproto.get.ts deleted file mode 100644 index 10b12a16..00000000 --- a/server/api/auth/atproto.get.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default defineOAuthBlueskyEventHandler({ - async onSuccess(event, { user }) { - await setUserSession(event, { - user: { - bluesky: user.did, - }, - loggedInAt: Date.now(), - }) - - return sendRedirect(event, '/') - }, -}) From 6215eb3e48c9785db203b976e9040d3bc1e69991 Mon Sep 17 00:00:00 2001 From: zeudev Date: Wed, 28 Jan 2026 04:48:34 -0800 Subject: [PATCH 03/37] working atproto auth w/o nuxt-auth-utils --- app/components/AppHeader.vue | 4 + app/components/AuthButton.vue | 18 ++ app/components/AuthModal.vue | 105 +++++++ nuxt.config.ts | 3 + package.json | 2 + pnpm-lock.yaml | 286 ++++++++++++++++++ server/api/auth/atproto.get.ts | 83 +++++ .../routes/oauth-client-metadata.json.get.ts | 3 + server/utils/atproto.ts | 28 ++ 9 files changed, 532 insertions(+) create mode 100644 app/components/AuthButton.vue create mode 100644 app/components/AuthModal.vue create mode 100644 server/api/auth/atproto.get.ts create mode 100644 server/routes/oauth-client-metadata.json.get.ts create mode 100644 server/utils/atproto.ts diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue index d3ab19aa..27f011ab 100644 --- a/app/components/AppHeader.vue +++ b/app/components/AppHeader.vue @@ -54,6 +54,10 @@ withDefaults( + +
  • + +
  • diff --git a/app/components/AuthButton.vue b/app/components/AuthButton.vue new file mode 100644 index 00000000..65664e22 --- /dev/null +++ b/app/components/AuthButton.vue @@ -0,0 +1,18 @@ + + + diff --git a/app/components/AuthModal.vue b/app/components/AuthModal.vue new file mode 100644 index 00000000..9c88a6be --- /dev/null +++ b/app/components/AuthModal.vue @@ -0,0 +1,105 @@ + + + diff --git a/nuxt.config.ts b/nuxt.config.ts index a7464448..f2d2ca20 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -18,6 +18,9 @@ export default defineNuxtConfig({ ], devtools: { enabled: true }, + devServer: { + host: '127.0.0.1', + }, app: { head: { diff --git a/package.json b/package.json index 4465fca2..eebfa1b2 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "test:unit": "vitest --project unit" }, "dependencies": { + "@atproto/api": "^0.18.17", + "@atproto/oauth-client-node": "^0.3.15", "@iconify-json/simple-icons": "^1.2.67", "@iconify-json/vscode-icons": "^1.2.40", "@nuxt/a11y": "1.0.0-alpha.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e01ccde..b58a2f48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,12 @@ importers: .: dependencies: + '@atproto/api': + specifier: ^0.18.17 + version: 0.18.17 + '@atproto/oauth-client-node': + specifier: ^0.3.15 + version: 0.3.15 '@iconify-json/simple-icons': specifier: ^1.2.67 version: 1.2.67 @@ -226,6 +232,78 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@atproto-labs/did-resolver@0.2.5': + resolution: {integrity: sha512-he7EC6OMSifNs01a4RT9mta/yYitoKDzlK9ty2TFV5Uj/+HpB4vYMRdIDFrRW0Hcsehy90E2t/dw0t7361MEKQ==} + + '@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.24': + resolution: {integrity: sha512-w/zvktigmRQpOLQQclp48tbb2K/2XW8j1szoIpT8T8v6P5dZ8GGVDIEF142xQMX9vWToFqMTu1P2yOuz8e3Ilg==} + engines: {node: '>=18.7.0'} + + '@atproto-labs/handle-resolver@0.3.5': + resolution: {integrity: sha512-r3b+plCh/0arN535Aool9gL6yTSbAPDOyReURbA2TWAaeW4vrSJPwR6yYUx0k0vmVPjkZPIdUVd63bG/+VG5MA==} + + '@atproto-labs/identity-resolver@0.3.5': + resolution: {integrity: sha512-kSxnreUSPhKL77doUbSl/9I6Y9qpkpD7MMJoYFQVU/WG0PB90tzfIb6DNuWsjbU2I5Q91Nzc4Tm4VJMV+OPKGQ==} + + '@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.17': + resolution: {integrity: sha512-TeJkLGPkiK3jblwTDSNTH+CnS6WgaOiHDZeVVzywtxomyyF0FpQVSMz5eP3sDhxyHJqpI3E2AOYD7PO/JSbzJw==} + + '@atproto/common-web@0.4.13': + resolution: {integrity: sha512-TewRUyB/dVJ5PtI3QmJzEgT3wDsvpnLJ+48hPl+LuUueJPamZevXKJN6dFjtbKAMFRnl2bKfdsf79qwvdSaLKQ==} + + '@atproto/did@0.2.4': + resolution: {integrity: sha512-nxNiCgXeo7pfjojq9fpfZxCO0X0xUipNVKW+AHNZwQKiUDt6zYL0VXEfm8HBUwQOCmKvj2pRRSM1Cur+tUWk3g==} + + '@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/lex-data@0.0.9': + resolution: {integrity: sha512-1slwe4sG0cyWtsq16+rBoWIxNDqGPkkvN+PV6JuzA7dgUK9bjUmXBGQU4eZlUPSS43X1Nhmr/9VjgKmEzU9vDw==} + + '@atproto/lex-json@0.0.9': + resolution: {integrity: sha512-Q2v1EVZcnd+ndyZj1r2UlGikA7q6It24CFPLbxokcf5Ba4RBupH8IkkQX7mqUDSRWPgQdmZYIdW9wUln+MKDqw==} + + '@atproto/lexicon@0.6.1': + resolution: {integrity: sha512-/vI1kVlY50Si+5MXpvOucelnYwb0UJ6Qto5mCp+7Q5C+Jtp+SoSykAPVvjVtTnQUH2vrKOFOwpb3C375vSKzXw==} + + '@atproto/oauth-client-node@0.3.15': + resolution: {integrity: sha512-iuT7QrLli7IyB4px1+lHvm/YoIRfNRpbNG9seJRtu5eX4N5aLsBP6vpXs9rCygd1+/15LcLRAAGKVEcrLT9tXA==} + engines: {node: '>=18.7.0'} + + '@atproto/oauth-client@0.5.13': + resolution: {integrity: sha512-FLbqHkC7BAVZ90LHVzSxQf+s8ZNIQI4TsDuhYDyzi7lYtktFHDbgd88KuM2ClJFOtGCsSS17yR1Joy925tDSaA==} + + '@atproto/oauth-types@0.6.1': + resolution: {integrity: sha512-3z92GN/6zCq9E2GTTfZM27tWEbvi1qwFSA7KoS5+wqBC4kSsLvnLxmbKH402Z40DfWS4YWqw0DkHsgP0LNFDEA==} + + '@atproto/syntax@0.4.3': + resolution: {integrity: sha512-YoZUz40YAJr5nPwvCDWgodEOlt5IftZqPJvA0JDWjuZKD8yXddTwSzXSaKQAzGOpuM+/A3uXRtPzJJqlScc+iA==} + + '@atproto/xrpc@0.7.7': + resolution: {integrity: sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==} + '@babel/code-frame@7.28.6': resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} @@ -3186,6 +3264,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + await-lock@2.2.2: + resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} + axe-core@4.11.1: resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} engines: {node: '>=4'} @@ -3467,6 +3548,9 @@ packages: core-js-compat@3.48.0: resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} + core-js@3.48.0: + resolution: {integrity: sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -4383,6 +4467,10 @@ packages: resolution: {integrity: sha512-tAAg/72/VxOUW7RQSX1pIxJVucYKcjFjfvj60L57jrZpYCHC3XN0WCQ3sNYL4Gmvv+7GPvTAjc+KSdeNuE8oWQ==} engines: {node: '>=12.22.0'} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} + iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -4590,6 +4678,9 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} + iso-datestring-validator@2.2.2: + resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -4622,6 +4713,9 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + jose@5.10.0: + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + js-beautify@1.15.4: resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} @@ -5006,6 +5100,9 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + nano-spawn@2.0.0: resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==} engines: {node: '>=20.17'} @@ -6154,6 +6251,10 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} + tlds@1.261.0: + resolution: {integrity: sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==} + hasBin: true + tldts-core@7.0.19: resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} @@ -6269,6 +6370,9 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + uint8arrays@3.0.0: + resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} + ultrahtml@1.6.0: resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} @@ -6291,6 +6395,10 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici@6.23.0: + resolution: {integrity: sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==} + engines: {node: '>=18.17'} + unenv@2.0.0-rc.24: resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} @@ -6316,6 +6424,9 @@ packages: resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} engines: {node: '>=4'} + unicode-segmenter@0.14.5: + resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==} + unicode-trie@2.0.0: resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} @@ -6954,6 +7065,9 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -6995,6 +7109,154 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': optional: true + '@atproto-labs/did-resolver@0.2.5': + 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.4 + 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.3.0 + undici: 6.23.0 + + '@atproto-labs/fetch@0.2.3': + dependencies: + '@atproto-labs/pipe': 0.1.1 + + '@atproto-labs/handle-resolver-node@0.1.24': + dependencies: + '@atproto-labs/fetch-node': 0.2.0 + '@atproto-labs/handle-resolver': 0.3.5 + '@atproto/did': 0.2.4 + + '@atproto-labs/handle-resolver@0.3.5': + dependencies: + '@atproto-labs/simple-store': 0.3.0 + '@atproto-labs/simple-store-memory': 0.1.4 + '@atproto/did': 0.2.4 + zod: 3.25.76 + + '@atproto-labs/identity-resolver@0.3.5': + dependencies: + '@atproto-labs/did-resolver': 0.2.5 + '@atproto-labs/handle-resolver': 0.3.5 + + '@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.17': + dependencies: + '@atproto/common-web': 0.4.13 + '@atproto/lexicon': 0.6.1 + '@atproto/syntax': 0.4.3 + '@atproto/xrpc': 0.7.7 + await-lock: 2.2.2 + multiformats: 9.9.0 + tlds: 1.261.0 + zod: 3.25.76 + + '@atproto/common-web@0.4.13': + dependencies: + '@atproto/lex-data': 0.0.9 + '@atproto/lex-json': 0.0.9 + '@atproto/syntax': 0.4.3 + zod: 3.25.76 + + '@atproto/did@0.2.4': + 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/lex-data@0.0.9': + dependencies: + multiformats: 9.9.0 + tslib: 2.8.1 + uint8arrays: 3.0.0 + unicode-segmenter: 0.14.5 + + '@atproto/lex-json@0.0.9': + dependencies: + '@atproto/lex-data': 0.0.9 + tslib: 2.8.1 + + '@atproto/lexicon@0.6.1': + dependencies: + '@atproto/common-web': 0.4.13 + '@atproto/syntax': 0.4.3 + iso-datestring-validator: 2.2.2 + multiformats: 9.9.0 + zod: 3.25.76 + + '@atproto/oauth-client-node@0.3.15': + dependencies: + '@atproto-labs/did-resolver': 0.2.5 + '@atproto-labs/handle-resolver-node': 0.1.24 + '@atproto-labs/simple-store': 0.3.0 + '@atproto/did': 0.2.4 + '@atproto/jwk': 0.6.0 + '@atproto/jwk-jose': 0.1.11 + '@atproto/jwk-webcrypto': 0.2.0 + '@atproto/oauth-client': 0.5.13 + '@atproto/oauth-types': 0.6.1 + + '@atproto/oauth-client@0.5.13': + dependencies: + '@atproto-labs/did-resolver': 0.2.5 + '@atproto-labs/fetch': 0.2.3 + '@atproto-labs/handle-resolver': 0.3.5 + '@atproto-labs/identity-resolver': 0.3.5 + '@atproto-labs/simple-store': 0.3.0 + '@atproto-labs/simple-store-memory': 0.1.4 + '@atproto/did': 0.2.4 + '@atproto/jwk': 0.6.0 + '@atproto/oauth-types': 0.6.1 + '@atproto/xrpc': 0.7.7 + core-js: 3.48.0 + multiformats: 9.9.0 + zod: 3.25.76 + + '@atproto/oauth-types@0.6.1': + dependencies: + '@atproto/did': 0.2.4 + '@atproto/jwk': 0.6.0 + zod: 3.25.76 + + '@atproto/syntax@0.4.3': + dependencies: + tslib: 2.8.1 + + '@atproto/xrpc@0.7.7': + dependencies: + '@atproto/lexicon': 0.6.1 + zod: 3.25.76 + '@babel/code-frame@7.28.6': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -10232,6 +10494,8 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + await-lock@2.2.2: {} + axe-core@4.11.1: {} b4a@1.7.3: {} @@ -10506,6 +10770,8 @@ snapshots: dependencies: browserslist: 4.28.1 + core-js@3.48.0: {} + core-util-is@1.0.3: {} crc-32@1.2.2: {} @@ -11614,6 +11880,8 @@ snapshots: transitivePeerDependencies: - supports-color + ipaddr.js@2.3.0: {} + iron-webcrypto@1.2.1: {} is-array-buffer@3.0.5: @@ -11796,6 +12064,8 @@ snapshots: isexe@3.1.1: {} + iso-datestring-validator@2.2.2: {} + istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: @@ -11833,6 +12103,8 @@ snapshots: jiti@2.6.1: {} + jose@5.10.0: {} + js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -12231,6 +12503,8 @@ snapshots: muggle-string@0.4.1: {} + multiformats@9.9.0: {} + nano-spawn@2.0.0: {} nanoid@3.3.11: {} @@ -13790,6 +14064,8 @@ snapshots: tinyrainbow@3.0.3: {} + tlds@1.261.0: {} + tldts-core@7.0.19: optional: true @@ -13915,6 +14191,10 @@ snapshots: ufo@1.6.3: {} + uint8arrays@3.0.0: + dependencies: + multiformats: 9.9.0 + ultrahtml@1.6.0: {} unbox-primitive@1.1.0: @@ -13948,6 +14228,8 @@ snapshots: undici-types@7.16.0: {} + undici@6.23.0: {} + unenv@2.0.0-rc.24: dependencies: pathe: 2.0.3 @@ -13972,6 +14254,8 @@ snapshots: unicode-property-aliases-ecmascript@2.2.0: {} + unicode-segmenter@0.14.5: {} + unicode-trie@2.0.0: dependencies: pako: 0.2.9 @@ -14708,4 +14992,6 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 + zod@3.25.76: {} + zwitch@2.0.4: {} diff --git a/server/api/auth/atproto.get.ts b/server/api/auth/atproto.get.ts new file mode 100644 index 00000000..ac0b90cc --- /dev/null +++ b/server/api/auth/atproto.get.ts @@ -0,0 +1,83 @@ +import type { H3Event } from 'h3' +import { Agent } from '@atproto/api' +import { NodeOAuthClient } from '@atproto/oauth-client-node' +import type { + NodeSavedSession, + NodeSavedSessionStore, + NodeSavedState, + NodeSavedStateStore, +} from '@atproto/oauth-client-node' +import { scope, getOauthClientMetadata } from '~~/server/utils/atproto' +import { createError, getQuery, sendRedirect, getCookie, setCookie, deleteCookie } from 'h3' + +export default defineEventHandler(async event => { + const query = getQuery(event) + const clientMetadata = getOauthClientMetadata() + const stateStore = new StateStore(event) + const sessionStore = new SessionStore(event) + const atclient = new NodeOAuthClient({ + stateStore, + sessionStore, + clientMetadata, + }) + + if (!query.code) { + const handle = query.handle?.toString() + + if (!handle) { + throw createError({ + status: 400, + message: 'Handle not provided in query', + }) + } + + const redirectUrl = await atclient.authorize(handle, { scope }) + return sendRedirect(event, redirectUrl.toString()) + } + + const { session } = await atclient.callback(new URLSearchParams(query as Record)) + const agent = new Agent(session) + event.context.agent = agent + console.log(agent.did) + return sendRedirect(event, '/') +}) + +export class StateStore implements NodeSavedStateStore { + private readonly stateKey = 'oauth:bluesky:stat' + + constructor(private event: H3Event) {} + + async get(): Promise { + const result = getCookie(this.event, this.stateKey) + if (!result) return + return JSON.parse(atob(result)) + } + + async set(key: string, val: NodeSavedState) { + setCookie(this.event, this.stateKey, btoa(JSON.stringify(val))) + } + + async del() { + deleteCookie(this.event, this.stateKey) + } +} + +export class SessionStore implements NodeSavedSessionStore { + private readonly sessionKey = 'oauth:bluesky:session' + + constructor(private event: H3Event) {} + + async get(): Promise { + const result = getCookie(this.event, this.sessionKey) + if (!result) return + return JSON.parse(atob(result)) + } + + async set(key: string, val: NodeSavedSession) { + setCookie(this.event, this.sessionKey, btoa(JSON.stringify(val))) + } + + async del() { + deleteCookie(this.event, this.sessionKey) + } +} diff --git a/server/routes/oauth-client-metadata.json.get.ts b/server/routes/oauth-client-metadata.json.get.ts new file mode 100644 index 00000000..0ea235ed --- /dev/null +++ b/server/routes/oauth-client-metadata.json.get.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(() => { + return getOauthClientMetadata() +}) diff --git a/server/utils/atproto.ts b/server/utils/atproto.ts new file mode 100644 index 00000000..e80ebea5 --- /dev/null +++ b/server/utils/atproto.ts @@ -0,0 +1,28 @@ +import { OAuthClientMetadataInput } from '@atproto/oauth-client-node' + +// TODO: limit scope as features gets added +export const scope = 'atproto transition:generic' + +export function getOauthClientMetadata() { + const dev = import.meta.dev + + // TODO: CHECK - on dev, match in nuxt.config.ts devServer: { host: "127.0.0.1" } + const client_uri = dev ? `http://127.0.0.1:3000` : 'https://npmx.dev' + const redirect_uri = `${client_uri}/api/auth/atproto` + + const client_id = dev + ? `http://localhost?redirect_uri=${encodeURIComponent(redirect_uri)}&scope=${encodeURIComponent(scope)}` + : `${client_uri}/oauth-client-metadata.json` + + return { + client_name: 'npmx.dev', + client_id, + client_uri, + scope, + redirect_uris: [redirect_uri] as [string, ...string[]], + grant_types: ['authorization_code', 'refresh_token'], + application_type: 'web', + token_endpoint_auth_method: 'none', + dpop_bound_access_tokens: true, + } as OAuthClientMetadataInput +} From 477cebb331556f5d5408a7658186910310e279da Mon Sep 17 00:00:00 2001 From: zeudev Date: Wed, 28 Jan 2026 19:46:28 -0800 Subject: [PATCH 04/37] working atproto oauth login and logout --- app/components/AppHeader.vue | 11 +- app/components/AuthButton.vue | 3 +- app/components/AuthModal.vue | 21 +- app/composables/useAtproto.ts | 30 + pnpm-lock.yaml | 2060 ++++++++++++++++------------- server/api/auth/atproto.get.ts | 23 +- server/api/auth/session.delete.ts | 9 + server/api/auth/session.get.ts | 7 + server/utils/atproto.ts | 4 +- 9 files changed, 1264 insertions(+), 904 deletions(-) create mode 100644 app/composables/useAtproto.ts create mode 100644 server/api/auth/session.delete.ts create mode 100644 server/api/auth/session.get.ts diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue index 9c57a139..96613c5e 100644 --- a/app/components/AppHeader.vue +++ b/app/components/AppHeader.vue @@ -137,15 +137,6 @@ onKeyStroke(',', e => { class="hidden sm:inline-flex items-center justify-center w-5 h-5 text-xs bg-bg-muted border border-border rounded" aria-hidden="true" > - - - - - -
  • - -
  • - , @@ -153,6 +144,8 @@ onKeyStroke(',', e => { + + diff --git a/app/components/AuthButton.vue b/app/components/AuthButton.vue index 65664e22..0c5820e8 100644 --- a/app/components/AuthButton.vue +++ b/app/components/AuthButton.vue @@ -1,5 +1,6 @@