@adminforth/open-signup 1.0.2 → 1.0.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.
- package/custom/SignupPage.vue +55 -47
- package/dist/custom/SignupPage.vue +55 -47
- package/dist/index.js +58 -86
- package/index.ts +69 -97
- package/package.json +1 -1
- package/types.ts +4 -13
- package/dist/custom/ResetPassword.vue +0 -295
- package/dist/custom/ResetPasswordUnderLogin.vue +0 -13
package/custom/SignupPage.vue
CHANGED
|
@@ -37,26 +37,28 @@
|
|
|
37
37
|
<!-- Modal body -->
|
|
38
38
|
<div class="p-4 md:p-5">
|
|
39
39
|
<form v-if="!requestSent" class="space-y-4" role="alert" @submit.prevent>
|
|
40
|
-
<div class="relative">
|
|
40
|
+
<div v-if="!verifyToken" class="relative">
|
|
41
41
|
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
|
|
42
42
|
<input type="email" name="email" id="email"
|
|
43
43
|
tabindex="1"
|
|
44
|
-
|
|
44
|
+
autocomplete="username"
|
|
45
|
+
@keydown.enter="passwordInput?.focus()"
|
|
45
46
|
ref="emailInput"
|
|
46
47
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white"
|
|
47
48
|
placeholder="name@company.com"
|
|
48
49
|
required
|
|
49
50
|
/>
|
|
50
51
|
</div>
|
|
51
|
-
<div class="relative">
|
|
52
|
+
<div v-if="isPasswordNeeded" class="relative">
|
|
52
53
|
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">New password</label>
|
|
53
54
|
<input
|
|
54
55
|
tabindex="2"
|
|
56
|
+
autocomplete="new-password"
|
|
55
57
|
ref="passwordInput"
|
|
56
58
|
:type="unmasked ? 'text' : 'password'"
|
|
57
59
|
name="password" id="password"
|
|
58
60
|
v-model="password"
|
|
59
|
-
@keydown.enter="passwordConfirmationInput
|
|
61
|
+
@keydown.enter="passwordConfirmationInput?.focus()"
|
|
60
62
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white"
|
|
61
63
|
placeholder="New password" required
|
|
62
64
|
/>
|
|
@@ -71,10 +73,11 @@
|
|
|
71
73
|
</button>
|
|
72
74
|
</div>
|
|
73
75
|
|
|
74
|
-
<div class="relative">
|
|
76
|
+
<div v-if="isPasswordNeeded" class="relative">
|
|
75
77
|
<label for="password_confirmation" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Confirm new password</label>
|
|
76
78
|
<input
|
|
77
79
|
ref="passwordConfirmationInput"
|
|
80
|
+
autocomplete="new-password"
|
|
78
81
|
:type="unmasked ? 'text' : 'password'"
|
|
79
82
|
name="password_confirmation" id="password_confirmation"
|
|
80
83
|
tabindex="3"
|
|
@@ -105,7 +108,7 @@
|
|
|
105
108
|
|
|
106
109
|
<Button
|
|
107
110
|
:disabled="inProgress || (validationRunning && validationError)"
|
|
108
|
-
@click="doSignup"
|
|
111
|
+
@click="() => verifyToken ? signupAfterEmailConfirmation() : doSignup()"
|
|
109
112
|
type="submit"
|
|
110
113
|
class="w-full"
|
|
111
114
|
:loader="inProgress"
|
|
@@ -115,9 +118,11 @@
|
|
|
115
118
|
</form>
|
|
116
119
|
<!-- END of set new paasord -->
|
|
117
120
|
<div v-else class="flex items center justify-center p-4 mb-4 text-sm text-green-800 rounded-lg bg-green-50 dark:bg-green-800 dark:text-green-400" role="alert">
|
|
118
|
-
|
|
119
|
-
</div>
|
|
120
|
-
|
|
121
|
+
Please check your email at {{ sentToEmail }} to confirm your email address.
|
|
122
|
+
</div>
|
|
123
|
+
<p class="text-gray-500 dark:text-gray-400 font-sm text-right mt-3">
|
|
124
|
+
or <Link to="/login">{{ toLoginText }}</Link>
|
|
125
|
+
</p>
|
|
121
126
|
</div>
|
|
122
127
|
</div>
|
|
123
128
|
</div>
|
|
@@ -128,7 +133,6 @@
|
|
|
128
133
|
|
|
129
134
|
|
|
130
135
|
<script setup lang="ts">
|
|
131
|
-
|
|
132
136
|
import { onMounted, ref, computed, Ref } from 'vue';
|
|
133
137
|
import { useCoreStore } from '@/stores/core';
|
|
134
138
|
import { useUserStore } from '@/stores/user';
|
|
@@ -136,27 +140,33 @@ import { callAdminForthApi, loadFile, applyRegexValidation } from '@/utils';
|
|
|
136
140
|
import { useRoute, useRouter } from 'vue-router';
|
|
137
141
|
import { IconEyeSolid, IconEyeSlashSolid } from '@iconify-prerendered/vue-flowbite';
|
|
138
142
|
import Button from '@/afcl/Button.vue';
|
|
143
|
+
import Link from '@/afcl/Link.vue';
|
|
139
144
|
|
|
140
145
|
const inProgress = ref(false);
|
|
141
146
|
|
|
142
147
|
const coreStore = useCoreStore();
|
|
143
148
|
const requestSent = ref(false);
|
|
144
149
|
|
|
145
|
-
const emailInput = ref(null);
|
|
146
|
-
const passwordInput = ref(null);
|
|
147
|
-
const passwordConfirmationInput = ref(null);
|
|
150
|
+
const emailInput: Ref<HTMLInputElement | null> = ref(null);
|
|
151
|
+
const passwordInput: Ref<HTMLInputElement | null> = ref(null);
|
|
152
|
+
const passwordConfirmationInput: Ref<HTMLInputElement | null> = ref(null);
|
|
148
153
|
|
|
149
154
|
const password = ref("");
|
|
150
155
|
const passwordConfirmation = ref("");
|
|
151
156
|
const unmasked = ref(false);
|
|
152
157
|
const sentToEmail: Ref<string> = ref('');
|
|
153
158
|
|
|
159
|
+
const requestEmailConfirmation = computed(() => route.meta.requestEmailConfirmation);
|
|
160
|
+
const verifyToken = computed(() => route.query.token);
|
|
161
|
+
const toLoginText = computed(() => `${verifyToken.value ? 'Go' : 'Back'} to login`);
|
|
162
|
+
const isPasswordNeeded = computed(() => !requestEmailConfirmation.value || (requestEmailConfirmation.value && verifyToken.value));
|
|
163
|
+
|
|
154
164
|
const user = useUserStore();
|
|
155
165
|
|
|
156
166
|
const route = useRoute();
|
|
157
167
|
const router = useRouter();
|
|
158
168
|
|
|
159
|
-
function
|
|
169
|
+
function checkPassword() {
|
|
160
170
|
|
|
161
171
|
if (!password.value || !passwordConfirmation.value) {
|
|
162
172
|
return 'Please enter both password and password confirmation';
|
|
@@ -187,39 +197,15 @@ const validationRunning = ref(false);
|
|
|
187
197
|
|
|
188
198
|
const validationError = computed(() => {
|
|
189
199
|
if (validationRunning.value) {
|
|
190
|
-
return
|
|
200
|
+
return checkPassword();
|
|
191
201
|
}
|
|
192
202
|
return null;
|
|
193
203
|
});
|
|
194
204
|
|
|
195
|
-
const error: Ref<
|
|
205
|
+
const error: Ref<string | null> = ref(null);
|
|
196
206
|
|
|
197
207
|
onMounted(async () => {
|
|
198
|
-
|
|
199
|
-
// call method completeVerifiedSignup to confirm { token }
|
|
200
|
-
// if success, then redirect to login page
|
|
201
|
-
|
|
202
|
-
const resp = await callAdminForthApi({
|
|
203
|
-
path: `/plugin/${route.meta.pluginInstanceId}/complete-verified-signup`,
|
|
204
|
-
method: 'POST',
|
|
205
|
-
body: {
|
|
206
|
-
token: route.query.token,
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
if (resp.error) {
|
|
210
|
-
window.adminforth.alert({
|
|
211
|
-
message: `Error fetching data: ${error.message}`,
|
|
212
|
-
variant: 'danger',
|
|
213
|
-
});
|
|
214
|
-
} else if (resp.redirectTo) {
|
|
215
|
-
router.push(resp.redirectTo);
|
|
216
|
-
} else {
|
|
217
|
-
await user.finishLogin();
|
|
218
|
-
}
|
|
219
|
-
return;
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
emailInput.value.focus();
|
|
208
|
+
emailInput.value?.focus();
|
|
223
209
|
});
|
|
224
210
|
|
|
225
211
|
|
|
@@ -242,7 +228,7 @@ async function doSignup() {
|
|
|
242
228
|
error.value = 'Please enter your email';
|
|
243
229
|
return;
|
|
244
230
|
}
|
|
245
|
-
if (
|
|
231
|
+
if (!requestEmailConfirmation.value && checkPassword()) {
|
|
246
232
|
validationRunning.value = true;
|
|
247
233
|
return;
|
|
248
234
|
}
|
|
@@ -254,7 +240,7 @@ async function doSignup() {
|
|
|
254
240
|
body: {
|
|
255
241
|
email,
|
|
256
242
|
url: window.location.origin + window.location.pathname,
|
|
257
|
-
password: password.value,
|
|
243
|
+
...(!requestEmailConfirmation.value ? {password: password.value} : {}),
|
|
258
244
|
}
|
|
259
245
|
});
|
|
260
246
|
inProgress.value = false;
|
|
@@ -264,15 +250,37 @@ async function doSignup() {
|
|
|
264
250
|
error.value = null;
|
|
265
251
|
requestSent.value = true;
|
|
266
252
|
sentToEmail.value = email;
|
|
267
|
-
if (resp.redirectTo) {
|
|
253
|
+
if (resp.redirectTo && !requestEmailConfirmation.value) {
|
|
268
254
|
router.push(resp.redirectTo);
|
|
269
|
-
} else {
|
|
255
|
+
} else if (!requestEmailConfirmation.value) {
|
|
270
256
|
error.value = null;
|
|
271
257
|
await user.finishLogin();
|
|
272
258
|
}
|
|
273
259
|
}
|
|
274
260
|
}
|
|
275
261
|
|
|
276
|
-
|
|
277
|
-
|
|
262
|
+
const signupAfterEmailConfirmation = async () => {
|
|
263
|
+
if (checkPassword()) {
|
|
264
|
+
validationRunning.value = true;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const resp = await callAdminForthApi({
|
|
268
|
+
path: `/plugin/${route.meta.pluginInstanceId}/complete-verified-signup`,
|
|
269
|
+
method: 'POST',
|
|
270
|
+
body: {
|
|
271
|
+
token: verifyToken.value,
|
|
272
|
+
password: password.value,
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
if (resp.error) {
|
|
276
|
+
window.adminforth.alert({
|
|
277
|
+
message: `Error fetching data: ${resp.error}`,
|
|
278
|
+
variant: 'danger',
|
|
279
|
+
});
|
|
280
|
+
} else if (resp.redirectTo) {
|
|
281
|
+
router.push(resp.redirectTo);
|
|
282
|
+
} else {
|
|
283
|
+
await user.finishLogin();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
278
286
|
</script>
|
|
@@ -37,26 +37,28 @@
|
|
|
37
37
|
<!-- Modal body -->
|
|
38
38
|
<div class="p-4 md:p-5">
|
|
39
39
|
<form v-if="!requestSent" class="space-y-4" role="alert" @submit.prevent>
|
|
40
|
-
<div class="relative">
|
|
40
|
+
<div v-if="!verifyToken" class="relative">
|
|
41
41
|
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
|
|
42
42
|
<input type="email" name="email" id="email"
|
|
43
43
|
tabindex="1"
|
|
44
|
-
|
|
44
|
+
autocomplete="username"
|
|
45
|
+
@keydown.enter="passwordInput?.focus()"
|
|
45
46
|
ref="emailInput"
|
|
46
47
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white"
|
|
47
48
|
placeholder="name@company.com"
|
|
48
49
|
required
|
|
49
50
|
/>
|
|
50
51
|
</div>
|
|
51
|
-
<div class="relative">
|
|
52
|
+
<div v-if="isPasswordNeeded" class="relative">
|
|
52
53
|
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">New password</label>
|
|
53
54
|
<input
|
|
54
55
|
tabindex="2"
|
|
56
|
+
autocomplete="new-password"
|
|
55
57
|
ref="passwordInput"
|
|
56
58
|
:type="unmasked ? 'text' : 'password'"
|
|
57
59
|
name="password" id="password"
|
|
58
60
|
v-model="password"
|
|
59
|
-
@keydown.enter="passwordConfirmationInput
|
|
61
|
+
@keydown.enter="passwordConfirmationInput?.focus()"
|
|
60
62
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white"
|
|
61
63
|
placeholder="New password" required
|
|
62
64
|
/>
|
|
@@ -71,10 +73,11 @@
|
|
|
71
73
|
</button>
|
|
72
74
|
</div>
|
|
73
75
|
|
|
74
|
-
<div class="relative">
|
|
76
|
+
<div v-if="isPasswordNeeded" class="relative">
|
|
75
77
|
<label for="password_confirmation" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Confirm new password</label>
|
|
76
78
|
<input
|
|
77
79
|
ref="passwordConfirmationInput"
|
|
80
|
+
autocomplete="new-password"
|
|
78
81
|
:type="unmasked ? 'text' : 'password'"
|
|
79
82
|
name="password_confirmation" id="password_confirmation"
|
|
80
83
|
tabindex="3"
|
|
@@ -105,7 +108,7 @@
|
|
|
105
108
|
|
|
106
109
|
<Button
|
|
107
110
|
:disabled="inProgress || (validationRunning && validationError)"
|
|
108
|
-
@click="doSignup"
|
|
111
|
+
@click="() => verifyToken ? signupAfterEmailConfirmation() : doSignup()"
|
|
109
112
|
type="submit"
|
|
110
113
|
class="w-full"
|
|
111
114
|
:loader="inProgress"
|
|
@@ -115,9 +118,11 @@
|
|
|
115
118
|
</form>
|
|
116
119
|
<!-- END of set new paasord -->
|
|
117
120
|
<div v-else class="flex items center justify-center p-4 mb-4 text-sm text-green-800 rounded-lg bg-green-50 dark:bg-green-800 dark:text-green-400" role="alert">
|
|
118
|
-
|
|
119
|
-
</div>
|
|
120
|
-
|
|
121
|
+
Please check your email at {{ sentToEmail }} to confirm your email address.
|
|
122
|
+
</div>
|
|
123
|
+
<p class="text-gray-500 dark:text-gray-400 font-sm text-right mt-3">
|
|
124
|
+
or <Link to="/login">{{ toLoginText }}</Link>
|
|
125
|
+
</p>
|
|
121
126
|
</div>
|
|
122
127
|
</div>
|
|
123
128
|
</div>
|
|
@@ -128,7 +133,6 @@
|
|
|
128
133
|
|
|
129
134
|
|
|
130
135
|
<script setup lang="ts">
|
|
131
|
-
|
|
132
136
|
import { onMounted, ref, computed, Ref } from 'vue';
|
|
133
137
|
import { useCoreStore } from '@/stores/core';
|
|
134
138
|
import { useUserStore } from '@/stores/user';
|
|
@@ -136,27 +140,33 @@ import { callAdminForthApi, loadFile, applyRegexValidation } from '@/utils';
|
|
|
136
140
|
import { useRoute, useRouter } from 'vue-router';
|
|
137
141
|
import { IconEyeSolid, IconEyeSlashSolid } from '@iconify-prerendered/vue-flowbite';
|
|
138
142
|
import Button from '@/afcl/Button.vue';
|
|
143
|
+
import Link from '@/afcl/Link.vue';
|
|
139
144
|
|
|
140
145
|
const inProgress = ref(false);
|
|
141
146
|
|
|
142
147
|
const coreStore = useCoreStore();
|
|
143
148
|
const requestSent = ref(false);
|
|
144
149
|
|
|
145
|
-
const emailInput = ref(null);
|
|
146
|
-
const passwordInput = ref(null);
|
|
147
|
-
const passwordConfirmationInput = ref(null);
|
|
150
|
+
const emailInput: Ref<HTMLInputElement | null> = ref(null);
|
|
151
|
+
const passwordInput: Ref<HTMLInputElement | null> = ref(null);
|
|
152
|
+
const passwordConfirmationInput: Ref<HTMLInputElement | null> = ref(null);
|
|
148
153
|
|
|
149
154
|
const password = ref("");
|
|
150
155
|
const passwordConfirmation = ref("");
|
|
151
156
|
const unmasked = ref(false);
|
|
152
157
|
const sentToEmail: Ref<string> = ref('');
|
|
153
158
|
|
|
159
|
+
const requestEmailConfirmation = computed(() => route.meta.requestEmailConfirmation);
|
|
160
|
+
const verifyToken = computed(() => route.query.token);
|
|
161
|
+
const toLoginText = computed(() => `${verifyToken.value ? 'Go' : 'Back'} to login`);
|
|
162
|
+
const isPasswordNeeded = computed(() => !requestEmailConfirmation.value || (requestEmailConfirmation.value && verifyToken.value));
|
|
163
|
+
|
|
154
164
|
const user = useUserStore();
|
|
155
165
|
|
|
156
166
|
const route = useRoute();
|
|
157
167
|
const router = useRouter();
|
|
158
168
|
|
|
159
|
-
function
|
|
169
|
+
function checkPassword() {
|
|
160
170
|
|
|
161
171
|
if (!password.value || !passwordConfirmation.value) {
|
|
162
172
|
return 'Please enter both password and password confirmation';
|
|
@@ -187,39 +197,15 @@ const validationRunning = ref(false);
|
|
|
187
197
|
|
|
188
198
|
const validationError = computed(() => {
|
|
189
199
|
if (validationRunning.value) {
|
|
190
|
-
return
|
|
200
|
+
return checkPassword();
|
|
191
201
|
}
|
|
192
202
|
return null;
|
|
193
203
|
});
|
|
194
204
|
|
|
195
|
-
const error: Ref<
|
|
205
|
+
const error: Ref<string | null> = ref(null);
|
|
196
206
|
|
|
197
207
|
onMounted(async () => {
|
|
198
|
-
|
|
199
|
-
// call method completeVerifiedSignup to confirm { token }
|
|
200
|
-
// if success, then redirect to login page
|
|
201
|
-
|
|
202
|
-
const resp = await callAdminForthApi({
|
|
203
|
-
path: `/plugin/${route.meta.pluginInstanceId}/complete-verified-signup`,
|
|
204
|
-
method: 'POST',
|
|
205
|
-
body: {
|
|
206
|
-
token: route.query.token,
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
if (resp.error) {
|
|
210
|
-
window.adminforth.alert({
|
|
211
|
-
message: `Error fetching data: ${error.message}`,
|
|
212
|
-
variant: 'danger',
|
|
213
|
-
});
|
|
214
|
-
} else if (resp.redirectTo) {
|
|
215
|
-
router.push(resp.redirectTo);
|
|
216
|
-
} else {
|
|
217
|
-
await user.finishLogin();
|
|
218
|
-
}
|
|
219
|
-
return;
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
emailInput.value.focus();
|
|
208
|
+
emailInput.value?.focus();
|
|
223
209
|
});
|
|
224
210
|
|
|
225
211
|
|
|
@@ -242,7 +228,7 @@ async function doSignup() {
|
|
|
242
228
|
error.value = 'Please enter your email';
|
|
243
229
|
return;
|
|
244
230
|
}
|
|
245
|
-
if (
|
|
231
|
+
if (!requestEmailConfirmation.value && checkPassword()) {
|
|
246
232
|
validationRunning.value = true;
|
|
247
233
|
return;
|
|
248
234
|
}
|
|
@@ -254,7 +240,7 @@ async function doSignup() {
|
|
|
254
240
|
body: {
|
|
255
241
|
email,
|
|
256
242
|
url: window.location.origin + window.location.pathname,
|
|
257
|
-
password: password.value,
|
|
243
|
+
...(!requestEmailConfirmation.value ? {password: password.value} : {}),
|
|
258
244
|
}
|
|
259
245
|
});
|
|
260
246
|
inProgress.value = false;
|
|
@@ -264,15 +250,37 @@ async function doSignup() {
|
|
|
264
250
|
error.value = null;
|
|
265
251
|
requestSent.value = true;
|
|
266
252
|
sentToEmail.value = email;
|
|
267
|
-
if (resp.redirectTo) {
|
|
253
|
+
if (resp.redirectTo && !requestEmailConfirmation.value) {
|
|
268
254
|
router.push(resp.redirectTo);
|
|
269
|
-
} else {
|
|
255
|
+
} else if (!requestEmailConfirmation.value) {
|
|
270
256
|
error.value = null;
|
|
271
257
|
await user.finishLogin();
|
|
272
258
|
}
|
|
273
259
|
}
|
|
274
260
|
}
|
|
275
261
|
|
|
276
|
-
|
|
277
|
-
|
|
262
|
+
const signupAfterEmailConfirmation = async () => {
|
|
263
|
+
if (checkPassword()) {
|
|
264
|
+
validationRunning.value = true;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const resp = await callAdminForthApi({
|
|
268
|
+
path: `/plugin/${route.meta.pluginInstanceId}/complete-verified-signup`,
|
|
269
|
+
method: 'POST',
|
|
270
|
+
body: {
|
|
271
|
+
token: verifyToken.value,
|
|
272
|
+
password: password.value,
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
if (resp.error) {
|
|
276
|
+
window.adminforth.alert({
|
|
277
|
+
message: `Error fetching data: ${resp.error}`,
|
|
278
|
+
variant: 'danger',
|
|
279
|
+
});
|
|
280
|
+
} else if (resp.redirectTo) {
|
|
281
|
+
router.push(resp.redirectTo);
|
|
282
|
+
} else {
|
|
283
|
+
await user.finishLogin();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
278
286
|
</script>
|