config.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { settings } from 'app/customization/settings';
  2. export const MULTITENANT = appSetting('config', 'multitenant');
  3. export const MULTITENANT_IMAGES_PROXY = appSetting('config', 'multitenant_images_proxy');
  4. export const APP_URL = appSetting('config', 'app_url') ;
  5. export const UNA_URL = appSetting('config', 'una_url');
  6. export const UNA_API_KEY = appSetting('config', 'una_api_key');
  7. export const APP_ORIGIN = appSetting('config', 'app_origin');
  8. export function appSetting(section, name, path, extraSettings = null) {
  9. appSetting.cacheSettings = appSetting.cacheSettings || {};
  10. const cacheKey = path ? `${section}_${name}_${path}` : `${section}_${name}`;
  11. if (appSetting.cacheSettings.hasOwnProperty(cacheKey)) {
  12. return appSetting.cacheSettings[cacheKey];
  13. }
  14. const sectionData = settings?.[section];
  15. const result = path ? sectionData?.[name]?.[path] : sectionData?.[name];
  16. appSetting.cacheSettings[cacheKey] = result ?? '';
  17. return appSetting.cacheSettings[cacheKey];
  18. }
  19. export function getBaseUrl() {
  20. // Client-side
  21. if (typeof window !== "undefined") {
  22. return `${window.location.protocol}//${window.location.host}`;
  23. }
  24. // Server-side / SSR (shared bundle has no next/headers — prefer configured app URL)
  25. const appUrl = typeof APP_URL === 'string' ? APP_URL.replace(/\/$/, '') : '';
  26. if (appUrl) {
  27. return appUrl;
  28. }
  29. try {
  30. const h = headers();
  31. const host = h.get("host") || "localhost:3000";
  32. const proto = h.get("x-forwarded-proto") || "http";
  33. return `${proto}://${host}`;
  34. } catch {
  35. return "http://localhost:3000"; // fallback for SSR
  36. }
  37. }
  38. export async function getRemoteSettings(isServer = false) {
  39. const url = '/api.php?cnf=1';
  40. // Fast-fail if base URL is missing
  41. if (!UNA_URL) {
  42. return isServer ? { hash: '', data: {} } : {};
  43. }
  44. const buildOptions = () => {
  45. if (isServer) {
  46. return {
  47. cache: 'no-store',
  48. headers: {
  49. authorization: 'Bearer ' + UNA_API_KEY,
  50. }
  51. };
  52. }
  53. return {
  54. cache: 'no-store',
  55. headers: {
  56. Origin: APP_ORIGIN
  57. },
  58. };
  59. };
  60. const fetchOnce = async (timeoutMs) => {
  61. const request = fetch(UNA_URL + url, buildOptions()).then(async (r) => {
  62. if (!r.ok)
  63. throw new Error('HTTP ' + r.status);
  64. try {
  65. return await r.json();
  66. } catch (e) {
  67. return {};
  68. }
  69. });
  70. let to;
  71. const timeout = new Promise((_, reject) => {
  72. to = setTimeout(() => reject(new Error('Timeout')), timeoutMs);
  73. });
  74. try {
  75. return await Promise.race([request, timeout]);
  76. } finally {
  77. clearTimeout(to);
  78. }
  79. };
  80. const maxAttempts = 3;
  81. const baseDelayMs = 300;
  82. const timeoutPerAttemptMs = 3500;
  83. let lastError = null;
  84. for (let attempt = 1; attempt <= maxAttempts; attempt++) {
  85. try {
  86. const cnf = await fetchOnce(timeoutPerAttemptMs);
  87. const raw = cnf && typeof cnf.data !== 'undefined' && cnf.data !== '' ? cnf.data : {};
  88. let cnfData = {};
  89. try {
  90. cnfData = typeof raw === 'string' ? JSON.parse(raw) : (raw || {});
  91. } catch (e) {
  92. cnfData = {};
  93. }
  94. if (isServer)
  95. return { hash: cnf?.hash || '', data: cnfData };
  96. return cnfData;
  97. } catch (error) {
  98. lastError = error;
  99. if (attempt < maxAttempts) {
  100. const delay = baseDelayMs * attempt;
  101. await new Promise((resolve) => setTimeout(resolve, delay));
  102. continue;
  103. }
  104. }
  105. }
  106. // On consistent failure, return safe empty payload matching the expected shape
  107. if (isServer)
  108. return { hash: '', data: {} };
  109. return {};
  110. };