Merge branch 'master' into Fix-up-statcards
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,3 +25,4 @@ dist-ssr
|
|||||||
.env
|
.env
|
||||||
dashboard/build/**
|
dashboard/build/**
|
||||||
dashboard-server/frontend/build/**
|
dashboard-server/frontend/build/**
|
||||||
|
._*
|
||||||
@@ -38,7 +38,13 @@ const corsOptions = {
|
|||||||
|
|
||||||
console.log('CORS check for origin:', origin);
|
console.log('CORS check for origin:', origin);
|
||||||
|
|
||||||
// Check if origin is allowed
|
// Allow local network IPs (192.168.1.xxx)
|
||||||
|
if (origin && origin.match(/^http:\/\/192\.168\.1\.\d{1,3}(:\d+)?$/)) {
|
||||||
|
callback(null, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if origin is in allowed list
|
||||||
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
|
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
|
||||||
callback(null, true);
|
callback(null, true);
|
||||||
} else {
|
} else {
|
||||||
@@ -96,19 +102,19 @@ app.post('/login', (req, res) => {
|
|||||||
expiresIn: '24h'
|
expiresIn: '24h'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Determine if request is from localhost
|
// Determine if request is from local network
|
||||||
const isLocalhost = req.headers.origin?.includes('localhost');
|
const isLocalNetwork = req.headers.origin?.includes('192.168.1.') || req.headers.origin?.includes('localhost');
|
||||||
|
|
||||||
const cookieOptions = {
|
const cookieOptions = {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: !isLocalhost,
|
secure: !isLocalNetwork, // Only use secure for non-local requests
|
||||||
sameSite: isLocalhost ? 'lax' : 'none',
|
sameSite: isLocalNetwork ? 'lax' : 'none',
|
||||||
path: '/',
|
path: '/',
|
||||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add domain only for production
|
// Only set domain for production
|
||||||
if (!isLocalhost) {
|
if (!isLocalNetwork) {
|
||||||
cookieOptions.domain = '.kent.pw';
|
cookieOptions.domain = '.kent.pw';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,13 +169,13 @@ app.get('/check', (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.post('/logout', (req, res) => {
|
app.post('/logout', (req, res) => {
|
||||||
const isLocalhost = req.headers.origin?.includes('localhost');
|
const isLocalNetwork = req.headers.origin?.includes('192.168.1.') || req.headers.origin?.includes('localhost');
|
||||||
const cookieOptions = {
|
const cookieOptions = {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: !isLocalhost,
|
secure: !isLocalNetwork,
|
||||||
sameSite: isLocalhost ? 'lax' : 'none',
|
sameSite: isLocalNetwork ? 'lax' : 'none',
|
||||||
path: '/',
|
path: '/',
|
||||||
domain: isLocalhost ? undefined : '.kent.pw'
|
domain: isLocalNetwork ? undefined : '.kent.pw'
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('Clearing cookie with options:', cookieOptions);
|
console.log('Clearing cookie with options:', cookieOptions);
|
||||||
|
|||||||
@@ -91,29 +91,33 @@ const DashboardLayout = () => {
|
|||||||
<div className="grid grid-cols-1 xl:grid-cols-6 gap-4">
|
<div className="grid grid-cols-1 xl:grid-cols-6 gap-4">
|
||||||
<div className="xl:col-span-4 col-span-6">
|
<div className="xl:col-span-4 col-span-6">
|
||||||
<div className="space-y-4 h-full w-full">
|
<div className="space-y-4 h-full w-full">
|
||||||
|
<div id="stats">
|
||||||
<StatCards />
|
<StatCards />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="xl:col-span-2 col-span-6 h-[500px] xl:h-[643px] 2xl:h-[510px] lg:hidden xl:block">
|
</div>
|
||||||
|
<div id="feed-xl" className="xl:col-span-2 col-span-6 h-[500px] xl:h-[643px] 2xl:h-[510px] lg:hidden xl:block">
|
||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
<div className="h-full"><EventFeed /></div>
|
<div className="h-full"><EventFeed /></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-12 gap-4">
|
<div className="grid grid-cols-12 gap-4">
|
||||||
<div className="hidden lg:col-span-6 lg:block xl:hidden h-[740px]">
|
<div id="feed-lg" className="hidden lg:col-span-6 lg:block xl:hidden h-[740px]">
|
||||||
<EventFeed />
|
<EventFeed />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-12 lg:col-span-6 xl:col-span-4 h-[600px] lg:h-[740px]">
|
<div id="products" className="col-span-12 lg:col-span-6 xl:col-span-4 h-[600px] lg:h-[740px]">
|
||||||
<ProductGrid />
|
<ProductGrid />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-12 xl:col-span-8 h-full w-full flex">
|
<div id="sales" className="col-span-12 xl:col-span-8 h-full w-full flex">
|
||||||
<SalesChart className="w-full h-full"/>
|
<SalesChart className="w-full h-full"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="calls">
|
||||||
<AircallDashboard />
|
<AircallDashboard />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</ScrollProvider>
|
</ScrollProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,25 +20,13 @@ const Navigation = () => {
|
|||||||
const baseSections = [
|
const baseSections = [
|
||||||
{ id: "stats", label: "Statistics" },
|
{ id: "stats", label: "Statistics" },
|
||||||
{
|
{
|
||||||
id: "realtime",
|
id: "feed",
|
||||||
label: "Realtime",
|
label: "Event Feed",
|
||||||
responsiveIds: ["realtime-lg", "realtime-md"],
|
responsiveIds: ["feed-xl", "feed-lg"],
|
||||||
order: { md: 2, default: 1 },
|
|
||||||
},
|
},
|
||||||
{
|
{ id: "products", label: "Top Products" },
|
||||||
id: "products",
|
{ id: "sales", label: "Sales Chart" },
|
||||||
label: "Top Products",
|
{ id: "calls", label: "Aircall" },
|
||||||
responsiveIds: ["products-lg", "products-md"],
|
|
||||||
order: { md: 1, default: 2 },
|
|
||||||
},
|
|
||||||
{ id: "feed", label: "Activity Feed" },
|
|
||||||
{ id: "sales", label: "Sales Metrics" },
|
|
||||||
{ id: "campaigns", label: "Campaigns" },
|
|
||||||
{ id: "meta", label: "Meta Ads" },
|
|
||||||
{ id: "analytics", label: "Analytics" },
|
|
||||||
{ id: "behavior", label: "User Behavior" },
|
|
||||||
{ id: "gorgias", label: "Customer Service" },
|
|
||||||
{ id: "calls", label: "Calls" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const sortSections = (sections) => {
|
const sortSections = (sections) => {
|
||||||
|
|||||||
@@ -72,8 +72,10 @@ export default defineConfig(({ mode }) => {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: true,
|
secure: true,
|
||||||
cookieDomainRewrite: {
|
cookieDomainRewrite: {
|
||||||
"dashboard.kent.pw": "localhost",
|
"dashboard.kent.pw": "",
|
||||||
},
|
},
|
||||||
|
hostRewrite: true,
|
||||||
|
autoRewrite: true,
|
||||||
configure: (proxy, _options) => {
|
configure: (proxy, _options) => {
|
||||||
proxy.on("error", (err, req, res) => {
|
proxy.on("error", (err, req, res) => {
|
||||||
console.log("Auth proxy error:", err);
|
console.log("Auth proxy error:", err);
|
||||||
@@ -85,13 +87,29 @@ export default defineConfig(({ mode }) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
proxy.on("proxyReq", (proxyReq, req, _res) => {
|
proxy.on("proxyReq", (proxyReq, req, _res) => {
|
||||||
|
proxyReq.setHeader('X-Forwarded-Host', req.headers.host);
|
||||||
|
proxyReq.setHeader('X-Forwarded-Proto', 'http');
|
||||||
|
|
||||||
|
const origin = req.headers.origin || `http://${req.headers.host}`;
|
||||||
|
proxyReq.setHeader('origin', origin);
|
||||||
|
|
||||||
console.log("Outgoing auth request:", {
|
console.log("Outgoing auth request:", {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
url: req.url,
|
url: req.url,
|
||||||
headers: req.headers,
|
headers: proxyReq.getHeaders(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
proxy.on("proxyRes", (proxyRes, req, _res) => {
|
proxy.on("proxyRes", (proxyRes, req, res) => {
|
||||||
|
const cookies = proxyRes.headers['set-cookie'];
|
||||||
|
if (cookies) {
|
||||||
|
proxyRes.headers['set-cookie'] = cookies.map(cookie =>
|
||||||
|
cookie
|
||||||
|
.replace(/Domain=[^;]+;/g, '')
|
||||||
|
.replace(/Secure;/g, '')
|
||||||
|
.replace(/SameSite=None/g, 'SameSite=Lax')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
console.log("Auth proxy response:", {
|
console.log("Auth proxy response:", {
|
||||||
statusCode: proxyRes.statusCode,
|
statusCode: proxyRes.statusCode,
|
||||||
url: req.url,
|
url: req.url,
|
||||||
|
|||||||
Reference in New Issue
Block a user