bunrest
bunrest copied to clipboard
Handlers Failing to Chain
Update 2 | Notes for Global Use
Global use seems to be failing for handlers that have a middleware with the following type: (req: BunRequest, res: BunResponse, next?: (err?: Error) => {}, err?: Error) => void | Promise<any>
. Once I removed the err?: Error
from my cors handler it was registering globally. I could then proceed to use it as follows:
app.use(cors());
Update 1 | Fix for Chaining
Got a solution for the chaining:
bunrest/src/server.ts
private openServer(...args): Server {
// other code
// middlewares hander
if (that.middlewares.length !== 0) {
const plainMid = that.middlewares.filter(mid => req.path.startsWith(mid.path) || mid.path === '*');
// rest of code
}
}
Slightly altering the plainMid
variable makes all the difference. Now middlewares in route handlers chain such as:
app.get("/path", middleware1, middleware2, async (req, res) => {
// code
});
Original Issue
So I was having issues with the Express cors
package and began creating one that is fully compatible and typed with bunrest
(ideally for release as a package down the road). That being said, my middlewares are not chaining. I have a custom auth middleware to handle API keys and what not which is crucial, however, my cors is only being hit when there's a preflight (I have to specifically add it to router.options
). Here is what I have:
auth.ts
authRouter.post(
"/logout",
cors({
allowedHeaders: ["X-API-KEY", "X-AUTH-TOKEN"],
methods: ["GET", "POST", "PATCH"],
origins: ["https://www.test.dev"],
}),
authMiddleware,
async (req, res) => {
try {
await doSomething();
res.status(200).json({ success: true });
} catch (ex) {
res.status(500).json({ success: false });
}
}
);
cors.ts
NOTE: this is a stripped down version
export default function cors(options?: CorsOptions) {
const _isOrigin = (header: string): boolean => {
if (Array.isArray(origins)) return origins.includes(header);
else return true;
};
const middelware: Handler = (req, res, next?, err?) => {
console.log("hit");
// @ts-ignore
const host = req.headers["host"];
const isvalidOriginNoPreflight = _isOrigin(host);
if (!isvalidOriginNoPreflight) {
res.status(400).send("");
}
// @ts-ignore
next();
}
};
return middelware;
}
authMiddleware.ts
export const authMiddleware: Handler = (req, res, next?, err?) => {
const isValid = validateStuff();
if (!isValid) {
res.status(401).json({
message: "Access Denied",
});
} else {
// @ts-ignore
next();
}
} else {
res.status(400).json({ message: "Invalid credentials provided." });
}
};
I am sending my request from Postman localhost, so when I only include the cors
middleware it rejects my request due to the host not being part of the origins. Equally, when I only include the authMiddleware
it does what it should. However, when I chain them, only the last middleware works. So if it goes cors
, then authMiddleware
; only the auth middleware will run and vice versa.
Additionally, the global app.use(req, res, next?, err?) => {...}
does not hit the cors
(express or my custom one) middleware if I put it in there.
Other Relevant Info:
Bun version: v1.0.7
bunrest version: v1.3.6
platform: ubuntu 20.04 (docker image)
node installed: yes
node version: v18.18.2