- Create @reviq/utils package with PBKDF2-SHA256 password hashing compatible with Cloudflare Workers (uses crypto.subtle) - Update api-server and CLI to use new utils package for consistent password hashing format across the codebase - Add pino logging to api-server for better request debugging - Make login request tokens cryptographically secure base58 strings instead of database IDs - Add migration to make login_requests.token non-nullable with unique constraint - Fix RPCLink URL construction for client-side API calls - Add db:codegen script to root package.json Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
78 lines
1.8 KiB
TypeScript
78 lines
1.8 KiB
TypeScript
import type { APIContext } from "./context.js";
|
|
import { LoggingHandlerPlugin } from "@orpc/experimental-pino";
|
|
import { RPCHandler } from "@orpc/server/fetch";
|
|
import { createDb } from "@reviq/db";
|
|
import pino from "pino";
|
|
import {
|
|
DEFAULT_PORT,
|
|
DEFAULT_RP_NAME,
|
|
getAllowedOrigins,
|
|
} from "./constants.js";
|
|
import { router } from "./router.js";
|
|
|
|
const logger = pino({
|
|
transport: {
|
|
target: "pino-pretty",
|
|
options: {
|
|
colorize: true,
|
|
},
|
|
},
|
|
});
|
|
|
|
const db = createDb();
|
|
const handler = new RPCHandler(router, {
|
|
plugins: [
|
|
new LoggingHandlerPlugin({
|
|
logger,
|
|
logRequestResponse: true,
|
|
}),
|
|
],
|
|
});
|
|
|
|
const port = Bun.env.PORT ?? DEFAULT_PORT;
|
|
const allowedOrigins = getAllowedOrigins();
|
|
const rpName = Bun.env.RP_NAME ?? DEFAULT_RP_NAME;
|
|
|
|
Bun.serve({
|
|
port,
|
|
async fetch(request) {
|
|
const url = new URL(request.url);
|
|
|
|
if (url.pathname.startsWith("/api/v1/rpc")) {
|
|
// Build context for the request
|
|
const origin =
|
|
request.headers.get("origin") ?? `http://localhost:${String(port)}`;
|
|
|
|
// Create response headers for setting cookies
|
|
const resHeaders = new Headers();
|
|
|
|
const context: APIContext = {
|
|
db,
|
|
origin,
|
|
allowedOrigins,
|
|
rpName,
|
|
reqHeaders: request.headers,
|
|
resHeaders,
|
|
};
|
|
|
|
const { response } = await handler.handle(request, {
|
|
prefix: "/api/v1/rpc",
|
|
context,
|
|
});
|
|
|
|
// Merge response headers (cookies) into the response
|
|
if (response) {
|
|
resHeaders.forEach((value, key) => {
|
|
response.headers.append(key, value);
|
|
});
|
|
}
|
|
|
|
return response ?? new Response("Not Found", { status: 404 });
|
|
}
|
|
|
|
return new Response("Not Found", { status: 404 });
|
|
},
|
|
});
|
|
|
|
logger.info({ port }, "API server running");
|