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ı
This commit is contained in:
@@ -6,3 +6,14 @@ 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;
|
||||
});
|
||||
|
||||
@@ -45,6 +45,9 @@ 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 &&
|
||||
@@ -144,6 +147,8 @@ export const LoopSetupCard = () => {
|
||||
allowIp: profile.allowIp,
|
||||
targetLoops: profile.targetLoops,
|
||||
delayMs: profile.delayMs,
|
||||
profileName: profile.name,
|
||||
profileId: profile.id,
|
||||
});
|
||||
setLoopForm({
|
||||
allowIp: profile.allowIp,
|
||||
|
||||
@@ -77,6 +77,15 @@ 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 &&
|
||||
|
||||
@@ -25,6 +25,8 @@ export interface LoopJob {
|
||||
targetLoops: number;
|
||||
doneLoops: number;
|
||||
delayMs: number;
|
||||
profileName?: string;
|
||||
profileId?: string;
|
||||
status: string;
|
||||
bans: { bannedIps: string[] };
|
||||
nextRunAt?: string;
|
||||
|
||||
@@ -18,6 +18,9 @@ export const useAuthStore = create<AuthState>((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) {
|
||||
@@ -27,6 +30,7 @@ export const useAuthStore = create<AuthState>((set) => ({
|
||||
},
|
||||
logout: async () => {
|
||||
await api.post("/api/auth/logout");
|
||||
localStorage.removeItem("qbuffer_token");
|
||||
set({ username: null });
|
||||
},
|
||||
check: async () => {
|
||||
@@ -34,6 +38,7 @@ export const useAuthStore = create<AuthState>((set) => ({
|
||||
const response = await api.get("/api/auth/me");
|
||||
set({ username: response.data.username ?? "session" });
|
||||
} catch (error) {
|
||||
localStorage.removeItem("qbuffer_token");
|
||||
set({ username: null });
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import path from "node:path";
|
||||
|
||||
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,
|
||||
},
|
||||
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,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user