@vc-shell/framework 1.1.98-rc.4 → 1.1.99-alpha.0

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 (96) hide show
  1. package/core/api/platform.ts +9883 -9883
  2. package/core/composables/useNotifications/index.ts +32 -1
  3. package/core/composables/useSettings/index.ts +8 -3
  4. package/core/composables/useUser/index.ts +74 -171
  5. package/core/composables/useUserManagement/index.ts +67 -25
  6. package/core/interceptors/index.ts +19 -56
  7. package/core/plugins/signalR/index.ts +27 -1
  8. package/core/providers/README.md +176 -0
  9. package/core/providers/auth-provider-manager.ts +74 -0
  10. package/core/providers/auth-provider-utils.ts +26 -0
  11. package/core/providers/example-custom-auth-provider.ts +162 -0
  12. package/core/providers/index.ts +3 -0
  13. package/core/providers/platform-auth-provider.ts +207 -0
  14. package/core/types/auth-provider.ts +40 -0
  15. package/core/types/index.ts +2 -0
  16. package/dist/core/api/platform.d.ts +1 -1
  17. package/dist/core/api/platform.d.ts.map +1 -1
  18. package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
  19. package/dist/core/composables/useSettings/index.d.ts.map +1 -1
  20. package/dist/core/composables/useUser/index.d.ts +18 -9
  21. package/dist/core/composables/useUser/index.d.ts.map +1 -1
  22. package/dist/core/composables/useUserManagement/index.d.ts +7 -7
  23. package/dist/core/composables/useUserManagement/index.d.ts.map +1 -1
  24. package/dist/core/interceptors/index.d.ts +2 -1
  25. package/dist/core/interceptors/index.d.ts.map +1 -1
  26. package/dist/core/plugins/signalR/index.d.ts +2 -0
  27. package/dist/core/plugins/signalR/index.d.ts.map +1 -1
  28. package/dist/core/providers/auth-provider-manager.d.ts +34 -0
  29. package/dist/core/providers/auth-provider-manager.d.ts.map +1 -0
  30. package/dist/core/providers/auth-provider-utils.d.ts +17 -0
  31. package/dist/core/providers/auth-provider-utils.d.ts.map +1 -0
  32. package/dist/core/providers/example-custom-auth-provider.d.ts +45 -0
  33. package/dist/core/providers/example-custom-auth-provider.d.ts.map +1 -0
  34. package/dist/core/providers/index.d.ts +3 -0
  35. package/dist/core/providers/index.d.ts.map +1 -0
  36. package/dist/core/providers/platform-auth-provider.d.ts +34 -0
  37. package/dist/core/providers/platform-auth-provider.d.ts.map +1 -0
  38. package/dist/core/types/auth-provider.d.ts +27 -0
  39. package/dist/core/types/auth-provider.d.ts.map +1 -0
  40. package/dist/core/types/index.d.ts +1 -1
  41. package/dist/core/types/index.d.ts.map +1 -1
  42. package/dist/framework.js +6348 -6198
  43. package/dist/index.css +1 -1
  44. package/dist/index.d.ts +8 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/injection-keys.d.ts +2 -1
  47. package/dist/injection-keys.d.ts.map +1 -1
  48. package/dist/shared/components/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
  49. package/dist/shared/components/sign-in/useExternalProvider.d.ts +1 -1
  50. package/dist/shared/components/sign-in/useExternalProvider.d.ts.map +1 -1
  51. package/dist/shared/modules/dynamic/helpers/nodeBuilder.d.ts.map +1 -1
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
  54. package/dist/vendor-tiptap-core-ClsTgaMv.js +3699 -0
  55. package/dist/{vendor-tiptap-extension-blockquote-BVmAuV7o.js → vendor-tiptap-extension-blockquote-r1MBx4hD.js} +1 -1
  56. package/dist/{vendor-tiptap-extension-bold-BOh8AIRZ.js → vendor-tiptap-extension-bold-BjLI4i8b.js} +1 -1
  57. package/dist/{vendor-tiptap-extension-code-R4pc2wFE.js → vendor-tiptap-extension-code-D5-kDnMW.js} +1 -1
  58. package/dist/{vendor-tiptap-extension-code-block-DibKlZFG.js → vendor-tiptap-extension-code-block-RjEb0zPA.js} +1 -1
  59. package/dist/{vendor-tiptap-extension-document-BwORJR1k.js → vendor-tiptap-extension-document--PLOxIdq.js} +1 -1
  60. package/dist/{vendor-tiptap-extension-hard-break-DH36OfVk.js → vendor-tiptap-extension-hard-break-9cxC2YOS.js} +13 -9
  61. package/dist/{vendor-tiptap-extension-heading-oMLORiPI.js → vendor-tiptap-extension-heading-2w0TutHn.js} +1 -1
  62. package/dist/{vendor-tiptap-extension-horizontal-rule-BMHSoB_Y.js → vendor-tiptap-extension-horizontal-rule-CFowa_lc.js} +1 -1
  63. package/dist/vendor-tiptap-extension-image-aWn-na6j.js +127 -0
  64. package/dist/{vendor-tiptap-extension-italic-BzqrUuB0.js → vendor-tiptap-extension-italic-Bn-6saY0.js} +1 -1
  65. package/dist/{vendor-tiptap-extension-link-hMFZ0hfl.js → vendor-tiptap-extension-link-BmcG1_k-.js} +1 -1
  66. package/dist/{vendor-tiptap-extension-list-Bj5AK6Pq.js → vendor-tiptap-extension-list-BrNBJ45n.js} +1 -1
  67. package/dist/{vendor-tiptap-extension-paragraph-Bs1wl42E.js → vendor-tiptap-extension-paragraph-DAiYhwUB.js} +1 -1
  68. package/dist/vendor-tiptap-extension-placeholder-9tURDKy-.js +1 -0
  69. package/dist/{vendor-tiptap-extension-strike-C4YpGyzc.js → vendor-tiptap-extension-strike-DqbXPfos.js} +1 -1
  70. package/dist/vendor-tiptap-extension-table-DQwPaR7v.js +374 -0
  71. package/dist/vendor-tiptap-extension-table-cell-C0tEP_0i.js +1 -0
  72. package/dist/vendor-tiptap-extension-table-header-C0tEP_0i.js +1 -0
  73. package/dist/vendor-tiptap-extension-table-row-C0tEP_0i.js +1 -0
  74. package/dist/{vendor-tiptap-extension-text-C4dQW13r.js → vendor-tiptap-extension-text-BFnfj70b.js} +1 -1
  75. package/dist/{vendor-tiptap-extension-text-style-a_NYjXT6.js → vendor-tiptap-extension-text-style-Darua3qr.js} +1 -1
  76. package/dist/{vendor-tiptap-extension-underline-DthCaPX3.js → vendor-tiptap-extension-underline-QyVnBqQZ.js} +1 -1
  77. package/dist/{vendor-tiptap-extensions-C8rF1qdq.js → vendor-tiptap-extensions-CU-D7bfm.js} +1 -1
  78. package/dist/{vendor-tiptap-markdown-DRc3qhBU.js → vendor-tiptap-markdown-BwATYN5A.js} +1 -1
  79. package/dist/{vendor-tiptap-starter-kit-BfUUblkP.js → vendor-tiptap-starter-kit-5luf7zzS.js} +17 -17
  80. package/dist/{vendor-tiptap-vue-3-DYxT2sf6.js → vendor-tiptap-vue-3-CFBErZGb.js} +1 -1
  81. package/dist/{vendor-vueuse-components-B0zqjNRW.js → vendor-vueuse-components-sgKpNzof.js} +1 -1
  82. package/dist/{vendor-vueuse-core-CYgwn-B2.js → vendor-vueuse-core-D0cN7FqY.js} +10 -10
  83. package/dist/{vendor-vueuse-shared-B_uDJJ6V.js → vendor-vueuse-shared-Pt0UEStA.js} +19 -19
  84. package/package.json +7 -5
  85. package/shared/components/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +2 -2
  86. package/shared/components/app-switcher/composables/useAppSwitcher/index.ts +15 -1
  87. package/shared/components/sign-in/useExternalProvider.ts +11 -1
  88. package/shared/modules/dynamic/helpers/nodeBuilder.ts +11 -3
  89. package/ui/components/organisms/vc-app/vc-app.vue +20 -2
  90. package/dist/vendor-tiptap-core-8RGSOCZs.js +0 -3442
  91. package/dist/vendor-tiptap-extension-image-DF1ZJ94q.js +0 -80
  92. package/dist/vendor-tiptap-extension-placeholder-CupUGaI_.js +0 -1
  93. package/dist/vendor-tiptap-extension-table-D8RFr_6X.js +0 -368
  94. package/dist/vendor-tiptap-extension-table-cell-k9uLwyL6.js +0 -1
  95. package/dist/vendor-tiptap-extension-table-header-k9uLwyL6.js +0 -1
  96. package/dist/vendor-tiptap-extension-table-row-k9uLwyL6.js +0 -1
