Skip to content

Commit

Permalink
chore: update middlewares, logger, remove cmd from wrong group
Browse files Browse the repository at this point in the history
  • Loading branch information
Keyrxng committed Oct 29, 2024
1 parent cca629b commit 8831f6e
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 9 deletions.
4 changes: 0 additions & 4 deletions src/bot/setcommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ function getPrivateChatCommands(): BotCommand[] {
command: "wallet",
description: "Register your wallet address",
},
{
command: "setcommands",
description: "Set the bot's commands",
},
];
}

Expand Down
4 changes: 2 additions & 2 deletions src/server/middlewares/request-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function requestLogger(): MiddlewareHandler {
const { method } = c.req;
const path = getPath(c.req.raw);

c.var.logger.debug("Incoming request", {
c.var.logger.info("Incoming request", {
method,
path,
});
Expand All @@ -15,7 +15,7 @@ export function requestLogger(): MiddlewareHandler {
await next();

const endTime = performance.now();
c.var.logger.debug("Request completed", {
c.var.logger.info("Request completed", {
method,
path,
status: c.res.status,
Expand Down
62 changes: 62 additions & 0 deletions src/server/middlewares/wares.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { HTTPException } from "hono/http-exception";
import type { Context } from "hono";

export function rateLimit(options: { windowMs: number; max: number }) {
const hits = new Map<string, { count: number; resetTime: number }>();
return async (c: Context, next: () => Promise<void>) => {
const ip = c.req.header("x-forwarded-for") ?? c.req.header("x-real-ip");
const now = Date.now();
const record = hits.get(ip ?? "") ?? { count: 0, resetTime: now + options.windowMs };
if (record.resetTime <= now) {
record.count = 0;
record.resetTime = now + options.windowMs;
}
record.count++;
if (record.count > options.max) {
c.res.headers.set("Retry-After", Math.ceil((record.resetTime - now) / 1000).toString());
throw new HTTPException(429, { message: "Too Many Requests" });
}
if (ip) {
hits.set(ip, record);
await next();
} else {
// throws when resetting local. Might not be required at all but was for debugging
// throw new HTTPException(400, { message: "Bad Request" });
}
};
}

export function cors(options = { origin: "*", methods: "GET,POST,OPTIONS", headers: "Content-Type" }) {
return async (c: Context, next: () => Promise<void>) => {
c.res.headers.set("Access-Control-Allow-Origin", options.origin);
c.res.headers.set("Access-Control-Allow-Methods", options.methods);
c.res.headers.set("Access-Control-Allow-Headers", options.headers);
if (c.req.method === "OPTIONS") {
return c.text("", 204);
}
await next();
};
}

export function securityHeaders() {
return async (c: Context, next: () => Promise<void>) => {
c.res.headers.set("X-Content-Type-Options", "nosniff");
c.res.headers.set("X-Frame-Options", "DENY");
c.res.headers.set("Referrer-Policy", "no-referrer");
c.res.headers.set("Content-Security-Policy", "default-src 'self'");
await next();
};
}

export function jsonErrorHandler() {
return async (c: Context, next: () => Promise<void>) => {
try {
await next();
} catch (err) {
if (err instanceof SyntaxError && err.message.includes("JSON")) {
throw new HTTPException(400, { message: "Invalid JSON" });
}
throw err;
}
};
}
3 changes: 1 addition & 2 deletions src/types/plugin-context-single.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Value } from "@sinclair/typebox/value";
import { Logs } from "@ubiquity-dao/ubiquibot-logger";
import { createAdapters } from "../adapters";
import { PluginInputs, pluginSettingsSchema } from "./plugin-inputs";
import { Env, envValidator } from "./env";
Expand Down Expand Up @@ -129,7 +128,7 @@ export class PluginContext {
// if we have a token coming from GitHub we'll use it instead of the storage app.
octokit: !this.inputs.authToken ? octokit : this.getGitHubEventOctokit(),
env: this.env,
logger: new Logs("verbose"),
logger,
} as Context;

return {
Expand Down
2 changes: 1 addition & 1 deletion tests/__mocks__/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ async function getValue(body: ReadableStream<Uint8Array> | null) {
try {
return JSON.parse(text);
} catch (error) {
console.error("Failed to parse body as JSON", error);
logger.error("Failed to parse body as JSON", error);
}
}
}
Expand Down

0 comments on commit 8831f6e

Please sign in to comment.