4077-login_recover-password & account_verifyEmail #1063

Merged
alexm merged 52 commits from 4077-login_recover-password into dev 2022-11-28 11:34:03 +00:00
7 changed files with 52 additions and 30 deletions
Showing only changes of commit 00f5689825 - Show all commits

View File

@ -1,26 +1,29 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('recoverPassword', {
Self.remoteMethodCtx('recoverPassword', {
description: 'Send email to the user',
accepts: [
{
arg: 'email',
type: 'string',
description: 'The email of user',
required: false
required: true
}
],
http: {
path: `/recoverPassword`,
verb: 'GET'
verb: 'POST'
}
});
Self.recoverPassword = async function(email) {
console.log('ENTRY');
Self.recoverPassword = async function(ctx, email) {
const models = Self.app.models;
const user = await models.User.findOne({
const origin = ctx.req.headers.origin;
alexm marked this conversation as resolved Outdated
Outdated
Review

He dejado esta ruta(recoverPassword) porque si se llama directamente resetPassword y el correo que se le pasa no pertenece a un usuario, devuelve un error al frontend.

Usando una ruta con try catch, hacemos que no devuelva nunca error y asi no pueden saber si ese correo es de un usuario nuestro o no.

He dejado esta ruta(recoverPassword) porque si se llama directamente resetPassword y el correo que se le pasa no pertenece a un usuario, devuelve un error al frontend. Usando una ruta con try catch, hacemos que no devuelva nunca error y asi no pueden saber si ese correo es de un usuario nuestro o no.
Outdated
Review

Nomes deuria de ignorar el error de tipo "usuario no existe", tots els demes deuria de rellançarlos

catch(err) {
	if (err.code === 'EMAIL_NOT_FOUND')
    	console.error(err);
    else
    	throw err;
}
	
Nomes deuria de ignorar el error de tipo "usuario no existe", tots els demes deuria de rellançarlos ``` catch(err) { if (err.code === 'EMAIL_NOT_FOUND') console.error(err); else throw err; } ```
const ttl = 1209600;
const user = await models.Account.findOne({
fields: ['id', 'name', 'password'],
where: {
email: email
}
@ -29,12 +32,12 @@ module.exports = Self => {
if (!user)
throw new UserError(`This email does not belong to a user`);
alexm marked this conversation as resolved Outdated
Outdated
Review

Aixina dones pistes sobre si el correu existeix, si no trova el correu fes return de forma que el client es comporte de la mateixa manera. Aquest métode nomes deuria fallar en errors inesperats, que tornarien al client com a HTTP 500 Internal server error

Aixina dones pistes sobre si el correu existeix, si no trova el correu fes `return` de forma que el client es comporte de la mateixa manera. Aquest métode nomes deuria fallar en errors inesperats, que tornarien al client com a *HTTP 500 Internal server error*
const token = await models.Account.login({
user: email,
password: user.password
const token = await models.AccessToken.create({
ttl: ttl,
userId: user.id
});
await Self.rawSql(`CALL vn.mail_insert(?,?,?,?)`,
[email, null, 'Recovery Password', `?token=${token}`]);
return await Self.rawSql(`CALL vn.mail_insert(?,?,?,?)`,
[email, null, 'Recovery Password', `${origin}/#!/account/${user.id}/basic-data?access_token=${token.id}`]);
};
alexm marked this conversation as resolved Outdated
Outdated
Review

Gasta una plantilla ejs com ací, no fa falta afegir dependencies:

Gasta una plantilla *ejs* com ací, no fa falta afegir dependencies: * https://gitea.verdnatura.es/juan/hedera-web/src/branch/master/back/common/models/user.js#L52
};

View File

@ -85,20 +85,27 @@
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
},
},
{
"property": "recoverPassword",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
},
{
"property": "logout",
"property": "logout",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
},
{
"property": "validateToken",
"property": "validateToken",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
}
}
]
}

View File

@ -7,7 +7,7 @@ import UserError from 'core/lib/user-error';
* @property {Boolean} loggedIn Whether the user is currently logged
*/
export default class Auth {
constructor($http, $q, $state, $transitions, $window, vnToken, vnModules, aclService) {
constructor($http, $q, $state, $transitions, $window, vnToken, vnModules, aclService, $location) {
Object.assign(this, {
$http,
$q,
@ -17,7 +17,8 @@ export default class Auth {
vnToken,
vnModules,
aclService,
loggedIn: false
loggedIn: false,
$location
});
}
@ -25,15 +26,18 @@ export default class Auth {
let criteria = {
to: state => !state.name.includes('login')
};
this.vnToken.set(this.$location.$$search.access_token, false);
console.log(this.$location.$$search.access_token, false);
this.$transitions.onStart(criteria, transition => {
if (this.loggedIn)
return true;
let redirectToLogin = () => {
return transition.router.stateService.target('login');
// return transition.router.stateService.target('login');
};
if (this.vnToken.token) {
if (this.vnToken.token || this) {
return this.loadAcls()
.then(() => true)
.catch(redirectToLogin);
@ -59,6 +63,7 @@ export default class Auth {
}
onLoginOk(json, remember) {
console.log(json.data.token);
this.vnToken.set(json.data.token, remember);
return this.loadAcls().then(() => {
@ -79,7 +84,7 @@ export default class Auth {
this.loggedIn = false;
this.vnModules.reset();
this.aclService.reset();
this.$state.go('login');
// this.$state.go('login');
return promise;
}
@ -96,6 +101,6 @@ export default class Auth {
});
}
}
Auth.$inject = ['$http', '$q', '$state', '$transitions', '$window', 'vnToken', 'vnModules', 'aclService'];
Auth.$inject = ['$http', '$q', '$state', '$transitions', '$window', 'vnToken', 'vnModules', 'aclService', '$location'];
ngModule.service('vnAuth', Auth);

View File

@ -11,7 +11,7 @@ function interceptor($q, vnApp, vnToken, $translate) {
},
request(config) {
vnApp.pushLoader();
console.log(vnToken.token);
if (config.url.charAt(0) !== '/' && apiPath)
config.url = `${apiPath}${config.url}`;
if (vnToken.token)

View File

@ -6,3 +6,4 @@ Enter: Entrar
I do not remember my password: No recuerdo mi contraseña
Recover password: Recuperar contraseña
We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña
Notification sent!: ¡Notificación enviada!

View File

@ -5,11 +5,14 @@ import './style.scss';
* A simple login form.
*/
export default class Controller {
constructor($, $element, $http) {
constructor($scope, $element, $http, vnApp, $translate, $state) {
Object.assign(this, {
$,
$scope,
$element,
$http
$http,
vnApp,
$translate,
$state
});
}
@ -18,11 +21,14 @@ export default class Controller {
email: this.email
};
this.$http.get('Accounts/recoverPassword', params)
.then(() => console.log('try')); // this.vnApp.showMessage(this.$t('Notification sent!')));
this.$http.post('Accounts/recoverPassword', params)
.then(() => {
this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
this.$state.go('login');
});
}
}
Controller.$inject = ['$scope', '$element', '$http'];
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state'];
ngModule.vnComponent('vnRecoverPassword', {
template: require('./recover-password.html'),

View File

@ -112,10 +112,10 @@ function $exceptionHandler(vnApp, $window, $state, $injector) {
switch (exception.status) {
case 401:
if ($state.current.name != 'login') {
if (!$state.current.name.includes('login')) {
messageT = 'Session has expired';
let params = {continue: $window.location.hash};
$state.go('login', params);
// $state.go('login', params);
} else
messageT = 'Invalid login';
break;