From f5dc2e34b698c5bcd3d1607d67bb22935ab82810 Mon Sep 17 00:00:00 2001 From: David Bushell Date: Wed, 4 Mar 2026 15:47:22 +0000 Subject: [PATCH] basic oauth callback --- package.json | 10 ++ pnpm-lock.yaml | 228 ++++++++++++++++++++++++--- src/lib/server/oauth.ts | 60 +++++++ src/routes/+page.server.ts | 40 +++++ src/routes/+page.svelte | 21 ++- src/routes/oauth/callback/+server.ts | 49 ++++++ svelte.config.js | 3 + tsconfig.json | 1 + vite.config.ts | 5 + 9 files changed, 393 insertions(+), 24 deletions(-) create mode 100644 src/lib/server/oauth.ts create mode 100644 src/routes/+page.server.ts create mode 100644 src/routes/oauth/callback/+server.ts diff --git a/package.json b/package.json index 0e70784..fab5659 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,15 @@ "svelte-check": "^4.4.2", "typescript": "^5.9.3", "vite": "^7.3.1" + }, + "dependencies": { + "@atcute/atproto": "^3.1.10", + "@atcute/bluesky": "^3.2.20", + "@atcute/client": "^4.2.1", + "@atcute/identity-resolver": "^1.2.2", + "@atcute/identity-resolver-node": "^1.0.3", + "@atcute/lexicons": "^1.2.9", + "@atcute/oauth-node-client": "^1.1.0", + "@types/node": "^25.3.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e766c8..aa45891 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,16 +7,41 @@ settings: importers: .: + dependencies: + '@atcute/atproto': + specifier: ^3.1.10 + version: 3.1.10 + '@atcute/bluesky': + specifier: ^3.2.20 + version: 3.2.20 + '@atcute/client': + specifier: ^4.2.1 + version: 4.2.1 + '@atcute/identity-resolver': + specifier: ^1.2.2 + version: 1.2.2(@atcute/identity@1.1.3) + '@atcute/identity-resolver-node': + specifier: ^1.0.3 + version: 1.0.3(@atcute/identity-resolver@1.2.2(@atcute/identity@1.1.3))(@atcute/identity@1.1.3) + '@atcute/lexicons': + specifier: ^1.2.9 + version: 1.2.9 + '@atcute/oauth-node-client': + specifier: ^1.1.0 + version: 1.1.0 + '@types/node': + specifier: ^25.3.3 + version: 25.3.3 devDependencies: '@sveltejs/adapter-auto': specifier: ^7.0.0 - version: 7.0.1(@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1)) + version: 7.0.1(@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.3))) '@sveltejs/kit': specifier: ^2.50.2 - version: 2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1) + version: 2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.3)) '@sveltejs/vite-plugin-svelte': specifier: ^6.2.4 - version: 6.2.4(svelte@5.53.7)(vite@7.3.1) + version: 6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)) svelte: specifier: ^5.51.0 version: 5.53.7 @@ -28,10 +53,64 @@ importers: version: 5.9.3 vite: specifier: ^7.3.1 - version: 7.3.1 + version: 7.3.1(@types/node@25.3.3) packages: + '@atcute/atproto@3.1.10': + resolution: {integrity: sha512-+GKZpOc0PJcdWMQEkTfg/rSNDAAHxmAUGBl60g2az15etqJn5WaUPNGFE2sB7hKpwi5Ue2h/L0OacINcE/JDDQ==} + + '@atcute/bluesky@3.2.20': + resolution: {integrity: sha512-N+o7K31ptnHSFoYKOHfQYJHFqU7CgGbCX8lDeWvpQuwkEMTEPojrQXIQD/+FL+FVEvRV/84LNi9cEnhPKShE5w==} + + '@atcute/client@4.2.1': + resolution: {integrity: sha512-ZBFM2pW075JtgGFu5g7HHZBecrClhlcNH8GVP9Zz1aViWR+cjjBsTpeE63rJs+FCOHFYlirUyo5L8SGZ4kMINw==} + + '@atcute/identity-resolver-node@1.0.3': + resolution: {integrity: sha512-RPH5M4ZRayKRcGnJWUOPVhN5WSYURXXZxKzgVT9lj/WZCH6ij2Vg3P3Eva7GGs0SG1ytnX1XVBTMoIk8nF/SLQ==} + peerDependencies: + '@atcute/identity': ^1.0.0 + '@atcute/identity-resolver': ^1.0.0 + + '@atcute/identity-resolver@1.2.2': + resolution: {integrity: sha512-eUh/UH4bFvuXS0X7epYCeJC/kj4rbBXfSRumLEH4smMVwNOgTo7cL/0Srty+P/qVPoZEyXdfEbS0PHJyzoXmHw==} + peerDependencies: + '@atcute/identity': ^1.0.0 + + '@atcute/identity@1.1.3': + resolution: {integrity: sha512-oIqPoI8TwWeQxvcLmFEZLdN2XdWcaLVtlm8pNk0E72As9HNzzD9pwKPrLr3rmTLRIoULPPFmq9iFNsTeCIU9ng==} + + '@atcute/lexicons@1.2.9': + resolution: {integrity: sha512-/RRHm2Cw9o8Mcsrq0eo8fjS9okKYLGfuFwrQ0YoP/6sdSDsXshaTLJsvLlcUcaDaSJ1YFOuHIo3zr2Om2F/16g==} + + '@atcute/multibase@1.1.8': + resolution: {integrity: sha512-pJgtImMZKCjqwRbu+2GzB+4xQjKBXDwdZOzeqe0u97zYKRGftpGYGvYv3+pMe2xXe+msDyu7Nv8iJp+U14otTA==} + + '@atcute/oauth-crypto@0.1.0': + resolution: {integrity: sha512-qZYDCNLF/4B6AndYT1rsQelN8621AC5u/sL5PHvlr/qqAbmmUwCBGjEgRSyZtHE1AqD60VNiSMlOgAuEQTSl3w==} + + '@atcute/oauth-keyset@0.1.0': + resolution: {integrity: sha512-+wqT/+I5Lg9VzKnKY3g88+N45xbq+wsdT6bHDGqCVa2u57gRvolFF4dY+weMfc/OX641BIZO6/o+zFtKBsMQnQ==} + + '@atcute/oauth-node-client@1.1.0': + resolution: {integrity: sha512-xCp/VfjtvTeKscKR/oI2hdMTp1/DaF/7ll8b6yZOCgbKlVDDfhCn5mmKNVARGTNaoywxrXG3XffbWCIx3/E87w==} + + '@atcute/oauth-types@0.1.1': + resolution: {integrity: sha512-u+3KMjse3Uc/9hDyilu1QVN7IpcnjVXgRzhddzBB8Uh6wePHNVBDdi9wQvFTVVA3zmxtMJVptXRyLLg6Ou9bqg==} + + '@atcute/uint8array@1.1.1': + resolution: {integrity: sha512-3LsC8XB8TKe9q/5hOA5sFuzGaIFdJZJNewC5OKa3o/eU6+K7JR6see9Zy2JbQERNVnRl11EzbNov1efgLMAs4g==} + + '@atcute/util-fetch@1.0.5': + resolution: {integrity: sha512-qjHj01BGxjSjIFdPiAjSARnodJIIyKxnCMMEcXMESo9TAyND6XZQqrie5fia+LlYWVXdpsTds8uFQwc9jdKTig==} + + '@atcute/util-text@1.1.1': + resolution: {integrity: sha512-JH0SxzUQJAmbOBTYyhxQbkkI6M33YpjlVLEcbP5GYt43xgFArzV0FJVmEpvIj0kjsmphHB45b6IitdvxPdec9w==} + + '@badrap/valita@0.4.6': + resolution: {integrity: sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==} + engines: {node: '>= 18'} + '@esbuild/aix-ppc64@0.27.3': resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} @@ -395,6 +474,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/node@25.3.3': + resolution: {integrity: sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -481,6 +563,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@5.1.6: + resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} + engines: {node: ^18 || >=20} + hasBin: true + obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} @@ -544,6 +631,12 @@ packages: engines: {node: '>=14.17'} hasBin: true + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + unicode-segmenter@0.14.5: + resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==} + vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -597,6 +690,92 @@ packages: snapshots: + '@atcute/atproto@3.1.10': + dependencies: + '@atcute/lexicons': 1.2.9 + + '@atcute/bluesky@3.2.20': + dependencies: + '@atcute/atproto': 3.1.10 + '@atcute/lexicons': 1.2.9 + + '@atcute/client@4.2.1': + dependencies: + '@atcute/identity': 1.1.3 + '@atcute/lexicons': 1.2.9 + + '@atcute/identity-resolver-node@1.0.3(@atcute/identity-resolver@1.2.2(@atcute/identity@1.1.3))(@atcute/identity@1.1.3)': + dependencies: + '@atcute/identity': 1.1.3 + '@atcute/identity-resolver': 1.2.2(@atcute/identity@1.1.3) + '@atcute/lexicons': 1.2.9 + + '@atcute/identity-resolver@1.2.2(@atcute/identity@1.1.3)': + dependencies: + '@atcute/identity': 1.1.3 + '@atcute/lexicons': 1.2.9 + '@atcute/util-fetch': 1.0.5 + '@badrap/valita': 0.4.6 + + '@atcute/identity@1.1.3': + dependencies: + '@atcute/lexicons': 1.2.9 + '@badrap/valita': 0.4.6 + + '@atcute/lexicons@1.2.9': + dependencies: + '@atcute/uint8array': 1.1.1 + '@atcute/util-text': 1.1.1 + '@standard-schema/spec': 1.1.0 + esm-env: 1.2.2 + + '@atcute/multibase@1.1.8': + dependencies: + '@atcute/uint8array': 1.1.1 + + '@atcute/oauth-crypto@0.1.0': + dependencies: + '@atcute/multibase': 1.1.8 + '@atcute/uint8array': 1.1.1 + '@badrap/valita': 0.4.6 + nanoid: 5.1.6 + + '@atcute/oauth-keyset@0.1.0': + dependencies: + '@atcute/oauth-crypto': 0.1.0 + + '@atcute/oauth-node-client@1.1.0': + dependencies: + '@atcute/client': 4.2.1 + '@atcute/identity': 1.1.3 + '@atcute/identity-resolver': 1.2.2(@atcute/identity@1.1.3) + '@atcute/lexicons': 1.2.9 + '@atcute/oauth-crypto': 0.1.0 + '@atcute/oauth-keyset': 0.1.0 + '@atcute/oauth-types': 0.1.1 + '@atcute/util-fetch': 1.0.5 + '@badrap/valita': 0.4.6 + nanoid: 5.1.6 + + '@atcute/oauth-types@0.1.1': + dependencies: + '@atcute/identity': 1.1.3 + '@atcute/lexicons': 1.2.9 + '@atcute/oauth-keyset': 0.1.0 + '@badrap/valita': 0.4.6 + + '@atcute/uint8array@1.1.1': {} + + '@atcute/util-fetch@1.0.5': + dependencies: + '@badrap/valita': 0.4.6 + + '@atcute/util-text@1.1.1': + dependencies: + unicode-segmenter: 0.14.5 + + '@badrap/valita@0.4.6': {} + '@esbuild/aix-ppc64@0.27.3': optional: true @@ -777,15 +956,15 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/adapter-auto@7.0.1(@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1))': + '@sveltejs/adapter-auto@7.0.1(@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.3)))': dependencies: - '@sveltejs/kit': 2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1) + '@sveltejs/kit': 2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.3)) - '@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1)': + '@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)))(svelte@5.53.7)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.3))': dependencies: '@standard-schema/spec': 1.1.0 '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.7)(vite@7.3.1) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)) '@types/cookie': 0.6.0 acorn: 8.16.0 cookie: 0.6.0 @@ -797,31 +976,35 @@ snapshots: set-cookie-parser: 3.0.1 sirv: 3.0.2 svelte: 5.53.7 - vite: 7.3.1 + vite: 7.3.1(@types/node@25.3.3) optionalDependencies: typescript: 5.9.3 - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1))(svelte@5.53.7)(vite@7.3.1)': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)))(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.7)(vite@7.3.1) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)) obug: 2.1.1 svelte: 5.53.7 - vite: 7.3.1 + vite: 7.3.1(@types/node@25.3.3) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1)': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1))(svelte@5.53.7)(vite@7.3.1) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)))(svelte@5.53.7)(vite@7.3.1(@types/node@25.3.3)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 svelte: 5.53.7 - vite: 7.3.1 - vitefu: 1.1.2(vite@7.3.1) + vite: 7.3.1(@types/node@25.3.3) + vitefu: 1.1.2(vite@7.3.1(@types/node@25.3.3)) '@types/cookie@0.6.0': {} '@types/estree@1.0.8': {} + '@types/node@25.3.3': + dependencies: + undici-types: 7.18.2 + '@types/trusted-types@2.0.7': {} acorn@8.16.0: {} @@ -902,6 +1085,8 @@ snapshots: nanoid@3.3.11: {} + nanoid@5.1.6: {} + obug@2.1.1: {} picocolors@1.1.1: {} @@ -1001,7 +1186,11 @@ snapshots: typescript@5.9.3: {} - vite@7.3.1: + undici-types@7.18.2: {} + + unicode-segmenter@0.14.5: {} + + vite@7.3.1(@types/node@25.3.3): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -1010,10 +1199,11 @@ snapshots: rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: + '@types/node': 25.3.3 fsevents: 2.3.3 - vitefu@1.1.2(vite@7.3.1): + vitefu@1.1.2(vite@7.3.1(@types/node@25.3.3)): optionalDependencies: - vite: 7.3.1 + vite: 7.3.1(@types/node@25.3.3) zimmerframe@1.1.4: {} diff --git a/src/lib/server/oauth.ts b/src/lib/server/oauth.ts new file mode 100644 index 0000000..2f3a34e --- /dev/null +++ b/src/lib/server/oauth.ts @@ -0,0 +1,60 @@ +import { + CompositeDidDocumentResolver, + CompositeHandleResolver, + LocalActorResolver, + PlcDidDocumentResolver, + WebDidDocumentResolver, + WellKnownHandleResolver, +} from "@atcute/identity-resolver"; +import { NodeDnsHandleResolver } from "@atcute/identity-resolver-node"; +import { + MemoryStore, + OAuthClient, + scope, + type StoredState, +} from "@atcute/oauth-node-client"; + +const TEN_MINUTES_MS = 10 * 60_000; + +/** + * {@link https://github.com/mary-ext/atcute/tree/trunk/packages/oauth/node-client-public-example} + */ +export function createOAuthClient() { + // [TODO] dynamic hostname/port + const redirectUri = `http://127.0.0.1:5173/oauth/callback`; + + const client = new OAuthClient({ + metadata: { + redirect_uris: [redirectUri], + scope: [scope.rpc({ lxm: ["app.bsky.actor.getProfile"], aud: "*" })], + }, + + actorResolver: new LocalActorResolver({ + handleResolver: new CompositeHandleResolver({ + methods: { + dns: new NodeDnsHandleResolver(), + http: new WellKnownHandleResolver(), + }, + }), + didDocumentResolver: new CompositeDidDocumentResolver({ + methods: { + plc: new PlcDidDocumentResolver(), + web: new WebDidDocumentResolver(), + }, + }), + }), + // [TODO] custom database K/V store + stores: { + sessions: new MemoryStore({ maxSize: 10 }), + states: new MemoryStore({ + maxSize: 10, + ttl: TEN_MINUTES_MS, + ttlAutopurge: true, + }), + }, + }); + + return client; +} + +export const oAuthClient = createOAuthClient(); diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts new file mode 100644 index 0000000..aa1f94d --- /dev/null +++ b/src/routes/+page.server.ts @@ -0,0 +1,40 @@ +import { type Actions, fail, redirect } from "@sveltejs/kit"; +import { isActorIdentifier } from "@atcute/lexicons/syntax"; +// import crypto from "node:crypto"; +import { oAuthClient } from "$lib/server/oauth.ts"; +// import { dev } from "$app/environment"; + +export const actions = { + login: async ({ request }) => { + const formData = await request.formData(); + const handle = formData.get("handle"); + + if (isActorIdentifier(handle) === false) { + return fail(400, { handle, invalid: true }); + } + const { url } = await oAuthClient.authorize({ + target: { + "type": "account", + identifier: handle, + }, + // scope: [ + // "atproto", + // ].join(" "), + }); + // [TODO] delete / handled by @atcute? + // cookies.set( + // "atproto_oauth_request", + // crypto.createHash("sha256") + // .update(stateId, "utf8") + // .digest("hex"), + // { + // httpOnly: true, + // maxAge: 60 * 5, + // path: "/", + // secure: !dev, + // sameSite: "lax", + // }, + // ); + redirect(303, url); + }, +} satisfies Actions; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index f5639d1..e073d50 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,5 +1,16 @@ -

Welcome to SvelteKit

-

- Visit svelte.dev/docs/kit to read the - documentation -

+ + +
+

Login

+ {#if form?.invalid} +

Invalid handle

+ {/if} + + + +
diff --git a/src/routes/oauth/callback/+server.ts b/src/routes/oauth/callback/+server.ts new file mode 100644 index 0000000..3c4bc8e --- /dev/null +++ b/src/routes/oauth/callback/+server.ts @@ -0,0 +1,49 @@ +import { AppBskyActorGetProfile } from "@atcute/bluesky"; +import { Client, ok } from "@atcute/client"; +import { redirect } from "@sveltejs/kit"; +import { oAuthClient } from "$lib/server/oauth.ts"; +import type { RequestHandler } from "./$types"; +import type { OAuthSession } from "@atcute/oauth-node-client"; + +export const GET: RequestHandler = async (event) => { + const { url, cookies } = event; + + // [TODO] delete / handled by @atcute? + // const state = cookies.get("atproto_oauth_request"); + // if (state === undefined) { + // return redirect(303, "/?error=expired"); + // } + // cookies.delete( + // "atproto_oauth_request", + // { path: "/" }, + // ); + + console.log(...url.searchParams); + + let session: OAuthSession; + try { + session = (await oAuthClient.callback(url.searchParams)).session; + } catch (err) { + console.error(err); + redirect(303, "/?error=session"); + } + console.log(session); + + const rpc = new Client({ handler: session }); + const profile = await ok( + rpc.call(AppBskyActorGetProfile, { + params: { actor: session.did }, + }), + ); + + console.log(profile); + + /** + * [TODO] + * parse session params + * encrypt session cookie + * redirect to? + */ + + redirect(303, "/?success"); +}; diff --git a/svelte.config.js b/svelte.config.js index 75e1de6..1c5c46a 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -7,6 +7,9 @@ const config = { // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter(), + alias: { + $lib: "src/lib", + }, }, }; diff --git a/tsconfig.json b/tsconfig.json index b779dc2..16be499 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "sourceMap": true, "strict": true, "moduleResolution": "bundler", + "types": ["@atcute/bluesky"], }, // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files diff --git a/vite.config.ts b/vite.config.ts index 80864b9..40b211c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -3,4 +3,9 @@ import { defineConfig } from "vite"; export default defineConfig({ plugins: [sveltekit()], + server: { + host: "127.0.0.1", + port: 5173, + allowedHosts: [], + }, }); -- 2.51.2