diff --git a/debian/control b/debian/control index 5cb4e1c16..966599102 100644 --- a/debian/control +++ b/debian/control @@ -240,6 +240,7 @@ Architecture: all Depends: ${misc:Depends}, ${perl:Depends}, libconvert-pem-perl, + libregexp-common-perl, libcrypt-openssl-rsa-perl, liblemonldap-ng-handler-perl (= ${binary:Version}), lemonldap-ng-fastcgi-server (= ${binary:Version}) | lemonldap-ng-uwsgi-app (= ${binary:Version}) | apache2 | httpd-cgi diff --git a/fastcgi-server/man/llng-fastcgi-server.8p b/fastcgi-server/man/llng-fastcgi-server.8p index d0f8d5c42..89641b461 100644 --- a/fastcgi-server/man/llng-fastcgi-server.8p +++ b/fastcgi-server/man/llng-fastcgi-server.8p @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -54,20 +54,16 @@ .\" Avoid warning from groff about undefined register 'F'. .de IX .. -.nr rF 0 -.if \n(.g .if rF .nr rF 1 -.if (\n(rF:(\n(.g==0)) \{\ -. if \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" +.if !\nF .nr F 0 +.if \nF>0 \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" .. -. if !\nF==2 \{\ -. nr % 0 -. nr F 2 -. \} +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 . \} .\} -.rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. @@ -133,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "llng-fastcgi-server 8" -.TH llng-fastcgi-server 8 "2019-12-13" "perl v5.30.0" "User Contributed Perl Documentation" +.TH llng-fastcgi-server 8 "2020-01-24" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm index 9fd7390af..d6193e40a 100644 --- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm @@ -260,6 +260,7 @@ sub defaultValues { 'rest2fActivation' => 0, 'restAuthnLevel' => 2, 'restClockTolerance' => 15, + 'sameSite' => 'None', 'samlAttributeAuthorityDescriptorAttributeServiceSOAP' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;', 'samlAuthnContextMapKerberos' => 4, diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/2F.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/2F.pm index c9dfd5690..57b67efd6 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/2F.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/2F.pm @@ -265,7 +265,7 @@ sub _delete2FFromSessions { . " 2F device(s) attached to sessionId $_ ..." ); $session->data->{_2fDevices} = to_json( \@keep ); $session->update( $session->data ); - + # Delete from local cache if ( $session->{options}->{localStorage} ) { $module = $session->{options}->{localStorage}; @@ -309,9 +309,10 @@ sub _delete2F { return $res if ( $res->{res} ne 'ok' ); $removed = $res->{removed} || {}; + my $whatToTrace = Lemonldap::NG::Handler::PSGI::Main->tsv->{whatToTrace}; $res = $self->_delete2FFromSessions( $uid, $type, $id, $self->_getSSOMod, 'SSO', - 'uid' ); + $whatToTrace ); return $res if ( $res->{res} ne 'ok' ); $res->{removed} ||= {}; diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm index 3d36affcc..10fe37167 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm @@ -2805,6 +2805,23 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.] 'restUserDBUrl' => { 'type' => 'url' }, + 'sameSite' => { + 'default' => 'None', + 'select' => [ { + 'k' => 'Strict', + 'v' => 'Strict' + }, + { + 'k' => 'Lax', + 'v' => 'Lax' + }, + { + 'k' => 'None', + 'v' => 'None' + } + ], + 'type' => 'select' + }, 'samlAttributeAuthorityDescriptorAttributeServiceSOAP' => { 'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;', diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm index 08a98dc7c..2a1279f1c 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm @@ -1088,6 +1088,17 @@ sub attributes { documentation => 'Cookie securisation method', flags => 'hp', }, + sameSite => { + type => 'select', + select => [ + { k => 'Strict', v => 'Strict' }, + { k => 'Lax', v => 'Lax' }, + { k => 'None', v => 'None' }, + ], + default => 'None', + documentation => 'Cookie SameSite value', + flags => 'hp', + }, # Viewer viewerHiddenKeys => { diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Tree.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Tree.pm index cd422b4bb..ff3e768eb 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Tree.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Tree.pm @@ -538,7 +538,8 @@ sub tree { nodes => [ 'cookieName', '*domain', 'cda', 'securedCookie', - 'httpOnly', 'cookieExpiration' + 'httpOnly', 'cookieExpiration', + 'sameSite', ] }, { diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Diff.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Diff.pm index cfa4bc305..1b5373fab 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Diff.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Diff.pm @@ -202,7 +202,7 @@ sub _copyAppList { my ( $self, $conf ) = @_; my %res; if ( $conf->{type} eq 'category' ) { - foreach ( grep { $_ !~ /^(?:catname|type)$/ } keys %$conf ) { + foreach ( grep { $_ !~ /^(?:catname|type|order)$/ } keys %$conf ) { my @tmp = _copyAppList( $self, $conf->{$_} ); $res{ $tmp[0] } = $tmp[1]; } diff --git a/lemonldap-ng-manager/site/coffee/notifications.coffee b/lemonldap-ng-manager/site/coffee/notifications.coffee index a0d94b672..4d6741aa5 100644 --- a/lemonldap-ng-manager/site/coffee/notifications.coffee +++ b/lemonldap-ng-manager/site/coffee/notifications.coffee @@ -142,7 +142,10 @@ llapp.controller 'NotificationsExplorerCtrl', [ '$scope', '$translator', '$locat $scope.getLanguage = (lang) -> $scope.lang = lang - $scope.form = 'white' + if $scope.form.date + $scope.form.date = new Date() + else + $scope.form = 'white' $scope.init() $scope.showM = false @@ -172,22 +175,23 @@ llapp.controller 'NotificationsExplorerCtrl', [ '$scope', '$translator', '$locat over = 0 # Launch HTTP query - $http.get("#{scriptname}notifications/#{$scope.type}?#{query}").then (response) -> - data = response.data - if data.result - for n in data.values - autoId++ - n.id = "node#{autoId}" - if level < scheme.length - 1 - n.nodes = [] - n.level = level + 1 - n.query = query - n.over = over - node.push n - $scope.total = data.total if value == '' - $scope.waiting = false - , (resp) -> - $scope.waiting = false + if $scope.type == 'done' || $scope.type == 'actives' + $http.get("#{scriptname}notifications/#{$scope.type}?#{query}").then (response) -> + data = response.data + if data.result + for n in data.values + autoId++ + n.id = "node#{autoId}" + if level < scheme.length - 1 + n.nodes = [] + n.level = level + 1 + n.query = query + n.over = over + node.push n + $scope.total = data.total if value == '' + $scope.waiting = false + , (resp) -> + $scope.waiting = false $scope.displayNotification = (scope) -> $scope.waiting = true @@ -202,7 +206,11 @@ llapp.controller 'NotificationsExplorerCtrl', [ '$scope', '$translator', '$locat reference: node.reference condition: node.condition if $scope.type == 'actives' - $scope.currentNotification.notifications = response.data.notifications + notif = JSON.parse response.data.notifications + $scope.currentNotification.text = notif.text + $scope.currentNotification.title = notif.title + $scope.currentNotification.subtitle = notif.subtitle + $scope.currentNotification.notifications = response.data.notifications else $scope.currentNotification.done = response.data.done $scope.waiting = false diff --git a/lemonldap-ng-manager/site/htdocs/static/js/notifications.js b/lemonldap-ng-manager/site/htdocs/static/js/notifications.js index 60ec428dc..9447cfcb2 100644 --- a/lemonldap-ng-manager/site/htdocs/static/js/notifications.js +++ b/lemonldap-ng-manager/site/htdocs/static/js/notifications.js @@ -159,7 +159,11 @@ }; $scope.getLanguage = function(lang) { $scope.lang = lang; - $scope.form = 'white'; + if ($scope.form.date) { + $scope.form.date = new Date(); + } else { + $scope.form = 'white'; + } $scope.init(); return $scope.showM = false; }; @@ -190,31 +194,33 @@ } else { over = 0; } - return $http.get(scriptname + "notifications/" + $scope.type + "?" + query).then(function(response) { - var data, i, len, n, ref; - data = response.data; - if (data.result) { - ref = data.values; - for (i = 0, len = ref.length; i < len; i++) { - n = ref[i]; - autoId++; - n.id = "node" + autoId; - if (level < scheme.length - 1) { - n.nodes = []; - n.level = level + 1; - n.query = query; - n.over = over; + if ($scope.type === 'done' || $scope.type === 'actives') { + return $http.get(scriptname + "notifications/" + $scope.type + "?" + query).then(function(response) { + var data, i, len, n, ref; + data = response.data; + if (data.result) { + ref = data.values; + for (i = 0, len = ref.length; i < len; i++) { + n = ref[i]; + autoId++; + n.id = "node" + autoId; + if (level < scheme.length - 1) { + n.nodes = []; + n.level = level + 1; + n.query = query; + n.over = over; + } + node.push(n); + } + if (value === '') { + $scope.total = data.total; } - node.push(n); } - if (value === '') { - $scope.total = data.total; - } - } - return $scope.waiting = false; - }, function(resp) { - return $scope.waiting = false; - }); + return $scope.waiting = false; + }, function(resp) { + return $scope.waiting = false; + }); + } }; $scope.displayNotification = function(scope) { var node, notificationId; @@ -226,12 +232,17 @@ notificationId = node.uid + "_" + node.reference; } $http.get(scriptname + "notifications/" + $scope.type + "/" + notificationId).then(function(response) { + var notif; $scope.currentNotification = { uid: node.uid, reference: node.reference, condition: node.condition }; if ($scope.type === 'actives') { + notif = JSON.parse(response.data.notifications); + $scope.currentNotification.text = notif.text; + $scope.currentNotification.title = notif.title; + $scope.currentNotification.subtitle = notif.subtitle; $scope.currentNotification.notifications = response.data.notifications; } else { $scope.currentNotification.done = response.data.done; diff --git a/lemonldap-ng-manager/site/htdocs/static/js/notifications.min.js b/lemonldap-ng-manager/site/htdocs/static/js/notifications.min.js index d3e79296d..be4d9e5e4 100644 --- a/lemonldap-ng-manager/site/htdocs/static/js/notifications.min.js +++ b/lemonldap-ng-manager/site/htdocs/static/js/notifications.min.js @@ -1 +1 @@ -(function(){var u,m,g;g=[function(t){return"groupBy=substr(uid,1)"},function(t){return"uid="+t+"*&groupBy=uid"},function(t){return"uid="+t}],m=function(t,e,n){return console.log("overScheme => level",e,"over",n),1===e&&t.length>n?"uid="+t+"*&groupBy=substr(uid,"+(e+n+1)+")":null},u={actives:[{title:"markAsDone",icon:"check"}],done:[{title:"deleteNotification",icon:"trash"}],new:[{title:"save",icon:"save"}],home:[]},angular.module("llngNotificationsExplorer",["ui.tree","ui.bootstrap","llApp"]).controller("NotificationsExplorerCtrl",["$scope","$translator","$location","$q","$http","$uibModal",function(f,e,t,o,i,r){var d,n,a;return f.links=links,f.menulinks=menulinks,f.staticPrefix=staticPrefix,f.scriptname=scriptname,f.formPrefix=formPrefix,f.availableLanguages=availableLanguages,f.waiting=!0,f.showM=!1,f.showT=!0,f.showForm=!1,f.data=[],f.form={},f.formPost={},f.currentScope=null,f.currentNotification=null,f.menu=u,f.translateP=e.translateP,f.translate=e.translate,f.translateTitle=function(t){return e.translateField(t,"title")},f.menuClick=function(t){if(t.popup)window.open(t.popup);else switch(t.action||(t.action=t.title),typeof t.action){case"function":t.action(f.currentNode,f);break;case"string":f[t.action]();break;default:console.log(typeof t.action)}return f.showM=!1},f.markAsDone=function(){return f.waiting=!0,i.put(scriptname+"notifications/"+f.type+"/"+f.currentNotification.uid+"_"+f.currentNotification.reference,{done:1}).then(function(t){return f.currentNotification=null,f.currentScope.remove(),f.message={title:"notificationDeleted"},f.showModal("alert.html"),f.waiting=!1,f.init()},function(t){return f.message={title:"notificationNotDeleted",message:t.statusText},f.showModal("alert.html"),f.waiting=!1,f.init()})},f.deleteNotification=function(){return f.waiting=!0,i.delete(scriptname+"notifications/"+f.type+"/"+f.currentNotification.uid+"_"+f.currentNotification.reference+"_"+f.currentNotification.done).then(function(t){return f.currentNotification=null,f.currentScope.remove(),f.message={title:"notificationPurged"},f.showModal("alert.html"),f.waiting=!1,f.init()},function(t){return f.message={title:"notificationNotPurged",message:t.statusText},f.showModal("alert.html"),f.waiting=!1,f.init()})},f.stoggle=function(t){var e;return 0===(e=t.$modelValue).nodes.length&&f.updateTree(e.value,e.nodes,e.level,e.over,e.query,e.count),t.toggle()},f.notifDate=function(t){return null!=t?(t.match(/(\d{4})-(\d{2})-(\d{2})/)&&(t=t.substr(0,4)+t.substr(5,2)+t.substr(8,2)),new Date(t.substr(0,4),t.substr(4,2)-1,t.substr(6,2)).toLocaleDateString()):""},f.getLanguage=function(t){return f.lang=t,f.form="white",f.init(),f.showM=!1},f.$on("$locationChangeSuccess",function(t,e,n){var i;return i=e.match(/#!?\/(\w+)/),f.type=null!=i?i[1]:"actives","new"===f.type?f.displayCreateForm():(f.showForm=!1,f.init())}),d=0,f.updateTree=function(a,u,c,s,t,e){var l,n;return f.waiting=!0,l=g[c](a,t),25 level",e,"over",n),1===e&&t.length>n?"uid="+t+"*&groupBy=substr(uid,"+(e+n+1)+")":null},u={actives:[{title:"markAsDone",icon:"check"}],done:[{title:"deleteNotification",icon:"trash"}],new:[{title:"save",icon:"save"}],home:[]},angular.module("llngNotificationsExplorer",["ui.tree","ui.bootstrap","llApp"]).controller("NotificationsExplorerCtrl",["$scope","$translator","$location","$q","$http","$uibModal",function(f,e,t,o,i,r){var d,n,a;return f.links=links,f.menulinks=menulinks,f.staticPrefix=staticPrefix,f.scriptname=scriptname,f.formPrefix=formPrefix,f.availableLanguages=availableLanguages,f.waiting=!0,f.showM=!1,f.showT=!0,f.showForm=!1,f.data=[],f.form={},f.formPost={},f.currentScope=null,f.currentNotification=null,f.menu=u,f.translateP=e.translateP,f.translate=e.translate,f.translateTitle=function(t){return e.translateField(t,"title")},f.menuClick=function(t){if(t.popup)window.open(t.popup);else switch(t.action||(t.action=t.title),typeof t.action){case"function":t.action(f.currentNode,f);break;case"string":f[t.action]();break;default:console.log(typeof t.action)}return f.showM=!1},f.markAsDone=function(){return f.waiting=!0,i.put(scriptname+"notifications/"+f.type+"/"+f.currentNotification.uid+"_"+f.currentNotification.reference,{done:1}).then(function(t){return f.currentNotification=null,f.currentScope.remove(),f.message={title:"notificationDeleted"},f.showModal("alert.html"),f.waiting=!1,f.init()},function(t){return f.message={title:"notificationNotDeleted",message:t.statusText},f.showModal("alert.html"),f.waiting=!1,f.init()})},f.deleteNotification=function(){return f.waiting=!0,i.delete(scriptname+"notifications/"+f.type+"/"+f.currentNotification.uid+"_"+f.currentNotification.reference+"_"+f.currentNotification.done).then(function(t){return f.currentNotification=null,f.currentScope.remove(),f.message={title:"notificationPurged"},f.showModal("alert.html"),f.waiting=!1,f.init()},function(t){return f.message={title:"notificationNotPurged",message:t.statusText},f.showModal("alert.html"),f.waiting=!1,f.init()})},f.stoggle=function(t){var e;return 0===(e=t.$modelValue).nodes.length&&f.updateTree(e.value,e.nodes,e.level,e.over,e.query,e.count),t.toggle()},f.notifDate=function(t){return null!=t?(t.match(/(\d{4})-(\d{2})-(\d{2})/)&&(t=t.substr(0,4)+t.substr(5,2)+t.substr(8,2)),new Date(t.substr(0,4),t.substr(4,2)-1,t.substr(6,2)).toLocaleDateString()):""},f.getLanguage=function(t){return f.lang=t,f.form.date?f.form.date=new Date:f.form="white",f.init(),f.showM=!1},f.$on("$locationChangeSuccess",function(t,e,n){var i;return i=e.match(/#!?\/(\w+)/),f.type=null!=i?i[1]:"actives","new"===f.type?f.displayCreateForm():(f.showForm=!1,f.init())}),d=0,f.updateTree=function(a,u,c,s,t,e){var l,n;if(f.waiting=!0,l=g[c](a,t),25 -

{{total}}

+

{{total}} {{translate('session_s')}}

- + {{translate('noData')}}
  1. diff --git a/lemonldap-ng-manager/site/templates/diff.tpl b/lemonldap-ng-manager/site/templates/diff.tpl index 45506dc91..9b2412585 100644 --- a/lemonldap-ng-manager/site/templates/diff.tpl +++ b/lemonldap-ng-manager/site/templates/diff.tpl @@ -50,7 +50,7 @@
    - + {{translate('noData')}}
    1. diff --git a/lemonldap-ng-manager/site/templates/notifications.tpl b/lemonldap-ng-manager/site/templates/notifications.tpl index 706022e2b..697ecf264 100644 --- a/lemonldap-ng-manager/site/templates/notifications.tpl +++ b/lemonldap-ng-manager/site/templates/notifications.tpl @@ -21,12 +21,12 @@
-

{{total}}

+

{{total}} {{translate('notification_s')}}

- + {{translate('noData')}}
  1. @@ -40,7 +40,7 @@