@sowell/quasar-app-extension-auth 0.2.2 → 0.2.6
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/.github/workflows/main.yml +1 -1
- package/.github/workflows/publish.yml +24 -0
- package/README.md +2 -2
- package/package.json +4 -3
- package/src/assets/Logo.svg +6 -0
- package/src/assets/error.svg +5 -0
- package/src/assets/success.svg +6 -0
- package/src/boot/router-guards.ts +6 -6
- package/src/components/dialogs/Message.vue +81 -0
- package/src/components/dialogs/SendEmail.vue +69 -0
- package/src/components/pages/Auth.vue +142 -126
- package/src/components/pages/ResetPassword.vue +54 -70
- package/src/i18n/en-US/index.ts +1 -0
- package/src/i18n/fr-FR/index.ts +1 -0
- package/src/injects/prompts.ts +1 -0
- package/src/prompts.js +9 -3
- package/src/routes/index.ts +1 -0
- package/src/store/index.ts +16 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: npm-publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
npm-publish:
|
|
10
|
+
name: npm-publish
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout repository
|
|
14
|
+
uses: actions/checkout@v2
|
|
15
|
+
- name: Nodejs
|
|
16
|
+
uses: actions/setup-node@v2
|
|
17
|
+
with:
|
|
18
|
+
node-version: "14"
|
|
19
|
+
cache: yarn
|
|
20
|
+
registry-url: https://registry.npmjs.org
|
|
21
|
+
- name: publish
|
|
22
|
+
run: npm publish --access public
|
|
23
|
+
env:
|
|
24
|
+
NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# Install
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
quasar ext add
|
|
11
|
+
quasar ext add @sowell/auth
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
Quasar CLI will retrieve it from NPM and install the extension.
|
|
@@ -78,7 +78,7 @@ The default is auth/getInfosUser and return email or phone number
|
|
|
78
78
|
# Uninstall
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
|
-
quasar ext remove
|
|
81
|
+
quasar ext remove @sowell/auth
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
# Info
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sowell/quasar-app-extension-auth",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
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",
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
"lint": "cd dev && eslint --ext .js,.ts,.vue ./",
|
|
9
9
|
"dev": "cd dev && quasar dev",
|
|
10
10
|
"dep": "cd dev && yarn",
|
|
11
|
-
"test:
|
|
12
|
-
"test:
|
|
11
|
+
"test:link": "cd dev && yarn test:link",
|
|
12
|
+
"test:browser": "cd dev && yarn test:browser",
|
|
13
|
+
"test": "cd dev && yarn test"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [],
|
|
15
16
|
"author": "SoWell SAS",
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="39.779" height="70.275" viewBox="0 0 39.779 70.275">
|
|
2
|
+
<g id="Logo_Sowell_bleu" data-name="Logo Sowell bleu" transform="translate(-403.55 -422.444)">
|
|
3
|
+
<path id="Tracé_455" data-name="Tracé 455" d="M440.01,457.9l-9.08-19.791a4,4,0,0,0-5.243-2.083h0a4,4,0,0,0-2.083,5.243l4.939,11.466a19.894,19.894,0,0,0-20.414,6.519,4.349,4.349,0,0,0-.21,1.945c0,2.45,2.091,4.11,4.578,4.11a4.524,4.524,0,0,0,3.021-1.149c1.98-1.693,5.1-3.689,7.905-3.689a11.327,11.327,0,1,1-11.3,12.2c.065-1.637.144-2.7.144-2.7a4.326,4.326,0,0,0-8.417-1.406l-.018-.009c-.006.039-.012.078-.019.118a4.317,4.317,0,0,0-.2,1.3c0,.072,0,.149.006.223q-.072.862-.076,1.74a19.814,19.814,0,0,0,5.441,13.66l14.429,19.43,15.461-20.608h0a21.785,21.785,0,0,0,4.413-12.484C443.729,465.218,440.01,457.9,440.01,457.9Z" transform="translate(0 -12.306)" fill="#40c4ff"/>
|
|
4
|
+
<path id="Tracé_456" data-name="Tracé 456" d="M802.618,443.124l-.884-17.044a4,4,0,0,0-4.326-3.622h0a3.985,3.985,0,0,0-2.968,1.771Z" transform="translate(-362.817 0)" fill="#40c4ff"/>
|
|
5
|
+
</g>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg id="noun_Error_1688921" xmlns="http://www.w3.org/2000/svg" width="63" height="63" viewBox="0 0 63 63">
|
|
2
|
+
<circle id="Ellipse_90" data-name="Ellipse 90" cx="31.5" cy="31.5" r="31.5" fill="#f2d7d7"/>
|
|
3
|
+
<path id="Tracé_727" data-name="Tracé 727" d="M14.477,29.163h0A4.078,4.078,0,0,1,10.5,25.186V9.277A4.078,4.078,0,0,1,14.477,5.3h0a4.078,4.078,0,0,1,3.977,3.977V25.186A4.078,4.078,0,0,1,14.477,29.163Z" transform="translate(17.34 8.753)" fill="#ce0101"/>
|
|
4
|
+
<path id="Tracé_728" data-name="Tracé 728" d="M14.477,23.654h0A4.078,4.078,0,0,1,10.5,19.677h0A4.078,4.078,0,0,1,14.477,15.7h0a4.078,4.078,0,0,1,3.977,3.977h0A4.078,4.078,0,0,1,14.477,23.654Z" transform="translate(17.34 25.927)" fill="#ce0101"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="62" height="62" viewBox="0 0 62 62">
|
|
2
|
+
<g id="noun_validation_1683882" transform="translate(0.1 -0.4)">
|
|
3
|
+
<circle id="Ellipse_89" data-name="Ellipse 89" cx="31" cy="31" r="31" transform="translate(-0.1 0.4)" fill="#dff2d6"/>
|
|
4
|
+
<path id="Tracé_724" data-name="Tracé 724" d="M36.165,13.221a1.189,1.189,0,0,0-1.868.311L21.84,31.906l-8.253-8.253a1.169,1.169,0,0,0-1.868.156,1.667,1.667,0,0,0,.156,2.18l9.5,9.342h0c.156.156.156.156.311.156a.152.152,0,0,1,.156.156c.156,0,.311.156.623.156h0c.156,0,.467,0,.467-.156l.156-.156c.156,0,.156-.156.311-.156h0L36.632,15.713A2.752,2.752,0,0,0,36.165,13.221Z" transform="translate(6.399 6.953)" fill="#3b9843"/>
|
|
5
|
+
</g>
|
|
6
|
+
</svg>
|
|
@@ -5,17 +5,17 @@ import { BootInterface } from "../interfaces";
|
|
|
5
5
|
|
|
6
6
|
export default boot(({ router, store }: BootInterface) => {
|
|
7
7
|
const {
|
|
8
|
-
"@sowell/auth": { LOCAL_LOGIN_ROUTE
|
|
8
|
+
"@sowell/auth": { LOCAL_LOGIN_ROUTE },
|
|
9
9
|
} = prompts;
|
|
10
10
|
|
|
11
11
|
router.beforeEach((to, from, next) => {
|
|
12
|
-
let isValid = store.getters["token/getIsValid"]
|
|
13
|
-
let token = store.getters["token/getRaw"]
|
|
12
|
+
let isValid = store.getters["token/getIsValid"];
|
|
13
|
+
let token = store.getters["token/getRaw"];
|
|
14
14
|
if (
|
|
15
|
-
!isValid
|
|
16
|
-
|
|
15
|
+
(!isValid ||
|
|
16
|
+
!token ) &&
|
|
17
17
|
to.path !== LOCAL_LOGIN_ROUTE &&
|
|
18
|
-
to.
|
|
18
|
+
to.name !== "update_password"
|
|
19
19
|
) {
|
|
20
20
|
next(LOCAL_LOGIN_ROUTE);
|
|
21
21
|
} else {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<q-card style="min-width: 350px; border-radius: 30px">
|
|
3
|
+
<q-toolbar>
|
|
4
|
+
<q-space />
|
|
5
|
+
<q-btn
|
|
6
|
+
class="q-pt-md"
|
|
7
|
+
flat
|
|
8
|
+
dense
|
|
9
|
+
color="primary"
|
|
10
|
+
icon="close"
|
|
11
|
+
v-close-popup
|
|
12
|
+
/>
|
|
13
|
+
</q-toolbar>
|
|
14
|
+
<q-card-section class="text-center">
|
|
15
|
+
<img v-if="sendEmailSuccess" src="../../assets/success.svg" />
|
|
16
|
+
<img v-else src="../../assets/error.svg" />
|
|
17
|
+
</q-card-section>
|
|
18
|
+
|
|
19
|
+
<q-card-section class="q-pt-none q-pl-lg q-pr-lg">
|
|
20
|
+
<div
|
|
21
|
+
class="text-subtitle1 q-mt-sm text-center"
|
|
22
|
+
style="font-size: 14px; font-weigth: 300; line-height: 20px"
|
|
23
|
+
data-cy="resetMessage"
|
|
24
|
+
>
|
|
25
|
+
{{
|
|
26
|
+
sendEmailSuccess ? $t("auth.emailSent") : $t("auth.emailNotRecognize")
|
|
27
|
+
}}
|
|
28
|
+
</div>
|
|
29
|
+
<div
|
|
30
|
+
class="q-mt-sm text-center q-mb-xl"
|
|
31
|
+
style="font-size: 15px; color: #737676"
|
|
32
|
+
v-if="sendEmailSuccess"
|
|
33
|
+
>
|
|
34
|
+
{{ emailResetPassword }}
|
|
35
|
+
</div>
|
|
36
|
+
</q-card-section>
|
|
37
|
+
<q-card-actions class="q-ml-lg q-mr-lg q-mb-lg">
|
|
38
|
+
<q-btn
|
|
39
|
+
v-if="!sendEmailSuccess"
|
|
40
|
+
data-cy="submit-login"
|
|
41
|
+
rounded
|
|
42
|
+
:label="$t('auth.reSend')"
|
|
43
|
+
color="primary"
|
|
44
|
+
padding="10px 5px 10px 5px"
|
|
45
|
+
:loading="loading"
|
|
46
|
+
no-caps
|
|
47
|
+
type="submit"
|
|
48
|
+
@click="reSendEmail"
|
|
49
|
+
class="full-width"
|
|
50
|
+
/>
|
|
51
|
+
</q-card-actions>
|
|
52
|
+
</q-card>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script lang="ts">
|
|
56
|
+
import { defineComponent } from "vue";
|
|
57
|
+
|
|
58
|
+
export default defineComponent({
|
|
59
|
+
props: {
|
|
60
|
+
emailResetPassword: {
|
|
61
|
+
type: String,
|
|
62
|
+
required: true,
|
|
63
|
+
},
|
|
64
|
+
sendEmailSuccess: {
|
|
65
|
+
type: Boolean,
|
|
66
|
+
required: true,
|
|
67
|
+
},
|
|
68
|
+
loading: {
|
|
69
|
+
type: Boolean,
|
|
70
|
+
required: true,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
emit: ["resetPassword"],
|
|
74
|
+
setup(props: any, { emit }: any) {
|
|
75
|
+
const reSendEmail = () => {
|
|
76
|
+
emit("reSendEmail");
|
|
77
|
+
};
|
|
78
|
+
return { reSendEmail };
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
</script>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<q-card style="min-width: 350px; border-radius: 30px">
|
|
3
|
+
<q-toolbar>
|
|
4
|
+
<q-space />
|
|
5
|
+
<q-btn
|
|
6
|
+
class="q-pt-md"
|
|
7
|
+
flat
|
|
8
|
+
dense
|
|
9
|
+
color="primary"
|
|
10
|
+
icon="close"
|
|
11
|
+
v-close-popup
|
|
12
|
+
/>
|
|
13
|
+
</q-toolbar>
|
|
14
|
+
<q-card-section>
|
|
15
|
+
<p
|
|
16
|
+
class="resetPasswordTitle text-center"
|
|
17
|
+
style="font-size: 20px; font-weigth: 600"
|
|
18
|
+
>
|
|
19
|
+
{{ $t("auth.tapEmail") }}
|
|
20
|
+
</p>
|
|
21
|
+
</q-card-section>
|
|
22
|
+
|
|
23
|
+
<q-card-section class="q-pt-none q-pl-lg q-pr-lg">
|
|
24
|
+
<q-input
|
|
25
|
+
v-model="email"
|
|
26
|
+
dense
|
|
27
|
+
outlined
|
|
28
|
+
data-cy="emailReset"
|
|
29
|
+
:placeholder="$t('auth.email')"
|
|
30
|
+
autofocus
|
|
31
|
+
/>
|
|
32
|
+
<div
|
|
33
|
+
class="text-subtitle1 q-mt-sm"
|
|
34
|
+
style="font-size: 13px; font-weigth: 300; line-height: 20px"
|
|
35
|
+
>
|
|
36
|
+
{{ $t("auth.resetText") }}
|
|
37
|
+
</div>
|
|
38
|
+
</q-card-section>
|
|
39
|
+
|
|
40
|
+
<q-card-actions align="center" class="q-ml-lg q-mr-lg q-mb-lg">
|
|
41
|
+
<q-btn
|
|
42
|
+
rounded
|
|
43
|
+
color="primary"
|
|
44
|
+
data-cy="sendEmails"
|
|
45
|
+
no-caps
|
|
46
|
+
:label="$t('common.reset')"
|
|
47
|
+
class="btn-min full-width"
|
|
48
|
+
@click="sendEmail"
|
|
49
|
+
v-close-popup
|
|
50
|
+
/>
|
|
51
|
+
</q-card-actions>
|
|
52
|
+
</q-card>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script lang="ts">
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
import { defineComponent, ref } from "vue";
|
|
58
|
+
|
|
59
|
+
export default defineComponent({
|
|
60
|
+
emit: ["resetPassword"],
|
|
61
|
+
setup(props: any, { emit }: any) {
|
|
62
|
+
const email = ref("");
|
|
63
|
+
const sendEmail = () => {
|
|
64
|
+
emit("resetPassword", email.value);
|
|
65
|
+
};
|
|
66
|
+
return { sendEmail, email };
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
@@ -1,138 +1,122 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<q-layout>
|
|
3
|
-
<q-page-
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
<q-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<q-card-section>
|
|
14
|
-
<q-input
|
|
15
|
-
data-cy="email"
|
|
16
|
-
v-model.trim="email"
|
|
17
|
-
type="email"
|
|
18
|
-
:label="$t('auth.email')"
|
|
19
|
-
:rules="validations['email']"
|
|
20
|
-
lazy-rules
|
|
21
|
-
autofocus
|
|
22
|
-
rounded
|
|
23
|
-
outlined
|
|
24
|
-
dense
|
|
25
|
-
class="full-width q-mb-md"
|
|
26
|
-
/>
|
|
27
|
-
<q-input
|
|
28
|
-
data-cy="password"
|
|
29
|
-
v-model="password"
|
|
30
|
-
:type="showPassword ? 'text' : 'password'"
|
|
31
|
-
:label="$t('auth.password')"
|
|
32
|
-
:rules="validations['password']"
|
|
33
|
-
lazy-rules
|
|
34
|
-
rounded
|
|
35
|
-
outlined
|
|
36
|
-
dense
|
|
37
|
-
class="full-width q-mb-md"
|
|
38
|
-
>
|
|
39
|
-
<template #append>
|
|
40
|
-
<q-icon
|
|
41
|
-
:name="showPassword ? 'visibility' : 'visibility_off'"
|
|
42
|
-
class="cursor-pointer"
|
|
43
|
-
@click="showPassword = !showPassword"
|
|
44
|
-
/>
|
|
45
|
-
</template>
|
|
46
|
-
</q-input>
|
|
47
|
-
</q-card-section>
|
|
48
|
-
<div class="forgottenPass">
|
|
49
|
-
<q-btn
|
|
50
|
-
@click="forgottenPassword = true"
|
|
51
|
-
no-caps
|
|
52
|
-
flat
|
|
53
|
-
:label="$t('auth.forgottenPassword')"
|
|
54
|
-
/>
|
|
55
|
-
</div>
|
|
56
|
-
<q-card-actions>
|
|
57
|
-
<q-btn
|
|
58
|
-
data-cy="submit-login"
|
|
59
|
-
rounded
|
|
60
|
-
:label="$t('auth.login')"
|
|
61
|
-
color="primary"
|
|
62
|
-
:loading="loading"
|
|
63
|
-
type="submit"
|
|
64
|
-
class="full-width"
|
|
65
|
-
:disable="isSubmitBtnDisabled()"
|
|
66
|
-
/>
|
|
67
|
-
</q-card-actions>
|
|
68
|
-
</q-form>
|
|
69
|
-
</q-card>
|
|
70
|
-
<div>
|
|
71
|
-
<q-dialog v-model="forgottenPassword" persistent>
|
|
72
|
-
<q-card style="min-width: 350px">
|
|
73
|
-
<q-card-section>
|
|
74
|
-
<p class="resetPasswordTitle">
|
|
75
|
-
{{ $t("auth.tapEmail") }}
|
|
76
|
-
</p>
|
|
77
|
-
</q-card-section>
|
|
78
|
-
|
|
79
|
-
<q-card-section class="q-pt-none">
|
|
80
|
-
<q-input
|
|
81
|
-
v-model="emailResetPassword"
|
|
82
|
-
dense
|
|
83
|
-
rounded
|
|
84
|
-
outlined
|
|
85
|
-
:placeholder="$t('auth.email')"
|
|
86
|
-
autofocus
|
|
87
|
-
/>
|
|
88
|
-
</q-card-section>
|
|
89
|
-
|
|
90
|
-
<q-card-actions align="right">
|
|
91
|
-
<q-btn
|
|
92
|
-
outline
|
|
93
|
-
rounded
|
|
94
|
-
:label="$t('common.cancel')"
|
|
95
|
-
class="btn-min"
|
|
96
|
-
v-close-popup
|
|
97
|
-
/>
|
|
98
|
-
<q-btn
|
|
99
|
-
rounded
|
|
100
|
-
color="primary"
|
|
101
|
-
:label="$t('common.send')"
|
|
102
|
-
class="btn-min"
|
|
103
|
-
@click="resetPassword"
|
|
104
|
-
/>
|
|
105
|
-
</q-card-actions>
|
|
106
|
-
</q-card>
|
|
107
|
-
</q-dialog>
|
|
3
|
+
<q-page class="column justify-center items-center">
|
|
4
|
+
<div class="q-pa-xl">
|
|
5
|
+
<div class="column justify-ceter">
|
|
6
|
+
<img src="../../assets/Logo.svg" class="q-mb-sm" />
|
|
7
|
+
<div class="text-subtitle1 text-center head" style="font-weight: 600">
|
|
8
|
+
{{ $t("auth.title") }}
|
|
9
|
+
</div>
|
|
10
|
+
<div class="q-mt-xl q-mb-lg text-subtitle1" style="font-size: 14px">
|
|
11
|
+
{{ $t("auth.loginHelp") }}
|
|
12
|
+
</div>
|
|
108
13
|
</div>
|
|
109
|
-
|
|
110
|
-
|
|
14
|
+
<q-form @submit="onSubmit">
|
|
15
|
+
<q-input
|
|
16
|
+
data-cy="email"
|
|
17
|
+
v-model.trim="email"
|
|
18
|
+
type="email"
|
|
19
|
+
:label="$t('auth.email')"
|
|
20
|
+
:rules="validations['email']"
|
|
21
|
+
lazy-rules
|
|
22
|
+
dense
|
|
23
|
+
:input-style="{ fontSize: '14px', fontWeight: '500' }"
|
|
24
|
+
/>
|
|
25
|
+
<q-input
|
|
26
|
+
data-cy="password"
|
|
27
|
+
v-model="password"
|
|
28
|
+
:type="showPassword ? 'text' : 'password'"
|
|
29
|
+
:label="$t('auth.password')"
|
|
30
|
+
:rules="validations['password']"
|
|
31
|
+
lazy-rules
|
|
32
|
+
dense
|
|
33
|
+
:input-style="{ fontSize: '14px', fontWeight: '600' }"
|
|
34
|
+
>
|
|
35
|
+
<template #append>
|
|
36
|
+
<q-icon
|
|
37
|
+
:name="showPassword ? 'visibility' : 'visibility_off'"
|
|
38
|
+
class="cursor-pointer"
|
|
39
|
+
@click="showPassword = !showPassword"
|
|
40
|
+
/>
|
|
41
|
+
</template>
|
|
42
|
+
</q-input>
|
|
43
|
+
<div
|
|
44
|
+
class="q-mb-xl"
|
|
45
|
+
@click="forgottenPassword = true"
|
|
46
|
+
data-cy="forgot-password"
|
|
47
|
+
style="color: #40c4ff; font-weight: 500; cursor: pointer"
|
|
48
|
+
>
|
|
49
|
+
{{ $t("auth.forgottenPassword") }}
|
|
50
|
+
</div>
|
|
51
|
+
<q-btn
|
|
52
|
+
data-cy="submit-login"
|
|
53
|
+
rounded
|
|
54
|
+
:label="$t('auth.login')"
|
|
55
|
+
style="background: #40c4ff"
|
|
56
|
+
no-caps
|
|
57
|
+
text-color="white"
|
|
58
|
+
:loading="loading"
|
|
59
|
+
type="submit"
|
|
60
|
+
class="full-width q-mt-lg"
|
|
61
|
+
:disable="isSubmitBtnDisabled()"
|
|
62
|
+
/>
|
|
63
|
+
</q-form>
|
|
64
|
+
</div>
|
|
65
|
+
<div>
|
|
66
|
+
<q-dialog v-model="forgottenPassword" persistent>
|
|
67
|
+
<send-email @resetPassword="resetPassword" />
|
|
68
|
+
</q-dialog>
|
|
69
|
+
<q-dialog v-model="isReset" persistent>
|
|
70
|
+
<sowell-message
|
|
71
|
+
:emailResetPassword="emailResetPassword"
|
|
72
|
+
:sendEmailSuccess="sendEmailSuccess"
|
|
73
|
+
:loading="loading"
|
|
74
|
+
@reSendEmail="resetPassword"
|
|
75
|
+
/>
|
|
76
|
+
</q-dialog>
|
|
77
|
+
</div>
|
|
78
|
+
</q-page>
|
|
111
79
|
</q-layout>
|
|
112
80
|
</template>
|
|
113
81
|
|
|
114
82
|
<script lang="ts">
|
|
115
|
-
//import prompts from "app/quasar.extensions.json";
|
|
116
83
|
import isEmail from "validator/es/lib/isEmail";
|
|
117
84
|
import { defineComponent, ref, onMounted } from "vue";
|
|
118
85
|
import { $api, $prompts, $router, $store } from "../../injects";
|
|
119
86
|
import { useQuasar } from "quasar";
|
|
120
87
|
import { useI18n } from "vue-i18n";
|
|
121
88
|
import { AxiosError, AxiosResponse } from "axios";
|
|
89
|
+
import prompts from "app/quasar.extensions.json";
|
|
90
|
+
import SendEmail from "../dialogs/SendEmail.vue";
|
|
91
|
+
import SowellMessage from "../dialogs/Message.vue";
|
|
92
|
+
|
|
93
|
+
interface HeadersInterface {
|
|
94
|
+
headers: {
|
|
95
|
+
"x-requested-roles"?: string
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
122
99
|
export default defineComponent({
|
|
123
100
|
name: "Auth",
|
|
101
|
+
components: { SendEmail, SowellMessage },
|
|
124
102
|
setup() {
|
|
103
|
+
const {
|
|
104
|
+
"@sowell/auth": { X_REQUESTED_ROLES },
|
|
105
|
+
} = prompts;
|
|
125
106
|
const email = ref("");
|
|
126
107
|
const password = ref("");
|
|
127
108
|
const loading = ref(false);
|
|
128
109
|
const showPassword = ref(false);
|
|
129
110
|
const forgottenPassword = ref(false);
|
|
111
|
+
const isReset = ref(false);
|
|
112
|
+
const sendEmailSuccess = ref(false);
|
|
130
113
|
const emailResetPassword = ref("");
|
|
131
114
|
const { post } = $api();
|
|
132
115
|
const {
|
|
133
116
|
LOCAL_SUCCESS_REDIRECTION_ROUTE,
|
|
134
117
|
AUTH_SERVER_SIGNING_ROUTE,
|
|
135
118
|
AUTH_SERVER_RESET_PASSWORD_ROUTE,
|
|
119
|
+
APP_SERVER_BASE_URL,
|
|
136
120
|
} = $prompts();
|
|
137
121
|
const $q = useQuasar();
|
|
138
122
|
const { push, replace } = $router();
|
|
@@ -153,26 +137,22 @@ export default defineComponent({
|
|
|
153
137
|
password: [(val: string) => !!val || t("auth.passwordPresenceError")],
|
|
154
138
|
});
|
|
155
139
|
|
|
156
|
-
const resetPassword = () => {
|
|
140
|
+
const resetPassword = (email: string) => {
|
|
157
141
|
const data = {
|
|
158
|
-
|
|
142
|
+
auth: {
|
|
143
|
+
email,
|
|
144
|
+
base: APP_SERVER_BASE_URL,
|
|
145
|
+
},
|
|
159
146
|
};
|
|
160
147
|
|
|
161
148
|
post(AUTH_SERVER_RESET_PASSWORD_ROUTE, data)
|
|
162
149
|
.then(() => {
|
|
163
|
-
$q.notify({
|
|
164
|
-
message: t("auth.emailSent"),
|
|
165
|
-
color: "positive",
|
|
166
|
-
position: "top",
|
|
167
|
-
});
|
|
168
150
|
forgottenPassword.value = false;
|
|
151
|
+
isReset.value = true;
|
|
152
|
+
sendEmailSuccess.value = true;
|
|
169
153
|
})
|
|
170
154
|
.catch(() => {
|
|
171
|
-
|
|
172
|
-
message: t("auth.emailNotRecognize"),
|
|
173
|
-
color: "negative",
|
|
174
|
-
position: "top",
|
|
175
|
-
});
|
|
155
|
+
isReset.value = true;
|
|
176
156
|
});
|
|
177
157
|
};
|
|
178
158
|
|
|
@@ -184,8 +164,14 @@ export default defineComponent({
|
|
|
184
164
|
password: password.value,
|
|
185
165
|
},
|
|
186
166
|
};
|
|
167
|
+
const options: HeadersInterface = {
|
|
168
|
+
headers:{}
|
|
169
|
+
};
|
|
170
|
+
// @ts-ignore
|
|
171
|
+
let requestedRoles = window.Cypress ? window.Cypress.requestedRoles : X_REQUESTED_ROLES;
|
|
172
|
+
if (requestedRoles) options.headers["x-requested-roles"] = requestedRoles;
|
|
187
173
|
|
|
188
|
-
post(AUTH_SERVER_SIGNING_ROUTE, data)
|
|
174
|
+
post(AUTH_SERVER_SIGNING_ROUTE, data, options)
|
|
189
175
|
.then((response: AxiosResponse) => {
|
|
190
176
|
const token = response.data.jwt;
|
|
191
177
|
dispatch("token/updateRaw", token);
|
|
@@ -193,11 +179,31 @@ export default defineComponent({
|
|
|
193
179
|
})
|
|
194
180
|
.catch((error: AxiosError) => {
|
|
195
181
|
loading.value = false;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
182
|
+
switch (error.response?.status) {
|
|
183
|
+
case 403:
|
|
184
|
+
$q.notify({
|
|
185
|
+
message: t("auth.403"),
|
|
186
|
+
color: "negative",
|
|
187
|
+
position: "top",
|
|
188
|
+
});
|
|
189
|
+
console.log('403')
|
|
190
|
+
break;
|
|
191
|
+
case 404:
|
|
192
|
+
$q.notify({
|
|
193
|
+
message: t("auth.404"),
|
|
194
|
+
color: "negative",
|
|
195
|
+
position: "top",
|
|
196
|
+
});
|
|
197
|
+
console.log('404')
|
|
198
|
+
break;
|
|
199
|
+
default:
|
|
200
|
+
$q.notify({
|
|
201
|
+
message: t("auth.loginFailed"),
|
|
202
|
+
color: "negative",
|
|
203
|
+
position: "top",
|
|
204
|
+
});
|
|
205
|
+
console.log('default')
|
|
206
|
+
}
|
|
201
207
|
});
|
|
202
208
|
};
|
|
203
209
|
|
|
@@ -221,7 +227,17 @@ export default defineComponent({
|
|
|
221
227
|
forgottenPassword,
|
|
222
228
|
emailResetPassword,
|
|
223
229
|
resetPassword,
|
|
230
|
+
isReset,
|
|
231
|
+
sendEmailSuccess,
|
|
224
232
|
};
|
|
225
233
|
},
|
|
226
234
|
});
|
|
227
235
|
</script>
|
|
236
|
+
|
|
237
|
+
<style scoped>
|
|
238
|
+
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600&display=swap");
|
|
239
|
+
|
|
240
|
+
.q-page {
|
|
241
|
+
font-family: "Montserrat", sans-serif;
|
|
242
|
+
}
|
|
243
|
+
</style>
|
|
@@ -1,59 +1,59 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<q-
|
|
3
|
-
<q-
|
|
4
|
-
<
|
|
5
|
-
<div class="
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
v-model="password"
|
|
15
|
-
type="password"
|
|
16
|
-
:label="$t('auth.newPassword')"
|
|
17
|
-
:rules="validations['passwordRules']"
|
|
18
|
-
rounded
|
|
19
|
-
outlined
|
|
20
|
-
dense
|
|
21
|
-
class="full-width q-mb-md"
|
|
22
|
-
>
|
|
23
|
-
</q-input>
|
|
24
|
-
<q-input
|
|
25
|
-
id="passwordConfirmation"
|
|
26
|
-
v-model="passwordConfirmation"
|
|
27
|
-
type="password"
|
|
28
|
-
:label="$t('auth.newPasswordConfirmation')"
|
|
29
|
-
:rules="validations['passwordConfirmationRules']"
|
|
30
|
-
rounded
|
|
31
|
-
outlined
|
|
32
|
-
dense
|
|
33
|
-
class="full-width q-mb-md"
|
|
2
|
+
<q-layout>
|
|
3
|
+
<q-page class="flex flex-center">
|
|
4
|
+
<div>
|
|
5
|
+
<div class="column items-center q-mb-xl">
|
|
6
|
+
<img
|
|
7
|
+
style="width: 40px"
|
|
8
|
+
src="../../assets/Logo.svg"
|
|
9
|
+
class="q-mb-sm"
|
|
10
|
+
/>
|
|
11
|
+
<div
|
|
12
|
+
class="text-h5 text-center head q-mt-sm"
|
|
13
|
+
style="font-size: 17px; font-weight: 500"
|
|
34
14
|
>
|
|
35
|
-
|
|
36
|
-
|
|
15
|
+
{{ $t("auth.passwordRecovery") }}
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
<q-form class="column items-center" @submit="onSubmit">
|
|
19
|
+
<div>
|
|
20
|
+
<div class="q-mb-sm" style="font-size: 14px; font-weight: 400">
|
|
21
|
+
{{ $t("auth.newPassword") }}
|
|
22
|
+
</div>
|
|
23
|
+
<q-input
|
|
24
|
+
id="password"
|
|
25
|
+
v-model="password"
|
|
26
|
+
data-cy="reset-password"
|
|
27
|
+
:rules="validations['passwordRules']"
|
|
28
|
+
outlined
|
|
29
|
+
dense
|
|
30
|
+
class="full-width q-mb-md"
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
34
|
+
<div class="full-width">
|
|
35
|
+
<q-btn
|
|
36
|
+
rounded
|
|
37
|
+
:label="$t('common.register')"
|
|
38
|
+
color="primary"
|
|
39
|
+
:loading="loading"
|
|
40
|
+
type="submit"
|
|
41
|
+
no-caps
|
|
42
|
+
data-cy="send-new-password"
|
|
43
|
+
class="full-width"
|
|
44
|
+
:disable="canSubmit"
|
|
45
|
+
/>
|
|
46
|
+
</div>
|
|
47
|
+
</q-form>
|
|
48
|
+
</div>
|
|
49
|
+
</q-page>
|
|
50
|
+
</q-layout>
|
|
52
51
|
</template>
|
|
53
52
|
|
|
54
53
|
<script lang="ts">
|
|
55
|
-
|
|
54
|
+
//@ts-ignore
|
|
56
55
|
import { computed, defineComponent, ref } from "vue";
|
|
56
|
+
import { useQuasar } from "quasar";
|
|
57
57
|
import { useI18n } from "vue-i18n";
|
|
58
58
|
import { useRouter } from "vue-router";
|
|
59
59
|
import { $api, $prompts } from "../../injects";
|
|
@@ -70,31 +70,21 @@ export default defineComponent({
|
|
|
70
70
|
const $q = useQuasar();
|
|
71
71
|
const router = useRouter();
|
|
72
72
|
const password = ref("");
|
|
73
|
-
const passwordConfirmation = ref("");
|
|
74
73
|
const loading = ref(false);
|
|
75
74
|
const { t } = useI18n();
|
|
76
75
|
|
|
77
|
-
const canSubmit = computed(() =>
|
|
78
|
-
return password.value != "" &&
|
|
79
|
-
password.value === passwordConfirmation.value
|
|
80
|
-
? false
|
|
81
|
-
: true;
|
|
82
|
-
});
|
|
76
|
+
const canSubmit = computed(() => password.value.length < 6);
|
|
83
77
|
|
|
84
78
|
const validations = {
|
|
85
79
|
passwordRules: [
|
|
86
|
-
(val: string) => !!val || t("auth.
|
|
87
|
-
|
|
88
|
-
passwordConfirmationRules: [
|
|
89
|
-
(val: string) =>
|
|
90
|
-
val === password.value || t("auth.newPasswordConfirmationFailed"),
|
|
80
|
+
(val: string) => !!val || t("auth.passwordPresenceError"),
|
|
81
|
+
(val: string) => val.length >= 6 || t("auth.passwordLengthError"),
|
|
91
82
|
],
|
|
92
83
|
};
|
|
93
84
|
|
|
94
85
|
const onSubmit = () => {
|
|
95
86
|
const data = {
|
|
96
87
|
password: password.value,
|
|
97
|
-
password_confirmation: passwordConfirmation.value,
|
|
98
88
|
};
|
|
99
89
|
patch(AUTH_SERVER_UPDATE_PASSWORD_ROUTE, data)
|
|
100
90
|
.then(() => {
|
|
@@ -116,7 +106,6 @@ export default defineComponent({
|
|
|
116
106
|
|
|
117
107
|
return {
|
|
118
108
|
password,
|
|
119
|
-
passwordConfirmation,
|
|
120
109
|
validations,
|
|
121
110
|
loading,
|
|
122
111
|
onSubmit,
|
|
@@ -127,13 +116,8 @@ export default defineComponent({
|
|
|
127
116
|
</script>
|
|
128
117
|
|
|
129
118
|
<style scoped>
|
|
130
|
-
.
|
|
119
|
+
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600&display=swap");
|
|
131
120
|
.q-page {
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.q-card {
|
|
136
|
-
width: 400px;
|
|
137
|
-
padding: 50px;
|
|
121
|
+
font-family: "Montserrat", sans-serif;
|
|
138
122
|
}
|
|
139
123
|
</style>
|
package/src/i18n/en-US/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export default {
|
|
|
14
14
|
emailSent: "Email sent, check your inbox",
|
|
15
15
|
tapEmail: "Please enter your email",
|
|
16
16
|
404: "No user found with the provided credentials",
|
|
17
|
+
403: "Insufficient rights, your account does not allow access to this interface",
|
|
17
18
|
},
|
|
18
19
|
common: {
|
|
19
20
|
register: "Save",
|
package/src/i18n/fr-FR/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export default {
|
|
|
14
14
|
emailSent: "Email envoyé, vérifier votre boite email",
|
|
15
15
|
tapEmail: "Entrer votre email",
|
|
16
16
|
404: "Aucun utilisateur trouvé avec les identifiants donnés",
|
|
17
|
+
403: "Droits insuffisants, votre compte ne permet pas d'acceder à cette interface",
|
|
17
18
|
},
|
|
18
19
|
common: {
|
|
19
20
|
register: "Enregistre",
|
package/src/injects/prompts.ts
CHANGED
package/src/prompts.js
CHANGED
|
@@ -82,9 +82,8 @@ module.exports = function () {
|
|
|
82
82
|
name: "VUEX_SET_EMAIL_MUTATION",
|
|
83
83
|
type: "input",
|
|
84
84
|
required: true,
|
|
85
|
-
message:
|
|
86
|
-
|
|
87
|
-
default: "auth/set_email_user"
|
|
85
|
+
message: "Vuex mutation to store user email when authenticated",
|
|
86
|
+
default: "auth/set_email_user",
|
|
88
87
|
},
|
|
89
88
|
{
|
|
90
89
|
name: "VUEX_SET_INFOS_USER_MUTATION",
|
|
@@ -107,5 +106,12 @@ module.exports = function () {
|
|
|
107
106
|
message: "Vuex getter user information",
|
|
108
107
|
default: "auth/get_infos_user",
|
|
109
108
|
},
|
|
109
|
+
{
|
|
110
|
+
name: "X_REQUESTED_ROLES",
|
|
111
|
+
type: "input",
|
|
112
|
+
required: true,
|
|
113
|
+
message: "Role required for the application",
|
|
114
|
+
default: "",
|
|
115
|
+
},
|
|
110
116
|
];
|
|
111
117
|
};
|
package/src/routes/index.ts
CHANGED
package/src/store/index.ts
CHANGED
|
@@ -34,13 +34,28 @@ const mutations: MutationTree<tokenStateInterface> = {
|
|
|
34
34
|
},
|
|
35
35
|
setPayload(state, value: payload) {
|
|
36
36
|
state.payload = {...value}
|
|
37
|
+
},
|
|
38
|
+
reset(state) {
|
|
39
|
+
state.raw = ""
|
|
40
|
+
state.payload = {
|
|
41
|
+
company_hp: undefined,
|
|
42
|
+
exp: undefined,
|
|
43
|
+
gm_key: "",
|
|
44
|
+
roles: [],
|
|
45
|
+
sub: null
|
|
46
|
+
}
|
|
37
47
|
}
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
const actions: ActionTree<tokenStateInterface, any> = {
|
|
41
51
|
updateRaw({ commit }, value: string) {
|
|
42
52
|
commit("setRaw", value);
|
|
43
|
-
|
|
53
|
+
let parseJwt: string
|
|
54
|
+
try {
|
|
55
|
+
parseJwt = JSON.parse(window.atob(value.split(".")[1]));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
parseJwt = ""
|
|
58
|
+
}
|
|
44
59
|
commit("setPayload", parseJwt)
|
|
45
60
|
}
|
|
46
61
|
}
|