@sowell/quasar-app-extension-auth 1.10.1 → 1.11.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/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sowell/quasar-app-extension-auth",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"description": "A Quasar app extension to manage Authentication",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": "https://github.com/sowell-ai/quasar.extension.auth",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"lint": "
|
|
8
|
+
"lint": "eslint --ext .js,.ts,.vue ./",
|
|
9
9
|
"dev": "cd dev && quasar dev",
|
|
10
10
|
"dep": "cd dev && yarn",
|
|
11
11
|
"test:link": "cd dev && yarn test:link",
|
|
12
12
|
"test:browser": "cd dev && yarn test:browser",
|
|
13
|
-
"test": "
|
|
13
|
+
"test": "vitest run"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [],
|
|
16
16
|
"author": "SoWell SAS",
|
|
@@ -34,7 +34,10 @@
|
|
|
34
34
|
"eslint-plugin-vue": "^7.0.0",
|
|
35
35
|
"jwt-decode": "^3.1.2",
|
|
36
36
|
"quasar": "^2.8.4",
|
|
37
|
-
"typescript": "^4.4.2"
|
|
37
|
+
"typescript": "^4.4.2",
|
|
38
|
+
"vitest": "^4.1.11",
|
|
39
|
+
"vue": "^3.2.0",
|
|
40
|
+
"vue-i18n": "^9"
|
|
38
41
|
},
|
|
39
42
|
"directories": {
|
|
40
43
|
"test": "test"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
alt="Background logo"
|
|
12
12
|
/>
|
|
13
13
|
</div>
|
|
14
|
-
<div class="row justify-between items-center full-width q-px-lg
|
|
14
|
+
<div class="row justify-between items-center full-width q-px-lg top-bar">
|
|
15
15
|
<div
|
|
16
16
|
class="row items-center back-link"
|
|
17
17
|
data-testid="restricted-back-btn"
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
|
|
63
63
|
<div
|
|
64
64
|
v-else
|
|
65
|
-
class="row justify-center full-height q-pl-sm q-pr-sm"
|
|
65
|
+
class="row justify-center full-height q-pl-sm q-pr-sm send-email-form"
|
|
66
66
|
style="background: #f4f5f6"
|
|
67
67
|
data-testid="ask-password-change-form"
|
|
68
68
|
>
|
|
@@ -107,6 +107,9 @@
|
|
|
107
107
|
<q-input
|
|
108
108
|
data-testid="email-input"
|
|
109
109
|
v-model="email"
|
|
110
|
+
type="email"
|
|
111
|
+
autocapitalize="off"
|
|
112
|
+
autocorrect="off"
|
|
110
113
|
dense
|
|
111
114
|
borderless
|
|
112
115
|
bg-color="white"
|
|
@@ -247,9 +250,18 @@ export default defineComponent({
|
|
|
247
250
|
max-height: 100vh;
|
|
248
251
|
}
|
|
249
252
|
|
|
253
|
+
/* Ce composant s'affiche dans un q-dialog. Sur iOS, Quasar (q-ios-padding)
|
|
254
|
+
décale déjà .q-dialog__inner sous la barre d'état : on ne lit donc PAS
|
|
255
|
+
env(), sinon le décalage serait doublé. --safe-area-inset-top n'est
|
|
256
|
+
injectée que par Capacitor SystemBars sur Android (edge-to-edge, 15+). */
|
|
250
257
|
.top-bar {
|
|
251
258
|
z-index: 1;
|
|
252
259
|
max-width: 430px;
|
|
260
|
+
padding-top: calc(24px + var(--safe-area-inset-top, 0px));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.send-email-form {
|
|
264
|
+
padding-top: var(--safe-area-inset-top, 0px);
|
|
253
265
|
}
|
|
254
266
|
|
|
255
267
|
.back-link {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
class="background-logo"
|
|
9
9
|
alt="Background logo" />
|
|
10
10
|
</div>
|
|
11
|
-
<div class="row justify-between items-center full-width q-px-lg
|
|
11
|
+
<div class="row justify-between items-center full-width q-px-lg top-bar">
|
|
12
12
|
<div
|
|
13
13
|
class="row items-center back-link"
|
|
14
14
|
data-testid="back-btn"
|
|
@@ -424,6 +424,11 @@ export default defineComponent({
|
|
|
424
424
|
.top-bar {
|
|
425
425
|
z-index: 1;
|
|
426
426
|
max-width: 430px;
|
|
427
|
+
/* 24px = ancien q-pt-lg. Sur iOS (viewport-fit=cover), la page n'a pas de
|
|
428
|
+
q-header : le padding iOS de Quasar ne s'applique pas, on ajoute donc la
|
|
429
|
+
safe-area ici. --safe-area-inset-top est injectée par SystemBars sur
|
|
430
|
+
Android ; env() vaut 0 sur le web. */
|
|
431
|
+
padding-top: calc(24px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px)));
|
|
427
432
|
}
|
|
428
433
|
|
|
429
434
|
.back-link {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
class="background-logo"
|
|
9
9
|
alt="Background logo" />
|
|
10
10
|
</div>
|
|
11
|
-
<div class="row justify-between items-center full-width q-px-lg
|
|
11
|
+
<div class="row justify-between items-center full-width q-px-lg top-bar">
|
|
12
12
|
<div
|
|
13
13
|
class="row items-center back-link"
|
|
14
14
|
data-testid="back-btn"
|
|
@@ -317,6 +317,11 @@ export default defineComponent({
|
|
|
317
317
|
.top-bar {
|
|
318
318
|
z-index: 1;
|
|
319
319
|
max-width: 430px;
|
|
320
|
+
/* 24px = ancien q-pt-lg. Sur iOS (viewport-fit=cover), la page n'a pas de
|
|
321
|
+
q-header : le padding iOS de Quasar ne s'applique pas, on ajoute donc la
|
|
322
|
+
safe-area ici. --safe-area-inset-top est injectée par SystemBars sur
|
|
323
|
+
Android ; env() vaut 0 sur le web. */
|
|
324
|
+
padding-top: calc(24px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px)));
|
|
320
325
|
}
|
|
321
326
|
|
|
322
327
|
.back-link {
|
|
@@ -124,6 +124,9 @@ export function useMagicLink() {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
const requestChannels = async () => {
|
|
127
|
+
// Quasar's `loading` does not disable the button: Enter would resubmit and send
|
|
128
|
+
// a second e-mail, invalidating the first link (the API replaces the token).
|
|
129
|
+
if (isLoading.value) return
|
|
127
130
|
apiErrorMessage.value = ""
|
|
128
131
|
if (!validateEmail()) return
|
|
129
132
|
isLoading.value = true
|
|
@@ -138,14 +141,21 @@ export function useMagicLink() {
|
|
|
138
141
|
channels.value = offered.length ? offered : ["email"]
|
|
139
142
|
channelTargets.value = targets
|
|
140
143
|
selectedChannel.value = "email"
|
|
144
|
+
// Nothing to choose when only e-mail is offered (user without phone, or an
|
|
145
|
+
// app restricted to e-mail): send the link straight away.
|
|
146
|
+
if (channels.value.length === 1 && channels.value[0] === "email") {
|
|
147
|
+
await sendMagicLink("email")
|
|
148
|
+
return
|
|
149
|
+
}
|
|
141
150
|
step.value = "channel"
|
|
142
151
|
} catch (error) {
|
|
143
152
|
const axiosError = error as AxiosError
|
|
144
153
|
if (axiosError.response?.status === 403) {
|
|
145
|
-
// Backend check:
|
|
146
|
-
// rescued as Rescueable::Forbidden with i18n key
|
|
147
|
-
// No pre-flight signal exists
|
|
148
|
-
//
|
|
154
|
+
// Backend check: the user's company (or its master/slaves) has
|
|
155
|
+
// `no_password_reset` set, rescued as Rescueable::Forbidden with i18n key
|
|
156
|
+
// errors.magiclink.forbidden. No pre-flight signal exists on the front, so
|
|
157
|
+
// it only finds out by attempting the call, hence no button hiding. The
|
|
158
|
+
// same 403 can come from the automatic send in requestChannels.
|
|
149
159
|
restricted.value = true
|
|
150
160
|
restrictedMessage.value = readApiError(error) || ""
|
|
151
161
|
} else if (axiosError.response?.status === 404) {
|