4077-login_recover-password & account_verifyEmail #1063
|
@ -20,6 +20,7 @@ module.exports = Self => {
|
||||||
Self.recoverPassword = async function(ctx, email) {
|
Self.recoverPassword = async function(ctx, email) {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const origin = ctx.req.headers.origin;
|
const origin = ctx.req.headers.origin;
|
||||||
|
const $t = ctx.req.__; // $translate
|
||||||
const ttl = 1209600;
|
const ttl = 1209600;
|
||||||
|
|
||||||
const user = await models.Account.findOne({
|
const user = await models.Account.findOne({
|
||||||
|
@ -37,7 +38,13 @@ module.exports = Self => {
|
||||||
userId: user.id
|
userId: user.id
|
||||||
});
|
});
|
||||||
|
|
||||||
return await Self.rawSql(`CALL vn.mail_insert(?,?,?,?)`,
|
await Self.rawSql(`CALL vn.mail_insert(?,?,?,?)`, [
|
||||||
[email, null, 'Recovery Password', `${origin}/#!/account/${user.id}/basic-data?access_token=${token.id}`]);
|
email,
|
||||||
|
null,
|
||||||
|
$t('Recovery password'),
|
||||||
|
`${origin}/#!/account/${user.id}/basic-data?access_token=${token.id}`
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('account recoverPassword()', () => {
|
||||||
|
const ctx = {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost:5000'}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ctx.req.__ = value => {
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
it('should throw an error when email does not belong to a user', async() => {
|
||||||
|
let error;
|
||||||
|
try {
|
||||||
|
await models.Account.recoverPassword(ctx, 'thor@mydomain.com');
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toEqual('This email does not belong to a user');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update password when it passes requirements', async() => {
|
||||||
|
const user = await models.Account.findById(1107);
|
||||||
|
await models.Account.recoverPassword(ctx, user.email);
|
||||||
|
|
||||||
|
const [result] = await models.AccessToken.find({
|
||||||
|
where: {
|
||||||
|
userId: user.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,6 +1,6 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('account changePassword()', () => {
|
describe('account setPassword()', () => {
|
||||||
it('should throw an error when password does not meet requirements', async() => {
|
it('should throw an error when password does not meet requirements', async() => {
|
||||||
let req = app.models.Account.setPassword(1, 'insecurePass');
|
let req = app.models.Account.setPassword(1, 'insecurePass');
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,15 @@ export default class Auth {
|
||||||
to: state => !state.name.includes('login')
|
to: state => !state.name.includes('login')
|
||||||
};
|
};
|
||||||
|
|
||||||
this.vnToken.set(this.$location.$$search.access_token, false);
|
if (this.$location.$$search.access_token)
|
||||||
console.log(this.$location.$$search.access_token, false);
|
this.vnToken.set(this.$location.$$search.access_token, false);
|
||||||
|
|
||||||
this.$transitions.onStart(criteria, transition => {
|
this.$transitions.onStart(criteria, transition => {
|
||||||
if (this.loggedIn)
|
if (this.loggedIn)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
let redirectToLogin = () => {
|
let redirectToLogin = () => {
|
||||||
// return transition.router.stateService.target('login');
|
return transition.router.stateService.target('login');
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.vnToken.token || this) {
|
if (this.vnToken.token || this) {
|
||||||
|
@ -63,7 +64,6 @@ export default class Auth {
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoginOk(json, remember) {
|
onLoginOk(json, remember) {
|
||||||
console.log(json.data.token);
|
|
||||||
this.vnToken.set(json.data.token, remember);
|
this.vnToken.set(json.data.token, remember);
|
||||||
|
|
||||||
return this.loadAcls().then(() => {
|
return this.loadAcls().then(() => {
|
||||||
|
@ -84,7 +84,7 @@ export default class Auth {
|
||||||
this.loggedIn = false;
|
this.loggedIn = false;
|
||||||
this.vnModules.reset();
|
this.vnModules.reset();
|
||||||
this.aclService.reset();
|
this.aclService.reset();
|
||||||
// this.$state.go('login');
|
this.$state.go('login');
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ function interceptor($q, vnApp, vnToken, $translate) {
|
||||||
},
|
},
|
||||||
request(config) {
|
request(config) {
|
||||||
vnApp.pushLoader();
|
vnApp.pushLoader();
|
||||||
console.log(vnToken.token);
|
|
||||||
if (config.url.charAt(0) !== '/' && apiPath)
|
if (config.url.charAt(0) !== '/' && apiPath)
|
||||||
config.url = `${apiPath}${config.url}`;
|
config.url = `${apiPath}${config.url}`;
|
||||||
if (vnToken.token)
|
if (vnToken.token)
|
||||||
|
|
|
@ -115,7 +115,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) {
|
||||||
if (!$state.current.name.includes('login')) {
|
if (!$state.current.name.includes('login')) {
|
||||||
messageT = 'Session has expired';
|
messageT = 'Session has expired';
|
||||||
let params = {continue: $window.location.hash};
|
let params = {continue: $window.location.hash};
|
||||||
// $state.go('login', params);
|
$state.go('login', params);
|
||||||
} else
|
} else
|
||||||
messageT = 'Invalid login';
|
messageT = 'Invalid login';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -233,5 +233,6 @@
|
||||||
"Descanso diario 12h.": "Descanso diario 12h.",
|
"Descanso diario 12h.": "Descanso diario 12h.",
|
||||||
"Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.",
|
"Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.",
|
||||||
"Dirección incorrecta": "Dirección incorrecta",
|
"Dirección incorrecta": "Dirección incorrecta",
|
||||||
"This email does not belong to a user": "This email does not belong to a user"
|
"This email does not belong to a user": "Este correo electrónico no pertenece a un usuario.",
|
||||||
}
|
"Recovery password": "Recuperar contraseña"
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,11 @@ import Descriptor from 'salix/components/descriptor';
|
||||||
import UserError from 'core/lib/user-error';
|
import UserError from 'core/lib/user-error';
|
||||||
|
|
||||||
class Controller extends Descriptor {
|
class Controller extends Descriptor {
|
||||||
|
constructor($element, $scope, $location) {
|
||||||
|
super($element, $scope);
|
||||||
|
this.$location = $location;
|
||||||
|
}
|
||||||
|
|
||||||
get user() {
|
get user() {
|
||||||
return this.entity;
|
return this.entity;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +29,11 @@ class Controller extends Descriptor {
|
||||||
.then(res => this.hasAccount = res.data.exists);
|
.then(res => this.hasAccount = res.data.exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$onInit() {
|
||||||
|
if (this.$location.$$search.access_token)
|
||||||
|
this.onChangePassClick(false);
|
||||||
|
}
|
||||||
|
|
||||||
onDelete() {
|
onDelete() {
|
||||||
return this.$http.delete(`Accounts/${this.id}`)
|
return this.$http.delete(`Accounts/${this.id}`)
|
||||||
.then(() => this.$state.go('account.index'))
|
.then(() => this.$state.go('account.index'))
|
||||||
|
@ -114,6 +124,8 @@ class Controller extends Descriptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$element', '$scope', '$location'];
|
||||||
|
|
||||||
ngModule.component('vnUserDescriptor', {
|
ngModule.component('vnUserDescriptor', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
|
|
|
@ -105,4 +105,15 @@ describe('component vnUserDescriptor', () => {
|
||||||
expect(controller.emit).toHaveBeenCalledWith('change');
|
expect(controller.emit).toHaveBeenCalledWith('change');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('onInit()', () => {
|
||||||
|
it('should open onChangePassClick popup', () => {
|
||||||
|
controller.$location = {$$search: {access_token: 'RANDOM_TOKEN'}};
|
||||||
|
jest.spyOn(controller, 'onChangePassClick');
|
||||||
|
|
||||||
|
controller.$onInit();
|
||||||
|
|
||||||
|
expect(controller.onChangePassClick).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue