Autenticación por token
This commit is contained in:
parent
5db994e263
commit
4eff9d451b
|
@ -9,3 +9,4 @@ rules:
|
||||||
operator-linebreak: 0
|
operator-linebreak: 0
|
||||||
radix: 0
|
radix: 0
|
||||||
guard-for-in: 0
|
guard-for-in: 0
|
||||||
|
camelcase: 0
|
||||||
|
|
|
@ -37,50 +37,10 @@
|
||||||
"name": "Asociar al proceso",
|
"name": "Asociar al proceso",
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"processId": "${command.PickProcess}",
|
"processId": "${command:PickProcess}",
|
||||||
"port": 5858,
|
"port": 5858,
|
||||||
"sourceMaps": false,
|
"sourceMaps": false,
|
||||||
"outFiles": []
|
"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": []
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
export * from './module';
|
import './ngModule';
|
||||||
import './config';
|
import './config';
|
||||||
|
import './login/index';
|
||||||
export {component as Login} from './login/login';
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {module} from './module';
|
import ngModule from './ngModule';
|
||||||
|
|
||||||
config.$inject = ['$translatePartialLoaderProvider', '$httpProvider'];
|
config.$inject = ['$translatePartialLoaderProvider', '$httpProvider'];
|
||||||
export function config($translatePartialLoaderProvider, $httpProvider) {
|
export function config($translatePartialLoaderProvider, $httpProvider) {
|
||||||
|
@ -7,4 +7,4 @@ export function config($translatePartialLoaderProvider, $httpProvider) {
|
||||||
$httpProvider.defaults.useXDomain = true;
|
$httpProvider.defaults.useXDomain = true;
|
||||||
delete $httpProvider.defaults.headers.common['X-Requested-With'];
|
delete $httpProvider.defaults.headers.common['X-Requested-With'];
|
||||||
}
|
}
|
||||||
module.config(config);
|
ngModule.config(config);
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<div>
|
||||||
|
<div class="box-wrapper">
|
||||||
|
<div class="box">
|
||||||
|
<img src="./logo.svg"/>
|
||||||
|
<form name="form" ng-submit="$ctrl.submit()">
|
||||||
|
<vn-textfield label="User" model="$ctrl.email"></vn-textfield>
|
||||||
|
<vn-textfield label="Password" model="$ctrl.password" type="password"></vn-textfield>
|
||||||
|
<div class="footer">
|
||||||
|
<vn-submit label="Enter"></vn-submit>
|
||||||
|
<div class="spinner-wrapper">
|
||||||
|
<vn-spinner enable="$ctrl.loading"></vn-spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
||||||
|
</div>
|
|
@ -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
|
||||||
|
});
|
|
@ -1,18 +0,0 @@
|
||||||
<div>
|
|
||||||
<div class="box-wrapper">
|
|
||||||
<div class="box">
|
|
||||||
<img src="./logo.svg"/>
|
|
||||||
<form name="form" ng-submit="$ctrl.submit()">
|
|
||||||
<vn-textfield label="User" field="$ctrl.model.email"></vn-textfield>
|
|
||||||
<vn-password label="Password" field="$ctrl.model.password"></vn-password>
|
|
||||||
<div class="footer">
|
|
||||||
<vn-submit label="Enter"></vn-submit>
|
|
||||||
<div class="spinner-wrapper">
|
|
||||||
<vn-spinner enable="$ctrl.loading"></vn-spinner>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<vn-snackbar></vn-snackbar>
|
|
||||||
</div>
|
|
|
@ -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});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -44,4 +44,3 @@ vn-login > div {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
import {ng} from 'vendor';
|
|
||||||
import * as core from 'core';
|
|
||||||
|
|
||||||
export const module = ng.module('vnAuth', [core.NAME]);
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import {ng} from 'vendor';
|
||||||
|
import 'core';
|
||||||
|
|
||||||
|
let ngModule = ng.module('vnAuth', ['vnCore']);
|
||||||
|
export default ngModule;
|
|
@ -1,5 +1,4 @@
|
||||||
import {ng} from 'vendor';
|
import {ng} from 'vendor';
|
||||||
import * as core from 'core';
|
import 'core';
|
||||||
|
|
||||||
export const NAME = 'client';
|
export const module = ng.module('client', []);
|
||||||
export const module = ng.module(NAME, []);
|
|
||||||
|
|
|
@ -24,8 +24,16 @@
|
||||||
on-open="$ctrl.onPassOpen()"
|
on-open="$ctrl.onPassOpen()"
|
||||||
on-response="$ctrl.onPassChange(response)">
|
on-response="$ctrl.onPassChange(response)">
|
||||||
<dbody>
|
<dbody>
|
||||||
<vn-password label="New password" model="$ctrl.newPassword"></vn-password>
|
<vn-textfield
|
||||||
<vn-password label="Repeat password" model="$ctrl.repeatPassword"></vn-password>
|
type="password"
|
||||||
|
label="New password"
|
||||||
|
model="$ctrl.newPassword">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-textfield
|
||||||
|
type="password"
|
||||||
|
label="Repeat password"
|
||||||
|
model="$ctrl.repeatPassword">
|
||||||
|
</vn-textfield>
|
||||||
</dbody>
|
</dbody>
|
||||||
<buttons>
|
<buttons>
|
||||||
<button response="CANCEL" translate>Cancel</button>
|
<button response="CANCEL" translate>Cancel</button>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import './confirm/index';
|
||||||
import './title/index';
|
import './title/index';
|
||||||
import './subtitle/index';
|
import './subtitle/index';
|
||||||
import './spinner/index';
|
import './spinner/index';
|
||||||
|
import './snackbar/index';
|
||||||
|
|
||||||
export {NAME as BUTTON, directive as ButtonDirective} from './button/button';
|
export {NAME as BUTTON, directive as ButtonDirective} from './button/button';
|
||||||
export {NAME as BUTTON_MDL, factory as buttonMdl} from './button/button.mdl';
|
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 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, 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 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, directive as SubmitDirective} from './submit/submit';
|
||||||
export {NAME as SUBMIT_MDL, factory as submitMdl} from './submit/submit.mdl';
|
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, directive as ComboDirective} from './combo/combo';
|
||||||
export {NAME as COMBO_MDL, factory as comboMdl} from './combo/combo.mdl';
|
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';
|
export {NAME as DATE_PICKER, directive as DatePickerDirective} from './date-picker/date-picker';
|
||||||
|
|
|
@ -7,10 +7,10 @@ export function config($translateProvider, $translatePartialLoaderProvider) {
|
||||||
let conf = {urlTemplate: '/static/locale/{part}/{lang}.json'};
|
let conf = {urlTemplate: '/static/locale/{part}/{lang}.json'};
|
||||||
let langs = ['en', 'es'];
|
let langs = ['en', 'es'];
|
||||||
let localLangs = {
|
let localLangs = {
|
||||||
'en_US': 'en',
|
en_US: 'en',
|
||||||
'en_UK': 'en',
|
en_UK: 'en',
|
||||||
'es_ES': 'es',
|
es_ES: 'es',
|
||||||
'es_AR': 'es'
|
es_AR: 'es'
|
||||||
};
|
};
|
||||||
$translateProvider
|
$translateProvider
|
||||||
.useSanitizeValueStrategy('escape')
|
.useSanitizeValueStrategy('escape')
|
||||||
|
|
|
@ -23,26 +23,25 @@
|
||||||
margin-top: -10em;
|
margin-top: -10em;
|
||||||
margin-left: -14em;
|
margin-left: -14em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-bar {
|
.button-bar {
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
color: #ffa410;
|
color: #ffa410;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: .5em;
|
padding: .5em;
|
||||||
margin: -0.5em;
|
margin: -0.5em;
|
||||||
margin-left: .5em;
|
margin-left: .5em;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(1,1,1,.1);
|
background-color: rgba(1,1,1,.1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import * as vendors from 'vendor';
|
import * as vendors from 'vendor';
|
||||||
import {getModuleName, getVendorDependencies} from './lib/util';
|
import {getVendorDependencies} from './lib/util';
|
||||||
|
|
||||||
const DEPENDENCIES = getVendorDependencies(vendors);
|
const DEPENDENCIES = getVendorDependencies(vendors);
|
||||||
export const NAME = getModuleName('core');
|
export const module = vendors.ng.module('vnCore', DEPENDENCIES);
|
||||||
export const module = vendors.ng.module(NAME, DEPENDENCIES);
|
|
||||||
|
|
|
@ -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);
|
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="mdl-textfield mdl-js-textfield *[className]*">
|
|
||||||
<input class="mdl-textfield__input" type="password" name="*[name]*" ng-model="*[model]*" rule="*[rule]*" *[enabled]*/>
|
|
||||||
<label class="mdl-textfield__label" translate>*[label]*</label>
|
|
||||||
</div>
|
|
|
@ -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);
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="mdl-js-snackbar mdl-snackbar *[className]*" style="z-index: 200;">
|
<div class="mdl-js-snackbar mdl-snackbar" style="z-index: 200;">
|
||||||
<div class="mdl-snackbar__text"></div>
|
<div class="mdl-snackbar__text"></div>
|
||||||
<button class="mdl-snackbar__action" type="button"></button>
|
<button class="mdl-snackbar__action" type="button"></button>
|
||||||
</div>
|
</div>
|
|
@ -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
|
||||||
|
});
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
|
@ -14,8 +14,8 @@ export default class Spinner extends Component {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Enables/disables the spinner.
|
* Enables/disables the spinner.
|
||||||
*
|
*
|
||||||
* @param {Boolean} %true to enable, %false to disable
|
* @param {Boolean} value %true to enable, %false to disable
|
||||||
*/
|
*/
|
||||||
set enable(value) {
|
set enable(value) {
|
||||||
if (value)
|
if (value)
|
||||||
|
@ -25,7 +25,7 @@ export default class Spinner extends Component {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns the current spinner state.
|
* Returns the current spinner state.
|
||||||
*
|
*
|
||||||
* @return {Boolean} %true if it's enabled, %false otherwise
|
* @return {Boolean} %true if it's enabled, %false otherwise
|
||||||
*/
|
*/
|
||||||
get enable() {
|
get enable() {
|
||||||
|
|
|
@ -6,7 +6,12 @@
|
||||||
ng-model="*[model]*"
|
ng-model="*[model]*"
|
||||||
vn-validation="*[rule]*"
|
vn-validation="*[rule]*"
|
||||||
*[enabled]*/>
|
*[enabled]*/>
|
||||||
<button type="button" class="mdl-chip__action" title="Clear text">
|
<button
|
||||||
|
type="button"
|
||||||
|
class="mdl-chip__action"
|
||||||
|
tabindex="-1"
|
||||||
|
title="Clear text"
|
||||||
|
style="visibility: hidden">
|
||||||
<i class="material-icons">clear</i>
|
<i class="material-icons">clear</i>
|
||||||
</button>
|
</button>
|
||||||
<label class="mdl-textfield__label" translate>*[label]*</label>
|
<label class="mdl-textfield__label" translate>*[label]*</label>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
vn-textfield {
|
vn-textfield {
|
||||||
.mdl-chip__action{
|
.mdl-chip__action {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
right: -6px;
|
right: -6px;
|
||||||
margin: 22px 0px;
|
margin: 22px 0px;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
.material-icons{
|
.material-icons {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import {ng} from 'vendor';
|
import {ng} from 'vendor';
|
||||||
import {NAME as SALIX} from './module';
|
import './module';
|
||||||
|
|
||||||
export const bootstrap = () => {
|
export const bootstrap = () => {
|
||||||
const selector = 'selector';
|
const selector = 'selector';
|
||||||
|
@ -11,7 +11,7 @@ export const bootstrap = () => {
|
||||||
|
|
||||||
let _element = _script && document.querySelector(_script.getAttribute(selector));
|
let _element = _script && document.querySelector(_script.getAttribute(selector));
|
||||||
if (!_element) {
|
if (!_element) {
|
||||||
throw new Error("element is not defined");
|
throw new Error('Element is not defined');
|
||||||
}
|
}
|
||||||
ng.bootstrap(_element, [SALIX]);
|
ng.bootstrap(_element, ['salix']);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,16 +9,14 @@ export const COMPONENT = {
|
||||||
};
|
};
|
||||||
module.component(NAME, COMPONENT);
|
module.component(NAME, COMPONENT);
|
||||||
|
|
||||||
controller.$inject = ['$translate'];
|
controller.$inject = ['$translate', '$window', '$document'];
|
||||||
function controller($translate, $translatePartialLoader) {
|
function controller($translate, $window, $document) {
|
||||||
this.onLogoutClick = function() {
|
this.onLogoutClick = function() {
|
||||||
let appName = 'salix';
|
$window.location = 'salix/logout';
|
||||||
document.cookie = `${appName}-session=; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
|
|
||||||
window.location = `/auth?api_key=${appName}`;
|
|
||||||
};
|
};
|
||||||
this.onChangeLanguage = function() {
|
this.onChangeLanguage = function() {
|
||||||
let lang = $translate.use() == 'en' ? 'es' : 'en';
|
let lang = $translate.use() == 'en' ? 'es' : 'en';
|
||||||
$translate.use(lang);
|
$translate.use(lang);
|
||||||
console.log (`Locale changed: ${lang}`);
|
console.log(`Locale changed: ${lang}`);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,6 +1,4 @@
|
||||||
import * as vendors from 'vendor';
|
import {ng} from 'vendor';
|
||||||
import * as core from 'core';
|
import 'core';
|
||||||
import {NAME as CORE} from 'core';
|
|
||||||
|
|
||||||
export const NAME = 'salix';
|
export const module = ng.module('salix', ['vnCore']);
|
||||||
export const module = vendors.ng.module(NAME, [CORE]);
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
|
"default": "salix/login",
|
||||||
"salix": "/salix/login"
|
"salix": "/salix/login"
|
||||||
}
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
module.exports = function(app) {
|
|
||||||
/*
|
|
||||||
var User = app.models.User;
|
|
||||||
User.create ({
|
|
||||||
email: 'admin@admin.com',
|
|
||||||
password: '1234'
|
|
||||||
}, function (err, user) {});
|
|
||||||
*/
|
|
||||||
};
|
|
|
@ -1,12 +1,8 @@
|
||||||
|
|
||||||
module.exports = function(server) {
|
module.exports = function(server) {
|
||||||
// Install a `/` route that returns server status
|
server.enableAuth();
|
||||||
var router = server.loopback.Router();
|
|
||||||
|
|
||||||
router.get('/status', server.loopback.status());
|
var router = server.loopback.Router();
|
||||||
router.get(['/'],function(req,res){
|
router.get('/status', server.loopback.status());
|
||||||
res.render('index.ejs');
|
server.use(router);
|
||||||
});
|
|
||||||
|
|
||||||
server.use(router);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,32 +1,43 @@
|
||||||
var url = require ('url');
|
var url = require ('url');
|
||||||
|
|
||||||
module.exports = function(app) {
|
module.exports = function(app) {
|
||||||
var User = app.models.User;
|
let applications = app.get('applications');
|
||||||
var applications = app.get('applications');
|
|
||||||
var queryObject;
|
|
||||||
|
|
||||||
app.post('/', function(req, res) {
|
app.get('/',function(req, res){
|
||||||
User.login({
|
res.render('index.ejs');
|
||||||
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
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
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('/');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
},
|
},
|
||||||
"AccessToken": {
|
"AccessToken": {
|
||||||
"dataSource": "auth",
|
"dataSource": "auth",
|
||||||
"public": true,
|
"public": true
|
||||||
"strict": true
|
|
||||||
},
|
},
|
||||||
"ACL": {
|
"ACL": {
|
||||||
"dataSource": "auth",
|
"dataSource": "auth",
|
||||||
|
|
|
@ -10,7 +10,7 @@ var app = module.exports = loopback();
|
||||||
app.set('view engine', 'ejs');
|
app.set('view engine', 'ejs');
|
||||||
app.set('views', path.join(__dirname,'../client'));
|
app.set('views', path.join(__dirname,'../client'));
|
||||||
app.use(loopback.static(path.resolve(__dirname, '../client')));
|
app.use(loopback.static(path.resolve(__dirname, '../client')));
|
||||||
app.set('applications', require("./application.json"));
|
app.set('applications', require('./application.json'));
|
||||||
// fin
|
// fin
|
||||||
|
|
||||||
app.start = function() {
|
app.start = function() {
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
module.exports = function(server) {
|
|
||||||
//server.enableAuth();
|
|
||||||
};
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
|
||||||
module.exports = function(server) {
|
module.exports = function(server) {
|
||||||
|
server.enableAuth();
|
||||||
|
|
||||||
let router = server.loopback.Router();
|
let router = server.loopback.Router();
|
||||||
router.get('/status', server.loopback.status());
|
router.get('/status', server.loopback.status());
|
||||||
server.use(router);
|
server.use(router);
|
||||||
|
|
|
@ -14,25 +14,19 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"User": {
|
"User": {
|
||||||
"dataSource": "auth",
|
"dataSource": "auth"
|
||||||
"public": true
|
|
||||||
},
|
},
|
||||||
"AccessToken": {
|
"AccessToken": {
|
||||||
"dataSource": "auth",
|
"dataSource": "auth"
|
||||||
"public": true,
|
|
||||||
"strict": true
|
|
||||||
},
|
},
|
||||||
"ACL": {
|
"ACL": {
|
||||||
"dataSource": "auth",
|
"dataSource": "auth"
|
||||||
"public": true
|
|
||||||
},
|
},
|
||||||
"RoleMapping": {
|
"RoleMapping": {
|
||||||
"dataSource": "auth",
|
"dataSource": "auth"
|
||||||
"public": true
|
|
||||||
},
|
},
|
||||||
"Role": {
|
"Role": {
|
||||||
"dataSource": "auth",
|
"dataSource": "auth"
|
||||||
"public": true
|
|
||||||
},
|
},
|
||||||
"Client": {
|
"Client": {
|
||||||
"dataSource": "vn",
|
"dataSource": "vn",
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
"compression": "^1.0.3",
|
"compression": "^1.0.3",
|
||||||
"cors": "^2.5.2",
|
"cors": "^2.5.2",
|
||||||
"helmet": "^1.3.0",
|
"helmet": "^1.3.0",
|
||||||
|
"loopback": "^2.22.0",
|
||||||
"loopback-boot": "^2.6.5",
|
"loopback-boot": "^2.6.5",
|
||||||
"loopback-component-explorer": "^2.4.0",
|
"loopback-component-explorer": "^2.4.0",
|
||||||
"serve-favicon": "^2.0.1",
|
"loopback-connector-mysql": "^4.1.0",
|
||||||
"strong-error-handler": "^1.0.1",
|
|
||||||
"loopback-datasource-juggler": "^2.39.0",
|
"loopback-datasource-juggler": "^2.39.0",
|
||||||
"loopback": "^2.22.0"
|
"serve-favicon": "^2.0.1",
|
||||||
|
"strong-error-handler": "^1.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^2.13.1",
|
"eslint": "^2.13.1",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = function(server) {
|
module.exports = function(server) {
|
||||||
// Install a `/` route that returns server status
|
server.enableAuth();
|
||||||
var router = server.loopback.Router();
|
|
||||||
router.get('/status', server.loopback.status());
|
var router = server.loopback.Router();
|
||||||
server.use(router);
|
router.get('/status', server.loopback.status());
|
||||||
|
server.use(router);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,24 +1,70 @@
|
||||||
module.exports = function (app) {
|
module.exports = function (app) {
|
||||||
var apiKey = app.get('api key');
|
|
||||||
var authUrl = app.get('url auth');
|
|
||||||
|
|
||||||
app.get('/', function (req, res) {
|
app.get('/', function (req, res) {
|
||||||
if (req.cookies['salix-session']) {
|
let token = req.cookies.vnToken;
|
||||||
res.render('index.ejs');
|
validateToken(token, function(isValid) {
|
||||||
}
|
if (isValid)
|
||||||
else {
|
res.render('index.ejs');
|
||||||
res.redirect(`${authUrl}/?api_key=${apiKey}`);
|
else
|
||||||
}
|
redirectToAuth(res, req.get('origin'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/login', function (req, res) {
|
app.get('/login', function (req, res) {
|
||||||
var token = req.query.access_token;
|
let token = req.query.token;
|
||||||
if (token) {
|
let continueUrl = req.query.continue;
|
||||||
res.cookie('salix-session', token, { httpOnly: true, path: '/salix' });
|
|
||||||
res.redirect('/salix');
|
validateToken(token, function(isValid) {
|
||||||
}
|
if (isValid) {
|
||||||
else {
|
res.cookie('vnToken', token, {httpOnly: true});
|
||||||
res.redirect(authUrl);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -2,5 +2,15 @@
|
||||||
"db": {
|
"db": {
|
||||||
"name": "db",
|
"name": "db",
|
||||||
"connector": "memory"
|
"connector": "memory"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"name": "mysql",
|
||||||
|
"connector": "mysql",
|
||||||
|
"database": "salix",
|
||||||
|
"debug": false,
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 3306,
|
||||||
|
"username": "root",
|
||||||
|
"password": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,19 @@
|
||||||
"./mixins"
|
"./mixins"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"User": {
|
||||||
|
"dataSource": "auth"
|
||||||
|
},
|
||||||
"AccessToken": {
|
"AccessToken": {
|
||||||
"dataSource": "db",
|
"dataSource": "auth"
|
||||||
"public": false
|
},
|
||||||
|
"ACL": {
|
||||||
|
"dataSource": "auth"
|
||||||
|
},
|
||||||
|
"RoleMapping": {
|
||||||
|
"dataSource": "auth"
|
||||||
|
},
|
||||||
|
"Role": {
|
||||||
|
"dataSource": "auth"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue