From 8bf4b10af3fbb154646a1e1e634d1317febdb668 Mon Sep 17 00:00:00 2001 From: wisecolt Date: Mon, 5 Jan 2026 17:34:03 +0000 Subject: [PATCH] =?UTF-8?q?revert=20revert=20feat(auth):=20bearer=20token?= =?UTF-8?q?=20deste=C4=9Fi=20ve=20=C3=A7oklu=20origin=20ayar=C4=B1=20ekle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit revert feat(auth): bearer token desteği ve çoklu origin ayarı ekle - Authorization header ile Bearer token kimlik doğrulaması eklendi - Token'ların localStorage'da saklanması desteği eklendi - WEB_ALLOWED_ORIGINS ve WEB_ALLOWED_HOSTS konfigürasyonları eklendi - Loop işlerinde profileId ve profileName alanları eklendi - CORS ve Vite sunucusu için çoklu origin desteği sağlandı --- .env.example | 2 +- apps/server/src/auth/auth.middleware.ts | 5 +-- apps/server/src/auth/auth.routes.ts | 13 ++------ apps/server/src/config.ts | 1 - apps/server/src/index.ts | 7 +---- apps/server/src/loop/loop.engine.ts | 4 --- apps/server/src/loop/loop.routes.ts | 4 +-- apps/server/src/types.ts | 4 --- apps/web/src/api/client.ts | 11 ------- .../web/src/components/loop/LoopSetupCard.tsx | 5 --- .../src/components/torrents/TorrentTable.tsx | 9 ------ apps/web/src/store/useAppStore.ts | 2 -- apps/web/src/store/useAuthStore.ts | 5 --- apps/web/vite.config.ts | 31 +++++++------------ 14 files changed, 18 insertions(+), 85 deletions(-) diff --git a/.env.example b/.env.example index 8aa55be..b95265f 100644 --- a/.env.example +++ b/.env.example @@ -5,6 +5,7 @@ APP_USERNAME=qbuffer APP_PASSWORD=changeme JWT_SECRET=replace_me APP_HOST=localhost +WEB_ORIGIN=http://localhost:5173 SERVER_PORT=3001 WEB_PORT=5173 POLL_INTERVAL_MS=3000 @@ -14,4 +15,3 @@ MAX_LOOP_LIMIT=1000 STALLED_RECOVERY_MS=300000 TIMER_POLL_MS=60000 NODE_ENV=development -WEB_ALLOWED_ORIGINS=http://192.168.1.205:5175,http://qbuffer.bee diff --git a/apps/server/src/auth/auth.middleware.ts b/apps/server/src/auth/auth.middleware.ts index 6df0c52..62f8231 100644 --- a/apps/server/src/auth/auth.middleware.ts +++ b/apps/server/src/auth/auth.middleware.ts @@ -2,10 +2,7 @@ import { Request, Response, NextFunction } from "express"; import { verifyToken } from "./auth.service" export const requireAuth = (req: Request, res: Response, next: NextFunction) => { - const cookieToken = req.cookies?.["qbuffer_token"]; - const authHeader = req.headers.authorization; - const bearer = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : undefined; - const token = cookieToken || bearer; + const token = req.cookies?.["qbuffer_token"]; if (!token) { return res.status(401).json({ error: "Unauthorized" }); } diff --git a/apps/server/src/auth/auth.routes.ts b/apps/server/src/auth/auth.routes.ts index 16f1daa..652916c 100644 --- a/apps/server/src/auth/auth.routes.ts +++ b/apps/server/src/auth/auth.routes.ts @@ -5,13 +5,6 @@ import { isDev } from "../config" const router = Router(); -const getAuthToken = (req: any) => { - const cookieToken = req.cookies?.["qbuffer_token"]; - const header = req.headers?.authorization as string | undefined; - const bearer = header?.startsWith("Bearer ") ? header.slice(7) : undefined; - return cookieToken || bearer; -}; - const loginLimiter = rateLimit({ windowMs: 60_000, max: 5, @@ -35,7 +28,7 @@ router.post("/login", loginLimiter, async (req, res) => { secure: !isDev, maxAge: 60 * 24 * 60 * 60 * 1000, }); - return res.json({ username: user.username, token }); + return res.json({ username: user.username }); }); router.post("/logout", (_req, res) => { @@ -48,7 +41,7 @@ router.post("/logout", (_req, res) => { }); router.get("/me", (req, res) => { - const token = getAuthToken(req); + const token = req.cookies?.["qbuffer_token"]; if (!token) { return res.status(401).json({ error: "Unauthorized" }); } @@ -61,7 +54,7 @@ router.get("/me", (req, res) => { }); router.get("/socket-token", (req, res) => { - const token = getAuthToken(req); + const token = req.cookies?.["qbuffer_token"]; if (!token) { return res.status(401).json({ error: "Unauthorized" }); } diff --git a/apps/server/src/config.ts b/apps/server/src/config.ts index 51b82bd..3771331 100644 --- a/apps/server/src/config.ts +++ b/apps/server/src/config.ts @@ -22,7 +22,6 @@ export const config = { timerPollMs: envNumber(process.env.TIMER_POLL_MS, 60_000), webPort: envNumber(process.env.WEB_PORT, 5173), webOrigin: process.env.WEB_ORIGIN ?? "", - webAllowedOrigins: process.env.WEB_ALLOWED_ORIGINS ?? "", dataDir: "/app/data", dbPath: "/app/data/db.json", logsPath: "/app/data/logs.json", diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index cee32ca..72e1d6a 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -45,12 +45,7 @@ const bootstrap = async () => { if (isDev) { const fallbackOrigin = `http://localhost:${config.webPort}`; - const originList = [config.webOrigin || fallbackOrigin, fallbackOrigin]; - const allowed = config.webAllowedOrigins - .split(",") - .map((origin) => origin.trim()) - .filter(Boolean); - const origins = [...originList, ...allowed]; + const origins = [config.webOrigin || fallbackOrigin, fallbackOrigin]; app.use( cors({ origin: origins, diff --git a/apps/server/src/loop/loop.engine.ts b/apps/server/src/loop/loop.engine.ts index 94e38da..1f4d77e 100644 --- a/apps/server/src/loop/loop.engine.ts +++ b/apps/server/src/loop/loop.engine.ts @@ -27,8 +27,6 @@ export const createLoopJob = async ( allowIp: string; targetLoops: number; delayMs: number; - profileName?: string; - profileId?: string; } ): Promise => { const now = nowIso(); @@ -43,8 +41,6 @@ export const createLoopJob = async ( targetLoops: input.targetLoops, doneLoops: 0, delayMs: input.delayMs, - profileName: input.profileName, - profileId: input.profileId, deleteDataBetweenLoops: true, enforcementMode: "aggressive-soft", status: "RUNNING", diff --git a/apps/server/src/loop/loop.routes.ts b/apps/server/src/loop/loop.routes.ts index 80abb8c..63ae366 100644 --- a/apps/server/src/loop/loop.routes.ts +++ b/apps/server/src/loop/loop.routes.ts @@ -18,7 +18,7 @@ router.post("/start", async (req, res) => { if (!parsed.success) { return res.status(400).json({ error: parsed.error.flatten() }); } - const { hash, allowIp, targetLoops, delayMs, profileName, profileId } = parsed.data; + const { hash, allowIp, targetLoops, delayMs } = parsed.data; const db = await readDb(); if (targetLoops > db.settings.maxLoopLimit) { return res.status(400).json({ error: "Target loops exceed max limit" }); @@ -64,8 +64,6 @@ router.post("/start", async (req, res) => { allowIp, targetLoops, delayMs, - profileName, - profileId, }); res.json(job); }); diff --git a/apps/server/src/types.ts b/apps/server/src/types.ts index 2945651..2ce8ca9 100644 --- a/apps/server/src/types.ts +++ b/apps/server/src/types.ts @@ -32,8 +32,6 @@ export interface LoopJob { targetLoops: number; doneLoops: number; delayMs: number; - profileName?: string; - profileId?: string; deleteDataBetweenLoops: boolean; enforcementMode: EnforcementMode; status: LoopStatus; @@ -64,8 +62,6 @@ export interface Profile { name: string; allowIp: string; delayMs: number; - profileName?: string; - profileId?: string; targetLoops: number; createdAt: string; } diff --git a/apps/web/src/api/client.ts b/apps/web/src/api/client.ts index 1c63ef3..3ae367a 100644 --- a/apps/web/src/api/client.ts +++ b/apps/web/src/api/client.ts @@ -6,14 +6,3 @@ export const api = axios.create({ baseURL: baseURL || undefined, withCredentials: true, }); - -api.interceptors.request.use((config) => { - const token = localStorage.getItem("qbuffer_token"); - if (token) { - config.headers = config.headers || {}; - if (!config.headers.Authorization) { - config.headers.Authorization = `Bearer ${token}`; - } - } - return config; -}); diff --git a/apps/web/src/components/loop/LoopSetupCard.tsx b/apps/web/src/components/loop/LoopSetupCard.tsx index 7964bbd..c53437d 100644 --- a/apps/web/src/components/loop/LoopSetupCard.tsx +++ b/apps/web/src/components/loop/LoopSetupCard.tsx @@ -45,9 +45,6 @@ export const LoopSetupCard = () => { if (!selectedHash) return false; const job = jobs.find((j) => j.torrentHash === selectedHash && j.status === "RUNNING"); if (!job) return false; - if (job.profileId) { - return job.profileId === profile.id; - } return ( job.allowIp === profile.allowIp && job.delayMs === profile.delayMs && @@ -147,8 +144,6 @@ export const LoopSetupCard = () => { allowIp: profile.allowIp, targetLoops: profile.targetLoops, delayMs: profile.delayMs, - profileName: profile.name, - profileId: profile.id, }); setLoopForm({ allowIp: profile.allowIp, diff --git a/apps/web/src/components/torrents/TorrentTable.tsx b/apps/web/src/components/torrents/TorrentTable.tsx index 64434ae..b992a24 100644 --- a/apps/web/src/components/torrents/TorrentTable.tsx +++ b/apps/web/src/components/torrents/TorrentTable.tsx @@ -77,15 +77,6 @@ export const TorrentTable = () => { const getProfileName = (hash: string) => { const job = jobs.find((j) => j.torrentHash === hash); if (!job) return null; - if (job.profileId) { - const profileById = profiles.find((p) => p.id === job.profileId); - if (profileById?.name) { - return profileById.name; - } - } - if (job.profileName) { - return job.profileName; - } const profile = profiles.find((p) => p.allowIp === job.allowIp && p.delayMs === job.delayMs && diff --git a/apps/web/src/store/useAppStore.ts b/apps/web/src/store/useAppStore.ts index b638d24..05db578 100644 --- a/apps/web/src/store/useAppStore.ts +++ b/apps/web/src/store/useAppStore.ts @@ -25,8 +25,6 @@ export interface LoopJob { targetLoops: number; doneLoops: number; delayMs: number; - profileName?: string; - profileId?: string; status: string; bans: { bannedIps: string[] }; nextRunAt?: string; diff --git a/apps/web/src/store/useAuthStore.ts b/apps/web/src/store/useAuthStore.ts index ed0f4e7..696f4e8 100644 --- a/apps/web/src/store/useAuthStore.ts +++ b/apps/web/src/store/useAuthStore.ts @@ -18,9 +18,6 @@ export const useAuthStore = create((set) => ({ set({ loading: true, error: null }); try { const response = await api.post("/api/auth/login", { username, password }); - if (response.data?.token) { - localStorage.setItem("qbuffer_token", response.data.token); - } set({ username: response.data.username, loading: false }); return true; } catch (error) { @@ -30,7 +27,6 @@ export const useAuthStore = create((set) => ({ }, logout: async () => { await api.post("/api/auth/logout"); - localStorage.removeItem("qbuffer_token"); set({ username: null }); }, check: async () => { @@ -38,7 +34,6 @@ export const useAuthStore = create((set) => ({ const response = await api.get("/api/auth/me"); set({ username: response.data.username ?? "session" }); } catch (error) { - localStorage.removeItem("qbuffer_token"); set({ username: null }); } }, diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 19cb559..f2a0e3c 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -1,24 +1,15 @@ -import { defineConfig, loadEnv } from "vite"; +import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import path from "node:path"; -export default defineConfig(({ mode }) => { - const env = loadEnv(mode, path.resolve(__dirname, "../.."), ""); - const allowedHosts = (env.WEB_ALLOWED_HOSTS || "") - .split(",") - .map((host) => host.trim().replace(/^"|"$/g, "")) - .filter(Boolean); - - return { - plugins: [react()], - build: { - outDir: path.resolve(__dirname, "../server/public"), - emptyOutDir: true, - }, - server: { - host: "0.0.0.0", - port: Number(env.WEB_PORT) || 5173, - allowedHosts: allowedHosts.length ? allowedHosts : true, - }, - }; +export default defineConfig({ + plugins: [react()], + build: { + outDir: path.resolve(__dirname, "../server/public"), + emptyOutDir: true, + }, + server: { + host: "0.0.0.0", + port: Number(process.env.WEB_PORT) || 5173, + }, });