diff --git a/.eslintrc.yml b/.eslintrc.yml index 7d4a3e1da..d2af2170f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -9,3 +9,4 @@ rules: operator-linebreak: 0 radix: 0 guard-for-in: 0 + camelcase: 0 diff --git a/.vscode/launch.json b/.vscode/launch.json index ce047cac4..244fe2b49 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -37,50 +37,10 @@ "name": "Asociar al proceso", "type": "node", "request": "attach", - "processId": "${command.PickProcess}", + "processId": "${command:PickProcess}", "port": 5858, "sourceMaps": false, "outFiles": [] - }, - { - "name": "Loopback", - "type": "node", - "request": "launch", - "program": "${workspaceRoot}/services/client/server/server.js", - "stopOnEntry": false, - "args": [], - "cwd": "${workspaceRoot}", - "preLaunchTask": null, - "runtimeExecutable": null, - "runtimeArgs": [ - "--nolazy" - ], - "env": { - "NODE_ENV": "development" - }, - "console": "internalConsole", - "sourceMaps": false, - "outFiles": [] - }, - { - "name": "gulp debug", - "type": "node", - "request": "launch", - "program": "${workspaceRoot}\\@salix\\node_modules\\gulp\\bin\\gulp.js", - "stopOnEntry": false, - "args": [], - "cwd": "${workspaceRoot}\\@salix", - "preLaunchTask": null, - "runtimeExecutable": null, - "runtimeArgs": [ - "--nolazy" - ], - "env": { - "NODE_ENV": "development" - }, - "console": "internalConsole", - "sourceMaps": false, - "outFiles": [] } ] } \ No newline at end of file diff --git a/client/auth/src/auth.js b/client/auth/src/auth.js index 03062dac6..703c81193 100644 --- a/client/auth/src/auth.js +++ b/client/auth/src/auth.js @@ -1,4 +1,3 @@ -export * from './module'; +import './ngModule'; import './config'; - -export {component as Login} from './login/login'; +import './login/index'; diff --git a/client/auth/src/config.js b/client/auth/src/config.js index 22096d217..61c73ebc3 100644 --- a/client/auth/src/config.js +++ b/client/auth/src/config.js @@ -1,4 +1,4 @@ -import {module} from './module'; +import ngModule from './ngModule'; config.$inject = ['$translatePartialLoaderProvider', '$httpProvider']; export function config($translatePartialLoaderProvider, $httpProvider) { @@ -7,4 +7,4 @@ export function config($translatePartialLoaderProvider, $httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; } -module.config(config); +ngModule.config(config); diff --git a/client/auth/src/login/index.html b/client/auth/src/login/index.html new file mode 100755 index 000000000..bb9ce247a --- /dev/null +++ b/client/auth/src/login/index.html @@ -0,0 +1,18 @@ +
+
+
+ +
+ + + +
+
+
+ +
diff --git a/client/auth/src/login/index.js b/client/auth/src/login/index.js new file mode 100644 index 000000000..824a47a1f --- /dev/null +++ b/client/auth/src/login/index.js @@ -0,0 +1,75 @@ +import ngModule from '../ngModule'; +import './style.scss'; + +export default class Controller { + constructor($element, $scope, $window, $http) { + this.$element = $element; + this.$ = $scope; + this.$window = $window; + this.$http = $http; + } + submit() { + if (!(this.email && this.password)) { + this.showMessage('Please insert your email and password'); + return; + } + + this.loading = true; + let params = { + email: this.email, + password: this.password, + location: this.$window.location.href + }; + this.$http.post('/auth/login', params).then( + json => this.onLoginOk(json), + json => this.onLoginErr(json) + ); + } + onLoginOk(json) { + this.loading = false; + let data = json.data; + let params = { + token: data.token, + continue: data.continue + }; + this.$window.location = `${data.loginUrl}?${this.encodeUri(params)}`; + } + encodeUri(object) { + let uri = ''; + for (var key in object) + if (object[key]) { + if (uri.length > 0) + uri += '&'; + uri += encodeURIComponent(key) + '=' + encodeURIComponent(object[key]); + } + return uri; + } + onLoginErr(json) { + this.loading = false; + this.model.password = ''; + + let message; + + switch (json.status) { + case 401: + message = 'Invalid credentials'; + break; + case -1: + message = 'Can\'t contact with server'; + break; + default: + message = 'Something went wrong'; + } + + this.showMessage(message); + } + showMessage(message) { + this.$.snackbar.show({message: message}); + } +} +Controller.$inject = ['$element', '$scope', '$window', '$http']; + +ngModule.component('vnLogin', { + template: require('./index.html'), + controller: Controller +}); diff --git a/client/auth/src/login/login.html b/client/auth/src/login/login.html deleted file mode 100755 index 8ff52f4ad..000000000 --- a/client/auth/src/login/login.html +++ /dev/null @@ -1,18 +0,0 @@ -
-
-
- -
- - - -
-
-
- -
diff --git a/client/auth/src/login/login.js b/client/auth/src/login/login.js deleted file mode 100644 index 5a44eb540..000000000 --- a/client/auth/src/login/login.js +++ /dev/null @@ -1,57 +0,0 @@ -import {module} from '../module'; -import './login.scss'; - -export const component = { - template: require('./login.html'), - controller: controller -}; -module.component('vnLogin', component); - -controller.$inject = ['$http', '$element', '$window']; -function controller($http, $element, $window) { - Object.assign(this, { - submit: function() { - let model = this.model; - - if (!(model && model.email && model.password)) { - this.showMessage('Please insert your email and password'); - return; - } - - this.loading = true; - model.appId = $window.location.href; - $http.post('/auth', this.model).then( - json => this.onLoginOk(json), - json => this.onLoginErr(json) - ); - }, - onLoginOk: function(json) { - this.loading = false; - let data = json.data; - $window.location = `${data.location}?access_token=${data.location}`; - }, - onLoginErr: function(json) { - this.loading = false; - this.model.password = ''; - - let message; - - switch (json.status) { - case 401: - message = 'Invalid credentials'; - break; - case -1: - message = 'Can\'t contact with server'; - break; - default: - message = 'Something went wrong'; - } - - this.showMessage(message); - }, - showMessage: function(message) { - let snackbar = $element.find('vn-snackbar').controller('vnSnackbar'); - snackbar.show({message: message}); - } - }); -} diff --git a/client/auth/src/login/login.scss b/client/auth/src/login/style.scss similarity index 99% rename from client/auth/src/login/login.scss rename to client/auth/src/login/style.scss index 2b856c012..fddd2d14e 100644 --- a/client/auth/src/login/login.scss +++ b/client/auth/src/login/style.scss @@ -44,4 +44,3 @@ vn-login > div { overflow: visible; } } - diff --git a/client/auth/src/module.js b/client/auth/src/module.js deleted file mode 100644 index db08992b5..000000000 --- a/client/auth/src/module.js +++ /dev/null @@ -1,4 +0,0 @@ -import {ng} from 'vendor'; -import * as core from 'core'; - -export const module = ng.module('vnAuth', [core.NAME]); diff --git a/client/auth/src/ngModule.js b/client/auth/src/ngModule.js new file mode 100644 index 000000000..657afe9fc --- /dev/null +++ b/client/auth/src/ngModule.js @@ -0,0 +1,5 @@ +import {ng} from 'vendor'; +import 'core'; + +let ngModule = ng.module('vnAuth', ['vnCore']); +export default ngModule; diff --git a/client/client/src/module.js b/client/client/src/module.js index 85de3c756..431ebee0b 100644 --- a/client/client/src/module.js +++ b/client/client/src/module.js @@ -1,5 +1,4 @@ import {ng} from 'vendor'; -import * as core from 'core'; +import 'core'; -export const NAME = 'client'; -export const module = ng.module(NAME, []); +export const module = ng.module('client', []); diff --git a/client/client/src/web-access/index.html b/client/client/src/web-access/index.html index 50cf431cd..71185cf0c 100644 --- a/client/client/src/web-access/index.html +++ b/client/client/src/web-access/index.html @@ -24,8 +24,16 @@ on-open="$ctrl.onPassOpen()" on-response="$ctrl.onPassChange(response)"> - - + + + + diff --git a/client/core/src/components.js b/client/core/src/components.js index 7a258fd3b..5c631ab04 100644 --- a/client/core/src/components.js +++ b/client/core/src/components.js @@ -12,6 +12,7 @@ import './confirm/index'; import './title/index'; import './subtitle/index'; import './spinner/index'; +import './snackbar/index'; export {NAME as BUTTON, directive as ButtonDirective} from './button/button'; export {NAME as BUTTON_MDL, factory as buttonMdl} from './button/button.mdl'; @@ -25,12 +26,8 @@ export {NAME as LABEL, directive as LabelDirective} from './label/label'; export {NAME as LABEL_MDL, factory as labelMdl} from './label/label.mdl'; export {NAME as ICON_BUTTON, directive as IconButtonDirective} from './icon-button/icon-button'; export {NAME as ICON_BUTTON_MDL, factory as iconButtonMdl} from './icon-button/icon-button.mdl'; -export {NAME as PASSWORD, directive as PasswordDirective} from './password/password'; -export {NAME as PASSWORD_MDL, factory as passwordMdl} from './password/password.mdl'; export {NAME as SUBMIT, directive as SubmitDirective} from './submit/submit'; export {NAME as SUBMIT_MDL, factory as submitMdl} from './submit/submit.mdl'; -export {NAME as SNACKBAR, directive as SnackbarDirective} from './snackbar/snackbar'; -export {NAME as SNACKBAR_MDL, factory as snackbarMdl} from './snackbar/snackbar.mdl'; export {NAME as COMBO, directive as ComboDirective} from './combo/combo'; export {NAME as COMBO_MDL, factory as comboMdl} from './combo/combo.mdl'; export {NAME as DATE_PICKER, directive as DatePickerDirective} from './date-picker/date-picker'; diff --git a/client/core/src/config.js b/client/core/src/config.js index 5b627b054..2b5358839 100644 --- a/client/core/src/config.js +++ b/client/core/src/config.js @@ -7,10 +7,10 @@ export function config($translateProvider, $translatePartialLoaderProvider) { let conf = {urlTemplate: '/static/locale/{part}/{lang}.json'}; let langs = ['en', 'es']; let localLangs = { - 'en_US': 'en', - 'en_UK': 'en', - 'es_ES': 'es', - 'es_AR': 'es' + en_US: 'en', + en_UK: 'en', + es_ES: 'es', + es_AR: 'es' }; $translateProvider .useSanitizeValueStrategy('escape') diff --git a/client/core/src/dialog/style.scss b/client/core/src/dialog/style.scss index dba0096c8..659cdb490 100644 --- a/client/core/src/dialog/style.scss +++ b/client/core/src/dialog/style.scss @@ -23,26 +23,25 @@ margin-top: -10em; margin-left: -14em; } - .button-bar { margin-top: 1.5em; text-align: right; - } - button { - background: none; - border: none; - text-transform: uppercase; - font-size: 1.1em; - color: #ffa410; - font-weight: bold; - cursor: pointer; - padding: .5em; - margin: -0.5em; - margin-left: .5em; + button { + background: none; + border: none; + text-transform: uppercase; + font-size: 1.1em; + color: #ffa410; + font-weight: bold; + cursor: pointer; + padding: .5em; + margin: -0.5em; + margin-left: .5em; - &:hover { - background-color: rgba(1,1,1,.1); + &:hover { + background-color: rgba(1,1,1,.1); + } } } } diff --git a/client/core/src/module.js b/client/core/src/module.js index d366003db..f96557167 100644 --- a/client/core/src/module.js +++ b/client/core/src/module.js @@ -1,6 +1,5 @@ import * as vendors from 'vendor'; -import {getModuleName, getVendorDependencies} from './lib/util'; +import {getVendorDependencies} from './lib/util'; const DEPENDENCIES = getVendorDependencies(vendors); -export const NAME = getModuleName('core'); -export const module = vendors.ng.module(NAME, DEPENDENCIES); +export const module = vendors.ng.module('vnCore', DEPENDENCIES); diff --git a/client/core/src/password/password.js b/client/core/src/password/password.js deleted file mode 100644 index 3ab7090d1..000000000 --- a/client/core/src/password/password.js +++ /dev/null @@ -1,27 +0,0 @@ -import {module as _module} from '../module'; -import * as resolveFactory from '../lib/resolveDefaultComponents'; -import * as normalizerFactory from '../lib/inputAttrsNormalizer'; -import * as util from '../lib/util'; - -const _NAME = 'password'; -export const NAME = util.getName(_NAME); - -directive.$inject = [resolveFactory.NAME, normalizerFactory.NAME]; -export function directive(resolve, normalizer) { - return { - restrict: 'E', - template: function(_, attrs) { - normalizer.normalize(attrs); - return resolve.getTemplate(_NAME, attrs); - }, - link: function(scope, element, attrs) { - scope.$watch(attrs.model, () => { - let mdlField = element[0].firstChild.MaterialTextfield; - if (mdlField) - mdlField.updateClasses_(); - }); - componentHandler.upgradeElement(element[0].firstChild); - } - } -} -_module.directive(NAME,directive); diff --git a/client/core/src/password/password.mdl.html b/client/core/src/password/password.mdl.html deleted file mode 100644 index a1daf50d4..000000000 --- a/client/core/src/password/password.mdl.html +++ /dev/null @@ -1,4 +0,0 @@ -
- - -
diff --git a/client/core/src/password/password.mdl.js b/client/core/src/password/password.mdl.js deleted file mode 100644 index a4102ef60..000000000 --- a/client/core/src/password/password.mdl.js +++ /dev/null @@ -1,17 +0,0 @@ -import {module} from '../module'; -import template from './password.mdl.html'; - -export const NAME = 'vnPasswordMdlFactory'; - -export function factory() { - return { - template: template, - default: { - label: 'Password', - enabled: 'enabled', - className: 'mdl-textfield--floating-label' - } - } -} - -module.factory(NAME, factory); diff --git a/client/core/src/snackbar/snackbar.mdl.html b/client/core/src/snackbar/index.html similarity index 57% rename from client/core/src/snackbar/snackbar.mdl.html rename to client/core/src/snackbar/index.html index 7b78a7c52..6f99d5fdb 100644 --- a/client/core/src/snackbar/snackbar.mdl.html +++ b/client/core/src/snackbar/index.html @@ -1,4 +1,4 @@ -
+
diff --git a/client/core/src/snackbar/index.js b/client/core/src/snackbar/index.js new file mode 100644 index 000000000..ce76c1ba3 --- /dev/null +++ b/client/core/src/snackbar/index.js @@ -0,0 +1,25 @@ +import {module} from '../module'; + +/** + * A simple component to show non-obstructive notifications to the user. + */ +export default class Controller { + constructor($element) { + this.snackbar = $element[0].firstChild; + componentHandler.upgradeElement(this.snackbar); + } + /** + * Shows a notification. + * + * @param {Object} data The message data + */ + show(data) { + this.snackbar.MaterialSnackbar.showSnackbar(data); + } +} +Controller.$inject = ['$element']; + +module.component('vnSnackbar', { + template: require('./index.html'), + controller: Controller +}); diff --git a/client/core/src/snackbar/snackbar.js b/client/core/src/snackbar/snackbar.js deleted file mode 100644 index 43cbf1903..000000000 --- a/client/core/src/snackbar/snackbar.js +++ /dev/null @@ -1,28 +0,0 @@ -import {module} from '../module'; -import * as resolveFactory from '../lib/resolveDefaultComponents'; -import * as util from '../lib/util'; - -const _NAME = 'snackbar'; -export const NAME = util.getName(_NAME); - -directive.$inject = [resolveFactory.NAME]; -export function directive(resolve) { - return { - restrict: 'E', - template: function(_, attrs) { - return resolve.getTemplate(_NAME, attrs); - }, - controller: controller - } -} -module.directive(NAME, directive); - -controller.$inject = ['$scope', '$element']; -function controller($scope, $element) { - let snackbar = $element[0].firstChild; - componentHandler.upgradeElement (snackbar); - - this.show = function(data) { - snackbar.MaterialSnackbar.showSnackbar(data); - } -} \ No newline at end of file diff --git a/client/core/src/snackbar/snackbar.mdl.js b/client/core/src/snackbar/snackbar.mdl.js deleted file mode 100644 index 2811797b5..000000000 --- a/client/core/src/snackbar/snackbar.mdl.js +++ /dev/null @@ -1,15 +0,0 @@ -import {module} from '../module'; -import template from './snackbar.mdl.html'; - -export const NAME = 'vnSnackbarMdlFactory'; - -export function factory() { - return { - template: template, - default: { - message: 'Default message' - } - } -} - -module.factory(NAME, factory); diff --git a/client/core/src/spinner/index.js b/client/core/src/spinner/index.js index 14419a4b7..daf694e1d 100644 --- a/client/core/src/spinner/index.js +++ b/client/core/src/spinner/index.js @@ -14,8 +14,8 @@ export default class Spinner extends Component { } /** * Enables/disables the spinner. - * - * @param {Boolean} %true to enable, %false to disable + * + * @param {Boolean} value %true to enable, %false to disable */ set enable(value) { if (value) @@ -25,7 +25,7 @@ export default class Spinner extends Component { } /** * Returns the current spinner state. - * + * * @return {Boolean} %true if it's enabled, %false otherwise */ get enable() { diff --git a/client/core/src/textfield/index.mdl.html b/client/core/src/textfield/index.mdl.html index f697c8790..ce326a7c7 100644 --- a/client/core/src/textfield/index.mdl.html +++ b/client/core/src/textfield/index.mdl.html @@ -6,7 +6,12 @@ ng-model="*[model]*" vn-validation="*[rule]*" *[enabled]*/> - diff --git a/client/core/src/textfield/style.scss b/client/core/src/textfield/style.scss index 006d8bbd2..239068d67 100644 --- a/client/core/src/textfield/style.scss +++ b/client/core/src/textfield/style.scss @@ -1,12 +1,12 @@ vn-textfield { - .mdl-chip__action{ + .mdl-chip__action { position: absolute; top: 0px; right: -6px; margin: 22px 0px; visibility: hidden; } - .material-icons{ + .material-icons { font-size: 18px; } } \ No newline at end of file diff --git a/client/salix/src/bootstrap.js b/client/salix/src/bootstrap.js index 119bbd5f4..b0a57a215 100644 --- a/client/salix/src/bootstrap.js +++ b/client/salix/src/bootstrap.js @@ -1,5 +1,5 @@ import {ng} from 'vendor'; -import {NAME as SALIX} from './module'; +import './module'; export const bootstrap = () => { const selector = 'selector'; @@ -11,7 +11,7 @@ export const bootstrap = () => { let _element = _script && document.querySelector(_script.getAttribute(selector)); if (!_element) { - throw new Error("element is not defined"); + throw new Error('Element is not defined'); } - ng.bootstrap(_element, [SALIX]); + ng.bootstrap(_element, ['salix']); }; diff --git a/client/salix/src/components/main-menu/main-menu.js b/client/salix/src/components/main-menu/main-menu.js index 29b9a1fb4..59f5bb151 100644 --- a/client/salix/src/components/main-menu/main-menu.js +++ b/client/salix/src/components/main-menu/main-menu.js @@ -9,16 +9,14 @@ export const COMPONENT = { }; module.component(NAME, COMPONENT); -controller.$inject = ['$translate']; -function controller($translate, $translatePartialLoader) { +controller.$inject = ['$translate', '$window', '$document']; +function controller($translate, $window, $document) { this.onLogoutClick = function() { - let appName = 'salix'; - document.cookie = `${appName}-session=; expires=Thu, 01 Jan 1970 00:00:01 GMT;`; - window.location = `/auth?api_key=${appName}`; + $window.location = 'salix/logout'; }; this.onChangeLanguage = function() { let lang = $translate.use() == 'en' ? 'es' : 'en'; $translate.use(lang); - console.log (`Locale changed: ${lang}`); + console.log(`Locale changed: ${lang}`); }; } \ No newline at end of file diff --git a/client/salix/src/module.js b/client/salix/src/module.js index 99dbd0b5c..59c1b6d36 100644 --- a/client/salix/src/module.js +++ b/client/salix/src/module.js @@ -1,6 +1,4 @@ -import * as vendors from 'vendor'; -import * as core from 'core'; -import {NAME as CORE} from 'core'; +import {ng} from 'vendor'; +import 'core'; -export const NAME = 'salix'; -export const module = vendors.ng.module(NAME, [CORE]); +export const module = ng.module('salix', ['vnCore']); diff --git a/services/auth/server/application.json b/services/auth/server/application.json index cfdcfc7fd..31f1c422b 100644 --- a/services/auth/server/application.json +++ b/services/auth/server/application.json @@ -1,3 +1,4 @@ { + "default": "salix/login", "salix": "/salix/login" } \ No newline at end of file diff --git a/services/auth/server/boot/createmodel.js b/services/auth/server/boot/createmodel.js deleted file mode 100644 index 1a25759e2..000000000 --- a/services/auth/server/boot/createmodel.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = function(app) { -/* - var User = app.models.User; - User.create ({ - email: 'admin@admin.com', - password: '1234' - }, function (err, user) {}); -*/ -}; diff --git a/services/auth/server/boot/root.js b/services/auth/server/boot/root.js index 3ca07fb25..2b24dd71a 100644 --- a/services/auth/server/boot/root.js +++ b/services/auth/server/boot/root.js @@ -1,12 +1,8 @@ module.exports = function(server) { - // Install a `/` route that returns server status - var router = server.loopback.Router(); + server.enableAuth(); - router.get('/status', server.loopback.status()); - router.get(['/'],function(req,res){ - res.render('index.ejs'); - }); - - server.use(router); + var router = server.loopback.Router(); + router.get('/status', server.loopback.status()); + server.use(router); }; diff --git a/services/auth/server/boot/routes.js b/services/auth/server/boot/routes.js index 7639159e2..dd022bdcc 100644 --- a/services/auth/server/boot/routes.js +++ b/services/auth/server/boot/routes.js @@ -1,32 +1,43 @@ var url = require ('url'); module.exports = function(app) { - var User = app.models.User; - var applications = app.get('applications'); - var queryObject; + let applications = app.get('applications'); - app.post('/', function(req, res) { - User.login({ - email: req.body.email, - password: req.body.password - }, 'user', function(err, token) { - if (err) { - res.status (401); - res.send(JSON.stringify({ - title: 'Login failed', - content: err, - redirectTo: '/', - redirectToLinkText: 'Try again' - })); - } else { - queryObject = url.parse (req.body.appId,true).query; - res.send(JSON.stringify({ - location: applications[queryObject.api_key], - accessToken: token.id - })); - } + app.get('/',function(req, res){ + res.render('index.ejs'); }); - }); -}; -require('q'); + app.post('/login', function(req, res) { + app.models.User.login({ + email: req.body.email, + password: req.body.password + }, 'user', function(err, token) { + if (err) { + res.status (401); + res.send(JSON.stringify({ + title: 'Login failed', + content: err, + redirectTo: '/', + redirectToLinkText: 'Try again' + })); + } else { + let query = url.parse(req.body.location, true).query; + let loginUrl = applications[query.apiKey]; + if (!loginUrl) + loginUrl = applications.default; + + res.send(JSON.stringify({ + token: token.id, + continue: query.continue, + loginUrl: loginUrl, + })); + } + }); + }); + + app.get('/logout', function (req, res) { + app.models.User.logout(req.accessToken.id, function(err) { + res.redirect('/'); + }); + }); +}; diff --git a/services/auth/server/model-config.json b/services/auth/server/model-config.json index 45d293eb7..c4cb72caa 100644 --- a/services/auth/server/model-config.json +++ b/services/auth/server/model-config.json @@ -19,8 +19,7 @@ }, "AccessToken": { "dataSource": "auth", - "public": true, - "strict": true + "public": true }, "ACL": { "dataSource": "auth", diff --git a/services/auth/server/server.js b/services/auth/server/server.js index f873e2c7d..7a917176d 100644 --- a/services/auth/server/server.js +++ b/services/auth/server/server.js @@ -10,7 +10,7 @@ var app = module.exports = loopback(); app.set('view engine', 'ejs'); app.set('views', path.join(__dirname,'../client')); app.use(loopback.static(path.resolve(__dirname, '../client'))); -app.set('applications', require("./application.json")); +app.set('applications', require('./application.json')); // fin app.start = function() { diff --git a/services/client/server/boot/authentication.js b/services/client/server/boot/authentication.js deleted file mode 100644 index 2cd84e88a..000000000 --- a/services/client/server/boot/authentication.js +++ /dev/null @@ -1,4 +0,0 @@ - -module.exports = function(server) { - //server.enableAuth(); -}; diff --git a/services/client/server/boot/root.js b/services/client/server/boot/root.js index 151db3f8d..c541f82d2 100644 --- a/services/client/server/boot/root.js +++ b/services/client/server/boot/root.js @@ -1,5 +1,7 @@ module.exports = function(server) { + server.enableAuth(); + let router = server.loopback.Router(); router.get('/status', server.loopback.status()); server.use(router); diff --git a/services/client/server/model-config.json b/services/client/server/model-config.json index e88f5a3b8..52cde6e4f 100644 --- a/services/client/server/model-config.json +++ b/services/client/server/model-config.json @@ -14,25 +14,19 @@ ] }, "User": { - "dataSource": "auth", - "public": true + "dataSource": "auth" }, "AccessToken": { - "dataSource": "auth", - "public": true, - "strict": true + "dataSource": "auth" }, "ACL": { - "dataSource": "auth", - "public": true + "dataSource": "auth" }, "RoleMapping": { - "dataSource": "auth", - "public": true + "dataSource": "auth" }, "Role": { - "dataSource": "auth", - "public": true + "dataSource": "auth" }, "Client": { "dataSource": "vn", diff --git a/services/salix/package.json b/services/salix/package.json index f8361d598..2eaa676a0 100644 --- a/services/salix/package.json +++ b/services/salix/package.json @@ -11,12 +11,13 @@ "compression": "^1.0.3", "cors": "^2.5.2", "helmet": "^1.3.0", + "loopback": "^2.22.0", "loopback-boot": "^2.6.5", "loopback-component-explorer": "^2.4.0", - "serve-favicon": "^2.0.1", - "strong-error-handler": "^1.0.1", + "loopback-connector-mysql": "^4.1.0", "loopback-datasource-juggler": "^2.39.0", - "loopback": "^2.22.0" + "serve-favicon": "^2.0.1", + "strong-error-handler": "^1.0.1" }, "devDependencies": { "eslint": "^2.13.1", diff --git a/services/salix/server/boot/root.js b/services/salix/server/boot/root.js index 35ea9d574..2b24dd71a 100644 --- a/services/salix/server/boot/root.js +++ b/services/salix/server/boot/root.js @@ -1,8 +1,8 @@ -'use strict'; module.exports = function(server) { - // Install a `/` route that returns server status - var router = server.loopback.Router(); - router.get('/status', server.loopback.status()); - server.use(router); + server.enableAuth(); + + var router = server.loopback.Router(); + router.get('/status', server.loopback.status()); + server.use(router); }; diff --git a/services/salix/server/boot/routes.js b/services/salix/server/boot/routes.js index e776804ae..a590a1218 100644 --- a/services/salix/server/boot/routes.js +++ b/services/salix/server/boot/routes.js @@ -1,24 +1,70 @@ module.exports = function (app) { - var apiKey = app.get('api key'); - var authUrl = app.get('url auth'); - app.get('/', function (req, res) { - if (req.cookies['salix-session']) { - res.render('index.ejs'); - } - else { - res.redirect(`${authUrl}/?api_key=${apiKey}`); - } + let token = req.cookies.vnToken; + validateToken(token, function(isValid) { + if (isValid) + res.render('index.ejs'); + else + redirectToAuth(res, req.get('origin')); + }); }); app.get('/login', function (req, res) { - var token = req.query.access_token; - if (token) { - res.cookie('salix-session', token, { httpOnly: true, path: '/salix' }); - res.redirect('/salix'); - } - else { - res.redirect(authUrl); - } + let token = req.query.token; + let continueUrl = req.query.continue; + + validateToken(token, function(isValid) { + if (isValid) { + res.cookie('vnToken', token, {httpOnly: true}); + res.redirect(continueUrl ? continueUrl : '/salix'); + } + else + redirectToAuth(res); + }); }); + + app.get('/logout', function (req, res) { + let token = req.cookies.vnToken; + app.models.User.logout(token, function(err) { + redirectToAuth(res); + }); + }); + + function validateToken(tokenId, cb) { + if (!tokenId) { + cb(false); + return; + } + + app.models.AccessToken.findById(tokenId, function(err, token) { + if (token) { + token.validate (function (err, isValid) { + cb(isValid === true); + }); + } + else + cb(false); + }); + } + + function redirectToAuth (res, continueUrl) { + let authUrl = app.get('url auth'); + let params = { + apiKey: app.get('api key'), + continue: continueUrl + }; + res.clearCookie ('vnToken'); + res.redirect(`${authUrl}/?${encodeUri(params)}`); + } }; + +function encodeUri(object) { + let uri = ''; + for (var key in object) + if (object[key]) { + if (uri.length > 0) + uri += '&'; + uri += encodeURIComponent(key) + '=' + encodeURIComponent(object[key]); + } + return uri; +} diff --git a/services/salix/server/datasources.json b/services/salix/server/datasources.json index 80b76b0b7..ea04dddf1 100644 --- a/services/salix/server/datasources.json +++ b/services/salix/server/datasources.json @@ -2,5 +2,15 @@ "db": { "name": "db", "connector": "memory" + }, + "auth": { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "" } -} \ No newline at end of file +} diff --git a/services/salix/server/model-config.json b/services/salix/server/model-config.json index c037e528c..e9dbc87cf 100644 --- a/services/salix/server/model-config.json +++ b/services/salix/server/model-config.json @@ -13,9 +13,19 @@ "./mixins" ] }, + "User": { + "dataSource": "auth" + }, "AccessToken": { - "dataSource": "db", - "public": false + "dataSource": "auth" + }, + "ACL": { + "dataSource": "auth" + }, + "RoleMapping": { + "dataSource": "auth" + }, + "Role": { + "dataSource": "auth" } - }