@hostlink/nuxt-light 1.18.3 → 1.19.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.
- package/dist/module.json +1 -1
- package/dist/runtime/components/L/ForgetPasswordDialog.vue +1 -1
- package/dist/runtime/components/L/System/Setting/authentication.vue +54 -0
- package/dist/runtime/components/l-app.vue +31 -6
- package/dist/runtime/components/l-facebook-button.vue +28 -0
- package/dist/runtime/components/l-login.vue +55 -6
- package/dist/runtime/components/l-microsoft-button.vue +119 -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 +142 -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,54 @@
|
|
|
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
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
withDefaults(defineProps<LSystemSettingAuthenticationProps>(), {
|
|
15
|
+
authentication_password_based: "1",
|
|
16
|
+
authentication_google_client_id: "",
|
|
17
|
+
authentication_facebook_app_id: "",
|
|
18
|
+
authentication_microsoft_client_id: ""
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const emits = defineEmits(["submit"])
|
|
22
|
+
|
|
23
|
+
const onSubmit = async (d: LSystemSettingAuthenticationProps) => {
|
|
24
|
+
|
|
25
|
+
//at least one authentication method should be enabled
|
|
26
|
+
if (d.authentication_password_based === "0" && !d.authentication_google_client_id && !d.authentication_facebook_app_id && !d.authentication_microsoft_client_id) {
|
|
27
|
+
|
|
28
|
+
light.notify({ message: "At least one authentication method should be enabled", color: "negative" })
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
emits("submit", d)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
</script>
|
|
39
|
+
<template>
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
<form-kit type="l-form" :bordered="false" @submit="onSubmit" :value="$props">
|
|
43
|
+
|
|
44
|
+
<form-kit label="Password based" type="l-checkbox" name="authentication_password_based" true-value="1"
|
|
45
|
+
false-value="0" />
|
|
46
|
+
<q-separator />
|
|
47
|
+
|
|
48
|
+
<form-kit label="Google Client ID" type="l-input" name="authentication_google_client_id" />
|
|
49
|
+
|
|
50
|
+
<form-kit label="Facebook App ID" type="l-input" name="authentication_facebook_app_id" />
|
|
51
|
+
|
|
52
|
+
<form-kit label="Microsoft Client ID" type="l-input" name="authentication_microsoft_client_id" />
|
|
53
|
+
</form-kit>
|
|
54
|
+
</template>
|
|
@@ -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";
|
|
@@ -25,22 +24,47 @@ try {
|
|
|
25
24
|
logged: true,
|
|
26
25
|
twoFactorAuthentication: true,
|
|
27
26
|
googleClientId: true,
|
|
28
|
-
forgetPasswordEnabled: true
|
|
27
|
+
forgetPasswordEnabled: true,
|
|
28
|
+
microsoftClientId: true,
|
|
29
|
+
passwordBasedEnabled: true,
|
|
30
|
+
facebookAppId: true,
|
|
29
31
|
}
|
|
30
32
|
})).app;
|
|
31
33
|
light.company = app.value.company;
|
|
32
34
|
light.companyLogo = app.value.companyLogo;
|
|
33
35
|
} catch (e) {
|
|
34
|
-
|
|
35
36
|
quasar.dialog({
|
|
36
37
|
title: 'Error',
|
|
37
|
-
message:
|
|
38
|
+
message: e.message,
|
|
38
39
|
ok: 'Reload',
|
|
39
40
|
}).onOk(() => {
|
|
40
41
|
window.location.reload();
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
if (app.value.facebookAppId) {
|
|
46
|
+
|
|
47
|
+
//load facebook sdk
|
|
48
|
+
|
|
49
|
+
(function (d, s, id) {
|
|
50
|
+
var js, fjs = d.getElementsByTagName(s)[0];
|
|
51
|
+
if (d.getElementById(id)) { return; }
|
|
52
|
+
js = d.createElement(s); js.id = id;
|
|
53
|
+
js.src = "https://connect.facebook.net/en_US/sdk.js";
|
|
54
|
+
fjs.parentNode.insertBefore(js, fjs);
|
|
55
|
+
}(document, 'script', 'facebook-jssdk')
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
window.fbAsyncInit = function () {
|
|
59
|
+
FB.init({
|
|
60
|
+
appId: app.value.facebookAppId,
|
|
61
|
+
xfbml: true,
|
|
62
|
+
version: 'v21.0'
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
44
68
|
|
|
45
69
|
|
|
46
70
|
</script>
|
|
@@ -48,6 +72,7 @@ try {
|
|
|
48
72
|
<q-layout v-if="!app.logged">
|
|
49
73
|
<q-page-container class="bg-grey-2" style="color:#1f1f1f">
|
|
50
74
|
<q-page padding>
|
|
75
|
+
<div id="fb-root"></div>
|
|
51
76
|
<l-login v-bind="app" @login="app.logged = true"></l-login>
|
|
52
77
|
</q-page>
|
|
53
78
|
</q-page-container>
|
|
@@ -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,19 +1,23 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, reactive, onMounted } from 'vue'
|
|
3
3
|
import { useQuasar } from 'quasar';
|
|
4
|
-
import { api, useHead } from '#imports';
|
|
4
|
+
import { api, useHead, m, useLight } 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
|
const props = defineProps({
|
|
12
13
|
twoFactorAuthentication: Boolean,
|
|
13
|
-
googleClientId: String,
|
|
14
|
+
googleClientId: String | undefined,
|
|
14
15
|
forgetPasswordEnabled: Boolean,
|
|
15
16
|
company: String,
|
|
16
|
-
companyLogo: String
|
|
17
|
+
companyLogo: String,
|
|
18
|
+
microsoftClientId: String | undefined,
|
|
19
|
+
passwordBasedEnabled: Boolean,
|
|
20
|
+
facebookAppId: String | undefined,
|
|
17
21
|
})
|
|
18
22
|
|
|
19
23
|
useHead({
|
|
@@ -46,10 +50,15 @@ const loginWithCode = (username, password) => {
|
|
|
46
50
|
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
const loading = ref(false);
|
|
54
|
+
|
|
49
55
|
const submit = async () => {
|
|
50
56
|
if (await form1.value.validate()) {
|
|
51
57
|
|
|
58
|
+
|
|
59
|
+
|
|
52
60
|
try {
|
|
61
|
+
loading.value = true;
|
|
53
62
|
await api.auth.login(data.username, data.password, data.code)
|
|
54
63
|
//window.self.location.reload();
|
|
55
64
|
//
|
|
@@ -68,6 +77,8 @@ const submit = async () => {
|
|
|
68
77
|
color: "negative",
|
|
69
78
|
icon: "sym_o_error",
|
|
70
79
|
});
|
|
80
|
+
} finally {
|
|
81
|
+
loading.value = false;
|
|
71
82
|
|
|
72
83
|
|
|
73
84
|
}
|
|
@@ -159,6 +170,7 @@ const handleGoogleCredentialResponse = async (response) => {
|
|
|
159
170
|
}
|
|
160
171
|
|
|
161
172
|
onMounted(() => {
|
|
173
|
+
|
|
162
174
|
if (props.googleClientId) {
|
|
163
175
|
if (!window.google) {
|
|
164
176
|
$q.notify({
|
|
@@ -191,6 +203,34 @@ onMounted(() => {
|
|
|
191
203
|
);
|
|
192
204
|
}
|
|
193
205
|
})
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
const microsoftLogin = async (resp) => {
|
|
210
|
+
try {
|
|
211
|
+
await api.auth.microsoftLogin(resp.accessToken);
|
|
212
|
+
emits("login");
|
|
213
|
+
} catch (e) {
|
|
214
|
+
$q.notify({
|
|
215
|
+
message: e.message,
|
|
216
|
+
color: "negative",
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const facebookLogin = (accessToken) => {
|
|
224
|
+
m("facebookLogin", { access_token: accessToken }).then(() => {
|
|
225
|
+
emits("login");
|
|
226
|
+
}).catch((e) => {
|
|
227
|
+
$q.notify({
|
|
228
|
+
message: e.message,
|
|
229
|
+
color: "negative",
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
194
234
|
</script>
|
|
195
235
|
|
|
196
236
|
<template>
|
|
@@ -204,7 +244,7 @@ onMounted(() => {
|
|
|
204
244
|
<div class="text-h6">
|
|
205
245
|
{{ company }}
|
|
206
246
|
</div>
|
|
207
|
-
<q-form ref="form1">
|
|
247
|
+
<q-form ref="form1" v-if="passwordBasedEnabled">
|
|
208
248
|
<div class="q-gutter-sm">
|
|
209
249
|
<l-input v-model.trim="data.username" label="Username" :rules="[v => !!v || $t('Username is required')]"
|
|
210
250
|
clearable :outlined="false" stackLabel autocomplete="username">
|
|
@@ -229,15 +269,24 @@ onMounted(() => {
|
|
|
229
269
|
</q-form>
|
|
230
270
|
</q-card-section>
|
|
231
271
|
<q-card-actions>
|
|
232
|
-
<l-btn label="Login" outline rounded color="primary" icon="sym_o_login" @click="submit"
|
|
272
|
+
<l-btn label="Login" outline rounded color="primary" icon="sym_o_login" @click="submit"
|
|
273
|
+
v-if="passwordBasedEnabled" />
|
|
233
274
|
<l-btn v-if="hasBioLogin" outline rounded color="primary" icon="sym_o_fingerprint" @click="bioLogin" />
|
|
234
275
|
<l-btn label="Forget password" outline rounded color="primary" icon="sym_o_lock_reset" @click="forgetPassword"
|
|
235
276
|
v-if="forgetPasswordEnabled" />
|
|
236
277
|
</q-card-actions>
|
|
237
|
-
<q-card-actions v-if="
|
|
278
|
+
<q-card-actions v-if="googleClientId">
|
|
238
279
|
<div>
|
|
239
280
|
<div id="g_id_signin"></div>
|
|
240
281
|
</div>
|
|
241
282
|
</q-card-actions>
|
|
283
|
+
|
|
284
|
+
<q-card-actions v-if="microsoftClientId">
|
|
285
|
+
<l-microsoft-button :client-id="microsoftClientId" @login="microsoftLogin"></l-microsoft-button>
|
|
286
|
+
</q-card-actions>
|
|
287
|
+
|
|
288
|
+
<q-card-actions v-if="facebookAppId">
|
|
289
|
+
<l-facebook-button @login="facebookLogin" />
|
|
290
|
+
</q-card-actions>
|
|
242
291
|
</q-card>
|
|
243
292
|
</template>
|
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
})
|
|
12
|
+
|
|
13
|
+
const emits = defineEmits(["login"]);
|
|
14
|
+
|
|
15
|
+
const onClick = async () => {
|
|
16
|
+
const myMSALObject = new PublicClientApplication({
|
|
17
|
+
auth: {
|
|
18
|
+
clientId: props.clientId,
|
|
19
|
+
authority: "https://login.microsoftonline.com/common",
|
|
20
|
+
redirectUri: window.location.origin,
|
|
21
|
+
},
|
|
22
|
+
cache: {
|
|
23
|
+
cacheLocation: "memoryStorage",
|
|
24
|
+
storeAuthStateInCookie: false,
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await myMSALObject.initialize();
|
|
30
|
+
|
|
31
|
+
const resp = await myMSALObject.loginPopup({
|
|
32
|
+
scopes: ["user.read"]
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
emits("login", resp);
|
|
36
|
+
|
|
37
|
+
} catch (e: any) {
|
|
38
|
+
$q.dialog({
|
|
39
|
+
title: "Error",
|
|
40
|
+
message: e.message,
|
|
41
|
+
color: "negative",
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<a @click="onClick" class="cursor-pointer">
|
|
52
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="215" height="41" viewBox="0 0 215 41">
|
|
53
|
+
<title>MS-SymbolLockup</title>
|
|
54
|
+
<rect width="215" height="41" fill="#fff" />
|
|
55
|
+
<path d="M214,1V40H1V1H214m1-1H0V41H215V0Z" fill="#8c8c8c" />
|
|
56
|
+
<path
|
|
57
|
+
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"
|
|
58
|
+
fill="#5e5e5e" />
|
|
59
|
+
<path
|
|
60
|
+
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"
|
|
61
|
+
fill="#5e5e5e" />
|
|
62
|
+
<path
|
|
63
|
+
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"
|
|
64
|
+
fill="#5e5e5e" />
|
|
65
|
+
<path
|
|
66
|
+
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"
|
|
67
|
+
fill="#5e5e5e" />
|
|
68
|
+
<path
|
|
69
|
+
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"
|
|
70
|
+
fill="#5e5e5e" />
|
|
71
|
+
<path
|
|
72
|
+
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"
|
|
73
|
+
fill="#5e5e5e" />
|
|
74
|
+
<path
|
|
75
|
+
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"
|
|
76
|
+
fill="#5e5e5e" />
|
|
77
|
+
<path
|
|
78
|
+
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"
|
|
79
|
+
fill="#5e5e5e" />
|
|
80
|
+
<path
|
|
81
|
+
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"
|
|
82
|
+
fill="#5e5e5e" />
|
|
83
|
+
<path
|
|
84
|
+
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"
|
|
85
|
+
fill="#5e5e5e" />
|
|
86
|
+
<path
|
|
87
|
+
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"
|
|
88
|
+
fill="#5e5e5e" />
|
|
89
|
+
<path
|
|
90
|
+
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"
|
|
91
|
+
fill="#5e5e5e" />
|
|
92
|
+
<path
|
|
93
|
+
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"
|
|
94
|
+
fill="#5e5e5e" />
|
|
95
|
+
<path
|
|
96
|
+
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"
|
|
97
|
+
fill="#5e5e5e" />
|
|
98
|
+
<path
|
|
99
|
+
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"
|
|
100
|
+
fill="#5e5e5e" />
|
|
101
|
+
<path
|
|
102
|
+
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"
|
|
103
|
+
fill="#5e5e5e" />
|
|
104
|
+
<path
|
|
105
|
+
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"
|
|
106
|
+
fill="#5e5e5e" />
|
|
107
|
+
<path
|
|
108
|
+
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"
|
|
109
|
+
fill="#5e5e5e" />
|
|
110
|
+
<path
|
|
111
|
+
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"
|
|
112
|
+
fill="#5e5e5e" />
|
|
113
|
+
<rect x="13" y="11" width="9" height="9" fill="#f25022" />
|
|
114
|
+
<rect x="13" y="21" width="9" height="9" fill="#00a4ef" />
|
|
115
|
+
<rect x="23" y="11" width="9" height="9" fill="#7fba00" />
|
|
116
|
+
<rect x="23" y="21" width="9" height="9" fill="#ffb900" />
|
|
117
|
+
</svg>
|
|
118
|
+
</a>
|
|
119
|
+
</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,23 @@
|
|
|
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
|
+
facebookAppId: true,
|
|
15
|
+
}, my: {
|
|
16
|
+
google: true,
|
|
17
|
+
microsoft: true,
|
|
18
|
+
facebook: true,
|
|
19
|
+
}
|
|
20
|
+
})
|
|
11
21
|
|
|
12
22
|
const $q = useQuasar();
|
|
13
23
|
my = reactive(my);
|
|
@@ -17,7 +27,7 @@ const handleGoogleCredentialResponse = async (response) => {
|
|
|
17
27
|
await m("googleRegister", { credential: response.credential })
|
|
18
28
|
|
|
19
29
|
const resp = await q("my", ["gmail"]);
|
|
20
|
-
my.
|
|
30
|
+
my.google = resp.google;
|
|
21
31
|
|
|
22
32
|
light.notify({
|
|
23
33
|
message: "Google account linked",
|
|
@@ -84,33 +94,146 @@ const onUnlink = async () => {
|
|
|
84
94
|
my.gmail = null;
|
|
85
95
|
window.location.reload();
|
|
86
96
|
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const ms = reactive({});
|
|
100
|
+
|
|
101
|
+
const onUnlinkMicrosoft = async () => {
|
|
102
|
+
//confirm
|
|
103
|
+
light.dialog({
|
|
104
|
+
title: "Unlink",
|
|
105
|
+
color: "negative",
|
|
106
|
+
message: "Are you sure you want to unlink your Microsoft account?",
|
|
107
|
+
ok: "Yes",
|
|
108
|
+
cancel: "No",
|
|
109
|
+
}).onOk(async () => {
|
|
110
|
+
await m("unlinkMicrosoft");
|
|
111
|
+
my.microsoft = null;
|
|
112
|
+
window.location.reload();
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const onLinkMicrosoft = async (resp) => {
|
|
117
|
+
try {
|
|
118
|
+
await m("microsoftRegister", { account_id: resp.account.localAccountId });
|
|
119
|
+
light.notify({
|
|
120
|
+
message: "Microsoft account linked",
|
|
121
|
+
color: "positive",
|
|
122
|
+
});
|
|
87
123
|
|
|
124
|
+
window.location.reload();
|
|
125
|
+
} catch (e) {
|
|
126
|
+
light.notify({
|
|
127
|
+
message: e.message,
|
|
128
|
+
color: "negative",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const onLinkFacebook = (accessToken) => {
|
|
134
|
+
try {
|
|
135
|
+
m("facebookRegister", { access_token: accessToken })
|
|
136
|
+
light.notify({
|
|
137
|
+
message: "Facebook account linked",
|
|
138
|
+
color: "positive",
|
|
139
|
+
});
|
|
140
|
+
} catch (e) {
|
|
141
|
+
light.notify({
|
|
142
|
+
message: e.message,
|
|
143
|
+
color: "negative",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const onUnlinkFacebook = async () => {
|
|
150
|
+
//confirm
|
|
151
|
+
light.dialog({
|
|
152
|
+
title: "Unlink",
|
|
153
|
+
color: "negative",
|
|
154
|
+
message: "Are you sure you want to unlink your Facebook account?",
|
|
155
|
+
ok: "Yes",
|
|
156
|
+
cancel: "No",
|
|
157
|
+
}).onOk(async () => {
|
|
158
|
+
await m("unlinkFacebook");
|
|
159
|
+
my.facebook = null;
|
|
160
|
+
window.location.reload();
|
|
161
|
+
})
|
|
88
162
|
}
|
|
89
163
|
|
|
90
164
|
</script>
|
|
91
165
|
<template>
|
|
92
|
-
<q-card>
|
|
93
|
-
<
|
|
94
|
-
<
|
|
95
|
-
|
|
166
|
+
<q-card :bordered="false">
|
|
167
|
+
<q-card-section>
|
|
168
|
+
<h2 class="text-h6">Google</h2>
|
|
169
|
+
<template v-if="app.googleClientId">
|
|
170
|
+
<template v-if="my.google">
|
|
171
|
+
|
|
96
172
|
{{ $t('You have already linked your Google account.') }}<br />
|
|
97
|
-
Your gmail id is {{ my.
|
|
98
|
-
|
|
173
|
+
Your gmail id is {{ my.google }}<br />
|
|
174
|
+
<l-btn label="Unlink" @click="onUnlink" icon="sym_o_link_off"></l-btn>
|
|
99
175
|
|
|
100
|
-
|
|
101
|
-
<l-btn label="Unlink" @click="onUnlink" icon="sym_o_delete"></l-btn>
|
|
102
|
-
</q-card-actions>
|
|
176
|
+
</template>
|
|
103
177
|
|
|
178
|
+
<template v-else>
|
|
179
|
+
{{ $t('Click the button below to link your Google account.') }}
|
|
180
|
+
<div id="g_id_signin"></div>
|
|
181
|
+
</template>
|
|
104
182
|
</template>
|
|
105
183
|
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
184
|
+
<template v-else>
|
|
185
|
+
Google login is not available. Please set authentication google client id in server settings.
|
|
186
|
+
</template>
|
|
187
|
+
</q-card-section>
|
|
188
|
+
|
|
111
189
|
|
|
112
|
-
<q-
|
|
113
|
-
|
|
190
|
+
<q-separator />
|
|
191
|
+
|
|
192
|
+
<q-card-section>
|
|
193
|
+
<h2 class="text-h6">Microsoft</h2>
|
|
194
|
+
<template v-if="app.microsoftClientId">
|
|
195
|
+
<template v-if="my.microsoft">
|
|
196
|
+
{{ $t('You have already linked your Microsoft account.') }}<br />
|
|
197
|
+
Your account id is {{ my.microsoft }}
|
|
198
|
+
<br />
|
|
199
|
+
<l-btn label="Unlink" @click="onUnlinkMicrosoft" icon="sym_o_link_off"></l-btn>
|
|
200
|
+
</template>
|
|
201
|
+
<template v-else>
|
|
202
|
+
<div>{{ $t('Click the button below to link your Microsoft account.') }}</div>
|
|
203
|
+
<div>
|
|
204
|
+
<l-microsoft-button :client-id="app.microsoftClientId" @login="onLinkMicrosoft" />
|
|
205
|
+
</div>
|
|
206
|
+
</template>
|
|
207
|
+
</template>
|
|
208
|
+
<template v-else>
|
|
209
|
+
Micorsoft login is not available. Please set authentication microsft client id in server settings.
|
|
210
|
+
</template>
|
|
114
211
|
</q-card-section>
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
<q-separator />
|
|
215
|
+
<q-card-section>
|
|
216
|
+
<h2 class="text-h6">Facebook</h2>
|
|
217
|
+
<template v-if="app.facebookAppId">
|
|
218
|
+
<template v-if="my.facebook">
|
|
219
|
+
{{ $t('You have already linked your Facebook account.') }}<br />
|
|
220
|
+
Your account id is {{ my.facebook }}
|
|
221
|
+
<l-btn label="Unlink" @click="onUnlinkFacebook" icon="sym_o_link_off"></l-btn>
|
|
222
|
+
</template>
|
|
223
|
+
<template v-else>
|
|
224
|
+
<div>{{ $t('Click the button below to link your Facebook account.') }}</div>
|
|
225
|
+
<l-facebook-button @login="onLinkFacebook" />
|
|
226
|
+
</template>
|
|
227
|
+
</template>
|
|
228
|
+
<template v-else>
|
|
229
|
+
Facebook login is not available. Please set authentication facebook app id in server settings.
|
|
230
|
+
</template>
|
|
231
|
+
</q-card-section>
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
115
238
|
</q-card>
|
|
116
239
|
</template>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hostlink/nuxt-light",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
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",
|