import { sitemapAllowedForClient, widgetsFilterForClient } from './security.js';
import { requireHeader } from './../middleware.js';
import { backendInfo } from '../../server.js';
import { getAllSitemaps, getSitemap, getSitemapPage } from './backend.js';
import proxy from 'express-http-proxy';
const sitemapAccess = () => {
return async function (req, res, next) {
const org = req.headers['x-openhab-org'] || '';
const user = req.headers['x-openhab-user'];
try {
const allowed = await sitemapAllowedForClient(backendInfo.HOST, req, user, org, req.params.sitemapname);
if (allowed === true) {
next();
} else {
res.status(403).send();
}
} catch {
res.status(500).send();
}
};
};
/**
* Provides required /sitemaps routes.
*
* @memberof routes
* @param {*} app expressjs app
*/
const sitemaps = (app) => {
/**
* @swagger
* /auth/sitemaps:
* get:
* summary: Authorization endpoint for Sitemap access.
* description: Used by NGINX auth_request.
* tags: [Auth]
* parameters:
* - in: header
* name: X-OPENHAB-USER
* required: true
* description: Name of user
* schema:
* type: string
* style: form
* - in: header
* name: X-OPENHAB-ORG
* required: false
* description: Organisations the user is member of
* schema:
* type: string
* style: form
* - in: header
* name: X-ORIGINAL-URI
* required: true
* description: Original request URI
* schema:
* type: string
* style: form
* responses:
* 200:
* description: Allowed
* 403:
* description: Forbidden
*/
app.get('/auth/sitemaps', requireHeader('X-OPENHAB-USER'), requireHeader('X-ORIGINAL-URI'), async (req, res) => {
const org = req.headers['x-openhab-org'] || '';
const user = req.headers['x-openhab-user'];
const regex1 = /(\?|&)sitemap=([a-zA-Z_0-9]+)[&]?/;
const regex2 = /\/sitemaps\/([a-zA-Z_0-9]+)/;
const sitemapname1 = regex1.exec(req.headers['x-original-uri']);
const sitemapname2 = regex2.exec(req.headers['x-original-uri']);
const sitemapname = (sitemapname1 == null) ? sitemapname2 : sitemapname1;
if (sitemapname == null) return res.status(403).send();
try {
const allowed = await sitemapAllowedForClient(backendInfo.HOST, req, user, org, sitemapname[2]);
if (allowed === true) {
res.status(200).send();
} else {
res.status(403).send();
}
} catch (err) {
res.status(500).send();
}
});
/**
* @swagger
* /rest/sitemaps:
* get:
* summary: Get all available sitemaps.
* tags: [Sitemaps]
* parameters:
* - in: header
* name: X-OPENHAB-USER
* required: true
* description: Name of user
* schema:
* type: string
* style: form
* - in: header
* name: X-OPENHAB-ORG
* required: false
* description: Organisations the user is member of
* schema:
* type: string
* style: form
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* type: array
* items:
* type: object
*/
app.get('/rest/sitemaps', requireHeader('X-OPENHAB-USER'), async (req, res) => {
const org = req.headers['x-openhab-org'] || '';
const user = req.headers['x-openhab-user'];
try {
const allSitemaps = await getAllSitemaps(backendInfo.HOST, req);
let filteredSitemaps = [];
for (const i in allSitemaps) {
if (await sitemapAllowedForClient(backendInfo.HOST, req, user, org, allSitemaps[i].name) === true) {
filteredSitemaps.push(allSitemaps[i]);
}
}
res.status(200).send(filteredSitemaps);
} catch (e) {
console.info(e);
res.status(500).send();
}
});
/**
* @swagger
* /rest/sitemaps/{sitemapname}:
* get:
* summary: Get a sitemap by name.
* tags: [Sitemaps]
* parameters:
* - in: path
* name: sitemapname
* required: true
* description: Sitemap name
* schema:
* type: string
* style: form
* - in: header
* name: X-OPENHAB-USER
* required: true
* description: Name of user
* schema:
* type: string
* style: form
* - in: header
* name: X-OPENHAB-ORG
* required: false
* description: Organisations the user is member of
* schema:
* type: string
* style: form
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* type: object
* 403:
* description: Sitemap access forbidden
* 404:
* description: Sitemap not found
*/
app.get('/rest/sitemaps/:sitemapname', requireHeader('X-OPENHAB-USER'), sitemapAccess(), async (req, res) => {
const org = req.headers['x-openhab-org'] || '';
const user = req.headers['x-openhab-user'];
try {
const response = await getSitemap(backendInfo.HOST, req, req.params.sitemapname);
const tempWidget = response.json.homepage.widgets;
//recursive filtering of child widgets
if (Array.isArray(tempWidget)) {
response.json.homepage.widgets = [];
const tempChWidgets = await widgetsFilterForClient(backendInfo.HOST, req, user, org, tempWidget);
response.json.homepage.widgets = tempChWidgets;
}
res.status(response.status).send(response.json);
} catch (e) {
console.info(e);
res.status(500).send();
}
});
/**
* @swagger
* /rest/sitemaps/{sitemapname}/{pageid}:
* get:
* summary: Polls the data for a sitemap.
* tags: [Sitemaps]
* parameters:
* - in: path
* name: sitemapname
* required: true
* description: Sitemap name
* schema:
* type: string
* style: form
* - in: path
* name: pageid
* required: true
* description: page id
* schema:
* type: string
* style: form
* - in: query
* name: parameters
* required: false
* description: Query parameters from API (subscriptionid)
* schema:
* type: string
* style: form
* - in: header
* name: X-OPENHAB-USER
* required: true
* description: Name of user
* schema:
* type: string
* style: form
* - in: header
* name: X-OPENHAB-ORG
* required: false
* description: Organisations the user is member of
* schema:
* type: string
* style: form
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* type: object
* 403:
* description: Sitemap access forbidden
* 404:
* description: Sitemap not found
*/
app.get('/rest/sitemaps/:sitemapname/:pageid', requireHeader('X-OPENHAB-USER'), sitemapAccess(), async (req, res) => {
const org = req.headers['x-openhab-org'] || '';
const user = req.headers['x-openhab-user'];
try {
const response = await getSitemapPage(backendInfo.HOST, req, req.params.sitemapname, req.params.pageid);
const tempWidget = response.json.widgets;
//recursive filtering of child widgets
if (Array.isArray(tempWidget)) {
response.json.widgets = [];
const tempChWidgets = await widgetsFilterForClient(backendInfo.HOST, req, user, org, tempWidget);
response.json.widgets = tempChWidgets;
}
res.status(response.status).send(response.json);
} catch (e) {
console.info(e);
res.status(500).send();
}
});
/**
* @swagger
* /rest/sitemaps/events/{subscriptionid}:
* get:
* summary: Get Sitemap events. Requires nginx.
* tags: [Sitemaps]
* parameters:
* - in: path
* name: subscriptionid
* required: true
* description: subscription id
* schema:
* type: string
* style: form
* - in: query
* name: sitemap
* required: false
* description: Sitemap name
* schema:
* type: string
* style: form
* - in: query
* name: pageid
* required: false
* description: page id
* schema:
* type: string
* style: form
* responses:
* 200:
* description: OK
* 400:
* description: Page not linked to the subscription.
* 404:
* description: Subscription not found.
*/
/**
* @swagger
* /rest/sitemaps/events/subscribe:
* post:
* summary: Creates a Sitemap event subscription. Requires nginx.
* tags: [Sitemaps]
* responses:
* 201:
* description: Subscription created.
* 503:
* description: Subscriptions limit reached.
*/
/**
* @swagger
* /basicui/:
* get:
* summary: Gets BasicUI. Requires nginx.
* tags: [Sitemaps]
* parameters:
* - in: path
* name: app
* required: true
* description: basic UI app and other components
* schema:
* type: string
* style: form
* - in: query
* name: parameters
* required: false
* description: Query parameters (e.g. sitemap, w)
* schema:
* type: string
* style: form
* responses:
* 200:
* description: OK
*/
};
export default sitemaps;