@sowell/quasar-app-extension-auth 0.2.0 → 0.2.4

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.
Files changed (48) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc.js +13 -13
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/main.yml +22 -0
  5. package/README.md +378 -10
  6. package/package.json +35 -19
  7. package/src/assets/Logo.svg +6 -0
  8. package/src/boot/axios.ts +17 -0
  9. package/src/boot/register.ts +8 -0
  10. package/src/boot/router-guards.ts +25 -0
  11. package/src/boot/router.ts +20 -0
  12. package/src/boot/store.ts +10 -0
  13. package/src/components/pages/Auth.vue +265 -0
  14. package/src/components/pages/ResetPassword.vue +123 -0
  15. package/src/i18n/en-US/index.ts +24 -0
  16. package/src/i18n/fr-FR/index.ts +24 -0
  17. package/src/i18n/index.ts +7 -0
  18. package/src/index.js +29 -25
  19. package/src/injects/api.ts +10 -0
  20. package/src/injects/index.ts +4 -0
  21. package/src/injects/prompts.ts +25 -0
  22. package/src/injects/router.ts +10 -0
  23. package/src/injects/store.ts +10 -0
  24. package/src/interfaces/Boot.ts +8 -0
  25. package/src/interfaces/TokenStateInterface.ts +11 -0
  26. package/src/interfaces/index.ts +2 -0
  27. package/src/prompts.js +42 -38
  28. package/src/routes/index.ts +23 -0
  29. package/src/shims-vue.d.ts +6 -0
  30. package/src/store/index.ts +66 -0
  31. package/tsconfig.json +14 -0
  32. package/.github/workflows/publish.yml +0 -22
  33. package/.prettierrc +0 -7
  34. package/.vscode/extensions.json +0 -12
  35. package/.vscode/settings.json +0 -22
  36. package/jsconfig.json +0 -7
  37. package/package-lock.json +0 -2344
  38. package/src/boot/axios.js +0 -17
  39. package/src/boot/navigation-guards.js +0 -16
  40. package/src/boot/register.js +0 -45
  41. package/src/components/Auth.vue +0 -279
  42. package/src/components/ResetCode.vue +0 -140
  43. package/src/components/ResetPassword.vue +0 -139
  44. package/src/components/prompt.js +0 -40
  45. package/src/config/setupHeaders.js +0 -6
  46. package/src/install.js +0 -10
  47. package/src/templates/.gitkeep +0 -0
  48. package/src/uninstall.js +0 -10
