@dashadmin/dash-admin 1.3.73 → 1.3.74-srcfree.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/dist/components/tenant/TenancyPlan.js +307 -0
  2. package/dist/systemResources.js +18 -2
  3. package/package.json +25 -22
  4. package/src/AppAsyncWrapper.tsx +0 -42
  5. package/src/AppWrapper.tsx +0 -45
  6. package/src/DASHAdmin.tsx +0 -502
  7. package/src/DASHAdmin.tsx.old +0 -456
  8. package/src/RoutingWrapper.tsx +0 -143
  9. package/src/classes/DASHStorageClass.tsx +0 -8
  10. package/src/components/Input/RichTextField.tsx +0 -27
  11. package/src/components/Redirect.tsx +0 -46
  12. package/src/components/avatar/Avatar.tsx +0 -71
  13. package/src/components/avatar/SingleImageUploader.tsx +0 -107
  14. package/src/components/currency/Format.tsx +0 -79
  15. package/src/components/custom/Redirect.tsx +0 -23
  16. package/src/components/error/Error.tsx +0 -168
  17. package/src/components/geocoding/GeocodingField.tsx +0 -167
  18. package/src/components/i18n/BridgedLocalesMenuButton.tsx +0 -160
  19. package/src/components/i18n/LangSwitcher.tsx +0 -204
  20. package/src/components/loader/GlobalLoader.tsx +0 -49
  21. package/src/components/logs/LogFile.tsx +0 -88
  22. package/src/components/logs/LogFileById.tsx +0 -68
  23. package/src/components/logs/LogViewer.tsx +0 -43
  24. package/src/components/menu/AppMenu.tsx +0 -22
  25. package/src/components/menu/CustomMenuItemLink.tsx +0 -61
  26. package/src/components/menu/DarkToggleMode.tsx +0 -65
  27. package/src/components/menu/LanguageToggleMode.tsx +0 -120
  28. package/src/components/misc/CustomImageInput.tsx +0 -62
  29. package/src/components/misc/DASHGlobalErrorHandler.tsx +0 -194
  30. package/src/components/misc/DarkModeSwitcher.tsx +0 -112
  31. package/src/components/misc/HorizontalScroller.tsx +0 -225
  32. package/src/components/misc/LanguageSwitcher.tsx +0 -199
  33. package/src/components/misc/MUIHtmlToolTip.tsx +0 -15
  34. package/src/components/misc/MuiSimpleJsonTable.tsx +0 -279
  35. package/src/components/misc/MultiLevelTable.tsx +0 -229
  36. package/src/components/misc/NoResults.tsx +0 -28
  37. package/src/components/misc/PDFViewer.tsx +0 -85
  38. package/src/components/navigation/Breadcrumbs.tsx +0 -220
  39. package/src/components/navigation/BreadcrumbsManager.tsx +0 -310
  40. package/src/components/navigation/index.tsx +0 -5
  41. package/src/components/panel/Error.tsx +0 -168
  42. package/src/components/permission/AvailablePermissionsContext.tsx +0 -173
  43. package/src/components/permission/PermissionsSelector.tsx +0 -834
  44. package/src/components/permission/PermissionsSelectorList.tsx +0 -473
  45. package/src/components/permission/tsx +0 -0
  46. package/src/components/racustombuttons/CustomRAButton.tsx +0 -87
  47. package/src/components/racustombuttons/QuickButton.tsx +0 -117
  48. package/src/components/racustombuttons/QuickEditButton.tsx +0 -115
  49. package/src/components/racustombuttons/QuickIconButton.tsx +0 -122
  50. package/src/components/scrollbar/Scrollbar.tsx +0 -31
  51. package/src/components/selects/MultiSelect.tsx +0 -53
  52. package/src/components/selects/RASearchableSelect.tsx +0 -282
  53. package/src/components/selects/RASearchableSelectChips.tsx +0 -308
  54. package/src/components/selects/SearchableSelect.tsx +0 -139
  55. package/src/components/serviceAccount/ApiKeyRevealDialog.tsx +0 -129
  56. package/src/components/serviceAccount/ServiceAccountStatusSwitch.tsx +0 -99
  57. package/src/components/subscription/BillingCycleSelectInput.tsx +0 -68
  58. package/src/components/subscription/PlanAddonsSettings.tsx +0 -563
  59. package/src/components/subscription/PlanAuditLog.tsx +0 -453
  60. package/src/components/subscription/PlanFeaturesSettings.tsx +0 -243
  61. package/src/components/subscription/PlanLimitsSettings.tsx +0 -230
  62. package/src/components/subscription/PlanMetadataSettings.tsx +0 -306
  63. package/src/components/subscription/PlanPricesSettings.tsx +0 -307
  64. package/src/components/subscription/index.ts +0 -7
  65. package/src/components/svgelements/SvgLoading.tsx +0 -229
  66. package/src/components/svgelements/SvgLogo.tsx +0 -53
  67. package/src/components/svgelements/SvgLogoMin.tsx +0 -64
  68. package/src/components/svgelements/SvgShipping.tsx +0 -673
  69. package/src/components/tenancy/GlobalTenantWrapper.tsx +0 -84
  70. package/src/components/tenancy/TenantSwitcher.tsx +0 -514
  71. package/src/components/tenant/AvailablePermissionsContext.tsx +0 -0
  72. package/src/components/tenant/SettingsSections.tsx +0 -151
  73. package/src/components/tenant/TenancySettings.tsx +0 -122
  74. package/src/components/tenant/TenantAttributes.tsx +0 -153
  75. package/src/components/tenant/TenantAttributesContext.tsx +0 -163
  76. package/src/components/tenant/TenantSelector.tsx +0 -142
  77. package/src/components/tenant/TenantSettings.tsx +0 -184
  78. package/src/components/tenant/TenantSettingsContext.tsx +0 -165
  79. package/src/components/tenant/TenantTheme.tsx +0 -172
  80. package/src/components/user/AvatarComponent.tsx +0 -317
  81. package/src/components/user/TenantAvatarComponent.tsx +0 -99
  82. package/src/components/user/UserPreferences.tsx +0 -677
  83. package/src/config/ACTIONS.tsx +0 -26
  84. package/src/config/ConstantsService.tsx +0 -44
  85. package/src/config/DASHAdminSystemConstants.tsx +0 -183
  86. package/src/config/PARSERS.tsx +0 -9
  87. package/src/contexts/DashQueryClientContext.tsx +0 -113
  88. package/src/contexts/DashResourceContext.tsx +0 -34
  89. package/src/contexts/I18nBridgeContext.tsx +0 -156
  90. package/src/contexts/I18nBridgeSetter.tsx +0 -39
  91. package/src/contexts/I18nReduxSync.tsx +0 -27
  92. package/src/contexts/SubscriptionPlanFormatsProvider.tsx +0 -217
  93. package/src/contexts/SystemRequestsCache.tsx +0 -215
  94. package/src/contexts/auth/AuthContext.tsx +0 -567
  95. package/src/contexts/auth/AuthContextLocalStorage.tsx +0 -140
  96. package/src/contexts/auth/DASHAuthenticationService.tsx +0 -915
  97. package/src/contexts/auth/WindowContext.tsx +0 -15
  98. package/src/contexts/auth/index.tsx +0 -3
  99. package/src/contexts/com/FCMContext.tsx +0 -415
  100. package/src/contexts/com/LaravelEchoContext.tsx +0 -41
  101. package/src/contexts/com/LaravelEchoMgr.tsx +0 -155
  102. package/src/contexts/com/components/DefaultNotificationComponent.tsx +0 -20
  103. package/src/contexts/com/components/EchoNotificationsCenter.tsx +0 -65
  104. package/src/contexts/com/components/NotificationAttributesTable.tsx +0 -54
  105. package/src/contexts/com/components/NotificationRenderer.tsx +0 -42
  106. package/src/contexts/com/components/NotificationsWidget.tsx +0 -182
  107. package/src/contexts/com/components/notificationFormats.tsx +0 -50
  108. package/src/contexts/com/useLaravelEcho.tsx +0 -432
  109. package/src/contexts/dictionary/DictionaryContext.tsx +0 -94
  110. package/src/declarations.d.ts +0 -17
  111. package/src/default-theme/DASHAppProviders.tsx +0 -117
  112. package/src/default-theme/DashThemeContext.tsx +0 -209
  113. package/src/default-theme/DashThemeContext.tsx.fast +0 -143
  114. package/src/default-theme/DashThemeContext.tsx.old +0 -306
  115. package/src/default-theme/DashThemeHelperProvider.tsx +0 -98
  116. package/src/default-theme/DomainAppLayout.tsx +0 -166
  117. package/src/default-theme/DomainHeader.tsx +0 -162
  118. package/src/default-theme/DomainTheme.tsx +0 -59
  119. package/src/default-theme/FullLayoutMarkup.tsx +0 -231
  120. package/src/default-theme/StaticLayout.tsx +0 -47
  121. package/src/default-theme/index.tsx +0 -11
  122. package/src/default-theme/menu/AppDashboardGrid.tsx +0 -279
  123. package/src/default-theme/menu/AppMaterialMenu.tsx +0 -546
  124. package/src/default-theme/menu/AppMenuComponents/SubmenuPortal.tsx +0 -61
  125. package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.tsx +0 -264
  126. package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.tsx +0 -31
  127. package/src/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.tsx +0 -293
  128. package/src/default-theme/menu/AppMenuComponents/expanded/SidebarItem.tsx +0 -92
  129. package/src/default-theme/menu/AppMenuComponents/getItem.tsx +0 -17
  130. package/src/default-theme/menu/AppMenuComponents/interfaces.tsx +0 -41
  131. package/src/default-theme/menu/AppMenuComponents/submenuConstants.ts +0 -90
  132. package/src/default-theme/menu/AppSidebarMaterial.tsx +0 -339
  133. package/src/default-theme/menu/SidebarActions.tsx +0 -84
  134. package/src/default-theme/updateDomCssVariables.tsx +0 -176
  135. package/src/helpers/checkRole.tsx +0 -66
  136. package/src/helpers/parseAxiosError.tsx +0 -41
  137. package/src/hooks/audio/useAudio.tsx +0 -39
  138. package/src/hooks/axios.tsx +0 -165
  139. package/src/hooks/data/useDashboardStats.tsx +0 -65
  140. package/src/hooks/data/usePackageByClientsStats.tsx +0 -44
  141. package/src/hooks/data/usePackageByCommunesStats.tsx +0 -44
  142. package/src/hooks/data/usePackageStats.tsx +0 -69
  143. package/src/hooks/data/usePackageWithdrawDetails.tsx +0 -61
  144. package/src/hooks/data/useStats.tsx +0 -86
  145. package/src/hooks/isCurrentPath.tsx +0 -22
  146. package/src/hooks/notifications/WSMessagesManager.tsx +0 -152
  147. package/src/hooks/notifications/WSPusherManager.tsx +0 -92
  148. package/src/hooks/useBreadcrumbs.tsx +0 -329
  149. package/src/hooks/useClickOutside.tsx +0 -57
  150. package/src/hooks/useFormPersistance.tsx +0 -150
  151. package/src/hooks/useGlobalErrorMediator.tsx +0 -43
  152. package/src/hooks/useGlobalLoaderMgr.tsx +0 -21
  153. package/src/hooks/useHash.tsx +0 -27
  154. package/src/hooks/useLocalStorage.tsx +0 -196
  155. package/src/hooks/usePolyglotTranslation.tsx +0 -62
  156. package/src/hooks/usePrevious.tsx +0 -9
  157. package/src/hooks/usePrintSelected.tsx +0 -37
  158. package/src/hooks/useVirtualHash.tsx +0 -33
  159. package/src/hooks/window/useWindowSize.tsx +0 -36
  160. package/src/index.tsx +0 -134
  161. package/src/interfaces/IAppResourceConfig.tsx +0 -20
  162. package/src/interfaces/Log.tsx +0 -16
  163. package/src/interfaces/Tenant.tsx +0 -25
  164. package/src/interfaces/communication/IActions.tsx +0 -5
  165. package/src/interfaces/communication/INotification.tsx +0 -21
  166. package/src/interfaces/communication/IPayload.tsx +0 -3
  167. package/src/interfaces/communication/IRequestAction.tsx +0 -10
  168. package/src/interfaces/communication/IRequestPayload.tsx +0 -7
  169. package/src/interfaces/communication/IResponseAction.tsx +0 -7
  170. package/src/interfaces/misc/IAny.tsx +0 -3
  171. package/src/interfaces/misc/IFlashMessage.tsx +0 -10
  172. package/src/interfaces/navigation/IAppMenu.ts +0 -14
  173. package/src/interfaces/navigation/ICollapsableSidebarMenu.ts +0 -12
  174. package/src/interfaces/navigation/IMenuItem.ts +0 -16
  175. package/src/interfaces/notifications/IModel.tsx +0 -6
  176. package/src/interfaces/notifications/IModelField.tsx +0 -8
  177. package/src/interfaces/notifications/IUserNotification.tsx +0 -12
  178. package/src/interfaces/notifications/IUserNotificationData.tsx +0 -13
  179. package/src/interfaces/notifications/IUserNotificationPayload.tsx +0 -8
  180. package/src/interfaces/user/IGetAuth.tsx +0 -92
  181. package/src/interfaces/user/ITenantSettings.tsx +0 -3
  182. package/src/interfaces/user/IUser.tsx +0 -60
  183. package/src/interfaces/user/IUserSettings.tsx +0 -43
  184. package/src/interfaces.tsx +0 -6
  185. package/src/layout/AppLayout.tsx +0 -112
  186. package/src/layout/ApplicationLayout.tsx +0 -197
  187. package/src/layout/MotionWrapper.original.tsx +0 -236
  188. package/src/layout/MotionWrapper.tsx +0 -236
  189. package/src/layout/ResourceMenu.tsx +0 -164
  190. package/src/layout/ResoureLayout.tsx +0 -105
  191. package/src/layout/TransitionWrapper.tsx +0 -125
  192. package/src/pages/ChangePassword.tsx +0 -179
  193. package/src/pages/DASHLanding.tsx +0 -22
  194. package/src/pages/DASHLightWeightLogin.tsx +0 -611
  195. package/src/pages/DASHSimpleLogin.tsx +0 -260
  196. package/src/pages/Login.tsx +0 -111
  197. package/src/pages/Profile.tsx +0 -357
  198. package/src/pages/RecoverPassword.tsx +0 -175
  199. package/src/pages/SingleImageUploader.tsx +0 -55
  200. package/src/pages/VerifyAccount.tsx +0 -128
  201. package/src/providers/authProvider.tsx +0 -217
  202. package/src/providers/dataProvider.tsx +0 -672
  203. package/src/providers/i18n/en.ts +0 -646
  204. package/src/providers/i18n/es.ts +0 -652
  205. package/src/providers/i18n/languages.tsx +0 -8
  206. package/src/providers/i18n/mergeTranslations.ts +0 -53
  207. package/src/providers/i18nProvider.tsx +0 -23
  208. package/src/react-admin-dash/RADashComponent.tsx +0 -240
  209. package/src/react-admin-dash/Resource.tsx +0 -77
  210. package/src/resources/Brand/BrandResource.tsx +0 -130
  211. package/src/resources/DASHResourceLoader.ts +0 -180
  212. package/src/resources/Log/LogResource.tsx +0 -73
  213. package/src/resources/Tenant/ImpersonateTenantResource.tsx +0 -113
  214. package/src/resources/Trash/TrashTemplate.tsx +0 -180
  215. package/src/resources/User/components/AvatarUploadField.tsx +0 -57
  216. package/src/resources/User/components/PasswordFields.tsx +0 -73
  217. package/src/resources/User/getProfileMenu.ts +0 -57
  218. package/src/resources/User/profileResource.tsx +0 -51
  219. package/src/resources/User/userLayout.tsx +0 -62
  220. package/src/resources/User/userResource.tsx +0 -111
  221. package/src/resources/User/userSchema.tsx +0 -213
  222. package/src/resources/User/usersFilters.tsx +0 -21
  223. package/src/resources.tsx +0 -280
  224. package/src/schemas/log.tsx +0 -45
  225. package/src/schemas/notification.tsx +0 -42
  226. package/src/schemas/permissions.tsx +0 -44
  227. package/src/schemas/roles.tsx +0 -48
  228. package/src/schemas/rolesDataGrid.tsx +0 -48
  229. package/src/schemas/subscription/components/SubscriptionActions.tsx +0 -153
  230. package/src/schemas/subscription/components/SubscriptionPaymentHistory.tsx +0 -127
  231. package/src/schemas/subscription/components/SubscriptionPlanFeatures.tsx +0 -162
  232. package/src/schemas/subscription/components/SubscriptionPlanPreview.tsx +0 -141
  233. package/src/schemas/subscription/components/SubscriptionPlanStats.tsx +0 -318
  234. package/src/schemas/subscription/components/SubscriptionStatusIndicator.tsx +0 -72
  235. package/src/schemas/subscription/subscriptionPlanSchema.tsx +0 -185
  236. package/src/schemas/subscription/subscriptionSchema.tsx +0 -152
  237. package/src/schemas/subscriptionPlan.ts +0 -422
  238. package/src/schemas/tenant.tsx +0 -129
  239. package/src/schemas/tenantUser.tsx +0 -96
  240. package/src/schemas/tenant_superadmin.tsx +0 -119
  241. package/src/schemas/user.tsx +0 -26
  242. package/src/systemResources.old.tsx +0 -928
  243. package/src/systemResources.tsx +0 -1369
  244. package/src/templates/ResourceTemplate.tsx +0 -240
  245. package/src/templates/ResourceTemplate.tsx.memoized_experiment +0 -350
  246. package/src/templates/ResourceTemplate.tsx.original +0 -396
  247. package/src/templates/ResourceTemplateCreate.tsx +0 -182
  248. package/src/templates/ResourceTemplateEdit.tsx +0 -176
  249. package/src/templates/ResourceTemplateFull.tsx +0 -581
  250. package/src/templates/ResourceTemplateList.tsx +0 -340
  251. package/src/templates/ResourceTemplateOld.tsx.bkup +0 -567
  252. package/src/templates/ResourceTemplateShow.tsx +0 -88
  253. package/src/templates/TrashTemplate.tsx +0 -179
  254. package/src/tenantResources.tsx +0 -223
  255. package/src/test_portal_bubbles.tsx +0 -40
  256. package/src/theme/AppHeader.tsx +0 -52
  257. package/src/theme/AppLayoutSetting.tsx +0 -33
  258. package/src/theme/AppLogo.tsx +0 -13
  259. package/src/theme/AppSidebar.tsx +0 -12
  260. package/src/theme/AppSidebarContent.tsx +0 -105
  261. package/src/theme/AppSidebarLogo.tsx +0 -48
  262. package/src/theme/components/PageTitle.tsx +0 -37
  263. package/src/utils/cache/CacheInvalidatorContext.tsx +0 -125
  264. package/src/utils/cache/CacheInvalidatorListenerComponent.tsx +0 -10
  265. package/src/utils/cache/useCacheInvalidatorListener.tsx +0 -27
  266. package/src/utils/convertFileToBase64.tsx +0 -9
  267. package/src/utils/convertToFile.tsx +0 -14
  268. package/src/utils/cookies.tsx +0 -33
  269. package/src/utils/dashDefaultQueryClient.tsx +0 -34
  270. package/src/utils/dataUrlToBlob.tsx +0 -30
  271. package/src/utils/deepReplace.tsx +0 -19
  272. package/src/utils/getProfileMenu.tsx +0 -41
  273. package/src/utils/getTenantSettings.tsx +0 -9
  274. package/src/utils/getType.tsx +0 -8
  275. package/src/utils/getUserSettings.tsx +0 -8
  276. package/src/utils/hasCode.tsx +0 -14
  277. package/src/utils/index.ts +0 -19
  278. package/src/utils/injectTenantStyles.ts +0 -28
  279. package/src/utils/isComponent.tsx +0 -45
  280. package/src/utils/navEvents.tsx +0 -91
  281. package/src/utils/prototypes.tsx +0 -5
  282. package/src/utils/regexp.tsx +0 -4
  283. package/src/utils/resolveObjectPath.tsx +0 -4
  284. package/src/utils/setNativeValue.tsx +0 -24
  285. package/src/utils/slugify.tsx +0 -11
  286. package/src/utils/validators/emailValidator.tsx +0 -6
  287. package/src/utils/validators/requiredValidator.tsx +0 -5
  288. package/src/utils/validators/rutValidator.tsx +0 -31
  289. package/src/utils/validators.tsx +0 -96
