diff --git a/ayanova/devdocs/todo.txt b/ayanova/devdocs/todo.txt index bfd81e3a..40c22cd9 100644 --- a/ayanova/devdocs/todo.txt +++ b/ayanova/devdocs/todo.txt @@ -36,26 +36,18 @@ To REMOVE: apt-get remove dotnet-runtime-3.0 (replace 3.0 with whatever version User / Contact self password administration and onboarding Still support current method of admin setting login and password as an option Keep the random generator for password only and expose it in the UI as a button beside the password field (magic wand?) - Need to be able to have a "RESET" route as per this: - https://www.troyhunt.com/everything-you-ever-wanted-to-know/ - However, it is also part of the onboarding process so the wording needs to be done carefully as this is also how staff trigger a new user account - For security reasons, Contact can't initiate the reset, it must be done by internal staff (though it doesn't need to be super high rights, limited should be ok, it's a caretaking issue really) - Reset sends via user email a time limited reset code as part of an url to go to the reset form in the AyaNova UI where they can enter new password which are sent along with the reset code to a User route - if the reset code is valid and brings up a user then checks if expired, if not then accepts the new login and password and redirects them to the login page + Login name is fixed and set by internal staff only Password only can be changed by the user Can this be a bulk job for Users? Because if hacked or import lots of users or migrate from v7 might want to do in bulk? TTM v.next? - todo: Translation strings for title and body, follow norms in linked docs regarding best practices - remember this is for reset but also for onboarding todo: need reset button / menu option for BOTH User edit forms -------------------- -Hello {user_name},\n\nYour login account for service is available once you set your password to login.\nYou can use the following link for the next 48 hours to set your password.\n\nSet your password: {action_link}\n\nIf you did not request an account or password reset, please ignore this email.\n\nThanks,\n{registered_to} ------------- - + todo: need reset route and form for user +todo: User update / save password and login, if try to change login but don't give password it bombs with server error +todo: if authenticated and click reset link sb logged out before reset form opens todo: SEEDER Sample customer contacts need random contact info also entered so it's visible as example diff --git a/ayanova/src/App.vue b/ayanova/src/App.vue index 603c91bb..c83faf44 100644 --- a/ayanova/src/App.vue +++ b/ayanova/src/App.vue @@ -339,8 +339,10 @@ export default { toPath = undefined; } + let isReset = toPath && toPath.includes("home-reset"); + //redirect to login if not authenticated - if (!vm.$store.state.authenticated) { + if (!vm.$store.state.authenticated && !isReset) { //If a direct open path was being used but user is not logged in this will catch it //otherwise they will just go on to that path directly diff --git a/ayanova/src/router.js b/ayanova/src/router.js index c22191f5..3f955eb7 100644 --- a/ayanova/src/router.js +++ b/ayanova/src/router.js @@ -127,14 +127,12 @@ export default new Router({ /* webpackChunkName: "ay-common" */ "./views/home-user-settings.vue" ) }, - // { - // path: "/home-translation", - // name: "home-translation", - // component: () => - // import( - // /* webpackChunkName: "ay-common" */ "./views/home-translation.vue" - // ) - // }, + { + path: "/home-reset", + name: "home-reset", + component: () => + import(/* webpackChunkName: "ay-common" */ "./views/home-reset.vue") + }, { path: "/home-password", name: "home-password", diff --git a/ayanova/src/views/cust-user.vue b/ayanova/src/views/cust-user.vue index 3fe53744..5ea8a6c2 100644 --- a/ayanova/src/views/cust-user.vue +++ b/ayanova/src/views/cust-user.vue @@ -855,7 +855,25 @@ export default { window.$gz.errorHandler.handleFormError(error, vm); } } + }, + async sendResetCode() { + let vm = this; + window.$gz.form.deleteAllErrorBoxErrors(vm); + try { + let res = await window.$gz.api.post( + `auth/request-reset-password/${vm.obj.id}`, + null + ); + if (res.error) { + vm.formState.serverError = res.error; + window.$gz.form.setErrorBoxErrors(vm); + } + } catch (error) { + window.$gz.errorHandler.handleFormError(error, vm); + } } + + //------more above here } }; @@ -923,6 +941,9 @@ async function clickHandler(menuItem) { }); } break; + case "sendreset": + m.vm.sendResetCode(); + break; default: window.$gz.eventBus.$emit( "notify-warning", @@ -1007,12 +1028,23 @@ function generateMenu(vm) { }); } - menuOptions.menuItems.push({ - title: "DirectNotification", - icon: "$ayiCommentAlt", - key: FORM_KEY + ":directnotify", - vm: vm - }); + if (vm.$route.params.recordid != 0) { + menuOptions.menuItems.push({ + title: "DirectNotification", + icon: "$ayiCommentAlt", + key: FORM_KEY + ":directnotify", + vm: vm + }); + + if (vm.rights.change) { + menuOptions.menuItems.push({ + title: "SendPasswordResetCode", + icon: null, + key: FORM_KEY + ":sendreset", + vm: vm + }); + } + } window.$gz.eventBus.$emit("menu-change", menuOptions); } diff --git a/ayanova/src/views/home-reset.vue b/ayanova/src/views/home-reset.vue new file mode 100644 index 00000000..71592ae4 --- /dev/null +++ b/ayanova/src/views/home-reset.vue @@ -0,0 +1,113 @@ + + +