Integración usuarios, errores solucionados

This commit is contained in:
Juan Ferrer Toribio 2017-05-21 18:36:07 +02:00
parent a06d1a579c
commit 5cfdd51cf4
19 changed files with 135 additions and 52 deletions

View File

@ -3,7 +3,7 @@
<div class="box"> <div class="box">
<img src="./logo.svg"/> <img src="./logo.svg"/>
<form name="form" ng-submit="$ctrl.submit()"> <form name="form" ng-submit="$ctrl.submit()">
<vn-textfield vn-id="userField" label="User" model="$ctrl.email"></vn-textfield> <vn-textfield vn-id="userField" label="User" model="$ctrl.user"></vn-textfield>
<vn-textfield label="Password" model="$ctrl.password" type="password"></vn-textfield> <vn-textfield label="Password" model="$ctrl.password" type="password"></vn-textfield>
<div class="footer"> <div class="footer">
<vn-submit label="Enter"></vn-submit> <vn-submit label="Enter"></vn-submit>

View File

@ -9,15 +9,15 @@ export default class Controller {
this.$http = $http; this.$http = $http;
} }
submit() { submit() {
if (!(this.email && this.password)) { if (!(this.user && this.password)) {
this.focusUser(); this.focusUser();
this.showMessage('Please insert your email and password'); this.showMessage('Please insert your user and password');
return; return;
} }
this.loading = true; this.loading = true;
let params = { let params = {
email: this.email, user: this.user,
password: this.password, password: this.password,
location: this.$window.location.href location: this.$window.location.href
}; };
@ -70,7 +70,7 @@ export default class Controller {
this.$.userField.focus(); this.$.userField.focus();
} }
showMessage(message) { showMessage(message) {
this.snackbar.show({message: message}); this.$.snackbar.show({message: message});
} }
} }
Controller.$inject = ['$element', '$scope', '$window', '$http']; Controller.$inject = ['$element', '$scope', '$window', '$http'];

View File

@ -43,7 +43,6 @@ export default class Autocomplete extends Component {
this.data.push(value); this.data.push(value);
} }
} }
mdlUpdate() { mdlUpdate() {
let mdlField = this.element.firstChild.MaterialTextfield; let mdlField = this.element.firstChild.MaterialTextfield;
if (mdlField) if (mdlField)
@ -344,7 +343,6 @@ export default class Autocomplete extends Component {
this.item = item; this.item = item;
this.mdlUpdate(); this.mdlUpdate();
} }
} }
Autocomplete.$inject = ['$element', '$scope', '$http', 'vnPopover']; Autocomplete.$inject = ['$element', '$scope', '$http', 'vnPopover'];

View File

@ -5,6 +5,7 @@ vn-textfield {
right: -6px; right: -6px;
margin: 22px 0px; margin: 22px 0px;
visibility: hidden; visibility: hidden;
background-color: white;
} }
.material-icons { .material-icons {
font-size: 18px; font-size: 18px;

View File

@ -5,7 +5,3 @@ import './config';
import './run'; import './run';
import './components'; import './components';
import './styles/index'; import './styles/index';
import {bootstrap} from './bootstrap';
bootstrap();

View File

@ -29,8 +29,8 @@ function vnAppInterceptor($q, $rootScope, logger, $translate, $cookies) {
return { return {
request: function(config) { request: function(config) {
$rootScope.loading = true; $rootScope.loading = true;
let token = $cookies.get('vnToken'); let token = $cookies.get('vnToken');
if (token) if (token)
config.headers.Authorization = token; config.headers.Authorization = token;
@ -50,8 +50,17 @@ function vnAppInterceptor($q, $rootScope, logger, $translate, $cookies) {
}, },
responseError: function(rejection) { responseError: function(rejection) {
$rootScope.loading = false; $rootScope.loading = false;
let message = rejection.data.error.message; let data = rejection.data;
logger.showError(message); let error;
if (data && data.error instanceof Object)
error = data.error.message;
else if (rejection.status === -1)
error = $translate.instant(`Can't contact with server`);
else
error = `${rejection.status}: ${rejection.statusText}`;
logger.showError(error);
return $q.reject(rejection); return $q.reject(rejection);
} }
}; };

View File

@ -5,5 +5,6 @@
"Change language": "Change language", "Change language": "Change language",
"Profile": "Profile", "Profile": "Profile",
"Data saved!": "Data saved!", "Data saved!": "Data saved!",
"Can't contact with server": "Can't contact with server",
"Push on applications menu": "To open a module push on applications menu" "Push on applications menu": "To open a module push on applications menu"
} }

View File

@ -5,5 +5,6 @@
"Change language": "Cambiar idioma", "Change language": "Cambiar idioma",
"Profile": "Perfil", "Profile": "Perfil",
"Data saved!": "¡Datos guardados!", "Data saved!": "¡Datos guardados!",
"Can't contact with server": "No se pudo contactar con el servidor",
"Push on applications menu": "Para abrir un módulo pulsa en el menú de aplicaciones" "Push on applications menu": "Para abrir un módulo pulsa en el menú de aplicaciones"
} }

View File