@@ -1,915 +0,0 @@
1
- /**
2
- * Lightweight authentication service for public app
3
- * This service handles authentication without react-admin dependencies
4
- */
5
-
6
- import { createAxiosInstance } from 'dash-axios-hook';
7
- import { getCookie, setCookie } from '../../utils/cookies';
8
- import { getEnv } from '../../config/DASHAdminSystemConstants';
9
- import { AuthPersistenceService, syncLocalStorageToDeviceStore, clearDeviceStoreAuth } from 'dash-auth';
10
- import { setAuthEvent } from './AuthContext';
11
- import {DASHAppConstants} from 'dash-constants';
12
-
13
- import {DASHAdminSystemConstants} from 'dash-constants'
14
-
15
- import { dashStorage } from 'dash-utils';
16
-
17
- import { DASH_REDUX_ACTIONS, dispatchToRedux } from 'dash-admin-state';
18
- import { ACTION_UPDATE_AUTH } from 'dash-admin-state/src/redux/reducers/Auth';
19
- export interface DASHAuthenticationServiceLoginCredentials {
20
- username: string;
21
- password: string;
22
- redirect?: string;
23
- meta?: any;
24
- }
25
-
26
- export interface DASHAuthenticationServiceAuthResponse {
27
- success: boolean;
28
- token?: string;
29
- user?: any;
30
- auth?: any;
31
- refreshToken?: string;
32
- error?: string;
33
- redirectAfterLogin?: string;
34
- }
35
-
36
- /*
37
- @TechDebt: refresh token strategy not implemented neither in backend or frontend.
38
- */
39
- class DASHAuthenticationService {
40
- private axiosInstance: any;
41
- private readonly REDIRECT_STORAGE_KEY = 'redirectAfterLogin';
42
-
43
- constructor() {
44
- // Initialize axios instance in constructor
45
- this.axiosInstance = createAxiosInstance();
46
- }
47
-
48
- // Method to recreate axios instance with new options if needed
49
- reinitializeAxios(options?: any) {
50
- this.axiosInstance = createAxiosInstance(options);
51
- }
52
-
53
- // Helper to sanitize redirect URLs for Electron file:// paths
54
- private sanitizeRedirectUrl(url: string): string {
55
- if (!url) return '/';
56
-
57
- // Check if this looks like a Windows file path (common in Electron)
58
- // e.g., "/C:/Program Files/..." or "C:/..." or file:// URLs
59
- const isWindowsFilePath = /^\/[A-Za-z]:\/|^[A-Za-z]:\/|^file:\/\//i.test(url);
60
-
61
- // Check if we are in an Electron/HashRouter environment
62
- const isElectron = window.location.protocol === 'file:' ||
63
- getEnv('IS_ELECTRON') === 'true' ||
64
- getEnv('IS_ELECTRON') === true;
65
-
66
- // Fix for Electron: If it is a file:// URL (or Windows path) AND contains a hash,
67
- // implies we want to preserve the internal route (e.g. file:///.../index.html#/dashboard)
68
- if (isWindowsFilePath || url.includes('index.html')) {
69
- if (url.includes('#')) {
70
- const parts = url.split('#');
71
- if (parts.length > 1 && parts[1]) {
72
- const route = parts[1];
73
- console.log('Detected file/electron path with hash, extracting route:', route);
74
- return '#' + route;
75
- }
76
- }
77
- }
78
-
79
- if (isWindowsFilePath) {
80
- console.log('Detected Windows file path in redirect, resetting to #/');
81
- return '#/';
82
- }
83
-
84
- // Check for common Electron file patterns
85
- if (url.includes('/resources/app/') || url.includes('/dist/index.html') || url.includes('Program Files')) {
86
- console.log('Detected Electron app path in redirect, resetting to #/');
87
- return '#/';
88
- }
89
-
90
- // If we are in Electron and the URL is a standard path (e.g. /selfservice/qr) without a hash,
91
- // force the hash prefix so HashRouter handles it correctly.
92
- if (isElectron && url.startsWith('/') && !url.startsWith('#')) {
93
- console.log('Detected Electron environment with standard path, adding hash prefix:', url);
94
- return '#' + url;
95
- }
96
-
97
- return url;
98
- }
99
-
100
- // Method to set pending redirect URL
101
- setPendingRedirect(url: string): void {
102
- // Guard: Skip if redirect is root path (causes infinite redirect loops)
103
- if (!url || url === '/' || url === '#/' || url === '#') {
104
- console.log('Skipping pending redirect for root path:', url);
105
- return;
106
- }
107
- const sanitizedUrl = this.sanitizeRedirectUrl(url);
108
- // Double-check sanitized URL isn't root either
109
- if (sanitizedUrl === '/' || sanitizedUrl === '#/' || sanitizedUrl === '#') {
110
- console.log('Skipping pending redirect for sanitized root path:', sanitizedUrl);
111
- return;
112
- }
113
- console.log('Setting pending redirect:', url, '→', sanitizedUrl);
114
- dashStorage.setItem(this.REDIRECT_STORAGE_KEY, sanitizedUrl);
115
- }
116
-
117
- // Method to get pending redirect URL
118
- getPendingRedirect(): string | null {
119
- return dashStorage.getItem(this.REDIRECT_STORAGE_KEY);
120
- }
121
-
122
- // Method to clear pending redirect URL
123
-
124
- clearPendingRedirect(): void {
125
- console.log('Clearing pending redirect');
126
- dashStorage.removeItem(this.REDIRECT_STORAGE_KEY);
127
- }
128
-
129
- // Helper to get redirect URL from user's first role with a configured redirect
130
- private getRoleRedirect(user: any): string | null {
131
- const roles = user?.roles;
132
- if (Array.isArray(roles) && roles.length > 0) {
133
- // Return the first role's redirect if defined
134
- for (const role of roles) {
135
- if (role.redirect) {
136
- console.log('Found role redirect:', role.name, '->', role.redirect);
137
- return role.redirect;
138
- }
139
- }
140
- }
141
- return null;
142
- }
143
-
144
- // Method to determine final redirect URL (backend takes precedence over localStorage)
145
- // persistRedirect: if true, saves to storage (use during login). If false, just returns the value (use during app init).
146
- private determineRedirectUrl(backendRedirect?: string, persistRedirect: boolean = true): string | null {
147
-
148
- let val = null;
149
- // Backend redirect takes precedence
150
- if (backendRedirect) {
151
- console.log('Using backend redirect:', backendRedirect, '(persist:', persistRedirect, ')');
152
- val = backendRedirect;
153
- if (persistRedirect) {
154
- this.setPendingRedirect(val);
155
- return this.getPendingRedirect();
156
- }
157
- return this.sanitizeRedirectUrl(val);
158
- }
159
-
160
- // Fall back to localStorage redirect
161
- const localStorageRedirect = this.getPendingRedirect();
162
- if (localStorageRedirect) {
163
- console.log('Using localStorage redirect:', localStorageRedirect);
164
- return localStorageRedirect;
165
- }
166
-
167
- val = getEnv("APP_DEFAULT_REDIRECT");
168
- if (persistRedirect) {
169
- this.setPendingRedirect(val);
170
- return this.getPendingRedirect();
171
- }
172
-
173
- return this.sanitizeRedirectUrl(val);
174
- }
175
-
176
- /**
177
- * Syncs the local "which tenant is this session scoped to" storage from
178
- * the backend's own resolution, on every auth response — login, token
179
- * init, refresh, and the persisted-auth fallback all call this so none of
180
- * them can drift out of sync with what the other three do.
181
- *
182
- * `auth.active_tenant_id` (see TenancyContextService on the backend) is
183
- * always authoritative now: a plain tenant-scoped user gets their own
184
- * tenant, a TenancyAdmin managing one tenant gets that one automatically,
185
- * and a TenancyAdmin managing several gets whatever they last explicitly
186
- * picked via TenantSwitcher (persisted server-side) — or null, which is a
187
- * real, intentional "prefers the tenancy-wide view" state, not "unset".
188
- * Trusting the backend outright (no `!dashStorage.getItem(...)` guard)
189
- * is what makes a preference set on one device actually show up on
190
- * another — the entire point of persisting it server-side instead of
191
- * only in this browser's storage.
192
- */
193
- private syncActiveTenant(auth: any): void {
194
- const impersonationEnabled = JSON.parse(
195
- DASHAdminSystemConstants.system.ENABLE_TENANT_IMPERSONATION.toString(),
196
- );
197
-
198
- if (!impersonationEnabled || !auth?.user?.tenant_id) {
199
- return;
200
- }
201
-
202
- dashStorage.setItem('tenant_id', auth.user.tenant_id);
203
- dashStorage.setItem('user_id', auth.user.id);
204
-
205
- const activeTenantId = auth.auth?.active_tenant_id;
206
- if (activeTenantId) {
207
- dashStorage.setItem('active_tenant_id', activeTenantId);
208
- } else {
209
- dashStorage.removeItem('active_tenant_id');
210
- }
211
- }
212
-
213
- // Update the login method to dispatch to Redux directly
214
- async login(credentials: DASHAuthenticationServiceLoginCredentials): Promise<DASHAuthenticationServiceAuthResponse> {
215
- console.log("=== DASH AUTH SERVICE LOGIN START ===");
216
- console.log("Credentials:", { username: credentials.username, password: "***", redirect: credentials.redirect, meta: credentials.meta });
217
-
218
- if (!(credentials.username && credentials.password)) {
219
- console.log("❌ Missing credentials");
220
- return Promise.resolve({
221
- success: false,
222
- error: 'Username and password are required'
223
- });
224
- }
225
-
226
- try {
227
- console.log("Making login request to /login");
228
-
229
- const loginResponse = await this.axiosInstance.post('/login', {
230
- email: credentials.username,
231
- password: credentials.password,
232
- redirect: credentials.redirect,
233
- meta: credentials.meta
234
- });
235
-
236
- console.log("Login response status:", loginResponse.status);
237
- console.log("Login response data:", loginResponse.data);
238
-
239
-
240
-
241
- if (loginResponse.status >= 200 && loginResponse.status <= 299) {
242
- console.log("✅ Login response successful");
243
-
244
- // ✅ Extract redirectTo from backend response FIRST
245
- const backendRedirectTo = loginResponse.data.redirectTo;
246
-
247
- console.log("đŸŽ¯ Backend redirectTo:", backendRedirectTo);
248
-
249
- const today = new Date();
250
- const expires = new Date();
251
- expires.setDate(today.getDate() + 2);
252
-
253
- // Check if we have token data
254
- if (loginResponse.data && loginResponse.data.token) {
255
-
256
- console.log("Setting token in storage");
257
- //setCookie('token', loginResponse.data.token, { expires });
258
- dashStorage.setItem('token', loginResponse.data.token);
259
-
260
- // Handle refresh token (backend uses snake_case: refresh_token)
261
- const refreshToken = loginResponse.data?.refresh_token || loginResponse.data?.refreshToken;
262
- if (refreshToken) {
263
- console.log("Setting refresh token in storage");
264
- dashStorage.setItem('refreshToken', refreshToken);
265
- }
266
-
267
- if (loginResponse.data?.meta) {
268
- console.log("Setting app");
269
- dashStorage.setItem('app', loginResponse.data.meta.app);
270
- }
271
-
272
- await syncLocalStorageToDeviceStore();
273
-
274
- } else {
275
- console.warn("âš ī¸ No token in login response");
276
- }
277
-
278
- try {
279
- console.log("Getting auth data from:", getEnv('APP_GETAUTH_ENDPOINT'));
280
-
281
- // Get complete auth data
282
- const authResponse = await this.axiosInstance.get(getEnv('APP_GETAUTH_ENDPOINT'));
283
- console.log("Auth response status:", authResponse.status);
284
- console.log("Auth response data:", authResponse.data);
285
-
286
- const auth = authResponse.data;
287
-
288
- // ✅ Use backend redirectTo as the primary redirect
289
- let finalRedirect = backendRedirectTo;
290
-
291
- // Only fall back to other redirects if backend didn't provide one
292
- if (!finalRedirect) {
293
- // Check auth response redirect, then check role redirects
294
- const roleRedirect = this.getRoleRedirect(auth.user);
295
- const authRedirect = auth.redirect || auth.user?.redirect || roleRedirect || null;
296
- console.log("Auth response redirect:", authRedirect, "(role redirect:", roleRedirect, ")");
297
-
298
- if (authRedirect) {
299
- finalRedirect = authRedirect;
300
- } else if (credentials.redirect && credentials.redirect !== '/login') {
301
- finalRedirect = credentials.redirect;
302
- } else {
303
- finalRedirect = getEnv("APP_DEFAULT_REDIRECT") || '/';
304
- }
305
- }
306
-
307
- console.log("đŸŽ¯ Final redirect determined:", finalRedirect);
308
-
309
- // Use AuthPersistenceService to save auth data
310
- AuthPersistenceService.saveAuth(auth);
311
-
312
- // Sync dash-user-locale with tenant's primary language or user preference
313
- const languageCode = auth.auth?.tenantSettings?.primary_language_code || auth.user?.preferences?.locale;
314
- if (languageCode) {
315
- localStorage.setItem('dash-user-locale', languageCode);
316
- // Dispatch event to trigger I18nBridgeContext locale change
317
- window.dispatchEvent(new CustomEvent('dash:locale-change', {
318
- detail: { locale: languageCode }
319
- }));
320
- console.log('🌐 DASHAuthService: Dispatched locale change event:', languageCode);
321
- }
322
-
323
- // Set basic localStorage for react-admin compatibility
324
- dashStorage.setItem('authenticated', 'true');
325
- dashStorage.setItem('user', JSON.stringify(auth.user));
326
- dashStorage.setItem(
327
- 'roles',
328
- auth.user?.roles
329
- ? JSON.stringify(auth.user.roles)
330
- : JSON.stringify(DASHAppConstants.system.GUEST_ROLE),
331
- );
332
-
333
- // Handle tenant impersonation if enabled, including which
334
- // tenant this session starts scoped to.
335
- this.syncActiveTenant(auth);
336
-
337
- const resultObject = {
338
- authenticated: true,
339
- user: auth.user,
340
- auth: auth.auth,
341
- token: loginResponse.data.token || dashStorage.getItem('token'),
342
- roles: auth.user?.roles
343
- }
344
-
345
- // Dispatch directly to Redux instead of using setAuthEvent
346
- console.log('🔄 DASHAuthenticationService: Dispatching to Redux:', resultObject);
347
- dispatchToRedux(
348
- DASH_REDUX_ACTIONS.updateAuth(ACTION_UPDATE_AUTH, {
349
- user: resultObject.user,
350
- authenticated: resultObject.authenticated,
351
- auth: resultObject.auth,
352
- })
353
- );
354
-
355
- await syncLocalStorageToDeviceStore();
356
- console.log("✅ Login completed successfully");
357
- return Promise.resolve({
358
- success: true,
359
- token: resultObject.token,
360
- user: resultObject.user,
361
- auth: resultObject.auth,
362
- redirectAfterLogin: finalRedirect, // ✅ Use the backend redirectTo
363
- });
364
- } catch (error) {
365
- await syncLocalStorageToDeviceStore();
366
- console.error('❌ Error getting auth data:', error);
367
- this.logoutFromStorage("login get auth error");
368
- return Promise.resolve({
369
- success: false,
370
- error: 'Failed to get user authentication data'
371
- });
372
- }
373
- } else {
374
- await syncLocalStorageToDeviceStore();
375
- console.log("❌ Login response status not successful:", loginResponse.status);
376
- this.logoutFromStorage("login status error logout");
377
- return Promise.reject({
378
- success: false,
379
- error: `Login failed with status: ${loginResponse.status}`
380
- });
381
- }
382
- } catch (error: any) {
383
- await syncLocalStorageToDeviceStore();
384
- console.error('❌ Login error:', error);
385
- console.error('Error details:', {
386
- message: error?.message,
387
- response: error?.response?.data,
388
- status: error?.response?.status
389
- });
390
- this.logoutFromStorage("login error logout");
391
- await syncLocalStorageToDeviceStore();
392
- return Promise.reject({
393
- success: false,
394
- error: error?.response?.data?.message || error?.message || 'Login failed'
395
- });
396
- }
397
-
398
-
399
- }
400
-
401
- // Update the initializeFromToken method to dispatch to Redux directly
402
- async initializeFromToken(): Promise<DASHAuthenticationServiceAuthResponse> {
403
- const token = dashStorage.getItem('token');
404
-
405
- if (!token) {
406
- return {
407
- success: false,
408
- error: 'No token found'
409
- };
410
- }
411
-
412
- try {
413
- console.log('Initializing auth from existing token...');
414
-
415
- // Get complete auth data using existing token
416
- const { data: auth } = await this.axiosInstance.get(getEnv('APP_GETAUTH_ENDPOINT'));
417
-
418
- // Extract redirect from backend auth response, including role redirects
419
- const roleRedirect = this.getRoleRedirect(auth.user);
420
- const backendRedirect = auth.redirect || auth.user?.redirect || roleRedirect || null;
421
- console.log("Backend redirect found during token initialization:", backendRedirect, "(role redirect:", roleRedirect, ")");
422
-
423
- // Use AuthPersistenceService to save auth data
424
- AuthPersistenceService.saveAuth(auth);
425
-
426
- // Set basic localStorage for react-admin compatibility
427
- dashStorage.setItem('authenticated', 'true');
428
- dashStorage.setItem('user', JSON.stringify(auth.user));
429
- dashStorage.setItem(
430
- 'roles',
431
- auth.user?.roles
432
- ? JSON.stringify(auth.user.roles)
433
- : JSON.stringify(DASHAppConstants.system.GUEST_ROLE),
434
- );
435
-
436
- // Handle tenant impersonation if enabled, including which tenant
437
- // this session is scoped to.
438
- this.syncActiveTenant(auth);
439
- if (auth.user?.tenant_id) {
440
- setCookie('tenant_id', auth.user.tenant_id);
441
- setCookie('user_id', auth.user.id);
442
- }
443
-
444
- const resultObject = {
445
- authenticated: true,
446
- user: auth.user,
447
- auth: auth.auth,
448
- token: token,
449
- roles: auth.user?.roles
450
- };
451
-
452
- // Dispatch directly to Redux instead of using setAuthEvent
453
- console.log('🔄 DASHAuthenticationService: Dispatching token init to Redux:', resultObject);
454
- dispatchToRedux(
455
- DASH_REDUX_ACTIONS.updateAuth(ACTION_UPDATE_AUTH, {
456
- user: resultObject.user,
457
- authenticated: resultObject.authenticated,
458
- auth: resultObject.auth,
459
- })
460
- );
461
-
462
- console.log('Auth initialized successfully from existing token');
463
- await syncLocalStorageToDeviceStore();
464
- // Determine final redirect URL - don't persist during token init (only during actual login)
465
- const redirectAfterLogin = this.determineRedirectUrl(backendRedirect, false);
466
-
467
- return {
468
- success: true,
469
- token: token,
470
- user: auth.user,
471
- auth: auth.auth,
472
- redirectAfterLogin: redirectAfterLogin
473
- };
474
- } catch (error) {
475
- console.error('Error initializing auth from token:', error);
476
- this.logoutFromStorage("initialize from token error");
477
- await syncLocalStorageToDeviceStore();
478
- return {
479
- success: false,
480
- error: 'Failed to initialize authentication from token'
481
- };
482
- }
483
- }
484
-
485
- async refreshToken(refreshToken: string): Promise<DASHAuthenticationServiceAuthResponse> {
486
- try {
487
- console.log('[DASHAuthService] Attempting to refresh token...');
488
-
489
- const response = await this.axiosInstance.post('/auth/refresh', {
490
- refresh_token: refreshToken
491
- });
492
-
493
- if (response.status >= 200 && response.status <= 299) {
494
- const data = response.data;
495
-
496
- // Update stored auth data using the same pattern as login
497
- if (data.token) {
498
- dashStorage.setItem('token', data.token);
499
- console.log('[DASHAuthService] Access token updated');
500
- }
501
-
502
- if (data.refresh_token) {
503
- dashStorage.setItem('refreshToken', data.refresh_token);
504
- console.log('[DASHAuthService] Refresh token rotated');
505
- }
506
-
507
- await syncLocalStorageToDeviceStore();
508
-
509
- console.log('[DASHAuthService] Token refresh successful');
510
-
511
- return {
512
- success: true,
513
- token: data.token,
514
- refreshToken: data.refresh_token,
515
- user: data.user
516
- };
517
- } else {
518
- console.warn('[DASHAuthService] Token refresh returned non-success status:', response.status);
519
- return {
520
- success: false,
521
- error: 'Token refresh failed'
522
- };
523
- }
524
- } catch (error: any) {
525
- console.error('[DASHAuthService] Token refresh error:', error);
526
-
527
- // Check if it's a 401 error (refresh token expired/invalid)
528
- if (error?.response?.status === 401) {
529
- console.log('[DASHAuthService] Refresh token is invalid or expired');
530
- // Clear auth state since refresh token is no longer valid
531
- this.logoutFromStorage('refresh_token_expired');
532
- }
533
-
534
- return {
535
- success: false,
536
- error: error?.response?.data?.message || error?.message || 'Network error occurred'
537
- };
538
- }
539
- }
540
-
541
- private logoutFromStorage = async (reason: string) => {
542
- console.log("logoutFromStorage", reason);
543
-
544
- // Clear pending redirect on logout
545
- //this.clearPendingRedirect();
546
- // Store current path as pending redirect
547
-
548
-
549
-
550
- // Use the centralized persistence service instead of manual cleanup
551
- AuthPersistenceService.markAsLoggedOut();
552
-
553
- // Clear auth data from device store (Electron/Capacitor)
554
- // This is crucial - it removes token/user from electron-store so they
555
- // don't get restored on next app launch
556
- await clearDeviceStoreAuth();
557
-
558
- // Keep only the IPC service cleanup
559
- const { DashIPCService } = window as any;
560
- DashIPCService && DashIPCService.action('stop-bg-service');
561
- };
562
-
563
- async checkAuth(): Promise<boolean> {
564
- // First check localStorage for basic auth state
565
- const isAuthenticated = JSON.parse(dashStorage.getItem('authenticated') || 'false');
566
- const user = JSON.parse(dashStorage.getItem('user') || 'null');
567
-
568
- if (isAuthenticated && user?.id) {
569
- // Also check if we have valid persisted auth data
570
- const persistedAuth = AuthPersistenceService.getAuth();
571
- if (persistedAuth) {
572
- return true;
573
- }
574
- }
575
-
576
- return false;
577
- }
578
-
579
- async getIdentity(): Promise<any> {
580
- const token = dashStorage.getItem('token');
581
- if (!token) {
582
- throw new Error('No token present');
583
- }
584
-
585
- try {
586
- const { data: auth } = await this.axiosInstance.get(getEnv('APP_GETAUTH_ENDPOINT'));
587
-
588
- dashStorage.setItem(
589
- 'roles',
590
- auth.user?.roles
591
- ? JSON.stringify(auth.user.roles)
592
- : JSON.stringify(DASHAppConstants.system.GUEST_ROLE),
593
- );
594
- dashStorage.setItem('authenticated', 'true');
595
- dashStorage.setItem('user', JSON.stringify(auth.user));
596
-
597
- // Handle tenant impersonation if enabled, including which tenant
598
- // this session is scoped to.
599
- this.syncActiveTenant(auth);
600
-
601
- await syncLocalStorageToDeviceStore();
602
-
603
- return auth;
604
- } catch (error) {
605
- this.logoutFromStorage("get identity error logout");
606
- throw error;
607
- }
608
- }
609
-
610
- // Rest of your methods remain the same...
611
- async shouldRefreshToken(): Promise<boolean> {
612
- const token = dashStorage.getItem('token');
613
- if (!token) return false;
614
-
615
- const refreshToken = dashStorage.getItem('refreshToken');
616
- return !!refreshToken;
617
- }
618
-
619
- async handleTokenRefresh(): Promise<boolean> {
620
- const refreshToken = dashStorage.getItem('refreshToken');
621
- if (!refreshToken) return false;
622
-
623
- try {
624
- const refreshResponse = await this.refreshToken(refreshToken);
625
- if (refreshResponse.success) {
626
-
627
- // Update localStorage with new token
628
- dashStorage.setItem('token', refreshResponse.token!);
629
- if (refreshResponse.refreshToken) {
630
- dashStorage.setItem('refreshToken', refreshResponse.refreshToken);
631
- }
632
- await syncLocalStorageToDeviceStore();
633
- return true;
634
- }
635
- } catch (error) {
636
- console.error('Token refresh failed:', error);
637
- this.logoutFromStorage("token refresh failed");
638
- }
639
- return false;
640
- }
641
-
642
- // Method to check if we should initialize from token on app load
643
- async shouldInitializeFromToken(forceGetAuth?: boolean): Promise<boolean> {
644
-
645
- if (forceGetAuth) { return true };
646
-
647
- const token = dashStorage.getItem('token');
648
- const isAuthenticated = JSON.parse(dashStorage.getItem('authenticated') || 'false');
649
- const user = dashStorage.getItem('user');
650
-
651
- // If we have a token but are not fully authenticated, we should initialize
652
- return !!(token && (!isAuthenticated || !user));
653
- }
654
-
655
- // Update the initializeApp method to dispatch to Redux directly
656
- async initializeApp(forceGetAuth?: boolean): Promise<DASHAuthenticationServiceAuthResponse> {
657
-
658
-
659
- console.log('Initializing DASH app authentication...');
660
- const USES_GET_AUTH = true; // TODO: add the get auth to the env and retrieve it through getEnv. nevertheless all apps uses getAuth.
661
-
662
- const shouldInit = await this.shouldInitializeFromToken(forceGetAuth);
663
-
664
- if (shouldInit) {
665
- console.log('Token found but not fully authenticated, initializing...');
666
- return await this.initializeFromToken();
667
- } else {
668
- const token = dashStorage.getItem('token');
669
- const isAuthenticated = JSON.parse(dashStorage.getItem('authenticated') || 'false');
670
- const user = dashStorage.getItem('user');
671
-
672
- if (token && isAuthenticated && user) {
673
- console.log('Already authenticated, checking if auth refresh needed');
674
-
675
- // If shouldGetAuth is true, refresh auth data to get latest tenant/user info
676
- if (USES_GET_AUTH) {
677
- try {
678
- console.log('Refreshing auth data for latest tenant/user information...');
679
-
680
- // Get fresh auth data
681
- const authResponse = await this.axiosInstance.get(getEnv('APP_GETAUTH_ENDPOINT'));
682
- console.log("Fresh auth response:", authResponse.data);
683
-
684
- const auth = authResponse.data;
685
-
686
- // Extract redirect from backend auth response, including role redirects
687
- const roleRedirect = this.getRoleRedirect(auth.user);
688
- const backendRedirect = auth.redirect || auth.user?.redirect || roleRedirect || null;
689
- console.log("Backend redirect found during app initialization:", backendRedirect, "(role redirect:", roleRedirect, ")");
690
-
691
- // Update stored auth data
692
- AuthPersistenceService.saveAuth(auth);
693
-
694
- // Sync dash-user-locale with fresh tenant/user preference
695
- const languageCode = auth.auth?.tenantSettings?.primary_language_code || auth.user?.preferences?.locale;
696
- if (languageCode) {
697
- localStorage.setItem('dash-user-locale', languageCode);
698
- // Dispatch event to trigger I18nBridgeContext locale change
699
- window.dispatchEvent(new CustomEvent('dash:locale-change', {
700
- detail: { locale: languageCode }
701
- }));
702
- console.log('🌐 DASHAuthService: Dispatched locale change event (app init):', languageCode);
703
- }
704
-
705
- // Update localStorage with fresh data
706
- dashStorage.setItem('user', JSON.stringify(auth.user));
707
- dashStorage.setItem(
708
- 'roles',
709
- auth.user?.roles
710
- ? JSON.stringify(auth.user.roles)
711
- : JSON.stringify(DASHAppConstants.system.GUEST_ROLE),
712
- );
713
-
714
- // Handle tenant impersonation with fresh data, including
715
- // which tenant this session is scoped to.
716
- this.syncActiveTenant(auth);
717
-
718
- const resultObject = {
719
- authenticated: true,
720
- user: auth.user,
721
- auth: auth.auth,
722
- token: token,
723
- roles: auth.user?.roles
724
- };
725
-
726
- // Dispatch directly to Redux with fresh data
727
- console.log('🔄 DASHAuthenticationService: Dispatching fresh auth to Redux:', resultObject);
728
- dispatchToRedux(
729
- DASH_REDUX_ACTIONS.updateAuth(ACTION_UPDATE_AUTH, {
730
- user: resultObject.user,
731
- authenticated: resultObject.authenticated,
732
- auth: resultObject.auth,
733
- })
734
- );
735
-
736
- // Determine final redirect URL (backend takes precedence)
737
- // Don't persist redirect during app init - only during actual login
738
- const redirectAfterLogin = this.determineRedirectUrl(backendRedirect, false);
739
-
740
- console.log('Auth data refreshed successfully');
741
-
742
- await syncLocalStorageToDeviceStore();
743
-
744
- return {
745
- success: true,
746
- token: token,
747
- user: auth.user,
748
- auth: auth.auth,
749
- redirectAfterLogin: redirectAfterLogin
750
- };
751
-
752
- } catch (error) {
753
- console.error('Error refreshing auth data:', error);
754
-
755
- // If refresh fails, fall back to existing data but don't fail the initialization
756
- console.log('Falling back to existing auth data');
757
-
758
- const existingUser = JSON.parse(user);
759
- const persistedAuth = AuthPersistenceService.getAuth();
760
-
761
- // Dispatch existing data to Redux
762
- console.log('🔄 DASHAuthenticationService: Dispatching existing auth to Redux');
763
- dispatchToRedux(
764
- DASH_REDUX_ACTIONS.updateAuth(ACTION_UPDATE_AUTH, {
765
- user: existingUser,
766
- authenticated: true,
767
- auth: persistedAuth?.auth || null,
768
- })
769
- );
770
-
771
- // Still check for localStorage redirect as fallback
772
- // Don't persist redirect during app init - only during actual login
773
- const redirectAfterLogin = this.determineRedirectUrl(undefined, false);
774
-
775
- await syncLocalStorageToDeviceStore();
776
-
777
- return {
778
- success: true,
779
- token: token,
780
- user: existingUser,
781
- auth: persistedAuth?.auth || null,
782
- redirectAfterLogin: redirectAfterLogin
783
- };
784
- }
785
- } else {
786
- console.log('No auth refresh needed, using existing data');
787
-
788
- const existingUser = JSON.parse(user);
789
- const persistedAuth = AuthPersistenceService.getAuth();
790
-
791
- // Dispatch existing data to Redux
792
- console.log('🔄 DASHAuthenticationService: Dispatching existing auth to Redux');
793
- dispatchToRedux(
794
- DASH_REDUX_ACTIONS.updateAuth(ACTION_UPDATE_AUTH, {
795
- user: existingUser,
796
- authenticated: true,
797
- auth: persistedAuth?.auth || null,
798
- })
799
- );
800
-
801
- // Still check for pending redirect even if not refreshing auth
802
- // Don't persist redirect during app init - only during actual login
803
- const redirectAfterLogin = this.determineRedirectUrl(undefined, false);
804
-
805
- await syncLocalStorageToDeviceStore();
806
-
807
- return {
808
- success: true,
809
- token: token,
810
- user: existingUser,
811
- auth: persistedAuth?.auth || null,
812
- redirectAfterLogin: redirectAfterLogin
813
- };
814
- }
815
- } else {
816
- console.log('No valid authentication found');
817
- await syncLocalStorageToDeviceStore();
818
- return {
819
- success: false,
820
- error: 'No valid authentication found'
821
- };
822
- }
823
- }
824
-
825
-
826
- }
827
-
828
- // Method to integrate with React Admin
829
- async loginWithReactAdmin(credentials: DASHAuthenticationServiceLoginCredentials, reactAdminLogin?: any): Promise<void> {
830
- debugger;
831
- const effectiveLogin = reactAdminLogin || this.login;
832
- const authResponse = await effectiveLogin(credentials);
833
- return authResponse;
834
- /*if (authResponse.success) {
835
- // Use React Admin's login with custom auth data
836
- await reactAdminLogin({
837
- customAuthData: {
838
- token: authResponse.token,
839
- user: authResponse.user,
840
- auth: authResponse.auth,
841
- refreshToken: authResponse.refreshToken,
842
- redirectAfterLogin: authResponse.redirectAfterLogin
843
- }
844
- });
845
- } else {
846
- throw new Error(authResponse.error || 'Login failed');
847
- }*/
848
- }
849
-
850
- // Function to get initial auth state with persisted values
851
- getInitialAuthState = () => {
852
- try {
853
- // Get persisted auth data
854
- const persistedAuth = AuthPersistenceService.getAuth();
855
- const storedUser = AuthPersistenceService.getUser();
856
- const storedToken = AuthPersistenceService.getToken();
857
- const isAuthenticated = JSON.parse(dashStorage.getItem('authenticated') || 'false');
858
-
859
- console.log('🔍 DASHLightApp: Initializing auth state with persisted data:', {
860
- hasPersistedAuth: !!persistedAuth,
861
- hasStoredUser: !!storedUser,
862
- hasStoredToken: !!storedToken,
863
- isAuthenticated,
864
- storedUser: storedUser ? `${storedUser.name || storedUser.email} (${storedUser.id})` : null,
865
- persistedAuthStructure: persistedAuth ? Object.keys(persistedAuth) : null
866
- });
867
-
868
- // If we have valid persisted auth data, use it
869
- if (isAuthenticated && storedUser && storedToken && persistedAuth) {
870
- console.log('✅ DASHLightApp: Using persisted auth state');
871
- const authState = {
872
- authenticated: true,
873
- user: storedUser, // This should be the actual user object
874
- auth: persistedAuth.auth || null, // This should be the actual auth object
875
- };
876
-
877
- console.log('🔍 DASHLightApp: Constructed auth state:', {
878
- authenticated: authState.authenticated,
879
- user: authState.user ? `${authState.user.name || authState.user.email} (${authState.user.id})` : null,
880
- auth: authState.auth ? 'present' : null
881
- });
882
-
883
- return authState;
884
- }
885
-
886
- // If we have a token but not full auth data, we'll let DASHAuthenticationService handle initialization
887
- if (storedToken && !isAuthenticated) {
888
- console.log('🔄 DASHLightApp: Token found but not authenticated, will initialize later');
889
- return {
890
- authenticated: false,
891
- user: null,
892
- auth: null,
893
- };
894
- }
895
-
896
- console.log('â„šī¸ DASHLightApp: No valid persisted auth found, using default auth state');
897
- return {
898
- authenticated: false,
899
- user: null,
900
- auth: null
901
- };
902
- } catch (error) {
903
- console.error('❌ DASHLightApp: Error getting initial auth state:', error);
904
- return {
905
- authenticated: false,
906
- user: null,
907
- auth: null
908
- };
909
- }
910
- };
911
-
912
-
913
- }
914
-
915
- export default new DASHAuthenticationService();