Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Auto detect text files and perform LF normalization
* text=auto

# Explicitly declare text files you want to always be normalized and converted to native line endings on checkout
*.ts text eol=lf
*.tsx text eol=lf
*.js text eol=lf
*.jsx text eol=lf
*.mjs text eol=lf
*.cjs text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.toml text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.html text eol=lf
*.xml text eol=lf
*.svg text eol=lf
*.sh text eol=lf

# Lock files should maintain LF
package-lock.json text eol=lf
bun.lockb binary
bun.lock text eol=lf
yarn.lock text eol=lf
pnpm-lock.yaml text eol=lf

# Denote all files that are truly binary and should not be modified
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary
*.pdf binary
*.zip binary
*.gz binary

# Windows-specific files
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ yarn-error.log*

*storybook.log
storybook-static

# IDE
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.idea
*.swp
*.swo
*~

# OS
Thumbs.db
15 changes: 15 additions & 0 deletions apps/backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Database Configuration
DATABASE_URL=postgresql://user:password@localhost:5432/eventer

# Supabase Configuration
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-key-here

# Server Configuration
PORT=4000
NODE_ENV=development

# CORS Configuration
# In development: http://localhost:3000
# In production: https://your-domain.com
CORS_ORIGIN=http://localhost:3000
31 changes: 25 additions & 6 deletions apps/backend/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
// import type { VercelRequest, VercelResponse } from "@vercel/node";
import type { VercelRequest, VercelResponse } from "@vercel/node";
import { app } from "../src";

export const config = {
runtime: "edge", // Required for edge deployment
};
export default async function handler(req: VercelRequest, res: VercelResponse) {
// Convert Vercel request to Web Request
const url = `${req.headers["x-forwarded-proto"] || "http"}://${req.headers.host}${req.url}`;
const headers = new Headers();
Object.entries(req.headers).forEach(([key, value]) => {
if (value) headers.set(key, Array.isArray(value) ? value.join(", ") : value);
});

export default async function handler(request: Request): Promise<Response> {
return app.handle(request);
const request = new Request(url, {
method: req.method,
headers,
body: req.method !== "GET" && req.method !== "HEAD" ? JSON.stringify(req.body) : undefined,
});

// Handle with Elysia
const response = await app.handle(request);

// Convert Web Response to Vercel Response
res.status(response.status);
response.headers.forEach((value, key) => {
res.setHeader(key, value);
});

const body = await response.text();
res.send(body);
}
2 changes: 1 addition & 1 deletion apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"scripts": {
"dev": "bun --watch src/index.ts",
"dev:cf": "wrangler dev",
"build": "bun build src/index.ts --outdir ./dist --target=node",
"build": "bun build src/index.ts --outdir ./dist --target=node --minify --external @supabase/supabase-js --external postgres --external drizzle-orm",
"start": "bun run dist/index.js",
"typecheck": "bun tsc --noEmit",
"db:migrate": "drizzle-kit migrate --config=drizzle.config.ts",
Expand Down
26 changes: 17 additions & 9 deletions apps/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ const conditionalSwagger = () => {
const app = new Elysia({ aot: false })
.use(
cors({
// origin: "https://eventer.betich.me",
origin: /.*\.betich\.me$/,
// [
// /.*\.betich\.me$/,
// process.env.NODE_ENV === "development" ? /localhost:\d+/ : "",
// env.CORS_ORIGIN || "",
// ],
origin:
process.env.NODE_ENV === "production"
? [/^https:\/\/.*\.betich\.me$/] // Only your domain in production
: [env.CORS_ORIGIN, /localhost:\d+/], // Allow localhost in dev
credentials: true,
preflight: true,
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
Expand All @@ -43,9 +40,20 @@ const app = new Elysia({ aot: false })
.use(userRouter)
.use(agendaRouter)
.use(authRouter)
.onRequest(({ set }) => {
.onRequest(({ request, set }) => {
set.headers["access-control-allow-credentials"] = "true";
// set.headers["access-control-allow-origin"] = "https://eventer.betich.me";

// Force HTTPS in production
if (process.env.NODE_ENV === "production") {
const proto = request.headers.get("x-forwarded-proto");
if (proto && proto !== "https") {
const url = new URL(request.url);
url.protocol = "https:";
set.status = 301;
set.headers.location = url.toString();
return;
}
}
});
// .group("/api", (app) =>
// app
Expand Down
8 changes: 8 additions & 0 deletions apps/backend/src/modules/agenda/agenda.route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Elysia, t } from "elysia";
import { db } from "#backend/infrastructure/db";
import { rateLimit, rateLimitPresets } from "#backend/shared/middleware/rate-limit.middleware";
import {
AgendaListResponseSchema,
AgendaSchema,
Expand All @@ -24,6 +25,13 @@ const agendaRepository = new AgendaRepository(db);
//TODO : Implement useGetAgenda(eventId, currentDay)

export const agendaRouter = new Elysia({ prefix: "/api/agenda" })
// Apply moderate rate limiting to agenda endpoints (30 requests per minute)
.use(
rateLimit({
...rateLimitPresets.moderate,
message: "Too many requests to agenda API. Please slow down.",
})
)

.get(
"/timer",
Expand Down
Loading
Loading