Merge branch 'v2.0' into master

This commit is contained in:
Xavier Guimard 2020-10-12 16:08:36 +02:00
commit 28c9623b73
98 changed files with 1240 additions and 215 deletions

View File

@ -30,7 +30,7 @@ use constant DEFAULTCONFBACKENDOPTIONS => (
dirName => '/usr/local/lemonldap-ng/data/conf',
);
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|ombModule)s)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|d(?:isablePersistentStorage|biDynamicHashEnabled)|g(?:roupsBeforeMacros|lobalLogoutTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|d(?:isablePersistentStorage|biDynamicHashEnabled)|g(?:roupsBeforeMacros|lobalLogoutTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs))$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );

View File

@ -237,12 +237,11 @@ sub defaultValues {
'passwordResetAllowedRetries' => 3,
'persistentSessionAttributes' =>
'_loginHistory _2fDevices notification_',
'port' => -1,
'portal' => 'http://auth.example.com/',
'portalAntiFrame' => 1,
'portalCheckLogins' => 1,
'portalDisplayAppslist' => 1,
'portalDisplayCertificateResetByMail' => 0,
'port' => -1,
'portal' => 'http://auth.example.com/',
'portalAntiFrame' => 1,
'portalCheckLogins' => 1,
'portalDisplayAppslist' => 1,
'portalDisplayChangePassword' => '$_auth =~ /^(LDAP|DBI|Demo)$/',
'portalDisplayFavApps' => 1,
'portalDisplayGeneratePassword' => 1,

View File

@ -2614,7 +2614,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'portalDisplayCertificateResetByMail' => {
'default' => 0,
'type' => 'boolOrExpr'
'type' => 'bool'
},
'portalDisplayChangePassword' => {
'default' => '$_auth =~ /^(LDAP|DBI|Demo)$/',

View File

@ -1097,9 +1097,9 @@ sub attributes {
documentation => 'Display logout tab in portal',
},
portalDisplayCertificateResetByMail => {
type => 'boolOrExpr',
type => 'bool',
default => 0,
documentation => 'Display Certificate Reset by mail tab in portal',
documentation => 'Display certificate reset by mail button in portal',
},
portalDisplayRegister => {
default => 1,

View File

@ -380,8 +380,8 @@ sub tests {
&& $conf->{samlServicePublicKeySig} );
return 1;
},
samlSignatureOverrideNeedsCertificate => sub {
return 1 if $conf->{samlServicePublicKeySig} =~ /CERTIFICATE/;
my @offenders;
@ -399,20 +399,23 @@ sub tests {
push @offenders, $sp;
}
}
return 1 unless @offenders;
return ( 0,
"Cannot set non-default signature method on "
return @offenders
? (
0,
"Cannot set non-default signature method on "
. join( ", ", @offenders )
. " unless SAML signature key is in certificate form" );
. " unless SAML signature key is in certificate form"
)
: 1;
},
samlSignatureUnsupportedAlg => sub {
my $oldlasso = eval
samlSignatureUnsupportedAlg => sub {
return 1
unless eval
'use Lasso; Lasso::check_version( 2, 5, 1, Lasso::Constants::CHECK_VERSION_NUMERIC) ? 0:1';
return 1 unless ($oldlasso);
my $allsha1 = 1;
$allsha1 = 0
undef $allsha1
unless $conf->{samlServiceSignatureMethod} eq "RSA_SHA1";
for my $idp ( keys %{ $conf->{samlIDPMetaDataOptions} } ) {
@ -423,7 +426,7 @@ sub tests {
->{samlIDPMetaDataOptionsSignatureMethod} ne
"RSA_SHA1" )
{
$allsha1 = 0;
undef $allsha1;
break;
}
}
@ -435,15 +438,17 @@ sub tests {
if ( $conf->{samlSPMetaDataOptions}->{$sp}
->{samlSPMetaDataOptionsSignatureMethod} ne "RSA_SHA1" )
{
$allsha1 = 0;
undef $allsha1;
break;
}
}
}
return 1 if $allsha1;
return ( 0,
return $allsha1
? 1
: (
0,
"Algorithms other than SHA1 are only supported on Lasso>=2.5.1"
);
);
},
# Try to parse combination with declared modules

View File

@ -730,6 +730,7 @@
"portalCustomization":"التخصيص",
"portalDisplayAppslist":"قائمة التطبيقات",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"portalDisplayChangePassword":"تغيير كلمة المرور",
"portalDisplayGeneratePassword":"Display generate password box",
"portalDisplayLoginHistory":"سجل تسجيل الدخول",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Confirmation mail subject",
"certificateResetByMailStep2Body":"Confirmation mail content",
"certificateResetByMailValidityDelay":"Minimum duration before expiration",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"contentSecurityPolicy":"Content security policy",
"contextSwitching":"Switch context another user",
"contextSwitchingAllowed2fModifications":"Allow 2FA modifications",
@ -730,6 +729,7 @@
"portalCustomization":"Customization",
"portalDisplayAppslist":"Applications list",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"portalDisplayChangePassword":"Password change",
"portalDisplayGeneratePassword":"Display generate password box",
"portalDisplayLoginHistory":"Login History",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Confirmation mail subject",
"certificateResetByMailStep2Body":"Confirmation mail content",
"certificateResetByMailValidityDelay":"Minimum duration before expiration",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"contentSecurityPolicy":"Content security policy",
"contextSwitching":"Switch context another user",
"contextSwitchingAllowed2fModifications":"Allow 2FA modifications",
@ -730,6 +729,7 @@
"portalCustomization":"Customization",
"portalDisplayAppslist":"Applications list",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"portalDisplayChangePassword":"Password change",
"portalDisplayGeneratePassword":"Display generate password box",
"portalDisplayLoginHistory":"Login History",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Sujet du message de confirmation",
"certificateResetByMailStep2Body":"Contenu du message de confirmation",
"certificateResetByMailValidityDelay":"Durée minimun avant expiration",
"portalDisplayCertificateResetByMail":"Réinitialiser votre certificat",
"contentSecurityPolicy":"Politique de sécurité de contenu",
"contextSwitching":"Endossement d'identité",
"contextSwitchingAllowed2fModifications":"Autoriser les modifications des SF",
@ -730,6 +729,7 @@
"portalCustomization":"Personnalisation",
"portalDisplayAppslist":"Liste des applications",
"portalDisplayFavApps":"Règle d'utilisation",
"portalDisplayCertificateResetByMail":"Réinitialisation du certificat",
"portalDisplayChangePassword":"Changement de mot de passe",
"portalDisplayGeneratePassword":"Afficher la boite de génération du mot de passe",
"portalDisplayLoginHistory":"Historique des connexions",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Soggetto della mail di conferma",
"certificateResetByMailStep2Body":"Confirmation mail content",
"certificateResetByMailValidityDelay":"Minimum duration before expiration",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"contentSecurityPolicy":"Politica di protezione dei contenuti",
"contextSwitching":"Switch context another user",
"contextSwitchingAllowed2fModifications":"Allow 2FA modifications",
@ -730,6 +729,7 @@
"portalCustomization":"Personalizzazione",
"portalDisplayAppslist":"Lista delle applicazioni",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"portalDisplayChangePassword":"Cambio password",
"portalDisplayGeneratePassword":"Display generate password box",
"portalDisplayLoginHistory":"Cronologia login",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Temat wiadomości potwierdzającej",
"certificateResetByMailStep2Body":"Treść wiadomości potwierdzającej",
"certificateResetByMailValidityDelay":"Minimalny czas do wygaśnięcia",
"portalDisplayCertificateResetByMail":"Zresetuj swój certyfikat",
"contentSecurityPolicy":"Polityka bezpieczeństwa treści",
"contextSwitching":"Przełącz kontekst innego użytkownika",
"contextSwitchingAllowed2fModifications":"Allow 2FA modifications",
@ -730,6 +729,7 @@
"portalCustomization":"Dostosowywanie",
"portalDisplayAppslist":"Lista aplikacji",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Zresetuj swój certyfikat",
"portalDisplayChangePassword":"Zmiana hasła",
"portalDisplayGeneratePassword":"Wyświetl pole generowania hasła",
"portalDisplayLoginHistory":"Historia logowania",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Doğrulama e-postası konusu",
"certificateResetByMailStep2Body":"Doğrulama e-postası içeriği",
"certificateResetByMailValidityDelay":"Sona ermeden önceki minimum süre",
"portalDisplayCertificateResetByMail":"Sertifikanızı sıfırlayın",
"contentSecurityPolicy":"İçerik güvenlik ilkesi",
"contextSwitching":"İçeriği başka bir kullanıcıyla değiştir",
"contextSwitchingAllowed2fModifications":"Allow 2FA modifications",
@ -730,6 +729,7 @@
"portalCustomization":"Özelleştirme",
"portalDisplayAppslist":"Uygulamalar listesi",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Sertifikanızı sıfırlayın",
"portalDisplayChangePassword":"Parola değişimi",
"portalDisplayGeneratePassword":"Parola oluşturma kutusunu görüntüle",
"portalDisplayLoginHistory":"Giriş Geçmişi",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Xác nhận chủ đề thư",
"certificateResetByMailStep2Body":"Xác nhận nội dung thư",
"certificateResetByMailValidityDelay":"Minimum duration before expiration",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"contentSecurityPolicy":"Chính sách bảo mật nội dung",
"contextSwitching":"Switch context another user",
"contextSwitchingAllowed2fModifications":"Allow 2FA modifications",
@ -730,6 +729,7 @@
"portalCustomization":"Tùy chỉnh",
"portalDisplayAppslist":"Danh sách ứng dụng",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"portalDisplayChangePassword":"Thay đổi mật khẩu",
"portalDisplayGeneratePassword":"Display generate password box",
"portalDisplayLoginHistory":"Lịch sử đăng nhập",

View File

@ -159,7 +159,6 @@
"certificateResetByMailStep2Subject":"Confirmation mail subject",
"certificateResetByMailStep2Body":"Confirmation mail content",
"certificateResetByMailValidityDelay":"Minimum duration before expiration",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"contentSecurityPolicy":"Content security policy",
"contextSwitching":"Switch context another user",
"contextSwitchingAllowed2fModifications":"Allow 2FA modifications",
@ -730,6 +729,7 @@
"portalCustomization":"Customization",
"portalDisplayAppslist":"Applications list",
"portalDisplayFavApps":"Activation rule",
"portalDisplayCertificateResetByMail":"Reset your certificate",
"portalDisplayChangePassword":"Password change",
"portalDisplayGeneratePassword":"Display generate password box",
"portalDisplayLoginHistory":"Login History",

File diff suppressed because one or more lines are too long

View File

@ -225,13 +225,11 @@ site/htdocs/static/bwr/font-awesome/fonts/fontawesome-webfont.woff
site/htdocs/static/bwr/font-awesome/fonts/fontawesome-webfont.woff2
site/htdocs/static/bwr/jquery-ui/jquery-ui.js
site/htdocs/static/bwr/jquery-ui/jquery-ui.min.js
site/htdocs/static/bwr/jquery-ui/jquery-ui.min.js.map
site/htdocs/static/bwr/jquery.cookie/jquery.cookie.js
site/htdocs/static/bwr/jquery.cookie/jquery.cookie.min.js
site/htdocs/static/bwr/jquery.cookie/jquery.cookie.min.js.map
site/htdocs/static/bwr/jquery/dist/jquery.js
site/htdocs/static/bwr/jquery/dist/jquery.min.js
site/htdocs/static/bwr/jquery/dist/jquery.min.js.map
site/htdocs/static/bwr/jquery/dist/jquery.min.map
site/htdocs/static/bwr/qrious/dist/qrious.js
site/htdocs/static/bwr/qrious/dist/qrious.js.map
@ -667,16 +665,18 @@ t/67-CheckUser-with-rules.t
t/67-CheckUser-with-token.t
t/67-CheckUser-with-UnrestrictedUser.t
t/67-CheckUser.t
t/68-ContextSwitching-with-2F-allowed.t
t/68-ContextSwitching-with-2F.t
t/68-ContextSwitching-with-Impersonation.t
t/68-ContextSwitching-with-Logout.t
t/68-ContextSwitching-with-TOTP-and-Notification.t
t/68-ContextSwitching-with-UnrestrictedUser.t
t/68-ContextSwitching.t
t/68-Impersonation-with-2F.t
t/68-Impersonation-with-doubleCookies.t
t/68-Impersonation-with-filtered-merge.t
t/68-Impersonation-with-History.t
t/68-Impersonation-with-merge.t
t/68-Impersonation-with-SFA.t
t/68-Impersonation-with-TOTP.t
t/68-Impersonation-with-UnrestrictedUser.t
t/68-Impersonation.t

View File

@ -38,7 +38,7 @@ sub run {
# Check if TOTP can be updated
return $self->p->sendError( $req, 'notAuthorized', 400 )
unless $self->allowedUpdateSfa($req, $action);
unless $self->allowedUpdateSfa( $req, $action );
# Verification that user has a valid TOTP app
if ( $action eq 'verify' ) {
@ -292,18 +292,26 @@ sub run {
if ( $_->{epoch} eq $epoch ) { $TOTPName = $_->{name}; () }
else { $_ }
} @$_2fDevices;
$self->logger->debug(
if ($TOTPName) {
$self->logger->debug(
"Delete 2F Device: { type => 'TOTP', epoch => $epoch, name => $TOTPName }"
);
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
$self->userLogger->notice(
"TOTP $TOTPName unregistration succeeds for $user");
return [
200,
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
['{"result":1}']
];
);
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
$self->userLogger->notice(
"TOTP $TOTPName unregistration succeeds for $user");
return [
200,
[
'Content-Type' => 'application/json',
'Content-Length' => 12,
],
['{"result":1}']
];
}
else {
$self->p->sendError( $req, '2FDeviceNotFound', 400 );
}
}
else {
$self->logger->error("Unknown TOTP action -> $action");

View File

@ -35,7 +35,7 @@ sub run {
# Check if U2F key can be updated
return $self->p->sendError( $req, 'notAuthorized', 400 )
unless $self->allowedUpdateSfa($req, $action);
unless $self->allowedUpdateSfa( $req, $action );
if ( $action eq 'register' ) {
@ -279,18 +279,26 @@ sub run {
if ( $_->{epoch} eq $epoch ) { $keyName = $_->{name}; () }
else { $_ }
} @$_2fDevices;
$self->logger->debug(
"Delete 2F Device : { type => 'U2F', epoch => $epoch, name => $keyName }"
);
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
$self->userLogger->notice(
"U2F key $keyName unregistration succeeds for $user");
return [
200,
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
['{"result":1}']
];
if ($keyName) {
$self->logger->debug(
"Delete 2F Device: { type => 'U2F', epoch => $epoch, name => $keyName }"
);
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
$self->userLogger->notice(
"U2F key $keyName unregistration succeeds for $user");
return [
200,
[
'Content-Type' => 'application/json',
'Content-Length' => 12,
],
['{"result":1}']
];
}
else {
$self->p->sendError( $req, '2FDeviceNotFound', 400 );
}
}
else {
$self->logger->error("Unknown U2F action -> $action");

View File

@ -42,7 +42,7 @@ sub run {
RAW_ERROR => 'notAuthorized',
AUTH_ERROR_TYPE => 'warning',
}
) unless $self->allowedUpdateSfa($req, $action);
) unless $self->allowedUpdateSfa( $req, $action );
if ( $action eq 'register' ) {
my $otp = $req->param('otp');
@ -190,18 +190,26 @@ sub run {
if ( $_->{epoch} eq $epoch ) { $UBKName = $_->{name}; () }
else { $_ }
} @$_2fDevices;
$self->logger->debug(
if ($UBKName) {
$self->logger->debug(
"Delete 2F Device: { type => 'UBK', epoch => $epoch, name => $UBKName }"
);
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
$self->userLogger->notice(
"Yubikey $UBKName unregistration succeeds for $user");
return [
200,
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
['{"result":1}']
];
);
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
$self->userLogger->notice(
"Yubikey $UBKName unregistration succeeds for $user");
return [
200,
[
'Content-Type' => 'application/json',
'Content-Length' => 12,
],
['{"result":1}']
];
}
else {
$self->p->sendError( $req, '2FDeviceNotFound', 400 );
}
}
else {
$self->logger->error("Unknown Yubikey action -> $action");

View File

@ -1,5 +1,6 @@
package Lemonldap::NG::Portal::Plugins::AdaptativeAuthenticationLevel;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
@ -29,6 +30,7 @@ sub init {
next unless $rule;
$self->rules->{$_} = $rule;
}
return 1;
}
@ -74,9 +76,7 @@ sub adaptAuthenticationLevel {
'authenticationLevel' => $updatedAuthenticationLevel
}
);
}
return PE_OK;
}

