Merge branch 'v2.0'
This commit is contained in:
commit
94ec375094
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 ✔
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
------
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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' );
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -892,12 +892,10 @@ sub tree {
|
|||
'totp2fActivation',
|
||||
'totp2fSelfRegistration',
|
||||
'totp2fUserCanRemoveKey',
|
||||
'totp2fUserCanChangeKey',
|
||||
'totp2fIssuer',
|
||||
'totp2fInterval',
|
||||
'totp2fRange',
|
||||
'totp2fDigits',
|
||||
'totp2fDisplayExistingSecret',
|
||||
'totp2fTTL',
|
||||
'totp2fAuthnLevel',
|
||||
'totp2fLabel',
|
||||
|
|
|
@ -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":"لا يحتوي الخادم على إعدادات. استخدام قالب لحفظ الأول"
|
||||
}
|
||||
}
|
|
@ -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."
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
}
|
|
@ -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."
|
||||
}
|
||||
}
|
|
@ -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."
|
||||
}
|
||||
}
|
|
@ -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. "
|
||||
}
|
||||
}
|
|
@ -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."
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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",
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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/);
|
||||
|
||||
}
|
||||
|
|
|
@ -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 ||= '/';
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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/;
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
|
@ -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"}
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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);
|
|
@ -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"}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
|
@ -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"}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>① <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">② <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">③ <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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() );
|
|
@ -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');
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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": {
|
||||
|
|
Loading…
Reference in New Issue