282 lines
10 KiB
Diff
282 lines
10 KiB
Diff
diff --git a/tryton/sao/src/sao.js b/tryton/sao/src/sao.js
|
|
index bc6b3659..d495b9ad 100644
|
|
--- a/tryton/sao/src/sao.js
|
|
+++ b/tryton/sao/src/sao.js
|
|
@@ -649,6 +649,10 @@ var Sao = {
|
|
|
|
Sao.logout = function() {
|
|
var session = Sao.Session.current_session;
|
|
+ if (!session || !session.session) {
|
|
+ // Do not save states if there is no session
|
|
+ Sao.main_menu_screen = null;
|
|
+ }
|
|
Sao.Tab.tabs.close(true).done(function() {
|
|
jQuery('#user-preferences').empty();
|
|
jQuery('#global-search').empty();
|
|
@@ -1153,6 +1157,27 @@ var Sao = {
|
|
}
|
|
|
|
jQuery(document).ready(function() {
|
|
+ var url = new URL(window.location);
|
|
+ if (url.searchParams.has('session')) {
|
|
+ var database = url.searchParams.get('database');
|
|
+ var session = {
|
|
+ login_service: url.searchParams.get('login_service'),
|
|
+ login: url.searchParams.get('login'),
|
|
+ user_id: parseInt(url.searchParams.get('user_id'), 10),
|
|
+ session: url.searchParams.get('session'),
|
|
+ };
|
|
+ if (url.searchParams.has('renew')) {
|
|
+ var renew_id = parseInt(url.searchParams.get('renew'), 10);
|
|
+ if (session.user_id !== renew_id) {
|
|
+ window.close();
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ session = JSON.stringify(session);
|
|
+ localStorage.setItem('sao_session_' + database, session);
|
|
+ window.close();
|
|
+ return;
|
|
+ }
|
|
set_shortcuts();
|
|
try {
|
|
Notification.requestPermission();
|
|
diff --git a/tryton/sao/src/session.js b/tryton/sao/src/session.js
|
|
index 5f4753fc..dfb01dcd 100644
|
|
--- a/tryton/sao/src/session.js
|
|
+++ b/tryton/sao/src/session.js
|
|
@@ -10,6 +10,7 @@
|
|
|
|
Sao.Session = Sao.class_(Object, {
|
|
init: function(database, login) {
|
|
+ this.login_service = null;
|
|
this.user_id = null;
|
|
this.session = null;
|
|
this.cache = new Cache();
|
|
@@ -124,6 +125,7 @@
|
|
if (session_data !== null) {
|
|
session_data = JSON.parse(session_data);
|
|
if (!this.login || this.login == session_data.login) {
|
|
+ this.login_service = session_data.login_service;
|
|
this.login = session_data.login;
|
|
this.user_id = session_data.user_id;
|
|
this.session = session_data.session;
|
|
@@ -215,6 +217,11 @@
|
|
'name': 'login',
|
|
'placeholder': Sao.i18n.gettext('User name')
|
|
});
|
|
+ dialog.button = jQuery('<button/>', {
|
|
+ 'class': 'btn btn-primary btn-block',
|
|
+ 'type': 'submit',
|
|
+ 'title': Sao.i18n.gettext("Login"),
|
|
+ }).text(' ' + Sao.i18n.gettext("Login"));
|
|
dialog.body.append(jQuery('<div/>', {
|
|
'class': 'form-group'
|
|
}).append(jQuery('<label/>', {
|
|
@@ -222,20 +229,22 @@
|
|
'for': 'database'
|
|
}).text(Sao.i18n.gettext('Database')))
|
|
.append(dialog.database_select)
|
|
- .append(dialog.database_input)
|
|
- ).append(jQuery('<div/>', {
|
|
+ .append(dialog.database_input))
|
|
+ .append(jQuery('<div/>', {
|
|
+ 'class': 'panel panel-default',
|
|
+ })
|
|
+ .append(jQuery('<div/>', {
|
|
+ 'class': 'panel-body',
|
|
+ })
|
|
+ .append(jQuery('<div/>', {
|
|
'class': 'form-group'
|
|
}).append(jQuery('<label/>', {
|
|
'class': 'control-label',
|
|
'for': 'login'
|
|
}).text(Sao.i18n.gettext('User name')))
|
|
.append(dialog.login_input)
|
|
- );
|
|
- dialog.button = jQuery('<button/>', {
|
|
- 'class': 'btn btn-primary',
|
|
- 'type': 'submit',
|
|
- 'title': Sao.i18n.gettext("Login"),
|
|
- }).text(' ' + Sao.i18n.gettext("Login")).appendTo(dialog.footer);
|
|
+ )
|
|
+ .append(dialog.button)));
|
|
return dialog;
|
|
};
|
|
|
|
@@ -261,7 +270,11 @@
|
|
});
|
|
};
|
|
|
|
- var ok_func = function() {
|
|
+ var disable_form = function(disabled=true) {
|
|
+ dialog.body.find('input,select,button').prop('disabled', disabled);
|
|
+ };
|
|
+
|
|
+ var login = function() {
|
|
var login = dialog.login_input.val();
|
|
var database = database || dialog.database_select.val() ||
|
|
dialog.database_input.val();
|
|
@@ -271,7 +284,7 @@
|
|
return;
|
|
}
|
|
dialog.button.focus();
|
|
- dialog.button.prop('disabled', true);
|
|
+ disable_form();
|
|
dialog.modal.modal('hide');
|
|
session.database = database;
|
|
session.login = login;
|
|
@@ -284,19 +297,54 @@
|
|
window.location = '#' + database;
|
|
}
|
|
}, function() {
|
|
- dialog.button.prop('disabled', false);
|
|
+ disable_form(false);
|
|
dialog.modal.modal('show');
|
|
empty_field().closest('.form-group').addClass('has-error');
|
|
empty_field().first().focus();
|
|
});
|
|
};
|
|
|
|
+ var login_service = function(evt) {
|
|
+ var database = database || dialog.database_select.val() ||
|
|
+ dialog.database_input.val();
|
|
+ dialog.modal.find('.has-error').removeClass('has-error');
|
|
+ if (!database) {
|
|
+ dialog.database_select
|
|
+ .closest('.form-group').addClass('has-error');
|
|
+ return;
|
|
+ }
|
|
+ disable_form();
|
|
+ var host = window.location.protocol + '//' + window.location.host;
|
|
+ var next = new URL(host + '/');
|
|
+ next.searchParams.append('login_service', evt.data);
|
|
+ var url = new URL(host + '/' + database + evt.data);
|
|
+ url.searchParams.append('next', next.href);
|
|
+ var service_window = window.open(url.href, '_blank', 'popup=1');
|
|
+ const timer = window.setInterval(() => {
|
|
+ if (service_window.closed) {
|
|
+ window.clearInterval(timer);
|
|
+ session.database = database;
|
|
+ session.restore();
|
|
+ if (session.session) {
|
|
+ dfd.resolve(session);
|
|
+ dialog.modal.remove();
|
|
+ if (database_url() != database) {
|
|
+ window.location = '#' + database;
|
|
+ }
|
|
+ } else {
|
|
+ disable_form(false);
|
|
+ empty_field().first().focus();
|
|
+ }
|
|
+ }
|
|
+ }, 500);
|
|
+ };
|
|
+
|
|
dialog.modal.modal({
|
|
backdrop: false,
|
|
keyboard: false
|
|
});
|
|
dialog.modal.find('form').unbind().submit(function(e) {
|
|
- ok_func();
|
|
+ login();
|
|
e.preventDefault();
|
|
});
|
|
dialog.modal.on('shown.bs.modal', function() {
|
|
@@ -324,6 +372,24 @@
|
|
}, function() {
|
|
dialog.database_input.show();
|
|
});
|
|
+
|
|
+ jQuery.when(Sao.Authentication.services()).then(function(services) {
|
|
+ if (services.length) {
|
|
+ var panel_body = jQuery('<div/>', {
|
|
+ 'class': 'panel-body',
|
|
+ }).append(jQuery('<p/>')
|
|
+ .text(Sao.i18n.gettext("Login with")));
|
|
+ dialog.body.append(jQuery('<div/>', {
|
|
+ 'class': 'panel panel-default',
|
|
+ }).append(panel_body));
|
|
+ for (const [name, url] of services) {
|
|
+ panel_body.append(jQuery('<button/>', {
|
|
+ 'class': 'btn btn-block btn-default',
|
|
+ 'type': 'button',
|
|
+ }).text(name).click(url, login_service));
|
|
+ }
|
|
+ }
|
|
+ });
|
|
return dfd.promise();
|
|
};
|
|
|
|
@@ -332,11 +398,36 @@
|
|
return session.prm;
|
|
}
|
|
var dfd = jQuery.Deferred();
|
|
+ session.session = null;
|
|
session.prm = dfd.promise();
|
|
- session.do_login().then(dfd.resolve, function() {
|
|
- Sao.logout();
|
|
- dfd.reject();
|
|
- }).done(function () {
|
|
+ if (!session.login_service) {
|
|
+ session.do_login().then(dfd.resolve, function() {
|
|
+ Sao.logout();
|
|
+ dfd.reject();
|
|
+ });
|
|
+ } else {
|
|
+ session.unstore();
|
|
+ var host = window.location.protocol + '//' + window.location.host;
|
|
+ var next = new URL(host + '/');
|
|
+ next.searchParams.append('login_service', session.login_service);
|
|
+ next.searchParams.append('renew', session.user_id);
|
|
+ var url = new URL(host + '/' + session.database + session.login_service);
|
|
+ url.searchParams.append('next', next.href);
|
|
+ var service_window = window.open(url.href, '_blank', 'popup=1');
|
|
+ const timer = window.setInterval(() => {
|
|
+ if (service_window.closed) {
|
|
+ window.clearInterval(timer);
|
|
+ session.restore();
|
|
+ if (session.session) {
|
|
+ dfd.resolve();
|
|
+ } else {
|
|
+ Sao.logout();
|
|
+ dfd.reject();
|
|
+ }
|
|
+ }
|
|
+ }, 500);
|
|
+ }
|
|
+ dfd.done(function() {
|
|
Sao.Bus.listen();
|
|
});
|
|
return session.prm;
|
|
@@ -485,4 +576,29 @@
|
|
return data.result;
|
|
});
|
|
};
|
|
+
|
|
+ Sao.Authentication = {};
|
|
+
|
|
+ Sao.Authentication.services = function() {
|
|
+ var timeoutID = Sao.common.processing.show();
|
|
+ return jQuery.ajax({
|
|
+ 'contentType': 'application/json',
|
|
+ 'data': JSON.stringify({
|
|
+ 'id': 0,
|
|
+ 'method': 'common.authentication.services',
|
|
+ 'params': []
|
|
+ }),
|
|
+ 'dataType': 'json',
|
|
+ 'url': '/',
|
|
+ 'type': 'post',
|
|
+ 'complete': [function() {
|
|
+ Sao.common.processing.hide(timeoutID);
|
|
+ }]
|
|
+ }).then(function(data) {
|
|
+ Sao.Authentication.services = function() {
|
|
+ return data.result;
|
|
+ };
|
|
+ return data.result;
|
|
+ });
|
|
+ };
|
|
}());
|