View File

@ -42,6 +42,7 @@ sub init {
push @{ $self->rules }, [ $sub, $id ];
}
}
return 1;
}

View File

@ -2,7 +2,10 @@ package Lemonldap::NG::Portal::Plugins::BruteForceProtection;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_WAIT);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_WAIT
);
our $VERSION = '2.1.0';
@ -30,11 +33,13 @@ sub init {
);
return 0;
}
unless ( $self->conf->{loginHistoryEnabled} ) {
$self->logger->error(
'"BruteForceProtection" plugin enabled WITHOUT "History" plugin');
return 0;
}
unless ( $self->conf->{failedLoginNumber} >
$self->conf->{bruteForceProtectionMaxFailed} )
{
@ -45,6 +50,7 @@ sub init {
. ')' );
return 0;
}
if ( $self->conf->{bruteForceProtectionIncrementalTempo} ) {
my $lockTimes = @{ $self->lockTimes } =
sort { $a <=> $b }
@ -87,6 +93,7 @@ sub init {
else {
$self->maxAge( $self->conf->{bruteForceProtectionMaxAge} );
}
return 1;
}

View File

@ -107,6 +107,7 @@ sub init {
'::CertificateResetByMail::' . $self->conf->{registerDB}
)
) or return 0;
return 1;
}

View File

@ -21,8 +21,9 @@ sub init {
'checkStateSecret is required for "check state" plugin');
return 0;
}
$self->addUnauthRoute( checkstate => 'check', ['GET'] );
$self->addAuthRoute( checkstate => 'check', ['GET'] );
$self->addUnauthRoute( checkstate => 'check', ['GET'] )
->addAuthRoute( checkstate => 'check', ['GET'] );
return 1;
}

View File

@ -3,10 +3,10 @@ package Lemonldap::NG::Portal::Plugins::CheckUser;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_BADCREDENTIALS
PE_MALFORMEDUSER
PE_TOKENEXPIRED
PE_NOTOKEN
PE_TOKENEXPIRED
PE_MALFORMEDUSER
PE_BADCREDENTIALS
);
our $VERSION = '2.1.0';
@ -49,8 +49,8 @@ sub persistentAttrs {
sub init {
my ($self) = @_;
$self->addAuthRoute( checkuser => 'check', ['POST'] );
$self->addAuthRouteWithRedirect( checkuser => 'display', ['GET'] );
$self->addAuthRoute( checkuser => 'check', ['POST'] )
->addAuthRouteWithRedirect( checkuser => 'display', ['GET'] );
# Parse checkUser rules
$self->idRule(

View File

@ -2,7 +2,10 @@ package Lemonldap::NG::Portal::Plugins::ForceAuthn;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_MUSTAUTHN);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_MUSTAUTHN
);
our $VERSION = '2.1.0';

View File

@ -4,8 +4,8 @@ use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_SESSIONNOTGRANTED
PE_BADCREDENTIALS
PE_SESSIONNOTGRANTED
);
our $VERSION = '2.1.0';
@ -18,20 +18,13 @@ has rules => ( is => 'rw', default => sub { {} } );
sub init {
my ($self) = @_;
my $hd = $self->p->HANDLER;
foreach ( keys %{ $self->conf->{grantSessionRules} // {} } ) {
$self->logger->debug("GrantRule key -> $_");
$self->logger->debug(
"GrantRule value -> " . $self->conf->{grantSessionRules}->{$_} );
my $rule =
$hd->buildSub(
$hd->substitute( $self->conf->{grantSessionRules}->{$_} ) );
unless ($rule) {
my $error = $hd->tsv->{jail}->error || '???';
$self->logger->error("Bad grantSession rule -> $error");
$self->logger->debug("Skipping GrantSession rule \"$_\"");
next;
}
my $rule = $self->p->buildRule( $self->conf->{grantSessionRules}->{$_},
'grantSessionRules' );
next unless ($rule);
$self->rules->{$_} = $rule;
}
return 1;

View File

@ -2,12 +2,17 @@ package Lemonldap::NG::Portal::Plugins::History;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_INFO PE_OK);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_INFO
);
our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::OtherSessions';
extends qw(
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::OtherSessions
);
# INITIALIZATION

View File

@ -3,15 +3,17 @@ package Lemonldap::NG::Portal::Plugins::Impersonation;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_MALFORMEDUSER
PE_OK PE_BADCREDENTIALS
PE_IMPERSONATION_SERVICE_NOT_ALLOWED
PE_MALFORMEDUSER
);
our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::_tokenRule';
extends qw(
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::_tokenRule
);
# INITIALIZATION

View File

