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

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, {

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

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({

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');

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
front/js/api.js Normal file
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;
}

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>

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": "تنفيذ الإجراء",

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",
@@ -763,4 +765,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Actualitza el valor sota. Sigues curós de seguir el format anterior. <b>No hi ha validació.</b>",
"test_event_tooltip": "Deseu els canvis primer abans de comprovar la configuració."
}
}

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",

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",

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",

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",

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": "",

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",
@@ -763,4 +765,4 @@
"settings_system_label": "Système",
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. <b>Il n'y a pas de pas de contrôle.</b>",
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
}
}

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",
@@ -763,4 +765,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
}
}

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": "アクションを実行",

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",

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ę",

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",
@@ -763,4 +765,4 @@
"settings_system_label": "",
"settings_update_item_warning": "",
"test_event_tooltip": "Guarde as alterações antes de testar as definições."
}
}

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",

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": "Запустить действие",

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": "",

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",

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": "Запустити дію",
@@ -763,4 +765,4 @@
"settings_system_label": "Система",
"settings_update_item_warning": "Оновіть значення нижче. Слідкуйте за попереднім форматом. <b>Перевірка не виконана.</b>",
"test_event_tooltip": "Перш ніж перевіряти налаштування, збережіть зміни."
}
}

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": "运行动作",

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

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,