From c645479800e5e5f07cfed68f7cb2540591a4d403 Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Thu, 26 Mar 2020 20:15:55 +0100 Subject: [PATCH 1/6] CORS: Add "origin" accessor to portal requests --- lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm index 92931ad06..d6be65a46 100644 --- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm @@ -69,6 +69,7 @@ sub encodings { $_[0]->env->{HTTP_ACCEPT_ENCODING} } sub languages { $_[0]->env->{HTTP_ACCEPT_LANGUAGE} } sub authorization { $_[0]->env->{HTTP_AUTHORIZATION} } sub hostname { $_[0]->env->{HTTP_HOST} } +sub origin { $_[0]->env->{HTTP_ORIGIN} } sub referer { $_[0]->env->{REFERER} } sub query_string { $_[0]->env->{QUERY_STRING} } From 2440fc7866cb2408feed552c2f18c0d8a0cb0a47 Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Thu, 26 Mar 2020 20:18:37 +0100 Subject: [PATCH 2/6] use sendJSONresponse instead of handcrafting portal response --- .../lib/Lemonldap/NG/Portal/Main/Run.pm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index c131250e2..7384193d7 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -260,11 +260,15 @@ sub do { if ( !$self->conf->{noAjaxHook} and $req->wantJSON ) { $self->logger->debug('Processing to JSON response'); if ( ( $err > 0 and !$req->id ) or $err eq PE_SESSIONNOTGRANTED ) { - return [ - 401, - [ 'WWW-Authenticate' => "SSO " . $self->conf->{portal} ], - [qq'{"result":0,"error":$err}'] - ]; + return $self->sendJSONresponse( + $req, + { result => 0, error => $err }, + code => 401, + headers => [ + 'WWW-Authenticate' => "SSO " . $self->conf->{portal}, + "Content-Type" => "application/javascript" + ], + ); } elsif ( $err > 0 and $err != PE_PASSWORD_OK and $err != PE_LOGOUT_OK ) { return $self->sendJSONresponse( From e1767abfda77e939ccfde2aa5ff355c24bcde519 Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Thu, 26 Mar 2020 20:19:38 +0100 Subject: [PATCH 3/6] CORS: special handling for AJAX SSL (#2110) --- .../lib/Lemonldap/NG/Portal/Main/Run.pm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index 7384193d7..52216c5b7 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -1100,7 +1100,19 @@ sub corsPreflight { sub sendJSONresponse { my ( $self, $req, $j, %args ) = @_; my $res = Lemonldap::NG::Common::PSGI::sendJSONresponse(@_); - if ( $self->conf->{corsEnabled} ) { + + # If this is a cross-domain request from the portal itself + # (Ajax SSL to a different VHost) + # we allow CORS + if ( $req->origin and index( $self->conf->{portal}, $req->origin ) == 0 ) { + $self->logger->debug('AJAX request from portal, allowing CORS'); + push @{ $res->[1] }, + "Access-Control-Allow-Origin" => $req->origin, + "Access-Control-Allow-Methods" => "*", + "Access-Control-Allow-Credentials" => "true"; + + } + elsif ( $self->conf->{corsEnabled} ) { my @cors = split /;/, $self->cors; push @{ $res->[1] }, @cors; $self->logger->debug('Apply following CORS policy :'); From 8c94bf0f13ed0cac351a80025602ac430a6e9309 Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Fri, 27 Mar 2020 19:08:23 +0100 Subject: [PATCH 4/6] Allow portal JSON responses to include a rendered HTML error block (#2110) --- lemonldap-ng-portal/MANIFEST | 1 + .../lib/Lemonldap/NG/Portal/Main/Request.pm | 4 ++++ .../lib/Lemonldap/NG/Portal/Main/Run.pm | 16 +++++++++++++--- .../site/templates/bootstrap/errormsg.tpl | 7 +++++++ 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 lemonldap-ng-portal/site/templates/bootstrap/errormsg.tpl diff --git a/lemonldap-ng-portal/MANIFEST b/lemonldap-ng-portal/MANIFEST index 2f8ee2573..f5d76e51e 100644 --- a/lemonldap-ng-portal/MANIFEST +++ b/lemonldap-ng-portal/MANIFEST @@ -392,6 +392,7 @@ site/templates/bootstrap/customLoginFooter.tpl site/templates/bootstrap/customLoginHeader.tpl site/templates/bootstrap/decryptvalue.tpl site/templates/bootstrap/error.tpl +site/templates/bootstrap/errormsg.tpl site/templates/bootstrap/ext2fcheck.tpl site/templates/bootstrap/footer.tpl site/templates/bootstrap/globallogout.tpl diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Request.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Request.pm index f2916c541..63e85c388 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Request.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Request.pm @@ -80,6 +80,10 @@ has captcha => ( is => 'rw' ); # Token has token => ( is => 'rw' ); +# Whether or not to include a HTML render of the error message +# in error responses +has wantErrorRender => ( is => 'rw' ); + # Error type sub error_type { my $req = shift; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index 52216c5b7..b348191de 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -260,9 +260,19 @@ sub do { if ( !$self->conf->{noAjaxHook} and $req->wantJSON ) { $self->logger->debug('Processing to JSON response'); if ( ( $err > 0 and !$req->id ) or $err eq PE_SESSIONNOTGRANTED ) { + my $json = { result => 0, error => $err }; + if ( $req->wantErrorRender ) { + $json->{html} = $self->loadTemplate( + $req, + 'errormsg', + params => { + AUTH_ERROR => $err, + AUTH_ERROR_TYPE => $req->error_type, + } + ); + } return $self->sendJSONresponse( - $req, - { result => 0, error => $err }, + $req, $json, code => 401, headers => [ 'WWW-Authenticate' => "SSO " . $self->conf->{portal}, @@ -1045,7 +1055,7 @@ sub registerLogin { } my $history = $req->sessionInfo->{_loginHistory} ||= {}; - my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login'; + my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login'; $history->{$type} ||= []; $self->logger->debug("Current login saved into $type"); diff --git a/lemonldap-ng-portal/site/templates/bootstrap/errormsg.tpl b/lemonldap-ng-portal/site/templates/bootstrap/errormsg.tpl new file mode 100644 index 000000000..70530cb53 --- /dev/null +++ b/lemonldap-ng-portal/site/templates/bootstrap/errormsg.tpl @@ -0,0 +1,7 @@ + +
alert">"> + + seconds. + +
+
From 05a23480b00e0cd58c9b384b3118340015062055 Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Fri, 27 Mar 2020 19:03:56 +0100 Subject: [PATCH 5/6] Remember selected choice tab when doing a page refresh in JS (#2110) --- lemonldap-ng-portal/site/coffee/portal.coffee | 5 +++++ .../site/htdocs/static/bootstrap/js/skin.js | 7 ++++++- .../site/htdocs/static/bootstrap/js/skin.min.js | 2 +- .../site/htdocs/static/bootstrap/js/skin.min.js.map | 2 +- lemonldap-ng-portal/site/htdocs/static/common/js/portal.js | 3 +++ .../site/htdocs/static/common/js/portal.min.js | 2 +- .../site/htdocs/static/common/js/portal.min.js.map | 2 +- 7 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lemonldap-ng-portal/site/coffee/portal.coffee b/lemonldap-ng-portal/site/coffee/portal.coffee index d0fb426c8..aeeca46e9 100644 --- a/lemonldap-ng-portal/site/coffee/portal.coffee +++ b/lemonldap-ng-portal/site/coffee/portal.coffee @@ -227,6 +227,11 @@ datas = {} $(window).on 'load', () -> # Get application/init variables datas = getValues() + + # Keep the currently selected tab + if "datas" of window && "choicetab" of window.datas + datas.choicetab = window.datas.choicetab; + # Export datas for other scripts window.datas = datas diff --git a/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.js b/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.js index 98a833b4e..390dd86e4 100644 --- a/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.js +++ b/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.js @@ -1,4 +1,4 @@ -$(document).ready(function() { +$(window).on("load", function() { // Adapt some class to fit Bootstrap theme $("div.message-positive").addClass("alert-success"); @@ -16,4 +16,9 @@ $(document).ready(function() { } }); + // Remember selected tab + $('#authMenu .nav-link').on('click', function (e) { + window.datas.choicetab = e.target.hash.substr(1) + }); + }); diff --git a/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js b/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js index 9de89e351..16b7c52aa 100644 --- a/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js +++ b/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js @@ -1 +1 @@ -$(document).ready(function(){$("div.message-positive").addClass("alert-success"),$("div.message-warning").addClass("alert-warning"),$("div.message-negative").addClass("alert-danger"),$("table.info").addClass("table"),$(".notifCheck").addClass("checkbox"),$('.collapse li[class!="dropdown"]').on("click",function(){$(".navbar-toggler").hasClass("collapsed")||$(".navbar-toggler").trigger("click")})}); \ No newline at end of file +$(window).on("load",function(){$("div.message-positive").addClass("alert-success"),$("div.message-warning").addClass("alert-warning"),$("div.message-negative").addClass("alert-danger"),$("table.info").addClass("table"),$(".notifCheck").addClass("checkbox"),$('.collapse li[class!="dropdown"]').on("click",function(){$(".navbar-toggler").hasClass("collapsed")||$(".navbar-toggler").trigger("click")}),$("#authMenu .nav-link").on("click",function(a){window.datas.choicetab=a.target.hash.substr(1)})}); \ No newline at end of file diff --git a/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js.map b/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js.map index 57bd24649..8c7979360 100644 --- a/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js.map +++ b/lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.js"],"names":["$","document","ready","addClass","on","hasClass","trigger"],"mappings":"AAAAA,EAAEC,UAAUC,MAAM,WAGhBF,EAAE,wBAAwBG,SAAS,iBACnCH,EAAE,uBAAuBG,SAAS,iBAClCH,EAAE,wBAAwBG,SAAS,gBAEnCH,EAAE,cAAcG,SAAS,SAEzBH,EAAE,eAAeG,SAAS,YAG1BH,EAAE,mCAAmCI,GAAG,QAAS,WAC1CJ,EAAE,mBAAmBK,SAAS,cACjCL,EAAE,mBAAmBM,QAAQ"} \ No newline at end of file +{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/bootstrap/js/skin.js"],"names":["$","window","on","addClass","hasClass","trigger","e","datas","choicetab","target","hash","substr"],"mappings":"AAAAA,EAAEC,QAAQC,GAAG,OAAQ,WAGnBF,EAAE,wBAAwBG,SAAS,iBACnCH,EAAE,uBAAuBG,SAAS,iBAClCH,EAAE,wBAAwBG,SAAS,gBAEnCH,EAAE,cAAcG,SAAS,SAEzBH,EAAE,eAAeG,SAAS,YAG1BH,EAAE,mCAAmCE,GAAG,QAAS,WAC1CF,EAAE,mBAAmBI,SAAS,cACjCJ,EAAE,mBAAmBK,QAAQ,WAKjCL,EAAE,uBAAuBE,GAAG,QAAS,SAAUI,GAC3CL,OAAOM,MAAMC,UAAYF,EAAEG,OAAOC,KAAKC,OAAO"} \ No newline at end of file diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/portal.js b/lemonldap-ng-portal/site/htdocs/static/common/js/portal.js index 0dc825253..4a2d7bc19 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/portal.js +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/portal.js @@ -225,6 +225,9 @@ LemonLDAP::NG Portal jQuery scripts $(window).on('load', function() { var action, al, authMenuIndex, authMenuTabs, back_url, i, l, lang, langdiv, langs, langs2, len, len1, len2, len3, link, m, menuIndex, menuTabs, method, n, nl, nlangs, queryLang, queryString, re, ref, ref1, ref2, setCookieLang, urlParams; datas = getValues(); + if ("datas" in window && "choicetab" in window.datas) { + datas.choicetab = window.datas.choicetab; + } window.datas = datas; $("#appslist").sortable({ axis: "y", diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/portal.min.js b/lemonldap-ng-portal/site/htdocs/static/common/js/portal.min.js index 8035e0494..87b2b1cad 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/portal.min.js +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/portal.min.js @@ -1 +1 @@ -(function(){var D,e,I,C,_,M,N,R,t,U,f,i,A,l,J=[].indexOf||function(t){for(var e=0,n=this.length;e div.category",update:function(){return U()}}),N(),$("div.message").fadeIn("slow"),$("input[name=timezone]").val(-(new Date).getTimezoneOffset()/60),v=$("#menu").tabs({active:0}),(w=$('#menu a[href="#'+D.displaytab+'"]').parent().index())<0&&(w=0),v.tabs("option","active",w),a=$("#authMenu").tabs({active:0}),(n=$('#authMenu a[href="#'+D.displaytab+'"]').parent().index())<0&&(n=0),a.tabs("option","active",n),D.choicetab&&a.tabs("option","active",$('#authMenu a[href="#'+D.choicetab+'"]').parent().index()),D.login?$("input[type=password]:first").focus():0===$("input[autofocus]").length&&$("input[type!=hidden]:first").focus(),D.newwindow&&$("#appslist a").attr("target","_blank"),$("p.removeOther").length&&(t=$("form.login").attr("action"),b=$("form.login").attr("method"),r="",-1!==t.indexOf("?")?t.substring(0,t.indexOf("?")):r=t+"?",$("form.login input[type=hidden]").each(function(t){return r+="&"+$(this).attr("name")+"="+$(this).val()}),d=$("p.removeOther a").attr("href")+"&method="+b+"&url="+btoa(r),$("p.removeOther a").attr("href",d)),(k=window.location.search)&&(console.log("Parsed queryString:",k),G=new URLSearchParams(k)),G&&((O=G.get("llnglanguage"))&&console.log("Get lang from parameter"),1===(E=G.get("setCookieLang"))&&console.log("Set lang cookie")),l||(l=I("llnglanguage"))&&!O&&console.log("Get lang from cookie"),l)J.call(window.availableLanguages,l)<0&&(l=window.availableLanguages[0],O||console.log("Get default lang"));else if(navigator){for(c=[],u=[],T=[navigator.language],navigator.languages&&(T=navigator.languages),o=0,g=(S=window.availableLanguages).length;o ';for(i=0,p=T.length;i",O),E&&(console.log("Set lang ->",O),R("llnglanguage",O)),A(O)):(console.log("Selected lang ->",l),R("llnglanguage",l),A(l)),s="",y=0,h=(P=window.availableLanguages).length;y ';return $("#languages").html(s),$(".langicon").on("click",function(){return l=$(this).attr("title"),R("llnglanguage",l),A(l)}),D.pingInterval&&0 div.category",update:function(){return U()}}),N(),$("div.message").fadeIn("slow"),$("input[name=timezone]").val(-(new Date).getTimezoneOffset()/60),v=$("#menu").tabs({active:0}),(m=$('#menu a[href="#'+D.displaytab+'"]').parent().index())<0&&(m=0),v.tabs("option","active",m),a=$("#authMenu").tabs({active:0}),(n=$('#authMenu a[href="#'+D.displaytab+'"]').parent().index())<0&&(n=0),a.tabs("option","active",n),D.choicetab&&a.tabs("option","active",$('#authMenu a[href="#'+D.choicetab+'"]').parent().index()),D.login?$("input[type=password]:first").focus():0===$("input[autofocus]").length&&$("input[type!=hidden]:first").focus(),D.newwindow&&$("#appslist a").attr("target","_blank"),$("p.removeOther").length&&(t=$("form.login").attr("action"),b=$("form.login").attr("method"),r="",-1!==t.indexOf("?")?t.substring(0,t.indexOf("?")):r=t+"?",$("form.login input[type=hidden]").each(function(t){return r+="&"+$(this).attr("name")+"="+$(this).val()}),f=$("p.removeOther a").attr("href")+"&method="+b+"&url="+btoa(r),$("p.removeOther a").attr("href",f)),(k=window.location.search)&&(console.log("Parsed queryString:",k),G=new URLSearchParams(k)),G&&((O=G.get("llnglanguage"))&&console.log("Get lang from parameter"),1===(E=G.get("setCookieLang"))&&console.log("Set lang cookie")),l||(l=I("llnglanguage"))&&!O&&console.log("Get lang from cookie"),l)J.call(window.availableLanguages,l)<0&&(l=window.availableLanguages[0],O||console.log("Get default lang"));else if(navigator){for(c=[],u=[],T=[navigator.language],navigator.languages&&(T=navigator.languages),o=0,g=(S=window.availableLanguages).length;o ';for(i=0,p=T.length;i",O),E&&(console.log("Set lang ->",O),R("llnglanguage",O)),A(O)):(console.log("Selected lang ->",l),R("llnglanguage",l),A(l)),s="",y=0,h=(P=window.availableLanguages).length;y ';return $("#languages").html(s),$(".langicon").on("click",function(){return l=$(this).attr("title"),R("llnglanguage",l),A(l)}),D.pingInterval&&0 Date: Thu, 26 Mar 2020 20:21:09 +0100 Subject: [PATCH 6/6] Improve SSL error reporting (#2110) --- .../lib/Lemonldap/NG/Portal/Auth/SSL.pm | 14 +++++++++ lemonldap-ng-portal/site/coffee/ssl.coffee | 31 +++++++++++++------ .../site/coffee/sslChoice.coffee | 31 +++++++++++++------ .../site/htdocs/static/common/js/ssl.js | 26 ++++++++++------ .../site/htdocs/static/common/js/ssl.min.js | 2 +- .../htdocs/static/common/js/ssl.min.js.map | 2 +- .../site/htdocs/static/common/js/sslChoice.js | 26 ++++++++++------ .../htdocs/static/common/js/sslChoice.min.js | 2 +- .../static/common/js/sslChoice.min.js.map | 2 +- .../site/templates/bootstrap/login.tpl | 16 +++++----- 10 files changed, 101 insertions(+), 51 deletions(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/SSL.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/SSL.pm index 284c38676..bc133274f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/SSL.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/SSL.pm @@ -31,6 +31,13 @@ sub init { # @return Lemonldap::NG::Portal constant sub extractFormInfo { my ( $self, $req ) = @_; + + # If this is the ajax query, allow response to contain HTML code + # to update the portal error message + if ( $req->wantJSON ) { + $req->wantErrorRender(1); + } + my $field = $self->conf->{SSLVar}; if ( $req->env->{SSL_CLIENT_I_DN} ) { $self->logger->debug( @@ -55,6 +62,12 @@ sub extractFormInfo { return PE_BADCERTIFICATE; } elsif ( $self->conf->{sslByAjax} and not $req->param('nossl') ) { + + # If this is the AJAX query + if ( $req->wantJSON ) { + return PE_CERTIFICATEREQUIRED; + } + $self->logger->debug( 'Append ' . $self->{Name} . ' init/script' ); $req->data->{customScript} .= $self->{AjaxInitScript}; $self->logger->debug( @@ -68,6 +81,7 @@ sub extractFormInfo { $req->data->{customScript} .= $self->{AjaxInitScript}; $self->logger->debug( "Send init/script -> " . $req->data->{customScript} ); + return PE_BADCERTIFICATE; } $self->userLogger->warn('No certificate found'); return PE_CERTIFICATEREQUIRED; diff --git a/lemonldap-ng-portal/site/coffee/ssl.coffee b/lemonldap-ng-portal/site/coffee/ssl.coffee index 04571e691..d365bae13 100644 --- a/lemonldap-ng-portal/site/coffee/ssl.coffee +++ b/lemonldap-ng-portal/site/coffee/ssl.coffee @@ -5,12 +5,9 @@ tryssl = () -> console.log 'path -> ', path console.log 'Call URL -> ', window.datas.sslHost $.ajax window.datas.sslHost, - dataType: 'jsonp' - # PE_BADCREDENTIALS - statusCode: - 401: () -> - $('#lform').submit() - console.log 'Error code 401' + dataType: 'json', + xhrFields: + withCredentials: true # If request succeed, cookie is set, posting form to get redirection # or menu success: (data) -> @@ -18,9 +15,23 @@ tryssl = () -> console.log 'Success -> ', data # Case else, will display PE_BADCREDENTIALS or fallback to next auth # backend - error: () -> - sendUrl path - console.log 'Error' + error: (result) -> + # If the AJAX query didn't fire at all, it's probably + # a bad certificate + if result.status == 0 + # We couldn't send the request. + # if client verification is optional, this means + # the certificate was rejected (or some network error) + sendUrl path + # For compatibility with earlier configs, handle PE9 by posting form + if result.responseJSON && 'error' of result.responseJSON && result.responseJSON.error == "9" + sendUrl path + + # If the server sent a html error description, display it + if result.responseJSON && 'html' of result.responseJSON + $('#errormsg').html(result.responseJSON.html); + $(window).trigger('load'); + console.log 'Error during AJAX SSL authentication', result false sendUrl = (path) -> @@ -34,4 +45,4 @@ sendUrl = (path) -> $('#lform').submit() $(document).ready -> - $('.sslclick').on 'click', tryssl \ No newline at end of file + $('.sslclick').on 'click', tryssl diff --git a/lemonldap-ng-portal/site/coffee/sslChoice.coffee b/lemonldap-ng-portal/site/coffee/sslChoice.coffee index ebc35caa9..1b1da6765 100644 --- a/lemonldap-ng-portal/site/coffee/sslChoice.coffee +++ b/lemonldap-ng-portal/site/coffee/sslChoice.coffee @@ -5,12 +5,9 @@ tryssl = () -> console.log 'path -> ', path console.log 'Call URL -> ', window.datas.sslHost $.ajax window.datas.sslHost, - dataType: 'jsonp' - # PE_BADCREDENTIALS - statusCode: - 401: () -> - $('#lformSSL').submit() - console.log 'Error code 401' + dataType: 'json', + xhrFields: + withCredentials: true # If request succeed, cookie is set, posting form to get redirection # or menu success: (data) -> @@ -18,9 +15,23 @@ tryssl = () -> console.log 'Success -> ', data # Case else, will display PE_BADCREDENTIALS or fallback to next auth # backend - error: () -> - sendUrl path - console.log 'Error' + error: (result) -> + # If the AJAX query didn't fire at all, it's probably + # a bad certificate + if result.status == 0 + # We couldn't send the request. + # if client verification is optional, this means + # the certificate was rejected (or some network error) + sendUrl path + # For compatibility with earlier configs, handle PE9 by posting form + if result.responseJSON && 'error' of result.responseJSON && result.responseJSON.error == "9" + sendUrl path + + # If the server sent a html error description, display it + if result.responseJSON && 'html' of result.responseJSON + $('#errormsg').html(result.responseJSON.html); + $(window).trigger('load'); + console.log 'Error during AJAX SSL authentication', result false sendUrl = (path) -> @@ -34,4 +45,4 @@ sendUrl = (path) -> $('#lformSSL').submit() $(document).ready -> - $('.sslclick').on 'click', tryssl \ No newline at end of file + $('.sslclick').on 'click', tryssl diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.js b/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.js index 078a6de79..2a9f924d3 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.js +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.12.7 +// Generated by CoffeeScript 1.12.8 (function() { var sendUrl, tryssl; @@ -8,20 +8,26 @@ console.log('path -> ', path); console.log('Call URL -> ', window.datas.sslHost); $.ajax(window.datas.sslHost, { - dataType: 'jsonp', - statusCode: { - 401: function() { - $('#lform').submit(); - return console.log('Error code 401'); - } + dataType: 'json', + xhrFields: { + withCredentials: true }, success: function(data) { sendUrl(path); return console.log('Success -> ', data); }, - error: function() { - sendUrl(path); - return console.log('Error'); + error: function(result) { + if (result.status === 0) { + sendUrl(path); + } + if (result.responseJSON && 'error' in result.responseJSON && result.responseJSON.error === "9") { + sendUrl(path); + } + if (result.responseJSON && 'html' in result.responseJSON) { + $('#errormsg').html(result.responseJSON.html); + $(window).trigger('load'); + } + return console.log('Error during AJAX SSL authentication', result); } }); return false; diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js b/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js index ce57187c1..45298b2c6 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js @@ -1 +1 @@ -(function(){var t,o;o=function(){var n;return n=window.location.pathname,console.log("path -> ",n),console.log("Call URL -> ",window.datas.sslHost),$.ajax(window.datas.sslHost,{dataType:"jsonp",statusCode:{401:function(){return $("#lform").submit(),console.log("Error code 401")}},success:function(o){return t(n),console.log("Success -> ",o)},error:function(){return t(n),console.log("Error")}}),!1},t=function(o){var n;return(n=$("#lform").attr("action")).match(/^#$/)?n=o:n+=o,console.log("form action URL -> ",n),$("#lform").attr("action",n),$("#lform").submit()},$(document).ready(function(){return $(".sslclick").on("click",o)})}).call(this); \ No newline at end of file +(function(){var r,o;o=function(){var n;return n=window.location.pathname,console.log("path -> ",n),console.log("Call URL -> ",window.datas.sslHost),$.ajax(window.datas.sslHost,{dataType:"json",xhrFields:{withCredentials:!0},success:function(o){return r(n),console.log("Success -> ",o)},error:function(o){return 0===o.status&&r(n),o.responseJSON&&"error"in o.responseJSON&&"9"===o.responseJSON.error&&r(n),o.responseJSON&&"html"in o.responseJSON&&($("#errormsg").html(o.responseJSON.html),$(window).trigger("load")),console.log("Error during AJAX SSL authentication",o)}}),!1},r=function(o){var n;return(n=$("#lform").attr("action")).match(/^#$/)?n=o:n+=o,console.log("form action URL -> ",n),$("#lform").attr("action",n),$("#lform").submit()},$(document).ready(function(){return $(".sslclick").on("click",o)})}).call(this); \ No newline at end of file diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js.map b/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js.map index 702cc06fd..91acebed7 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js.map +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/ssl.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/ssl.js"],"names":["sendUrl","tryssl","path","window","location","pathname","console","log","datas","sslHost","$","ajax","dataType","statusCode","401","submit","success","data","error","form_url","attr","match","document","ready","on","call","this"],"mappings":"CACA,WACE,IAAIA,EAASC,EAEbA,EAAS,WACP,IAAIC,EAqBJ,OApBAA,EAAOC,OAAOC,SAASC,SACvBC,QAAQC,IAAI,WAAYL,GACxBI,QAAQC,IAAI,eAAgBJ,OAAOK,MAAMC,SACzCC,EAAEC,KAAKR,OAAOK,MAAMC,QAAS,CAC3BG,SAAU,QACVC,WAAY,CACVC,IAAK,WAEH,OADAJ,EAAE,UAAUK,SACLT,QAAQC,IAAI,oBAGvBS,QAAS,SAASC,GAEhB,OADAjB,EAAQE,GACDI,QAAQC,IAAI,cAAeU,IAEpCC,MAAO,WAEL,OADAlB,EAAQE,GACDI,QAAQC,IAAI,aAGhB,GAGTP,EAAU,SAASE,GACjB,IAAIiB,EASJ,OARAA,EAAWT,EAAE,UAAUU,KAAK,WACfC,MAAM,OACjBF,EAAWjB,EAEXiB,GAAsBjB,EAExBI,QAAQC,IAAI,sBAAuBY,GACnCT,EAAE,UAAUU,KAAK,SAAUD,GACpBT,EAAE,UAAUK,UAGrBL,EAAEY,UAAUC,MAAM,WAChB,OAAOb,EAAE,aAAac,GAAG,QAASvB,OAGnCwB,KAAKC"} \ No newline at end of file +{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/ssl.js"],"names":["sendUrl","tryssl","path","window","location","pathname","console","log","datas","sslHost","$","ajax","dataType","xhrFields","withCredentials","success","data","error","result","status","responseJSON","html","trigger","form_url","attr","match","submit","document","ready","on","call","this"],"mappings":"CACA,WACE,IAAIA,EAASC,EAEbA,EAAS,WACP,IAAIC,EA2BJ,OA1BAA,EAAOC,OAAOC,SAASC,SACvBC,QAAQC,IAAI,WAAYL,GACxBI,QAAQC,IAAI,eAAgBJ,OAAOK,MAAMC,SACzCC,EAAEC,KAAKR,OAAOK,MAAMC,QAAS,CAC3BG,SAAU,OACVC,UAAW,CACTC,iBAAiB,GAEnBC,QAAS,SAASC,GAEhB,OADAhB,EAAQE,GACDI,QAAQC,IAAI,cAAeS,IAEpCC,MAAO,SAASC,GAWd,OAVsB,IAAlBA,EAAOC,QACTnB,EAAQE,GAENgB,EAAOE,cAAgB,UAAWF,EAAOE,cAA8C,MAA9BF,EAAOE,aAAaH,OAC/EjB,EAAQE,GAENgB,EAAOE,cAAgB,SAAUF,EAAOE,eAC1CV,EAAE,aAAaW,KAAKH,EAAOE,aAAaC,MACxCX,EAAEP,QAAQmB,QAAQ,SAEbhB,QAAQC,IAAI,uCAAwCW,OAGxD,GAGTlB,EAAU,SAASE,GACjB,IAAIqB,EASJ,OARAA,EAAWb,EAAE,UAAUc,KAAK,WACfC,MAAM,OACjBF,EAAWrB,EAEXqB,GAAsBrB,EAExBI,QAAQC,IAAI,sBAAuBgB,GACnCb,EAAE,UAAUc,KAAK,SAAUD,GACpBb,EAAE,UAAUgB,UAGrBhB,EAAEiB,UAAUC,MAAM,WAChB,OAAOlB,EAAE,aAAamB,GAAG,QAAS5B,OAGnC6B,KAAKC"} \ No newline at end of file diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.js b/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.js index 59d97dabd..6495d7883 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.js +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.12.7 +// Generated by CoffeeScript 1.12.8 (function() { var sendUrl, tryssl; @@ -8,20 +8,26 @@ console.log('path -> ', path); console.log('Call URL -> ', window.datas.sslHost); $.ajax(window.datas.sslHost, { - dataType: 'jsonp', - statusCode: { - 401: function() { - $('#lformSSL').submit(); - return console.log('Error code 401'); - } + dataType: 'json', + xhrFields: { + withCredentials: true }, success: function(data) { sendUrl(path); return console.log('Success -> ', data); }, - error: function() { - sendUrl(path); - return console.log('Error'); + error: function(result) { + if (result.status === 0) { + sendUrl(path); + } + if (result.responseJSON && 'error' in result.responseJSON && result.responseJSON.error === "9") { + sendUrl(path); + } + if (result.responseJSON && 'html' in result.responseJSON) { + $('#errormsg').html(result.responseJSON.html); + $(window).trigger('load'); + } + return console.log('Error during AJAX SSL authentication', result); } }); return false; diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js b/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js index af9cc930b..b8d8e791a 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js @@ -1 +1 @@ -(function(){var t,o;o=function(){var n;return n=window.location.pathname,console.log("path -> ",n),console.log("Call URL -> ",window.datas.sslHost),$.ajax(window.datas.sslHost,{dataType:"jsonp",statusCode:{401:function(){return $("#lformSSL").submit(),console.log("Error code 401")}},success:function(o){return t(n),console.log("Success -> ",o)},error:function(){return t(n),console.log("Error")}}),!1},t=function(o){var n;return(n=$("#lformSSL").attr("action")).match(/^#$/)?n=o:n+=o,console.log("form action URL -> ",n),$("#lformSSL").attr("action",n),$("#lformSSL").submit()},$(document).ready(function(){return $(".sslclick").on("click",o)})}).call(this); \ No newline at end of file +(function(){var r,o;o=function(){var n;return n=window.location.pathname,console.log("path -> ",n),console.log("Call URL -> ",window.datas.sslHost),$.ajax(window.datas.sslHost,{dataType:"json",xhrFields:{withCredentials:!0},success:function(o){return r(n),console.log("Success -> ",o)},error:function(o){return 0===o.status&&r(n),o.responseJSON&&"error"in o.responseJSON&&"9"===o.responseJSON.error&&r(n),o.responseJSON&&"html"in o.responseJSON&&($("#errormsg").html(o.responseJSON.html),$(window).trigger("load")),console.log("Error during AJAX SSL authentication",o)}}),!1},r=function(o){var n;return(n=$("#lformSSL").attr("action")).match(/^#$/)?n=o:n+=o,console.log("form action URL -> ",n),$("#lformSSL").attr("action",n),$("#lformSSL").submit()},$(document).ready(function(){return $(".sslclick").on("click",o)})}).call(this); \ No newline at end of file diff --git a/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js.map b/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js.map index 46d2ed6c4..6a1383a30 100644 --- a/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js.map +++ b/lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.js"],"names":["sendUrl","tryssl","path","window","location","pathname","console","log","datas","sslHost","$","ajax","dataType","statusCode","401","submit","success","data","error","form_url","attr","match","document","ready","on","call","this"],"mappings":"CACA,WACE,IAAIA,EAASC,EAEbA,EAAS,WACP,IAAIC,EAqBJ,OApBAA,EAAOC,OAAOC,SAASC,SACvBC,QAAQC,IAAI,WAAYL,GACxBI,QAAQC,IAAI,eAAgBJ,OAAOK,MAAMC,SACzCC,EAAEC,KAAKR,OAAOK,MAAMC,QAAS,CAC3BG,SAAU,QACVC,WAAY,CACVC,IAAK,WAEH,OADAJ,EAAE,aAAaK,SACRT,QAAQC,IAAI,oBAGvBS,QAAS,SAASC,GAEhB,OADAjB,EAAQE,GACDI,QAAQC,IAAI,cAAeU,IAEpCC,MAAO,WAEL,OADAlB,EAAQE,GACDI,QAAQC,IAAI,aAGhB,GAGTP,EAAU,SAASE,GACjB,IAAIiB,EASJ,OARAA,EAAWT,EAAE,aAAaU,KAAK,WAClBC,MAAM,OACjBF,EAAWjB,EAEXiB,GAAsBjB,EAExBI,QAAQC,IAAI,sBAAuBY,GACnCT,EAAE,aAAaU,KAAK,SAAUD,GACvBT,EAAE,aAAaK,UAGxBL,EAAEY,UAAUC,MAAM,WAChB,OAAOb,EAAE,aAAac,GAAG,QAASvB,OAGnCwB,KAAKC"} \ No newline at end of file +{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/sslChoice.js"],"names":["sendUrl","tryssl","path","window","location","pathname","console","log","datas","sslHost","$","ajax","dataType","xhrFields","withCredentials","success","data","error","result","status","responseJSON","html","trigger","form_url","attr","match","submit","document","ready","on","call","this"],"mappings":"CACA,WACE,IAAIA,EAASC,EAEbA,EAAS,WACP,IAAIC,EA2BJ,OA1BAA,EAAOC,OAAOC,SAASC,SACvBC,QAAQC,IAAI,WAAYL,GACxBI,QAAQC,IAAI,eAAgBJ,OAAOK,MAAMC,SACzCC,EAAEC,KAAKR,OAAOK,MAAMC,QAAS,CAC3BG,SAAU,OACVC,UAAW,CACTC,iBAAiB,GAEnBC,QAAS,SAASC,GAEhB,OADAhB,EAAQE,GACDI,QAAQC,IAAI,cAAeS,IAEpCC,MAAO,SAASC,GAWd,OAVsB,IAAlBA,EAAOC,QACTnB,EAAQE,GAENgB,EAAOE,cAAgB,UAAWF,EAAOE,cAA8C,MAA9BF,EAAOE,aAAaH,OAC/EjB,EAAQE,GAENgB,EAAOE,cAAgB,SAAUF,EAAOE,eAC1CV,EAAE,aAAaW,KAAKH,EAAOE,aAAaC,MACxCX,EAAEP,QAAQmB,QAAQ,SAEbhB,QAAQC,IAAI,uCAAwCW,OAGxD,GAGTlB,EAAU,SAASE,GACjB,IAAIqB,EASJ,OARAA,EAAWb,EAAE,aAAac,KAAK,WAClBC,MAAM,OACjBF,EAAWrB,EAEXqB,GAAsBrB,EAExBI,QAAQC,IAAI,sBAAuBgB,GACnCb,EAAE,aAAac,KAAK,SAAUD,GACvBb,EAAE,aAAagB,UAGxBhB,EAAEiB,UAAUC,MAAM,WAChB,OAAOlB,EAAE,aAAamB,GAAG,QAAS5B,OAGnC6B,KAAKC"} \ No newline at end of file diff --git a/lemonldap-ng-portal/site/templates/bootstrap/login.tpl b/lemonldap-ng-portal/site/templates/bootstrap/login.tpl index ac03be8a9..ed834e622 100644 --- a/lemonldap-ng-portal/site/templates/bootstrap/login.tpl +++ b/lemonldap-ng-portal/site/templates/bootstrap/login.tpl @@ -4,13 +4,15 @@ - -
alert">"> - - seconds. - -
-
+
+ +
alert">"> + + seconds. + +
+
+