Compare commits

...

6 Commits

4 changed files with 42 additions and 41 deletions

View File

@ -1,22 +1,25 @@
{ {
"name": "backend", "name": "backend",
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
"private": true, "private": true,
"devDependencies": { "scripts": {
"@types/bun": "latest", "start": "bun run src/index.ts"
"@types/pg": "^8.15.6", },
"drizzle-kit": "^0.31.6", "devDependencies": {
"tsx": "^4.20.6" "@types/bun": "latest",
}, "@types/pg": "^8.15.6",
"peerDependencies": { "drizzle-kit": "^0.31.6",
"typescript": "^5" "tsx": "^4.20.6"
}, },
"dependencies": { "peerDependencies": {
"dotenv": "^17.2.3", "typescript": "^5"
"drizzle-orm": "^0.44.7", },
"pg": "^8.16.3", "dependencies": {
"zod": "^4.1.12", "dotenv": "^17.2.3",
"types": "workspace:*" "drizzle-orm": "^0.44.7",
} "pg": "^8.16.3",
"zod": "^4.1.12",
"types": "workspace:*"
}
} }

View File

@ -6,7 +6,7 @@ import { styleText } from "node:util";
const CORS_HEADERS = { const CORS_HEADERS = {
"Access-Control-Allow-Origin": ENV.FRONTEND_URL, "Access-Control-Allow-Origin": ENV.FRONTEND_URL,
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization", "Access-Control-Allow-Headers": "*",
}; };
const allowCors = async (_: Request): Promise<Response> => { const allowCors = async (_: Request): Promise<Response> => {
@ -16,7 +16,7 @@ const allowCors = async (_: Request): Promise<Response> => {
type Handler = (req: Request) => Promise<Response>; type Handler = (req: Request) => Promise<Response>;
type Middleware = (fn: Handler) => Handler; type Middleware = (fn: Handler) => Handler;
const withCors = (fn: Handler): Handler => { const withCors: Middleware = (fn) => {
return async (req) => { return async (req) => {
const res = await fn(req); const res = await fn(req);
@ -42,7 +42,7 @@ const getColors = (status: number): Parameters<typeof styleText>[0] => {
} }
}; };
const withLogger = (fn: Handler): Handler => { const withLogger: Middleware = (fn) => {
return async (req) => { return async (req) => {
const res = await fn(req); const res = await fn(req);
@ -58,26 +58,14 @@ const withLogger = (fn: Handler): Handler => {
}; };
}; };
const withFrontendReferrer: Middleware = (fn) => {
return async (req) => {
const referrer = req.headers.get("referrer");
if (referrer !== ENV.FRONTEND_URL) {
return new Response(undefined, { status: 403 });
}
return fn(req);
};
};
const server = Bun.serve({ const server = Bun.serve({
port: ENV.PORT, port: ENV.PORT,
routes: { routes: {
"/health": new Response("alive!"), "/health": new Response("alive!"),
"/sign": { "/sign": {
GET: withFrontendReferrer(withLogger(withCors(getPetitions))), GET: withLogger(withCors(getPetitions)),
POST: withFrontendReferrer(withLogger(withCors(signPetition))), POST: withLogger(withCors(signPetition)),
OPTIONS: withFrontendReferrer(withLogger(allowCors)), OPTIONS: withLogger(allowCors),
}, },
}, },
}); });

View File

@ -1,5 +1,6 @@
import { db } from "./database"; import { db } from "./database";
import { signaturesTable } from "./schema"; import { signaturesTable } from "./schema";
import { desc } from "drizzle-orm";
export const insertSignature = async ( export const insertSignature = async (
signature: typeof signaturesTable.$inferInsert, signature: typeof signaturesTable.$inferInsert,
@ -15,5 +16,8 @@ export const insertSignature = async (
export const getSignatures = async (): Promise< export const getSignatures = async (): Promise<
Array<typeof signaturesTable.$inferSelect> Array<typeof signaturesTable.$inferSelect>
> => { > => {
return db.select().from(signaturesTable); return db
.select()
.from(signaturesTable)
.orderBy(desc(signaturesTable.createdAt));
}; };

View File

@ -6,9 +6,15 @@ import { ArrowLeft, Users } from "lucide-react";
import { usePetitions } from "@/state"; import { usePetitions } from "@/state";
const Testimonies = () => { const Testimonies = () => {
const { signatures } = usePetitions(); const { signatures: allSignatures } = usePetitions();
const signatures = allSignatures
.filter((s) => s.comment != null)
.map((s) => ({
...s,
name: s.name ?? "Anonymous",
}));
const totalCount = signatures.length; const totalCount = allSignatures.length;
const navigate = useNavigate(); const navigate = useNavigate();