@ -0,0 +1,36 @@
{
"name": "Account",
"base": "PersistedModel",
"validateUpsert": true,
"properties": {
"id": {
"type": "number",
"required": true
},
"name": {
"type": "string",
"required": true
},
"password": {
"type": "string",
"required": true
},
"active": {
"type": "boolean"
}
},
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
},
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
}
]
}

View File

@ -16,6 +16,7 @@
"loopback-component-explorer": "^2.4.0", "loopback-component-explorer": "^2.4.0",
"loopback-connector-mysql": "^3.0.0", "loopback-connector-mysql": "^3.0.0",
"loopback-datasource-juggler": "^2.39.0", "loopback-datasource-juggler": "^2.39.0",
"md5": "^2.2.1",
"serve-favicon": "^2.0.1", "serve-favicon": "^2.0.1",
"strong-error-handler": "^1.0.1" "strong-error-handler": "^1.0.1"
}, },

View File

@ -1,6 +1,8 @@
var url = require ('url'); var url = require('url');
var md5 = require('md5');
module.exports = function(app) { module.exports = function(app) {
let User = app.models.User;
let applications = app.get('applications'); let applications = app.get('applications');
app.get('/',function(req, res){ app.get('/',function(req, res){
@ -8,19 +10,31 @@ module.exports = function(app) {
}); });
app.post('/login', function(req, res) { app.post('/login', function(req, res) {
app.models.User.login({ let user = req.body.user;
email: req.body.email, let password = req.body.password;
password: req.body.password let syncOnFail = true;
}, 'user', function(err, token) {
login();
function login() {
let loginInfo = {
username: user,
password: password
};
User.login(loginInfo, 'user', loginCb);
}
function loginCb(err, token) {
if (err) { if (err) {
res.status (401); if(syncOnFail) {
res.send(JSON.stringify({ syncOnFail = false;
title: 'Login failed', let filter = {where: {name: user}};
content: err, app.models.Account.findOne(filter, findCb);
redirectTo: '/', }
redirectToLinkText: 'Try again' else
})); badLogin();
} else { return;
}
let query = url.parse(req.body.location, true).query; let query = url.parse(req.body.location, true).query;
let loginUrl = applications[query.apiKey]; let loginUrl = applications[query.apiKey];
if (!loginUrl) if (!loginUrl)
@ -32,12 +46,30 @@ module.exports = function(app) {
loginUrl: loginUrl, loginUrl: loginUrl,
})); }));
} }
}); function findCb(err, instance) {
if(!instance || instance.password !== md5(password)) {
badLogin();
return;
}
let where = {username: user};
let userData = {
username: user,
password: password,
email: `${user}@verdnatura.es`
};
User.upsertWithWhere(where, userData, login);
}
function badLogin() {
res.status(401);
res.send(JSON.stringify({
message: 'Login failed'
}));
}
}); });
app.get('/logout', function (req, res) { app.get('/logout', function (req, res) {
app.models.User.logout(req.accessToken.id, function(err) { User.logout(req.accessToken.id,
res.redirect('/'); () => res.redirect('/'));
});
}); });
}; };

View File

@ -1,7 +1,8 @@
{ {
"db": { "db": {
"name": "db", "name": "db",
"connector": "memory" "connector": "memory",
"file": "db.json"
}, },
"auth": { "auth": {
"name": "mysql", "name": "mysql",

View File

@ -27,5 +27,8 @@
}, },
"Role": { "Role": {
"dataSource": "auth" "dataSource": "auth"
},
"Account": {
"dataSource": "auth"
} }
} }

View File

@ -11,6 +11,10 @@
"type": "string", "type": "string",
"required": true "required": true
}, },
"password": {
"type": "string",
"required": true
},
"active": { "active": {
"type": "boolean" "type": "boolean"
} }

View File

@ -33,6 +33,9 @@
"dataSource": "auth", "dataSource": "auth",
"public": false "public": false
}, },
"Account": {
"dataSource": "auth"
},
"Client": { "Client": {
"dataSource": "vn" "dataSource": "vn"
}, },
@ -54,9 +57,6 @@
"Country": { "Country": {
"dataSource": "vn" "dataSource": "vn"
}, },
"Account": {
"dataSource": "vn"
},
"ContactChannel": { "ContactChannel": {
"dataSource": "vn" "dataSource": "vn"
}, },

View File

@ -4,8 +4,8 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Salix</title> <title>Salix</title>
</head> </head>
<body> <body ng-app="salix">
<vn-app id="app"></vn-app> <vn-app></vn-app>
<script type="text/javascript" <script type="text/javascript"
src="/static/routes.js"> src="/static/routes.js">
</script> </script>
@ -16,8 +16,7 @@
src="/static/bundle.vendor.js"> src="/static/bundle.vendor.js">
</script> </script>
<script type="text/javascript" <script type="text/javascript"
src="/static/bundle.salix.js" src="/static/bundle.salix.js">
selector="#app">
</script> </script>
</body> </body>
</html> </html>

View File

@ -59,7 +59,8 @@ function encodeUri(object) {
if (object[key]) { if (object[key]) {
if (uri.length > 0) if (uri.length > 0)
uri += '&'; uri += '&';
uri += encodeURIComponent(key) + '=' + encodeURIComponent(object[key]); uri += encodeURIComponent(key) + '=';
uri += encodeURIComponent(object[key]);
} }
return uri; return uri;
} }