Add user authentication and dynamic feature/category inputs

Implement Keycloak authentication, protected routes, and add combobox and autocomplete components for tool categories and features.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 776963d0-f75d-42e2-a57b-cc36bdff8495
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 0b145113-c016-4f54-b000-13bd3b0ba8f0
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0683fb79-a27c-485c-9333-5f4b288c4567/776963d0-f75d-42e2-a57b-cc36bdff8495/z4uWN6A
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
cheffe01
2026-05-25 13:20:15 +00:00
parent e03c51a75e
commit 7abb048edc
22 changed files with 1027 additions and 68 deletions
+28 -1
View File
@@ -1,11 +1,18 @@
import express, { type Express } from "express";
import cors from "cors";
import pinoHttp from "pino-http";
import session from "express-session";
import ConnectPgSimple from "connect-pg-simple";
import router from "./routes";
import { logger } from "./lib/logger";
import "./types/session.d.ts";
const PgStore = ConnectPgSimple(session);
const app: Express = express();
app.set("trust proxy", 1);
app.use(
pinoHttp({
logger,
@@ -25,10 +32,30 @@ app.use(
},
}),
);
app.use(cors());
app.use(cors({ origin: true, credentials: true }));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
session({
store: new PgStore({
conString: process.env.DATABASE_URL,
tableName: "sessions",
createTableIfMissing: true,
}),
secret: process.env.SESSION_SECRET || "dev-secret-change-in-production",
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === "production",
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24 * 7, // 7 days
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
},
}),
);
app.use("/api", router);
export default app;