@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.
@@ -19,4 +19,4 @@ jobs:
19
19
  uses: cypress-io/github-action@v2
20
20
  with:
21
21
  working-directory: dev
22
- command: yarn test:e2e:ci
22
+ command: yarn test
@@ -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 mamy-auth
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 mamy-auth
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.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:e2e": "cd dev && yarn && cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress open\"",
12
- "test:e2e:ci": "cd dev && yarn && cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
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, LOCAL_CHECK_CODE_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
- !token &&
15
+ (!isValid ||
16
+ !token ) &&
17
17
  to.path !== LOCAL_LOGIN_ROUTE &&
18
- to.path !== LOCAL_CHECK_CODE_ROUTE
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-container>
4
- <q-page class="flex flex-center">
5
- <q-card square>
6
- <q-card-section>
7
- <div class="text-h5 text-center head">
8
- {{ $t("auth.title") }}
9
- </div>
10
- </q-card-section>
11
-
12
- <q-form class="q-gutter-md" @submit="onSubmit">
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
- </q-page>
110
- </q-page-container>
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
- email: emailResetPassword.value,
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
- $q.notify({
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
- $q.notify({
197
- message: t("auth.loginFailed"),
198
- color: "negative",
199
- position: "top",
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-page class="flex flex-center">
3
- <q-card square>
4
- <q-card-section>
5
- <div class="text-h5 text-center head">
6
- {{ $t("auth.passwordRecovery") }}
7
- </div>
8
- </q-card-section>
9
-
10
- <q-form class="q-gutter-md" @submit="onSubmit">
11
- <q-card-section>
12
- <q-input
13
- id="password"
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
- </q-input>
36
- </q-card-section>
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
- <q-card-actions>
39
- <q-btn
40
- rounded
41
- :label="$t('common.register')"
42
- color="primary"
43
- :loading="loading"
44
- type="submit"
45
- class="full-width"
46
- :disable="canSubmit"
47
- />
48
- </q-card-actions>
49
- </q-form>
50
- </q-card>
51
- </q-page>
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
- import { useQuasar } from "quasar";
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.newPasswordPresenceError"),
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
- .head,
119
+ @import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600&display=swap");
131
120
  .q-page {
132
- opacity: 0.7;
133
- }
134
-
135
- .q-card {
136
- width: 400px;
137
- padding: 50px;
121
+ font-family: "Montserrat", sans-serif;
138
122
  }
139
123
  </style>
@@ -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",
@@ -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",
@@ -1,5 +1,6 @@
1
1
  import { inject } from "vue";
2
2
  export interface PromptsInterface {
3
+ APP_SERVER_BASE_URL: string;
3
4
  LOCAL_LOGIN_ROUTE: string;
4
5
  LOCAL_SUCCESS_REDIRECTION_ROUTE: string;
5
6
  LOCAL_CHECK_CODE_ROUTE: string;
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
- "Vuex mutation to store user email when authenticated",
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
  };
@@ -14,6 +14,7 @@ const routes: RouteRecordRaw[] = [
14
14
  },
15
15
  {
16
16
  path: LOCAL_UPDATE_PASSWORD_ROUTE,
17
+ name:"update_password",
17
18
  // @ts-ignore
18
19
  component: () => import("@sowell/auth/pages/ResetPassword.vue"),
19
20
  },
@@ -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
- const parseJwt = JSON.parse(window.atob(value.split(".")[1]));
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
  }