@ -6,36 +6,39 @@ use Mouse;
use POSIX qw(strftime);
use Lemonldap::NG::Common::FormEncode;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_BADCREDENTIALS
PE_OK
PE_MAILOK
PE_NOTOKEN
PE_MAILERROR
PE_PASSWORD_OK
PE_BADMAILTOKEN
PE_CAPTCHAEMPTY
PE_CAPTCHAERROR
PE_MAILCONFIRMATION_ALREADY_SENT
PE_MAILCONFIRMOK
PE_MAILERROR
PE_MAILFIRSTACCESS
PE_MAILFORMEMPTY
PE_MAILNOTFOUND
PE_MAILOK
PE_TOKENEXPIRED
PE_USERNOTFOUND
PE_MAILCONFIRMOK
PE_MALFORMEDUSER
PE_NOTOKEN
PE_OK
PE_PASSWORDFIRSTACCESS
PE_MAILFORMEMPTY
PE_BADCREDENTIALS
PE_MAILFIRSTACCESS
PE_PASSWORDFORMEMPTY
PE_PASSWORD_MISMATCH
PE_PASSWORD_OK
PE_PP_INSUFFICIENT_PASSWORD_QUALITY
PE_PASSWORDFIRSTACCESS
PE_PP_PASSWORD_TOO_SHORT
PE_PP_PASSWORD_TOO_YOUNG
PE_PP_PASSWORD_IN_HISTORY
PE_TOKENEXPIRED
PE_USERNOTFOUND
PE_MAILCONFIRMATION_ALREADY_SENT
PE_PP_INSUFFICIENT_PASSWORD_QUALITY
);
our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::SMTP', 'Lemonldap::NG::Portal::Lib::_tokenRule';
extends qw(
Lemonldap::NG::Portal::Lib::SMTP
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::_tokenRule
);
# PROPERTIES
@ -352,7 +355,9 @@ sub _reset {
$body =~ s/\$url/$url/g;
$body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge;
$self->logger->info("User ".$req->data->{mailAddress}." is trying to reset his/her password");
$self->logger->info( "User "
. $req->data->{mailAddress}
. " is trying to reset his/her password" );
# Send mail
unless (

View File

@ -15,9 +15,9 @@ use strict;
use Mouse;
use MIME::Base64;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_NOTIFICATION
PE_ERROR
PE_OK
PE_ERROR
PE_NOTIFICATION
);
our $VERSION = '2.1.0';
@ -40,8 +40,8 @@ sub init {
my ($self) = @_;
# Declare new routes
$self->addUnauthRoute( notifback => 'getNotifBack', [ 'POST', 'GET' ] );
$self->addAuthRoute( notifback => 'getNotifBack', ['POST'] );
$self->addUnauthRoute( notifback => 'getNotifBack', [ 'POST', 'GET' ] )
->addAuthRoute( notifback => 'getNotifBack', ['POST'] );
$self->addAuthRouteWithRedirect(
mynotifications => { '*' => 'myNotifs' },
['GET']
@ -104,7 +104,7 @@ sub init {
return 0;
}
1;
return 1;
}
#sub checkNotifForAuthUser {

View File

@ -9,23 +9,27 @@ our $VERSION = '2.1.0';
sub init {
my ($self) = @_;
$self->addAuthRoute( public => { ':tpl' => 'run' }, ['GET'] );
$self->addUnauthRoute( public => { ':tpl' => 'run' }, ['GET'] );
$self->addAuthRoute( public => { ':tpl' => 'run' }, ['GET'] )
->addUnauthRoute( public => { ':tpl' => 'run' }, ['GET'] );
return 1;
}
sub run {
my ( $self, $req ) = @_;
my $tpl = $req->param('tpl');
unless ( $tpl =~ /^[\w\.\-]+$/ ) {
$self->userLogger->error("Bad public path $tpl");
return $self->p->sendError( $req, 'File not found', 404 );
}
$tpl = "public/$tpl";
my $path =
$self->conf->{templateDir} . '/'
. $self->conf->{portalSkin}
. "/$tpl.tpl";
unless ( -e $path ) {
$self->userLogger->warn("File not found: $path");
return $self->p->sendError( $req, 'File not found', 404 );

View File

@ -59,15 +59,17 @@ use Mouse;
use JSON qw(from_json to_json);
use MIME::Base64;
use Lemonldap::NG::Portal::Main::Constants qw(
portalConsts
PE_OK
portalConsts
PE_PASSWORD_OK
);
our $VERSION = '2.1.0';
extends
qw (Lemonldap::NG::Portal::Main::Plugin Lemonldap::NG::Portal::Lib::Captcha);
extends qw(
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::Captcha
);
has configStorage => (
is => 'ro',

View File

@ -5,12 +5,16 @@ use Mouse;
our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::OtherSessions';
extends qw(
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::OtherSessions
);
sub init {
my ($self) = @_;
$self->addUnauthRoute( refreshsessions => 'run', ['POST'] );
return 1;
}
sub run {

View File

@ -6,26 +6,29 @@ use Mouse;
use POSIX qw(strftime);
use Lemonldap::NG::Common::FormEncode;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_MAILOK
PE_NOTOKEN
PE_MAILERROR
PE_BADMAILTOKEN
PE_CAPTCHAEMPTY
PE_CAPTCHAERROR
PE_MALFORMEDUSER
PE_MAILCONFIRMATION_ALREADY_SENT
PE_MAILCONFIRMOK
PE_MAILERROR
PE_MAILOK
PE_NOTOKEN
PE_OK
PE_REGISTERALREADYEXISTS
PE_REGISTERFIRSTACCESS
PE_REGISTERFORMEMPTY
PE_TOKENEXPIRED
PE_MAILCONFIRMOK
PE_MALFORMEDUSER
PE_REGISTERFORMEMPTY
PE_REGISTERFIRSTACCESS
PE_REGISTERALREADYEXISTS
PE_MAILCONFIRMATION_ALREADY_SENT
);
our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::SMTP', 'Lemonldap::NG::Portal::Lib::_tokenRule';
extends qw(
Lemonldap::NG::Portal::Lib::SMTP
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::_tokenRule
);
# PROPERTIES

View File

@ -13,12 +13,17 @@ package Lemonldap::NG::Portal::Plugins::SOAPServer;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_FORMEMPTY);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_FORMEMPTY
);
our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Common::Conf::AccessLib';
extends qw(
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Common::Conf::AccessLib
);
has server => ( is => 'rw' );
@ -112,29 +117,33 @@ sub init {
$self->addUnauthRoute(
sessions => { '*' => 'unauthSessions' },
['POST']
);
$self->addUnauthRoute(
)
->addUnauthRoute(
adminSessions => 'unauthAdminSessions',
['POST']
);
$self->addAuthRoute(
)
->addAuthRoute(
sessions => { '*' => 'badSoapRequest' },
['POST']
);
$self->addAuthRoute(
)
->addAuthRoute(
adminSessions => { '*' => 'badSoapRequest' },
['POST']
);
);
}
if ( $self->conf->{soapConfigServer} ) {
$self->addUnauthRoute( config => { '*' => 'config' }, ['POST'] );
$self->addAuthRoute( config => { '*' => 'badSoapRequest' }, ['POST'] );
$self->addUnauthRoute( config => { '*' => 'config' }, ['POST'] )
->addAuthRoute( config => { '*' => 'badSoapRequest' }, ['POST'] );
}
if ( $self->conf->{wsdlServer} ) {
$self->addUnauthRoute( 'portal.wsdl' => 'getWsdl', ['GET'] );
$self->addAuthRoute( 'portal.wsdl' => 'getWsdl', ['GET'] );
$self->addUnauthRoute( 'portal.wsdl' => 'getWsdl', ['GET'] )
->addAuthRoute( 'portal.wsdl' => 'getWsdl', ['GET'] );
}
1;
return 1;
}
# SOAP DISPATCHERS

View File

@ -7,14 +7,16 @@ use JSON qw(from_json to_json);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_ERROR
PE_TOKENEXPIRED
PE_NOTOKEN
PE_TOKENEXPIRED
);
our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::OtherSessions';
extends qw(
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::OtherSessions
);
use constant endAuth => 'run';

View File

@ -19,8 +19,9 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
sub init {
my ($self) = @_;
$self->addUnauthRoute( portalStatus => 'status', ['GET'] );
$self->addAuthRoute( portalStatus => 'status', ['GET'] );
$self->addUnauthRoute( portalStatus => 'status', ['GET'] )
->addAuthRoute( portalStatus => 'status', ['GET'] );
return 1;
}

View File

