@sowell/quasar-app-extension-auth 0.2.6 → 0.2.7
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/README.md +1 -1
- package/package.json +1 -1
- package/src/components/pages/Auth.vue +1 -0
- package/src/components/pages/ResetPassword.vue +121 -17
- package/src/prompts.js +2 -2
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
no-caps
|
|
42
42
|
data-cy="send-new-password"
|
|
43
43
|
class="full-width"
|
|
44
|
-
:disable="canSubmit"
|
|
44
|
+
:disable="!canSubmit"
|
|
45
45
|
/>
|
|
46
46
|
</div>
|
|
47
47
|
</q-form>
|
|
@@ -52,50 +52,111 @@
|
|
|
52
52
|
|
|
53
53
|
<script lang="ts">
|
|
54
54
|
//@ts-ignore
|
|
55
|
-
import { computed, defineComponent, ref } from "vue";
|
|
55
|
+
import { computed, defineComponent, ref, Ref, onMounted } from "vue";
|
|
56
56
|
import { useQuasar } from "quasar";
|
|
57
57
|
import { useI18n } from "vue-i18n";
|
|
58
|
-
import {
|
|
59
|
-
import
|
|
58
|
+
import { $api, $prompts, $router } from "../../injects";
|
|
59
|
+
import jwt from 'jwt-decode'
|
|
60
|
+
import { Buffer } from 'buffer'
|
|
61
|
+
|
|
62
|
+
interface DecodedToken { // FIXME: consider to move to its own file
|
|
63
|
+
sub: number,
|
|
64
|
+
email: string,
|
|
65
|
+
token: string
|
|
66
|
+
}
|
|
60
67
|
|
|
61
68
|
export default defineComponent({
|
|
62
69
|
name: "ResetPassword",
|
|
63
70
|
|
|
64
71
|
setup() {
|
|
65
|
-
const { patch } = $api();
|
|
72
|
+
const { patch, post } = $api();
|
|
66
73
|
const {
|
|
74
|
+
AUTH_SERVER_SIGNING_ROUTE,
|
|
67
75
|
AUTH_SERVER_UPDATE_PASSWORD_ROUTE,
|
|
68
|
-
|
|
76
|
+
LOCAL_LOGIN_ROUTE,
|
|
69
77
|
} = $prompts();
|
|
70
78
|
const $q = useQuasar();
|
|
71
|
-
const router =
|
|
79
|
+
const router = $router()
|
|
80
|
+
const $route = router.currentRoute.value
|
|
72
81
|
const password = ref("");
|
|
73
82
|
const loading = ref(false);
|
|
74
83
|
const { t } = useI18n();
|
|
75
84
|
|
|
76
|
-
const
|
|
85
|
+
const token = ref("")
|
|
86
|
+
|
|
87
|
+
const decodedToken = computed(() => {
|
|
88
|
+
if (!token.value) return null
|
|
89
|
+
return jwt(token.value) as DecodedToken
|
|
90
|
+
}) as Ref<DecodedToken | null>
|
|
91
|
+
|
|
92
|
+
const canSubmit = computed(() => {
|
|
93
|
+
return decodedToken.value !== null && password.value.length >= 6
|
|
94
|
+
});
|
|
77
95
|
|
|
78
96
|
const validations = {
|
|
79
97
|
passwordRules: [
|
|
80
98
|
(val: string) => !!val || t("auth.passwordPresenceError"),
|
|
81
|
-
(val: string) => val.length >= 6 || t("auth.passwordLengthError")
|
|
99
|
+
(val: string) => val.length >= 6 || t("auth.passwordLengthError")
|
|
100
|
+
],
|
|
101
|
+
passwordConfirmationRules: [
|
|
102
|
+
(val: string) =>
|
|
103
|
+
val === password.value || t("auth.newPasswordConfirmationFailed"),
|
|
104
|
+
(val: string) => !!val || t("auth.resetPasswordPresenceError"),
|
|
105
|
+
(val: string) => val.length >= 6 || t("auth.resetPasswordLengthError"),
|
|
82
106
|
],
|
|
83
107
|
};
|
|
84
108
|
|
|
109
|
+
const decodeKey = (key: string) => {
|
|
110
|
+
try {
|
|
111
|
+
const decodedKey = Buffer.from(key, "base64").toString("utf-8").split(',')
|
|
112
|
+
if (decodedKey.length !== 2) {
|
|
113
|
+
throw 'Invalid encoded key'
|
|
114
|
+
}
|
|
115
|
+
console.log('decodedKey', decodedKey)
|
|
116
|
+
const email = decodedKey[0].replace('{', '').split(':')[1]
|
|
117
|
+
const tmpToken = decodedKey[1].replace('}', '').split(':')[1]
|
|
118
|
+
return {
|
|
119
|
+
decoded: true,
|
|
120
|
+
email,
|
|
121
|
+
tmpToken
|
|
122
|
+
}
|
|
123
|
+
} catch (err) {
|
|
124
|
+
console.log('decodeKey err', err)
|
|
125
|
+
return {
|
|
126
|
+
decoded: false
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
85
131
|
const onSubmit = () => {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
132
|
+
const updatePasswordPayload = {
|
|
133
|
+
data: {
|
|
134
|
+
type: "users",
|
|
135
|
+
id: decodedToken.value.sub,
|
|
136
|
+
attributes:
|
|
137
|
+
{
|
|
138
|
+
password: password.value
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const updatePasswordHeaders = {
|
|
143
|
+
headers: {
|
|
144
|
+
'Authorization': `Bearer ${token.value}`
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
patch(
|
|
149
|
+
AUTH_SERVER_UPDATE_PASSWORD_ROUTE.replace(':userId', String(decodedToken.value.sub)),
|
|
150
|
+
updatePasswordPayload,
|
|
151
|
+
updatePasswordHeaders
|
|
152
|
+
).then(() => {
|
|
91
153
|
$q.notify({
|
|
92
154
|
message: t("auth.passwordRecoverySuccess"),
|
|
93
155
|
color: "positive",
|
|
94
156
|
position: "top",
|
|
95
157
|
});
|
|
96
|
-
router.push(
|
|
97
|
-
})
|
|
98
|
-
.catch(() => {
|
|
158
|
+
router.push(LOCAL_LOGIN_ROUTE);
|
|
159
|
+
}).catch(() => {
|
|
99
160
|
$q.notify({
|
|
100
161
|
message: t("auth.passwordRecoveryFailed"),
|
|
101
162
|
color: "negative",
|
|
@@ -104,6 +165,49 @@ export default defineComponent({
|
|
|
104
165
|
});
|
|
105
166
|
};
|
|
106
167
|
|
|
168
|
+
onMounted(() => {
|
|
169
|
+
let key = $route.query.key as string
|
|
170
|
+
const { decoded, email, tmpToken } = decodeKey(key)
|
|
171
|
+
|
|
172
|
+
if (!decoded) {
|
|
173
|
+
return $q.notify({
|
|
174
|
+
message: t("auth.passwordRecoveryInvalidLink"),
|
|
175
|
+
color: "negative",
|
|
176
|
+
position: "top",
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const tmpAuthPayload = {
|
|
181
|
+
auth: {
|
|
182
|
+
email: email,
|
|
183
|
+
token: tmpToken
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
post(AUTH_SERVER_SIGNING_ROUTE, tmpAuthPayload)
|
|
188
|
+
.then((response) => {
|
|
189
|
+
token.value = response.data.jwt
|
|
190
|
+
if (!token.value) throw 'Error reading the temporary token'
|
|
191
|
+
})
|
|
192
|
+
.catch((error) => {
|
|
193
|
+
if (error.response) {
|
|
194
|
+
// Request made and server responded
|
|
195
|
+
if (error.response.status === 404) {
|
|
196
|
+
return $q.notify({
|
|
197
|
+
message: t("auth.passwordRecoveryExpiredLink"),
|
|
198
|
+
color: "negative",
|
|
199
|
+
position: "top",
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return $q.notify({
|
|
204
|
+
message: t("auth.passwordRecoveryFailed"),
|
|
205
|
+
color: "negative",
|
|
206
|
+
position: "top",
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
})
|
|
210
|
+
|
|
107
211
|
return {
|
|
108
212
|
password,
|
|
109
213
|
validations,
|
package/src/prompts.js
CHANGED
|
@@ -27,7 +27,7 @@ module.exports = function () {
|
|
|
27
27
|
type: "input",
|
|
28
28
|
required: true,
|
|
29
29
|
message: "Route to update the password (page)",
|
|
30
|
-
default: "/
|
|
30
|
+
default: "/ResetPassword/",
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
name: "AUTH_SERVER_BASE_URL",
|
|
@@ -41,7 +41,7 @@ module.exports = function () {
|
|
|
41
41
|
type: "input",
|
|
42
42
|
required: true,
|
|
43
43
|
message: "API endpoint for signin (without host)",
|
|
44
|
-
default: "/
|
|
44
|
+
default: "/auth",
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
name: "AUTH_SERVER_RESET_PASSWORD_ROUTE",
|