Initial commit: Setup Bun, Elysia, Vite, React, TanStack Router, Mantine, and Biome

This commit is contained in:
bipproduction
2026-02-07 02:15:29 +08:00
commit b9abcaadde
46 changed files with 5742 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
import type Elysia from "elysia";
import { auth } from "@/utils/auth";
import { prisma } from "@/utils/db";
import logger from "@/utils/logger";
export function apiMiddleware(app: Elysia) {
return app
.derive(async ({ request }) => {
const headers = request.headers;
// First, try to get user from session (Better Auth)
const userSession = await auth.api.getSession({
headers,
});
if (userSession?.user) {
// Return user data from session if authenticated via session
return {
user: {
...userSession.user,
id: userSession.user.id,
email: userSession.user.email,
name: userSession.user.name,
image: userSession.user.image,
emailVerified: userSession.user.emailVerified,
role: userSession.user.role || "user",
},
};
}
// If no session, try API key authentication
let apiKey = headers.get("x-api-key");
if (!apiKey) {
// Also check Authorization header for API key
const authHeader =
headers.get("authorization") || headers.get("Authorization");
if (authHeader?.startsWith("Bearer ")) {
apiKey = authHeader.substring(7);
}
}
if (!apiKey) {
return { user: null };
}
try {
// Look up the API key in the database
const apiKeyRecord = await prisma.apiKey.findFirst({
where: {
key: apiKey,
isActive: true,
},
include: {
user: true, // Include the associated user
},
});
if (!apiKeyRecord) {
return { user: null };
}
// Check if API key has expired
if (
apiKeyRecord.expiresAt &&
new Date(apiKeyRecord.expiresAt) < new Date()
) {
logger.info({ keyId: apiKeyRecord.id }, "[AUTH] API key expired");
return { user: null };
}
// Return the associated user data
return {
user: {
id: apiKeyRecord.user.id,
email: apiKeyRecord.user.email,
name: apiKeyRecord.user.name,
image: apiKeyRecord.user.image,
emailVerified: apiKeyRecord.user.emailVerified,
role: apiKeyRecord.user.role || "user",
},
};
} catch (err) {
logger.warn({ err }, "[AUTH] Error verifying API key");
return { user: null };
}
})
.onBeforeHandle(({ user, set, request }) => {
if (!user) {
logger.warn(`[AUTH] Unauthorized: ${request.method} ${request.url}`);
set.status = 401;
return { message: "Unauthorized" };
}
});
}

View File

@@ -0,0 +1,125 @@
import { redirect } from "@tanstack/react-router";
/* ================================
* Types
* ================================ */
type UserRole = "user" | "admin";
type SessionUser = {
id: string;
role: UserRole;
};
type SessionResponse = {
user?: SessionUser;
};
/* ================================
* Session Fetcher
* ================================ */
async function fetchSession(): Promise<SessionResponse | null> {
try {
const baseURL =
import.meta.env.VITE_PUBLIC_URL || window.location.origin;
const res = await fetch(`${baseURL}/api/session`, {
method: "GET",
credentials: "include",
});
if (!res.ok) return null;
const { data } = await res.json();
return data as SessionResponse;
} catch {
return null;
}
}
/* ================================
* Redirect Helper
* ================================ */
function redirectToLogin(to: string, currentHref: string) {
throw redirect({
to,
search: { redirect: currentHref },
});
}
/* ================================
* Route Rules (Pattern Based)
* ================================ */
type RouteRule = {
match: (pathname: string) => boolean;
requireAuth?: boolean;
requiredRole?: UserRole;
redirectTo?: string;
};
const routeRules: RouteRule[] = [
{
match: (p) => p === "/profile" || p.startsWith("/profile/"),
requireAuth: true,
redirectTo: "/signin",
},
{
match: (p) => p === "/dashboard" || p.startsWith("/dashboard/"),
requireAuth: true,
requiredRole: "admin",
redirectTo: "/profile",
},
];
/* ================================
* Rule Resolver
* ================================ */
function findRouteRule(pathname: string): RouteRule | undefined {
return routeRules.find((rule) => rule.match(pathname));
}
/* ================================
* Protected Route Factory
* ================================ */
export interface ProtectedRouteOptions {
redirectTo?: string;
}
export function createProtectedRoute(options: ProtectedRouteOptions = {}) {
const { redirectTo = "/signin" } = options;
return async ({
location,
}: {
location: { pathname: string; href: string };
}) => {
const rule = findRouteRule(location.pathname);
if (!rule) return;
const session = await fetchSession();
const user = session?.user;
if (rule.requireAuth && !user) {
redirectToLogin(rule.redirectTo ?? redirectTo, location.href);
}
if (rule.requiredRole && user?.role !== rule.requiredRole) {
redirectToLogin(rule.redirectTo ?? redirectTo, location.href);
}
return {
session,
user,
};
};
}
/* ================================
* Default Middleware Export
* ================================ */
export const protectedRouteMiddleware = createProtectedRoute();