aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-02-12 22:50:43 +0000
committerMohamedBassem <me@mbassem.com>2024-02-12 22:50:43 +0000
commitb00d2b360d8000edcd9bfa82673ca322a9ac6d1a (patch)
treee939db73131a9a6fd04b249b8adac44816dad8b2
parent6e6d2c3cbc860d0024e9631b01eeef55b47933a5 (diff)
downloadkarakeep-b00d2b360d8000edcd9bfa82673ca322a9ac6d1a.tar.zst
hack: Hack API key support in the context creation of TRPC
-rw-r--r--.eslintrc.js1
-rw-r--r--packages/web/app/api/trpc/[trpc]/route.ts18
-rw-r--r--packages/web/server/api/client.ts2
-rw-r--r--packages/web/server/api/trpc.ts6
-rw-r--r--packages/web/server/auth.ts4
5 files changed, 22 insertions, 9 deletions
diff --git a/.eslintrc.js b/.eslintrc.js
index 13394572..a78fa42f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -8,7 +8,6 @@ module.exports = {
"next/core-web-vitals",
"eslint:recommended",
"plugin:react/recommended",
- "plugin:react-hooks/recommended",
"plugin:@next/next/recommended",
"plugin:tailwindcss/recommended",
"plugin:@typescript-eslint/recommended",
diff --git a/packages/web/app/api/trpc/[trpc]/route.ts b/packages/web/app/api/trpc/[trpc]/route.ts
index 4d108604..e04539a9 100644
--- a/packages/web/app/api/trpc/[trpc]/route.ts
+++ b/packages/web/app/api/trpc/[trpc]/route.ts
@@ -1,12 +1,28 @@
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter } from "@/server/api/routers/_app";
import { createContext } from "@/server/api/client";
+import { authenticateApiKey } from "@/server/auth";
const handler = (req: Request) =>
fetchRequestHandler({
endpoint: "/api/trpc",
req,
router: appRouter,
- createContext,
+ createContext: async (opts) => {
+ // TODO: This is a hack until we offer a proper REST API instead of the trpc based one.
+ // Check if the request has an Authorization token, if it does, assume that API key authentication is requested.
+ const authorizationHeader = opts.req.headers.get("Authorization");
+ if (authorizationHeader && authorizationHeader.startsWith("Bearer ")) {
+ const token = authorizationHeader.split(" ")[1];
+ try {
+ const user = await authenticateApiKey(token);
+ return { user };
+ } catch (e) {
+ // Fallthrough to cookie-based auth
+ }
+ }
+
+ return createContext();
+ },
});
export { handler as GET, handler as POST };
diff --git a/packages/web/server/api/client.ts b/packages/web/server/api/client.ts
index 7008e10d..7b4e6378 100644
--- a/packages/web/server/api/client.ts
+++ b/packages/web/server/api/client.ts
@@ -5,7 +5,7 @@ import { Context, createCallerFactory } from "./trpc";
export const createContext = async (): Promise<Context> => {
const session = await getServerAuthSession();
return {
- session,
+ user: session?.user ?? null,
};
};
diff --git a/packages/web/server/api/trpc.ts b/packages/web/server/api/trpc.ts
index 82aa2d18..1f4eb775 100644
--- a/packages/web/server/api/trpc.ts
+++ b/packages/web/server/api/trpc.ts
@@ -1,8 +1,8 @@
import { TRPCError, initTRPC } from "@trpc/server";
-import { Session } from "next-auth";
+import { User } from "next-auth";
export type Context = {
- session: Session | null;
+ user: User | null;
};
// Avoid exporting the entire t-object
@@ -17,7 +17,7 @@ export const procedure = t.procedure;
export const publicProcedure = t.procedure;
export const authedProcedure = t.procedure.use(function isAuthed(opts) {
- const user = opts.ctx.session?.user;
+ const user = opts.ctx.user;
if (!user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
diff --git a/packages/web/server/auth.ts b/packages/web/server/auth.ts
index f78fa8cf..6c00b4b5 100644
--- a/packages/web/server/auth.ts
+++ b/packages/web/server/auth.ts
@@ -108,7 +108,5 @@ export async function authenticateApiKey(key: string) {
throw new Error("Invalid API Key");
}
- return {
- user: apiKey.user,
- };
+ return apiKey.user;
}