Merge branch 'v2.0'

This commit is contained in:
Yadd 2021-06-25 14:07:11 +02:00
commit 94ec375094
74 changed files with 487 additions and 256 deletions

View File

@ -22,6 +22,7 @@ Name Comment Example
**ldapConfBase** DN of sessions branch ou=sessions,dc=example,dc=com
**ldapBindDN** Connection login cn=admin,dc=example,dc=password
**ldapBindPassword** Connection password secret
**ldapRaw** Binary attributes (?i:^jpegPhoto|;binary)
**Index** Fields to index refer to :ref:`fieldstoindex`
Optional parameters
Name Comment Default value
@ -33,3 +34,9 @@ Name Comment Default value
**ldapCAFile** Path of CA file bundle (system CA bundle)
**ldapCAPath** Perform CA directory (system CA bundle)
======================== ================================= ===============================
.. note::
In order to properly handle UTF-8 encoded values, you may need to set the
ldapRaw parameter to a non-null value. This requires
Apache::Session::Browseable >= 1.3.3

View File

@ -91,7 +91,7 @@ Ubuntu dist LLNG version Secured
19.10 Eoan `2.0.5 </documentation/2.0/>`__ |bad| CVE-2019-15941, CVE-2020-24660 None
20.04 Focal [9]_ `2.0.7 </documentation/2.0/>`__ |bad| CVE-2020-24660 None
20.10 Groovy `2.0.8 </documentation/2.0/>`__ |bad| CVE-2020-24660 None
20.10 Hirsute `2.0.11 </documentation/2.0/>`__ |clean| None
21.04 Hirsute `2.0.11 </documentation/2.0/>`__ |clean| None
=========== ============= ================================ ==================================================================== ===========
Bug report

View File

