103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
import type { Hono } from "hono";
|
|
import { contextStorage } from "hono/context-storage";
|
|
import { cors } from "hono/cors";
|
|
import { languageDetector } from "hono/language";
|
|
import isMobile from "is-mobile";
|
|
import { JwtProvider } from "../utils/token";
|
|
type AppFetch = (
|
|
input: string | Request | URL,
|
|
requestInit?: RequestInit
|
|
) => Response | Promise<Response>;
|
|
|
|
type RedisClientLike = {
|
|
connect(): Promise<unknown>;
|
|
get(key: string): Promise<string | null>;
|
|
set(...args: unknown[]): Promise<unknown> | unknown;
|
|
del(key: string): Promise<unknown> | unknown;
|
|
};
|
|
|
|
declare module "hono" {
|
|
interface ContextVariableMap {
|
|
fetch: AppFetch;
|
|
isMobile: boolean;
|
|
redis: RedisClientLike;
|
|
jwtProvider: JwtProvider;
|
|
jwtPayload: Record<string, unknown>;
|
|
userId: string;
|
|
role: string;
|
|
email: string;
|
|
}
|
|
}
|
|
|
|
let redisClientPromise: Promise<RedisClientLike> | null = null;
|
|
|
|
const getJwtSecret = () => {
|
|
const secret = (process.env.JWT_SECRET || process.env.STREAM_UI_JWT_SECRET || "").trim() || "secret_is_not_configured"
|
|
if (!secret) {
|
|
throw new Error("JWT secret is not configured");
|
|
}
|
|
return secret;
|
|
};
|
|
|
|
const getRedisUrl = () => {
|
|
const redisUrl = (process.env.REDIS_URL || process.env.STREAM_UI_REDIS_URL || "").trim() || "redis://:pass123@47.84.62.226:6379/3";
|
|
if (!redisUrl) {
|
|
throw new Error("Redis URL is not configured");
|
|
}
|
|
return redisUrl;
|
|
};
|
|
|
|
const getRedisClient = async (): Promise<RedisClientLike> => {
|
|
console.log("bun", typeof Bun)
|
|
|
|
if (!redisClientPromise) {
|
|
// redisClientPromise = import("Bun").then(async ({ RedisClient }) => {
|
|
// const client = new RedisClient(getRedisUrl()) as RedisClientLike;
|
|
// await client.connect();
|
|
// return client;
|
|
// });
|
|
}
|
|
// return await redisClientPromise;
|
|
return Promise.resolve() as any
|
|
};
|
|
|
|
export function setupMiddlewares(app: Hono) {
|
|
app.use(
|
|
"*",
|
|
languageDetector({
|
|
supportedLanguages: ["vi", "en"],
|
|
fallbackLanguage: "en",
|
|
lookupCookie: "i18next",
|
|
lookupFromHeaderKey: "accept-language",
|
|
order: ["cookie", "header"],
|
|
}),
|
|
contextStorage(),
|
|
async (c, next) => {
|
|
c.set("jwtProvider", JwtProvider.newJWTProvider(getJwtSecret()));
|
|
await next();
|
|
}
|
|
);
|
|
|
|
app.use(cors(), async (c, next) => {
|
|
c.set("fetch", app.request.bind(app));
|
|
|
|
const ua = c.req.header("User-Agent");
|
|
if (!ua) {
|
|
return c.json({ error: "User-Agent header is missing" }, 400);
|
|
}
|
|
|
|
c.set("isMobile", isMobile({ ua }));
|
|
await next();
|
|
});
|
|
app.use(async (c, next) => {
|
|
try {
|
|
const redisClient = await getRedisClient();
|
|
c.set("redis", redisClient);
|
|
await next();
|
|
} catch (e) {
|
|
console.error("Failed to connect to Redis", e);
|
|
return c.json({ error: "Redis unavailable" }, 500);
|
|
}
|
|
});
|
|
}
|