This commit is contained in:
Your Name committed 2026-06-18 22:38:38 -04:00
1 parent 927f03a8b7
commit 4c38f2a596
5 files changed
+83 -6

No files matched your search

+5 -1
View File
@@ -43,7 +43,11 @@ interface Scent {
} }
export default function PageBuilderPage() { export default function PageBuilderPage() {
const frontendBase = (import.meta.env.VITE_FRONTEND_URL || window.location.origin).replace(/\/$/, ''); const frontendBase = (
import.meta.env.DEV
? window.location.origin
: (import.meta.env.VITE_FRONTEND_URL || window.location.origin)
).replace(/\/$/, '');
const authHeaders = () => ({ const authHeaders = () => ({
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${localStorage.getItem('homaroma_admin_token')}`, Authorization: `Bearer ${localStorage.getItem('homaroma_admin_token')}`,
+4
View File
@@ -5,4 +5,8 @@ import tailwindcss from '@tailwindcss/vite'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react(), tailwindcss()], plugins: [react(), tailwindcss()],
server: {
host: true,
allowedHosts: true,
},
}) })
+24 -2
View File
@@ -30,6 +30,27 @@ import { mediaRoute } from "./routes/media";
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3051; const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3051;
const CORS_ORIGIN = process.env.CORS_ORIGIN || "http://localhost:5173"; const CORS_ORIGIN = process.env.CORS_ORIGIN || "http://localhost:5173";
const JWT_SECRET = process.env.JWT_SECRET || "homaroma_secret_2026_scent"; const JWT_SECRET = process.env.JWT_SECRET || "homaroma_secret_2026_scent";
const isDevelopment = process.env.NODE_ENV !== "production";
const isPrivateLanHostname = (hostname) => {
return (hostname === "localhost" ||
hostname === "127.0.0.1" ||
hostname === "0.0.0.0" ||
hostname === "::1" ||
/^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname) ||
/^192\.168\.\d{1,3}\.\d{1,3}$/.test(hostname) ||
/^172\.(1[6-9]|2\d|3[0-1])\.\d{1,3}\.\d{1,3}$/.test(hostname));
};
const allowLanDevOrigin = (request) => {
const origin = request.headers.get("origin");
if (!origin)
return false;
try {
return isPrivateLanHostname(new URL(origin).hostname);
}
catch {
return false;
}
};
const app = new Elysia() const app = new Elysia()
.onParse(async ({ request }) => { .onParse(async ({ request }) => {
console.log('[onParse] Incoming request URL:', request.url); console.log('[onParse] Incoming request URL:', request.url);
@@ -39,9 +60,10 @@ const app = new Elysia()
return text; return text;
} }
}) })
.use(cors({ .use(cors({
origin: [ origin: [
...CORS_ORIGIN.split(",").map((o) => o.trim()), ...CORS_ORIGIN.split(",").map((o) => o.trim()),
...(isDevelopment ? [allowLanDevOrigin] : []),
"https://admin.homaroma.shop", "https://admin.homaroma.shop",
"https://spa.homaroma.shop", // LIFF (SPA) "https://spa.homaroma.shop", // LIFF (SPA)
"https://homaroma.shop", // Main Website "https://homaroma.shop", // Main Website
@@ -96,4 +118,4 @@ const app = new Elysia()
.listen({ port: PORT, hostname: "0.0.0.0" }); .listen({ port: PORT, hostname: "0.0.0.0" });
console.log(`🌿 HomAroma API is running at http://${app.server?.hostname}:${app.server?.port}`); console.log(`🌿 HomAroma API is running at http://${app.server?.hostname}:${app.server?.port}`);
console.log(`📖 Swagger docs: http://${app.server?.hostname}:${app.server?.port}/swagger`); console.log(`📖 Swagger docs: http://${app.server?.hostname}:${app.server?.port}/swagger`);
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map
+25
View File
@@ -30,6 +30,30 @@ import { mediaRoute } from "./routes/media";
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3051; const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3051;
const CORS_ORIGIN = process.env.CORS_ORIGIN || "http://localhost:5173"; const CORS_ORIGIN = process.env.CORS_ORIGIN || "http://localhost:5173";
const JWT_SECRET = process.env.JWT_SECRET || "homaroma_secret_2026_scent"; const JWT_SECRET = process.env.JWT_SECRET || "homaroma_secret_2026_scent";
const isDevelopment = process.env.NODE_ENV !== "production";
const isPrivateLanHostname = (hostname: string) => {
return (
hostname === "localhost" ||
hostname === "127.0.0.1" ||
hostname === "0.0.0.0" ||
hostname === "::1" ||
/^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname) ||
/^192\.168\.\d{1,3}\.\d{1,3}$/.test(hostname) ||
/^172\.(1[6-9]|2\d|3[0-1])\.\d{1,3}\.\d{1,3}$/.test(hostname)
);
};
const allowLanDevOrigin = (request: Request) => {
const origin = request.headers.get("origin");
if (!origin) return false;
try {
return isPrivateLanHostname(new URL(origin).hostname);
} catch {
return false;
}
};
const app = new Elysia() const app = new Elysia()
.onParse(async ({ request }) => { .onParse(async ({ request }) => {
@@ -44,6 +68,7 @@ const app = new Elysia()
cors({ cors({
origin: [ origin: [
...CORS_ORIGIN.split(",").map((o) => o.trim()), ...CORS_ORIGIN.split(",").map((o) => o.trim()),
...(isDevelopment ? [allowLanDevOrigin] : []),
"https://admin.homaroma.shop", "https://admin.homaroma.shop",
"https://spa.homaroma.shop", // LIFF (SPA) "https://spa.homaroma.shop", // LIFF (SPA)
"https://homaroma.shop", // Main Website "https://homaroma.shop", // Main Website
+25 -3
View File
@@ -59,9 +59,31 @@ export interface Product {
images: ProductImage[] images: ProductImage[]
} }
export const API_BASE = (typeof import.meta !== 'undefined' && (import.meta as any).env?.VITE_API_URL) const DEFAULT_DEV_API_PORT = 3051
|| ((globalThis as any).process?.env?.VITE_API_URL)
|| 'http://localhost:3000/api' function resolveApiBase() {
const viteEnv = (typeof import.meta !== 'undefined' ? (import.meta as any).env : undefined)
const envValue = viteEnv?.VITE_API_URL || (globalThis as any).process?.env?.VITE_API_URL
if (envValue) {
const isDev = Boolean(viteEnv?.DEV)
const isLocalhostUrl = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/api\/?$/.test(envValue)
if (isDev && typeof window !== 'undefined' && isLocalhostUrl) {
return `${window.location.protocol}//${window.location.hostname}:${DEFAULT_DEV_API_PORT}/api`
}
return envValue
}
if (typeof window !== 'undefined') {
return `${window.location.protocol}//${window.location.hostname}:${DEFAULT_DEV_API_PORT}/api`
}
return 'http://localhost:3000/api'
}
export const API_BASE = resolveApiBase()
export const CATEGORY_IMAGES: Record<string, string> = { export const CATEGORY_IMAGES: Record<string, string> = {
'Oil Ozone': '/images/oil_ozone.png', 'Oil Ozone': '/images/oil_ozone.png',