@ -136,7 +136,6 @@ An example of its content:
"hybrid"
],
"authorization_endpoint" : "http://auth.example.com/oauth2/authorize",
"check_session_iframe" : "http://auth.example.com/oauth2/checksession",
"scopes_supported" : [
"openid",
"profile",

View File

@ -573,7 +573,6 @@ tokenUseGlobalStorage Enable global token stor
totp2fActivation TOTP activation ✔
totp2fAuthnLevel Authentication level for users authentified by password+TOTP ✔
totp2fDigits Number of digits for TOTP code ✔
totp2fDisplayExistingSecret Display existing TOTP secret in registration form ✔
totp2fInterval TOTP interval ✔
totp2fIssuer TOTP Issuer ✔
totp2fLabel Portal label for TOTP 2F ✔
@ -581,7 +580,6 @@ totp2fLogo Custom logo for TOTP 2F
totp2fRange TOTP range (number of interval to test) ✔
totp2fSelfRegistration TOTP self registration activation ✔
totp2fTTL TOTP device time to live ✔
totp2fUserCanChangeKey Authorize users to change existing TOTP secret ✔
totp2fUserCanRemoveKey Authorize users to remove existing TOTP secret ✔
trustedDomains Trusted domains ✔
twitterAppName ✔

View File

@ -52,10 +52,6 @@ In the manager (advanced parameters), you just have to enable it:
- **Interval**: interval for TOTP algorithm (default: 30)
- **Range**: number of additional intervals to test (default: 1)
- **Digits**: number of digit by codes (default: 6)
- **Display existing secret**: display an already registered secret
(default: disabled)
- **Change existing secret**: authorize a user to change its previoulsy
registered TOTP secret
- **Allow users to remove TOTP**: If enabled, users can unregister
TOTP.
- **Lifetime**: Unlimited by default. Set a Time To Live in seconds.

View File

@ -64,6 +64,32 @@ Because of `bug #2482 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues
This bug was fixed in 2.0.12, but administrators are advised to clean up their persistent session database to remove any duplicate persistent sessions remaining after the upgrade.
OpenID Connect check session iframe
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The OIDC check session iframe is not working, it has been removed from OIDC configuration metadata. It should not impact any installation as this feature was already broken.
Simplification of TOTP options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following options have been removed from TOTP configuration:
* Display existing secret (``totp2fDisplayExistingSecret``)
* Change existing secret (``totp2fUserCanChangeKey``)
As a consequence, users who are *not* using the default `bootstrap` skin may need to ajust their ``totp2fregister.tpl`` template:
* Move ``#divToHide`` from the ``.col-md-6`` div to the ``.card`` div
* Change::
<pre id="serialized"></pre>
* to::
<br/><tt id="secret"></tt>
* Remove the ``#changekey`` button
2.0.11
------

View File

@ -116,8 +116,7 @@ sub delete {
sub logError {
my $self = shift;
$Lemonldap::NG::Common::Conf::msg .=
"Database error: " . $self->_dbh->errstr . "\n";
"Database error: " . $DBI::errstr . "\n";
}
1;
__END__

View File

@ -31,7 +31,7 @@ use constant DEFAULTCONFBACKENDOPTIONS => (
);
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|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|ScopeRule|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)s)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $arrayParameters = qr/^mySessionAuthorizedRWKeys$/;
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(?:A(?:llow(?:(?:ClientCredentials|Password)Grant|Offline)|ccessToken(?:Claims|JWT))|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration|OnlyDeclaredScopes)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|c(?:a(?:sS(?:rvMetaDataOptions(?:Gateway|Renew)|trictMatching)|ptcha_(?:register|login|mail)_enabled)|o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|heck(?:DevOps(?:Download)?|State|User|XSS)|rowdsec|da)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:G(?:roup(?:DecodeSearchedValu|Recursiv)|etUserBeforePasswordChang)|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)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|(?:wsdlServ|findUs)er)$/;
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(?:A(?:llow(?:(?:ClientCredentials|Password)Grant|Offline)|ccessToken(?:Claims|JWT))|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration|OnlyDeclaredScopes)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|c(?:a(?:sS(?:rvMetaDataOptions(?:Gateway|Renew)|trictMatching)|ptcha_(?:register|login|mail)_enabled)|o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|heck(?:DevOps(?:Download)?|State|User|XSS)|rowdsec|da)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:G(?:roup(?:DecodeSearchedValu|Recursiv)|etUserBeforePasswordChang)|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)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|to(?:tp2fUserCanRemoveKey|kenUseGlobalStorage)|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|(?:wsdlServ|findUs)er)$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );

View File

@ -4163,10 +4163,6 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'default' => 6,
'type' => 'int'
},
'totp2fDisplayExistingSecret' => {
'default' => 0,
'type' => 'bool'
},
'totp2fInterval' => {
'default' => 30,
'type' => 'int'
@ -4191,10 +4187,6 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'totp2fTTL' => {
'type' => 'int'
},
'totp2fUserCanChangeKey' => {
'default' => 0,
'type' => 'bool'
},
'totp2fUserCanRemoveKey' => {
'default' => 1,
'type' => 'bool'

View File

@ -9,6 +9,7 @@ use Lemonldap::NG::Manager::Build::CTrees;
use Lemonldap::NG::Manager::Build::PortalConstants;
use Lemonldap::NG::Manager::Conf::Zero;
use Data::Dumper;
use Regexp::Common 'URI';
use Regexp::Assemble;
use JSON;
use Getopt::Std;
@ -466,6 +467,7 @@ sub buildPortalConstants() {
printf STDERR $format, $self->portalConstantsFile;
open( F, '>', $self->portalConstantsFile ) or die($!);
my $urire = $RE{URI}{HTTP}{ -scheme=>qr/https?/ }{-keep};
my $content = <<EOF;
# This file is generated by $module. Don't modify it by hand
package Lemonldap::NG::Portal::Main::Constants;
@ -476,6 +478,7 @@ use Exporter 'import';
our \$VERSION = '$Lemonldap::NG::Manager::Build::Attributes::VERSION';
use constant HANDLER => 'Lemonldap::NG::Handler::PSGI::Main';
use constant URIRE => qr{$urire};
use constant {
EOF
for my $pe (
@ -499,7 +502,7 @@ $portalConstsStr
}
# EXPORTER PARAMETERS
our \@EXPORT_OK = ( 'portalConsts', 'HANDLER', $exports );
our \@EXPORT_OK = ( 'portalConsts', 'HANDLER', 'URIRE', $exports );
our %EXPORT_TAGS = ( 'all' => [ \@EXPORT_OK, 'import' ], );
our \@EXPORT = qw(import PE_OK);

View File

@ -1885,17 +1885,6 @@ sub attributes {
default => 6,
documentation => 'Number of digits for TOTP code',
},
totp2fDisplayExistingSecret => {
type => 'bool',
default => 0,
documentation =>
'Display existing TOTP secret in registration form',
},
totp2fUserCanChangeKey => {
type => 'bool',
default => 0,
documentation => 'Authorize users to change existing TOTP secret',
},
totp2fUserCanRemoveKey => {
type => 'bool',
default => 1,

View File

@ -892,12 +892,10 @@ sub tree {
'totp2fActivation',
'totp2fSelfRegistration',
'totp2fUserCanRemoveKey',
'totp2fUserCanChangeKey',
'totp2fIssuer',
'totp2fInterval',
'totp2fRange',
'totp2fDigits',
'totp2fDisplayExistingSecret',
'totp2fTTL',
'totp2fAuthnLevel',
'totp2fLabel',

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"تفعيل",
"totp2fAuthnLevel":"TOTP authentication level",
"totp2fDigits":"Number of digits",
"totp2fDisplayExistingSecret":"Display existing secret",
"totp2fInterval":"Interval",
"totp2fIssuer":"TOTP Issuer name",
"totp2fLabel":"Label",
@ -1120,7 +1119,6 @@
"totp2fRange":"Range of attempts",
"totp2fSelfRegistration":"التسجيل الذاتي",
"totp2fTTL":"Lifetime",
"totp2fUserCanChangeKey":"Change existing secret",
"totp2fUserCanRemoveKey":"Allow user to remove TOTP",
"trustedDomains":"النطاقات الموثوق بها",
"trustedProxies":"عناوين الآي بي البروكسي الموثوق بها",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"خدمة أل يو أر ل",
"yubikey2fUserCanRemoveKey":"Allow user to remove Yubikey",
"zeroConfExplanations":"لا يحتوي الخادم على إعدادات. استخدام قالب لحفظ الأول"
}
}

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"Activation",
"totp2fAuthnLevel":"TOTP authentication level",
"totp2fDigits":"Number of digits",
"totp2fDisplayExistingSecret":"Display existing secret",
"totp2fInterval":"Interval",
"totp2fIssuer":"TOTP Issuer name",
"totp2fLabel":"Label",
@ -1120,7 +1119,6 @@
"totp2fRange":"Range of attempts",
"totp2fSelfRegistration":"Self registration",
"totp2fTTL":"Lifetime",
"totp2fUserCanChangeKey":"Change existing secret",
"totp2fUserCanRemoveKey":"Allow user to remove TOTP",
"trustedDomains":"Trusted domains",
"trustedProxies":"Trusted proxies IP",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"Service URL",
"yubikey2fUserCanRemoveKey":"Allow user to remove Yubikey",
"zeroConfExplanations":"Server has no configuration. Use template to save the first."
}
}

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"Activation",
"totp2fAuthnLevel":"TOTP authentication level",
"totp2fDigits":"Number of digits",
"totp2fDisplayExistingSecret":"Display existing secret",
"totp2fInterval":"Interval",
"totp2fIssuer":"TOTP Issuer name",
"totp2fLabel":"Label",
@ -1120,7 +1119,6 @@
"totp2fRange":"Range of attempts",
"totp2fSelfRegistration":"Self registration",
"totp2fTTL":"Lifetime",
"totp2fUserCanChangeKey":"Change existing secret",
"totp2fUserCanRemoveKey":"Allow user to remove TOTP",
"trustedDomains":"Trusted domains",
"trustedProxies":"Trusted proxies IP",

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"Activación",
"totp2fAuthnLevel":"Nivel de autentificación TOTP",
"totp2fDigits":"Cantidad de dígitos",
"totp2fDisplayExistingSecret":"Mostrar secreto existente",
"totp2fInterval":"Intervalo",
"totp2fIssuer":"Nombre de emisor TOTP",
"totp2fLabel":"Etiqueta",
@ -1120,7 +1119,6 @@
"totp2fRange":"Rango de intentos",
"totp2fSelfRegistration":"Autoregistro",
"totp2fTTL":"Tiempo de vida",
"totp2fUserCanChangeKey":"Cambiar secreto existente",
"totp2fUserCanRemoveKey":"Permitir al usuario eliminación de TOTP",
"trustedDomains":"Dominios de confianza",
"trustedProxies":"IP de proxies de confianza",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"Service URL",
"yubikey2fUserCanRemoveKey":"Allow user to remove Yubikey",
"zeroConfExplanations":"Server has no configuration. Use template to save the first."
}
}

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"Activation",
"totp2fAuthnLevel":"Niveau d'authentification TOTP",
"totp2fDigits":"Nombre de chiffres",
"totp2fDisplayExistingSecret":"Afficher la clef existante",
"totp2fInterval":"Intervalle",
"totp2fIssuer":"Nom du fournisseur TOTP",
"totp2fLabel":"Label",
@ -1120,7 +1119,6 @@
"totp2fRange":"Nombre d'intervalles à tester",
"totp2fSelfRegistration":"Auto-enregistrement",
"totp2fTTL":"Durée de vie",
"totp2fUserCanChangeKey":"Changer une clef existante",
"totp2fUserCanRemoveKey":"Autoriser les utilisateurs à effacer leur TOTP",
"trustedDomains":"Domaines approuvés",
"trustedProxies":"IP des proxys de confiance",

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"Attivazione",
"totp2fAuthnLevel":"Livello di autenticazione TOTP",
"totp2fDigits":"Numero di cifre",
"totp2fDisplayExistingSecret":"Mostra segreto esistente",
"totp2fInterval":"Intervallo",
"totp2fIssuer":"Nome dell'emittente TOTP",
"totp2fLabel":"Label",
@ -1120,7 +1119,6 @@
"totp2fRange":"Gamma di tentativi",
"totp2fSelfRegistration":"Auto-registrazione",
"totp2fTTL":"Lifetime",
"totp2fUserCanChangeKey":"Cambia segreto esistente",
"totp2fUserCanRemoveKey":"Autorizza l'utente a rimuovere TOTP",
"trustedDomains":"Domini attendibili",
"trustedProxies":"IP proxy attendibili",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"URL del servizio",
"yubikey2fUserCanRemoveKey":"Autorizza l'utente a rimuovere la Yubikey",
"zeroConfExplanations":"Il server non ha alcuna configurazione. Utilizza il modello per salvare il primo."
}
}

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"Aktywacja",
"totp2fAuthnLevel":"Poziom uwierzytelnienia TOTP",
"totp2fDigits":"Ilość cyfr",
"totp2fDisplayExistingSecret":"Pokaż istniejący sekret",
"totp2fInterval":"Interwał",
"totp2fIssuer":"TOTP Nazwa wystawcy",
"totp2fLabel":"Etykieta",
@ -1120,7 +1119,6 @@
"totp2fRange":"Zakres prób",
"totp2fSelfRegistration":"Samodzielna rejestracja",
"totp2fTTL":"Dożywotni",
"totp2fUserCanChangeKey":"Zmień istniejący sekret",
"totp2fUserCanRemoveKey":"Pozwól użytkownikowi usunąć TOTP",
"trustedDomains":"Zaufane domeny",
"trustedProxies":"Zaufane proxy IP",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"URL usługi",
"yubikey2fUserCanRemoveKey":"Pozwól użytkownikowi usunąć Yubikey",
"zeroConfExplanations":"Serwer nie ma konfiguracji. Użyj szablonu, aby zapisać pierwszy."
}
}

View File

@ -689,7 +689,7 @@
"oidcRPMetaDataOptionsRule":"Erişim kuralı",
"oidcRPMetaDataOptionsTimeouts":"Zaman aşımları",
"oidcRPMetaDataOptionsUserIDAttr":"Kullanıcı niteliği",
"oidcRPMetaDataOptionsUserInfoSignAlg":"UserInfo response format",
"oidcRPMetaDataOptionsUserInfoSignAlg":"UserInfo yanıt formatı",
"oidcRPMetaDataScopeRules":"Kapsam kuralları",
"oidcRPName":"OpenID Connect RP Adı",
"oidcRPStateTimeout":"Oturum zaman aşımını belirle",
@ -1112,7 +1112,6 @@
"totp2fActivation":"Aktivasyon",
"totp2fAuthnLevel":"TOTP doğrulama seviyesi",
"totp2fDigits":"Rakam sayısı",
"totp2fDisplayExistingSecret":"Mevcut sırı görüntüle",
"totp2fInterval":"Süre aralığı",
"totp2fIssuer":"TOTP Düzenleyici adı",
"totp2fLabel":"Etiket",
@ -1120,7 +1119,6 @@
"totp2fRange":"Deneme sayısı",
"totp2fSelfRegistration":"Kendi kendine kayıt",
"totp2fTTL":"Ömür boyu",
"totp2fUserCanChangeKey":"Mevcut sırı değiştir",
"totp2fUserCanRemoveKey":"Kullanıcının TOTP'yi kaldırmasına izin ver",
"trustedDomains":"Güvenilir etki alanları",
"trustedProxies":"Güvenilir tünel IP'si",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"Servis URL'si",
"yubikey2fUserCanRemoveKey":"Yubikey'i kaldırmak için kullanıcıya izin ver",
"zeroConfExplanations":"Sunucunun yapılandırması yok. Şimdi bir tane kaydetmek için şablonu kullanın."
}
}

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"Kích hoạt",
"totp2fAuthnLevel":"TOTP authentication level",
"totp2fDigits":"Number of digits",
"totp2fDisplayExistingSecret":"Display existing secret",
"totp2fInterval":"Interval",
"totp2fIssuer":"TOTP Issuer name",
"totp2fLabel":"Label",
@ -1120,7 +1119,6 @@
"totp2fRange":"Range of attempts",
"totp2fSelfRegistration":"Tự đăng ký",
"totp2fTTL":"Lifetime",
"totp2fUserCanChangeKey":"Change existing secret",
"totp2fUserCanRemoveKey":"Allow user to remove TOTP",
"trustedDomains":"Miền tin cậy",
"trustedProxies":"proxies IP tin cậy",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"Dịch vụ URL",
"yubikey2fUserCanRemoveKey":"Allow user to remove Yubikey",
"zeroConfExplanations":"Máy chủ không có cấu hình. Sử dụng mẫu để lưu đầu tiên. "
}
}

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"激活",
"totp2fAuthnLevel":"TOTP authentication level",
"totp2fDigits":"Number of digits",
"totp2fDisplayExistingSecret":"Display existing secret",
"totp2fInterval":"Interval",
"totp2fIssuer":"TOTP Issuer name",
"totp2fLabel":"Label",
@ -1120,7 +1119,6 @@
"totp2fRange":"Range of attempts",
"totp2fSelfRegistration":"Self registration",
"totp2fTTL":"Lifetime",
"totp2fUserCanChangeKey":"Change existing secret",
"totp2fUserCanRemoveKey":"Allow user to remove TOTP",
"trustedDomains":"Trusted domains",
"trustedProxies":"Trusted proxies IP",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"Service URL",
"yubikey2fUserCanRemoveKey":"Allow user to remove Yubikey",
"zeroConfExplanations":"Server has no configuration. Use template to save the first."
}
}

View File

@ -1112,7 +1112,6 @@
"totp2fActivation":"啟用",
"totp2fAuthnLevel":"TOTP 驗證等級",
"totp2fDigits":"位數",
"totp2fDisplayExistingSecret":"顯示既有的祕密",
"totp2fInterval":"間隔",
"totp2fIssuer":"TOTP 發行者名稱",
"totp2fLabel":"標籤",
@ -1120,7 +1119,6 @@
"totp2fRange":"嘗試範圍",
"totp2fSelfRegistration":"自行註冊",
"totp2fTTL":"終生",
"totp2fUserCanChangeKey":"變更既有的祕密",
"totp2fUserCanRemoveKey":"允許使用者移除 TOTP",
"trustedDomains":"受信任的網域",
"trustedProxies":"受信任的代理伺服器 IP",
@ -1211,4 +1209,4 @@
"yubikey2fUrl":"服務 URL",
"yubikey2fUserCanRemoveKey":"允許使用者移除 Yubikey",
"zeroConfExplanations":"伺服器未設定。使用飯本來儲存第一個。"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2715,18 +2715,6 @@
"title" : "totp2fDigits",
"type" : "int"
},
{
"default" : 0,
"id" : "totp2fDisplayExistingSecret",
"title" : "totp2fDisplayExistingSecret",
"type" : "bool"
},
{
"default" : 0,
"id" : "totp2fUserCanChangeKey",
"title" : "totp2fUserCanChangeKey",
"type" : "bool"
},
{
"default" : 1,
"id" : "totp2fUserCanRemoveKey",

View File

@ -36,8 +36,7 @@ sub init {
sub run {
my ( $self, $req, $action ) = @_;
my $user = $req->userData->{ $self->conf->{whatToTrace} };
return $self->p->sendError( $req,
'No ' . $self->conf->{whatToTrace} . ' found in user data', 500 )
return $self->p->sendError( $req, 'PE82', 400 )
unless $user;
# Check if TOTP can be updated
@ -118,7 +117,7 @@ sub run {
};
if ($@) {
$self->logger->error("Corrupted session (_2fDevices): $@");
return $self->p->sendError( $req, "Corrupted session", 500 );
return $self->p->sendError( $req, "serverError", 500 );
}
}
else {
@ -139,7 +138,7 @@ sub run {
$self->logger->debug("Reading TOTP secret if exists...");
$secret = $_->{_secret} foreach (@totp2f);
return $self->p->sendError( $req, 'totpExistingKey', 200 )
if ( $token->{_totp2fSecret} eq $secret );
if $secret;
### USER CAN ONLY REGISTER ONE TOTP ###
# Delete TOTP previously registered
@ -192,7 +191,7 @@ sub run {
};
if ($@) {
$self->logger->error("Corrupted session (_2fDevices): $@");
return $self->p->sendError( $req, "Corrupted session", 500 );
return $self->p->sendError( $req, "serverError", 500 );
}
}
@ -214,26 +213,15 @@ sub run {
$self->logger->debug("Reading TOTP secret if exists...");
$secret = $_->{_secret} foreach (@totp2f);
if ( ( $req->param('newkey') and $self->conf->{totp2fUserCanChangeKey} )
or not $secret )
{
if ($secret) {
return $self->p->sendError( $req, 'totpExistingKey', 200 );
}
else {
$secret = $self->newSecret;
$self->logger->debug("Generating new secret = $secret");
$nk = 1;
}
elsif ( $req->param('newkey') ) {
return $self->p->sendError( $req, 'notAuthorized', 200 );
}
elsif ( $self->conf->{totp2fDisplayExistingSecret} ) {
$self->logger->debug("User secret = $secret");
}
else {
return $self->p->sendError( $req, 'totpExistingKey', 200 );
}
# Secret is stored in a token: we choose to not accept secret returned
# by Ajax request to avoid some attacks
my $token = $self->ott->createToken( {
@ -283,7 +271,7 @@ sub run {
};
if ($@) {
$self->logger->error("Corrupted session (_2fDevices): $@");
return $self->p->sendError( $req, "Corrupted session", 500 );
return $self->p->sendError( $req, "serverError", 500 );
}
}
else {

View File

@ -12,6 +12,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_BADURL
PE_SENDRESPONSE
URIRE
);
our $VERSION = '2.1.0';
@ -93,8 +94,7 @@ sub storeEnvAndCheckGateway {
return PE_SENDRESPONSE;
}
if ( $service and $service =~ m#^(https?://[^/]+)(/.*)?$# ) {
my ( $host, $uri ) = ( $1, $2 );
if ( $service and $service =~ URIRE ) {
my $app = $self->getCasApp($service);
if ($app) {

View File

@ -5,7 +5,7 @@ use Mouse;
use URI::Escape;
use Lemonldap::NG::Common::FormEncode;
use Lemonldap::NG::Portal::Main::Constants
qw(PE_OK PE_BADURL PE_GET_SERVICE_NOT_ALLOWED);
qw(PE_OK PE_BADURL PE_GET_SERVICE_NOT_ALLOWED URIRE);
our $VERSION = '2.1.0';
@ -82,11 +82,11 @@ sub computeGetParams {
# Additional GET variables
my %getPrms;
if ( exists $self->conf->{issuerDBGetParameters} ) {
unless ( $req->urldc =~ m#^https?://([^/]+)# ) {
unless ( $req->urldc =~ URIRE ) {
$self->logger->error("Malformed url $req->urldc");
return;
}
my $vhost = $1;
my $vhost = $3 . ( $4 ? ":$4" : '' );
my $prms = $self->conf->{issuerDBGetParameters}->{$vhost};
unless ($prms) {
$self->logger->warn("IssuerGet: $vhost has no configuration");

View File

@ -2149,7 +2149,7 @@ sub metadata {
jwks_uri => $baseUrl . $jwks_uri,
authorization_endpoint => $baseUrl . $authorize_uri,
end_session_endpoint => $baseUrl . $endsession_uri,
check_session_iframe => $baseUrl . $checksession_uri,
#check_session_iframe => $baseUrl . $checksession_uri,
introspection_endpoint => $baseUrl . $introspection_uri,
# Logout capabilities

View File

@ -10,10 +10,10 @@ with 'Lemonldap::NG::Portal::Lib::OverConf';
our $VERSION = '2.1.0';
has modules => ( is => 'rw', default => sub { {} } );
has rules => ( is => 'rw', default => sub { {} } );
has type => ( is => 'rw' );
has catch => ( is => 'rw', default => sub { {} } );
has modules => ( is => 'rw', default => sub { {} } );
has rules => ( is => 'rw', default => sub { {} } );
has type => ( is => 'rw' );
has catch => ( is => 'rw', default => sub { {} } );
has sessionKey => ( is => 'ro', default => '_choice' );
my $_choiceRules;

View File

@ -7,6 +7,8 @@ use Exporter 'import';
our $VERSION = '2.1.0';
use constant HANDLER => 'Lemonldap::NG::Handler::PSGI::Main';
use constant URIRE =>
qr{(((?^:https?))://((?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::((?:[0-9]*)))?(/(((?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?]((?:(?:[;/?:@&=+$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?)};
use constant {
PE_LOGOUT_OK => -7,
PE_PASSWORD_OK => -6,
@ -224,6 +226,7 @@ sub portalConsts {
our @EXPORT_OK = (
'portalConsts',
'HANDLER',
'URIRE',
'PE_LOGOUT_OK',
'PE_PASSWORD_OK',
'PE_IDPCHOICE',

View File

@ -377,9 +377,17 @@ sub reloadConf {
$p =~ s#https?://([^/]*).*$#$1#;
$re->add( quotemeta($p) );
}
foreach my $vhost ( keys %{ $self->conf->{locationRules} } ) {
my $expr = quotemeta($vhost);
# Handle wildcards
if ( $vhost =~ /[\%\*]/ ) {
$expr =~ s/\\\*/[A-Za-z0-9\.]\*/;
$expr =~ s/\\\%/[A-Za-z0-9]\*/;
}
$re->add($expr);
$self->logger->debug("Vhost $vhost added in trusted domains");
$re->add( quotemeta($vhost) );
$self->conf->{vhostOptions} ||= {};
if ( my $tmp =
$self->conf->{vhostOptions}->{$vhost}->{vhostAliases} )
@ -392,7 +400,7 @@ sub reloadConf {
}
}
my $tmp = 'https?://' . $re->as_string . '(?::\d+)?(?:/|$)';
my $tmp = '^https?://' . $re->as_string . '(?::\d+)?(?:/|$)';
$self->trustedDomainsRe(qr/$tmp/);
}

View File

@ -6,6 +6,7 @@ use strict;
use Mouse;
use Clone 'clone';
use JSON qw(from_json to_json);
use Lemonldap::NG::Portal::Main::Constants 'URIRE';
our $VERSION = '2.1.0';
@ -450,9 +451,8 @@ sub _filterHash {
# Check rights
my $appdisplay = $apphash->{$key}->{options}->{display}
|| "auto";
my ( $vhost, $appuri ) =
$apphash->{$key}->{options}->{uri} =~ m#^https?://([^/]*)(.*)#;
$vhost =~ s/:\d+$//;
$apphash->{$key}->{options}->{uri} =~ URIRE;
my ( $vhost, $appuri ) = ( $3, $5 );
$vhost = $self->p->HANDLER->resolveAlias($vhost);
$appuri ||= '/';

View File

@ -156,12 +156,16 @@ sub controlUrl {
}
# Unprotected hosts
my ( $proto, $vhost, $appuri ) = $tmp =~ m{^(https?://)([^/#?]*)(.*)};
$vhost =~ s/:\d+$//;
unless ( $tmp =~ URIRE ) {
$self->userLogger->error("Bad URL $tmp");
delete $req->{urldc};
return PE_BADURL;
}
my ( $proto, $vhost, $appuri ) = ( $2, $3, $5 );
# Try to resolve alias
my $originalVhost = $self->HANDLER->resolveAlias($vhost);
$vhost = $proto . $originalVhost;
$vhost = $proto . '://' . $originalVhost;
$self->logger->debug( "Required URL (param: "
. ( $req->param('logout') ? 'HTTP Referer' : 'urldc' )
. " | value: $tmp | alias: $vhost)" );
@ -332,7 +336,7 @@ sub checkXSSAttack {
# Test value
$value =~ s/\%25/\%/g;
if ( $value =~ m/(?:\0|<|'|"|`|\%(?:00|3C|22|27|2C))/ ) {
if ( $value =~ m/(?:\0|<|'|"|`|\%(?:00|3C|22|27))/ ) {
$self->userLogger->error(
"XSS attack detected (param: $name | value: $value)");
return $self->conf->{checkXSS};

View File

@ -578,8 +578,10 @@ sub updateSession {
foreach ( keys %$infos ) {
$self->logger->debug("Update sessionInfo $_");
$self->_dump( $infos->{$_} );
$req->{sessionInfo}->{$_} = $self->HANDLER->data->{$_} =
$infos->{$_};
$req->{sessionInfo}->{$_} = $infos->{$_};
if ( $id eq $self->HANDLER->data->{_session_id} ) {
$self->HANDLER->data->{$_} = $infos->{$_};
}
}
# Update session in global storage with _updateTime
@ -884,14 +886,16 @@ sub sendHtml {
my $csp = $self->csp . "form-action " . $self->conf->{cspFormAction};
if ( my $url = $req->urldc ) {
$self->logger->debug("Required urldc : $url");
$url =~ s#(https?://[^/]+).*#$1#;
$url =~ URIRE;
$url = $2 . '://' . $3 . ( $4 ? ":$4" : '' );
$self->logger->debug("Set CSP form-action with urldc : $url");
$csp .= " $url";
}
my $url = $args{params}->{URL};
if ( defined $url ) {
$self->logger->debug("Required Params URL : $url");
if ( $url =~ s#(https?://[^/]+).*#$1# ) {
if ( $url =~ URIRE ) {
$url = $2 . '://' . $3 . ( $4 ? ":$4" : '' );
$self->logger->debug("Set CSP form-action with Params URL : $url");
$csp .= " $url";
}
@ -1082,7 +1086,7 @@ sub registerLogin {
}
my $history = $req->sessionInfo->{_loginHistory} ||= {};
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
$history->{$type} ||= [];
$self->logger->debug("Current login saved into $type");

View File

@ -6,6 +6,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_APACHESESSIONERROR
PE_ERROR
PE_OK
URIRE
);
our $VERSION = '2.1.0';
@ -25,7 +26,8 @@ sub changeUrldc {
my ( $self, $req ) = @_;
my $urldc = $req->{urldc} || '';
if ( $req->id
and $urldc !~ m#^https?://[^/]*$self->{conf}->{domain}(:\d+)?/#oi
and $urldc =~ URIRE
and $3 !~ m@\Q$self->{conf}->{domain}\E$@oi
and $self->p->isTrustedUrl($urldc) )
{
my $ssl = $urldc =~ /^https/;

View File

@ -5,6 +5,7 @@ use Mouse;
use JSON qw(from_json);
use Lemonldap::NG::Common::UserAgent;
use Lemonldap::NG::Portal::Main::Constants qw(
URIRE
PE_OK
PE_ERROR
PE_BADURL
@ -124,27 +125,26 @@ sub run {
# Check URL if allowed and exists
if ( $self->conf->{checkDevOpsDownload} and $url = $req->param('url') ) {
undef $url if $self->p->checkXSSAttack( 'CheckDevOps URL', $url );
if ( $url && $url =~ m#^(?:https?://)?([^/]*)(.*)#i ) {
if ( $url && $url =~ URIRE ) {
# Reformat url
my ( $vhost, $appuri ) = $url =~ m#^(?:https?://)?([^/]*)(.*)#i;
my ($proto) = $url =~ m#^(https?://).*#i;
$proto ||= 'http://';
$url = "$proto$vhost/rules.json";
my ( $proto, $vhost, $appuri ) = ( $2, $3, $5 );
$url = "$proto://$vhost/rules.json";
my $resp = $self->ua->get( $url, 'Accept' => 'application/json' );
$self->logger->debug( "Code/Message from $url: "
. $resp->code . '/'
. $resp->message );
my $content = $resp->decoded_content;
$self->logger->debug("Content received from $url: $content") if $content;
$self->logger->debug("Content received from $url: $content")
if $content;
if ( $resp->is_success ) {
$json = eval { from_json($content, { allow_nonref => 1 }) };
$json = eval { from_json( $content, { allow_nonref => 1 } ) };
if ($@) {
# Prepare form params
undef $json;
$msg = 'PE' . PE_BAD_DEVOPS_FILE;
$msg = 'PE' . PE_BAD_DEVOPS_FILE;
$self->userLogger->error(
"CheckDevOps: bad 'rules.json' file retrieved from $url ($@)"
);
@ -153,7 +153,7 @@ sub run {
else {
# Prepare form params
$msg = 'PE' . PE_FILENOTFOUND;
$msg = 'PE' . PE_FILENOTFOUND;
$self->userLogger->error(
"CheckDevOps: Unable to download 'rules.json' file from $url"
);
@ -162,8 +162,8 @@ sub run {
else {
# Prepare form params
$msg = 'PE' . PE_BADURL;
$self->userLogger->error('CheckDevOps: bad provided URL');
$msg = 'PE' . PE_BADURL;
$self->userLogger->error('CheckDevOps: bad URL provided');
}
}
unless ( $json || $msg ) {

View File

@ -192,7 +192,7 @@ sub check {
};
return $self->p->sendJSONresponse( $req, $params )
if $req->wantJSON && $msg;
# Display form
return $self->p->sendHtml( $req, 'checkuser', params => $params )
if $msg;
@ -405,7 +405,7 @@ sub check {
sub _resolveURL {
my ( $self, $req, $url ) = @_;
my ($proto) = $url =~ m#^(https?://).*#i;
my ( $vhost, $appuri ) = $url =~ m#^(?:https?://)?([^/]*)(.*)#i;
my ( $vhost, $appuri ) = $url =~ m@^(?:https?://)?([^/#]*)(.*)@i;
my ($port) = $vhost =~ m#^.+(:\d+)$#;
$port ||= '';
$vhost =~ s/:\d+$//;
@ -467,7 +467,7 @@ sub _userData {
sub _authorization {
my ( $self, $req, $uri, $attrs ) = @_;
my ( $vhost, $appuri ) = $uri =~ m#^https?://([^/]*)(.*)#;
my ( $vhost, $appuri ) = $uri =~ m@^https?://([^/#]*)(.*)@;
my $exist = 0;
$vhost =~ s/:\d+$//;
@ -489,7 +489,7 @@ sub _authorization {
sub _headers {
my ( $self, $req, $uri, $attrs, $savedUserData ) = @_;
my ($vhost) = $uri =~ m#^https?://([^/]*).*#;
my ($vhost) = $uri =~ m@^https?://([^/#]*).*@;
$vhost =~ s/:\d+$//;
$req->{env}->{HTTP_HOST} = $vhost;

View File

@ -62,6 +62,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
portalConsts
PE_PASSWORD_OK
URIRE
);
our $VERSION = '2.1.0';
@ -247,7 +248,7 @@ sub init {
mysession => { ':sessionType' => 'updateMySession' },
['PUT']
);
extends @parents if ($add);
extends @parents if ($add);
$self->setTypes( $self->conf ) if ( $self->conf->{restSessionServer} );
return 1;
@ -406,7 +407,8 @@ sub mysession {
if ( $self->p->checkXSSAttack( 'authorizationfor', $req->urldc ) );
# Split URL
my ( $host, $uri ) = ( $req->urldc =~ m#^https?://([^/]+)(/.*)?$# );
$req->urldc =~ URIRE;
my ( $host, $uri ) = ( $3 . ( $4 ? ":$4" : '' ), $5 );
$uri ||= '/';
return $self->p->sendError( $req, "Bad URL $req->{urldc}", 400 )
unless ($host);

View File

@ -16,6 +16,7 @@ use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_FORMEMPTY
URIRE
);
our $VERSION = '2.1.0';
@ -458,7 +459,7 @@ sub isAuthorizedURI {
my ( $self, $req, $id, $url ) = @_;
die 'id is required' unless ($id);
die 'uri is required' unless ($url);
die 'Bad uri' unless ( $url =~ m#^https?://([^/]+)(/.*)?$# );
die 'Bad uri' unless ( $url =~ URIRE );
my ( $host, $uri ) = ( $1, $2 );
# Get user session.

View File

@ -3,6 +3,7 @@ LemonLDAP::NG 2F registration script
###
setMsg = (msg, level) ->
$('#msg').attr 'trspan', msg
$('#msg').html window.translate msg
$('#color').removeClass 'message-positive message-warning alert-success alert-warning'
$('#color').addClass "message-#{level}"

View File

@ -3,6 +3,7 @@ LemonLDAP::NG TOTP registration script
###
setMsg = (msg, level) ->
$('#msg').attr 'trspan', msg
$('#msg').html window.translate msg
$('#color').removeClass 'message-positive message-warning message-danger alert-success alert-warning alert-danger'
$('#color').addClass "message-#{level}"
@ -19,14 +20,12 @@ displayError = (j, status, err) ->
token = ''
getKey = (reset) ->
getKey = () ->
setMsg 'yourTotpKey', 'warning'
$.ajax
type: "POST",
url: "#{portal}/2fregisters/totp/getkey"
dataType: 'json'
data:
newkey: reset
error: displayError
# Display key and QR code
success: (data) ->
@ -50,7 +49,8 @@ getKey = (reset) ->
value: s
size:150
# Display serialized key
$('#serialized').text(s)
secret = data.secret || ""
$('#secret').text(secret.toUpperCase().replace(/(.{4})/g, '$1 ').trim())
# Show message (warning level if key is new)
if data.newkey
setMsg 'yourNewTotpKey', 'warning'
@ -61,7 +61,8 @@ getKey = (reset) ->
verify = ->
val = $('#code').val()
unless val
setMsg 'fillTheForm', 'warning'
setMsg 'totpMissingCode', 'warning'
$("#code").focus()
else
$.ajax
type: "POST",
@ -82,6 +83,5 @@ verify = ->
setMsg 'yourKeyIsRegistered', 'success'
$(document).ready ->
getKey(0)
$('#changekey').on 'click', () -> getKey(1)
getKey()
$('#verify').on 'click', () -> verify()

View File

@ -3,6 +3,7 @@ LemonLDAP::NG U2F registration script
###
setMsg = (msg, level) ->
$('#msg').attr 'trspan', msg
$('#msg').html window.translate msg
$('#color').removeClass 'message-positive message-warning message-danger alert-success alert-warning alert-danger'
$('#color').addClass "message-#{level}"

View File

@ -8,6 +8,7 @@ LemonLDAP::NG 2F registration script
var delete2F, displayError, setMsg;
setMsg = function(msg, level) {
$('#msg').attr('trspan', msg);
$('#msg').html(window.translate(msg));
$('#color').removeClass('message-positive message-warning alert-success alert-warning');
$('#color').addClass("message-" + level);

View File

@ -1 +1 @@
!function(){var 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){if(console.log("Error",t),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),e.match(/module/)?o("notAuthorized","warning"):o(e,"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",".remove2f",function(){return e($(this).attr("device"),$(this).attr("epoch"))}),$("#goback").attr("href",portal),$(".data-epoch").each(function(){var e=new Date(1e3*$(this).text());return $(this).text(e.toLocaleString())})})}.call(this);
!function(){var o=function(e,r){return $("#msg").attr("trspan",e),$("#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){if(console.log("Error",t),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),e.match(/module/)?o("notAuthorized","warning"):o(e,"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",".remove2f",function(){return e($(this).attr("device"),$(this).attr("epoch"))}),$("#goback").attr("href",portal),$(".data-epoch").each(function(){var e=new Date(1e3*$(this).text());return $(this).text(e.toLocaleString())})})}.call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["2fregistration.js"],"names":["setMsg","msg","level","$","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","match","delete2F","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,IAEAA,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,IAGzCO,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GAC1BA,EAAIM,MAAM,UACLrB,EAAO,gBAAiB,WAExBA,EAAOe,EAAK,YAKzBO,EAAW,SAASC,EAAQC,GAU1B,MATe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OAETvB,EAAO,YAAa,WAEfG,EAAEsB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,eAAiBL,EAAS,UACxCM,KAAM,CACJL,MAAOA,GAETM,SAAU,OANEX,MAoBLV,EAZPsB,QAAS,SAASC,GAChB,OAAIA,EAAKb,MACHa,EAAKb,MAAME,MAAM,iBACZrB,EAAO,gBAAiB,WAExBA,EAAO,gBAAiB,WAExBgC,EAAKC,QACd9B,EAAE,WAAaqB,GAAOU,OACflC,EAAO,wBAAyB,kBAFlC,MASbG,EAAEgC,UAAUC,MAAM,WAKhB,OAJAjC,EAAE,QAAQkC,GAAG,QAAS,YAAa,WACjC,OAAOf,EAASnB,EAAEmC,MAAMC,KAAK,UAAWpC,EAAEmC,MAAMC,KAAK,YAEvDpC,EAAE,WAAWoC,KAAK,OAAQX,QACnBzB,EAAE,eAAeqC,KAAK,WAC3B,IACAC,EAAS,IAAIC,KAAsB,IAAjBvC,EAAEmC,MAAMK,QAC1B,OAAOxC,EAAEmC,MAAMK,KAAKF,EAAOG,uBAI9BC,KAAKP"}
{"version":3,"sources":["2fregistration.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","match","delete2F","device","epoch","ajax","type","url","portal","data","dataType","success","resp","result","hide","document","ready","on","this","each","myDate","Date","text","toLocaleString","call"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GAQrB,OAPAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,gEACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUM,SAAS,SAAWP,IAGzCQ,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GAC1BA,EAAIM,MAAM,UACLtB,EAAO,gBAAiB,WAExBA,EAAOgB,EAAK,YAKzBO,EAAW,SAASC,EAAQC,GAU1B,MATe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OAETxB,EAAO,YAAa,WAEfG,EAAEuB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,eAAiBL,EAAS,UACxCM,KAAM,CACJL,MAAOA,GAETM,SAAU,OANEX,MAoBLV,EAZPsB,QAAS,SAASC,GAChB,OAAIA,EAAKb,MACHa,EAAKb,MAAME,MAAM,iBACZtB,EAAO,gBAAiB,WAExBA,EAAO,gBAAiB,WAExBiC,EAAKC,QACd/B,EAAE,WAAasB,GAAOU,OACfnC,EAAO,wBAAyB,kBAFlC,MASbG,EAAEiC,UAAUC,MAAM,WAKhB,OAJAlC,EAAE,QAAQmC,GAAG,QAAS,YAAa,WACjC,OAAOf,EAASpB,EAAEoC,MAAMnC,KAAK,UAAWD,EAAEoC,MAAMnC,KAAK,YAEvDD,EAAE,WAAWC,KAAK,OAAQyB,QACnB1B,EAAE,eAAeqC,KAAK,WAC3B,IACAC,EAAS,IAAIC,KAAsB,IAAjBvC,EAAEoC,MAAMI,QAC1B,OAAOxC,EAAEoC,MAAMI,KAAKF,EAAOG,uBAI9BC,KAAKN"}

View File

@ -8,6 +8,7 @@ LemonLDAP::NG TOTP registration script
var displayError, getKey, setMsg, token, verify;
setMsg = function(msg, level) {
$('#msg').attr('trspan', msg);
$('#msg').html(window.translate(msg));
$('#color').removeClass('message-positive message-warning message-danger alert-success alert-warning alert-danger');
$('#color').addClass("message-" + level);
@ -30,18 +31,15 @@ LemonLDAP::NG TOTP registration script
token = '';
getKey = function(reset) {
getKey = function() {
setMsg('yourTotpKey', 'warning');
return $.ajax({
type: "POST",
url: portal + "/2fregisters/totp/getkey",
dataType: 'json',
data: {
newkey: reset
},
error: displayError,
success: function(data) {
var qr, s;
var qr, s, secret;
if (data.error) {
if (data.error.match(/totpExistingKey/)) {
$("#divToHide").hide();
@ -64,7 +62,8 @@ LemonLDAP::NG TOTP registration script
value: s,
size: 150
});
$('#serialized').text(s);
secret = data.secret || "";
$('#secret').text(secret.toUpperCase().replace(/(.{4})/g, '$1 ').trim());
if (data.newkey) {
setMsg('yourNewTotpKey', 'warning');
} else {
@ -79,7 +78,8 @@ LemonLDAP::NG TOTP registration script
var val;
val = $('#code').val();
if (!val) {
return setMsg('fillTheForm', 'warning');
setMsg('totpMissingCode', 'warning');
return $("#code").focus();
} else {
return $.ajax({
type: "POST",
@ -107,10 +107,7 @@ LemonLDAP::NG TOTP registration script
};
$(document).ready(function() {
getKey(0);
$('#changekey').on('click', function() {
return getKey(1);
});
getKey();
return $('#verify').on('click', function() {
return verify();
});

View File

@ -1 +1 @@
!function(){var o=function(e,r){return $("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},r=function(e,r,t){if(console.log("Error",t),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),o(e,"warning")},t="",e=function(e){return o("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",data:{newkey:e},error:r,success:function(e){var r;return e.error?(e.error.match(/totpExistingKey/)&&$("#divToHide").hide(),o(e.error,"warning")):e.portal&&e.user&&e.secret?($("#divToHide").show(),r="otpauth://totp/"+escape(e.portal)+":"+escape(e.user)+"?secret="+e.secret+"&issuer="+escape(e.portal),6!==e.digits&&(r+="&digits="+e.digits),30!==e.interval&&(r+="&period="+e.interval),new QRious({element:document.getElementById("qr"),value:r,size:150}),$("#serialized").text(r),e.newkey?o("yourNewTotpKey","warning"):o("yourTotpKey","success"),t=e.token):o("PE24","danger")}})},n=function(){var e=$("#code").val();return e?$.ajax({type:"POST",url:portal+"/2fregisters/totp/verify",dataType:"json",data:{token:t,code:e,TOTPName:$("#TOTPName").val()},error:r,success:function(e){return e.error?e.error.match(/bad(Code|Name)/)?o(e.error,"warning"):o(e.error,"danger"):o("yourKeyIsRegistered","success")}}):o("fillTheForm","warning")};$(document).ready(function(){return e(0),$("#changekey").on("click",function(){return e(1)}),$("#verify").on("click",n)})}.call(this);
!function(){var o=function(e,r){return $("#msg").attr("trspan",e),$("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},r=function(e,r,t){if(console.log("Error",t),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),o(e,"warning")},t="",e=function(){return o("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",error:r,success:function(e){var r;return e.error?(e.error.match(/totpExistingKey/)&&$("#divToHide").hide(),o(e.error,"warning")):e.portal&&e.user&&e.secret?($("#divToHide").show(),r="otpauth://totp/"+escape(e.portal)+":"+escape(e.user)+"?secret="+e.secret+"&issuer="+escape(e.portal),6!==e.digits&&(r+="&digits="+e.digits),30!==e.interval&&(r+="&period="+e.interval),new QRious({element:document.getElementById("qr"),value:r,size:150}),r=e.secret||"",$("#secret").text(r.toUpperCase().replace(/(.{4})/g,"$1 ").trim()),e.newkey?o("yourNewTotpKey","warning"):o("yourTotpKey","success"),t=e.token):o("PE24","danger")}})},s=function(){var e=$("#code").val();return e?$.ajax({type:"POST",url:portal+"/2fregisters/totp/verify",dataType:"json",data:{token:t,code:e,TOTPName:$("#TOTPName").val()},error:r,success:function(e){return e.error?e.error.match(/bad(Code|Name)/)?o(e.error,"warning"):o(e.error,"danger"):o("yourKeyIsRegistered","success")}}):(o("totpMissingCode","warning"),$("#code").focus())};$(document).ready(function(){return e(),$("#verify").on("click",s)})}.call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["totpregistration.js"],"names":["setMsg","msg","level","$","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","token","getKey","reset","ajax","type","url","portal","dataType","data","newkey","success","s","match","hide","user","secret","show","escape","digits","interval","QRious","element","document","getElementById","value","size","text","verify","val","code","TOTPName","ready","on","call","this"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,4FACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCO,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GACvBf,EAAOe,EAAK,YAIvBM,EAAQ,GAERC,EAAS,SAASC,GAEhB,OADAvB,EAAO,cAAe,WACfG,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJC,OAAQP,GAEVJ,MAAOV,EACPsB,QAAS,SAASF,GAChB,IAAQG,EACR,OAAIH,EAAKV,OACHU,EAAKV,MAAMc,MAAM,oBACnB9B,EAAE,cAAc+B,OAEXlC,EAAO6B,EAAKV,MAAO,YAEtBU,EAAKF,QAAUE,EAAKM,MAAQN,EAAKO,QAGvCjC,EAAE,cAAckC,OAChBL,EAAI,kBAAqBM,OAAOT,EAAKF,QAAW,IAAOW,OAAOT,EAAKM,MAAS,WAAaN,EAAKO,OAAS,WAAcE,OAAOT,EAAKF,QAC7G,IAAhBE,EAAKU,SACPP,GAAK,WAAaH,EAAKU,QAEH,KAAlBV,EAAKW,WACPR,GAAK,WAAaH,EAAKW,UAEpB,IAAIC,OAAO,CACdC,QAASC,SAASC,eAAe,MACjCC,MAAOb,EACPc,KAAM,MAER3C,EAAE,eAAe4C,KAAKf,GAClBH,EAAKC,OACP9B,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBqB,EAAQQ,EAAKR,OArBXrB,EAAO,OAAQ,cA0B9BgD,EAAS,WACP,IACAC,EAAM9C,EAAE,SAAS8C,MACjB,OAAKA,EAGI9C,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJR,MAAOA,EACP6B,KAAMD,EACNE,SAAUhD,EAAE,aAAa8C,OAE3B9B,MAAOV,EACPsB,QAAS,SAASF,GAChB,OAAIA,EAAKV,MACHU,EAAKV,MAAMc,MAAM,kBACZjC,EAAO6B,EAAKV,MAAO,WAEnBnB,EAAO6B,EAAKV,MAAO,UAGrBnB,EAAO,sBAAuB,cApBpCA,EAAO,cAAe,YA2BjCG,EAAEwC,UAAUS,MAAM,WAKhB,OAJA9B,EAAO,GACPnB,EAAE,cAAckD,GAAG,QAAS,WAC1B,OAAO/B,EAAO,KAETnB,EAAE,WAAWkD,GAAG,QACdL,MAIVM,KAAKC"}
{"version":3,"sources":["totpregistration.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","token","getKey","ajax","type","url","portal","dataType","success","data","secret","match","hide","user","show","s","escape","digits","interval","QRious","element","document","getElementById","value","size","text","toUpperCase","trim","newkey","verify","val","code","TOTPName","focus","ready","on","call","this"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GAQrB,OAPAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,4FACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUM,SAAS,SAAWP,IAGzCQ,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GACvBhB,EAAOgB,EAAK,YAIvBM,EAAQ,GAERC,EAAS,WAEP,OADAvB,EAAO,cAAe,WACfG,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAChB,IAAWC,EACX,OAAID,EAAKV,OACHU,EAAKV,MAAMY,MAAM,oBACnB7B,EAAE,cAAc8B,OAEXjC,EAAO8B,EAAKV,MAAO,YAEtBU,EAAKH,QAAUG,EAAKI,MAAQJ,EAAKC,QAGvC5B,EAAE,cAAcgC,OAChBC,EAAI,kBAAqBC,OAAOP,EAAKH,QAAW,IAAOU,OAAOP,EAAKI,MAAS,WAAaJ,EAAKC,OAAS,WAAcM,OAAOP,EAAKH,QAC7G,IAAhBG,EAAKQ,SACPF,GAAK,WAAaN,EAAKQ,QAEH,KAAlBR,EAAKS,WACPH,GAAK,WAAaN,EAAKS,UAEpB,IAAIC,OAAO,CACdC,QAASC,SAASC,eAAe,MACjCC,MAAOR,EACPS,KAAM,MAERd,EAASD,EAAKC,QAAU,GACxB5B,EAAE,WAAW2C,KAAKf,EAAOgB,cAAc1B,QAAQ,UAAW,OAAO2B,QAC7DlB,EAAKmB,OACPjD,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBsB,EAAQQ,EAAKR,OAtBXtB,EAAO,OAAQ,cA2B9BkD,EAAS,WACP,IACAC,EAAMhD,EAAE,SAASgD,MACjB,OAAKA,EAIIhD,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVE,KAAM,CACJR,MAAOA,EACP8B,KAAMD,EACNE,SAAUlD,EAAE,aAAagD,OAE3B/B,MAAOV,EACPmB,QAAS,SAASC,GAChB,OAAIA,EAAKV,MACHU,EAAKV,MAAMY,MAAM,kBACZhC,EAAO8B,EAAKV,MAAO,WAEnBpB,EAAO8B,EAAKV,MAAO,UAGrBpB,EAAO,sBAAuB,eArB3CA,EAAO,kBAAmB,WACnBG,EAAE,SAASmD,UA2BtBnD,EAAEuC,UAAUa,MAAM,WAEhB,OADAhC,IACOpB,EAAE,WAAWqD,GAAG,QACdN,MAIVO,KAAKC"}

View File

@ -8,6 +8,7 @@ LemonLDAP::NG U2F registration script
var displayError, register, setMsg, verify;
setMsg = function(msg, level) {
$('#msg').attr('trspan', msg);
$('#msg').html(window.translate(msg));
$('#color').removeClass('message-positive message-warning message-danger alert-success alert-warning alert-danger');
$('#color').addClass("message-" + level);

View File

@ -1 +1 @@
!function(){var s=function(e,r){return $("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},n=function(e,r,n){if(console.log("Error",n),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),s(e,"warning")},e=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/register",data:{},dataType:"json",error:n,success:function(r){var e=[{challenge:r.challenge,version:r.version}];return s("touchU2fDevice","positive"),$("#u2fPermission").show(),u2f.register(r.appId,e,[],function(e){return $("#u2fPermission").hide(),e.errorCode?s(e.error,"warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/registration",data:{registration:JSON.stringify(e),challenge:JSON.stringify(r),keyName:$("#keyName").val()},dataType:"json",success:function(e){return e.error?e.error.match(/badName/)?s(e.error,"warning"):s("u2fFailed","danger"):e.result?s("yourKeyIsRegistered","positive"):void 0},error:n})})}})},r=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/verify",data:{},dataType:"json",error:n,success:function(r){return s("touchU2fDevice","positive"),u2f.sign(r.appId,r.challenge,r.registeredKeys,function(e){return e.errorCode?s("unableToGetKey","warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/signature",data:{signature:JSON.stringify(e),challenge:r.challenge},dataType:"json",success:function(e){return e.error?s("u2fFailed","danger"):e.result?s("yourKeyIsVerified","positive"):void 0},error:function(e,r,n){return console.log("error",n)}})})}})};$(document).ready(function(){return $("#u2fPermission").hide(),$("#register").on("click",e),$("#verify").on("click",r),$("#goback").attr("href",portal)})}.call(this);
!function(){var s=function(r,e){return $("#msg").attr("trspan",r),$("#msg").html(window.translate(r)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e)},n=function(r,e,n){if(console.log("Error",n),(r=JSON.parse(r.responseText))&&r.error)return r=r.error.replace(/.* /,""),console.log("Returned error",r),s(r,"warning")},r=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/register",data:{},dataType:"json",error:n,success:function(e){var r=[{challenge:e.challenge,version:e.version}];return s("touchU2fDevice","positive"),$("#u2fPermission").show(),u2f.register(e.appId,r,[],function(r){return $("#u2fPermission").hide(),r.errorCode?s(r.error,"warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/registration",data:{registration:JSON.stringify(r),challenge:JSON.stringify(e),keyName:$("#keyName").val()},dataType:"json",success:function(r){return r.error?r.error.match(/badName/)?s(r.error,"warning"):s("u2fFailed","danger"):r.result?s("yourKeyIsRegistered","positive"):void 0},error:n})})}})},e=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/verify",data:{},dataType:"json",error:n,success:function(e){return s("touchU2fDevice","positive"),u2f.sign(e.appId,e.challenge,e.registeredKeys,function(r){return r.errorCode?s("unableToGetKey","warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/signature",data:{signature:JSON.stringify(r),challenge:e.challenge},dataType:"json",success:function(r){return r.error?s("u2fFailed","danger"):r.result?s("yourKeyIsVerified","positive"):void 0},error:function(r,e,n){return console.log("error",n)}})})}})};$(document).ready(function(){return $("#u2fPermission").hide(),$("#register").on("click",r),$("#verify").on("click",e),$("#goback").attr("href",portal)})}.call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["u2fregistration.js"],"names":["setMsg","msg","level","$","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","register","ajax","type","url","portal","data","dataType","success","ch","request","challenge","version","show","u2f","appId","hide","errorCode","registration","stringify","keyName","val","resp","match","result","verify","sign","registeredKeys","signature","document","ready","on","attr","call","this"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,4FACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCO,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GACvBf,EAAOe,EAAK,YAIvBM,EAAW,WACT,OAAOlB,EAAEmB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,yBACdC,KAAM,GACNC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAChB,IACAC,EAAU,CACR,CACEC,UAAWF,EAAGE,UACdC,QAASH,EAAGG,UAKhB,OAFAhC,EAAO,iBAAkB,YACzBG,EAAE,kBAAkB8B,OACbC,IAAIb,SAASQ,EAAGM,MAAOL,EAAS,GAAI,SAASJ,GAElD,OADAvB,EAAE,kBAAkBiC,OAChBV,EAAKW,UACArC,EAAO0B,EAAKP,MAAO,WAEnBhB,EAAEmB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,6BACdC,KAAM,CACJY,aAActB,KAAKuB,UAAUb,GAC7BK,UAAWf,KAAKuB,UAAUV,GAC1BW,QAASrC,EAAE,YAAYsC,OAEzBd,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKvB,MACHuB,EAAKvB,MAAMwB,MAAM,WACZ3C,EAAO0C,EAAKvB,MAAO,WAEnBnB,EAAO,YAAa,UAEpB0C,EAAKE,OACP5C,EAAO,sBAAuB,iBADhC,GAITmB,MAAOV,UAQnBoC,EAAS,WACP,OAAO1C,EAAEmB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,uBACdC,KAAM,GACNC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAEhB,OADA7B,EAAO,iBAAkB,YAClBkC,IAAIY,KAAKjB,EAAGM,MAAON,EAAGE,UAAWF,EAAGkB,eAAgB,SAASrB,GAClE,OAAIA,EAAKW,UACArC,EAAO,iBAAkB,WAEzBG,EAAEmB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,0BACdC,KAAM,CACJsB,UAAWhC,KAAKuB,UAAUb,GAC1BK,UAAWF,EAAGE,WAEhBJ,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKvB,MACAnB,EAAO,YAAa,UAClB0C,EAAKE,OACP5C,EAAO,oBAAqB,iBAD9B,GAITmB,MAAO,SAAST,EAAGC,EAAQC,GACzB,OAAOC,QAAQC,IAAI,QAASF,YAS1CT,EAAE8C,UAAUC,MAAM,WAIhB,OAHA/C,EAAE,kBAAkBiC,OACpBjC,EAAE,aAAagD,GAAG,QAAS9B,GAC3BlB,EAAE,WAAWgD,GAAG,QAASN,GAClB1C,EAAE,WAAWiD,KAAK,OAAQ3B,WAGlC4B,KAAKC"}
{"version":3,"sources":["u2fregistration.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","register","ajax","type","url","portal","data","dataType","success","ch","request","challenge","version","show","u2f","appId","hide","errorCode","registration","stringify","keyName","val","resp","match","result","verify","sign","registeredKeys","signature","document","ready","on","call","this"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GAQrB,OAPAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,4FACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUM,SAAS,SAAWP,IAGzCQ,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GACvBhB,EAAOgB,EAAK,YAIvBM,EAAW,WACT,OAAOnB,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,yBACdC,KAAM,GACNC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAChB,IACAC,EAAU,CACR,CACEC,UAAWF,EAAGE,UACdC,QAASH,EAAGG,UAKhB,OAFAjC,EAAO,iBAAkB,YACzBG,EAAE,kBAAkB+B,OACbC,IAAIb,SAASQ,EAAGM,MAAOL,EAAS,GAAI,SAASJ,GAElD,OADAxB,EAAE,kBAAkBkC,OAChBV,EAAKW,UACAtC,EAAO2B,EAAKP,MAAO,WAEnBjB,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,6BACdC,KAAM,CACJY,aAActB,KAAKuB,UAAUb,GAC7BK,UAAWf,KAAKuB,UAAUV,GAC1BW,QAAStC,EAAE,YAAYuC,OAEzBd,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKvB,MACHuB,EAAKvB,MAAMwB,MAAM,WACZ5C,EAAO2C,EAAKvB,MAAO,WAEnBpB,EAAO,YAAa,UAEpB2C,EAAKE,OACP7C,EAAO,sBAAuB,iBADhC,GAIToB,MAAOV,UAQnBoC,EAAS,WACP,OAAO3C,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,uBACdC,KAAM,GACNC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAEhB,OADA9B,EAAO,iBAAkB,YAClBmC,IAAIY,KAAKjB,EAAGM,MAAON,EAAGE,UAAWF,EAAGkB,eAAgB,SAASrB,GAClE,OAAIA,EAAKW,UACAtC,EAAO,iBAAkB,WAEzBG,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,0BACdC,KAAM,CACJsB,UAAWhC,KAAKuB,UAAUb,GAC1BK,UAAWF,EAAGE,WAEhBJ,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKvB,MACApB,EAAO,YAAa,UAClB2C,EAAKE,OACP7C,EAAO,oBAAqB,iBAD9B,GAIToB,MAAO,SAAST,EAAGC,EAAQC,GACzB,OAAOC,QAAQC,IAAI,QAASF,YAS1CV,EAAE+C,UAAUC,MAAM,WAIhB,OAHAhD,EAAE,kBAAkBkC,OACpBlC,EAAE,aAAaiD,GAAG,QAAS9B,GAC3BnB,EAAE,WAAWiD,GAAG,QAASN,GAClB3C,EAAE,WAAWC,KAAK,OAAQsB,WAGlC2B,KAAKC"}

View File

@ -126,7 +126,6 @@
"cancel":"إلغاء",
"captcha":"كلمة التحقق أو الكابتشا ",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"غير كلمة المرور الخاصة بك",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"تحقق من آخر تسجيلات دخول الخاصة بي",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"الاسم الاول",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"نسيت كلمة المرور؟",
@ -294,7 +292,12 @@
"submit":"قدم",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"يرجى لمس جهاز U2F وامض الآن.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"نوع",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Abbrechen",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Neuen Schlüssel erzeugen",
"changePwd":"Ändere dein Passwort",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Überprüfe meine letzten Logins",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fülle das Formular aus",
"firstName":"Vorname",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"Passwort vergessen ?",
@ -295,6 +293,11 @@
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"Es existiert bereits ein TOTP-Secret",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Please touch the flashing U2F device now.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Type",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Cancel",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"Change your password",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Check my last logins",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"First name",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"Forgot your password?",
@ -294,7 +292,12 @@
"submit":"Submit",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Please touch the flashing U2F device now.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Type",

View File

@ -126,7 +126,6 @@
"cancel":"Cancelar",
"captcha":"Captcha",
"certificateReset":"Reiniciar mi certificado",
"changeKey":"Generar nueva llave",
"changePwd":"Cambie su contraseña",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Verificar mis últimos accesos",
@ -169,7 +168,6 @@
"expired2Fremoved":"¡%s dispositivos 2F caducados han sido suprimidos!",
"explorer":"Explorer",
"ext2f":"Código de verificación",
"fillTheForm":"Llene el formulario",
"firstName":"Nombre",
"forbidden":"Acceso DENEGADO",
"forgotPwd":"Contraseña olvidada?",
@ -295,6 +293,11 @@
"switchContext":"Cambiar contexto",
"totp2f":"Aplicación OTP",
"totpExistingKey":"Un secreto TOTP ya existe",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Por favor toque el dispositivo U2F centelleante ahora.",
"touchU2fDeviceOrEnterTotp":"Por favor toque el dispositivo U2F centelleante o ingrese el código TOTP.",
"type":"Tipo",
@ -335,4 +338,4 @@
"yourProfile":"Conozca su perfil",
"yourTotpKey":"Su llave TOTP",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Peruuta",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"Vaihda salasanasi",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Tarkista viimeiset kirjautumiseni",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"Etunimi",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"Unohditko salasanasi?",
@ -294,7 +292,12 @@
"submit":"Lähetä",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Please touch the flashing U2F device now.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Type",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Annuler",
"captcha":"Captcha",
"certificateReset":"Réinitialiser mon certificat",
"changeKey":"Générer une nouvelle clef",
"changePwd":"Changez votre mot de passe",
"checkDevOps":"Vérifier un fichier DevOps",
"checkLastLogins":"Voir mes dernières connexions",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s seconds facteurs expirés ont été supprimés !",
"explorer":"Explorateur",
"ext2f":"Code de vérification",
"fillTheForm":"Remplissez le formulaire",
"firstName":"Prénom",
"forbidden":"Accès INTERDIT",
"forgotPwd":"Mot de passe oublié ?",
@ -294,7 +292,12 @@
"submit":"Envoyer",
"switchContext":"Changer de contexte",
"totp2f":"Application OTP",
"totpExistingKey":"Un secret TOTP existe déjà !",
"totpExistingKey":"Un périphérique TOTP est déja enregistré, vous devez le supprimer pour pouvoir en ajouter un nouveau",
"totpMissingCode":"Veuillez entrer le code fourni par votre application TOTP",
"totpQrCode":"Scannez ce QR code dans votre application TOTP",
"totpRegisterCode":"Recopiez le code affiché par votre application",
"totpRegisterName":"Choisissez un nom pour votre périphérique TOTP",
"totpSecretKey":"Si votre application n'accepte pas les QR codes, saisissez la clé suivante:",
"touchU2fDevice":"Posez votre doigt sur le périphérique U2F",
"touchU2fDeviceOrEnterTotp":"Posez votre doigt sur le périphérique U2F ou entrez le code TOTP",
"type":"Type",

View File

@ -126,7 +126,6 @@
"cancel":"Cancella",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Genera nuova chiave",
"changePwd":"Cambia la tua password",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Controllare i miei ultimi accessi",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Compila il modulo",
"firstName":"Nome",
"forbidden":"Accesso VIETATO",
"forgotPwd":"Password dimenticata?",
@ -295,6 +293,11 @@
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"Un segreto TOTP esiste già",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Adesso tocca il dispositivo U2F lampeggiante.",
"touchU2fDeviceOrEnterTotp":"Tocca il dispositivo U2F lampeggiante o inserisci il codice TOTP.",
"type":"Tipo",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"La tua chiave TOTP",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Cancel",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"Change your password",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Check my last logins",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"First name",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"Forgot your password?",
@ -294,7 +292,12 @@
"submit":"Submit",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Please touch the flashing U2F device now.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Type",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Anuluj",
"captcha":"Captcha",
"certificateReset":"Zresetuj mój certyfikat",
"changeKey":"Wygeneruj nowy klucz",
"changePwd":"Zmień swoje hasło",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Sprawdź moje ostatnie logowania",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s przeterminowane urządzenia 2F zostały usunięte!",
"explorer":"Eksplorator",
"ext2f":"Kod weryfikacyjny",
"fillTheForm":"Wypełnij formularz",
"firstName":"Imię",
"forbidden":"Dostęp ZABRONIONY",
"forgotPwd":"Zapomniałeś hasła?",
@ -295,6 +293,11 @@
"switchContext":"Przełącz kontekst",
"totp2f":"Aplikacja OTP",
"totpExistingKey":"Sekret TOTP już istnieje",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Dotknij teraz migającego urządzenia U2F.",
"touchU2fDeviceOrEnterTotp":"Dotknij migającego urządzenia U2F lub wprowadź kod TOTP.",
"type":"Rodzaj",
@ -335,4 +338,4 @@
"yourProfile":"Twój profil",
"yourTotpKey":"Twój klucz TOTP",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Cancel",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"Change your password",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Check my last logins",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"First name",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"Forgot your password?",
@ -294,7 +292,12 @@
"submit":"Submit",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Please touch the flashing U2F device now.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Type",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Cancel",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"Change your password",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Check my last logins",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"First name",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"Forgot your password?",
@ -294,7 +292,12 @@
"submit":"Submit",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Please touch the flashing U2F device now.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Type",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey"
}
}

View File

@ -125,8 +125,7 @@
"badName":"Hatalı isim",
"cancel":"İptal Et",
"captcha":"Captcha",
"certificateReset":"Reset my certificate",
"changeKey":"Yeni anahtar üret",
"certificateReset":"Sertifikamı sıfırla",
"changePwd":"Parolanı değiştir",
"checkDevOps":"DevOps eğitici dosyasını kontrol edin",
"checkLastLogins":"Son girişlerimi kontrol et",
@ -169,7 +168,6 @@
"expired2Fremoved":"Kullanım süresi dolan %s2F cihazı kaldırıldı!",
"explorer":"Explorer",
"ext2f":"Doğrulama kodu",
"fillTheForm":"Formu doldur",
"firstName":"Ad",
"forbidden":"Erişim YASAKLI",
"forgotPwd":"Parolanızı mı unuttunuz?",
@ -295,6 +293,11 @@
"switchContext":"Bağlam değiştir",
"totp2f":"OTP Uygulaması",
"totpExistingKey":"Bir TOTP sırrı zaten mevcut",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Lütfen şimdi yanıp sönen U2F cihazına dokunun.",
"touchU2fDeviceOrEnterTotp":"Lütfen şimdi yanıp sönen U2F cihazına dokunun veya TOTP kodunu girin.",
"type":"Tür",
@ -335,4 +338,4 @@
"yourProfile":"Profilini bil",
"yourTotpKey":"TOTP anahtarınız",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"Hủy",
"captcha":"Mã kiểm tra",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"Thay đổi mật khẩu của bạn",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Kiểm tra lần đăng nhập cuối cùng của bạn",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"Tên",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"Quên mật khẩu của bạn?",
@ -294,7 +292,12 @@
"submit":"Gửi",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Vui lòng chạm vào thiết bị U2F nhấp nháy ngay bây giờ.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Loại",
@ -335,4 +338,4 @@
"yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey"
}
}

View File

@ -126,7 +126,6 @@
"cancel":"取消",
"captcha":"验证码",
"certificateReset":"Reset my certificate",
"changeKey":"Generate new key",
"changePwd":"修改您的密码",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"Check my last logins",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s expired 2F devices have been removed!",
"explorer":"Explorer",
"ext2f":"Verification code",
"fillTheForm":"Fill the form",
"firstName":"名",
"forbidden":"Access FORBIDDEN",
"forgotPwd":"忘记密码?",
@ -294,7 +292,12 @@
"submit":"提交",
"switchContext":"Switch context",
"totp2f":"OTP App",
"totpExistingKey":"A TOTP secret already exists",
"totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"Please touch the flashing U2F device now.",
"touchU2fDeviceOrEnterTotp":"Please touch the flashing U2F device or enter TOTP code.",
"type":"Type",

View File

@ -126,7 +126,6 @@
"cancel":"取消",
"captcha":"驗證碼",
"certificateReset":"重設我們的憑證",
"changeKey":"生成新的金鑰",
"changePwd":"變更您的密碼",
"checkDevOps":"Check DevOps handler file",
"checkLastLogins":"檢查我的上次登入",
@ -169,7 +168,6 @@
"expired2Fremoved":"%s 個過期的雙因素驗證已被移除!",
"explorer":"探索者",
"ext2f":"驗證代碼",
"fillTheForm":"填表單",
"firstName":"名",
"forbidden":"禁止存取",
"forgotPwd":"忘記您的密碼?",
@ -295,6 +293,11 @@
"switchContext":"切換內容",
"totp2f":"OTP 應用程式",
"totpExistingKey":"TOTP 祕密已存在",
"totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application",
"totpRegisterName":"Choose a name for this TOTP device",
"totpSecretKey":"If your TOTP application does not support QR codes, enter the following key instead:",
"touchU2fDevice":"請立刻碰觸閃爍中的 U2F 裝置。",
"touchU2fDeviceOrEnterTotp":"請立刻碰觸閃爍中的 U2F 裝置或輸入 TOTP 代碼。",
"type":"類型",
@ -335,4 +338,4 @@
"yourProfile":"知道您的個人檔案",
"yourTotpKey":"您的 TOTP 金鑰",
"yubikey2f":"Yubikey"
}
}

View File

@ -4,34 +4,33 @@
<div id="color" class="message message-<TMPL_VAR NAME="ALERT"> alert"><span id="msg" trspan="<TMPL_VAR NAME="MSG">"></span></div>
<div class="card">
<div id="divToHide" class="card">
<div class="card-body">
<div class="row">
<div id="divToHide" class="col-md-6 text-center">
<div class="col-md-6 text-center">
<div >
<p>&#x2460; <span trspan="totpQrCode"></span></p>
<canvas id="qr"></canvas>
<pre id="serialized"></pre>
<p><span trspan="totpSecretKey"></span></p>
<tt id="secret"></tt>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="TOTPName"><span trspan="name">Name</span></label>
<label for="TOTPName">&#x2461; <span trspan="totpRegisterName">Name</span></label>
<input type="text" class="form-control" id="TOTPName" name="TOTPName" value="MyTOTP" trplaceholder="name" />
</div>
<div class="form-group">
<label for="code"><span trspan="code">Code</span></label>
<input id="code" class="form-control" name="code" type="number" autocomplete="off" />
<label for="code">&#x2462; <span trspan="totpRegisterCode">Code</span></label>
<input id="code" class="form-control" name="code" autocomplete="off" />
</div>
</div>
</div>
<div class="buttons">
<span id="changekey" class="btn btn-info" role="button">
<span class="fa fa-refresh"></span>
<span trspan="changeKey">Change key</span>
</span>
<span id="verify" class="btn btn-success" role="button">
<span class="fa fa-floppy-o"></span>
<span trspan="register">Register</span>

View File

@ -143,9 +143,9 @@ ok( $res->{MSG} eq 'PE105', 'PE105' )
or print STDERR Dumper($res);
count(4);
# Download file
# -------------
$query = 'url=http://test3.example.com';
# Bad URLs
# --------
$query = 'url=test3.example.com';
ok(
$res = $client->_post(
'/checkdevops',
@ -157,19 +157,26 @@ ok(
);
ok( $res = eval { from_json( $res->[2]->[0] ) }, 'Response is JSON' )
or print STDERR "$@\n" . Dumper($res);
ok( $res->{ALERTE} eq 'alert-info', 'alert-info found' )
ok( $res->{MSG} eq 'PE37', 'Bad URL' )
or print STDERR Dumper($res);
ok( $res->{FILE} =~ /headers/, 'headers found' )
count(3);
# --------
$query = 'url=http://test3.example.com#test';
ok(
$res = $client->_post(
'/checkdevops',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
),
'POST checkdevops with wrong url'
);
ok( $res = eval { from_json( $res->[2]->[0] ) }, 'Response is JSON' )
or print STDERR "$@\n" . Dumper($res);
ok( $res->{URL} eq 'http://test3.example.com/rules.json', 'Well formated URL' )
or print STDERR Dumper($res);
ok( $res->{FILE} =~ /rules/, 'rules found' )
or print STDERR Dumper($res);
ok( $res->{FILE} =~ /"\$uid ne qq#dwho#"/, 'rule found' )
or print STDERR Dumper($res);
ok( $res->{URL} eq 'http://test3.example.com/rules.json', 'URL found' )
or print STDERR Dumper($res);
ok( $res->{MSG} eq 'checkDevOps', 'MSG found' )
or print STDERR Dumper($res);
count(8);
count(3);
$client->logout($id);
clean_sessions();

View File

@ -0,0 +1,168 @@
use Test::More;
use strict;
use IO::String;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_FIRSTACCESS
);
require 't/test-lib.pm';
sub validate_cda {
my ( $client, $query, $domain, $expectedUser ) = @_;
# Initialize handler
use_ok('Lemonldap::NG::Handler::Server');
use_ok('Lemonldap::NG::Common::PSGI::Cli::Lib');
count(2);
my ( $cli, $app, $res );
ok( $app = Lemonldap::NG::Handler::Server->run( $client->ini ), 'App' );
count(1);
ok(
$res = $app->( {
'HTTP_ACCEPT' => 'text/html',
'SCRIPT_NAME' => '/',
'SERVER_NAME' => '127.0.0.1',
'QUERY_STRING' => $query,
'HTTP_CACHE_CONTROL' => 'max-age=0',
'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3',
'PATH_INFO' => '/',
'REQUEST_METHOD' => 'GET',
'REQUEST_URI' => "/?$query",
'X_ORIGINAL_URI' => "/?$query",
'SERVER_PORT' => '80',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'HTTP_USER_AGENT' =>
'Mozilla/5.0 (VAX-4000; rv:36.0) Gecko/20350101 Firefox',
'REMOTE_ADDR' => '127.0.0.1',
'HTTP_HOST' => $domain,
'VHOSTTYPE' => 'CDA',
}
),
'Push cda cookie'
);
count(1);
expectRedirection( $res, "http://$domain/" );
my $cid = expectCookie($res);
ok(
$res = $app->( {
'HTTP_ACCEPT' => 'text/html',
'SCRIPT_NAME' => '/',
'SERVER_NAME' => '127.0.0.1',
'HTTP_COOKIE' => "lemonldap=$cid",
'HTTP_CACHE_CONTROL' => 'max-age=0',
'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3',
'PATH_INFO' => '/',
'REQUEST_METHOD' => 'GET',
'REQUEST_URI' => "/",
'X_ORIGINAL_URI' => "/",
'SERVER_PORT' => '80',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'HTTP_USER_AGENT' =>
'Mozilla/5.0 (VAX-4000; rv:36.0) Gecko/20350101 Firefox',
'REMOTE_ADDR' => '127.0.0.1',
'HTTP_HOST' => $domain,
'VHOSTTYPE' => 'CDA',
}
),
'Authenticated query'
);
count(1);
expectOK($res);
expectAuthenticatedAs( $res, $expectedUser );
}
my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
useSafeJail => 1,
cda => 1,
logger => 'Lemonldap::NG::Common::Logger::Std',
}
}
);
# CDA with unauthentified user
ok(
$res = $client->_get(
'/',
query => 'url=' . encodeUrl('http://cda.example.llng/'),
accept => 'text/html',
),
'Unauth CDA request'
);
my ( $host, $url, $query ) = expectForm( $res, undef, undef, 'url' );
count(1);
# Authentification
$query .= '&user=dwho&password=dwho';
ok(
$res = $client->_post(
'/' => IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Post credentials'
);
count(1);
($query) =
expectRedirection( $res, qr#^http://cda.example.llng/\?(lemonldapcda=.*)$# );
my $id = expectCookie($res);
# Check that *.example.llng allows subdomains
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
query => 'url=' . encodeUrl('http://sub.cda.example.llng/'),
accept => 'text/html',
),
'CDA request to subdomain'
);
count(1);
my ($querytosub) = expectRedirection( $res,
qr#^http://sub.cda.example.llng/\?(lemonldapcda=.*)$# );
# Check that %.oneonly.llng rejects subdomains
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
query => 'url=' . encodeUrl('http://sub.cda.oneonly.llng/'),
accept => 'text/html',
),
'CDA request to subdomain'
);
count(1);
expectPortalError( $res, 37, "Subdomain CDA request not allowed by wildcard" );
# Check that %.oneonly.llng allows one-level domains
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
query => 'url=' . encodeUrl('http://cda.oneonly.llng/'),
accept => 'text/html',
),
'CDA request to one-level wildcard'
);
count(1);
my ($querytoone) =
expectRedirection( $res, qr#^http://cda.oneonly.llng/\?(lemonldapcda=.*)$# );
validate_cda( $client, $querytosub, 'sub.cda.example.llng', 'dwho' );
validate_cda( $client, $query, 'cda.example.llng', 'dwho' );
validate_cda( $client, $querytoone, 'cda.oneonly.llng', 'dwho' );
clean_sessions();
done_testing( count() );

View File

@ -24,7 +24,10 @@ my $client = LLNG::Manager::Test->new( {
ok(
$res = $client->_get(
'/',
query => 'url=aHR0cDovL3Rlc3QuZXhhbXBsZS5vcmcv',
query => buildForm( {
url => encodeUrl('http://test.example.org/'),
}
),
accept => 'text/html',
),
'Unauth CDA request'
@ -44,10 +47,30 @@ ok(
'Post credentials'
);
count(1);
my $id = expectCookie($res);
($query) =
expectRedirection( $res, qr#^http://test.example.org/\?(lemonldapcda=.*)$# );
# Check URLs are correctly filtered
ok(
$res = $client->_get(
'/',
query => buildForm( {
url => encodeUrl(
'http://your-untrusted-domain.com/?attack=http://test.example.org/'
),
}
),
cookie => "lemonldap=$id",
accept => 'text/html',
),
'Dangerous request'
);
count(1);
expectPortalError( $res, 37, "Untrusted URL denied by portal" );
# Handler part
use_ok('Lemonldap::NG::Handler::Server');
use_ok('Lemonldap::NG::Common::PSGI::Cli::Lib');

View File

@ -11,7 +11,7 @@ count(1);
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'debug',
logLevel => 'error',
mail2fActivation => '$uid eq "msmith"',
mail2fAuthnLevel => 3,
mail2fCodeRegex => '\d{4}',
@ -40,14 +40,15 @@ ok(
),
'Get portal'
);
expectAuthenticatedAs($res, 'dwho');
expectAuthenticatedAs( $res, 'dwho' );
count(1);
# Start logging in as msmith
my $s = buildForm({
user => 'msmith',
my $s = buildForm( {
user => 'msmith',
password => 'msmith',
});
}
);
ok(
$res = $client->_post(
'/',
@ -84,7 +85,7 @@ ok(
);
count(1);
# Finish logging in as msmith,
# Finish logging in as msmith,
# this corrupts the dwho cache with msmith macros
$query =~ s/code=/code=${code}/;
ok(
@ -97,7 +98,6 @@ ok(
'Post code'
);
count(1);
diag Dumper($res);
# Reuse the corrupted cache
ok(
@ -108,11 +108,7 @@ ok(
);
count(1);
TODO: {
local $TODO = "Fix 2539";
expectAuthenticatedAs($res, 'dwho');
}
expectAuthenticatedAs( $res, 'dwho' );
clean_sessions();

View File

@ -67,6 +67,10 @@
"*.example.llng": {
"Auth-User": "$uid",
"testHeader1": "'testHeader_value'"
},
"%.oneonly.llng": {
"Auth-User": "$uid",
"testHeader1": "'testHeader_value'"
}
},
"exportedVars": {
@ -109,6 +113,9 @@
},
"*.example.llng": {
"default": "accept"
},
"%.oneonly.llng": {
"default": "accept"
}
},
"macros": {