@hostlink/nuxt-light 1.15.4 → 1.16.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 +2 -2
- package/dist/runtime/components/L/ForgetPasswordDialog.vue +68 -0
- package/dist/runtime/components/L/ForgetPasswordResetDialog.vue +34 -0
- package/dist/runtime/components/L/System/Setting/developer.vue +48 -0
- package/dist/runtime/components/L/System/Setting/forget-password.vue +61 -0
- package/dist/runtime/components/L/System/Setting/general.vue +49 -0
- package/dist/runtime/components/L/System/Setting/mail.vue +88 -0
- package/dist/runtime/components/L/System/Setting/modules.vue +52 -0
- package/dist/runtime/components/L/System/Setting/security.vue +82 -0
- package/dist/runtime/components/l-checkbox.vue +4 -3
- package/dist/runtime/components/l-login.vue +28 -33
- package/dist/runtime/formkit/Checkbox.vue +3 -1
- package/dist/runtime/formkit/Form.vue +0 -10
- package/dist/runtime/formkit/Input.vue +0 -1
- package/dist/runtime/index.d.ts +8 -1
- package/dist/runtime/pages/System/setting.vue +10 -144
- package/package.json +2 -2
package/dist/module.json
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { useQuasar, useDialogPluginComponent } from 'quasar'
|
|
4
|
+
import { m, api } from '#imports';
|
|
5
|
+
const $q = useQuasar()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
|
|
9
|
+
|
|
10
|
+
const username = ref('')
|
|
11
|
+
const email = ref('')
|
|
12
|
+
const onOKClick = async () => {
|
|
13
|
+
if (username.value == '' || email.value == '') {
|
|
14
|
+
$q.notify({
|
|
15
|
+
type: 'negative',
|
|
16
|
+
message: 'Username and Email is required'
|
|
17
|
+
})
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
$q.loading.show();
|
|
23
|
+
await api.auth.forgetPassword(username.value, email.value);
|
|
24
|
+
onDialogOK({
|
|
25
|
+
username: username.value,
|
|
26
|
+
email: email.value
|
|
27
|
+
})
|
|
28
|
+
} catch (e) {
|
|
29
|
+
$q.notify({
|
|
30
|
+
type: 'negative',
|
|
31
|
+
message: e.message
|
|
32
|
+
})
|
|
33
|
+
onDialogCancel()
|
|
34
|
+
} finally {
|
|
35
|
+
$q.loading.hide();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<q-dialog ref="dialogRef">
|
|
44
|
+
<q-card class="q-dialog-plugin">
|
|
45
|
+
|
|
46
|
+
<q-card-section class="q-dialog__title">
|
|
47
|
+
Forget Password
|
|
48
|
+
</q-card-section>
|
|
49
|
+
|
|
50
|
+
<q-card-section class="q-dialog__message">
|
|
51
|
+
Please enter your username and email address, we will send you a code to reset your password
|
|
52
|
+
</q-card-section>
|
|
53
|
+
|
|
54
|
+
<q-card-section>
|
|
55
|
+
<q-input v-model="username" label="Username" stack-label
|
|
56
|
+
:rules="[val => !!val || 'Username is required']" hide-bottom-space />
|
|
57
|
+
<q-input v-model="email" label="Email" stack-label type="email" hide-bottom-space
|
|
58
|
+
:rules="[val => !!val || 'Email is required']" />
|
|
59
|
+
</q-card-section>
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
<q-card-actions align="right">
|
|
63
|
+
<q-btn label="Cancel" @click="onDialogCancel" flat color="primary" />
|
|
64
|
+
<q-btn label="OK" @click="onOKClick" flat color="primary" />
|
|
65
|
+
</q-card-actions>
|
|
66
|
+
</q-card>
|
|
67
|
+
</q-dialog>
|
|
68
|
+
</template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useQuasar, useDialogPluginComponent } from 'quasar'
|
|
3
|
+
import { m, api } from '#imports';
|
|
4
|
+
const $q = useQuasar()
|
|
5
|
+
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
|
|
6
|
+
|
|
7
|
+
defineProps({
|
|
8
|
+
username: String,
|
|
9
|
+
code: String
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
</script>
|
|
13
|
+
<template>
|
|
14
|
+
<q-dialog ref="dialogRef">
|
|
15
|
+
<q-card class="q-dialog-plugin">
|
|
16
|
+
<q-card-section class="q-dialog__title">
|
|
17
|
+
Reset password
|
|
18
|
+
</q-card-section>
|
|
19
|
+
|
|
20
|
+
<q-card-section class="q-dialog__message">
|
|
21
|
+
Please enter your new password
|
|
22
|
+
</q-card-section>
|
|
23
|
+
|
|
24
|
+
<q-card-section>
|
|
25
|
+
<form-kit type="form" :actions="false">
|
|
26
|
+
<form-kit type="l-input" name="password" :stack-label="true"></form-kit>
|
|
27
|
+
</form-kit>
|
|
28
|
+
</q-card-section>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
</q-card>
|
|
33
|
+
</q-dialog>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { q, m } from '#imports'
|
|
3
|
+
import { useQuasar } from 'quasar'
|
|
4
|
+
|
|
5
|
+
const $q = useQuasar()
|
|
6
|
+
|
|
7
|
+
const modelValue = defineModel<{
|
|
8
|
+
mode: string
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if (modelValue.value.mode != 'prod') {
|
|
14
|
+
modelValue.value.mode = 'dev'
|
|
15
|
+
} else {
|
|
16
|
+
modelValue.value.mode = 'prod'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const onSubmit = async (d, form) => {
|
|
20
|
+
let data = [];
|
|
21
|
+
Object.keys(d).forEach((key) => {
|
|
22
|
+
data.push({
|
|
23
|
+
name: key,
|
|
24
|
+
value: d[key]
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
await m("updateAppConfigs", { data })
|
|
28
|
+
//update the modelValue
|
|
29
|
+
Object.keys(d).forEach((key) => {
|
|
30
|
+
modelValue.value[key] = d[key]
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
$q.notify({ message: "Settings saved", color: "positive" })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
</script>
|
|
37
|
+
<template>
|
|
38
|
+
<FormKit type="l-form" :bordered="false" :value="{
|
|
39
|
+
mode: modelValue.mode
|
|
40
|
+
}" @submit="onSubmit">
|
|
41
|
+
<FormKit label="Mode" type="l-select" :options="[
|
|
42
|
+
{ label: 'Production', value: 'prod' },
|
|
43
|
+
{ label: 'Development', value: 'dev' },
|
|
44
|
+
|
|
45
|
+
]" name="mode" validation="required">
|
|
46
|
+
</FormKit>
|
|
47
|
+
</FormKit>
|
|
48
|
+
</template>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
|
|
3
|
+
import { q, m } from '#imports'
|
|
4
|
+
import { useQuasar } from 'quasar'
|
|
5
|
+
const $q = useQuasar()
|
|
6
|
+
|
|
7
|
+
const modelValue = defineModel<{
|
|
8
|
+
forget_password_enabled: string,
|
|
9
|
+
forget_password_subject: string,
|
|
10
|
+
forget_password_template: string,
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
if (!modelValue.value.forget_password_enabled == "0") {
|
|
14
|
+
modelValue.value.forget_password_enabled = "1"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!modelValue.value.forget_password_subject) {
|
|
18
|
+
modelValue.value.forget_password_subject = "Password Reset Code"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!modelValue.value.forget_password_template) {
|
|
22
|
+
modelValue.value.forget_password_template = "Your password reset code is: {code}"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const onSubmit = async (d) => {
|
|
27
|
+
let data = [];
|
|
28
|
+
Object.keys(d).forEach((key) => {
|
|
29
|
+
if (d[key] === undefined) {
|
|
30
|
+
d[key] = ""
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
data.push({
|
|
34
|
+
name: key,
|
|
35
|
+
value: d[key]
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
await m("updateAppConfigs", { data })
|
|
39
|
+
//update the props.data
|
|
40
|
+
Object.keys(d).forEach((key) => {
|
|
41
|
+
modelValue.value[key] = d[key]
|
|
42
|
+
})
|
|
43
|
+
$q.notify({ message: "Settings saved", color: "positive" })
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
</script>
|
|
47
|
+
<template>
|
|
48
|
+
<form-kit type="l-form" :value="{
|
|
49
|
+
forget_password_enabled: modelValue.forget_password_enabled,
|
|
50
|
+
forget_password_subject: modelValue.forget_password_subject,
|
|
51
|
+
forget_password_template: modelValue.forget_password_template,
|
|
52
|
+
}" @submit="onSubmit">
|
|
53
|
+
<form-kit type="l-checkbox" label="Forget Password Enabled" name="forget_password_enabled" true-value="1"
|
|
54
|
+
false-value="0" />
|
|
55
|
+
|
|
56
|
+
<form-kit type="l-input" label="Forget Password Subject" name="forget_password_subject" />
|
|
57
|
+
<form-kit type="l-input" label="Forget Password Template" name="forget_password_template"
|
|
58
|
+
input-type="textarea" />
|
|
59
|
+
|
|
60
|
+
</form-kit>
|
|
61
|
+
</template>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { q, m } from '#imports'
|
|
3
|
+
import { useQuasar } from 'quasar'
|
|
4
|
+
|
|
5
|
+
const $q = useQuasar()
|
|
6
|
+
|
|
7
|
+
const modelValue = defineModel<{
|
|
8
|
+
company: string
|
|
9
|
+
company_logo: string
|
|
10
|
+
copyright_name: string
|
|
11
|
+
copyright_year: string
|
|
12
|
+
}>()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const onSubmit = async (d, form) => {
|
|
16
|
+
let data = [];
|
|
17
|
+
Object.keys(d).forEach((key) => {
|
|
18
|
+
data.push({
|
|
19
|
+
name: key,
|
|
20
|
+
value: d[key]
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
await m("updateAppConfigs", { data })
|
|
24
|
+
|
|
25
|
+
Object.keys(d).forEach((key) => {
|
|
26
|
+
modelValue.value[key] = d[key]
|
|
27
|
+
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
$q.notify({ message: "Settings saved", color: "positive" })
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
</script>
|
|
34
|
+
<template>
|
|
35
|
+
<FormKit type="l-form" :bordered="false" :value="{
|
|
36
|
+
company: modelValue.company,
|
|
37
|
+
company_logo: modelValue.company_logo,
|
|
38
|
+
copyright_name: modelValue.copyright_name,
|
|
39
|
+
copyright_year: modelValue.copyright_year
|
|
40
|
+
}" @submit="onSubmit">
|
|
41
|
+
|
|
42
|
+
<FormKit type="l-input" label="Company" name="company" validation="required"></FormKit>
|
|
43
|
+
<FormKit type="l-input" label="Company logo" name="company_logo"></FormKit>
|
|
44
|
+
|
|
45
|
+
<FormKit label="Copyright name" type="l-input" name="copyright_name" validation="required" />
|
|
46
|
+
<FormKit label="Copyright year" type="l-input" name="copyright_year" validation="required" />
|
|
47
|
+
|
|
48
|
+
</FormKit>
|
|
49
|
+
</template>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { q, m } from '#imports'
|
|
3
|
+
import { useQuasar } from 'quasar'
|
|
4
|
+
const $q = useQuasar()
|
|
5
|
+
|
|
6
|
+
const modelValue = defineModel<{
|
|
7
|
+
mail_driver: string,
|
|
8
|
+
mail_host: string
|
|
9
|
+
mail_port: string
|
|
10
|
+
mail_username: string
|
|
11
|
+
mail_password: string
|
|
12
|
+
mail_encryption: string
|
|
13
|
+
mail_from: string
|
|
14
|
+
mail_from_name: string
|
|
15
|
+
mail_reply_to: string
|
|
16
|
+
mail_reply_to_name: string
|
|
17
|
+
}>()
|
|
18
|
+
|
|
19
|
+
if (!modelValue.value.mail_driver) {
|
|
20
|
+
modelValue.value.mail_driver = "mail"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const onSubmit = async (d) => {
|
|
24
|
+
let data = [];
|
|
25
|
+
Object.keys(d).forEach((key) => {
|
|
26
|
+
if (d[key] === undefined) {
|
|
27
|
+
d[key] = ""
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
data.push({
|
|
31
|
+
name: key,
|
|
32
|
+
value: d[key]
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
await m("updateAppConfigs", { data })
|
|
36
|
+
//update the props.data
|
|
37
|
+
Object.keys(d).forEach((key) => {
|
|
38
|
+
modelValue.value[key] = d[key]
|
|
39
|
+
})
|
|
40
|
+
$q.notify({ message: "Settings saved", color: "positive" })
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
</script>
|
|
44
|
+
<template>
|
|
45
|
+
<FormKit type="l-form" :bordered="false" :value="{
|
|
46
|
+
mail_driver: modelValue.mail_driver,
|
|
47
|
+
mail_host: modelValue.mail_host,
|
|
48
|
+
mail_port: modelValue.mail_port,
|
|
49
|
+
mail_username: modelValue.mail_username,
|
|
50
|
+
mail_password: modelValue.mail_password,
|
|
51
|
+
mail_encryption: modelValue.mail_encryption,
|
|
52
|
+
mail_from: modelValue.mail_from,
|
|
53
|
+
mail_from_name: modelValue.mail_from_name,
|
|
54
|
+
mail_reply_to: modelValue.mail_reply_to,
|
|
55
|
+
mail_reply_to_name: modelValue.mail_reply_to_name,
|
|
56
|
+
}" @submit="onSubmit" #default="{ value }">
|
|
57
|
+
|
|
58
|
+
<FormKit type="l-select" label="Mail Driver" name="mail_driver" :options="[{
|
|
59
|
+
label: 'Mail', value: 'mail'
|
|
60
|
+
}, {
|
|
61
|
+
label: 'SMTP', value: 'smtp'
|
|
62
|
+
}]" validation="required"></FormKit>
|
|
63
|
+
|
|
64
|
+
<FormKit type="l-input" label="From Address" name="mail_from" validation="email"></FormKit>
|
|
65
|
+
<FormKit type="l-input" label="From Name" name="mail_from_name"></FormKit>
|
|
66
|
+
<FormKit type="l-input" label="Reply To Address" name="mail_reply_to" validation="email">
|
|
67
|
+
</FormKit>
|
|
68
|
+
<FormKit type="l-input" label="Reply To Name" name="mail_reply_to_name"></FormKit>
|
|
69
|
+
|
|
70
|
+
<template v-if="value.mail_driver === 'smtp'">
|
|
71
|
+
<FormKit type="l-input" label="SMTP Host" name="mail_host"></FormKit>
|
|
72
|
+
<FormKit type="l-input" label="SMTP Port" name="mail_port"></FormKit>
|
|
73
|
+
<FormKit type="l-input" label="SMTP Username" name="mail_username"></FormKit>
|
|
74
|
+
<FormKit type="l-input" label="SMTP Password" name="mail_password"></FormKit>
|
|
75
|
+
|
|
76
|
+
<FormKit type="l-select" label="SMTP Encryption" name="mail_encryption" :options="[
|
|
77
|
+
{ label: 'None', value: 'none' },
|
|
78
|
+
{ label: 'SSL', value: 'ssl' },
|
|
79
|
+
{ label: 'TLS', value: 'tls' },
|
|
80
|
+
]"></FormKit>
|
|
81
|
+
</template>
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
</FormKit>
|
|
87
|
+
|
|
88
|
+
</template>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { q, m } from '#imports'
|
|
3
|
+
import { useQuasar } from 'quasar'
|
|
4
|
+
|
|
5
|
+
const $q = useQuasar()
|
|
6
|
+
|
|
7
|
+
const modelValue = defineModel<{
|
|
8
|
+
file_manager: string
|
|
9
|
+
revision: string
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const onSubmit = async (d, form) => {
|
|
13
|
+
let data = [];
|
|
14
|
+
Object.keys(d).forEach((key) => {
|
|
15
|
+
data.push({
|
|
16
|
+
name: key,
|
|
17
|
+
value: d[key]
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
await m("updateAppConfigs", {
|
|
21
|
+
data
|
|
22
|
+
})
|
|
23
|
+
//update the modelValue
|
|
24
|
+
Object.keys(d).forEach((key) => {
|
|
25
|
+
modelValue.value[key] = d[key]
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
$q.notify({
|
|
29
|
+
message: "Settings saved",
|
|
30
|
+
color: "positive"
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<FormKit type="l-form" :bordered="false" :value="{
|
|
39
|
+
file_manager: modelValue.file_manager,
|
|
40
|
+
revision: modelValue.revision
|
|
41
|
+
}" @submit="onSubmit">
|
|
42
|
+
<q-field label="File manager" stack-label>
|
|
43
|
+
<FormKit type="l-checkbox" label="Show" name="file_manager" true-value="1" false-value="0" />
|
|
44
|
+
</q-field>
|
|
45
|
+
|
|
46
|
+
<FormKit type="l-select" label="Revision" name="revision" use-input use-chips multiple hide-dropdown-icon
|
|
47
|
+
input-debounce="0" new-value-mode="add-unique" />
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
</FormKit>
|
|
51
|
+
|
|
52
|
+
</template>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { q, m } from '#imports'
|
|
3
|
+
import { useQuasar } from 'quasar'
|
|
4
|
+
|
|
5
|
+
const $q = useQuasar()
|
|
6
|
+
|
|
7
|
+
const modelValue = defineModel<{
|
|
8
|
+
password_contains_uppercase: string
|
|
9
|
+
password_contains_lowercase: string
|
|
10
|
+
password_contains_numeric: string
|
|
11
|
+
password_contains_symbol: string
|
|
12
|
+
password_min_length: string
|
|
13
|
+
two_factor_authentication: string
|
|
14
|
+
auth_lockout_duration: string
|
|
15
|
+
auth_lockout_attempts: string
|
|
16
|
+
access_token_expire: string
|
|
17
|
+
}>()
|
|
18
|
+
|
|
19
|
+
const onSubmit = async (d, form) => {
|
|
20
|
+
let data = [];
|
|
21
|
+
Object.keys(d).forEach((key) => {
|
|
22
|
+
data.push({
|
|
23
|
+
name: key,
|
|
24
|
+
value: d[key]
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
await m("updateAppConfigs", { data })
|
|
28
|
+
//update the modelValue
|
|
29
|
+
Object.keys(d).forEach((key) => {
|
|
30
|
+
modelValue.value[key] = d[key]
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
$q.notify({ message: "Settings saved", color: "positive" })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
|
|
40
|
+
<FormKit type="l-form" :bordered="false" :value="{
|
|
41
|
+
password_contains_uppercase: modelValue.password_contains_uppercase,
|
|
42
|
+
password_contains_lowercase: modelValue.password_contains_lowercase,
|
|
43
|
+
password_contains_numeric: modelValue.password_contains_numeric,
|
|
44
|
+
password_contains_symbol: modelValue.password_contains_symbol,
|
|
45
|
+
password_min_length: modelValue.password_min_length,
|
|
46
|
+
two_factor_authentication: modelValue.two_factor_authentication,
|
|
47
|
+
auth_lockout_duration: modelValue.auth_lockout_duration,
|
|
48
|
+
auth_lockout_attempts: modelValue.auth_lockout_attempts,
|
|
49
|
+
access_token_expire: modelValue.access_token_expire
|
|
50
|
+
|
|
51
|
+
}" @submit="onSubmit">
|
|
52
|
+
<q-field label="Password policy" stack-label :color="$light.color">
|
|
53
|
+
<FormKit type="l-checkbox" label="Upper Case" name="password_contains_uppercase" true-value="1"
|
|
54
|
+
false-value="0" />
|
|
55
|
+
<FormKit type="l-checkbox" label="Lower Case" name="password_contains_lowercase" true-value="1"
|
|
56
|
+
false-value="0" />
|
|
57
|
+
<FormKit type="l-checkbox" label="Number" name="password_contains_numeric" true-value="1" false-value="0" />
|
|
58
|
+
<FormKit type="l-checkbox" label="Special Character" name="password_contains_symbol" true-value="1"
|
|
59
|
+
false-value="0" />
|
|
60
|
+
</q-field>
|
|
61
|
+
|
|
62
|
+
<FormKit type="l-input" label="Password min Length" name="password_min_length" validation="required|number">
|
|
63
|
+
</FormKit>
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
<q-field label="Two factor authentication" stack-label :color="$light.color">
|
|
67
|
+
<FormKit type="l-checkbox" label="Enable" name="two_factor_authentication" true-value="1" false-value="0" />
|
|
68
|
+
</q-field>
|
|
69
|
+
|
|
70
|
+
<FormKit label="Auth lockout duration" type="l-input" name="auth_lockout_duration"
|
|
71
|
+
hint="The number of minutes the user is locked out after the maximum number of failed login attempts. Default is 15 minutes."
|
|
72
|
+
validation="required" />
|
|
73
|
+
|
|
74
|
+
<FormKit label="Auth lockout attempts" type="l-input" name="auth_lockout_attempts"
|
|
75
|
+
hint="The number of failed login attempts before the user is locked out. Default is 5 attempts."
|
|
76
|
+
validation="required" />
|
|
77
|
+
|
|
78
|
+
<FormKit label="Access token expiration" type="l-input" name="access_token_expire"
|
|
79
|
+
hint="The access token expiration time in seconds. Default is 28800 seconds (8 hours)."
|
|
80
|
+
validation="required" />
|
|
81
|
+
</FormKit>
|
|
82
|
+
</template>
|
|
@@ -5,15 +5,16 @@ import type { QCheckboxProps } from "quasar"
|
|
|
5
5
|
export interface LCheckboxProps extends QCheckboxProps {
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
const modelValue = defineModel();
|
|
9
|
+
|
|
8
10
|
const emit = defineEmits(["update:modelValue"]);
|
|
9
11
|
|
|
10
12
|
const props = defineProps<LCheckboxProps>()
|
|
11
13
|
|
|
12
14
|
const localValue = computed({
|
|
13
|
-
get: () =>
|
|
15
|
+
get: () => modelValue.value,
|
|
14
16
|
set: (value) => {
|
|
15
|
-
|
|
16
|
-
emit('update:modelValue', value)
|
|
17
|
+
modelValue.value = value;
|
|
17
18
|
}
|
|
18
19
|
});
|
|
19
20
|
</script>
|
|
@@ -13,7 +13,8 @@ const props = defineProps({
|
|
|
13
13
|
googleClientId: String
|
|
14
14
|
})
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const { t } = useI18n();
|
|
17
|
+
|
|
17
18
|
const form1 = ref(null);
|
|
18
19
|
const data = reactive({
|
|
19
20
|
username: "", password: "", code: ""
|
|
@@ -34,35 +35,44 @@ const submit = async () => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
const
|
|
38
|
+
const resetPassword = (username, code) => {
|
|
38
39
|
$q.dialog({
|
|
39
|
-
title:
|
|
40
|
-
message: "Please enter your
|
|
40
|
+
title: "Reset password",
|
|
41
|
+
message: "Please enter your new password",
|
|
41
42
|
prompt: {
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
model: "",
|
|
44
|
+
type: "password",
|
|
44
45
|
isValid: (val) => {
|
|
45
|
-
|
|
46
|
-
const re = /\S+@\S+\.\S+/;
|
|
47
|
-
return re.test(val);
|
|
46
|
+
return val.length > 0;
|
|
48
47
|
}
|
|
49
48
|
},
|
|
50
|
-
cancel: true
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
cancel: true,
|
|
50
|
+
persistent: true
|
|
51
|
+
}).onOk(async password => {
|
|
53
52
|
try {
|
|
54
|
-
await api.auth.
|
|
53
|
+
await api.auth.resetPassword(username, password, code);
|
|
54
|
+
$q.notify({
|
|
55
|
+
message: "Your password has been reset successfully",
|
|
56
|
+
color: "positive",
|
|
57
|
+
icon: "sym_o_check",
|
|
58
|
+
});
|
|
55
59
|
} catch (e) {
|
|
56
60
|
$q.notify({
|
|
57
61
|
message: e.message,
|
|
58
62
|
color: "negative",
|
|
59
63
|
icon: "sym_o_error",
|
|
60
64
|
});
|
|
61
|
-
|
|
62
|
-
} finally {
|
|
63
|
-
$q.loading.hide();
|
|
65
|
+
resetPassword(username, code);
|
|
64
66
|
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
const forgetPassword = async () => {
|
|
65
72
|
|
|
73
|
+
$q.dialog({
|
|
74
|
+
component: resolveComponent("l-forget-password-dialog"),
|
|
75
|
+
}).onOk(async (data) => {
|
|
66
76
|
$q.dialog({
|
|
67
77
|
title: "Enter your code",
|
|
68
78
|
message: "Please enter the code sent to your email, your code will expire in 10 minutes",
|
|
@@ -73,23 +83,8 @@ const forgetPassword = async () => {
|
|
|
73
83
|
cancel: true,
|
|
74
84
|
persistent: true
|
|
75
85
|
}).onOk(async code => {
|
|
76
|
-
if (await api.auth.verifyCode(
|
|
77
|
-
|
|
78
|
-
title: "Reset password",
|
|
79
|
-
message: "Please enter your new password",
|
|
80
|
-
required: true,
|
|
81
|
-
prompt: {
|
|
82
|
-
type: "password"
|
|
83
|
-
},
|
|
84
|
-
}).onOk(async password => {
|
|
85
|
-
if (await api.auth.resetPassword(email, password, code)) {
|
|
86
|
-
$q.notify({
|
|
87
|
-
message: "Your password has been reset successfully",
|
|
88
|
-
color: "positive",
|
|
89
|
-
icon: "sym_o_check",
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
});
|
|
86
|
+
if (await api.auth.verifyCode(data.username, code)) {
|
|
87
|
+
resetPassword(data.username, code);
|
|
93
88
|
} else {
|
|
94
89
|
$q.notify({
|
|
95
90
|
message: "Your code is invalid",
|
|
@@ -14,7 +14,9 @@ const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
|
14
14
|
|
|
15
15
|
</script>
|
|
16
16
|
<template>
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
<l-checkbox v-model="value" :label="context.label" v-bind="context.attrs" :error="error"
|
|
19
|
+
:error-message="errorMessage">
|
|
18
20
|
<template v-for="(s, name) in $slots" v-slot:[name]="props" :key="name">
|
|
19
21
|
<slot :name="name" v-bind="props ?? {}"></slot>
|
|
20
22
|
</template>
|
|
@@ -8,16 +8,6 @@ const route = useRoute();
|
|
|
8
8
|
const router = useRouter();
|
|
9
9
|
const quasar = useQuasar();
|
|
10
10
|
|
|
11
|
-
declare module '@formkit/inputs' {
|
|
12
|
-
interface FormKitInputProps<Props extends FormKitInputs<Props>> {
|
|
13
|
-
lForm: {
|
|
14
|
-
type: 'l-form';
|
|
15
|
-
gutter?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
16
|
-
bordered?: boolean;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
11
|
|
|
22
12
|
let props = defineProps({
|
|
23
13
|
context: {
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -73,6 +73,13 @@ declare module '@formkit/inputs' {
|
|
|
73
73
|
dense?: boolean;
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
+
interface FormKitInputProps<Props extends FormKitInputs<Props>> {
|
|
77
|
+
lForm: {
|
|
78
|
+
type: 'l-form';
|
|
79
|
+
gutter?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
80
|
+
bordered?: boolean;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
76
83
|
}
|
|
77
84
|
export declare const useLight: (options?: {
|
|
78
85
|
color?: string;
|
|
@@ -118,4 +125,4 @@ export declare const useLight: (options?: {
|
|
|
118
125
|
isGranted: (right?: string) => boolean;
|
|
119
126
|
setPermissions: (permissions: Array<string>) => void;
|
|
120
127
|
};
|
|
121
|
-
export * from "./lib.js";
|
|
128
|
+
export * from "./lib/index.js";
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref } from 'vue'
|
|
3
|
-
import { useQuasar } from 'quasar'
|
|
4
|
-
import { reset } from "@formkit/core"
|
|
5
3
|
import { q, m } from '#imports'
|
|
6
|
-
const quasar = useQuasar()
|
|
7
4
|
|
|
8
5
|
const { app } = await q({ app: { config: ["name", "value"] } })
|
|
9
6
|
const obj = app.config.reduce((acc, cur) => {
|
|
@@ -11,163 +8,32 @@ const obj = app.config.reduce((acc, cur) => {
|
|
|
11
8
|
return acc
|
|
12
9
|
}, {});
|
|
13
10
|
|
|
14
|
-
const fields = ["company", "company_logo",
|
|
15
|
-
"password_contains_uppercase",
|
|
16
|
-
"password_contains_lowercase",
|
|
17
|
-
"password_contains_numeric",
|
|
18
|
-
"password_contains_symbol",
|
|
19
|
-
"password_min_length",
|
|
20
|
-
"file_manager",
|
|
21
|
-
"two_factor_authentication",
|
|
22
|
-
"mode",
|
|
23
|
-
"auth_lockout_duration",
|
|
24
|
-
"auth_lockout_attempts",
|
|
25
|
-
"access_token_expire",
|
|
26
|
-
"copyright_year",
|
|
27
|
-
"copyright_name",
|
|
28
|
-
"revision"
|
|
29
|
-
];
|
|
30
|
-
|
|
31
11
|
obj.revision = obj.revision ? obj.revision.split(',') : []
|
|
32
12
|
|
|
33
|
-
//filter out fields that are not in the app.config table
|
|
34
|
-
Object.keys(obj).forEach((key) => {
|
|
35
|
-
if (!fields.includes(key)) {
|
|
36
|
-
delete obj[key]
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const onSubmit = async (d, form) => {
|
|
41
|
-
let data = [];
|
|
42
|
-
Object.keys(d).forEach((key) => {
|
|
43
|
-
data.push({
|
|
44
|
-
name: key,
|
|
45
|
-
value: d[key]
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
await m("updateAppConfigs", { data })
|
|
50
|
-
//show success
|
|
51
|
-
quasar.notify({
|
|
52
|
-
message: "Settings updated",
|
|
53
|
-
color: "positive",
|
|
54
|
-
icon: "check"
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
reset(form, d)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (obj.mode != 'prod') {
|
|
64
|
-
obj.mode = 'dev'
|
|
65
|
-
} else {
|
|
66
|
-
obj.mode = 'prod'
|
|
67
|
-
}
|
|
68
|
-
|
|
69
13
|
const tab = ref('general')
|
|
70
|
-
|
|
71
14
|
</script>
|
|
72
15
|
<template>
|
|
73
16
|
<l-page>
|
|
74
17
|
|
|
75
18
|
<l-card>
|
|
76
|
-
<q-splitter unit="px" :model-value="
|
|
19
|
+
<q-splitter unit="px" :model-value="145">
|
|
77
20
|
<template #before>
|
|
78
21
|
<q-tabs v-model="tab" vertical :active-color="$light.color">
|
|
79
22
|
<q-tab name="general" icon="sym_o_info" :label="$t('General')" />
|
|
80
23
|
<q-tab name="security" icon="sym_o_security" :label="$t('Security')" />
|
|
81
24
|
<q-tab name="Modules" icon="sym_o_apps" :label="$t('Modules')" />
|
|
82
|
-
<q-tab name="
|
|
25
|
+
<q-tab name="mail" icon="sym_o_email" :label="$t('Mail')" />
|
|
26
|
+
<q-tab name="forget-password" icon="sym_o_lock" :label="$t('Forget Password')" />
|
|
27
|
+
<q-tab name="developer" icon="sym_o_code" :label="$t('Developer')" />
|
|
83
28
|
</q-tabs>
|
|
84
29
|
</template>
|
|
85
30
|
<template #after>
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<FormKit type="l-input" label="Company" name="company" validation="required"></FormKit>
|
|
93
|
-
<FormKit type="l-input" label="Company logo" name="company_logo"></FormKit>
|
|
94
|
-
|
|
95
|
-
<FormKit label="Copyright name" type="l-input" name="copyright_name" validation="required" />
|
|
96
|
-
<FormKit label="Copyright year" type="l-input" name="copyright_year" validation="required" />
|
|
97
|
-
|
|
98
|
-
</FormKit>
|
|
99
|
-
|
|
100
|
-
<FormKit type="l-form" :bordered="false" :value="{
|
|
101
|
-
password_contains_uppercase: obj.password_contains_uppercase,
|
|
102
|
-
password_contains_lowercase: obj.password_contains_lowercase,
|
|
103
|
-
password_contains_numeric: obj.password_contains_numeric,
|
|
104
|
-
password_contains_symbol: obj.password_contains_symbol,
|
|
105
|
-
password_min_length: obj.password_min_length,
|
|
106
|
-
two_factor_authentication: obj.two_factor_authentication,
|
|
107
|
-
auth_lockout_duration: obj.auth_lockout_duration,
|
|
108
|
-
auth_lockout_attempts: obj.auth_lockout_attempts,
|
|
109
|
-
access_token_expire: obj.access_token_expire,
|
|
110
|
-
}" v-if="tab == 'security'" @submit="onSubmit">
|
|
111
|
-
<q-field label="Password policy" stack-label>
|
|
112
|
-
<FormKit type="l-checkbox" label="Upper Case" name="password_contains_uppercase"
|
|
113
|
-
true-value="1" false-value="0" />
|
|
114
|
-
<FormKit type="l-checkbox" label="Lower Case" name="password_contains_lowercase"
|
|
115
|
-
true-value="1" false-value="0" />
|
|
116
|
-
<FormKit type="l-checkbox" label="Number" name="password_contains_numeric" true-value="1"
|
|
117
|
-
false-value="0" />
|
|
118
|
-
<FormKit type="l-checkbox" label="Special Character" name="password_contains_symbol"
|
|
119
|
-
true-value="1" false-value="0" />
|
|
120
|
-
</q-field>
|
|
121
|
-
|
|
122
|
-
<FormKit type="l-input" label="Password min Length" name="password_min_length"
|
|
123
|
-
validation="required|number">
|
|
124
|
-
</FormKit>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<q-field label="Two factor authentication" stack-label>
|
|
128
|
-
<FormKit type="l-checkbox" label="Enable" name="two_factor_authentication" true-value="1"
|
|
129
|
-
false-value="0" />
|
|
130
|
-
</q-field>
|
|
131
|
-
|
|
132
|
-
<FormKit label="Auth lockout duration" type="l-input" name="auth_lockout_duration"
|
|
133
|
-
hint="The number of minutes the user is locked out after the maximum number of failed login attempts. Default is 15 minutes."
|
|
134
|
-
validation="required" />
|
|
135
|
-
|
|
136
|
-
<FormKit label="Auth lockout attempts" type="l-input" name="auth_lockout_attempts"
|
|
137
|
-
hint="The number of failed login attempts before the user is locked out. Default is 5 attempts."
|
|
138
|
-
validation="required" />
|
|
139
|
-
|
|
140
|
-
<FormKit label="Access token expiration" type="l-input" name="access_token_expire"
|
|
141
|
-
hint="The access token expiration time in seconds. Default is 28800 seconds (8 hours)."
|
|
142
|
-
validation="required" />
|
|
143
|
-
</FormKit>
|
|
144
|
-
|
|
145
|
-
<FormKit type="l-form" :bordered="false" :value="{
|
|
146
|
-
file_manager: obj.file_manager,
|
|
147
|
-
revision: obj.revision
|
|
148
|
-
}" v-if="tab == 'Modules'" @submit="onSubmit">
|
|
149
|
-
<q-field label="File manager" stack-label>
|
|
150
|
-
<FormKit type="l-checkbox" label="Show" name="file_manager" true-value="1"
|
|
151
|
-
false-value="0" />
|
|
152
|
-
</q-field>
|
|
153
|
-
|
|
154
|
-
<FormKit type="l-select" label="Revision" name="revision" use-input use-chips multiple
|
|
155
|
-
hide-dropdown-icon input-debounce="0" new-value-mode="add-unique" />
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
</FormKit>
|
|
159
|
-
|
|
160
|
-
<FormKit type="l-form" :bordered="false" :value="{
|
|
161
|
-
mode: obj.mode,
|
|
162
|
-
|
|
163
|
-
}" v-if="tab == 'Developer'" @submit="onSubmit">
|
|
164
|
-
<FormKit label="Mode" type="l-select" :options="[
|
|
165
|
-
{ label: 'Production', value: 'prod' },
|
|
166
|
-
{ label: 'Development', value: 'dev' },
|
|
167
|
-
|
|
168
|
-
]" name="mode" validation="required">
|
|
169
|
-
</FormKit>
|
|
170
|
-
</FormKit>
|
|
31
|
+
<l-system-setting-general v-if="tab == 'general'" v-model="obj" />
|
|
32
|
+
<l-system-setting-mail v-if="tab == 'mail'" v-model="obj" />
|
|
33
|
+
<l-system-setting-security v-if="tab == 'security'" v-model="obj" />
|
|
34
|
+
<l-system-setting-modules v-if="tab == 'Modules'" v-model="obj" />
|
|
35
|
+
<l-system-setting-developer v-if="tab == 'developer'" v-model="obj" />
|
|
36
|
+
<l-system-setting-forget-password v-if="tab == 'forget-password'" v-model="obj" />
|
|
171
37
|
</template>
|
|
172
38
|
</q-splitter>
|
|
173
39
|
</l-card>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hostlink/nuxt-light",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "HostLink Nuxt Light Framework",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@formkit/drag-and-drop": "^0.1.6",
|
|
36
|
-
"@hostlink/light": "^2.0.
|
|
36
|
+
"@hostlink/light": "^2.0.2",
|
|
37
37
|
"@nuxt/kit": "^3.7.4",
|
|
38
38
|
"@nuxt/module-builder": "^0.8.3",
|
|
39
39
|
"@quasar/extras": "^1.16.11",
|