diff --git a/apps/web/package.json b/apps/web/package.json index 0334cdc..e14f374 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -8,34 +8,25 @@ }, "dependencies": { "@atcast/atproto": "workspace:*", - "@atcast/eslint-config": "workspace:*", "@atcast/lib": "workspace:*", "@atcast/models": "workspace:*", - "@atcast/prettier-config": "workspace:*", "@atproto/api": "^0.13.35", - "@atproto/crypto": "^0.4.4", "@atproto/identity": "^0.4.6", "@atproto/jwk-jose": "^0.1.4", - "@atproto/lexicon": "^0.4.6", "@atproto/oauth-client": "^0.3.9", "@atproto/syntax": "^0.3.2", - "@atproto/xrpc": "^0.6.8", "@hookform/resolvers": "^3.10.0", "@iconify/json": "^2.2.304", "@normy/react-query": "^0.18.0", "@radix-ui/react-accessible-icon": "^1.1.2", "@radix-ui/react-slot": "^1.1.2", - "@react-spring/web": "^9.7.5", "@stylexjs/stylex": "^0.10.1", "@tanstack/react-query": "^5.66.0", "@uploadthing/react": "^7.1.5", "babel-plugin-react-compiler": "^19.0.0-beta-e552027-20250112", "clsx": "^2.1.1", - "cookie": "^1.0.2", "date-fns": "^4.1.0", "drizzle-orm": "^0.39.2", - "lru-cache": "^11.0.2", - "multiformats": "^13.3.1", "nanoid": "^5.0.9", "next": "^15.2.0-canary.46", "normalize.css": "^8.0.1", @@ -45,13 +36,13 @@ "react-hook-form": "^7.54.2", "react-scan": "^0.1.3", "react-textarea-autosize": "^8.5.7", - "superjson": "^2.2.2", - "unique-username-generator": "^1.4.0", "uploadthing": "^7.4.4", "yup": "^1.6.1", "zod": "^3.24.1" }, "devDependencies": { + "@atcast/eslint-config": "workspace:*", + "@atcast/prettier-config": "workspace:*", "@stylexswc/nextjs-plugin": "^0.6.5", "@stylexswc/postcss-plugin": "^0.6.5", "@stylexswc/rs-compiler": "^0.6.5", diff --git a/apps/web/src/lib/server/data/getSession.ts b/apps/web/src/lib/server/data/getSession.ts index ea916bf..55aebc7 100644 --- a/apps/web/src/lib/server/data/getSession.ts +++ b/apps/web/src/lib/server/data/getSession.ts @@ -1,5 +1,3 @@ -import { JoseKey } from "@atproto/jwk-jose"; -import { eq } from "drizzle-orm"; import { RequestCookies } from "next/dist/compiled/@edge-runtime/cookies"; import type { ReadonlyHeaders } from "next/dist/server/web/spec-extension/adapters/headers"; import type { ReadonlyRequestCookies } from "next/dist/server/web/spec-extension/adapters/request-cookies"; @@ -7,9 +5,9 @@ import { cookies, headers } from "next/headers"; import { NextRequest } from "next/server"; import { cache } from "react"; -import { createDPoPFetch, getClientId } from "@atcast/atproto"; +import { ensureSessionValid } from "@atcast/atproto"; import { SESSION_TOKEN } from "@atcast/lib"; -import { db, userSessions } from "@atcast/models"; +import { db } from "@atcast/models"; import { getBskyAuthInfo } from "@/lib/oauth/bsky"; import { AtprotoErrorResponse } from "@/lib/server/AtprotoErrorResponse"; @@ -109,63 +107,9 @@ export async function getSession( where: (users, { eq }) => eq(users.id, session!.userId), }); - if ( - session.accessTokenExpiresAt && - session.accessTokenExpiresAt < new Date() - ) { - const key = await JoseKey.fromJWK(session.jwk as any); - const bskyOauthSpec = await getBskyAuthInfo(); - - const dpopFetch = createDPoPFetch({ - key, - metadata: bskyOauthSpec, - }); - - const refreshResponse = await dpopFetch(bskyOauthSpec.token_endpoint, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - client_id: getClientId(), - grant_type: "refresh_token", - refresh_token: session.refreshToken, - }), - }); - const refreshData = await refreshResponse.json(); - - if (refreshData.error) { - return { - errorResponse: new AtprotoErrorResponse( - { - error: "InvalidToken", - }, - { - status: 401, - }, - ), - }; - } - - const insertResult = await db - .update(userSessions) - .set({ - accessToken: refreshData.access_token, - accessTokenExpiresAt: new Date( - Date.now() + refreshData.expires_in * 1000, - ), - refreshToken: refreshData.refresh_token, - accessTokenType: refreshData.token_type, - }) - .where(eq(userSessions.id, session.id)) - .returning(); - - if (!insertResult) { - throw new Error("Failed to update session"); - } - - session = insertResult[0]; - } + session = await ensureSessionValid(session, { + metadata: await getBskyAuthInfo(), + }); return { session, diff --git a/apps/worker/package.json b/apps/worker/package.json index fbb2148..c62d840 100644 --- a/apps/worker/package.json +++ b/apps/worker/package.json @@ -8,20 +8,18 @@ }, "dependencies": { "@atcast/atproto": "workspace:*", - "@atcast/eslint-config": "workspace:*", "@atcast/lib": "workspace:*", "@atcast/models": "workspace:*", - "@atcast/prettier-config": "workspace:*", "@atproto/api": "^0.13.35", "@atproto/identity": "^0.4.6", - "@atproto/jwk-jose": "^0.1.4", - "@atproto/syntax": "^0.3.2", "croner": "^9.0.0", "drizzle-orm": "^0.39.2", "hono": "^4.7.0", "uploadthing": "^7.4.4" }, "devDependencies": { + "@atcast/eslint-config": "workspace:*", + "@atcast/prettier-config": "workspace:*", "@tsconfig/bun": "^1.0.7", "@types/bun": "^1.2.2", "typescript": "^5.7.3" diff --git a/bun.lock b/bun.lock index 1d0151b..4527ba5 100644 --- a/bun.lock +++ b/bun.lock @@ -13,34 +13,25 @@ "name": "@atcast/web", "dependencies": { "@atcast/atproto": "workspace:*", - "@atcast/eslint-config": "workspace:*", "@atcast/lib": "workspace:*", "@atcast/models": "workspace:*", - "@atcast/prettier-config": "workspace:*", "@atproto/api": "^0.13.35", - "@atproto/crypto": "^0.4.4", "@atproto/identity": "^0.4.6", "@atproto/jwk-jose": "^0.1.4", - "@atproto/lexicon": "^0.4.6", "@atproto/oauth-client": "^0.3.9", "@atproto/syntax": "^0.3.2", - "@atproto/xrpc": "^0.6.8", "@hookform/resolvers": "^3.10.0", "@iconify/json": "^2.2.304", "@normy/react-query": "^0.18.0", "@radix-ui/react-accessible-icon": "^1.1.2", "@radix-ui/react-slot": "^1.1.2", - "@react-spring/web": "^9.7.5", "@stylexjs/stylex": "^0.10.1", "@tanstack/react-query": "^5.66.0", "@uploadthing/react": "^7.1.5", "babel-plugin-react-compiler": "^19.0.0-beta-e552027-20250112", "clsx": "^2.1.1", - "cookie": "^1.0.2", "date-fns": "^4.1.0", "drizzle-orm": "^0.39.2", - "lru-cache": "^11.0.2", - "multiformats": "^13.3.1", "nanoid": "^5.0.9", "next": "^15.2.0-canary.46", "normalize.css": "^8.0.1", @@ -50,13 +41,13 @@ "react-hook-form": "^7.54.2", "react-scan": "^0.1.3", "react-textarea-autosize": "^8.5.7", - "superjson": "^2.2.2", - "unique-username-generator": "^1.4.0", "uploadthing": "^7.4.4", "yup": "^1.6.1", "zod": "^3.24.1", }, "devDependencies": { + "@atcast/eslint-config": "workspace:*", + "@atcast/prettier-config": "workspace:*", "@stylexswc/nextjs-plugin": "^0.6.5", "@stylexswc/postcss-plugin": "^0.6.5", "@stylexswc/rs-compiler": "^0.6.5", @@ -79,20 +70,18 @@ "name": "@atcast/worker", "dependencies": { "@atcast/atproto": "workspace:*", - "@atcast/eslint-config": "workspace:*", "@atcast/lib": "workspace:*", "@atcast/models": "workspace:*", - "@atcast/prettier-config": "workspace:*", "@atproto/api": "^0.13.35", "@atproto/identity": "^0.4.6", - "@atproto/jwk-jose": "^0.1.4", - "@atproto/syntax": "^0.3.2", "croner": "^9.0.0", "drizzle-orm": "^0.39.2", "hono": "^4.7.0", "uploadthing": "^7.4.4", }, "devDependencies": { + "@atcast/eslint-config": "workspace:*", + "@atcast/prettier-config": "workspace:*", "@tsconfig/bun": "^1.0.7", "@types/bun": "^1.2.2", "typescript": "^5.7.3", @@ -104,7 +93,6 @@ "@atcast/models": "workspace:*", "@atproto/api": "^0.13.35", "@atproto/crypto": "^0.4.4", - "@atproto/identity": "^0.4.6", "@atproto/jwk-jose": "^0.1.4", "@atproto/lexicon": "^0.4.6", "@atproto/oauth-client": "^0.3.9", @@ -125,8 +113,6 @@ "name": "@atcast/eslint-config", "version": "0.0.0", "dependencies": { - "@atcast/prettier-config": "workspace:*", - "@types/bun": "^1.2.2", "@typescript-eslint/eslint-plugin": "^8.23.0", "@typescript-eslint/parser": "^8.23.0", "eslint": "~8.57.1", @@ -137,6 +123,8 @@ "typescript-eslint": "^8.23.0", }, "devDependencies": { + "@atcast/prettier-config": "workspace:*", + "@types/bun": "^1.2.2", "@types/eslint-config-prettier": "^6.11.3", }, }, @@ -557,18 +545,6 @@ "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q=="], - "@react-spring/animated": ["@react-spring/animated@9.7.5", "", { "dependencies": { "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg=="], - - "@react-spring/core": ["@react-spring/core@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w=="], - - "@react-spring/rafz": ["@react-spring/rafz@9.7.5", "", {}, "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw=="], - - "@react-spring/shared": ["@react-spring/shared@9.7.5", "", { "dependencies": { "@react-spring/rafz": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw=="], - - "@react-spring/types": ["@react-spring/types@9.7.5", "", {}, "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g=="], - - "@react-spring/web": ["@react-spring/web@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/core": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ=="], - "@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.30.1", "", { "os": "android", "cpu": "arm" }, "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q=="], @@ -899,10 +875,6 @@ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], - - "copy-anything": ["copy-anything@3.0.5", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w=="], - "core-js-pure": ["core-js-pure@3.40.0", "", {}, "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A=="], "cosmiconfig": ["cosmiconfig@8.3.6", "", { "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA=="], @@ -1283,8 +1255,6 @@ "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="], - "is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="], - "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], "isbinaryfile": ["isbinaryfile@4.0.10", "", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], @@ -1825,8 +1795,6 @@ "sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="], - "superjson": ["superjson@2.2.2", "", { "dependencies": { "copy-anything": "^3.0.2" } }, "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q=="], - "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], @@ -1931,8 +1899,6 @@ "undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], - "unique-username-generator": ["unique-username-generator@1.4.0", "", {}, "sha512-Y6CY5vLPeixB5V4t6b/y7KkOPWpbANCIln4O6MRzz2uPIxzDm6KshWxJKMeAxLU2EPyCK+ptw/YeZMkZPFv2bw=="], - "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], "unplugin": ["unplugin@2.1.2", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-Q3LU0e4zxKfRko1wMV2HmP8lB9KWislY7hxXpxd+lGx0PRInE4vhMBVEZwpdVYHvtqzhSrzuIfErsob6bQfCzw=="], diff --git a/packages/atproto/package.json b/packages/atproto/package.json index 76c9731..cfd1fbe 100644 --- a/packages/atproto/package.json +++ b/packages/atproto/package.json @@ -21,7 +21,6 @@ "@atcast/models": "workspace:*", "@atproto/api": "^0.13.35", "@atproto/crypto": "^0.4.4", - "@atproto/identity": "^0.4.6", "@atproto/jwk-jose": "^0.1.4", "@atproto/lexicon": "^0.4.6", "@atproto/oauth-client": "^0.3.9", diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 913b52d..14eff99 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -8,8 +8,6 @@ "format": "prettier --write **/*.{js,json} --ignore-path ../../.gitignore" }, "dependencies": { - "@atcast/prettier-config": "workspace:*", - "@types/bun": "^1.2.2", "@typescript-eslint/eslint-plugin": "^8.23.0", "@typescript-eslint/parser": "^8.23.0", "eslint": "~8.57.1", @@ -20,6 +18,8 @@ "typescript-eslint": "^8.23.0" }, "devDependencies": { - "@types/eslint-config-prettier": "^6.11.3" + "@atcast/prettier-config": "workspace:*", + "@types/eslint-config-prettier": "^6.11.3", + "@types/bun": "^1.2.2" } }