diff --git a/server.js b/server.js index a043c091..c183022e 100644 --- a/server.js +++ b/server.js @@ -144,7 +144,7 @@ const app = express() // Load middlewares for parsing JSON, and supporting HTML5 history routing .use(express.json({ limit: '1mb' })) // GET endpoint to run status of a given URL with GET request - .use(ENDPOINTS.statusCheck, (req, res) => { + .use(ENDPOINTS.statusCheck, protectConfig, (req, res) => { try { statusCheck(req.url, (results) => { if (!res.headersSent) { @@ -157,7 +157,7 @@ const app = express() } }) // POST Endpoint used to save config, by writing config file to disk - .use(ENDPOINTS.save, method('POST', (req, res) => { + .use(ENDPOINTS.save, protectConfig, method('POST', (req, res) => { try { saveConfig(req.body, (results) => { res.end(results); }); config = req.body.config; // update the config @@ -167,7 +167,7 @@ const app = express() } })) // GET endpoint to trigger a build, and respond with success status and output - .use(ENDPOINTS.rebuild, (req, res) => { + .use(ENDPOINTS.rebuild, protectConfig, (req, res) => { rebuild().then((response) => { res.end(JSON.stringify(response)); }).catch((response) => { @@ -175,7 +175,7 @@ const app = express() }); }) // GET endpoint to return system info, for widget - .use(ENDPOINTS.systemInfo, (req, res) => { + .use(ENDPOINTS.systemInfo, protectConfig, (req, res) => { try { const results = systemInfo(); systemInfo.success = true; @@ -185,7 +185,7 @@ const app = express() } }) // GET for accessing non-CORS API services - .use(ENDPOINTS.corsProxy, (req, res) => { + .use(ENDPOINTS.corsProxy, protectConfig, (req, res) => { try { corsProxy(req, res); } catch (e) { @@ -193,7 +193,7 @@ const app = express() } }) // GET endpoint to return user info - .use(ENDPOINTS.getUser, (req, res) => { + .use(ENDPOINTS.getUser, protectConfig, (req, res) => { try { const user = getUser(config, req); res.end(JSON.stringify(user)); diff --git a/src/utils/request.js b/src/utils/request.js index df59a76c..43e948b7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -7,6 +7,15 @@ * Throws on non-2xx responses (matching axios behavior) */ +/** Check if a request URL targets the local Dashy server */ +function isLocalRequest(url) { + if (!url) return false; + if (url.startsWith('/') && !url.startsWith('//')) return true; + const { origin } = window.location; + const domain = process.env.VUE_APP_DOMAIN; + return url.startsWith(origin) || (domain && url.startsWith(domain)); +} + class RequestError extends Error { constructor(message, opts = {}) { super(message); @@ -52,6 +61,16 @@ async function makeRequest(config) { signal: controller.signal, }; + // For local API requests, include basic auth headers when configured + // Dynamic import avoids circular dependency: request → Auth → ConfigAccumulator → store → request + if (isLocalRequest(fullUrl) && !fetchOptions.headers.Authorization) { + const { makeBasicAuthHeaders } = await import('@/utils/Auth'); + const authConfig = makeBasicAuthHeaders(); + if (authConfig.headers) { + Object.assign(fetchOptions.headers, authConfig.headers); + } + } + // Attach body for non-GET/HEAD requests if (data != null && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') { if (typeof data === 'string') {