4077-login_recover-password & account_verifyEmail #1063
|
@ -1,26 +1,20 @@
|
||||||
const path = require('path');
|
const LoopBackContext = require('loopback-context');
|
||||||
|
const {Email} = require('vn-print');
|
||||||
|
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
function getUrl() {
|
|
||||||
return Self.app.get('rootUrl') || app.get('url');
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFrom() {
|
|
||||||
return Self.dataSources.email.settings.transports[0].auth.from;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self.on('resetPasswordRequest', async function(info) {
|
Self.on('resetPasswordRequest', async function(info) {
|
||||||
const renderer = loopback.template(path.resolve(__dirname, '../../views/reset-password.ejs'));
|
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||||
const html = renderer({
|
const httpCtx = {req: loopBackContext.active};
|
||||||
url: `${getUrl()}#/reset-password?access_token=${info.accessToken.id}`
|
const httpRequest = httpCtx.req.http.req;
|
||||||
});
|
const headers = httpRequest.headers;
|
||||||
|
const origin = headers.origin;
|
||||||
|
|
||||||
await app.models.Email.send({
|
const params = {
|
||||||
to: info.email,
|
url: `${origin}/#!/login/reset-password?access_token=${info.accessToken.id}`
|
||||||
from: getFrom(),
|
};
|
||||||
subject: 'Password reset',
|
|
||||||
html
|
const sendEmail = new Email('recover-password', params);
|
||||||
});
|
|
||||||
console.log('> Sending password reset email to:', info.email);
|
return sendEmail.send();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ import UserError from 'core/lib/user-error';
|
||||||
* @property {Boolean} loggedIn Whether the user is currently logged
|
* @property {Boolean} loggedIn Whether the user is currently logged
|
||||||
*/
|
*/
|
||||||
export default class Auth {
|
export default class Auth {
|
||||||
constructor($http, $q, $state, $transitions, $window, vnToken, vnModules, aclService, $location) {
|
constructor($http, $q, $state, $transitions, $window, vnToken, vnModules, aclService) {
|
||||||
Object.assign(this, {
|
Object.assign(this, {
|
||||||
$http,
|
$http,
|
||||||
$q,
|
$q,
|
||||||
|
@ -17,8 +17,7 @@ export default class Auth {
|
||||||
vnToken,
|
vnToken,
|
||||||
vnModules,
|
vnModules,
|
||||||
aclService,
|
aclService,
|
||||||
loggedIn: false,
|
loggedIn: false
|
||||||
$location
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,10 +25,6 @@ export default class Auth {
|
||||||
let criteria = {
|
let criteria = {
|
||||||
to: state => !state.name.includes('login')
|
to: state => !state.name.includes('login')
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.$location.$$search.access_token)
|
|
||||||
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;
|
||||||
|
@ -103,6 +98,6 @@ export default class Auth {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Auth.$inject = ['$http', '$q', '$state', '$transitions', '$window', 'vnToken', 'vnModules', 'aclService', '$location'];
|
Auth.$inject = ['$http', '$q', '$state', '$transitions', '$window', 'vnToken', 'vnModules', 'aclService'];
|
||||||
|
|
||||||
ngModule.service('vnAuth', Auth);
|
ngModule.service('vnAuth', Auth);
|
||||||
|
|
|
@ -3,11 +3,15 @@
|
||||||
</vn-layout>
|
</vn-layout>
|
||||||
<ui-view
|
<ui-view
|
||||||
name="login"
|
name="login"
|
||||||
ng-if="!$ctrl.showLayout && !$ctrl.isRecover">
|
ng-if="!$ctrl.showLayout && !$ctrl.isRecover && !$ctrl.isRecover2">
|
||||||
</ui-view>
|
</ui-view>
|
||||||
<ui-view
|
<ui-view
|
||||||
name="recover-password"
|
name="recover-password"
|
||||||
ng-if="!$ctrl.showLayout && $ctrl.isRecover">
|
ng-if="!$ctrl.showLayout && $ctrl.isRecover">
|
||||||
</ui-view>
|
</ui-view>
|
||||||
|
<ui-view
|
||||||
|
name="reset-password"
|
||||||
|
ng-if="!$ctrl.showLayout && $ctrl.isReset">
|
||||||
|
</ui-view>
|
||||||
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
||||||
<vn-debug-info></vn-debug-info>
|
<vn-debug-info></vn-debug-info>
|
||||||
|
|
|
@ -15,12 +15,15 @@ export default class App extends Component {
|
||||||
|
|
||||||
get showLayout() {
|
get showLayout() {
|
||||||
let state = this.$state.current.name;
|
let state = this.$state.current.name;
|
||||||
return state && state != 'login' && !this.isRecover;
|
return state && state != 'login' && !this.isRecover && !this.isReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isRecover() {
|
get isRecover() {
|
||||||
let state = this.$state.current.name;
|
return this.$state.current.name == 'login.recover-password';
|
||||||
return state == 'login.recover-password';
|
}
|
||||||
|
|
||||||
|
get isReset() {
|
||||||
|
return this.$state.current.name == 'login.reset-password';
|
||||||
}
|
}
|
||||||
|
|
||||||
$onDestroy() {
|
$onDestroy() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import './layout';
|
||||||
import './left-menu/left-menu';
|
import './left-menu/left-menu';
|
||||||
import './login/login';
|
import './login/login';
|
||||||
import './login/recover-password';
|
import './login/recover-password';
|
||||||
|
import './login/reset-password';
|
||||||
import './module-card';
|
import './module-card';
|
||||||
import './module-main';
|
import './module-main';
|
||||||
import './side-menu/side-menu';
|
import './side-menu/side-menu';
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default class Controller {
|
||||||
email: this.email
|
email: this.email
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$http.post('Accounts/recoverPassword', params)
|
this.$http.post('users/reset', params)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
|
this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
|
||||||
this.$state.go('login');
|
this.$state.go('login');
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<div class="box">
|
||||||
|
<form name="form" ng-submit="$ctrl.submit()">
|
||||||
|
<h5 class="vn-mb-lg" translate>Reset password</h5>
|
||||||
|
<vn-textfield
|
||||||
|
label="New password"
|
||||||
|
ng-model="$ctrl.newPassword"
|
||||||
|
type="password"
|
||||||
|
info="{{'Password requirements' | translate:$ctrl.passRequirements}}"
|
||||||
|
vn-focus>
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-textfield
|
||||||
|
label="Repeat password"
|
||||||
|
ng-model="$ctrl.repeatPassword"
|
||||||
|
type="password">
|
||||||
|
</vn-textfield>
|
||||||
|
<div class="footer">
|
||||||
|
<vn-submit label="Change password"></vn-submit>
|
||||||
|
<div class="spinner-wrapper">
|
||||||
|
<vn-spinner enable="$ctrl.loading"></vn-spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -0,0 +1,53 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
const axios = require('axios');
|
||||||
alexm marked this conversation as resolved
|
|||||||
|
|
||||||
|
export default class Controller {
|
||||||
|
constructor($scope, $element, $http, vnApp, $translate, $state, $location) {
|
||||||
|
Object.assign(this, {
|
||||||
|
$scope,
|
||||||
|
$element,
|
||||||
|
$http,
|
||||||
|
vnApp,
|
||||||
|
$translate,
|
||||||
|
$state,
|
||||||
|
$location
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$onInit() {
|
||||||
|
const headers = {
|
||||||
|
Authorization: this.$location.$$search.access_token
|
||||||
|
};
|
||||||
|
|
||||||
|
axios.post('api/UserPasswords/findOne', null, {headers})
|
||||||
|
.then(res => {
|
||||||
|
this.passRequirements = res.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
if (!this.newPassword)
|
||||||
|
throw new UserError(`You must enter a new password`);
|
||||||
|
if (this.newPassword != this.repeatPassword)
|
||||||
|
throw new UserError(`Passwords don't match`);
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Authorization: this.$location.$$search.access_token
|
||||||
|
};
|
||||||
|
|
||||||
|
const newPassword = this.newPassword;
|
||||||
|
|
||||||
|
axios.post('api/users/reset-password', {newPassword}, {headers})
|
||||||
|
.then(() => {
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Password changed!'));
|
||||||
|
this.$state.go('login');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location'];
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnResetPassword', {
|
||||||
|
template: require('./reset-password.html'),
|
||||||
|
controller: Controller
|
||||||
|
});
|
|
@ -1,6 +1,7 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
vn-login,
|
vn-login,
|
||||||
|
vn-reset-password,
|
||||||
vn-recover-password{
|
vn-recover-password{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -11,13 +11,18 @@ function config($stateProvider, $urlRouterProvider) {
|
||||||
description: 'Login',
|
description: 'Login',
|
||||||
views: {
|
views: {
|
||||||
'login': {template: '<vn-login></vn-login>'},
|
'login': {template: '<vn-login></vn-login>'},
|
||||||
'recover-password': {template: '<vn-recover-password></vn-recover-password>'}
|
'recover-password': {template: '<vn-recover-password></vn-recover-password>'},
|
||||||
|
'reset-password': {template: '<vn-reset-password></vn-reset-password>'}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.state('login.recover-password', {
|
.state('login.recover-password', {
|
||||||
url: '/recover-password',
|
url: '/recover-password',
|
||||||
description: 'Recover-password'
|
description: 'Recover-password'
|
||||||
})
|
})
|
||||||
|
.state('login.reset-password', {
|
||||||
|
url: '/reset-password',
|
||||||
|
description: 'Reset-password'
|
||||||
|
})
|
||||||
.state('home', {
|
.state('home', {
|
||||||
url: '/',
|
url: '/',
|
||||||
description: 'Home',
|
description: 'Home',
|
||||||
|
|
Loading…
Reference in New Issue
Perque gastes axios y no el servei $http?