package/src/boot/axios.js DELETED
@@ -1,17 +0,0 @@
1
- import axios from "axios"
2
- // FIXME: find another way to call this path
3
- import prompts from "../../../../../quasar.extensions.json"
4
- import { headers } from "setupHeaders"
5
-
6
- const {
7
- "@sowell/auth": { auth_server_base_url }
8
- } = prompts
9
-
10
- const api = axios.create({
11
- baseURL: auth_server_base_url,
12
- headers: headers
13
- })
14
-
15
- export default ({ app }) => {
16
- app.provide("api", api)
17
- }
@@ -1,16 +0,0 @@
1
- // FIXME: find another way to call this path
2
- import prompts from "../../../../../quasar.extensions.json"
3
-
4
- export default ({ router, store }) => {
5
- const { "@sowell/auth": { local_login_route, local_check_code_route }} = prompts
6
- router.beforeEach((to, from, next) => {
7
- const isAuthenticated = store.state.auth.token !== null ? true : false
8
- if (!isAuthenticated && to.path !== local_login_route && to.path !== local_check_code_route) {
9
- next(local_login_route)
10
- }
11
- else {
12
- next()
13
-
14
- }
15
- })
16
- }
@@ -1,45 +0,0 @@
1
- import { boot } from "quasar/wrappers"
2
-
3
- // FIXME: find another way to call this path
4
- import prompts from "../../../../../quasar.extensions.json"
5
- import { i18n } from "../../../../../src/boot/i18n.js"
6
-
7
- export default boot(({ app, router }) => {
8
- let { routes } = router.options
9
- let routeData = routes.find((r) => r.path === "/")
10
- app.provide("prompts", prompts)
11
- app.provide("i18n", i18n.global)
12
-
13
- const {
14
- "@sowell/auth": {
15
- local_login_route,
16
- local_check_code_route,
17
- local_update_password_route
18
- }
19
- } = prompts
20
-
21
- const currentRoutes = routeData.children.map((route) => route.path)
22
-
23
- const newRoutes = [
24
- {
25
- path: local_login_route,
26
- component: () => import("../components/Auth")
27
- },
28
- {
29
- path: local_check_code_route,
30
- component: () => import("../components/ResetCode")
31
- },
32
- {
33
- path: local_update_password_route,
34
- component: () => import("../components/ResetPassword")
35
- }
36
- ]
37
-
38
- routeData.children = []
39
- for (let route of newRoutes) {
40
- if (!currentRoutes.includes(route.path)) {
41
- routeData.children.push(route)
42
- }
43
- }
44
- router.addRoute(routeData)
45
- })
@@ -1,279 +0,0 @@
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.title") }}
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="email"
14
- v-model.trim="emailOrPhone"
15
- type="email"
16
- :label="$t('auth.email')"
17
- :rules="validations['emailOrPhone']"
18
- lazy-rules
19
- autofocus
20
- rounded
21
- outlined
22
- dense
23
- class="full-width q-mb-md"
24
- />
25
- <q-input
26
- id="password"
27
- v-model="password"
28
- :type="showPassword ? 'text' : 'password'"
29
- :label="$t('auth.password')"
30
- :rules="validations['password']"
31
- lazy-rules
32
- rounded
33
- outlined
34
- dense
35
- class="full-width q-mb-md"
36
- >
37
- <template #append>
38
- <q-icon
39
- :name="showPassword ? 'visibility' : 'visibility_off'"
40
- class="cursor-pointer"
41
- @click="showPassword = !showPassword"
42
- />
43
- </template>
44
- </q-input>
45
- </q-card-section>
46
- <div class="forgottenPass">
47
- <q-btn
48
- @click="forgottenPassword = true"
49
- no-caps
50
- flat
51
- :label="$t('auth.forgottenPassword')"
52
- />
53
- </div>
54
- <q-card-actions>
55
- <q-btn
56
- rounded
57
- :label="$t('auth.login')"
58
- color="primary"
59
- :loading="loading"
60
- type="submit"
61
- class="full-width"
62
- />
63
- </q-card-actions>
64
- </q-form>
65
- </q-card>
66
- <div>
67
- <q-dialog v-model="forgottenPassword" persistent>
68
- <q-card style="min-width: 350px">
69
- <q-card-section>
70
- <p class="resetPasswordTitle">
71
- {{ $t("auth.tapEmail") }}
72
- </p>
73
- </q-card-section>
74
-
75
- <q-card-section class="q-pt-none">
76
- <q-input
77
- v-model="emailResetPassword"
78
- dense
79
- rounded
80
- outlined
81
- :placeholder="$t('auth.email')"
82
- autofocus
83
- />
84
- </q-card-section>
85
-
86
- <q-card-actions align="right">
87
- <q-btn
88
- outline
89
- rounded
90
- :label="$t('common.cancel')"
91
- class="btn-min"
92
- v-close-popup
93
- />
94
- <q-btn
95
- rounded
96
- color="primary"
97
- :label="$t('common.send')"
98
- class="btn-min"
99
- @click="resetPassword"
100
- />
101
- </q-card-actions>
102
- </q-card>
103
- </q-dialog>
104
- </div>
105
- </q-page>
106
- </template>
107
-
108
- <script>
109
- import { useStore } from "vuex"
110
- import { useQuasar } from "quasar"
111
- import { useRouter } from "vue-router"
112
- import { ref, onMounted, defineComponent, inject } from "vue"
113
- import isEmail from "validator/es/lib/isEmail"
114
- import prompts from "./prompt.js"
115
-
116
- export default defineComponent({
117
- name: "Auth",
118
-
119
- setup() {
120
- const i18n = inject("i18n")
121
- const api = inject("api")
122
- const {
123
- local_success_redirection_route,
124
- local_check_code_route,
125
- auth_server_signing_route,
126
- auth_server_reset_password_route,
127
- auth_type,
128
- vuex_set_token_mutation,
129
- vuex_set_email_or_phonenumber_user_mutation,
130
- vuex_clear_token_mutation,
131
- vuex_set_infos_user_mutation,
132
- vuex_get_token_getter
133
- } = prompts()
134
- const store = useStore()
135
- const $q = useQuasar()
136
- const router = useRouter()
137
- const phoneRegex = /\+.[0-9]/
138
- const emailOrPhone = ref("")
139
- const password = ref("")
140
- const loading = ref(false)
141
- const showPassword = ref(false)
142
- const forgottenPassword = ref(false)
143
- const emailResetPassword = ref("")
144
-
145
- onMounted(() => {
146
- if (store.state.auth.token) {
147
- router.replace(local_success_redirection_route)
148
- }
149
- })
150
-
151
- const validations = {
152
- emailOrPhone: [
153
- (val) => !!val || i18n.t("auth.emailPresenceError"),
154
- (val) =>
155
- isEmail(val) ||
156
- phoneRegex.test(val) ||
157
- i18n.t("auth.emailValidationError")
158
- ],
159
- password: [(val) => !!val || i18n.t("auth.passwordPresenceError")]
160
- }
161
-
162
- const resetPassword = async () => {
163
- let data = null
164
- if (isEmail(emailResetPassword.value)) {
165
- store.commit(vuex_set_infos_user_mutation, emailResetPassword.value)
166
- data = {
167
- email: emailResetPassword.value
168
- }
169
- } else if (phoneRegex.test(emailResetPassword.value)) {
170
- store.commit(vuex_set_infos_user_mutation, emailResetPassword.value)
171
- data = {
172
- phone_number: emailResetPassword.value
173
- }
174
- }
175
- await api
176
- .post(auth_server_reset_password_route, data)
177
- .then(() => {
178
- $q.notify({
179
- message: i18n.t("auth.emailSent"),
180
- color: "positive",
181
- position: "top"
182
- })
183
- router.push(local_check_code_route)
184
- })
185
- .catch(() => {
186
- $q.notify({
187
- message: i18n("auth.emailNotRecognize"),
188
- color: "negative",
189
- position: "top"
190
- })
191
- })
192
- }
193
-
194
- const onSubmit = async () => {
195
- loading.value = true
196
- let data = null
197
- if (isEmail(emailOrPhone.value)) {
198
- data = {
199
- email: emailOrPhone.value,
200
- password: password.value
201
- }
202
- } else if (phoneRegex.test(emailOrPhone.value)) {
203
- data = {
204
- phone_number: emailOrPhone.value,
205
- password: password.value
206
- }
207
- }
208
- await api
209
- .post(auth_server_signing_route, data)
210
- .then(async function (response) {
211
- const { data } = response
212
- if (response.status == "201") {
213
- store.commit(vuex_set_token_mutation, data.token)
214
- store.commit(
215
- vuex_set_email_or_phonenumber_user_mutation,
216
- emailOrPhone
217
- )
218
- api.defaults.headers.Authorization = `${auth_type} ${store.getters[vuex_get_token_getter]}`
219
- router.push(local_success_redirection_route)
220
- } else {
221
- store.commit(vuex_clear_token_mutation)
222
- api.defaults.headers.Authorization = ""
223
- }
224
- loading.value = false
225
- })
226
- .catch(() => {
227
- loading.value = false
228
- store.commit(vuex_clear_token_mutation)
229
- $q.notify({
230
- message: i18n.t("auth.loginFailed"),
231
- color: "negative",
232
- position: "top"
233
- })
234
- })
235
- }
236
-
237
- return {
238
- emailOrPhone,
239
- password,
240
- loading,
241
- showPassword,
242
- validations,
243
- onSubmit,
244
- forgottenPassword,
245
- emailResetPassword,
246
- resetPassword
247
- }
248
- }
249
- })
250
- </script>
251
-
252
- <style scoped>
253
- .head,
254
- .q-page {
255
- opacity: 0.7;
256
- }
257
-
258
- .q-card {
259
- width: 400px;
260
- padding: 50px;
261
- }
262
-
263
- .forgottenPass {
264
- margin-top: 0 !important;
265
- margin-left: 25px !important;
266
- cursor: pointer;
267
- color: #40c4ff;
268
- }
269
-
270
- .resetPasswordTitle {
271
- opacity: 0.7;
272
- text-align: center;
273
- font-size: 20px;
274
- }
275
-
276
- .btn-min {
277
- min-width: 100px !important;
278
- }
279
- </style>
@@ -1,140 +0,0 @@
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.secretCodeTitle") }}
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="codeSecret"
14
- v-model="code"
15
- :rules="validations['code']"
16
- type="text"
17
- :label="$t('auth.secretCode')"
18
- lazy-rules
19
- rounded
20
- outlined
21
- dense
22
- class="full-width q-mb-md"
23
- >
24
- </q-input>
25
- </q-card-section>
26
-
27
- <q-card-actions>
28
- <q-btn
29
- rounded
30
- :label="$t('common.send')"
31
- color="primary"
32
- :loading="loading"
33
- type="submit"
34
- class="full-width"
35
- />
36
- </q-card-actions>
37
- </q-form>
38
- </q-card>
39
- </q-page>
40
- </template>
41
-
42
- <script>
43
- import { ref, onMounted, defineComponent, inject } from "vue"
44
- import { useStore } from "vuex"
45
- import { useQuasar } from "quasar"
46
- import { useRouter } from "vue-router"
47
- import isEmail from "validator/es/lib/isEmail"
48
- import prompts from "./prompt.js"
49
-
50
- export default defineComponent({
51
- name: "ResetCode",
52
-
53
- setup() {
54
- const i18n = inject("i18n")
55
- const api = inject("api")
56
- const store = useStore()
57
- const $q = useQuasar()
58
- const router = useRouter()
59
- const phoneRegex = /\+.[0-9]/
60
- const code = ref("")
61
- const loading = ref(false)
62
- const {
63
- auth_server_signing_route,
64
- local_update_password_route,
65
- auth_type,
66
- local_success_redirection_route,
67
- vuex_set_token_mutation,
68
- vuex_set_email_or_phonenumber_user_mutation,
69
- vuex_get_token_getter,
70
- vuex_get_infos_user_getter
71
- } = prompts()
72
-
73
- const validations = {
74
- code: [(val) => !!val || i18n.t("auth.secretCodePresenceError")]
75
- }
76
-
77
- onMounted(() => {
78
- if (store.state.auth.token) {
79
- router.replace(local_success_redirection_route)
80
- }
81
- })
82
-
83
- async function onSubmit() {
84
- let data = {}
85
- const emailOrPhoneNumber = await store.getters[vuex_get_infos_user_getter]
86
- if (isEmail(emailOrPhoneNumber)) {
87
- data = {
88
- email: emailOrPhoneNumber,
89
- password_recovery_code: code.value
90
- }
91
- } else if (phoneRegex.text(emailOrPhoneNumber)) {
92
- data = {
93
- phone_number: emailOrPhoneNumber,
94
- password_recovery_code: code.value
95
- }
96
- }
97
-
98
- api
99
- .post(auth_server_signing_route, data)
100
- .then(({ data }) => {
101
- $q.notify({
102
- message: i18n.t("auth.secretCodeSuccess"),
103
- color: "positive",
104
- position: "top"
105
- })
106
- store.commit(vuex_set_token_mutation, data.token)
107
- store.commit(vuex_set_email_or_phonenumber_user_mutation, email)
108
- api.defaults.headers.Authorization = `${auth_type} ${store.getters[vuex_get_token_getter]}`
109
- router.push(local_update_password_route)
110
- })
111
- .catch(() => {
112
- $q.notify({
113
- message: i18n.t("auth.secretCodeFailed"),
114
- color: "negative",
115
- position: "top"
116
- })
117
- })
118
- }
119
-
120
- return {
121
- code,
122
- loading,
123
- validations,
124
- onSubmit
125
- }
126
- }
127
- })
128
- </script>
129
-
130
- <style scoped>
131
- .head,
132
- .q-page {
133
- opacity: 0.7;
134
- }
135
-
136
- .q-card {
137
- width: 400px;
138
- padding: 50px;
139
- }
140
- </style>
@@ -1,139 +0,0 @@
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"
34
- >
35
- </q-input>
36
- </q-card-section>
37
-
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>
52
- </template>
53
-
54
- <script>
55
- import { ref, defineComponent, computed, inject } from "vue"
56
- import { useQuasar } from "quasar"
57
- import { useRouter } from "vue-router"
58
- import prompts from "./prompt.js"
59
-
60
- export default defineComponent({
61
- name: "ResetPassword",
62
-
63
- setup() {
64
- const i18n = inject("i18n")
65
- const api = inject("api")
66
- const {
67
- auth_server_update_password_route,
68
- local_success_redirection_route
69
- } = prompts()
70
- const $q = useQuasar()
71
- const router = useRouter()
72
- const password = ref("")
73
- const passwordConfirmation = ref("")
74
- const loading = ref(false)
75
-
76
- const canSubmit = computed(() => {
77
- return password.value != "" &&
78
- password.value === passwordConfirmation.value
79
- ? false
80
- : true
81
- })
82
-
83
- const validations = {
84
- passwordRules: [
85
- (val) => !!val || i18n.t("auth.newPasswordPresenceError")
86
- ],
87
- passwordConfirmationRules: [
88
- (val) =>
89
- val === password.value || i18n.t("auth.newPasswordConfirmationFailed")
90
- ]
91
- }
92
-
93
- function onSubmit() {
94
- const data = {
95
- password: password.value,
96
- password_confirmation: passwordConfirmation.value
97
- }
98
- api
99
- .patch(auth_server_update_password_route, data)
100
- .then(() => {
101
- $q.notify({
102
- message: i18n.t("auth.passwordRecoverySuccess"),
103
- color: "positive",
104
- position: "top"
105
- })
106
- router.push(local_success_redirection_route)
107
- })
108
- .catch(() => {
109
- $q.notify({
110
- message: i18n.t("auth.passwordRecoveryFailed"),
111
- color: "negative",
112
- position: "top"
113
- })
114
- })
115
- }
116
-
117
- return {
118
- password,
119
- passwordConfirmation,
120
- validations,
121
- loading,
122
- onSubmit,
123
- canSubmit
124
- }
125
- }
126
- })
127
- </script>
128
-
129
- <style scoped>
130
- .head,
131
- .q-page {
132
- opacity: 0.7;
133
- }
134
-
135
- .q-card {
136
- width: 400px;
137
- padding: 50px;
138
- }
139
- </style>
@@ -1,40 +0,0 @@
1
- import { inject } from "vue"
2
- export default function prompts() {
3
- const {
4
- "@sowell/auth": {
5
- local_login_route,
6
- local_success_redirection_route,
7
- local_check_code_route,
8
- local_update_password_route,
9
- auth_server_base_url,
10
- auth_server_signing_route,
11
- auth_server_reset_password_route,
12
- auth_server_update_password_route,
13
- auth_type,
14
- vuex_set_token_mutation,
15
- vuex_set_email_or_phonenumber_user_mutation,
16
- vuex_clear_token_mutation,
17
- vuex_set_infos_user_mutation,
18
- vuex_get_token_getter,
19
- vuex_get_infos_user_getter
20
- }
21
- } = inject("prompts")
22
-
23
- return {
24
- local_login_route,
25
- local_success_redirection_route,
26
- local_check_code_route,
27
- local_update_password_route,
28
- auth_server_base_url,
29
- auth_server_signing_route,
30
- auth_server_reset_password_route,
31
- auth_server_update_password_route,
32
- auth_type,
33
- vuex_set_token_mutation,
34
- vuex_set_email_or_phonenumber_user_mutation,
35
- vuex_clear_token_mutation,
36
- vuex_set_infos_user_mutation,
37
- vuex_get_token_getter,
38
- vuex_get_infos_user_getter
39
- }
40
- }
@@ -1,6 +0,0 @@
1
- let headers = null
2
- const setup_headers = (payload) => {
3
- headers = payload
4
- }
5
-
6
- export { setup_headers, headers }
package/src/install.js DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * Quasar App Extension install script
3
- *
4
- * Docs: https://quasar.dev/app-extensions/development-guide/install-api
5
- * API: https://github.com/quasarframework/quasar/blob/master/app/lib/app-extension/InstallAPI.js
6
- */
7
-
8
- module.exports = function () {
9
- //
10
- }
File without changes