@sowell/quasar-app-extension-auth 0.3.14 → 0.3.16
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/package.json +1 -1
- package/src/components/pages/AuthReporter.vue +247 -0
- package/src/composables/auth.ts +22 -3
- package/src/prompts.js +7 -0
- package/src/routes/index.ts +33 -6
package/package.json
CHANGED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<q-layout>
|
|
3
|
+
<q-page class="column items-center">
|
|
4
|
+
<div class="column short-screen">
|
|
5
|
+
<div class="column col-7 justify-center">
|
|
6
|
+
<div class="row justify-center">
|
|
7
|
+
<img
|
|
8
|
+
src="../../assets/Logo.svg"
|
|
9
|
+
class="q-mb-sm q-mr-md"
|
|
10
|
+
style="width: 27px; height: 47px"
|
|
11
|
+
/>
|
|
12
|
+
<img
|
|
13
|
+
src="../../assets/Sowell.svg"
|
|
14
|
+
class="q-mb-sm"
|
|
15
|
+
style="width: 146px; height: 38px"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="col-5">
|
|
20
|
+
<q-form @submit="onSubmit">
|
|
21
|
+
<div>
|
|
22
|
+
<div
|
|
23
|
+
class="q-ml-xs q-mb-xs"
|
|
24
|
+
style="font-size: 14px; font-weight: 600"
|
|
25
|
+
>
|
|
26
|
+
{{ $t("auth.email") }}
|
|
27
|
+
</div>
|
|
28
|
+
<q-input
|
|
29
|
+
data-cy="email"
|
|
30
|
+
v-model.trim="email"
|
|
31
|
+
type="email"
|
|
32
|
+
borderless
|
|
33
|
+
:rules="validations['email']"
|
|
34
|
+
lazy-rules
|
|
35
|
+
:input-style="{ fontSize: '14px', fontWeight: '500' }"
|
|
36
|
+
>
|
|
37
|
+
<template #prepend>
|
|
38
|
+
<q-icon :name="icons.ionMailOutline" />
|
|
39
|
+
</template>
|
|
40
|
+
</q-input>
|
|
41
|
+
</div>
|
|
42
|
+
<div>
|
|
43
|
+
<div
|
|
44
|
+
class="q-ml-xs q-mb-xs"
|
|
45
|
+
style="font-size: 14px; font-weight: 600"
|
|
46
|
+
>
|
|
47
|
+
{{ $t("auth.password") }}
|
|
48
|
+
</div>
|
|
49
|
+
<q-input
|
|
50
|
+
data-cy="password"
|
|
51
|
+
v-model="password"
|
|
52
|
+
:type="showPassword ? 'text' : 'password'"
|
|
53
|
+
:rules="validations['password']"
|
|
54
|
+
lazy-rules
|
|
55
|
+
borderless
|
|
56
|
+
dense
|
|
57
|
+
:input-style="{ fontSize: '14px', fontWeight: '600' }"
|
|
58
|
+
>
|
|
59
|
+
<template #prepend>
|
|
60
|
+
<q-icon :name="icons.ionLockClosedOutline" />
|
|
61
|
+
</template>
|
|
62
|
+
<template #append>
|
|
63
|
+
<q-icon
|
|
64
|
+
:name="
|
|
65
|
+
showPassword
|
|
66
|
+
? icons.ionEyeOffOutline
|
|
67
|
+
: icons.ionEyeOutline
|
|
68
|
+
"
|
|
69
|
+
class="cursor-pointer q-mr-sm"
|
|
70
|
+
@click="showPassword = !showPassword"
|
|
71
|
+
/>
|
|
72
|
+
</template>
|
|
73
|
+
</q-input>
|
|
74
|
+
</div>
|
|
75
|
+
<div
|
|
76
|
+
v-if="errorEmailMessage || errorPasswordMessage"
|
|
77
|
+
class="q-pl-sm text-red column justify-center error_input"
|
|
78
|
+
>
|
|
79
|
+
<div>{{ errorEmailMessage }}</div>
|
|
80
|
+
<div>{{ errorPasswordMessage }}</div>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="column items-center q-mt-lg">
|
|
83
|
+
<div class="full-width">
|
|
84
|
+
<q-btn
|
|
85
|
+
data-cy="submit-login"
|
|
86
|
+
color="primary"
|
|
87
|
+
unelevated
|
|
88
|
+
text-color="white"
|
|
89
|
+
:loading="loading"
|
|
90
|
+
type="submit"
|
|
91
|
+
class="full-width q-mt-lg"
|
|
92
|
+
:disable="isSubmitBtnDisabled()"
|
|
93
|
+
>
|
|
94
|
+
<div style="font-weight: 600; font-size: 16px">
|
|
95
|
+
{{ $t("auth.login") }}
|
|
96
|
+
</div>
|
|
97
|
+
</q-btn>
|
|
98
|
+
</div>
|
|
99
|
+
<div
|
|
100
|
+
class="q-mb-lg q-mt-lg text-primary text-center"
|
|
101
|
+
@click="forgottenPassword = true"
|
|
102
|
+
data-cy="forgot-password"
|
|
103
|
+
style="font-size: 14px; cursor: pointer; width: 350px"
|
|
104
|
+
>
|
|
105
|
+
{{ $t("auth.forgottenPassword") }}
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</q-form>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
<div>
|
|
112
|
+
<q-dialog
|
|
113
|
+
v-model="forgottenPassword"
|
|
114
|
+
full-height
|
|
115
|
+
:maximized="true"
|
|
116
|
+
transition-show="fade"
|
|
117
|
+
transition-hide="fade"
|
|
118
|
+
persistent
|
|
119
|
+
>
|
|
120
|
+
<send-email @resetPassword="resetPassword" />
|
|
121
|
+
</q-dialog>
|
|
122
|
+
<q-dialog v-model="isReset" persistent>
|
|
123
|
+
<sowell-message
|
|
124
|
+
:emailResetPassword="emailResetPassword"
|
|
125
|
+
:sendEmailSuccess="sendEmailSuccess"
|
|
126
|
+
:loading="loading"
|
|
127
|
+
@retypeEmail="retypeEmail"
|
|
128
|
+
/>
|
|
129
|
+
</q-dialog>
|
|
130
|
+
</div>
|
|
131
|
+
</q-page>
|
|
132
|
+
<q-footer class="footer">
|
|
133
|
+
<q-toolbar>
|
|
134
|
+
<q-toolbar-title>
|
|
135
|
+
<div class="row justify-end text-black text-subtitle2 version-style">
|
|
136
|
+
v{{ appVersion.versionNumber }}
|
|
137
|
+
</div>
|
|
138
|
+
</q-toolbar-title>
|
|
139
|
+
</q-toolbar>
|
|
140
|
+
</q-footer>
|
|
141
|
+
</q-layout>
|
|
142
|
+
</template>
|
|
143
|
+
|
|
144
|
+
<script lang="ts">
|
|
145
|
+
import { defineComponent, reactive, onMounted, watch } from "vue";
|
|
146
|
+
import * as packageInfo from "app/package.json";
|
|
147
|
+
import SendEmail from "../dialogs/SendEmail.vue";
|
|
148
|
+
import SowellMessage from "../dialogs/Message.vue";
|
|
149
|
+
import { useAuth } from "composables/auth";
|
|
150
|
+
|
|
151
|
+
export default defineComponent({
|
|
152
|
+
name: "Auth",
|
|
153
|
+
components: { SendEmail, SowellMessage },
|
|
154
|
+
setup() {
|
|
155
|
+
const {
|
|
156
|
+
email,
|
|
157
|
+
password,
|
|
158
|
+
loading,
|
|
159
|
+
showPassword,
|
|
160
|
+
validations,
|
|
161
|
+
errorEmailMessage,
|
|
162
|
+
errorPasswordMessage,
|
|
163
|
+
forgottenPassword,
|
|
164
|
+
emailResetPassword,
|
|
165
|
+
isReset,
|
|
166
|
+
sendEmailSuccess,
|
|
167
|
+
authState,
|
|
168
|
+
APP_SERVER_BASE_URL,
|
|
169
|
+
onSubmit,
|
|
170
|
+
retypeEmail,
|
|
171
|
+
isSubmitBtnDisabled,
|
|
172
|
+
icons,
|
|
173
|
+
} = useAuth();
|
|
174
|
+
|
|
175
|
+
const appVersion = reactive({
|
|
176
|
+
versionNumber: "",
|
|
177
|
+
});
|
|
178
|
+
const resetPassword = async (email: string) => {
|
|
179
|
+
const data = {
|
|
180
|
+
auth: {
|
|
181
|
+
email,
|
|
182
|
+
base: APP_SERVER_BASE_URL,
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
try {
|
|
186
|
+
forgottenPassword.value = false;
|
|
187
|
+
await authState.resetPassword(data).then(() => {
|
|
188
|
+
sendEmailSuccess.value = true;
|
|
189
|
+
isReset.value = true;
|
|
190
|
+
});
|
|
191
|
+
} catch {
|
|
192
|
+
sendEmailSuccess.value = false;
|
|
193
|
+
isReset.value = true;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
onMounted(() => {
|
|
198
|
+
appVersion.versionNumber = packageInfo.version;
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
email,
|
|
203
|
+
password,
|
|
204
|
+
loading,
|
|
205
|
+
showPassword,
|
|
206
|
+
validations,
|
|
207
|
+
errorEmailMessage,
|
|
208
|
+
errorPasswordMessage,
|
|
209
|
+
forgottenPassword,
|
|
210
|
+
emailResetPassword,
|
|
211
|
+
isReset,
|
|
212
|
+
sendEmailSuccess,
|
|
213
|
+
onSubmit,
|
|
214
|
+
resetPassword,
|
|
215
|
+
isSubmitBtnDisabled,
|
|
216
|
+
retypeEmail,
|
|
217
|
+
icons,
|
|
218
|
+
appVersion,
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
</script>
|
|
223
|
+
|
|
224
|
+
<style>
|
|
225
|
+
.footer {
|
|
226
|
+
background: transparent;
|
|
227
|
+
}
|
|
228
|
+
.error_input {
|
|
229
|
+
height: 48px;
|
|
230
|
+
border-radius: 4px;
|
|
231
|
+
background: #fce4e3;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
div.q-field__messages {
|
|
235
|
+
display: none;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.short-screen {
|
|
239
|
+
height: 80vh;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@media screen and (max-height: 680px) {
|
|
243
|
+
.short-screen {
|
|
244
|
+
height: 65vh;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
</style>
|
package/src/composables/auth.ts
CHANGED
|
@@ -38,12 +38,29 @@ export function useAuth() {
|
|
|
38
38
|
const isReset = ref(false);
|
|
39
39
|
const sendEmailSuccess = ref(false);
|
|
40
40
|
const emailResetPassword = ref("");
|
|
41
|
+
const errorEmailMessage = ref("");
|
|
42
|
+
const errorPasswordMessage = ref("");
|
|
41
43
|
const validations = ref({
|
|
42
44
|
email: [
|
|
43
|
-
(val: string) =>
|
|
44
|
-
|
|
45
|
+
(val: string) => {
|
|
46
|
+
errorEmailMessage.value = !!val ? "" : t("auth.emailPresenceError");
|
|
47
|
+
return !!val || t("auth.emailPresenceError");
|
|
48
|
+
},
|
|
49
|
+
(val: string) => {
|
|
50
|
+
errorEmailMessage.value = isEmail(val.trim())
|
|
51
|
+
? ""
|
|
52
|
+
: t("auth.emailValidationError");
|
|
53
|
+
return isEmail(val.trim()) || t("auth.emailValidationError");
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
password: [
|
|
57
|
+
(val: string) => {
|
|
58
|
+
errorPasswordMessage.value = !!val
|
|
59
|
+
? ""
|
|
60
|
+
: t("auth.passwordPresenceError");
|
|
61
|
+
return !!val || t("auth.passwordPresenceError");
|
|
62
|
+
},
|
|
45
63
|
],
|
|
46
|
-
password: [(val: string) => !!val || t("auth.passwordPresenceError")],
|
|
47
64
|
});
|
|
48
65
|
|
|
49
66
|
const retypeEmail = () => {
|
|
@@ -97,6 +114,8 @@ export function useAuth() {
|
|
|
97
114
|
loading,
|
|
98
115
|
showPassword,
|
|
99
116
|
validations,
|
|
117
|
+
errorEmailMessage,
|
|
118
|
+
errorPasswordMessage,
|
|
100
119
|
forgottenPassword,
|
|
101
120
|
emailResetPassword,
|
|
102
121
|
isReset,
|
package/src/prompts.js
CHANGED
|
@@ -78,6 +78,13 @@ module.exports = function () {
|
|
|
78
78
|
message: "Vuex mutation to clear token",
|
|
79
79
|
default: "auth/clear_token",
|
|
80
80
|
},
|
|
81
|
+
{
|
|
82
|
+
name: "UI_PAGE",
|
|
83
|
+
type: "input",
|
|
84
|
+
required: false,
|
|
85
|
+
message: "Login page for mobile app",
|
|
86
|
+
default: "",
|
|
87
|
+
},
|
|
81
88
|
{
|
|
82
89
|
name: "VUEX_SET_EMAIL_MUTATION",
|
|
83
90
|
type: "input",
|
package/src/routes/index.ts
CHANGED
|
@@ -3,22 +3,49 @@ import prompts from "app/quasar.extensions.json";
|
|
|
3
3
|
import { RouteRecordRaw } from "vue-router";
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
|
-
"@sowell/auth": {
|
|
6
|
+
"@sowell/auth": {
|
|
7
|
+
LOCAL_LOGIN_ROUTE,
|
|
8
|
+
LOCAL_UPDATE_PASSWORD_ROUTE,
|
|
9
|
+
X_REQUESTED_ROLES,
|
|
10
|
+
UI_PAGE,
|
|
11
|
+
},
|
|
7
12
|
} = prompts;
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
// FIXME: Utiliser le UI_PAGE pour choisir les page a utiliser pour la version web ou mobile (auth et reset password)
|
|
15
|
+
const webAuthRoles = ["superadmin", "clean_manager"];
|
|
16
|
+
|
|
17
|
+
let mobileAuthPage = "";
|
|
18
|
+
|
|
19
|
+
switch (UI_PAGE) {
|
|
20
|
+
case "mobile_clean":
|
|
21
|
+
mobileAuthPage = "Auth.vue";
|
|
22
|
+
break;
|
|
23
|
+
case "reporter":
|
|
24
|
+
mobileAuthPage = "AuthReporter.vue";
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
mobileAuthPage = "Auth.vue";
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
10
30
|
|
|
11
31
|
const routes: RouteRecordRaw[] = [
|
|
12
32
|
{
|
|
13
33
|
path: LOCAL_LOGIN_ROUTE,
|
|
14
|
-
|
|
15
|
-
|
|
34
|
+
component: () =>
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
import(
|
|
37
|
+
`@sowell/auth/pages/${
|
|
38
|
+
webAuthRoles.includes(X_REQUESTED_ROLES)
|
|
39
|
+
? "WebAuth.vue"
|
|
40
|
+
: mobileAuthPage
|
|
41
|
+
}`
|
|
42
|
+
),
|
|
16
43
|
},
|
|
17
44
|
{
|
|
18
45
|
path: LOCAL_UPDATE_PASSWORD_ROUTE,
|
|
19
|
-
name:"update_password",
|
|
20
|
-
// @ts-ignore
|
|
46
|
+
name: "update_password",
|
|
21
47
|
component: () =>
|
|
48
|
+
// @ts-ignore
|
|
22
49
|
import(
|
|
23
50
|
`@sowell/auth/pages/${
|
|
24
51
|
webAuthRoles.includes(X_REQUESTED_ROLES)
|