@hostlink/nuxt-light 1.18.3 → 1.19.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/dist/module.json +1 -1
- package/dist/runtime/components/L/ForgetPasswordDialog.vue +1 -1
- package/dist/runtime/components/L/System/Setting/authentication.vue +57 -0
- package/dist/runtime/components/l-app-main.vue +8 -7
- package/dist/runtime/components/l-app.vue +33 -7
- package/dist/runtime/components/l-facebook-button.vue +28 -0
- package/dist/runtime/components/l-login.vue +82 -19
- package/dist/runtime/components/l-microsoft-button.vue +120 -0
- package/dist/runtime/components/l-page.vue +0 -1
- package/dist/runtime/pages/System/setting.vue +23 -1
- package/dist/runtime/pages/User/setting/open_id.vue +144 -19
- package/package.json +4 -2
package/dist/module.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref } from 'vue'
|
|
3
3
|
import { useQuasar, useDialogPluginComponent } from 'quasar'
|
|
4
|
-
import {
|
|
4
|
+
import { api } from '#imports';
|
|
5
5
|
import { useI18n } from 'vue-i18n';
|
|
6
6
|
const { t } = useI18n();
|
|
7
7
|
const $q = useQuasar()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useLight, m } from "#imports"
|
|
3
|
+
const light = useLight()
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export interface LSystemSettingAuthenticationProps {
|
|
7
|
+
authentication_password_based: string,
|
|
8
|
+
authentication_google_client_id: string,
|
|
9
|
+
authentication_facebook_app_id: string,
|
|
10
|
+
authentication_microsoft_client_id: string,
|
|
11
|
+
authentication_microsoft_tenant_id: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
withDefaults(defineProps<LSystemSettingAuthenticationProps>(), {
|
|
16
|
+
authentication_password_based: "1",
|
|
17
|
+
authentication_google_client_id: "",
|
|
18
|
+
authentication_facebook_app_id: "",
|
|
19
|
+
authentication_microsoft_client_id: "",
|
|
20
|
+
authentication_microsoft_tenant_id: "",
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const emits = defineEmits(["submit"])
|
|
24
|
+
|
|
25
|
+
const onSubmit = async (d: LSystemSettingAuthenticationProps) => {
|
|
26
|
+
|
|
27
|
+
//at least one authentication method should be enabled
|
|
28
|
+
if (d.authentication_password_based === "0" && !d.authentication_google_client_id && !d.authentication_facebook_app_id && !d.authentication_microsoft_client_id) {
|
|
29
|
+
|
|
30
|
+
light.notify({ message: "At least one authentication method should be enabled", color: "negative" })
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
emits("submit", d)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
</script>
|
|
41
|
+
<template>
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
<form-kit type="l-form" :bordered="false" @submit="onSubmit" :value="$props">
|
|
45
|
+
|
|
46
|
+
<form-kit label="Password based" type="l-checkbox" name="authentication_password_based" true-value="1"
|
|
47
|
+
false-value="0" />
|
|
48
|
+
<q-separator />
|
|
49
|
+
|
|
50
|
+
<form-kit label="Google Client ID" type="l-input" name="authentication_google_client_id" />
|
|
51
|
+
|
|
52
|
+
<form-kit label="Facebook App ID" type="l-input" name="authentication_facebook_app_id" />
|
|
53
|
+
|
|
54
|
+
<form-kit label="Microsoft Client ID" type="l-input" name="authentication_microsoft_client_id" />
|
|
55
|
+
<form-kit label="Microsoft Tenant ID" type="l-input" name="authentication_microsoft_tenant_id" />
|
|
56
|
+
</form-kit>
|
|
57
|
+
</template>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import { useRoute, useRouter } from 'vue-router';
|
|
3
3
|
import { useLight, q, m } from "#imports";
|
|
4
4
|
import { useQuasar } from 'quasar';
|
|
@@ -7,15 +7,12 @@ import { ref, computed, reactive, provide, watch, toRaw } from 'vue';
|
|
|
7
7
|
import { useRuntimeConfig } from 'nuxt/app';
|
|
8
8
|
import { api } from '#imports';
|
|
9
9
|
|
|
10
|
-
const { t } = useI18n();
|
|
11
|
-
|
|
12
10
|
const emits = defineEmits(["logout"]);
|
|
13
11
|
const $q = useQuasar();
|
|
14
12
|
$q.loading.show()
|
|
15
13
|
|
|
16
14
|
const config = useRuntimeConfig();
|
|
17
15
|
|
|
18
|
-
|
|
19
16
|
const appVersion = config.public.appVersion ?? '0.0.1';
|
|
20
17
|
|
|
21
18
|
const tt = await q({
|
|
@@ -113,10 +110,9 @@ if (my && my.roles.indexOf('Administrators') != -1) {
|
|
|
113
110
|
light.isAdmin = true;
|
|
114
111
|
}
|
|
115
112
|
|
|
116
|
-
const menuOverlayHeader = ref(false)
|
|
117
113
|
const layoutView = computed(() => {
|
|
118
114
|
let s = ''
|
|
119
|
-
s += menuOverlayHeader
|
|
115
|
+
s += style.menuOverlayHeader ? 'l' : 'h'
|
|
120
116
|
s += 'Hh LpR lFr'
|
|
121
117
|
return s
|
|
122
118
|
})
|
|
@@ -124,7 +120,8 @@ const layoutView = computed(() => {
|
|
|
124
120
|
const style = reactive({
|
|
125
121
|
miniState: my.styles?.miniState || false,
|
|
126
122
|
dense: my.styles?.dense || false,
|
|
127
|
-
footer: my.styles?.footer || false
|
|
123
|
+
footer: my.styles?.footer || false,
|
|
124
|
+
menuOverlayHeader: my.styles?.menuOverlayHeader || false
|
|
128
125
|
});
|
|
129
126
|
|
|
130
127
|
const isMouseOnDrawer = ref(false)
|
|
@@ -176,6 +173,10 @@ watch(() => light.theme, async () => {
|
|
|
176
173
|
$q.dark.set(light.isDarkMode());
|
|
177
174
|
})
|
|
178
175
|
|
|
176
|
+
watch(() => style.menuOverlayHeader, async (value) => {
|
|
177
|
+
await light.setStyle("menuOverlayHeader", value)
|
|
178
|
+
})
|
|
179
|
+
|
|
179
180
|
watch(() => style.miniState, async (value) => {
|
|
180
181
|
await m("updateMyStyle", {
|
|
181
182
|
name: "miniState",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
3
|
-
import { useLight, watch } from "#imports";
|
|
4
|
-
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { reloadNuxtApp, useLight, watch } from "#imports";
|
|
5
4
|
import { useQuasar } from 'quasar'
|
|
6
5
|
import { q } from '#imports'
|
|
7
6
|
import { useRoute } from "vue-router";
|
|
@@ -24,23 +23,49 @@ try {
|
|
|
24
23
|
companyLogo: true,
|
|
25
24
|
logged: true,
|
|
26
25
|
twoFactorAuthentication: true,
|
|
26
|
+
forgetPasswordEnabled: true,
|
|
27
27
|
googleClientId: true,
|
|
28
|
-
|
|
28
|
+
microsoftClientId: true,
|
|
29
|
+
microsoftTenantId: true,
|
|
30
|
+
passwordBasedEnabled: true,
|
|
31
|
+
facebookAppId: true,
|
|
29
32
|
}
|
|
30
33
|
})).app;
|
|
31
34
|
light.company = app.value.company;
|
|
32
35
|
light.companyLogo = app.value.companyLogo;
|
|
33
36
|
} catch (e) {
|
|
34
|
-
|
|
35
37
|
quasar.dialog({
|
|
36
38
|
title: 'Error',
|
|
37
|
-
message:
|
|
39
|
+
message: e.message,
|
|
38
40
|
ok: 'Reload',
|
|
39
41
|
}).onOk(() => {
|
|
40
42
|
window.location.reload();
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
|
|
46
|
+
if (app.value.facebookAppId) {
|
|
47
|
+
|
|
48
|
+
//load facebook sdk
|
|
49
|
+
|
|
50
|
+
(function (d, s, id) {
|
|
51
|
+
var js, fjs = d.getElementsByTagName(s)[0];
|
|
52
|
+
if (d.getElementById(id)) { return; }
|
|
53
|
+
js = d.createElement(s); js.id = id;
|
|
54
|
+
js.src = "https://connect.facebook.net/en_US/sdk.js";
|
|
55
|
+
fjs.parentNode.insertBefore(js, fjs);
|
|
56
|
+
}(document, 'script', 'facebook-jssdk')
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
window.fbAsyncInit = function () {
|
|
60
|
+
FB.init({
|
|
61
|
+
appId: app.value.facebookAppId,
|
|
62
|
+
xfbml: true,
|
|
63
|
+
version: 'v21.0'
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
44
69
|
|
|
45
70
|
|
|
46
71
|
</script>
|
|
@@ -48,12 +73,13 @@ try {
|
|
|
48
73
|
<q-layout v-if="!app.logged">
|
|
49
74
|
<q-page-container class="bg-grey-2" style="color:#1f1f1f">
|
|
50
75
|
<q-page padding>
|
|
76
|
+
<div id="fb-root"></div>
|
|
51
77
|
<l-login v-bind="app" @login="app.logged = true"></l-login>
|
|
52
78
|
</q-page>
|
|
53
79
|
</q-page-container>
|
|
54
80
|
</q-layout>
|
|
55
81
|
|
|
56
|
-
<l-app-main v-else @logout="app.logged = false">
|
|
82
|
+
<l-app-main v-else @logout="app.logged = false" v-bind="app">
|
|
57
83
|
<template #header>
|
|
58
84
|
<slot name="header"></slot>
|
|
59
85
|
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
|
|
3
|
+
import { ref, onMounted } from 'vue';
|
|
4
|
+
const button = ref(null);
|
|
5
|
+
const emits = defineEmits(["login"]);
|
|
6
|
+
|
|
7
|
+
onMounted(() => {
|
|
8
|
+
if (window.FB) {
|
|
9
|
+
window.FB.XFBML.parse()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
window.onFacebookLogin = () => {
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
window.FB.getAccessToken(accessToken => {
|
|
20
|
+
emits('login', accessToken)
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
</script>
|
|
25
|
+
<template>
|
|
26
|
+
<div class="fb-login-button" data-size="large" data-button-type="" data-layout="" data-auto-logout-link="false"
|
|
27
|
+
data-use-continue-as="false" ref="button" data-onlogin="onFacebookLogin()"></div>
|
|
28
|
+
</template>
|
|
@@ -1,20 +1,27 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import { ref, reactive, onMounted } from 'vue'
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, reactive, onMounted, resolveComponent } from 'vue'
|
|
3
3
|
import { useQuasar } from 'quasar';
|
|
4
|
-
import { api, useHead } from '#imports';
|
|
4
|
+
import { api, useHead, m } from '#imports';
|
|
5
5
|
import { useI18n } from 'vue-i18n';
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
const { t } = useI18n();
|
|
8
9
|
|
|
9
10
|
const emits = defineEmits(["login"]);
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
export interface LLoginProps {
|
|
13
|
+
company: string,
|
|
14
|
+
companyLogo: string,
|
|
15
|
+
twoFactorAuthentication: boolean,
|
|
16
|
+
forgetPasswordEnabled: boolean,
|
|
17
|
+
passwordBasedEnabled: boolean,
|
|
18
|
+
googleClientId?: string,
|
|
19
|
+
microsoftClientId?: string,
|
|
20
|
+
microsoftTenantId?: string,
|
|
21
|
+
facebookAppId?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const props = defineProps<LLoginProps>();
|
|
18
25
|
|
|
19
26
|
useHead({
|
|
20
27
|
title: props.company
|
|
@@ -27,11 +34,12 @@ const data = reactive({
|
|
|
27
34
|
|
|
28
35
|
const $q = useQuasar()
|
|
29
36
|
|
|
30
|
-
const loginWithCode = (username, password) => {
|
|
37
|
+
const loginWithCode = (username: string, password: string) => {
|
|
31
38
|
$q.dialog({
|
|
32
39
|
title: t("Enter your code"),
|
|
33
40
|
message: t("Please enter your two factor authentication code (If you lost your authenticator, please contact your administrator)"),
|
|
34
41
|
prompt: {
|
|
42
|
+
model: "",
|
|
35
43
|
type: "text",
|
|
36
44
|
required: true
|
|
37
45
|
},
|
|
@@ -46,10 +54,15 @@ const loginWithCode = (username, password) => {
|
|
|
46
54
|
|
|
47
55
|
}
|
|
48
56
|
|
|
57
|
+
const loading = ref(false);
|
|
58
|
+
|
|
49
59
|
const submit = async () => {
|
|
50
60
|
if (await form1.value.validate()) {
|
|
51
61
|
|
|
62
|
+
|
|
63
|
+
|
|
52
64
|
try {
|
|
65
|
+
loading.value = true;
|
|
53
66
|
await api.auth.login(data.username, data.password, data.code)
|
|
54
67
|
//window.self.location.reload();
|
|
55
68
|
//
|
|
@@ -68,13 +81,15 @@ const submit = async () => {
|
|
|
68
81
|
color: "negative",
|
|
69
82
|
icon: "sym_o_error",
|
|
70
83
|
});
|
|
84
|
+
} finally {
|
|
85
|
+
loading.value = false;
|
|
71
86
|
|
|
72
87
|
|
|
73
88
|
}
|
|
74
89
|
}
|
|
75
90
|
}
|
|
76
91
|
|
|
77
|
-
const resetPassword = (username, code) => {
|
|
92
|
+
const resetPassword = (username: string, code: string) => {
|
|
78
93
|
$q.dialog({
|
|
79
94
|
title: t("Reset password"),
|
|
80
95
|
message: t("Please enter your new password"),
|
|
@@ -116,6 +131,7 @@ const forgetPassword = async () => {
|
|
|
116
131
|
title: t("Enter your code"),
|
|
117
132
|
message: t("Please enter the code sent to your email, your code will expire in 10 minutes"),
|
|
118
133
|
prompt: {
|
|
134
|
+
model: "",
|
|
119
135
|
type: "text",
|
|
120
136
|
required: true
|
|
121
137
|
},
|
|
@@ -144,8 +160,12 @@ const bioLogin = async () => {
|
|
|
144
160
|
try {
|
|
145
161
|
await api.auth.WebAuthn.login(localStorage.getItem("username"));
|
|
146
162
|
window.self.location.reload();
|
|
147
|
-
} catch (e) {
|
|
148
|
-
notify(
|
|
163
|
+
} catch (e: any) {
|
|
164
|
+
$q.notify({
|
|
165
|
+
message: e.message,
|
|
166
|
+
color: "negative",
|
|
167
|
+
icon: "sym_o_error",
|
|
168
|
+
});
|
|
149
169
|
}
|
|
150
170
|
|
|
151
171
|
}
|
|
@@ -153,12 +173,17 @@ const handleGoogleCredentialResponse = async (response) => {
|
|
|
153
173
|
try {
|
|
154
174
|
await api.auth.googleLogin(response.credential);
|
|
155
175
|
window.self.location.reload();
|
|
156
|
-
} catch (e) {
|
|
157
|
-
notify(
|
|
176
|
+
} catch (e: any) {
|
|
177
|
+
$q.notify({
|
|
178
|
+
message: e.message,
|
|
179
|
+
color: "negative",
|
|
180
|
+
icon: "sym_o_error",
|
|
181
|
+
});
|
|
158
182
|
}
|
|
159
183
|
}
|
|
160
184
|
|
|
161
185
|
onMounted(() => {
|
|
186
|
+
|
|
162
187
|
if (props.googleClientId) {
|
|
163
188
|
if (!window.google) {
|
|
164
189
|
$q.notify({
|
|
@@ -191,6 +216,34 @@ onMounted(() => {
|
|
|
191
216
|
);
|
|
192
217
|
}
|
|
193
218
|
})
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
const microsoftLogin = async (resp) => {
|
|
223
|
+
try {
|
|
224
|
+
await api.auth.microsoftLogin(resp.accessToken);
|
|
225
|
+
emits("login");
|
|
226
|
+
} catch (e) {
|
|
227
|
+
$q.notify({
|
|
228
|
+
message: e.message,
|
|
229
|
+
color: "negative",
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const facebookLogin = (accessToken) => {
|
|
237
|
+
m("facebookLogin", { access_token: accessToken }).then(() => {
|
|
238
|
+
emits("login");
|
|
239
|
+
}).catch((e) => {
|
|
240
|
+
$q.notify({
|
|
241
|
+
message: e.message,
|
|
242
|
+
color: "negative",
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
194
247
|
</script>
|
|
195
248
|
|
|
196
249
|
<template>
|
|
@@ -204,7 +257,7 @@ onMounted(() => {
|
|
|
204
257
|
<div class="text-h6">
|
|
205
258
|
{{ company }}
|
|
206
259
|
</div>
|
|
207
|
-
<q-form ref="form1">
|
|
260
|
+
<q-form ref="form1" v-if="passwordBasedEnabled">
|
|
208
261
|
<div class="q-gutter-sm">
|
|
209
262
|
<l-input v-model.trim="data.username" label="Username" :rules="[v => !!v || $t('Username is required')]"
|
|
210
263
|
clearable :outlined="false" stackLabel autocomplete="username">
|
|
@@ -229,15 +282,25 @@ onMounted(() => {
|
|
|
229
282
|
</q-form>
|
|
230
283
|
</q-card-section>
|
|
231
284
|
<q-card-actions>
|
|
232
|
-
<l-btn label="Login" outline rounded color="primary" icon="sym_o_login" @click="submit"
|
|
285
|
+
<l-btn label="Login" outline rounded color="primary" icon="sym_o_login" @click="submit"
|
|
286
|
+
v-if="passwordBasedEnabled" />
|
|
233
287
|
<l-btn v-if="hasBioLogin" outline rounded color="primary" icon="sym_o_fingerprint" @click="bioLogin" />
|
|
234
288
|
<l-btn label="Forget password" outline rounded color="primary" icon="sym_o_lock_reset" @click="forgetPassword"
|
|
235
289
|
v-if="forgetPasswordEnabled" />
|
|
236
290
|
</q-card-actions>
|
|
237
|
-
<q-card-actions v-if="
|
|
291
|
+
<q-card-actions v-if="googleClientId">
|
|
238
292
|
<div>
|
|
239
293
|
<div id="g_id_signin"></div>
|
|
240
294
|
</div>
|
|
241
295
|
</q-card-actions>
|
|
296
|
+
|
|
297
|
+
<q-card-actions v-if="microsoftClientId">
|
|
298
|
+
<l-microsoft-button :client-id="microsoftClientId" :tenant-id="microsoftTenantId"
|
|
299
|
+
@login="microsoftLogin"></l-microsoft-button>
|
|
300
|
+
</q-card-actions>
|
|
301
|
+
|
|
302
|
+
<q-card-actions v-if="facebookAppId">
|
|
303
|
+
<l-facebook-button @login="facebookLogin" />
|
|
304
|
+
</q-card-actions>
|
|
242
305
|
</q-card>
|
|
243
306
|
</template>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { PublicClientApplication } from '@azure/msal-browser';
|
|
3
|
+
import { useQuasar } from 'quasar';
|
|
4
|
+
const $q = useQuasar()
|
|
5
|
+
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
clientId: {
|
|
8
|
+
type: String,
|
|
9
|
+
required: true
|
|
10
|
+
},
|
|
11
|
+
tenantId: String
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const emits = defineEmits(["login"]);
|
|
15
|
+
|
|
16
|
+
const onClick = async () => {
|
|
17
|
+
const myMSALObject = new PublicClientApplication({
|
|
18
|
+
auth: {
|
|
19
|
+
clientId: props.clientId,
|
|
20
|
+
authority: "https://login.microsoftonline.com/" + props.tenantId,
|
|
21
|
+
redirectUri: window.location.origin,
|
|
22
|
+
},
|
|
23
|
+
cache: {
|
|
24
|
+
cacheLocation: "memoryStorage",
|
|
25
|
+
storeAuthStateInCookie: false,
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
await myMSALObject.initialize();
|
|
31
|
+
|
|
32
|
+
const resp = await myMSALObject.loginPopup({
|
|
33
|
+
scopes: ["user.read"]
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
emits("login", resp);
|
|
37
|
+
|
|
38
|
+
} catch (e: any) {
|
|
39
|
+
$q.dialog({
|
|
40
|
+
title: "Error",
|
|
41
|
+
message: e.message,
|
|
42
|
+
color: "negative",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<template>
|
|
52
|
+
<a @click="onClick" class="cursor-pointer">
|
|
53
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="215" height="41" viewBox="0 0 215 41">
|
|
54
|
+
<title>MS-SymbolLockup</title>
|
|
55
|
+
<rect width="215" height="41" fill="#fff" />
|
|
56
|
+
<path d="M214,1V40H1V1H214m1-1H0V41H215V0Z" fill="#8c8c8c" />
|
|
57
|
+
<path
|
|
58
|
+
d="M45.812,25.082V23.288a2.849,2.849,0,0,0,.576.4,4.5,4.5,0,0,0,.707.3,5.513,5.513,0,0,0,.747.187,3.965,3.965,0,0,0,.688.065,2.937,2.937,0,0,0,1.637-.365,1.2,1.2,0,0,0,.538-1.062,1.16,1.16,0,0,0-.179-.649,1.928,1.928,0,0,0-.5-.5,5.355,5.355,0,0,0-.757-.435q-.437-.209-.935-.436c-.356-.19-.687-.383-1-.578a4.358,4.358,0,0,1-.8-.648,2.728,2.728,0,0,1-.534-.8,2.6,2.6,0,0,1-.194-1.047,2.416,2.416,0,0,1,.333-1.285,2.811,2.811,0,0,1,.879-.9,4.026,4.026,0,0,1,1.242-.528,5.922,5.922,0,0,1,1.42-.172,5.715,5.715,0,0,1,2.4.374v1.721a3.832,3.832,0,0,0-2.3-.645,4.106,4.106,0,0,0-.773.074,2.348,2.348,0,0,0-.689.241,1.5,1.5,0,0,0-.494.433,1.054,1.054,0,0,0-.19.637,1.211,1.211,0,0,0,.146.608,1.551,1.551,0,0,0,.429.468,4.276,4.276,0,0,0,.688.414c.271.134.584.28.942.436q.547.285,1.036.6a4.881,4.881,0,0,1,.856.7,3.015,3.015,0,0,1,.586.846,2.464,2.464,0,0,1,.217,1.058,2.635,2.635,0,0,1-.322,1.348,2.608,2.608,0,0,1-.868.892,3.82,3.82,0,0,1-1.257.5,6.988,6.988,0,0,1-1.5.155c-.176,0-.392-.014-.649-.04s-.518-.067-.787-.117a7.772,7.772,0,0,1-.761-.187A2.4,2.4,0,0,1,45.812,25.082Z"
|
|
59
|
+
fill="#5e5e5e" />
|
|
60
|
+
<path
|
|
61
|
+
d="M55.129,16.426a1.02,1.02,0,0,1-.714-.272.89.89,0,0,1-.3-.688.916.916,0,0,1,.3-.7,1.008,1.008,0,0,1,.714-.278,1.039,1.039,0,0,1,.732.278.909.909,0,0,1,.3.7.9.9,0,0,1-.3.678A1.034,1.034,0,0,1,55.129,16.426Zm.842,9.074h-1.7V18h1.7Z"
|
|
62
|
+
fill="#5e5e5e" />
|
|
63
|
+
<path
|
|
64
|
+
d="M65.017,24.9q0,4.131-4.153,4.131a6.187,6.187,0,0,1-2.556-.491V26.986a4.726,4.726,0,0,0,2.337.7,2.342,2.342,0,0,0,2.672-2.628V24.24h-.029a2.947,2.947,0,0,1-4.742.436,4.041,4.041,0,0,1-.838-2.684,4.738,4.738,0,0,1,.9-3.04,3,3,0,0,1,2.476-1.128,2.384,2.384,0,0,1,2.2,1.216h.029V18h1.7Zm-1.684-2.835v-.973a1.91,1.91,0,0,0-.524-1.352A1.718,1.718,0,0,0,61.5,19.18a1.793,1.793,0,0,0-1.512.714,3.217,3.217,0,0,0-.546,2,2.774,2.774,0,0,0,.524,1.769,1.678,1.678,0,0,0,1.387.662,1.805,1.805,0,0,0,1.429-.632A2.391,2.391,0,0,0,63.333,22.064Z"
|
|
65
|
+
fill="#5e5e5e" />
|
|
66
|
+
<path
|
|
67
|
+
d="M73.908,25.5h-1.7V21.273q0-2.1-1.486-2.1a1.622,1.622,0,0,0-1.282.582,2.162,2.162,0,0,0-.5,1.469V25.5H67.229V18h1.707v1.245h.029A2.673,2.673,0,0,1,71.4,17.824a2.265,2.265,0,0,1,1.868.795,3.57,3.57,0,0,1,.644,2.3Z"
|
|
68
|
+
fill="#5e5e5e" />
|
|
69
|
+
<path
|
|
70
|
+
d="M80.962,16.426a1.02,1.02,0,0,1-.714-.272.89.89,0,0,1-.3-.688.916.916,0,0,1,.3-.7,1.008,1.008,0,0,1,.714-.278,1.039,1.039,0,0,1,.732.278.909.909,0,0,1,.3.7.9.9,0,0,1-.3.678A1.034,1.034,0,0,1,80.962,16.426ZM81.8,25.5H80.1V18h1.7Z"
|
|
71
|
+
fill="#5e5e5e" />
|
|
72
|
+
<path
|
|
73
|
+
d="M90.7,25.5H89V21.273q0-2.1-1.486-2.1a1.622,1.622,0,0,0-1.282.582,2.157,2.157,0,0,0-.506,1.469V25.5H84.023V18H85.73v1.245h.03a2.673,2.673,0,0,1,2.431-1.421,2.265,2.265,0,0,1,1.868.795,3.57,3.57,0,0,1,.644,2.3Z"
|
|
74
|
+
fill="#5e5e5e" />
|
|
75
|
+
<path
|
|
76
|
+
d="M106.984,18l-2.212,7.5h-1.78l-1.361-5.083a3.215,3.215,0,0,1-.1-.659H101.5a3.069,3.069,0,0,1-.131.644l-1.48,5.1H98.145L95.939,18H97.7l1.363,5.405a3.16,3.16,0,0,1,.087.645H99.2a3.384,3.384,0,0,1,.117-.659L100.832,18h1.6l1.347,5.428a3.732,3.732,0,0,1,.095.644h.052a3.387,3.387,0,0,1,.11-.644L105.365,18Z"
|
|
77
|
+
fill="#5e5e5e" />
|
|
78
|
+
<path
|
|
79
|
+
d="M109.1,16.426a1.018,1.018,0,0,1-.714-.272.886.886,0,0,1-.3-.688.912.912,0,0,1,.3-.7,1.006,1.006,0,0,1,.714-.278,1.039,1.039,0,0,1,.732.278.912.912,0,0,1,.3.7.9.9,0,0,1-.3.678A1.034,1.034,0,0,1,109.1,16.426Zm.841,9.074h-1.7V18h1.7Z"
|
|
80
|
+
fill="#5e5e5e" />
|
|
81
|
+
<path
|
|
82
|
+
d="M116.117,25.42a2.955,2.955,0,0,1-1.31.248q-2.182,0-2.183-2.094V19.333h-1.253V18h1.253V16.264l1.7-.483V18h1.794v1.333h-1.794v3.75a1.484,1.484,0,0,0,.241.952,1.006,1.006,0,0,0,.807.285,1.167,1.167,0,0,0,.746-.248Z"
|
|
83
|
+
fill="#5e5e5e" />
|
|
84
|
+
<path
|
|
85
|
+
d="M124.248,25.5h-1.7V21.4q0-2.226-1.487-2.226a1.556,1.556,0,0,0-1.26.644,2.568,2.568,0,0,0-.513,1.649V25.5h-1.707V14.4h1.707v4.849h.029a2.685,2.685,0,0,1,2.432-1.421q2.5,0,2.5,3.055Z"
|
|
86
|
+
fill="#5e5e5e" />
|
|
87
|
+
<path
|
|
88
|
+
d="M141.907,25.5h-1.728V18.7q0-.835.1-2.043h-.029a6.992,6.992,0,0,1-.285.988L136.831,25.5h-1.2l-3.143-7.793a7.236,7.236,0,0,1-.277-1.047h-.029q.057.63.058,2.058V25.5h-1.611V15h2.453l2.762,7a10.884,10.884,0,0,1,.41,1.2h.036c.181-.551.327-.962.44-1.23L139.541,15h2.366Z"
|
|
89
|
+
fill="#5e5e5e" />
|
|
90
|
+
<path
|
|
91
|
+
d="M145.158,16.426a1.022,1.022,0,0,1-.714-.272.89.89,0,0,1-.3-.688.916.916,0,0,1,.3-.7,1.009,1.009,0,0,1,.714-.278,1.043,1.043,0,0,1,.733.278.911.911,0,0,1,.3.7.9.9,0,0,1-.3.678A1.038,1.038,0,0,1,145.158,16.426ZM146,25.5h-1.7V18H146Z"
|
|
92
|
+
fill="#5e5e5e" />
|
|
93
|
+
<path
|
|
94
|
+
d="M153.589,25.156a4.2,4.2,0,0,1-2.131.52,3.606,3.606,0,0,1-2.695-1.044,3.691,3.691,0,0,1-1.026-2.706,4.07,4.07,0,0,1,1.1-2.978,3.944,3.944,0,0,1,2.948-1.124,4.3,4.3,0,0,1,1.81.36v1.582a2.743,2.743,0,0,0-1.67-.586,2.32,2.32,0,0,0-1.766.728,2.665,2.665,0,0,0-.688,1.908,2.536,2.536,0,0,0,.648,1.838,2.3,2.3,0,0,0,1.739.674,2.716,2.716,0,0,0,1.729-.652Z"
|
|
95
|
+
fill="#5e5e5e" />
|
|
96
|
+
<path
|
|
97
|
+
d="M159.625,19.619a1.4,1.4,0,0,0-.887-.242,1.513,1.513,0,0,0-1.259.682,3.04,3.04,0,0,0-.506,1.852V25.5h-1.7V18h1.7v1.545H157a2.606,2.606,0,0,1,.766-1.233,1.724,1.724,0,0,1,1.154-.444,1.432,1.432,0,0,1,.7.14Z"
|
|
98
|
+
fill="#5e5e5e" />
|
|
99
|
+
<path
|
|
100
|
+
d="M164.02,25.676a3.719,3.719,0,0,1-2.773-1.051,3.8,3.8,0,0,1-1.036-2.787,3.7,3.7,0,0,1,3.991-4.014,3.6,3.6,0,0,1,2.739,1.033,3.986,3.986,0,0,1,.982,2.864,3.932,3.932,0,0,1-1.059,2.875A3.8,3.8,0,0,1,164.02,25.676Zm.08-6.5a1.938,1.938,0,0,0-1.575.7,2.913,2.913,0,0,0-.579,1.919,2.744,2.744,0,0,0,.586,1.856,1.965,1.965,0,0,0,1.568.678,1.87,1.87,0,0,0,1.542-.666,2.956,2.956,0,0,0,.538-1.9,3,3,0,0,0-.538-1.911A1.858,1.858,0,0,0,164.1,19.18Z"
|
|
101
|
+
fill="#5e5e5e" />
|
|
102
|
+
<path
|
|
103
|
+
d="M169.182,25.266V23.691a3.392,3.392,0,0,0,2.1.725q1.539,0,1.538-.908a.714.714,0,0,0-.132-.436,1.241,1.241,0,0,0-.355-.318,2.784,2.784,0,0,0-.527-.25q-.3-.108-.677-.248a7.052,7.052,0,0,1-.832-.389,2.545,2.545,0,0,1-.615-.465,1.745,1.745,0,0,1-.37-.59,2.145,2.145,0,0,1-.125-.769,1.775,1.775,0,0,1,.256-.955,2.223,2.223,0,0,1,.69-.7,3.289,3.289,0,0,1,.98-.425,4.511,4.511,0,0,1,1.136-.143,5.181,5.181,0,0,1,1.86.315v1.487a3.136,3.136,0,0,0-1.816-.542,2.317,2.317,0,0,0-.582.066,1.472,1.472,0,0,0-.443.183.886.886,0,0,0-.286.282.669.669,0,0,0-.1.363.77.77,0,0,0,.1.41.93.93,0,0,0,.3.3,2.654,2.654,0,0,0,.483.234q.282.105.649.23a9.4,9.4,0,0,1,.867.4,2.886,2.886,0,0,1,.656.465,1.806,1.806,0,0,1,.417.6,2.034,2.034,0,0,1,.147.81,1.847,1.847,0,0,1-.264,1,2.205,2.205,0,0,1-.7.7,3.292,3.292,0,0,1-1.015.413,5.222,5.222,0,0,1-1.212.136A5.115,5.115,0,0,1,169.182,25.266Z"
|
|
104
|
+
fill="#5e5e5e" />
|
|
105
|
+
<path
|
|
106
|
+
d="M179.443,25.676a3.717,3.717,0,0,1-2.772-1.051,3.793,3.793,0,0,1-1.036-2.787,3.7,3.7,0,0,1,3.991-4.014,3.6,3.6,0,0,1,2.739,1.033,3.986,3.986,0,0,1,.982,2.864,3.932,3.932,0,0,1-1.059,2.875A3.8,3.8,0,0,1,179.443,25.676Zm.08-6.5a1.936,1.936,0,0,0-1.574.7,2.908,2.908,0,0,0-.579,1.919,2.739,2.739,0,0,0,.586,1.856,1.964,1.964,0,0,0,1.567.678,1.868,1.868,0,0,0,1.542-.666,2.95,2.95,0,0,0,.539-1.9,2.99,2.99,0,0,0-.539-1.911A1.857,1.857,0,0,0,179.523,19.18Z"
|
|
107
|
+
fill="#5e5e5e" />
|
|
108
|
+
<path
|
|
109
|
+
d="M189.067,15.781a1.533,1.533,0,0,0-.784-.2q-1.237,0-1.237,1.4V18h1.743v1.333h-1.736V25.5h-1.7V19.333h-1.282V18h1.282V16.784a2.362,2.362,0,0,1,.777-1.871,2.82,2.82,0,0,1,1.94-.684,2.879,2.879,0,0,1,1,.138Z"
|
|
110
|
+
fill="#5e5e5e" />
|
|
111
|
+
<path
|
|
112
|
+
d="M194.23,25.42a2.955,2.955,0,0,1-1.31.248q-2.182,0-2.183-2.094V19.333h-1.253V18h1.253V16.264l1.7-.483V18h1.793v1.333h-1.793v3.75a1.484,1.484,0,0,0,.241.952,1,1,0,0,0,.806.285,1.165,1.165,0,0,0,.746-.248Z"
|
|
113
|
+
fill="#5e5e5e" />
|
|
114
|
+
<rect x="13" y="11" width="9" height="9" fill="#f25022" />
|
|
115
|
+
<rect x="13" y="21" width="9" height="9" fill="#00a4ef" />
|
|
116
|
+
<rect x="23" y="11" width="9" height="9" fill="#7fba00" />
|
|
117
|
+
<rect x="23" y="21" width="9" height="9" fill="#ffb900" />
|
|
118
|
+
</svg>
|
|
119
|
+
</a>
|
|
120
|
+
</template>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref } from 'vue'
|
|
3
|
-
import { q, m } from '#imports'
|
|
3
|
+
import { q, m, useLight } from '#imports';
|
|
4
|
+
|
|
5
|
+
const light = useLight()
|
|
4
6
|
|
|
5
7
|
const { app } = await q({ app: { config: ["name", "value"] } })
|
|
6
8
|
const obj = app.config.reduce((acc, cur) => {
|
|
@@ -11,6 +13,24 @@ const obj = app.config.reduce((acc, cur) => {
|
|
|
11
13
|
obj.revision = obj.revision ? obj.revision.split(',') : []
|
|
12
14
|
|
|
13
15
|
const tab = ref('general')
|
|
16
|
+
|
|
17
|
+
const onSubmit = async (d) => {
|
|
18
|
+
let data = [];
|
|
19
|
+
Object.keys(d).forEach((key) => {
|
|
20
|
+
data.push({
|
|
21
|
+
name: key,
|
|
22
|
+
value: d[key]
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
await m("updateAppConfigs", { data })
|
|
26
|
+
|
|
27
|
+
light.notify({ message: "Settings saved", color: "positive" })
|
|
28
|
+
|
|
29
|
+
//update the modelValue
|
|
30
|
+
Object.keys(d).forEach((key) => {
|
|
31
|
+
obj[key] = d[key]
|
|
32
|
+
})
|
|
33
|
+
}
|
|
14
34
|
</script>
|
|
15
35
|
<template>
|
|
16
36
|
<l-page>
|
|
@@ -24,6 +44,7 @@ const tab = ref('general')
|
|
|
24
44
|
<q-tab name="Modules" icon="sym_o_apps" :label="$t('Modules')" />
|
|
25
45
|
<q-tab name="mail" icon="sym_o_email" :label="$t('Mail')" />
|
|
26
46
|
<q-tab name="forget-password" icon="sym_o_lock" :label="$t('Forget password')" />
|
|
47
|
+
<q-tab name="authentication" icon="sym_o_passkey" :label="$t('Authentication')" />
|
|
27
48
|
<q-tab name="developer" icon="sym_o_code" :label="$t('Developer')" />
|
|
28
49
|
</q-tabs>
|
|
29
50
|
</template>
|
|
@@ -34,6 +55,7 @@ const tab = ref('general')
|
|
|
34
55
|
<l-system-setting-modules v-if="tab == 'Modules'" v-model="obj" />
|
|
35
56
|
<l-system-setting-developer v-if="tab == 'developer'" v-model="obj" />
|
|
36
57
|
<l-system-setting-forget-password v-if="tab == 'forget-password'" v-model="obj" />
|
|
58
|
+
<l-system-setting-authentication v-if="tab == 'authentication'" v-bind="obj" @submit="onSubmit" />
|
|
37
59
|
</template>
|
|
38
60
|
</q-splitter>
|
|
39
61
|
</l-card>
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { reactive, onMounted, nextTick } from "vue"
|
|
3
3
|
import { useQuasar } from "quasar";
|
|
4
|
-
import { q, m,
|
|
4
|
+
import { q, m, useLight } from '#imports'
|
|
5
5
|
import { useI18n } from 'vue-i18n'
|
|
6
6
|
|
|
7
7
|
const light = useLight()
|
|
8
8
|
const { t } = useI18n()
|
|
9
9
|
const quasar = useQuasar();
|
|
10
|
-
let { app, my } = await q({
|
|
10
|
+
let { app, my } = await q({
|
|
11
|
+
app: {
|
|
12
|
+
googleClientId: true,
|
|
13
|
+
microsoftClientId: true,
|
|
14
|
+
microsoftTenantId: true,
|
|
15
|
+
facebookAppId: true,
|
|
16
|
+
}, my: {
|
|
17
|
+
google: true,
|
|
18
|
+
microsoft: true,
|
|
19
|
+
facebook: true,
|
|
20
|
+
}
|
|
21
|
+
})
|
|
11
22
|
|
|
12
23
|
const $q = useQuasar();
|
|
13
24
|
my = reactive(my);
|
|
@@ -17,7 +28,7 @@ const handleGoogleCredentialResponse = async (response) => {
|
|
|
17
28
|
await m("googleRegister", { credential: response.credential })
|
|
18
29
|
|
|
19
30
|
const resp = await q("my", ["gmail"]);
|
|
20
|
-
my.
|
|
31
|
+
my.google = resp.google;
|
|
21
32
|
|
|
22
33
|
light.notify({
|
|
23
34
|
message: "Google account linked",
|
|
@@ -84,33 +95,147 @@ const onUnlink = async () => {
|
|
|
84
95
|
my.gmail = null;
|
|
85
96
|
window.location.reload();
|
|
86
97
|
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const ms = reactive({});
|
|
101
|
+
|
|
102
|
+
const onUnlinkMicrosoft = async () => {
|
|
103
|
+
//confirm
|
|
104
|
+
light.dialog({
|
|
105
|
+
title: "Unlink",
|
|
106
|
+
color: "negative",
|
|
107
|
+
message: "Are you sure you want to unlink your Microsoft account?",
|
|
108
|
+
ok: "Yes",
|
|
109
|
+
cancel: "No",
|
|
110
|
+
}).onOk(async () => {
|
|
111
|
+
await m("unlinkMicrosoft");
|
|
112
|
+
my.microsoft = null;
|
|
113
|
+
window.location.reload();
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const onLinkMicrosoft = async (resp) => {
|
|
118
|
+
try {
|
|
119
|
+
await m("microsoftRegister", { account_id: resp.account.localAccountId });
|
|
120
|
+
light.notify({
|
|
121
|
+
message: "Microsoft account linked",
|
|
122
|
+
color: "positive",
|
|
123
|
+
});
|
|
87
124
|
|
|
125
|
+
window.location.reload();
|
|
126
|
+
} catch (e) {
|
|
127
|
+
light.notify({
|
|
128
|
+
message: e.message,
|
|
129
|
+
color: "negative",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const onLinkFacebook = (accessToken) => {
|
|
135
|
+
try {
|
|
136
|
+
m("facebookRegister", { access_token: accessToken })
|
|
137
|
+
light.notify({
|
|
138
|
+
message: "Facebook account linked",
|
|
139
|
+
color: "positive",
|
|
140
|
+
});
|
|
141
|
+
} catch (e) {
|
|
142
|
+
light.notify({
|
|
143
|
+
message: e.message,
|
|
144
|
+
color: "negative",
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const onUnlinkFacebook = async () => {
|
|
151
|
+
//confirm
|
|
152
|
+
light.dialog({
|
|
153
|
+
title: "Unlink",
|
|
154
|
+
color: "negative",
|
|
155
|
+
message: "Are you sure you want to unlink your Facebook account?",
|
|
156
|
+
ok: "Yes",
|
|
157
|
+
cancel: "No",
|
|
158
|
+
}).onOk(async () => {
|
|
159
|
+
await m("unlinkFacebook");
|
|
160
|
+
my.facebook = null;
|
|
161
|
+
window.location.reload();
|
|
162
|
+
})
|
|
88
163
|
}
|
|
89
164
|
|
|
90
165
|
</script>
|
|
91
166
|
<template>
|
|
92
|
-
<q-card>
|
|
93
|
-
<
|
|
94
|
-
<
|
|
95
|
-
|
|
167
|
+
<q-card :bordered="false">
|
|
168
|
+
<q-card-section>
|
|
169
|
+
<h2 class="text-h6">Google</h2>
|
|
170
|
+
<template v-if="app.googleClientId">
|
|
171
|
+
<template v-if="my.google">
|
|
172
|
+
|
|
96
173
|
{{ $t('You have already linked your Google account.') }}<br />
|
|
97
|
-
Your gmail id is {{ my.
|
|
98
|
-
|
|
174
|
+
Your gmail id is {{ my.google }}<br />
|
|
175
|
+
<l-btn label="Unlink" @click="onUnlink" icon="sym_o_link_off"></l-btn>
|
|
99
176
|
|
|
100
|
-
|
|
101
|
-
<l-btn label="Unlink" @click="onUnlink" icon="sym_o_delete"></l-btn>
|
|
102
|
-
</q-card-actions>
|
|
177
|
+
</template>
|
|
103
178
|
|
|
179
|
+
<template v-else>
|
|
180
|
+
{{ $t('Click the button below to link your Google account.') }}
|
|
181
|
+
<div id="g_id_signin"></div>
|
|
182
|
+
</template>
|
|
104
183
|
</template>
|
|
105
184
|
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
185
|
+
<template v-else>
|
|
186
|
+
Google login is not available. Please set authentication google client id in server settings.
|
|
187
|
+
</template>
|
|
188
|
+
</q-card-section>
|
|
189
|
+
|
|
111
190
|
|
|
112
|
-
<q-
|
|
113
|
-
|
|
191
|
+
<q-separator />
|
|
192
|
+
|
|
193
|
+
<q-card-section>
|
|
194
|
+
<h2 class="text-h6">Microsoft</h2>
|
|
195
|
+
<template v-if="app.microsoftClientId">
|
|
196
|
+
<template v-if="my.microsoft">
|
|
197
|
+
{{ $t('You have already linked your Microsoft account.') }}<br />
|
|
198
|
+
Your account id is {{ my.microsoft }}
|
|
199
|
+
<br />
|
|
200
|
+
<l-btn label="Unlink" @click="onUnlinkMicrosoft" icon="sym_o_link_off"></l-btn>
|
|
201
|
+
</template>
|
|
202
|
+
<template v-else>
|
|
203
|
+
<div>{{ $t('Click the button below to link your Microsoft account.') }}</div>
|
|
204
|
+
<div>
|
|
205
|
+
<l-microsoft-button :client-id="app.microsoftClientId" :tenant-id="app.microsoftTenantId"
|
|
206
|
+
@login="onLinkMicrosoft" />
|
|
207
|
+
</div>
|
|
208
|
+
</template>
|
|
209
|
+
</template>
|
|
210
|
+
<template v-else>
|
|
211
|
+
Micorsoft login is not available. Please set authentication microsft client id in server settings.
|
|
212
|
+
</template>
|
|
114
213
|
</q-card-section>
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
<q-separator />
|
|
217
|
+
<q-card-section>
|
|
218
|
+
<h2 class="text-h6">Facebook</h2>
|
|
219
|
+
<template v-if="app.facebookAppId">
|
|
220
|
+
<template v-if="my.facebook">
|
|
221
|
+
{{ $t('You have already linked your Facebook account.') }}<br />
|
|
222
|
+
Your account id is {{ my.facebook }}
|
|
223
|
+
<l-btn label="Unlink" @click="onUnlinkFacebook" icon="sym_o_link_off"></l-btn>
|
|
224
|
+
</template>
|
|
225
|
+
<template v-else>
|
|
226
|
+
<div>{{ $t('Click the button below to link your Facebook account.') }}</div>
|
|
227
|
+
<l-facebook-button @login="onLinkFacebook" />
|
|
228
|
+
</template>
|
|
229
|
+
</template>
|
|
230
|
+
<template v-else>
|
|
231
|
+
Facebook login is not available. Please set authentication facebook app id in server settings.
|
|
232
|
+
</template>
|
|
233
|
+
</q-card-section>
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
115
240
|
</q-card>
|
|
116
241
|
</template>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hostlink/nuxt-light",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.1",
|
|
4
4
|
"description": "HostLink Nuxt Light Framework",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,8 +32,9 @@
|
|
|
32
32
|
"test:watch": "vitest watch"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"@azure/msal-browser": "^3.26.1",
|
|
35
36
|
"@formkit/drag-and-drop": "^0.1.6",
|
|
36
|
-
"@hostlink/light": "^2.0
|
|
37
|
+
"@hostlink/light": "^2.1.0",
|
|
37
38
|
"@nuxt/kit": "^3.7.4",
|
|
38
39
|
"@nuxt/module-builder": "^0.8.3",
|
|
39
40
|
"@quasar/extras": "^1.16.11",
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
51
|
+
"@azure/identity": "^4.5.0",
|
|
50
52
|
"@nuxt/devtools": "latest",
|
|
51
53
|
"@nuxt/eslint-config": "^0.2.0",
|
|
52
54
|
"@nuxt/schema": "^3.7.4",
|