add Keycloak, add better canvas
This commit is contained in:
@@ -1,9 +1,42 @@
|
||||
import type { Express } from "express";
|
||||
import type { Express, Request, Response, NextFunction } from "express";
|
||||
import { createServer, type Server } from "http";
|
||||
import { WebSocketServer, WebSocket } from "ws";
|
||||
import { storage } from "./storage";
|
||||
import { insertPixelSchema, insertUserCooldownSchema, type WSMessage } from "@shared/schema";
|
||||
import { CanvasExporter } from "./export";
|
||||
import { config } from "./config";
|
||||
|
||||
// Authentication middleware
|
||||
function requireAuth(req: Request, res: Response, next: NextFunction) {
|
||||
if (!config.enableKeycloak) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// Check if user is authenticated via Keycloak
|
||||
if (req.kauth && req.kauth.grant) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return res.status(401).json({ message: "Authentication required" });
|
||||
}
|
||||
|
||||
// Get user info from Keycloak token
|
||||
function getUserFromToken(req: Request): { userId: string; username: string } {
|
||||
if (!config.enableKeycloak || !req.kauth?.grant?.access_token) {
|
||||
return {
|
||||
userId: "User",
|
||||
username: "Anonymous"
|
||||
};
|
||||
}
|
||||
|
||||
const token = req.kauth.grant.access_token;
|
||||
const content = token.content;
|
||||
|
||||
return {
|
||||
userId: content.sub || content.preferred_username || "User",
|
||||
username: content.preferred_username || content.name || "User"
|
||||
};
|
||||
}
|
||||
|
||||
export async function registerRoutes(app: Express): Promise<Server> {
|
||||
const httpServer = createServer(app);
|
||||
@@ -15,6 +48,38 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
const exporter = new CanvasExporter(storage);
|
||||
exporter.startAutoExport();
|
||||
|
||||
// Authentication Routes
|
||||
app.get("/api/auth/status", (req, res) => {
|
||||
if (!config.enableKeycloak) {
|
||||
return res.json({ authenticated: false, keycloakEnabled: false });
|
||||
}
|
||||
|
||||
const isAuthenticated = req.kauth && req.kauth.grant;
|
||||
const user = isAuthenticated ? getUserFromToken(req) : null;
|
||||
|
||||
res.json({
|
||||
authenticated: isAuthenticated,
|
||||
keycloakEnabled: true,
|
||||
user: user
|
||||
});
|
||||
});
|
||||
|
||||
// Login redirect
|
||||
app.get("/login", (req, res) => {
|
||||
if (config.enableKeycloak && req.kauth) {
|
||||
return req.kauth.login(req, res);
|
||||
}
|
||||
res.redirect("/");
|
||||
});
|
||||
|
||||
// Logout
|
||||
app.get("/logout", (req, res) => {
|
||||
if (config.enableKeycloak && req.kauth) {
|
||||
return req.kauth.logout(req, res);
|
||||
}
|
||||
res.redirect("/");
|
||||
});
|
||||
|
||||
// API Routes
|
||||
app.get("/api/pixels", async (req, res) => {
|
||||
try {
|
||||
@@ -37,9 +102,14 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Config is now read-only from file
|
||||
// Remove the POST endpoint for config updates
|
||||
|
||||
app.post("/api/pixels", async (req, res) => {
|
||||
app.post("/api/pixels", requireAuth, async (req, res) => {
|
||||
try {
|
||||
const pixelData = insertPixelSchema.parse(req.body);
|
||||
const userInfo = getUserFromToken(req);
|
||||
const pixelData = insertPixelSchema.parse({
|
||||
...req.body,
|
||||
userId: userInfo.userId,
|
||||
username: userInfo.username
|
||||
});
|
||||
const config = await storage.getCanvasConfig();
|
||||
|
||||
// Validate coordinates
|
||||
@@ -50,7 +120,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
|
||||
// Check cooldown unless events are enabled
|
||||
if (!config.enableAutomaticEvents) {
|
||||
const cooldown = await storage.getUserCooldown(pixelData.userId);
|
||||
const cooldown = await storage.getUserCooldown(userInfo.userId);
|
||||
if (cooldown && cooldown.cooldownEnds > new Date()) {
|
||||
return res.status(429).json({ message: "Cooldown active" });
|
||||
}
|
||||
@@ -58,7 +128,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Set new cooldown
|
||||
const cooldownEnd = new Date(Date.now() + (config.defaultCooldown * 1000));
|
||||
await storage.setUserCooldown({
|
||||
userId: pixelData.userId,
|
||||
userId: userInfo.userId,
|
||||
cooldownEnds: cooldownEnd,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user