@vc-shell/framework 1.1.98-rc.5 → 1.1.99-alpha.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.
- package/core/api/platform.ts +9883 -9883
- package/core/composables/useNotifications/index.ts +32 -1
- package/core/composables/useSettings/index.ts +8 -3
- package/core/composables/useUser/index.ts +74 -171
- package/core/composables/useUserManagement/index.ts +67 -25
- package/core/interceptors/index.ts +19 -56
- package/core/plugins/signalR/index.ts +27 -1
- package/core/providers/README.md +176 -0
- package/core/providers/auth-provider-manager.ts +74 -0
- package/core/providers/auth-provider-utils.ts +26 -0
- package/core/providers/example-custom-auth-provider.ts +162 -0
- package/core/providers/index.ts +3 -0
- package/core/providers/platform-auth-provider.ts +207 -0
- package/core/types/auth-provider.ts +40 -0
- package/core/types/index.ts +2 -0
- package/dist/core/api/platform.d.ts +1 -1
- package/dist/core/api/platform.d.ts.map +1 -1
- package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
- package/dist/core/composables/useSettings/index.d.ts.map +1 -1
- package/dist/core/composables/useUser/index.d.ts +18 -9
- package/dist/core/composables/useUser/index.d.ts.map +1 -1
- package/dist/core/composables/useUserManagement/index.d.ts +7 -7
- package/dist/core/composables/useUserManagement/index.d.ts.map +1 -1
- package/dist/core/interceptors/index.d.ts +2 -1
- package/dist/core/interceptors/index.d.ts.map +1 -1
- package/dist/core/plugins/signalR/index.d.ts +2 -0
- package/dist/core/plugins/signalR/index.d.ts.map +1 -1
- package/dist/core/providers/auth-provider-manager.d.ts +34 -0
- package/dist/core/providers/auth-provider-manager.d.ts.map +1 -0
- package/dist/core/providers/auth-provider-utils.d.ts +17 -0
- package/dist/core/providers/auth-provider-utils.d.ts.map +1 -0
- package/dist/core/providers/example-custom-auth-provider.d.ts +45 -0
- package/dist/core/providers/example-custom-auth-provider.d.ts.map +1 -0
- package/dist/core/providers/index.d.ts +3 -0
- package/dist/core/providers/index.d.ts.map +1 -0
- package/dist/core/providers/platform-auth-provider.d.ts +34 -0
- package/dist/core/providers/platform-auth-provider.d.ts.map +1 -0
- package/dist/core/types/auth-provider.d.ts +27 -0
- package/dist/core/types/auth-provider.d.ts.map +1 -0
- package/dist/core/types/index.d.ts +1 -1
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/framework.js +6348 -6198
- package/dist/index.css +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/injection-keys.d.ts +2 -1
- package/dist/injection-keys.d.ts.map +1 -1
- package/dist/shared/components/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
- package/dist/shared/components/sign-in/useExternalProvider.d.ts +1 -1
- package/dist/shared/components/sign-in/useExternalProvider.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/helpers/nodeBuilder.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
- package/dist/vendor-tiptap-core-ClsTgaMv.js +3699 -0
- package/dist/{vendor-tiptap-extension-blockquote-BVmAuV7o.js → vendor-tiptap-extension-blockquote-r1MBx4hD.js} +1 -1
- package/dist/{vendor-tiptap-extension-bold-BOh8AIRZ.js → vendor-tiptap-extension-bold-BjLI4i8b.js} +1 -1
- package/dist/{vendor-tiptap-extension-code-R4pc2wFE.js → vendor-tiptap-extension-code-D5-kDnMW.js} +1 -1
- package/dist/{vendor-tiptap-extension-code-block-DibKlZFG.js → vendor-tiptap-extension-code-block-RjEb0zPA.js} +1 -1
- package/dist/{vendor-tiptap-extension-document-BwORJR1k.js → vendor-tiptap-extension-document--PLOxIdq.js} +1 -1
- package/dist/{vendor-tiptap-extension-hard-break-DH36OfVk.js → vendor-tiptap-extension-hard-break-9cxC2YOS.js} +13 -9
- package/dist/{vendor-tiptap-extension-heading-oMLORiPI.js → vendor-tiptap-extension-heading-2w0TutHn.js} +1 -1
- package/dist/{vendor-tiptap-extension-horizontal-rule-BMHSoB_Y.js → vendor-tiptap-extension-horizontal-rule-CFowa_lc.js} +1 -1
- package/dist/vendor-tiptap-extension-image-aWn-na6j.js +127 -0
- package/dist/{vendor-tiptap-extension-italic-BzqrUuB0.js → vendor-tiptap-extension-italic-Bn-6saY0.js} +1 -1
- package/dist/{vendor-tiptap-extension-link-hMFZ0hfl.js → vendor-tiptap-extension-link-BmcG1_k-.js} +1 -1
- package/dist/{vendor-tiptap-extension-list-Bj5AK6Pq.js → vendor-tiptap-extension-list-BrNBJ45n.js} +1 -1
- package/dist/{vendor-tiptap-extension-paragraph-Bs1wl42E.js → vendor-tiptap-extension-paragraph-DAiYhwUB.js} +1 -1
- package/dist/vendor-tiptap-extension-placeholder-9tURDKy-.js +1 -0
- package/dist/{vendor-tiptap-extension-strike-C4YpGyzc.js → vendor-tiptap-extension-strike-DqbXPfos.js} +1 -1
- package/dist/vendor-tiptap-extension-table-DQwPaR7v.js +374 -0
- package/dist/vendor-tiptap-extension-table-cell-C0tEP_0i.js +1 -0
- package/dist/vendor-tiptap-extension-table-header-C0tEP_0i.js +1 -0
- package/dist/vendor-tiptap-extension-table-row-C0tEP_0i.js +1 -0
- package/dist/{vendor-tiptap-extension-text-C4dQW13r.js → vendor-tiptap-extension-text-BFnfj70b.js} +1 -1
- package/dist/{vendor-tiptap-extension-text-style-a_NYjXT6.js → vendor-tiptap-extension-text-style-Darua3qr.js} +1 -1
- package/dist/{vendor-tiptap-extension-underline-DthCaPX3.js → vendor-tiptap-extension-underline-QyVnBqQZ.js} +1 -1
- package/dist/{vendor-tiptap-extensions-C8rF1qdq.js → vendor-tiptap-extensions-CU-D7bfm.js} +1 -1
- package/dist/{vendor-tiptap-markdown-DRc3qhBU.js → vendor-tiptap-markdown-BwATYN5A.js} +1 -1
- package/dist/{vendor-tiptap-starter-kit-BfUUblkP.js → vendor-tiptap-starter-kit-5luf7zzS.js} +17 -17
- package/dist/{vendor-tiptap-vue-3-DYxT2sf6.js → vendor-tiptap-vue-3-CFBErZGb.js} +1 -1
- package/dist/{vendor-vueuse-components-B0zqjNRW.js → vendor-vueuse-components-sgKpNzof.js} +1 -1
- package/dist/{vendor-vueuse-core-CYgwn-B2.js → vendor-vueuse-core-D0cN7FqY.js} +10 -10
- package/dist/{vendor-vueuse-shared-B_uDJJ6V.js → vendor-vueuse-shared-Pt0UEStA.js} +19 -19
- package/package.json +7 -5
- package/shared/components/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +2 -2
- package/shared/components/app-switcher/composables/useAppSwitcher/index.ts +15 -1
- package/shared/components/sign-in/useExternalProvider.ts +11 -1
- package/shared/modules/dynamic/helpers/nodeBuilder.ts +11 -3
- package/ui/components/organisms/vc-app/vc-app.vue +20 -2
- package/dist/vendor-tiptap-core-8RGSOCZs.js +0 -3442
- package/dist/vendor-tiptap-extension-image-DF1ZJ94q.js +0 -80
- package/dist/vendor-tiptap-extension-placeholder-CupUGaI_.js +0 -1
- package/dist/vendor-tiptap-extension-table-D8RFr_6X.js +0 -368
- package/dist/vendor-tiptap-extension-table-cell-k9uLwyL6.js +0 -1
- package/dist/vendor-tiptap-extension-table-header-k9uLwyL6.js +0 -1
- 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,
|
|
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 {
|
|
16
|
+
import { AuthProviderKey } from "../../../injection-keys";
|
|
17
|
+
import { authProviderManager } from "../../providers/auth-provider-manager";
|
|
18
18
|
|
|
19
|
-
|
|
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<
|
|
24
|
+
user: ComputedRef<IUserDetail | undefined>;
|
|
22
25
|
loading: ComputedRef<boolean>;
|
|
23
26
|
isAdministrator: ComputedRef<boolean | undefined>;
|
|
24
|
-
loadUser: () => Promise<
|
|
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<
|
|
29
|
-
resetPasswordByToken: (userId: string, password: string, token: string) => Promise<
|
|
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<
|
|
32
|
-
getLoginType: () => Promise<
|
|
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<
|
|
40
|
+
user: ComputedRef<IUserDetail | undefined>;
|
|
38
41
|
loading: ComputedRef<boolean>;
|
|
39
42
|
isAuthenticated: ComputedRef<boolean>;
|
|
40
43
|
isAdministrator: ComputedRef<boolean | undefined>;
|
|
41
|
-
loadUser: () => Promise<
|
|
44
|
+
loadUser: () => Promise<IUserDetail>;
|
|
42
45
|
signOut: () => Promise<void>;
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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:
|
|
186
|
-
loading:
|
|
187
|
-
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
|
-
|
|
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
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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 {
|
|
1
|
+
import { inject, ComputedRef, getCurrentInstance } from "vue";
|
|
2
2
|
import { createSharedComposable } from "@vueuse/core";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
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<
|
|
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<
|
|
16
|
-
resetPasswordByToken: (userId: string, password: string, token: string) => Promise<
|
|
17
|
-
getLoginType: () => Promise<
|
|
18
|
-
loadUser: () => Promise<
|
|
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<
|
|
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
|
-
//
|
|
28
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
*
|
|
13
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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;
|