@ -45,6 +45,7 @@ has timeout => (
sub init {
my ($self) = @_;
$self->addAuthRoute( registerbrowser => 'storeBrowser', ['POST'] );
return 1;
}

View File

@ -3,8 +3,8 @@ package Lemonldap::NG::Portal::Plugins::Upgrade;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_CONFIRM
PE_OK
PE_CONFIRM
PE_TOKENEXPIRED
);
@ -32,10 +32,12 @@ sub init {
"-> Upgrade tokens will be stored into global storage");
$self->ott->cache(undef);
}
$self->addAuthRoute( upgradesession => 'askUpgrade', ['GET'] );
$self->addAuthRoute( upgradesession => 'confirmUpgrade', ['POST'] );
$self->addAuthRoute( renewsession => 'askRenew', ['GET'] );
$self->addAuthRoute( renewsession => 'confirmRenew', ['POST'] );
$self->addAuthRoute( upgradesession => 'askUpgrade', ['GET'] )
->addAuthRoute( upgradesession => 'confirmUpgrade', ['POST'] )
->addAuthRoute( renewsession => 'askRenew', ['GET'] )
->addAuthRoute( renewsession => 'confirmRenew', ['POST'] );
return 1;
}
sub askUpgrade {
@ -107,14 +109,15 @@ sub confirm {
}
}
}
$req->steps( ['controlUrl'] );
my $res = $self->p->process($req);
return $self->p->do( $req, [ sub { $res } ] ) if ($res);
return $self->p->do( $req, [ sub { $res } ] ) if $res;
if ( $upg or $req->param('confirm') == 1 ) {
$req->data->{noerror} = 1;
if ($sfOnly) {
$req->data->{doingSfUpgrade} = 1;
# Short circuit the first part of login, only do a 2FA step
@ -134,7 +137,6 @@ sub confirm {
'', 0
); # Insert token
# Do a regular login
# Do a regular login
return $self->p->login($req);
}
}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
/*
LemonLDAP::NG 2F registration script

View File

@ -1 +1 @@
(function(){var e,t,o;o=function(e,r){return $("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},t=function(e,r,t){var n;if(console.log("Error",t),(n=JSON.parse(e.responseText))&&n.error)return n=n.error.replace(/.* /,""),console.log("Returned error",n),n.match(/module/)?o("notAuthorized","warning"):o(n,"warning")},e=function(e,r){return"U2F"===e?e="u":"UBK"===e?e="yubikey":"TOTP"===e?e="totp":o("u2fFailed","warning"),$.ajax({type:"POST",url:portal+"2fregisters/"+e+"/delete",data:{epoch:r},dataType:"json",error:t,success:function(e){return e.error?e.error.match(/notAuthorized/)?o("notAuthorized","warning"):o("unknownAction","warning"):e.result?($("#delete-"+r).hide(),o("yourKeyIsUnregistered","positive")):void 0}})},$(document).ready(function(){return $("body").on("click",".btn-danger",function(){return e($(this).attr("device"),$(this).attr("epoch"))}),$("#goback").attr("href",portal),$(".data-epoch").each(function(){var e;return e=new Date(1e3*$(this).text()),$(this).text(e.toLocaleString())})})}).call(this);
(function(){var e,t,o;o=function(e,r){return $("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},t=function(e,r,t){var n;if(console.log("Error",t),(n=JSON.parse(e.responseText))&&n.error)return n=n.error.replace(/.* /,""),console.log("Returned error",n),n.match(/module/)?o("notAuthorized","warning"):o(n,"warning")},e=function(e,r){return"U2F"===e?e="u":"UBK"===e?e="yubikey":"TOTP"===e?e="totp":o("u2fFailed","warning"),$.ajax({type:"POST",url:portal+"2fregisters/"+e+"/delete",data:{epoch:r},dataType:"json",error:t,success:function(e){return e.error?e.error.match(/notAuthorized/)?o("notAuthorized","warning"):o("unknownAction","warning"):e.result?($("#delete-"+r).hide(),o("yourKeyIsUnregistered","positive")):void 0},error:t})},$(document).ready(function(){return $("body").on("click",".btn-danger",function(){return e($(this).attr("device"),$(this).attr("epoch"))}),$("#goback").attr("href",portal),$(".data-epoch").each(function(){var e;return e=new Date(1e3*$(this).text()),$(this).text(e.toLocaleString())})})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["2fregistration.js"],"names":["delete2F","displayError","setMsg","msg","level","$","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","match","device","epoch","ajax","type","url","portal","data","dataType","success","resp","result","hide","document","ready","on","this","attr","each","myDate","Date","text","toLocaleString","call"],"mappings":"CAMA,WACE,IAAIA,EAAUC,EAAcC,EAE5BA,EAAS,SAASC,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,gEACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCH,EAAe,SAASU,EAAGC,EAAQC,GACjC,IAAIC,EAGJ,GAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,OAFAN,EAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GAC1BA,EAAIQ,MAAM,UACLpB,EAAO,gBAAiB,WAExBA,EAAOY,EAAK,YAKzBd,EAAW,SAASuB,EAAQC,GAU1B,MATe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OAETrB,EAAO,YAAa,WAEfG,EAAEoB,KAAK,CAAAC,KACN,OADMC,IAEPC,OAAS,eAAiBL,EAAS,UAF5BM,KAGN,CACJL,MAAOA,GAJGM,SAMF,OANEV,MAoBLnB,EApBK8B,QAQH,SAASC,GAChB,OAAIA,EAAKZ,MACHY,EAAKZ,MAAME,MAAM,iBACZpB,EAAO,gBAAiB,WAExBA,EAAO,gBAAiB,WAExB8B,EAAKC,QACd5B,EAAE,WAAamB,GAAOU,OACfhC,EAAO,wBAAyB,kBAFlC,MASbG,EAAE8B,UAAUC,MAAM,WAKhB,OAJA/B,EAAE,QAAQgC,GAAG,QAAS,cAAe,WACnC,OAAOrC,EAASK,EAAEiC,MAAMC,KAAK,UAAWlC,EAAEiC,MAAMC,KAAK,YAEvDlC,EAAE,WAAWkC,KAAK,OAAQX,QACnBvB,EAAE,eAAemC,KAAK,WAC3B,IAAIC,EAEJ,OADAA,EAAS,IAAIC,KAAsB,IAAjBrC,EAAEiC,MAAMK,QACnBtC,EAAEiC,MAAMK,KAAKF,EAAOG,wBAI9BC,KAAKP"}
{"version":3,"sources":["2fregistration.js"],"names":["delete2F","displayError","setMsg","msg","level","$","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","match","device","epoch","ajax","type","url","portal","data","dataType","success","resp","result","hide","document","ready","on","this","attr","each","myDate","Date","text","toLocaleString","call"],"mappings":"CAMA,WACE,IAAIA,EAAUC,EAAcC,EAE5BA,EAAS,SAASC,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,gEACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCH,EAAe,SAASU,EAAGC,EAAQC,GACjC,IAAIC,EAGJ,GAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,OAFAN,EAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GAC1BA,EAAIQ,MAAM,UACLpB,EAAO,gBAAiB,WAExBA,EAAOY,EAAK,YAKzBd,EAAW,SAASuB,EAAQC,GAU1B,MATe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OAETrB,EAAO,YAAa,WAEfG,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,eAAiBL,EAAS,UACxCM,KAAM,CACJL,MAAOA,GAETM,SAAU,OACVV,MAAOnB,EACP8B,QAAS,SAASC,GAChB,OAAIA,EAAKZ,MACHY,EAAKZ,MAAME,MAAM,iBACZpB,EAAO,gBAAiB,WAExBA,EAAO,gBAAiB,WAExB8B,EAAKC,QACd5B,EAAE,WAAamB,GAAOU,OACfhC,EAAO,wBAAyB,kBAFlC,GAKTkB,MAAOnB,KAIXI,EAAE8B,UAAUC,MAAM,WAKhB,OAJA/B,EAAE,QAAQgC,GAAG,QAAS,cAAe,WACnC,OAAOrC,EAASK,EAAEiC,MAAMC,KAAK,UAAWlC,EAAEiC,MAAMC,KAAK,YAEvDlC,EAAE,WAAWkC,KAAK,OAAQX,QACnBvB,EAAE,eAAemC,KAAK,WAC3B,IAAIC,EAEJ,OADAA,EAAS,IAAIC,KAAsB,IAAjBrC,EAAEiC,MAAMK,QACnBtC,EAAEiC,MAAMK,KAAKF,EAAOG,wBAI9BC,KAAKP"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
$(document).ready(function() {
return $('#upgrd').submit();

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var renewCaptcha;

View File

@ -1 +1 @@
(function(){var e;e=function(){return console.log("Call URL -> ",portal+"renewcaptcha"),$.ajax({type:"GET",url:portal+"renewcaptcha",dataType:"json",error:function(e,r,o){var n;if(console.log("Error",o),(n=JSON.parse(e.responseText))&&n.error)return console.log("Returned error",n)},success:function(e){var r,o;return o=e.newtoken,console.log("GET new token -> ",o),r=e.newimage,console.log("GET new image -> ",r),$("#token").attr("value",o),$("#captcha").attr("src",r)}})},$(document).ready(function(){return $("#logout").attr("href",portal),$(".renewcaptchaclick").on("click",e)})}).call(this);
(function(){var e=function(){return console.log("Call URL -> ",portal+"renewcaptcha"),$.ajax({type:"GET",url:portal+"renewcaptcha",dataType:"json",error:function(e,r,o){var n;if(console.log("Error",o),(n=JSON.parse(e.responseText))&&n.error)return console.log("Returned error",n)},success:function(e){var r,o=e.newtoken;return console.log("GET new token -> ",o),r=e.newimage,console.log("GET new image -> ",r),$("#token").attr("value",o),$("#captcha").attr("src",r)}})};$(document).ready(function(){return $("#logout").attr("href",portal),$(".renewcaptchaclick").on("click",e)})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["captcha.js"],"names":["renewCaptcha","console","log","portal","$","ajax","type","url","dataType","error","j","status","err","res","JSON","parse","responseText","success","data","newimage","newtoken","attr","document","ready","on","call","this"],"mappings":"CACA,WACE,IAAIA,EAEJA,EAAe,WAEb,OADAC,QAAQC,IAAI,eAAgBC,OAAS,gBAC9BC,EAAEC,KAAK,CACZC,KAAM,MACNC,IAAKJ,OAAS,eACdK,SAAU,OACVC,MAAO,SAASC,EAAGC,EAAQC,GACzB,IAAIC,EAGJ,GAFAZ,QAAQC,IAAI,QAASU,IACrBC,EAAMC,KAAKC,MAAML,EAAEM,gBACRH,EAAIJ,MACb,OAAOR,QAAQC,IAAI,iBAAkBW,IAGzCI,QAAS,SAASC,GAChB,IAAIC,EAAUC,EAMd,OALAA,EAAWF,EAAKE,SAChBnB,QAAQC,IAAI,oBAAqBkB,GACjCD,EAAWD,EAAKC,SAChBlB,QAAQC,IAAI,oBAAqBiB,GACjCf,EAAE,UAAUiB,KAAK,QAASD,GACnBhB,EAAE,YAAYiB,KAAK,MAAOF,OAKvCf,EAAEkB,UAAUC,MAAM,WAEhB,OADAnB,EAAE,WAAWiB,KAAK,OAAQlB,QACnBC,EAAE,sBAAsBoB,GAAG,QAASxB,OAG5CyB,KAAKC"}
{"version":3,"sources":["captcha.js"],"names":["renewCaptcha","console","log","portal","$","ajax","type","url","dataType","error","j","status","err","res","JSON","parse","responseText","success","data","newimage","newtoken","attr","document","ready","on","call","this"],"mappings":"CACA,WACE,IAEAA,EAAe,WAEb,OADAC,QAAQC,IAAI,eAAgBC,OAAS,gBAC9BC,EAAEC,KAAK,CACZC,KAAM,MACNC,IAAKJ,OAAS,eACdK,SAAU,OACVC,MAAO,SAASC,EAAGC,EAAQC,GACzB,IAAIC,EAGJ,GAFAZ,QAAQC,IAAI,QAASU,IACrBC,EAAMC,KAAKC,MAAML,EAAEM,gBACRH,EAAIJ,MACb,OAAOR,QAAQC,IAAI,iBAAkBW,IAGzCI,QAAS,SAASC,GAChB,IAAIC,EACJC,EAAWF,EAAKE,SAKhB,OAJAnB,QAAQC,IAAI,oBAAqBkB,GACjCD,EAAWD,EAAKC,SAChBlB,QAAQC,IAAI,oBAAqBiB,GACjCf,EAAE,UAAUiB,KAAK,QAASD,GACnBhB,EAAE,YAAYiB,KAAK,MAAOF,OAKvCf,EAAEkB,UAAUC,MAAM,WAEhB,OADAnB,EAAE,WAAWiB,KAAK,OAAQlB,QACnBC,EAAE,sBAAsBoB,GAAG,QAASxB,OAG5CyB,KAAKC"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var go, i, timer, timerIsEnabled;

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var go, i, timer;

View File

@ -1 +1 @@
(function(){var t,e,n;e=30,t=function(){return $("#globallogout").submit()},n=function(){var t;return t=$("#timer").html(),0<e&&e--,t=t.replace(/\d+/,e),$("#timer").html(t),window.setTimeout(n,1e3)},$(document).ready(function(){return $(".data-epoch").each(function(){var t;return t=new Date(1e3*$(this).text()),$(this).text(t.toLocaleString())}),window.setTimeout(t,3e4),window.setTimeout(n,1e3)})}).call(this);
(function(){var e=30,t=function(){return $("#globallogout").submit()},n=function(){var t=$("#timer").html();return 0<e&&e--,t=t.replace(/\d+/,e),$("#timer").html(t),window.setTimeout(n,1e3)};$(document).ready(function(){return $(".data-epoch").each(function(){var t=new Date(1e3*$(this).text());return $(this).text(t.toLocaleString())}),window.setTimeout(t,3e4),window.setTimeout(n,1e3)})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["globalLogout.js"],"names":["go","i","timer","$","submit","h","html","replace","window","setTimeout","document","ready","each","myDate","Date","this","text","toLocaleString","call"],"mappings":"CACA,WACE,IAAIA,EAAIC,EAAGC,EAEXD,EAAI,GAEJD,EAAK,WACH,OAAOG,EAAE,iBAAiBC,UAG5BF,EAAQ,WACN,IAAIG,EAOJ,OANAA,EAAIF,EAAE,UAAUG,OACR,EAAJL,GACFA,IAEFI,EAAIA,EAAEE,QAAQ,MAAON,GACrBE,EAAE,UAAUG,KAAKD,GACVG,OAAOC,WAAWP,EAAO,MAGlCC,EAAEO,UAAUC,MAAM,WAOhB,OANAR,EAAE,eAAeS,KAAK,WACpB,IAAIC,EAEJ,OADAA,EAAS,IAAIC,KAAsB,IAAjBX,EAAEY,MAAMC,QACnBb,EAAEY,MAAMC,KAAKH,EAAOI,oBAE7BT,OAAOC,WAAWT,EAAI,KACfQ,OAAOC,WAAWP,EAAO,SAGjCgB,KAAKH"}
{"version":3,"sources":["globalLogout.js"],"names":["i","go","$","submit","timer","h","html","replace","window","setTimeout","document","ready","each","myDate","Date","this","text","toLocaleString","call"],"mappings":"CACA,WACE,IAEAA,EAAI,GAEJC,EAAK,WACH,OAAOC,EAAE,iBAAiBC,UAG5BC,EAAQ,WACN,IACAC,EAAIH,EAAE,UAAUI,OAMhB,OALQ,EAAJN,GACFA,IAEFK,EAAIA,EAAEE,QAAQ,MAAOP,GACrBE,EAAE,UAAUI,KAAKD,GACVG,OAAOC,WAAWL,EAAO,MAGlCF,EAAEQ,UAAUC,MAAM,WAOhB,OANAT,EAAE,eAAeU,KAAK,WACpB,IACAC,EAAS,IAAIC,KAAsB,IAAjBZ,EAAEa,MAAMC,QAC1B,OAAOd,EAAEa,MAAMC,KAAKH,EAAOI,oBAE7BT,OAAOC,WAAWR,EAAI,KACfO,OAAOC,WAAWL,EAAO,SAGjCc,KAAKH"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
$(document).ready(function() {
return $(".idploop").on('click', function() {

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var _go, go, i, stop, timer;

View File

@ -1 +1 @@
(function(){var i,t,n,e,o;n=30,i=1,e=function(){return i=0,$("#divToHide").hide(),$("#wait").hide()},t=function(){if(i)return $("#form").submit()},o=function(){var i;return i=$("#timer").html(),0<n&&n--,i=i.replace(/\d+/,n),$("#timer").html(i),window.setTimeout(o,1e3)},$(window).on("load",function(){return window.datas.activeTimer&&(window.setTimeout(t,3e4),window.setTimeout(o,1e3)),$("#wait").on("click",function(){return e()})})}).call(this);
(function(){var t=30,i=1,e=function(){return i=0,$("#divToHide").hide(),$("#wait").hide()},n=function(){if(i)return $("#form").submit()},o=function(){var i=$("#timer").html();return 0<t&&t--,i=i.replace(/\d+/,t),$("#timer").html(i),window.setTimeout(o,1e3)};$(window).on("load",function(){return window.datas.activeTimer&&(window.setTimeout(n,3e4),window.setTimeout(o,1e3)),$("#wait").on("click",e)})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["info.js"],"names":["_go","go","i","stop","timer","$","hide","submit","h","html","replace","window","setTimeout","on","datas","call","this"],"mappings":"CACA,WACE,IAAIA,EAAKC,EAAIC,EAAGC,EAAMC,EAEtBF,EAAI,GAEJF,EAAM,EAENG,EAAO,WAGL,OAFAH,EAAM,EACNK,EAAE,cAAcC,OACTD,EAAE,SAASC,QAGpBL,EAAK,WACH,GAAID,EACF,OAAOK,EAAE,SAASE,UAItBH,EAAQ,WACN,IAAII,EAOJ,OANAA,EAAIH,EAAE,UAAUI,OACR,EAAJP,GACFA,IAEFM,EAAIA,EAAEE,QAAQ,MAAOR,GACrBG,EAAE,UAAUI,KAAKD,GACVG,OAAOC,WAAWR,EAAO,MAGlCC,EAAEM,QAAQE,GAAG,OAAQ,WAOnB,OANIF,OAAOG,MAAmB,cAC5BH,OAAOC,WAAWX,EAAI,KACtBU,OAAOC,WAAWR,EAAO,MAIpBC,EAAE,SAASQ,GAAG,QAAS,WAC5B,OAAOV,UAIVY,KAAKC"}
{"version":3,"sources":["info.js"],"names":["i","_go","stop","$","hide","go","submit","timer","h","html","replace","window","setTimeout","on","datas","call","this"],"mappings":"CACA,WACE,IAEAA,EAAI,GAEJC,EAAM,EAENC,EAAO,WAGL,OAFAD,EAAM,EACNE,EAAE,cAAcC,OACTD,EAAE,SAASC,QAGpBC,EAAK,WACH,GAAIJ,EACF,OAAOE,EAAE,SAASG,UAItBC,EAAQ,WACN,IACAC,EAAIL,EAAE,UAAUM,OAMhB,OALQ,EAAJT,GACFA,IAEFQ,EAAIA,EAAEE,QAAQ,MAAOV,GACrBG,EAAE,UAAUM,KAAKD,GACVG,OAAOC,WAAWL,EAAO,MAGlCJ,EAAEQ,QAAQE,GAAG,OAAQ,WAOnB,OANIF,OAAOG,MAAmB,cAC5BH,OAAOC,WAAWP,EAAI,KACtBM,OAAOC,WAAWL,EAAO,MAIpBJ,EAAE,SAASU,GAAG,QACZX,OAIVa,KAAKC"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
$(document).ready(function() {
return $.ajax((window.location.href.match(/\/upgradesession/) ? window.location.href : portal) + '?kerberos=1', {

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var _krbJsAlreadySent;

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
/*
LemonLDAP::NG Notifications script

View File

@ -1 +1 @@
(function(){var t,o,a,i,e,r,n;o=$("#msg").attr("trspan"),a=function(t,e){return $("#msg").html(window.translate(t)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e)},t=function(t,e,n){return a("notificationRetrieveFailed","warning"),console.log("Error:",n,"Status:",e)},r=function(t){return t?($("#icon-explorer-button").removeClass("fa-eye"),$("#icon-explorer-button").addClass("fa-eye-slash")):($("#icon-explorer-button").removeClass("fa-eye-slash"),$("#icon-explorer-button").addClass("fa-eye"))},e=function(t){return t?($("#explorer").hide(),$("#color").hide(),r(0)):($("#explorer").show(),$("#color").show(),r(1))},i=function(t,e,n){return a(o,"positive"),$(".btn-danger").each(function(){return $(this).removeClass("btn-danger"),$(this).addClass("btn-success")}),$(".fa-eye-slash").each(function(){return $(this).removeClass("fa-eye-slash"),$(this).addClass("fa-eye")}),$(".verify").each(function(){return $(this).text(window.translate("verify")),$(this).attr("trspan","verify")}),e&&n?(t.removeClass("btn-success"),t.addClass("btn-danger"),$("#icon-"+e+"-"+n).removeClass("fa-eye"),$("#icon-"+e+"-"+n).addClass("fa-eye-slash"),$("#text-"+e+"-"+n).text(window.translate("hide")),$("#text-"+e+"-"+n).attr("trspan","hide"),$("#myNotification").removeAttr("hidden"),r(1)):($("#myNotification").attr("hidden","true"),$("#explorer-button").attr("hidden","true"))},n=function(n,o,r){return console.log("Ref:",n,"epoch:",o),n&&o?(console.log("Send AJAX request"),$.ajax({type:"GET",url:portal+"mynotifications/"+n,data:{epoch:o},dataType:"json",error:t,success:function(t){var e;return t.result?(console.log("Notification:",t.notification),i(r,n,o),$("#displayNotif").html(t.notification),$("#notifRef").text(n),e=new Date(1e3*o),$("#notifEpoch").text(e.toLocaleString()),$("#explorer-button").removeAttr("hidden")):a("notificationNotFound","warning")}})):a("notificationRetrieveFailed","warning")},$(document).ready(function(){return $(".data-epoch").each(function(){var t;return t=new Date(1e3*$(this).text()),$(this).text(t.toLocaleString())}),$("#goback").attr("href",portal),$("body").on("click",".btn-success",function(){return n($(this).attr("notif"),$(this).attr("epoch"),$(this))}),$("body").on("click",".btn-danger",function(){return i($(this))}),$("body").on("click",".btn-info",function(){return e($("#explorer").is(":visible"))})})}).call(this);
(function(){var o=$("#msg").attr("trspan"),a=function(t,e){return $("#msg").html(window.translate(t)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e)},t=function(t,e,n){return a("notificationRetrieveFailed","warning"),console.log("Error:",n,"Status:",e)},r=function(t){return t?($("#icon-explorer-button").removeClass("fa-eye"),$("#icon-explorer-button").addClass("fa-eye-slash")):($("#icon-explorer-button").removeClass("fa-eye-slash"),$("#icon-explorer-button").addClass("fa-eye"))},e=function(t){return t?($("#explorer").hide(),$("#color").hide(),r(0)):($("#explorer").show(),$("#color").show(),r(1))},i=function(t,e,n){return a(o,"positive"),$(".btn-danger").each(function(){return $(this).removeClass("btn-danger"),$(this).addClass("btn-success")}),$(".fa-eye-slash").each(function(){return $(this).removeClass("fa-eye-slash"),$(this).addClass("fa-eye")}),$(".verify").each(function(){return $(this).text(window.translate("verify")),$(this).attr("trspan","verify")}),e&&n?(t.removeClass("btn-success"),t.addClass("btn-danger"),$("#icon-"+e+"-"+n).removeClass("fa-eye"),$("#icon-"+e+"-"+n).addClass("fa-eye-slash"),$("#text-"+e+"-"+n).text(window.translate("hide")),$("#text-"+e+"-"+n).attr("trspan","hide"),$("#myNotification").removeAttr("hidden"),r(1)):($("#myNotification").attr("hidden","true"),$("#explorer-button").attr("hidden","true"))},n=function(n,o,r){return console.log("Ref:",n,"epoch:",o),n&&o?(console.log("Send AJAX request"),$.ajax({type:"GET",url:portal+"mynotifications/"+n,data:{epoch:o},dataType:"json",error:t,success:function(t){var e;return t.result?(console.log("Notification:",t.notification),i(r,n,o),$("#displayNotif").html(t.notification),$("#notifRef").text(n),e=new Date(1e3*o),$("#notifEpoch").text(e.toLocaleString()),$("#explorer-button").removeAttr("hidden")):a("notificationNotFound","warning")}})):a("notificationRetrieveFailed","warning")};$(document).ready(function(){return $(".data-epoch").each(function(){var t=new Date(1e3*$(this).text());return $(this).text(t.toLocaleString())}),$("#goback").attr("href",portal),$("body").on("click",".btn-success",function(){return n($(this).attr("notif"),$(this).attr("epoch"),$(this))}),$("body").on("click",".btn-danger",function(){return i($(this))}),$("body").on("click",".btn-info",function(){return e($("#explorer").is(":visible"))})})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["notifications.js"],"names":["displayError","msg","setMsg","toggle","toggle_explorer","toggle_eye","viewNotif","$","attr","level","html","window","translate","removeClass","addClass","j","status","err","console","log","slash","visible","hide","show","button","notif","epoch","each","this","text","removeAttr","ajax","type","url","portal","data","dataType","error","success","resp","myDate","result","notification","Date","toLocaleString","document","ready","on","is","call"],"mappings":"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"}
{"version":3,"sources":["notifications.js"],"names":["msg","$","attr","setMsg","level","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","toggle_eye","slash","toggle_explorer","visible","hide","show","toggle","button","notif","epoch","each","this","text","removeAttr","viewNotif","ajax","type","url","portal","data","dataType","error","success","resp","myDate","result","notification","Date","toLocaleString","document","ready","on","is","call"],"mappings":"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"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var values;

View File

@ -1 +1 @@
(function(){var o;o={},$(document).ready(function(){return $("script[type='application/init']").each(function(){var e,n,t;try{for(e in t=JSON.parse($(this).text()),n=[],t)n.push(o[e]=t[e]);return n}catch(e){return console.log("Parsing error",e)}}),window.addEventListener("message",function(e){var n,t,o,r,i;return t=e.data,console.log("message=",t),n=decodeURIComponent(t.split(" ")[0]),r=decodeURIComponent(t.split(" ")[1]),o=decodeURIComponent(r.split(".")[1]),i=r===btoa(n+" "+e.origin+" "+o)+"."+o?"unchanged":"changed",e.source.postMessage(i,e.origin)},!1)})}).call(this);
(function(){var r;r={},$(document).ready(function(){return $("script[type='application/init']").each(function(){var n,e,t,o;try{for(e in o=JSON.parse($(this).text()),t=[],o)t.push(r[e]=o[e]);return t}catch(e){return n=e,console.log("Parsing error",n)}}),window.addEventListener("message",function(e){var n,t,o,r,i;return t=e.data,console.log("message=",t),n=decodeURIComponent(t.split(" ")[0]),r=decodeURIComponent(t.split(" ")[1]),o=decodeURIComponent(r.split(".")[1]),i=r===btoa(n+" "+e.origin+" "+o)+"."+o?"unchanged":"changed",e.source.postMessage(i,e.origin)},!1)})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["oidcchecksession.js"],"names":["values","$","document","ready","each","k","results","tmp","JSON","parse","this","text","push","error","console","log","window","addEventListener","e","client_id","message","salt","session_state","stat","data","decodeURIComponent","split","btoa","origin","source","postMessage","call"],"mappings":"CACA,WACE,IAAIA,EAEJA,EAAS,GAETC,EAAEC,UAAUC,MAAM,WAehB,OAdAF,EAAE,mCAAmCG,KAAK,WACxC,IAAOC,EAAGC,EAASC,EACnB,IAGE,IAAKF,KAFLE,EAAMC,KAAKC,MAAMR,EAAES,MAAMC,QACzBL,EAAU,GACAC,EACRD,EAAQM,KAAKZ,EAAOK,GAAKE,EAAIF,IAE/B,OAAOC,EACP,MAAOO,GAEP,OAAOC,QAAQC,IAAI,gBADfF,MAIDG,OAAOC,iBAAiB,UAAW,SAASC,GACjD,IAAIC,EAAWC,EAASC,EAAMC,EAAmBC,EAYjD,OAXAH,EAAUF,EAAEM,KACZV,QAAQC,IAAI,WAAYK,GACxBD,EAAYM,mBAAmBL,EAAQM,MAAM,KAAK,IAClDJ,EAAgBG,mBAAmBL,EAAQM,MAAM,KAAK,IACtDL,EAAOI,mBAAmBH,EAAcI,MAAM,KAAK,IAGjDH,EADED,IADCK,KAAKR,EAAY,IAAMD,EAAEU,OAAS,IAAMP,GAAQ,IAAMA,EAElD,YAEA,UAEFH,EAAEW,OAAOC,YAAYP,EAAML,EAAEU,UACnC,OAGJG,KAAKrB"}
{"version":3,"sources":["oidcchecksession.js"],"names":["values","$","document","ready","each","e","k","results","tmp","JSON","parse","this","text","push","error","console","log","window","addEventListener","client_id","message","salt","session_state","stat","data","decodeURIComponent","split","btoa","origin","source","postMessage","call"],"mappings":"CACA,WACE,IAAIA,EAEJA,EAAS,GAETC,EAAEC,UAAUC,MAAM,WAehB,OAdAF,EAAE,mCAAmCG,KAAK,WACxC,IAAIC,EAAGC,EAAGC,EAASC,EACnB,IAGE,IAAKF,KAFLE,EAAMC,KAAKC,MAAMT,EAAEU,MAAMC,QACzBL,EAAU,GACAC,EACRD,EAAQM,KAAKb,EAAOM,GAAKE,EAAIF,IAE/B,OAAOC,EACP,MAAOO,GAEP,OADAT,EAAIS,EACGC,QAAQC,IAAI,gBAAiBX,MAGjCY,OAAOC,iBAAiB,UAAW,SAASb,GACjD,IAAIc,EAAWC,EAASC,EAAMC,EAAmBC,EAYjD,OAXAH,EAAUf,EAAEmB,KACZT,QAAQC,IAAI,WAAYI,GACxBD,EAAYM,mBAAmBL,EAAQM,MAAM,KAAK,IAClDJ,EAAgBG,mBAAmBL,EAAQM,MAAM,KAAK,IACtDL,EAAOI,mBAAmBH,EAAcI,MAAM,KAAK,IAGjDH,EADED,IADCK,KAAKR,EAAY,IAAMd,EAAEuB,OAAS,IAAMP,GAAQ,IAAMA,EAElD,YAEA,UAEFhB,EAAEwB,OAAOC,YAAYP,EAAMlB,EAAEuB,UACnC,OAGJG,KAAKpB"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
document.onreadystatechange = function() {
var redirect;

View File

@ -15,7 +15,6 @@
go = function() {
return Fingerprint2.get(function(components) {
var result, values;
console.error(components);
values = components.map((function(_this) {
return function(component) {
return component.value;

View File

@ -1 +1 @@
(function(){var n;$(document).ready(function(){return window.requestIdleCallback?requestIdleCallback(function(){return n()}):setTimeout(n,500)}),n=function(){return Fingerprint2.get(function(n){var r,t;return console.error(n),t=n.map(function(n){return n.value}),r=Fingerprint2.x64hash128(t.join(""),31),$("#fg").attr("value",r),$("#form").submit()})}}).call(this);
(function(){var n;$(document).ready(function(){return window.requestIdleCallback?requestIdleCallback(function(){return n()}):setTimeout(n,500)}),n=function(){return Fingerprint2.get(function(n){var t,r;return r=n.map(function(n){return n.value}),t=Fingerprint2.x64hash128(r.join(""),31),$("#fg").attr("value",t),$("#form").submit()})}}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["registerbrowser.js"],"names":["go","$","document","ready","window","requestIdleCallback","setTimeout","Fingerprint2","get","components","result","values","console","error","map","component","value","x64hash128","join","attr","submit","call","this"],"mappings":"CACA,WACE,IAAIA,EAEJC,EAAEC,UAAUC,MAAM,WAChB,OAAIC,OAAOC,oBACFA,oBAAoB,WACzB,OAAOL,MAGFM,WAAWN,EAAI,OAI1BA,EAAK,WACH,OAAOO,aAAaC,IAAI,SAASC,GAC/B,IAAIC,EAAQC,EASZ,OARAC,QAAQC,MAAMJ,GACdE,EAASF,EAAWK,IACX,SAASC,GACd,OAAOA,EAAUC,QAGrBN,EAASH,aAAaU,WAAWN,EAAOO,KAAK,IAAK,IAClDjB,EAAE,OAAOkB,KAAK,QAAST,GAChBT,EAAE,SAASmB,cAIrBC,KAAKC"}
{"version":3,"sources":["registerbrowser.js"],"names":["go","$","document","ready","window","requestIdleCallback","setTimeout","Fingerprint2","get","components","result","values","map","component","value","x64hash128","join","attr","submit","call","this"],"mappings":"CACA,WACE,IAAIA,EAEJC,EAAEC,UAAUC,MAAM,WAChB,OAAIC,OAAOC,oBACFA,oBAAoB,WACzB,OAAOL,MAGFM,WAAWN,EAAI,OAI1BA,EAAK,WACH,OAAOO,aAAaC,IAAI,SAASC,GAC/B,IAAIC,EAAQC,EAQZ,OAPAA,EAASF,EAAWG,IACX,SAASC,GACd,OAAOA,EAAUC,QAGrBJ,EAASH,aAAaQ,WAAWJ,EAAOK,KAAK,IAAK,IAClDf,EAAE,OAAOgB,KAAK,QAASP,GAChBT,EAAE,SAASiB,cAIrBC,KAAKC"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var sendUrl, tryssl;

View File

@ -1 +1 @@
(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);
(function(){var o=function(){var n=window.location.pathname;return 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=$("#lform").attr("action");return n.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);

View File

@ -1 +1 @@
{"version":3,"sources":["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"}
{"version":3,"sources":["ssl.js"],"names":["tryssl","path","window","location","pathname","console","log","datas","sslHost","$","ajax","dataType","xhrFields","withCredentials","success","data","sendUrl","error","result","status","responseJSON","html","trigger","form_url","attr","match","submit","document","ready","on","call","this"],"mappings":"CACA,WACE,IAEAA,EAAS,WACP,IACAC,EAAOC,OAAOC,SAASC,SA0BvB,OAzBAC,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,OADAC,EAAQf,GACDI,QAAQC,IAAI,cAAeS,IAEpCE,MAAO,SAASC,GAWd,OAVsB,IAAlBA,EAAOC,QACTH,EAAQf,GAENiB,EAAOE,cAAgB,UAAWF,EAAOE,cAA8C,MAA9BF,EAAOE,aAAaH,OAC/ED,EAAQf,GAENiB,EAAOE,cAAgB,SAAUF,EAAOE,eAC1CX,EAAE,aAAaY,KAAKH,EAAOE,aAAaC,MACxCZ,EAAEP,QAAQoB,QAAQ,SAEbjB,QAAQC,IAAI,uCAAwCY,OAGxD,GAGTF,EAAU,SAASf,GACjB,IACAsB,EAAWd,EAAE,UAAUe,KAAK,UAQ5B,OAPID,EAASE,MAAM,OACjBF,EAAWtB,EAEXsB,GAAsBtB,EAExBI,QAAQC,IAAI,sBAAuBiB,GACnCd,EAAE,UAAUe,KAAK,SAAUD,GACpBd,EAAE,UAAUiB,UAGrBjB,EAAEkB,UAAUC,MAAM,WAChB,OAAOnB,EAAE,aAAaoB,GAAG,QAAS7B,OAGnC8B,KAAKC"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
(function() {
var sendUrl, tryssl;

View File

@ -1 +1 @@
(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);
(function(){var o=function(){var n=window.location.pathname;return 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=$("#lformSSL").attr("action");return n.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);

View File

@ -1 +1 @@
{"version":3,"sources":["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"}
{"version":3,"sources":["sslChoice.js"],"names":["tryssl","path","window","location","pathname","console","log","datas","sslHost","$","ajax","dataType","xhrFields","withCredentials","success","data","sendUrl","error","result","status","responseJSON","html","trigger","form_url","attr","match","submit","document","ready","on","call","this"],"mappings":"CACA,WACE,IAEAA,EAAS,WACP,IACAC,EAAOC,OAAOC,SAASC,SA0BvB,OAzBAC,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,OADAC,EAAQf,GACDI,QAAQC,IAAI,cAAeS,IAEpCE,MAAO,SAASC,GAWd,OAVsB,IAAlBA,EAAOC,QACTH,EAAQf,GAENiB,EAAOE,cAAgB,UAAWF,EAAOE,cAA8C,MAA9BF,EAAOE,aAAaH,OAC/ED,EAAQf,GAENiB,EAAOE,cAAgB,SAAUF,EAAOE,eAC1CX,EAAE,aAAaY,KAAKH,EAAOE,aAAaC,MACxCZ,EAAEP,QAAQoB,QAAQ,SAEbjB,QAAQC,IAAI,uCAAwCY,OAGxD,GAGTF,EAAU,SAASf,GACjB,IACAsB,EAAWd,EAAE,aAAae,KAAK,UAQ/B,OAPID,EAASE,MAAM,OACjBF,EAAWtB,EAEXsB,GAAsBtB,EAExBI,QAAQC,IAAI,sBAAuBiB,GACnCd,EAAE,aAAae,KAAK,SAAUD,GACvBd,EAAE,aAAaiB,UAGxBjB,EAAEkB,UAAUC,MAAM,WAChB,OAAOnB,EAAE,aAAaoB,GAAG,QAAS7B,OAGnC8B,KAAKC"}

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
/*
LemonLDAP::NG U2F verify script

View File

@ -94,6 +94,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"قبول",
"accessDenied":"ليس لديك إذن بالدخول لهذا التطبيق",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"Dieser Dienst benötigt Zwei-Faktor-Authentifizierung. Bitte legen Sie ein Gerät an und gehen dann zum Portal zurück.",
"accept":"Akzeptieren",
"accessDenied":"Sie haben keine Zugriffsberechtigung für diese Anwendung",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"Accept",
"accessDenied":"You have no access authorization for this application",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"Este servicio necesita la autenticación de dos factores. Registre un dispositivo ahora, luego reingrese al portal.",
"accept":"Aceptar",
"accessDenied":"No está autorizado a acceder a esta aplicación",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"Hyväksy",
"accessDenied":"Sinulla ei ole käyttöoikeutta tähän sovellukseen",

View File

@ -93,6 +93,7 @@
"PE101":"Le mot de passe contient des caractères interdits",
"PE102":"Mise à niveau de la session",
"PE103":"Aucun second facteur disponible pour votre compte",
"2FDeviceNotFound":"Second facteur non trouvé",
"2fRegRequired":"Ce service requiert une authentification à deux facteurs. Enregistrez un équipement ici et retournez au portail.",
"accept":"Accepter",
"accessDenied":"Vous n'avez pas les droits d'accès à cette application",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"Questo servizio richiede un'autenticazione a doppio fattore. Registrare un dispositivo ora, quindi tornare al portale.",
"accept":"Accetta",
"accessDenied":"Non hai un'autorizzazione di accesso per questa applicazione",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"Accept",
"accessDenied":"You have no access authorization for this application",

View File

@ -93,6 +93,7 @@
"PE101":"Hasło zawiera niedozwolone znaki",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"Ta usługa wymaga podwójnego uwierzytelnienia. Zarejestruj urządzenie 2ndFA teraz, a następnie wróć do portalu.",
"accept":"Akceptuj",
"accessDenied":"Nie masz dostępu do tej aplikacji",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"Accept",
"accessDenied":"You have no access authorization for this application",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"Accept",
"accessDenied":"You have no access authorization for this application",

View File

@ -93,6 +93,7 @@
"PE101":"Parola izin verilmeyen karakterler içeriyor",
"PE102":"Oturum yükseltilmeli",
"PE103":"Hesabınız için ikinci faktör kullanılabilir değil",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"Bu servis iki adımlı kimlik doğrulama gerektiriyor. Şimdi bir cihaz ekleyin ve ardından portala geri dönün",
"accept":"Kabul Et",
"accessDenied":"Bu uygulamaya erişim yetkiniz yok",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"Chấp nhận",
"accessDenied":"Bạn không có quyền truy cập vào ứng dụng này",

View File

@ -93,6 +93,7 @@
"PE101":"Password contains not allowed characters",
"PE102":"Session must be upgraded",
"PE103":"No second factors available for your account",
"2FDeviceNotFound":"2F device not found",
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
"accept":"Accept 方法",
"accessDenied":"您无权访问此应用",

View File

@ -46,8 +46,8 @@
</TMPL_IF>
<TMPL_IF NAME="OidcConsents">
<li class="nav-item"><a class="nav-link" href="#oidcConsents"><span>
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/oidc.png" width="16" height="16" alt="login history" />
<span trspan="oidcConsents">OIDC Consents</span>
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/oidc.png" width="16" height="16" alt="OIDC consents" />
<span trspan="oidcConsents">OIDC Consent</span>
</span></a></li>
</TMPL_IF>
<TMPL_IF NAME="Logout">
@ -87,13 +87,13 @@
</TMPL_IF>
<TMPL_IF NAME="DecryptValue">
<li class="dropdown-item"><a href="/decryptvalue" class="nav-link">
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/decryptValue.png" width="20" height="20" alt="DecryptValue" />
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/decryptValue.png" width="20" height="20" alt="DecryptCipheredValue" />
<span trspan="decryptCipheredValue">decryptCipheredValue</span>
</a></li>
</TMPL_IF>
<TMPL_IF NAME="ContextSwitching">
<li class="dropdown-item"><a href="/switchcontext" class="nav-link">
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/switchcontext_<TMPL_VAR NAME="contextSwitching">.png" width="20" height="20" alt="ContentSwitching" />
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/switchcontext_<TMPL_VAR NAME="contextSwitching">.png" width="20" height="20" alt="ContextSwitching" />
<span trspan="contextSwitching_<TMPL_VAR NAME="contextSwitching">">contextSwitching_<TMPL_VAR NAME="ContextSwitching"></span>
</a></li>
</TMPL_IF>

View File

@ -45,7 +45,7 @@
</TMPL_IF>
<TMPL_IF NAME="DISPLAY_UPDATECERTIF">
<a class="btn btn-primary" href="<TMPL_VAR NAME="MAILCERTIF_URL">?skin=<TMPL_VAR NAME="SKIN"><TMPL_IF NAME="key">&<TMPL_VAR NAME="CHOICE_PARAM">=<TMPL_VAR NAME="key"></TMPL_IF><TMPL_IF NAME="AUTH_URL">&url=<TMPL_VAR NAME="AUTH_URL"></TMPL_IF>">
<a class="btn btn-secondary" href="<TMPL_VAR NAME="MAILCERTIF_URL">?skin=<TMPL_VAR NAME="SKIN"><TMPL_IF NAME="key">&<TMPL_VAR NAME="CHOICE_PARAM">=<TMPL_VAR NAME="key"></TMPL_IF><TMPL_IF NAME="AUTH_URL">&url=<TMPL_VAR NAME="AUTH_URL"></TMPL_IF>">
<span class="fa fa-refresh"></span>
<span trspan="certificateReset">Reset my certificate</span>
</a>

View File

@ -0,0 +1,469 @@
use Test::More;
use strict;
use IO::String;
use JSON qw(to_json from_json);
BEGIN {
require 't/test-lib.pm';
}
my $maintests = 64;
SKIP: {
require Lemonldap::NG::Common::TOTP;
eval { require Crypt::U2F::Server; require Authen::U2F::Tester };
if ( $@ or $Crypt::U2F::Server::VERSION < 0.42 ) {
skip 'Missing U2F libraries', $maintests;
}
eval { require Convert::Base32 };
if ($@) {
skip 'Convert::Base32 is missing';
}
my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
authentication => 'Demo',
userDB => 'Same',
portalMainLogo => 'common/logos/logo_llng_old.png',
contextSwitchingRule => 1,
contextSwitchingStopWithLogout => 0,
contextSwitchingAllowed2fModifications => 1,
totp2fSelfRegistration => 1,
totp2fActivation => 1,
u2fSelfRegistration => 1,
u2fActivation => 1,
}
}
);
## Try to authenticate
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
my ( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'password' );
$query =~ s/user=/user=rtyler/;
$query =~ s/password=/password=rtyler/;
ok(
$res = $client->_post(
'/',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Auth query'
);
my $id = expectCookie($res);
expectRedirection( $res, 'http://auth.example.com/' );
# Get Menu
# ------------------------
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'Get Menu',
);
expectOK($res);
ok(
$res->[2]->[0] =~
m%<span trspan="connectedAs">Connected as</span> rtyler%,
'Connected as rtyler'
) or print STDERR Dumper( $res->[2]->[0] );
expectAuthenticatedAs( $res, 'rtyler' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
## Try to register a TOTP
# TOTP form
my ( $key, $token, $code );
ok(
$res = $client->_get(
'/2fregisters/totp',
cookie => "lemonldap=$id",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# JS query
ok(
$res = $client->_post(
'/2fregisters/totp/getkey', IO::String->new(''),
cookie => "lemonldap=$id",
length => 0,
),
'Get new key'
);
eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' );
ok( $key = $res->{secret}, 'Found secret' ) or print STDERR Dumper($res);
ok( $token = $res->{token}, 'Found token' ) or print STDERR Dumper($res);
ok( $res->{user} eq 'rtyler', 'Found user' )
or print STDERR Dumper($res);
$key = Convert::Base32::decode_base32($key);
# Post code
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
'Code' );
ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
my $s = "code=$code&token=$token&TOTPName=myTOTP";
ok(
$res = $client->_post(
'/2fregisters/totp/verify',
IO::String->new($s),
length => length($s),
cookie => "lemonldap=$id",
),
'Post code'
);
eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' );
ok( $res->{result} == 1, 'TOTP is registered' );
## Try to register an U2F key
ok(
$res = $client->_get(
'/2fregisters/u',
cookie => "lemonldap=$id",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /u2fregistration\.(?:min\.)?js/, 'Found U2F js' );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# Ajax registration request
ok(
$res = $client->_post(
'/2fregisters/u/register', IO::String->new(''),
accept => 'application/json',
cookie => "lemonldap=$id",
length => 0,
),
'Get registration challenge'
);
expectOK($res);
my $data;
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok( ( $data->{challenge} and $data->{appId} ), ' Get challenge and appId' )
or explain( $data, 'challenge and appId' );
# Build U2F tester
my $tester = Authen::U2F::Tester->new(
certificate => Crypt::OpenSSL::X509->new_from_string(
'-----BEGIN CERTIFICATE-----
MIIB6DCCAY6gAwIBAgIJAJKuutkN2sAfMAoGCCqGSM49BAMCME8xCzAJBgNVBAYT
AlVTMQ4wDAYDVQQIDAVUZXhhczEaMBgGA1UECgwRVW50cnVzdGVkIFUyRiBPcmcx
FDASBgNVBAMMC3ZpcnR1YWwtdTJmMB4XDTE4MDMyODIwMTc1OVoXDTI3MTIyNjIw
MTc1OVowTzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRowGAYDVQQKDBFV
bnRydXN0ZWQgVTJGIE9yZzEUMBIGA1UEAwwLdmlydHVhbC11MmYwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAAQTij+9mI1FJdvKNHLeSQcOW4ob3prvIXuEGJMrQeJF
6OYcgwxrVqsmNMl5w45L7zx8ryovVOti/mtqkh2pQjtpo1MwUTAdBgNVHQ4EFgQU
QXKKf+rrZwA4WXDCU/Vebe4gYXEwHwYDVR0jBBgwFoAUQXKKf+rrZwA4WXDCU/Ve
be4gYXEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEAiCdOEmw5
hknzHR1FoyFZKRrcJu17a1PGcqTFMJHTC70CIHeCZ8KVuuMIPjoofQd1l1E221rv
RJY1Oz1fUNbrIPsL
-----END CERTIFICATE-----', Crypt::OpenSSL::X509::FORMAT_PEM()
),
key => Crypt::PK::ECC->new(
\'-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOdbZw1swQIL+RZoDQ9zwjWY5UjA1NO81WWjwbmznUbgoAoGCCqGSM49
AwEHoUQDQgAEE4o/vZiNRSXbyjRy3kkHDluKG96a7yF7hBiTK0HiRejmHIMMa1ar
JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
-----END EC PRIVATE KEY-----'
),
);
my $r = $tester->register( $data->{appId}, $data->{challenge} );
ok( $r->is_success, ' Good challenge value' )
or diag( $r->error_message );
my $registrationData = JSON::to_json( {
clientData => $r->client_data,
errorCode => 0,
registrationData => $r->registration_data,
version => "U2F_V2"
}
);
( $host, $url, $query );
$query = Lemonldap::NG::Common::FormEncode::build_urlencoded(
registration => $registrationData,
challenge => $res->[2]->[0],
);
ok(
$res = $client->_post(
'/2fregisters/u/registration', IO::String->new($query),
length => length($query),
accept => 'application/json',
cookie => "lemonldap=$id",
),
'Push registration data'
);
expectOK($res);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok( $data->{result} == 1, 'U2F key is registered' )
or explain( $data, '"result":1' );
$client->logout($id);
## Try to authenticate
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'password' );
$query =~ s/user=/user=rtyler/;
$query =~ s/password=/password=rtyler/;
ok(
$res = $client->_post(
'/',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Auth query'
);
( $host, $url, $query ) = expectForm( $res, undef, '/2fchoice', 'token' );
$query .= '&sf=totp';
ok(
$res = $client->_post(
'/2fchoice',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Post TOTP choice'
);
( $host, $url, $query ) =
expectForm( $res, undef, '/totp2fcheck', 'token' );
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
'Code' );
$query =~ s/code=/code=$code/;
ok(
$res = $client->_post(
'/totp2fcheck', IO::String->new($query),
length => length($query),
),
'Post code'
);
$id = expectCookie($res);
# Get Menu
# ------------------------
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'Get Menu',
);
expectOK($res);
expectAuthenticatedAs( $res, 'rtyler' );
# Try to switch context 'dwho'
# ContextSwitching form
ok(
$res = $client->_get(
'/switchcontext',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'ContextSwitching form',
);
( $host, $url, $query ) =
expectForm( $res, undef, '/switchcontext', 'spoofId' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_ON">%,
'Found trspan="contextSwitching_ON"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_ON"' );
## POST form
$query =~ s/spoofId=/spoofId=dwho/;
ok(
$res = $client->_post(
'/switchcontext',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST switchcontext'
);
expectRedirection( $res, 'http://auth.example.com/' );
my $id2 = expectCookie($res);
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id2",
accept => 'text/html'
),
'Get Menu',
);
expectAuthenticatedAs( $res, 'dwho' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
'Found trspan="contextSwitching_OFF"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' );
# 2fregisters
ok(
$res = $client->_get(
'/2fregisters',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form 2fregisters'
);
ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
my $devices;
ok( $devices = $res->[2]->[0] =~ s%<span device=\'(TOTP|U2F)\' epoch=\'\d{10}\'%%g,
'2F devices found' )
or print STDERR Dumper( $res->[2]->[0] );
ok( $devices == 2, 'two 2F devices found' )
or explain( $devices, 'Two 2F devices registered' );
## Try to register a TOTP
# TOTP form
ok(
$res = $client->_get(
'/2fregisters/totp',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' )
or print STDERR Dumper( $res->[2]->[0] );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# JS query
ok(
$res = $client->_post(
'/2fregisters/totp/getkey', IO::String->new(''),
cookie => "lemonldap=$id2",
length => 0,
),
'Get new key'
);
eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' );
ok( $res->{error} eq 'totpExistingKey', 'TOTP already registered' )
or explain( $res, 'Bad result' );
# Try to unregister TOTP
ok(
$res = $client->_post(
'/2fregisters/totp/delete',
IO::String->new("epoch=1234567890"),
length => 16,
cookie => "lemonldap=$id2",
),
'Delete TOTP query'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{error} eq '2FDeviceNotFound', '2F device not found'
) or explain( $data, 'Bad result' );
# Try to verify TOTP
$s = "code=123456&token=1234567890&TOTPName=myTOTP";
ok(
$res = $client->_post(
'/2fregisters/totp/verify',
IO::String->new($s),
length => length($s),
cookie => "lemonldap=$id2",
),
'Post code'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok( $data->{error} eq 'PE82', 'PE82' )
or explain( $data, 'Bad result' );
## Try to register an U2F key
# U2F form
ok(
$res = $client->_get(
'/2fregisters/u',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /u2fregistration\.(?:min\.)?js/, 'Found U2F js' );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# Ajax registration request
ok(
$res = $client->_post(
'/2fregisters/u/register', IO::String->new(''),
accept => 'application/json',
cookie => "lemonldap=$id2",
length => 0,
),
'Get registration challenge'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{challenge} =~ /\w+/, 'Get challenge'
) or explain( $data, 'Bad result' );
# Try to unregister U2F key
ok(
$res = $client->_post(
'/2fregisters/u/delete',
IO::String->new("epoch=1234567890"),
length => 16,
cookie => "lemonldap=$id2",
),
'Delete U2F key query'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{error} eq '2FDeviceNotFound', '2F device not found'
) or explain( $data, 'Bad result' );
$client->logout($id);
$client->logout($id2);
}
count($maintests);
clean_sessions();
done_testing( count() );

View File

@ -0,0 +1,469 @@
use Test::More;
use strict;
use IO::String;
use JSON qw(to_json from_json);
BEGIN {
require 't/test-lib.pm';
}
my $maintests = 63;
SKIP: {
require Lemonldap::NG::Common::TOTP;
eval { require Crypt::U2F::Server; require Authen::U2F::Tester };
if ( $@ or $Crypt::U2F::Server::VERSION < 0.42 ) {
skip 'Missing U2F libraries', $maintests;
}
eval { require Convert::Base32 };
if ($@) {
skip 'Convert::Base32 is missing';
}
my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
authentication => 'Demo',
userDB => 'Same',
portalMainLogo => 'common/logos/logo_llng_old.png',
contextSwitchingRule => 1,
contextSwitchingStopWithLogout => 0,
contextSwitchingAllowed2fModifications => 0,
totp2fSelfRegistration => 1,
totp2fActivation => 1,
u2fSelfRegistration => 1,
u2fActivation => 1,
}
}
);
## Try to authenticate
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
my ( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'password' );
$query =~ s/user=/user=rtyler/;
$query =~ s/password=/password=rtyler/;
ok(
$res = $client->_post(
'/',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Auth query'
);
my $id = expectCookie($res);
expectRedirection( $res, 'http://auth.example.com/' );
# Get Menu
# ------------------------
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'Get Menu',
);
expectOK($res);
ok(
$res->[2]->[0] =~
m%<span trspan="connectedAs">Connected as</span> rtyler%,
'Connected as rtyler'
) or print STDERR Dumper( $res->[2]->[0] );
expectAuthenticatedAs( $res, 'rtyler' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
## Try to register a TOTP
# TOTP form
my ( $key, $token, $code );
ok(
$res = $client->_get(
'/2fregisters/totp',
cookie => "lemonldap=$id",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# JS query
ok(
$res = $client->_post(
'/2fregisters/totp/getkey', IO::String->new(''),
cookie => "lemonldap=$id",
length => 0,
),
'Get new key'
);
eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' );
ok( $key = $res->{secret}, 'Found secret' ) or print STDERR Dumper($res);
ok( $token = $res->{token}, 'Found token' ) or print STDERR Dumper($res);
ok( $res->{user} eq 'rtyler', 'Found user' )
or print STDERR Dumper($res);
$key = Convert::Base32::decode_base32($key);
# Post code
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
'Code' );
ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
my $s = "code=$code&token=$token&TOTPName=myTOTP";
ok(
$res = $client->_post(
'/2fregisters/totp/verify',
IO::String->new($s),
length => length($s),
cookie => "lemonldap=$id",
),
'Post code'
);
eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' );
ok( $res->{result} == 1, 'TOTP is registered' );
## Try to register an U2F key
ok(
$res = $client->_get(
'/2fregisters/u',
cookie => "lemonldap=$id",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /u2fregistration\.(?:min\.)?js/, 'Found U2F js' );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# Ajax registration request
ok(
$res = $client->_post(
'/2fregisters/u/register', IO::String->new(''),
accept => 'application/json',
cookie => "lemonldap=$id",
length => 0,
),
'Get registration challenge'
);
expectOK($res);
my $data;
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok( ( $data->{challenge} and $data->{appId} ), ' Get challenge and appId' )
or explain( $data, 'challenge and appId' );
# Build U2F tester
my $tester = Authen::U2F::Tester->new(
certificate => Crypt::OpenSSL::X509->new_from_string(
'-----BEGIN CERTIFICATE-----
MIIB6DCCAY6gAwIBAgIJAJKuutkN2sAfMAoGCCqGSM49BAMCME8xCzAJBgNVBAYT
AlVTMQ4wDAYDVQQIDAVUZXhhczEaMBgGA1UECgwRVW50cnVzdGVkIFUyRiBPcmcx
FDASBgNVBAMMC3ZpcnR1YWwtdTJmMB4XDTE4MDMyODIwMTc1OVoXDTI3MTIyNjIw
MTc1OVowTzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRowGAYDVQQKDBFV
bnRydXN0ZWQgVTJGIE9yZzEUMBIGA1UEAwwLdmlydHVhbC11MmYwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAAQTij+9mI1FJdvKNHLeSQcOW4ob3prvIXuEGJMrQeJF
6OYcgwxrVqsmNMl5w45L7zx8ryovVOti/mtqkh2pQjtpo1MwUTAdBgNVHQ4EFgQU
QXKKf+rrZwA4WXDCU/Vebe4gYXEwHwYDVR0jBBgwFoAUQXKKf+rrZwA4WXDCU/Ve
be4gYXEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEAiCdOEmw5
hknzHR1FoyFZKRrcJu17a1PGcqTFMJHTC70CIHeCZ8KVuuMIPjoofQd1l1E221rv
RJY1Oz1fUNbrIPsL
-----END CERTIFICATE-----', Crypt::OpenSSL::X509::FORMAT_PEM()
),
key => Crypt::PK::ECC->new(
\'-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOdbZw1swQIL+RZoDQ9zwjWY5UjA1NO81WWjwbmznUbgoAoGCCqGSM49
AwEHoUQDQgAEE4o/vZiNRSXbyjRy3kkHDluKG96a7yF7hBiTK0HiRejmHIMMa1ar
JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
-----END EC PRIVATE KEY-----'
),
);
my $r = $tester->register( $data->{appId}, $data->{challenge} );
ok( $r->is_success, ' Good challenge value' )
or diag( $r->error_message );
my $registrationData = JSON::to_json( {
clientData => $r->client_data,
errorCode => 0,
registrationData => $r->registration_data,
version => "U2F_V2"
}
);
( $host, $url, $query );
$query = Lemonldap::NG::Common::FormEncode::build_urlencoded(
registration => $registrationData,
challenge => $res->[2]->[0],
);
ok(
$res = $client->_post(
'/2fregisters/u/registration', IO::String->new($query),
length => length($query),
accept => 'application/json',
cookie => "lemonldap=$id",
),
'Push registration data'
);
expectOK($res);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok( $data->{result} == 1, 'U2F key is registered' )
or explain( $data, '"result":1' );
$client->logout($id);
## Try to authenticate
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'password' );
$query =~ s/user=/user=rtyler/;
$query =~ s/password=/password=rtyler/;
ok(
$res = $client->_post(
'/',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Auth query'
);
( $host, $url, $query ) = expectForm( $res, undef, '/2fchoice', 'token' );
$query .= '&sf=totp';
ok(
$res = $client->_post(
'/2fchoice',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Post TOTP choice'
);
( $host, $url, $query ) =
expectForm( $res, undef, '/totp2fcheck', 'token' );
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
'Code' );
$query =~ s/code=/code=$code/;
ok(
$res = $client->_post(
'/totp2fcheck', IO::String->new($query),
length => length($query),
),
'Post code'
);
$id = expectCookie($res);
# Get Menu
# ------------------------
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'Get Menu',
);
expectOK($res);
expectAuthenticatedAs( $res, 'rtyler' );
# Try to switch context 'dwho'
# ContextSwitching form
ok(
$res = $client->_get(
'/switchcontext',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'ContextSwitching form',
);
( $host, $url, $query ) =
expectForm( $res, undef, '/switchcontext', 'spoofId' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_ON">%,
'Found trspan="contextSwitching_ON"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_ON"' );
## POST form
$query =~ s/spoofId=/spoofId=dwho/;
ok(
$res = $client->_post(
'/switchcontext',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST switchcontext'
);
expectRedirection( $res, 'http://auth.example.com/' );
my $id2 = expectCookie($res);
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id2",
accept => 'text/html'
),
'Get Menu',
);
expectAuthenticatedAs( $res, 'dwho' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
'Found trspan="contextSwitching_OFF"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' );
# 2fregisters
ok(
$res = $client->_get(
'/2fregisters',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form 2fregisters'
);
ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
ok( $res->[2]->[0] !~ m%<span device=\'(TOTP|U2F)\' epoch=\'\d{10}\'%g,
'No 2F device found' )
or print STDERR Dumper( $res->[2]->[0] );
## Try to register a TOTP
# TOTP form
ok(
$res = $client->_get(
'/2fregisters/totp',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' )
or print STDERR Dumper( $res->[2]->[0] );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# JS query
ok(
$res = $client->_post(
'/2fregisters/totp/getkey', IO::String->new(''),
cookie => "lemonldap=$id2",
length => 0,
),
'Get new key'
);
eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' );
ok( $res->{error} eq 'notAuthorized', 'Not authorized to register a TOTP' )
or explain( $res, 'Bad result' );
# Try to unregister TOTP
ok(
$res = $client->_post(
'/2fregisters/totp/delete',
IO::String->new("epoch=1234567890"),
length => 16,
cookie => "lemonldap=$id2",
),
'Delete TOTP query'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{error} eq 'notAuthorized',
'Not authorized to unregister a TOTP'
) or explain( $data, 'Bad result' );
# Try to verify TOTP
$s = "code=123456&token=1234567890&TOTPName=myTOTP";
ok(
$res = $client->_post(
'/2fregisters/totp/verify',
IO::String->new($s),
length => length($s),
cookie => "lemonldap=$id2",
),
'Post code'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok( $data->{error} eq 'notAuthorized', 'Not authorized to verify a TOTP' )
or explain( $data, 'Bad result' );
## Try to register an U2F key
# U2F form
ok(
$res = $client->_get(
'/2fregisters/u',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form registration'
);
ok( $res->[2]->[0] =~ /u2fregistration\.(?:min\.)?js/, 'Found U2F js' );
ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo'
) or print STDERR Dumper( $res->[2]->[0] );
# Ajax registration request
ok(
$res = $client->_post(
'/2fregisters/u/register', IO::String->new(''),
accept => 'application/json',
cookie => "lemonldap=$id2",
length => 0,
),
'Get registration challenge'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{error} eq 'notAuthorized',
'Not authorized to register an U2F key'
) or explain( $data, 'Bad result' );
# Try to unregister U2F key
ok(
$res = $client->_post(
'/2fregisters/u/delete',
IO::String->new("epoch=1234567890"),
length => 16,
cookie => "lemonldap=$id2",
),
'Delete U2F key query'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{error} eq 'notAuthorized',
'Not authorized to unregister an U2F key'
) or explain( $data, 'Bad result' );
$client->logout($id);
$client->logout($id2);
}
count($maintests);
clean_sessions();
done_testing( count() );

View File

@ -68,7 +68,7 @@ expectAuthenticatedAs( $res, 'dwho' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'Connected as dwho'
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
count(3);

View File

@ -72,7 +72,7 @@ expectAuthenticatedAs( $res, 'rtyler' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'Connected as rtyler'
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
count(2);

View File

@ -135,7 +135,7 @@ expectAuthenticatedAs( $res, 'rtyler' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'Connected as rtyler'
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
count(3);

View File

@ -71,7 +71,7 @@ expectAuthenticatedAs( $res, 'rtyler' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'Connected as rtyler'
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
count(2);

View File

@ -113,7 +113,7 @@ expectAuthenticatedAs( $res, 'dwho' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'Connected as dwho'
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
count(2);

View File

@ -29,7 +29,6 @@ SKIP: {
impersonationRule => 1,
totp2fSelfRegistration => 1,
totp2fActivation => 1,
totp2fAuthnLevel => 8,
u2fSelfRegistration => 1,
u2fActivation => 1,
}