[Bug] `store.auth` is always `null` in following `derive()`
Closed this issue · 0 comments
EDIT: I didn't read Elysia's docs properly - the derive
method is run in the onTransform
hook, which itself runs before the onBefore
hook (used in elysia-clerk
).
TLDR: I shouldn't use derive
but onBeforeHandle
instead.
Hey, I'm running into a weird issue: anytime I try to use the value auth
set in the global store
provided by Elysia its value is null
, but when I use methods exposed by the plugin I'm able to get result of the toAuth()
method without any issue.
I'm trying to use this plugin inside a custom hook I'm working on (which basically merges the Clerk auth and a custom API auth system).
Here's the code implementation of my hook:
import { Elysia } from "elysia";
import { clerkClient, clerkPlugin } from "elysia-clerk";
export const unifiedAuthPlugin = () => {
return new Elysia()
.use(
clerkPlugin({
secretKey: process.env.CLERK_SECRET_KEY,
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
})
)
.derive(
async ({
store,
set,
headers,
request,
}) => {
try {
console.log("store", store.auth); // This returns `null`
const authStatus = await clerkClient.authenticateRequest({
request,
});
const res = authStatus.toAuth();
console.log("res", res); // This returns the data which is expected to be provided by the plugin (the user ID and every other user-related fields/methods)
store.auth = res;
console.log("store.auth", store.auth); // Works as expected after setting the value from `res`
} catch (error) {
console.error("Error occurred while authenticating request:", error)
}
}
);
};
Here's how my custom hook is used:
import { Elysia } from "elysia";
import { unifiedAuthPlugin } from "../../middlewares/unifiedAuth";
import { getUserSettings } from "./service";
export const users = new Elysia({ prefix: "/users" })
.use(unifiedAuthPlugin())
.get(
"/settings",
({ store }) => {
return getUserSettings({ id: store.auth?.userId });
},
{
detail: {
tags: ["User"],
description: "Get my settings",
},
}
);
And here's my entry file (index.ts
):
import { Elysia } from "elysia";
import { ApiResult } from "./helpers/ApiError";
import { users } from "./resources/users/router";
import swagger from "@elysiajs/swagger";
import cors from "@elysiajs/cors";
const app = new Elysia()
.use(
swagger({
documentation: {
info: {
title: "My API",
version: "1.0.0",
},
tags: [
{ name: "User", description: "User endpoints" },
],
},
})
)
.use(cors())
.get("/", () => {
const result = new ApiResult(
{ code: 200, message: "Success", error: false },
{ status: "ok" }
);
return result;
})
.use(users)
.listen(3000);
My "hotfix" for now is to just manually authenticate the request with the exposed methods.