diff --git a/package.json b/package.json index bf806d7..de38f87 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,6 @@ "graphql-yoga": "^5.0.0", "itty-durable": "^2.1.0", "jest": "^29.7.0", - "node-fetch": "^3.3.2" + "node-fetch": "2.7.0" } } diff --git a/packages/core/package.json b/packages/core/package.json index 0d7a048..f3a32c1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -2,7 +2,7 @@ "name": "@authdog/hydra-core", "version": "1.0.0", "description": "", - "main": "index.js", + "main": "build/index.js", "scripts": { "dev": "tsc -w -p tsconfig.json", "build": "tsc -p tsconfig.json", diff --git a/packages/core/src/handlers/graphql.ts b/packages/core/src/handlers/graphql.ts new file mode 100644 index 0000000..077c0b2 --- /dev/null +++ b/packages/core/src/handlers/graphql.ts @@ -0,0 +1,28 @@ +import { createYoga } from "graphql-yoga"; +import { schema } from "../schema"; + +export const GraphQLHandler = async (req: Request, env: any, ctx: any) => { + const yoga = createYoga({ + schema, + context: async (event) => { + const { request } = event; + const authorization = + (request.headers.get("Authorization") || + request.headers.get("authorization")) ?? + null; + + const forwardedFor = request.headers.get("x-forwarded-for"); + // "x-forwarded-for": "\"[2a02:1210:5274:9f00:b94e:d462:5886:5cc2]\", 140.248.74.113, 140.248.74.113", + // extract ip address in [] in forwardedFor + const remoteIp = forwardedFor?.match(/\[(.*?)\]/)?.[1] ?? null; + + return { + authorization, + remoteIp, + userAgent: request.headers.get("user-agent") ?? null, + }; + }, + landingPage: false, + }); + return yoga(req, env, ctx); +}; \ No newline at end of file diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e09b73f..b1d22f6 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,29 +1 @@ -import { createYoga } from "graphql-yoga"; -import { schema } from "./schema"; - -export const GraphQLHandler = async (req: Request, env: any, ctx: any) => { - const yoga = createYoga({ - schema, - context: async (event) => { - const { request } = event; - const authorization = - (request.headers.get("Authorization") || - request.headers.get("authorization")) ?? - null; - - const forwardedFor = request.headers.get("x-forwarded-for"); - // "x-forwarded-for": "\"[2a02:1210:5274:9f00:b94e:d462:5886:5cc2]\", 140.248.74.113, 140.248.74.113", - // extract ip address in [] in forwardedFor - const remoteIp = forwardedFor?.match(/\[(.*?)\]/)?.[1] ?? null; - - return { - // request: modifiedRequest, // Pass the modified request to the context - authorization, - remoteIp, - userAgent: request.headers.get("user-agent") ?? null, - }; - }, - landingPage: false, - }); - return yoga(req, env, ctx); -}; +export {GraphQLHandler} from "./handlers/graphql"; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f56341e..c8cd1bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,8 +20,8 @@ importers: specifier: ^29.7.0 version: 29.7.0(@types/node@20.9.0) node-fetch: - specifier: ^3.3.2 - version: 3.3.2 + specifier: 2.7.0 + version: 2.7.0 devDependencies: '@types/jest': specifier: ^29.5.8 @@ -57,6 +57,9 @@ importers: services/itty-hydra: dependencies: + '@authdog/hydra-core': + specifier: workspace:* + version: link:../../packages/core itty-cors: specifier: ^0.3.6 version: 0.3.6 @@ -66,6 +69,9 @@ importers: keylab: specifier: ^0.1.30 version: 0.1.30 + node-fetch: + specifier: '2.7' + version: 2.7.0 devDependencies: '@esbuild-plugins/node-globals-polyfill': specifier: 0.2.3 @@ -1672,11 +1678,6 @@ packages: shebang-command: 2.0.0 which: 2.0.2 - /data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - dev: false - /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -2011,14 +2012,6 @@ packages: dependencies: bser: 2.1.1 - /fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 - dev: false - /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2059,13 +2052,6 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true - /formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - dependencies: - fetch-blob: 3.2.0 - dev: false - /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2936,18 +2922,16 @@ packages: /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - /node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - dev: false - - /node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 + whatwg-url: 5.0.0 dev: false /node-int64@0.4.0: @@ -3392,6 +3376,10 @@ packages: dependencies: is-number: 7.0.0 + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + /tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} dependencies: @@ -3612,15 +3600,21 @@ packages: dependencies: makeerror: 1.0.12 - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false /webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} dev: true + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + /whatwg-url@7.1.0: resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} dependencies: diff --git a/services/itty-hydra/handlers/hydraHandler.ts b/services/itty-hydra/handlers/hydraHandler.ts new file mode 100644 index 0000000..be2422b --- /dev/null +++ b/services/itty-hydra/handlers/hydraHandler.ts @@ -0,0 +1,11 @@ +interface Context { + +} + +export const Hydra = async (request: Request, env: any, ctx: Context + + ) => { + return new Response("Hydra handler", { + status: 200, + }); +} \ No newline at end of file diff --git a/services/itty-hydra/main.ts b/services/itty-hydra/main.ts index 4083fb5..2867af0 100644 --- a/services/itty-hydra/main.ts +++ b/services/itty-hydra/main.ts @@ -3,6 +3,7 @@ import { createCors } from "itty-cors"; import { withDurables } from "itty-durable"; import { NotFound } from "./handlers/notFound"; import { Health } from "./handlers/health"; +import {GraphQLHandler} from "@authdog/hydra-core"; const { preflight, corsify } = createCors(); @@ -12,11 +13,20 @@ router .options("*", preflight) .get("/", Health) .get("/health", Health) + .get("/graphql", GraphQLHandler) .get("*", NotFound); const handleRequest = (req, env, ctx) => { + const {HYDRA_ACME} = env; + + const enrichedContext = { + ...ctx, + kv: HYDRA_ACME, + rateLimiter: null, + }; + return router - .handle(req, env, ctx) + .handle(req, env, enrichedContext) .catch( (err) => () => new Response(err.stack, { diff --git a/services/itty-hydra/package.json b/services/itty-hydra/package.json index 4905dfb..bad12fd 100644 --- a/services/itty-hydra/package.json +++ b/services/itty-hydra/package.json @@ -12,9 +12,11 @@ "author": "", "license": "ISC", "dependencies": { + "@authdog/hydra-core": "workspace:*", "itty-cors": "^0.3.6", "itty-router": "^4.0.23", - "keylab": "^0.1.30" + "keylab": "^0.1.30", + "node-fetch": "2.7" }, "devDependencies": { "@esbuild-plugins/node-globals-polyfill": "0.2.3", diff --git a/services/itty-hydra/wrangler.base.toml b/services/itty-hydra/wrangler.base.toml index 5e6e220..b9c3723 100644 --- a/services/itty-hydra/wrangler.base.toml +++ b/services/itty-hydra/wrangler.base.toml @@ -4,6 +4,10 @@ workers_dev = true compatibility_date = "2023-10-10" compatibility_flags = ["nodejs_compat"] +kv_namespaces = [ + { binding = "HYDRA_ACME", id = "c63f48a0f29843e8ab8251ef533e1c9c" } +] + [build] command = "npm run build" @@ -17,6 +21,3 @@ ip = "0.0.0.0" local_protocol="http" upstream_protocol="https" -kv_namespaces = [ - { binding = "HYDRA_ACME", id = "c63f48a0f29843e8ab8251ef533e1c9c" } -] \ No newline at end of file