@@ -1,6 +1,8 @@
1
1
  import { PushNotification, PushNotificationClient } from "./../../api/platform";
2
- import { computed, ComputedRef, ref, onUnmounted } from "vue";
2
+ import { computed, ComputedRef, ref, onUnmounted, inject } from "vue";
3
3
  import * as _ from "lodash-es";
4
+ import { AuthProviderKey } from "../../../injection-keys";
5
+ import { shouldEnablePlatformFeatures } from "../../providers/auth-provider-utils";
4
6
 
5
7
  const notificationsClient = new PushNotificationClient();
6
8
 
@@ -29,6 +31,10 @@ const subscribers = new Map<
29
31
  let subscriberCounter = 0;
30
32
 
31
33
  export function useNotifications(notifyType?: string | string[]): INotifications {
34
+ // Check if we're using a custom auth provider
35
+ const authProvider = inject(AuthProviderKey);
36
+ const isPlatformProvider = shouldEnablePlatformFeatures(authProvider);
37
+
32
38
  if (notifyType) {
33
39
  const types = Array.isArray(notifyType) ? notifyType : [notifyType];
34
40
 
@@ -49,6 +55,12 @@ export function useNotifications(notifyType?: string | string[]): INotifications
49
55
  }
50
56
 
51
57
  async function loadFromHistory(take = 10) {
58
+ // Skip platform API calls for custom authentication providers
59
+ if (!isPlatformProvider) {
60
+ console.log("[useNotifications] Skipping loadFromHistory - custom authentication provider detected");
61
+ return;
62
+ }
63
+
52
64
  // TODO temporary workaround to get push notifications without base type
53
65
  try {
54
66
  const result = await fetch("/api/platform/pushnotifications", {
@@ -106,6 +118,25 @@ export function useNotifications(notifyType?: string | string[]): INotifications
106
118
  }
107
119
 
108
120
  async function markAllAsRead() {
121
+ // Skip platform API calls for custom authentication providers
122
+ if (!isPlatformProvider) {
123
+ console.log("[useNotifications] Skipping markAllAsRead - custom authentication provider detected");
124
+ // Still update local state
125
+ notifications.value = notifications.value.map((x) => {
126
+ if (x.isNew) {
127
+ x.isNew = false;
128
+ }
129
+ return x;
130
+ });
131
+ pushNotifications.value = pushNotifications.value.map((x) => {
132
+ if (x.isNew) {
133
+ x.isNew = false;
134
+ }
135
+ return x;
136
+ });
137
+ return;
138
+ }
139
+
109
140
  try {
110
141
  notifications.value = notifications.value.map((x) => {
111
142
  if (x.isNew) {
@@ -1,8 +1,10 @@
1
1
  import { useAsync } from "./../useAsync";
2
2
  import { useApiClient } from "./../useApiClient";
3
- import { computed, Ref, ref, ComputedRef, onMounted } from "vue";
3
+ import { computed, Ref, ref, ComputedRef, onMounted, inject } from "vue";
4
4
  import { SettingClient } from "./../../api/platform";
5
5
  import { useLoading } from "../useLoading";
6
+ import { shouldEnablePlatformFeatures } from "../../providers/auth-provider-utils";
7
+ import { AuthProviderKey } from "../../../injection-keys";
6
8
 
7
9
  interface IUISetting {
8
10
  contrast_logo?: string;
@@ -19,13 +21,16 @@ interface IUseSettings {
19
21
  }
20
22
 
21
23
  export function useSettings(): IUseSettings {
24
+ // Check if we're using a custom auth provider
25
+ const authProvider = inject(AuthProviderKey);
26
+ const isPlatformProvider = shouldEnablePlatformFeatures(authProvider);
22
27
  const uiSettings = ref<IUISetting | undefined>();
23
28
  const customSettingsApplied = ref(false);
24
29
 
25
30
  const { getApiClient } = useApiClient(SettingClient);
26
31
 
27
32
  const { loading, action: getUiCustomizationSettings } = useAsync(async () => {
28
- if (customSettingsApplied.value) return;
33
+ if (customSettingsApplied.value || !isPlatformProvider) return;
29
34
 
30
35
  const result = await (await getApiClient()).getUICustomizationSetting();
31
36
  const settings = await JSON.parse(result.defaultValue ?? null);
@@ -51,7 +56,7 @@ export function useSettings(): IUseSettings {
51
56
  }
52
57
 
53
58
  onMounted(async () => {
54
- if (!uiSettings.value && !customSettingsApplied.value) {
59
+ if (!uiSettings.value && !customSettingsApplied.value && isPlatformProvider) {
55
60
  await getUiCustomizationSettings();
56
61
  }
57
62
  });
@@ -1,211 +1,114 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { computed, Ref, ref, ComputedRef } from "vue";
2
+ import { computed, inject, ComputedRef, getCurrentInstance } from "vue";
3
3
  import {
4
4
  UserDetail,
5
- SecurityClient,
6
- ResetPasswordConfirmRequest,
7
5
  SecurityResult,
8
- ValidatePasswordResetTokenRequest,
9
6
  IdentityResult,
10
- ChangePasswordRequest,
11
7
  LoginType,
12
- LoginRequest,
13
8
  SignInResult,
9
+ IUserDetail,
10
+ ISecurityResult,
11
+ ILoginType,
12
+ IIdentityResult,
14
13
  } from "./../../api/platform";
15
- import { RequestPasswordResult } from "./../../types";
14
+ import { RequestPasswordResult, IAuthProvider } from "./../../types";
16
15
  import { createSharedComposable } from "@vueuse/core";
17
- import { useExternalProvider } from "../../../shared/components/sign-in/useExternalProvider";
16
+ import { AuthProviderKey } from "../../../injection-keys";
17
+ import { authProviderManager } from "../../providers/auth-provider-manager";
18
18
 
19
- // Interface for the full internal API provided by _createInternalUserLogic
19
+ /**
20
+ * Interface for the full internal API
21
+ * @deprecated This interface is kept for backward compatibility but will be removed in future versions
22
+ */
20
23
  export interface IUserInternalAPI {
21
- user: ComputedRef<UserDetail | undefined>;
24
+ user: ComputedRef<IUserDetail | undefined>;
22
25
  loading: ComputedRef<boolean>;
23
26
  isAdministrator: ComputedRef<boolean | undefined>;
24
- loadUser: () => Promise<UserDetail>;
27
+ loadUser: () => Promise<IUserDetail>;
25
28
  signIn: (username: string, password: string) => Promise<SignInResult | { succeeded: boolean; error?: any }>;
26
29
  signOut: () => Promise<void>;
27
30
  validateToken: (userId: string, token: string) => Promise<boolean>;
28
- validatePassword: (password: string) => Promise<IdentityResult>;
29
- resetPasswordByToken: (userId: string, password: string, token: string) => Promise<SecurityResult>;
31
+ validatePassword: (password: string) => Promise<IIdentityResult>;
32
+ resetPasswordByToken: (userId: string, password: string, token: string) => Promise<ISecurityResult>;
30
33
  requestPasswordReset: (loginOrEmail: string) => Promise<RequestPasswordResult>;
31
- changeUserPassword: (oldPassword: string, newPassword: string) => Promise<SecurityResult | undefined>;
32
- getLoginType: () => Promise<LoginType[]>;
34
+ changeUserPassword: (oldPassword: string, newPassword: string) => Promise<ISecurityResult | undefined>;
35
+ getLoginType: () => Promise<ILoginType[]>;
33
36
  isAuthenticated: ComputedRef<boolean>;
34
37
  }
35
38
 
36
39
  export interface IAppUserAPI {
37
- user: ComputedRef<UserDetail | undefined>;
40
+ user: ComputedRef<IUserDetail | undefined>;
38
41
  loading: ComputedRef<boolean>;
39
42
  isAuthenticated: ComputedRef<boolean>;
40
43
  isAdministrator: ComputedRef<boolean | undefined>;
41
- loadUser: () => Promise<UserDetail>;
44
+ loadUser: () => Promise<IUserDetail>;
42
45
  signOut: () => Promise<void>;
43
46
  }
44
47
 
45
- const user: Ref<UserDetail | undefined> = ref();
46
-
47
- export function _createInternalUserLogic(): IUserInternalAPI {
48
- const loading: Ref<boolean> = ref(false);
49
-
50
- const { storage: externalSignInStorage, signOut: externalSignOut } = useExternalProvider();
51
-
52
- const securityClient = new SecurityClient();
53
-
54
- const isAuthenticated = computed(() => user.value?.userName != null);
55
-
56
- async function validateToken(userId: string, token: string): Promise<boolean> {
57
- let result = false;
58
- try {
59
- loading.value = true;
60
- result = await securityClient.validatePasswordResetToken(userId, {
61
- token,
62
- } as ValidatePasswordResetTokenRequest);
63
- } catch (e) {
64
- //TODO: log error
65
- } finally {
66
- loading.value = false;
48
+ /**
49
+ * Get auth provider with fallback to global instance
50
+ * This allows composables to work before Vue app context is available
51
+ * Priority: Vue DI > Global Manager (always has default PlatformAuthProvider)
52
+ */
53
+ function getAuthProvider(): IAuthProvider {
54
+ // Try to get from Vue DI first (preferred method for components)
55
+ const instance = getCurrentInstance();
56
+ if (instance) {
57
+ const injectedProvider = inject(AuthProviderKey, null);
58
+ if (injectedProvider) {
59
+ return injectedProvider;
67
60
  }
68
- return result;
69
- }
70
-
71
- async function validatePassword(password: string): Promise<IdentityResult> {
72
- return securityClient.validatePassword(password);
73
- }
74
-
75
- async function resetPasswordByToken(userId: string, password: string, token: string): Promise<SecurityResult> {
76
- return securityClient.resetPasswordByToken(userId, {
77
- newPassword: password,
78
- token,
79
- } as ResetPasswordConfirmRequest);
80
61
  }
81
62
 
82
- async function signIn(
83
- username: string,
84
- password: string,
85
- ): Promise<SignInResult | { succeeded: boolean; error?: any; status?: number }> {
86
- console.debug(`[@vc-shell/framework#_createInternalUserLogic:signIn] - Entry point`);
87
- try {
88
- loading.value = true;
89
- const result = await securityClient.login(new LoginRequest({ userName: username, password }));
90
- return await securityClient
91
- .getCurrentUser()
92
- .then((res) => {
93
- if (res) {
94
- user.value = res;
95
- return result;
96
- }
97
- throw { succeeded: false };
98
- })
99
- .catch((e) => {
100
- throw e;
101
- });
102
- } catch (e: any) {
103
- //TODO: log error
104
- console.log(e);
105
- return { succeeded: false, error: e.message, status: e.status };
106
- } finally {
107
- loading.value = false;
108
- }
109
- }
110
-
111
- async function signOut(): Promise<void> {
112
- console.debug(`[@vc-shell/framework#_createInternalUserLogic:signOut] - Entry point`);
113
-
114
- user.value = undefined;
115
-
116
- if (externalSignInStorage.value?.providerType) {
117
- await externalSignOut(externalSignInStorage.value.providerType);
118
- } else {
119
- securityClient.logout();
120
- }
121
- }
122
-
123
- async function loadUser(): Promise<UserDetail> {
124
- console.debug(`[@vc-shell/framework#_createInternalUserLogic:loadUser] - Entry point`);
125
-
126
- try {
127
- loading.value = true;
128
- user.value = await securityClient.getCurrentUser();
129
- console.log("[_createInternalUserLogic]: an user details has been loaded", user.value);
130
- } catch (e: any) {
131
- console.error(e);
132
- } finally {
133
- loading.value = false;
134
- }
135
-
136
- return { ...user.value } as UserDetail;
137
- }
138
-
139
- async function requestPasswordReset(loginOrEmail: string): Promise<RequestPasswordResult> {
140
- try {
141
- loading.value = true;
142
- await securityClient.requestPasswordReset(loginOrEmail);
143
- return { succeeded: true };
144
- } catch (e) {
145
- //TODO: log error
146
- return { succeeded: false, error: e as string };
147
- } finally {
148
- loading.value = false;
149
- }
150
- }
151
-
152
- async function changeUserPassword(oldPassword: string, newPassword: string): Promise<SecurityResult | undefined> {
153
- let result;
154
-
155
- try {
156
- loading.value = true;
157
- const command = new ChangePasswordRequest({
158
- oldPassword,
159
- newPassword,
160
- });
161
-
162
- result = await securityClient.changeCurrentUserPassword(command);
163
- } catch (e: any) {
164
- return { succeeded: false, errors: [e.message] } as SecurityResult;
165
- } finally {
166
- loading.value = false;
167
- }
168
-
169
- return result;
170
- }
171
-
172
- async function getLoginType() {
173
- let result: LoginType[] | null = null;
174
- try {
175
- result = await securityClient.getLoginTypes();
176
- } catch (e) {
177
- console.error(e);
178
- throw e;
179
- }
63
+ // Fallback to global provider (always available with default PlatformAuthProvider)
64
+ return authProviderManager.getProvider();
65
+ }
180
66
 
181
- return result;
182
- }
67
+ /**
68
+ * Internal user logic - delegates to auth provider
69
+ * @deprecated This function is kept for backward compatibility but will be removed in future versions
70
+ * Use auth provider directly or useUser/useUserManagement composables
71
+ */
72
+ export function _createInternalUserLogic(): IUserInternalAPI {
73
+ const authProvider = getAuthProvider();
183
74
 
184
75
  return {
185
- user: computed(() => user.value),
186
- loading: computed(() => loading.value),
187
- isAdministrator: computed(() => user.value?.isAdministrator),
188
- isAuthenticated,
189
- loadUser,
190
- signIn,
191
- signOut,
192
- validateToken,
193
- validatePassword,
194
- resetPasswordByToken,
195
- requestPasswordReset,
196
- changeUserPassword,
197
- getLoginType,
76
+ user: authProvider.user,
77
+ loading: authProvider.loading,
78
+ isAdministrator: authProvider.isAdministrator,
79
+ isAuthenticated: authProvider.isAuthenticated,
80
+ loadUser: authProvider.loadUser.bind(authProvider),
81
+ signIn: authProvider.signIn.bind(authProvider),
82
+ signOut: authProvider.signOut.bind(authProvider),
83
+ validateToken: authProvider.validateToken.bind(authProvider),
84
+ validatePassword: authProvider.validatePassword.bind(authProvider),
85
+ resetPasswordByToken: authProvider.resetPasswordByToken.bind(authProvider),
86
+ requestPasswordReset: authProvider.requestPasswordReset.bind(authProvider),
87
+ changeUserPassword: authProvider.changeUserPassword.bind(authProvider),
88
+ getLoginType: authProvider.getLoginType.bind(authProvider),
198
89
  };
199
90
  }
200
91
 
201
92
  export const useUser = createSharedComposable((): IAppUserAPI => {
202
- const internals = _createInternalUserLogic();
93
+ // Get provider dynamically on each access to ensure correct provider is used
94
+ // This is important because custom auth providers may be set after composable creation
95
+
203
96
  return {
204
- user: internals.user,
205
- loading: internals.loading,
206
- isAuthenticated: internals.isAuthenticated,
207
- isAdministrator: internals.isAdministrator,
208
- loadUser: internals.loadUser,
209
- signOut: internals.signOut,
97
+ // Computed properties should get provider dynamically
98
+ get user() {
99
+ return getAuthProvider().user;
100
+ },
101
+ get loading() {
102
+ return getAuthProvider().loading;
103
+ },
104
+ get isAuthenticated() {
105
+ return getAuthProvider().isAuthenticated;
106
+ },
107
+ get isAdministrator() {
108
+ return getAuthProvider().isAdministrator;
109
+ },
110
+ // Methods get provider dynamically on each call
111
+ loadUser: () => getAuthProvider().loadUser(),
112
+ signOut: () => getAuthProvider().signOut(),
210
113
  };
211
114
  });
@@ -1,45 +1,87 @@
1
- import { computed, ComputedRef } from "vue";
1
+ import { inject, ComputedRef, getCurrentInstance } from "vue";
2
2
  import { createSharedComposable } from "@vueuse/core";
3
- import { _createInternalUserLogic, IUserInternalAPI } from "../useUser"; // Import the internal logic
4
- import { SecurityResult, IdentityResult, LoginType, UserDetail, SignInResult } from "./../../api/platform";
5
- import { RequestPasswordResult } from "./../../types";
3
+ import {
4
+ SecurityResult,
5
+ IdentityResult,
6
+ LoginType,
7
+ UserDetail,
8
+ SignInResult,
9
+ IUserDetail,
10
+ IIdentityResult,
11
+ ISecurityResult,
12
+ ILoginType,
13
+ } from "./../../api/platform";
14
+ import { RequestPasswordResult, IAuthProvider } from "./../../types";
15
+ import { AuthProviderKey } from "../../../injection-keys";
16
+ import { authProviderManager } from "../../providers/auth-provider-manager";
6
17
 
7
18
  // Interface for the API exposed by useUserManagement (for framework/admin use)
8
19
  export interface IUserManagementAPI {
9
- user: ComputedRef<UserDetail | undefined>;
20
+ user: ComputedRef<IUserDetail | undefined>;
10
21
  loading: ComputedRef<boolean>;
11
22
  isAdministrator: ComputedRef<boolean | undefined>;
12
23
  isAuthenticated: ComputedRef<boolean>;
13
24
  // Methods specific to user management
14
25
  validateToken: (userId: string, token: string) => Promise<boolean>;
15
- validatePassword: (password: string) => Promise<IdentityResult>;
16
- resetPasswordByToken: (userId: string, password: string, token: string) => Promise<SecurityResult>;
17
- getLoginType: () => Promise<LoginType[]>;
18
- loadUser: () => Promise<UserDetail>;
26
+ validatePassword: (password: string) => Promise<IIdentityResult>;
27
+ resetPasswordByToken: (userId: string, password: string, token: string) => Promise<ISecurityResult>;
28
+ getLoginType: () => Promise<ILoginType[]>;
29
+ loadUser: () => Promise<IUserDetail>;
19
30
  requestPasswordReset: (loginOrEmail: string) => Promise<RequestPasswordResult>;
20
- changeUserPassword: (oldPassword: string, newPassword: string) => Promise<SecurityResult | undefined>;
31
+ changeUserPassword: (oldPassword: string, newPassword: string) => Promise<ISecurityResult | undefined>;
21
32
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
33
  signIn: (username: string, password: string) => Promise<SignInResult | { succeeded: boolean; error?: any }>;
23
34
  signOut: () => Promise<void>;
24
35
  }
25
36
 
37
+ /**
38
+ * Get auth provider with fallback to global instance
39
+ * This allows composables to work before Vue app context is available
40
+ * Priority: Vue DI > Global Manager (always has default PlatformAuthProvider)
41
+ */
42
+ function getAuthProvider(): IAuthProvider {
43
+ // Try to get from Vue DI first (preferred method for components)
44
+ const instance = getCurrentInstance();
45
+ if (instance) {
46
+ const injectedProvider = inject(AuthProviderKey, null);
47
+ if (injectedProvider) {
48
+ return injectedProvider;
49
+ }
50
+ }
51
+
52
+ // Fallback to global provider (always available with default PlatformAuthProvider)
53
+ return authProviderManager.getProvider();
54
+ }
55
+
26
56
  export const useUserManagement = createSharedComposable((): IUserManagementAPI => {
27
- // Utilize the same internal logic instance
28
- const internals: IUserInternalAPI = _createInternalUserLogic();
57
+ // Get provider dynamically on each access to ensure correct provider is used
58
+ // This is important because custom auth providers may be set after composable creation
29
59
 
30
60
  return {
31
- user: internals.user,
32
- loading: internals.loading,
33
- isAdministrator: internals.isAdministrator,
34
- isAuthenticated: internals.isAuthenticated,
35
- validateToken: internals.validateToken,
36
- validatePassword: internals.validatePassword,
37
- resetPasswordByToken: internals.resetPasswordByToken,
38
- getLoginType: internals.getLoginType,
39
- loadUser: internals.loadUser,
40
- requestPasswordReset: internals.requestPasswordReset,
41
- changeUserPassword: internals.changeUserPassword,
42
- signIn: internals.signIn,
43
- signOut: internals.signOut,
61
+ // Computed properties should get provider dynamically
62
+ get user() {
63
+ return getAuthProvider().user;
64
+ },
65
+ get loading() {
66
+ return getAuthProvider().loading;
67
+ },
68
+ get isAdministrator() {
69
+ return getAuthProvider().isAdministrator;
70
+ },
71
+ get isAuthenticated() {
72
+ return getAuthProvider().isAuthenticated;
73
+ },
74
+ // Methods get provider dynamically on each call
75
+ validateToken: (userId: string, token: string) => getAuthProvider().validateToken(userId, token),
76
+ validatePassword: (password: string) => getAuthProvider().validatePassword(password),
77
+ resetPasswordByToken: (userId: string, password: string, token: string) =>
78
+ getAuthProvider().resetPasswordByToken(userId, password, token),
79
+ getLoginType: () => getAuthProvider().getLoginType(),
80
+ loadUser: () => getAuthProvider().loadUser(),
81
+ requestPasswordReset: (loginOrEmail: string) => getAuthProvider().requestPasswordReset(loginOrEmail),
82
+ changeUserPassword: (oldPassword: string, newPassword: string) =>
83
+ getAuthProvider().changeUserPassword(oldPassword, newPassword),
84
+ signIn: (username: string, password: string) => getAuthProvider().signIn(username, password),
85
+ signOut: () => getAuthProvider().signOut(),
44
86
  };
45
87
  });
@@ -1,70 +1,33 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
  import { Router } from "vue-router";
3
- import { useUserManagement } from "../composables/useUserManagement";
4
2
  import { notification } from "../../shared";
3
+ import { IAuthProvider } from "../types/auth-provider";
5
4
 
6
- export function registerInterceptors(router: Router) {
5
+ export function registerInterceptors(router: Router, authProvider: IAuthProvider) {
7
6
  const { fetch: originalFetch } = window;
8
- const { signOut, isAuthenticated } = useUserManagement();
9
7
 
10
8
  window.fetch = async (...args) => {
11
9
  /**
12
- * Overrides the global `fetch` function to handle API calls in demo mode.
13
- * If `window.__DEMO_MODE__` is true, the fetch is cancelled and a warning is logged.
14
- * Otherwise, the original `fetch` function is called.
15
- * @param args - The arguments passed to the `fetch` function.
16
- * @returns A promise that resolves to the response from the API call.
10
+ * Intercepts fetch requests to handle authentication errors.
11
+ * Note: Demo mode should be handled by the auth provider itself, not by global interceptors.
17
12
  */
18
- if (window.__DEMO_MODE__) {
19
- console.warn("CANCELLED FETCH WHILE IN __DEMO_MODE__: ", ...args);
20
- console.warn("Please logout and add APP_PLATFORM_URL into .env file of your application to enable API calls");
21
- return new Promise((resolve: any) => {
22
- /**
23
- * This conditions are mocking login, currentuser API calls for demo purposes.
24
- */
25
- if (args[0] === "/api/platform/security/login") {
26
- resolve({
27
- status: 200,
28
- text: async () => JSON.stringify({ succeeded: true }),
29
- });
30
- } else if (args[0] === "/api/platform/security/currentuser") {
31
- notification.warning(
32
- "You are currently in DEMO mode until the first page refresh. \n All API calls are disabled. Please add APP_PLATFORM_URL to your application's .env file to enable API calls.",
33
- {
34
- timeout: 10000,
35
- },
36
- );
37
- resolve({
38
- status: 200,
39
- text: async () => JSON.stringify({ id: "demo_user_id", userName: "DEMO_USER" }),
40
- });
41
- } else {
42
- resolve({
43
- status: 200,
44
- text: async () => JSON.stringify({}),
45
- });
46
- }
47
- });
48
- } else {
49
- const response = await originalFetch(...args);
13
+ const response = await originalFetch(...args);
50
14
 
51
- /**
52
- * If the response is unauthorized, logout the user
53
- */
54
- if (response.status === 401) {
55
- //logout user
56
- if (isAuthenticated.value) {
57
- signOut().then(() => {
58
- redirect(router);
59
- notification.error(
60
- "Access Denied: Your session has expired or you do not have the necessary permissions.\nPlease log in again or contact the administrator for assistance.",
61
- );
62
- });
63
- }
15
+ /**
16
+ * If the response is unauthorized, logout the user
17
+ */
18
+ if (response.status === 401) {
19
+ //logout user
20
+ if (authProvider.isAuthenticated.value) {
21
+ authProvider.signOut().then(() => {
22
+ redirect(router);
23
+ notification.error(
24
+ "Access Denied: Your session has expired or you do not have the necessary permissions.\nPlease log in again or contact the administrator for assistance.",
25
+ );
26
+ });
64
27
  }
65
-
66
- return response;
67
28
  }
29
+
30
+ return response;
68
31
  };
69
32
 
70
33
  return window.fetch;
@@ -1,9 +1,12 @@
1
- import { App, watch, ref, InjectionKey } from "vue";
1
+ import { App, watch, ref, InjectionKey, inject } from "vue";
2
2
  import { HubConnection, HubConnectionBuilder, LogLevel } from "@microsoft/signalr";
3
3
  import { PushNotification } from "../../api/platform";
4
4
  import { useNotifications } from "./../../composables/useNotifications";
5
5
  import { useUserManagement } from "../../composables/useUserManagement";
6
6
  import { useCypressSignalRMock } from "cypress-signalr-mock";
7
+ import { AuthProviderKey } from "../../../injection-keys";
8
+ import { IAuthProvider } from "../../types/auth-provider";
9
+ import { shouldEnablePlatformFeatures } from "../../providers/auth-provider-utils";
7
10
 
8
11
  const { addNotification } = useNotifications();
9
12
  const currentCreator = ref<string | undefined>();
@@ -31,8 +34,31 @@ export const signalR = {
31
34
  app: App,
32
35
  options?: {
33
36
  creator?: string;
37
+ authProvider?: IAuthProvider;
34
38
  },
35
39
  ) {
40
+ // Check if we should enable SignalR (only for platform providers)
41
+ const authProvider = options?.authProvider;
42
+
43
+ console.log("[SignalR] Auth provider: ", authProvider);
44
+
45
+ // Check if platform features should be enabled
46
+ if (!shouldEnablePlatformFeatures(authProvider)) {
47
+ console.log("[SignalR] Skipping initialization - custom authentication provider detected");
48
+ console.log("[SignalR] SignalR is only available with platform authentication");
49
+
50
+ // Provide empty implementations to prevent errors
51
+ app.config.globalProperties.$updateSignalRCreator = () => {
52
+ console.warn("[SignalR] Not available with custom authentication provider");
53
+ };
54
+ app.provide(updateSignalRCreatorSymbol, () => {
55
+ console.warn("[SignalR] Not available with custom authentication provider");
56
+ });
57
+
58
+ return;
59
+ }
60
+
61
+ console.log("[SignalR] Initializing with platform authentication");
36
62
  currentCreator.value = options?.creator;
37
63
  const { isAuthenticated } = useUserManagement();
38
64
  let reconnect = false;