FE+BE: BACKEND_API_URL for reverse proxies #1390

Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
jokob-sk
2026-01-09 14:20:25 +11:00
parent 77803c18be
commit 0f1b19bddc
28 changed files with 75 additions and 30 deletions
+1 -4
View File
@@ -416,12 +416,9 @@ async function renderSmallBoxes() {
showSpinner();
// Get data from the server
const protocol = window.location.protocol.replace(':', '');
const host = window.location.hostname;
const apiToken = getSetting("API_TOKEN");
const port = getSetting("GRAPHQL_PORT"); // same port your Flask app runs on
const apiBase = `${protocol}://${host}:${port}`;
const apiBase = getApiBase();
const url = `${apiBase}/device/${getMac()}?period=${encodeURIComponent(period)}`;
const response = await fetch(url, {
+2 -5
View File
@@ -43,13 +43,10 @@ function getDeviceData() {
mac = getMac()
console.log(mac);
const protocol = window.location.protocol.replace(':', '');
const host = window.location.hostname;
const apiToken = getSetting("API_TOKEN");
const port = getSetting("GRAPHQL_PORT");
let period = $("#period").val()
const apiBase = `${protocol}://${host}:${port}`;
const apiBase = getApiBase();
const url = `${apiBase}/device/${mac}?period=${encodeURIComponent(period)}`;
// get data from server
+1 -4
View File
@@ -48,12 +48,9 @@ function loadEventsData() {
)
`;
const protocol = window.location.protocol.replace(':', '');
const host = window.location.hostname;
const port = getSetting("GRAPHQL_PORT");
const apiToken = getSetting("API_TOKEN");
const apiBase = `${protocol}://${host}:${port}`;
const apiBase = getApiBase();
const url = `${apiBase}/dbquery/read`;
$.ajax({
+1 -4
View File
@@ -36,12 +36,9 @@
// ---------------------------------------
// query data
function loadPresenceData() {
const protocol = window.location.protocol.replace(":", "");
const host = window.location.hostname;
const port = getSetting("GRAPHQL_PORT");
const apiToken = getSetting("API_TOKEN");
const apiBase = `${protocol}://${host}:${port}`;
const apiBase = getApiBase();
const url = `${apiBase}/sessions/calendar`;
$('#calendar').fullCalendar('removeEventSources');
+1 -4
View File
@@ -103,12 +103,9 @@ function loadSessionsData() {
showSpinner();
// Build API base
const protocol = window.location.protocol.replace(':', '');
const host = window.location.hostname;
const port = getSetting("GRAPHQL_PORT"); // or whatever port your Flask API runs on
const apiToken = getSetting("API_TOKEN");
const apiBase = `${protocol}://${host}:${port}`;
const apiBase = getApiBase();
const url = `${apiBase}/sessions/${getMac()}?period=${encodeURIComponent(period)}`;
// Call API with Authorization header
+15
View File
@@ -0,0 +1,15 @@
function getApiBase()
{
apiBase = getSetting("BACKEND_API_URL");
if(apiBase == "")
{
const protocol = window.location.protocol.replace(':', '');
const host = window.location.hostname;
const port = getSetting("GRAPHQL_PORT");
apiBase = `${protocol}://${host}:${port}`;
}
return apiBase;
}
+1
View File
@@ -44,6 +44,7 @@
<script src="lib/datatables.net/js/dataTables.select.min.js"></script>
<script src="js/common.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/api.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/modal.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/tests.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<script src="js/db_methods.js?v=<?php include 'php/templates/version.php'; ?>"></script>
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Object Type",
"AppEvents_Plugin": "المكونات الإضافية",
"AppEvents_Type": "النوع",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "هل تريد تنفيذ هذا الإجراء؟",
"BackDevDetail_Actions_Not_Registered": "لم يتم تسجيل الإجراء: ",
"BackDevDetail_Actions_Title_Run": "تنفيذ الإجراء",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Tipus d'objecte",
"AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Tipus",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Vol executar aquesta comanda?",
"BackDevDetail_Actions_Not_Registered": "Comanda no registrada: ",
"BackDevDetail_Actions_Title_Run": "Executar la comanda",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "",
"AppEvents_Plugin": "Zásuvný modul",
"AppEvents_Type": "Typ",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "",
"BackDevDetail_Actions_Not_Registered": "",
"BackDevDetail_Actions_Title_Run": "Spustit akci",
+2
View File
@@ -29,6 +29,8 @@
"AppEvents_Type": "Typ",
"Apprise_display_name": "Apprise",
"Apprise_icon": "<i class=\"fa fa-bullhorn\"></i>",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Möchtest du die Aktion ausführen?",
"BackDevDetail_Actions_Not_Registered": "Aktion nicht registriert: ",
"BackDevDetail_Actions_Title_Run": "Aktion ausführen",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Object Type",
"AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Type",
"BACKEND_API_URL_description": "Used to generate backend API URLs. Specify if you use reverse proxy to map to your <code>GRAPHQL_PORT</code>. Enter full URL starting with <code>http://</code> including the port number (no trailing slash <code>/</code>).",
"BACKEND_API_URL_name": "Backend API URL",
"BackDevDetail_Actions_Ask_Run": "Do you want to execute the action?",
"BackDevDetail_Actions_Not_Registered": "Action not registered: ",
"BackDevDetail_Actions_Title_Run": "Run action",
+2
View File
@@ -29,6 +29,8 @@
"AppEvents_Type": "Tipo",
"Apprise_display_name": "Apprise",
"Apprise_icon": "<i class=\"fa fa-bullhorn\"></i>",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "¿Desea ejecutar la acción?",
"BackDevDetail_Actions_Not_Registered": "Acción no registrada: ",
"BackDevDetail_Actions_Title_Run": "Ejecutar acción",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "",
"AppEvents_Plugin": "",
"AppEvents_Type": "",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "",
"BackDevDetail_Actions_Not_Registered": "",
"BackDevDetail_Actions_Title_Run": "",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Type d'objet",
"AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Type",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Voulez-vous exécuter cette action ?",
"BackDevDetail_Actions_Not_Registered": "Action non enregistrée : ",
"BackDevDetail_Actions_Title_Run": "Lancer l'action",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Tipo oggetto",
"AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Tipo",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Vuoi eseguire questa azione?",
"BackDevDetail_Actions_Not_Registered": "Azione non registrata: ",
"BackDevDetail_Actions_Title_Run": "Esegui azione",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "オブジェクトタイプ",
"AppEvents_Plugin": "プラグイン",
"AppEvents_Type": "種別",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "このアクションを実行してよろしいですか?",
"BackDevDetail_Actions_Not_Registered": "登録されていないアクション: ",
"BackDevDetail_Actions_Title_Run": "アクションを実行",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Objekttype",
"AppEvents_Plugin": "Programtillegg",
"AppEvents_Type": "Type",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Vil du utføre handlingen?",
"BackDevDetail_Actions_Not_Registered": "Handling ikke registrert: ",
"BackDevDetail_Actions_Title_Run": "Utfør handling",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Typ obiektu",
"AppEvents_Plugin": "Wtyczka",
"AppEvents_Type": "Typ",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Czy chcesz wykonać tę akcję?",
"BackDevDetail_Actions_Not_Registered": "Akcja nie jest zarejestrowana: ",
"BackDevDetail_Actions_Title_Run": "Uruchom akcję",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Tipo de Objeto",
"AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Tipo",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Você deseja executar esta ação?",
"BackDevDetail_Actions_Not_Registered": "Ação não registrada: ",
"BackDevDetail_Actions_Title_Run": "Executar ação",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Tipo de Objeto",
"AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Tipo",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Deseja executar esta ação?",
"BackDevDetail_Actions_Not_Registered": "Ação não registada: ",
"BackDevDetail_Actions_Title_Run": "Executar ação",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Тип объекта",
"AppEvents_Plugin": "Плагин",
"AppEvents_Type": "Тип",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Вы хотите выполнить действие?",
"BackDevDetail_Actions_Not_Registered": "Действие не зарегистрировано:· ",
"BackDevDetail_Actions_Title_Run": "Запустить действие",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "",
"AppEvents_Plugin": "",
"AppEvents_Type": "",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "",
"BackDevDetail_Actions_Not_Registered": "",
"BackDevDetail_Actions_Title_Run": "",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Nesne Tipi",
"AppEvents_Plugin": "Eklenti",
"AppEvents_Type": "Tür",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "İşlemi gerçekleştirmek istiyor musunuz?",
"BackDevDetail_Actions_Not_Registered": "Eylem kaydedilmedi: ",
"BackDevDetail_Actions_Title_Run": "Eylemi çalıştır",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "Тип об'єкта",
"AppEvents_Plugin": "Плагін",
"AppEvents_Type": "Тип",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "Ви хочете виконати дію?",
"BackDevDetail_Actions_Not_Registered": "Дія не зареєстрована: ",
"BackDevDetail_Actions_Title_Run": "Запустити дію",
+2
View File
@@ -27,6 +27,8 @@
"AppEvents_ObjectType": "对象类型",
"AppEvents_Plugin": "插件",
"AppEvents_Type": "类型",
"BACKEND_API_URL_description": "",
"BACKEND_API_URL_name": "",
"BackDevDetail_Actions_Ask_Run": "您要执行此操作吗?",
"BackDevDetail_Actions_Not_Registered": "未注册的操作: ",
"BackDevDetail_Actions_Title_Run": "运行动作",
+1 -4
View File
@@ -421,12 +421,9 @@ function getDevicesPresence (status) {
$('#tableDevicesBox')[0].className = 'box box-'+ color;
$('#tableDevicesTitle').html (tableTitle);
const protocol = window.location.protocol.replace(':', '');
const host = window.location.hostname;
const port = getSetting("GRAPHQL_PORT"); // Or Flask server port
const apiToken = getSetting("API_TOKEN");
const apiBase = `${protocol}://${host}:${port}`;
const apiBase = getApiBase();
// -----------------------------
// Load Devices as Resources
+9
View File
@@ -270,6 +270,15 @@ def importConfigs(pm, db, all_plugins):
"[]",
"General",
)
conf.BACKEND_API_URL = ccd(
"BACKEND_API_URL",
"",
c_d,
"API URL",
'{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}',
"[]",
"General",
)
conf.DAYS_TO_KEEP_EVENTS = ccd(
"DAYS_TO_KEEP_EVENTS",
90,