UNPKG

@unkey/nextjs

Version:

<div align="center"> <h1 align="center">@unkey/nextjs</h1> <h5>`@unkey/nextjs` the official SDK for Next.js. Just use it in your route handlers a direct and type-safe method to verify API keys.</h5> </div>

1 lines 4.48 kB
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Unkey } from \"@unkey/api\";\nimport * as errors from \"@unkey/api/models/errors\";\nimport { type NextRequest, NextResponse } from \"next/server\";\n\nexport type WithUnkeyConfig = {\n /**\n * The root key is required to verify keys.\n */\n rootKey: string;\n\n /**\n * \tArbitrary tags you may add during the verification to filter later.\n */\n tags?: string[];\n\n /**\n * Require keys to have these permissions to be valid.\n */\n permissions?: string;\n\n /**\n * How to get the key from the request\n * Usually the key is provided in an `Authorization` header, but you can do what you want.\n *\n * Return the key as string, or null if it doesn't exist.\n *\n * You can also override the response given to the caller by returning a `NextResponse`\n *\n * @default `req.headers.get(\"authorization\")?.replace(\"Bearer \", \"\") ?? null`\n */\n getKey?: (req: NextRequest) => string | null | Response | NextResponse;\n\n /**\n * Automatically return a custom response when a key is invalid\n */\n handleInvalidKey?: (\n req: NextRequest,\n result: UnkeyContext,\n ) => Response | NextResponse | Promise<Response> | Promise<NextResponse>;\n\n /**\n * What to do if things go wrong\n */\n onError?: (\n req: NextRequest,\n err: errors.APIError,\n ) => Response | NextResponse | Promise<Response> | Promise<NextResponse>;\n};\n\ntype VerifyResponse = Awaited<\n ReturnType<InstanceType<typeof Unkey>[\"keys\"][\"verifyKey\"]>\n>;\nexport type UnkeyContext = VerifyResponse;\n\nexport type NextContext = {\n params: Promise<Record<string, string | string[]>>;\n};\n\nexport type NextRequestWithUnkeyContext = NextRequest & { unkey: UnkeyContext };\n\nexport function withUnkey<TContext extends NextContext = NextContext>(\n handler: (\n req: NextRequestWithUnkeyContext,\n context: TContext,\n ) => Response | NextResponse | Promise<Response | NextResponse>,\n config: WithUnkeyConfig,\n) {\n return async (req: NextRequest, context: TContext) => {\n /**\n * Get key from request and return a response early if not found\n */\n const key = config?.getKey\n ? config.getKey(req)\n : (req.headers.get(\"authorization\")?.replace(\"Bearer \", \"\") ?? null);\n if (key === null) {\n return NextResponse.json({ error: \"unauthorized\" }, { status: 401 });\n }\n if (typeof key !== \"string\") {\n return key;\n }\n\n const unkey = new Unkey({\n rootKey: config.rootKey,\n });\n\n try {\n const res = await unkey.keys.verifyKey({\n key,\n permissions: config.permissions,\n tags: config.tags,\n });\n\n if (!res.data.valid && config.handleInvalidKey) {\n return config.handleInvalidKey(req, res);\n }\n\n if (!res.data.valid) {\n return new NextResponse(\"Unauthorized\", { status: 401 });\n }\n\n // @ts-ignore\n req.unkey = res;\n\n return handler(req as NextRequestWithUnkeyContext, context);\n } catch (err) {\n if (err instanceof errors.APIError) {\n if (config.onError) {\n return config.onError(req, err);\n }\n console.error(\n `unkey error: [CODE: ${err.statusCode}] - ${err.message}`,\n );\n return new NextResponse(\"Internal Server Error\", { status: 500 });\n }\n\n throw err;\n }\n };\n}\n"],"mappings":";AAAA,SAAS,aAAa;AACtB,YAAY,YAAY;AACxB,SAA2B,oBAAoB;AA0DxC,SAAS,UACd,SAIA,QACA;AACA,SAAO,OAAO,KAAkB,YAAsB;AAIpD,UAAM,MAAM,QAAQ,SAChB,OAAO,OAAO,GAAG,IAChB,IAAI,QAAQ,IAAI,eAAe,GAAG,QAAQ,WAAW,EAAE,KAAK;AACjE,QAAI,QAAQ,MAAM;AAChB,aAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACrE;AACA,QAAI,OAAO,QAAQ,UAAU;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,IAAI,MAAM;AAAA,MACtB,SAAS,OAAO;AAAA,IAClB,CAAC;AAED,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,KAAK,UAAU;AAAA,QACrC;AAAA,QACA,aAAa,OAAO;AAAA,QACpB,MAAM,OAAO;AAAA,MACf,CAAC;AAED,UAAI,CAAC,IAAI,KAAK,SAAS,OAAO,kBAAkB;AAC9C,eAAO,OAAO,iBAAiB,KAAK,GAAG;AAAA,MACzC;AAEA,UAAI,CAAC,IAAI,KAAK,OAAO;AACnB,eAAO,IAAI,aAAa,gBAAgB,EAAE,QAAQ,IAAI,CAAC;AAAA,MACzD;AAGA,UAAI,QAAQ;AAEZ,aAAO,QAAQ,KAAoC,OAAO;AAAA,IAC5D,SAAS,KAAK;AACZ,UAAI,eAAsB,iBAAU;AAClC,YAAI,OAAO,SAAS;AAClB,iBAAO,OAAO,QAAQ,KAAK,GAAG;AAAA,QAChC;AACA,gBAAQ;AAAA,UACN,uBAAuB,IAAI,UAAU,OAAO,IAAI,OAAO;AAAA,QACzD;AACA,eAAO,IAAI,aAAa,yBAAyB,EAAE,QAAQ,IAAI,CAAC;AAAA,MAClE;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AACF;","names":[]}