Merge branch 'unregister-my-u2f-key' into 'master'

Add self unregistration for u2f key (#1148)

See merge request lemonldap-ng/lemonldap-ng!14
environments/ppa-mbqj77/deployments/1
Xavier Guimard 7 years ago
commit 3d381edd6c
  1. 74
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm
  2. 1
      lemonldap-ng-manager/site/htdocs/static/js/conftree.min.js
  3. 31
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm
  4. 38
      lemonldap-ng-portal/site/coffee/u2fregistration.coffee
  5. 47
      lemonldap-ng-portal/site/htdocs/static/common/js/u2fregistration.js
  6. 2
      lemonldap-ng-portal/site/htdocs/static/common/js/u2fregistration.min.js
  7. 4
      lemonldap-ng-portal/site/htdocs/static/languages/ar.json
  8. 4
      lemonldap-ng-portal/site/htdocs/static/languages/de.json
  9. 4
      lemonldap-ng-portal/site/htdocs/static/languages/en.json
  10. 4
      lemonldap-ng-portal/site/htdocs/static/languages/es.json
  11. 2
      lemonldap-ng-portal/site/htdocs/static/languages/fr.json
  12. 2
      lemonldap-ng-portal/site/htdocs/static/languages/it.json
  13. 4
      lemonldap-ng-portal/site/htdocs/static/languages/nl.json
  14. 4
      lemonldap-ng-portal/site/htdocs/static/languages/pt.json
  15. 2
      lemonldap-ng-portal/site/htdocs/static/languages/ro.json
  16. 2
      lemonldap-ng-portal/site/htdocs/static/languages/vi.json
  17. 4
      lemonldap-ng-portal/site/templates/bootstrap/u2fregister.tpl

@ -8,12 +8,12 @@ sub types {
'authParamsText' => {
'test' => sub {
1;
}
}
},
'blackWhiteList' => {
'test' => sub {
1;
}
}
},
'bool' => {
'msgFail' => '__notABoolean__',
@ -36,17 +36,17 @@ sub types {
split( /\n/, $@, 0 ) )
);
return $err ? ( 1, "__badExpression__: $err" ) : 1;
}
}
},
'catAndAppList' => {
'test' => sub {
1;
}
}
},
'file' => {
'test' => sub {
1;
}
}
},
'hostname' => {
'form' => 'text',
@ -80,48 +80,48 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val};
}
return 1, "__unknownAttrOrMacro__: $val";
}
}
},
'longtext' => {
'test' => sub {
1;
}
}
},
'menuApp' => {
'test' => sub {
1;
}
}
},
'menuCat' => {
'test' => sub {
1;
}
}
},
'oidcmetadatajson' => {
'test' => sub {
1;
}
}
},
'oidcmetadatajwks' => {
'test' => sub {
1;
}
}
},
'oidcOPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'oidcRPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'password' => {
'msgFail' => '__malformedValue__',
'test' => sub {
1;
}
}
},
'pcre' => {
'form' => 'text',
@ -132,7 +132,7 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
}
};
return $@ ? ( 0, "__badRegexp__: $@" ) : 1;
}
}
},
'PerlModule' => {
'form' => 'text',
@ -142,17 +142,17 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'portalskin' => {
'test' => sub {
1;
}
}
},
'portalskinbackground' => {
'test' => sub {
1;
}
}
},
'post' => {
'test' => sub {
1;
}
}
},
'RSAPrivateKey' => {
'test' => sub {
@ -160,7 +160,7 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
m[^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:RSA\s+)PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
}
}
},
'RSAPublicKey' => {
'test' => sub {
@ -168,7 +168,7 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+=
m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
}
}
},
'RSAPublicKeyOrCertificate' => {
'test' => sub {
@ -176,37 +176,37 @@ m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\
m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
}
}
},
'rule' => {
'test' => sub {
1;
}
}
},
'samlAssertion' => {
'test' => sub {
1;
}
}
},
'samlAttribute' => {
'test' => sub {
1;
}
}
},
'samlIDPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'samlService' => {
'test' => sub {
1;
}
}
},
'samlSPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'select' => {
'test' => sub {
@ -216,19 +216,19 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\
return $test
? 1
: ( 1, "Invalid value '$_[0]' for this select" );
}
}
},
'subContainer' => {
'keyTest' => qr/\w/,
'test' => sub {
1;
}
}
},
'text' => {
'msgFail' => '__malformedValue__',
'test' => sub {
1;
}
}
},
'trool' => {
'msgFail' => '__authorizedValues__: -1, 0, 1',
@ -1036,7 +1036,7 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
split( /\n/, $@, 0 ) )
);
return $err ? ( 1, "__badExpression__: $err" ) : 1;
}
}
},
'type' => 'keyTextContainer'
},
@ -1208,7 +1208,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
and defined $conf->{$_}{$val};
}
return 1, "__unknownAttrOrMacro__: $val";
}
}
},
'type' => 'doubleHash'
},
@ -1490,7 +1490,7 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
split( /\n/, $@, 0 ) )
);
return $err ? ( 1, "__badExpression__: $err" ) : 1;
}
}
},
'type' => 'ruleContainer'
},
@ -2959,19 +2959,19 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'default' => 0,
'select' => [
{
'k' => '0',
'k' => 0,
'v' => 'unsecuredCookie'
},
{
'k' => '1',
'k' => 1,
'v' => 'securedCookie'
},
{
'k' => '2',
'k' => 2,
'v' => 'doubleCookie'
},
{
'k' => '3',
'k' => 3,
'v' => 'doubleCookieForSingleSession'
}
],

File diff suppressed because one or more lines are too long

@ -54,6 +54,37 @@ sub run {
$self->userLogger->warn("U2F Registration failed: $err");
return $self->p->sendError( $req, $err, 200 );
}
if ( $action eq 'unregister' ) {
my $challenge = $self->crypter->registrationChallenge;
return [ 200, [ 'Content-Type' => 'application/json' ], [$challenge] ];
}
if ( $action eq 'unregistration' ) {
my $resp;
unless ( $resp = $req->param('registration') ) {
return $self->p->sendError( $req, 'Missing unregistration parameter',
400 );
}
$self->logger->debug("Get unregistration data $resp");
my ( $keyHandle, $userKey ) = $self->crypter->registrationVerify($resp);
if ( $keyHandle and $userKey ) {
$self->p->updatePersistentSession(
$req,
{
_u2fKeyHandle => '',
_u2fUserKey => ''
}
);
return [
200, [ 'Content-Type' => 'application/json' ],
['{"result":1}']
];
}
my $err = Crypt::U2F::Server::Simple::lastError();
$self->userLogger->warn("U2F Unregistration failed: $err");
return $self->p->sendError( $req, $err, 200 );
}
if ( $action eq 'verify' ) {
my ( $err, $error ) = $self->loadUser($req);
if ( $err == -1 ) {

@ -54,6 +54,43 @@ register = ->
setMsg 'u2fRegistered', 'positive'
error: displayError
# Registration function (launched by "register" button)
unregister = ->
# 1 get registration token
$.ajax
type: "POST",
url: "#{portal}u2fregister/unregister"
data: {}
dataType: 'json'
error: displayError
success: (ch) ->
# 2 build response
request = [
challenge: ch.challenge
version: ch.version
]
setMsg 'touchU2fDevice', 'positive'
$('#u2fPermission').show()
u2f.register ch.appId, request, [], (data) ->
$('#u2fPermission').hide()
# Handle errors
if data.errorCode
setMsg 'unableToGetU2FKey', 'warning'
else
# 3 send response
$.ajax
type: "POST"
url: "#{portal}u2fregister/unregistration"
data:
registration: JSON.stringify data
dataType: 'json'
success: (resp) ->
if resp.error
setMsg 'u2fFailed', 'warning'
else if resp.result
setMsg 'u2fUnregistered', 'positive'
error: displayError
# Verification function (launched by "verify" button)
verify = ->
# 1 get challenge
@ -94,5 +131,6 @@ verify = ->
$(document).ready ->
$('#u2fPermission').hide()
$('#register').on 'click', register
$('#unregister').on 'click', unregister
$('#verify').on 'click', verify
$('#goback').attr 'href', portal

@ -5,7 +5,7 @@ LemonLDAP::NG U2F registration script
*/
(function() {
var displayError, register, setMsg, verify;
var displayError, register, setMsg, verify, unregister;
setMsg = function(msg, level) {
$('#msg').html(window.translate(msg));
@ -72,6 +72,50 @@ LemonLDAP::NG U2F registration script
});
};
unregister = function() {
return $.ajax({
type: "POST",
url: portal + "u2fregister/unregister",
data: {},
dataType: 'json',
error: displayError,
success: function(ch) {
var request;
request = [
{
challenge: ch.challenge,
version: ch.version
}
];
setMsg('touchU2fDevice', 'positive');
$('#u2fPermission').show();
return u2f.register(ch.appId, request, [], function(data) {
$('#u2fPermission').hide();
if (data.errorCode) {
return setMsg('unableToGetU2FKey', 'warning');
} else {
return $.ajax({
type: "POST",
url: portal + "u2fregister/unregistration",
data: {
registration: JSON.stringify(data)
},
dataType: 'json',
success: function(resp) {
if (resp.error) {
return setMsg('u2fFailed', 'warning');
} else if (resp.result) {
return setMsg('u2fUnregistered', 'positive');
}
},
error: displayError
});
}
});
}
});
};
verify = function() {
return $.ajax({
type: "POST",
@ -120,6 +164,7 @@ LemonLDAP::NG U2F registration script
$('#u2fPermission').hide();
$('#register').on('click', register);
$('#verify').on('click', verify);
$('#unregister').on('click', unregister);
return $('#goback').attr('href', portal);
});

@ -1 +1 @@
(function(){var a,b,c,d;c=function(e,f){$("#msg").html(window.translate(e));$("#color").removeClass("message-positive message-warning alert-success alert-warning");$("#color").addClass("message-"+f);if(f==="positive"){f="success"}return $("#color").addClass("alert-"+f)};a=function(f,e,h){var g;console.log("Error",h);g=JSON.parse(f.responseText);if(g&&g.error){g=g.error.replace(/.* /,"");console.log("Returned error",g);return c(g,"warning")}};b=function(){return $.ajax({type:"POST",url:portal+"u2fregister/register",data:{},dataType:"json",error:a,success:function(e){var f;f=[{challenge:e.challenge,version:e.version}];c("touchU2fDevice","positive");$("#u2fPermission").show();return u2f.register(e.appId,f,[],function(g){$("#u2fPermission").hide();if(g.errorCode){return c("unableToGetU2FKey","warning")}else{return $.ajax({type:"POST",url:portal+"u2fregister/registration",data:{registration:JSON.stringify(g)},dataType:"json",success:function(h){if(h.error){return c("u2fFailed","warning")}else{if(h.result){return c("u2fRegistered","positive")}}},error:a})}})}})};d=function(){return $.ajax({type:"POST",url:portal+"u2fregister/verify",data:{},dataType:"json",error:a,success:function(e){var f;f=[{keyHandle:e.keyHandle,version:e.version}];c("touchU2fDevice","positive");return u2f.sign(e.appId,e.challenge,f,function(g){if(g.errorCode){return c("unableToGetU2FKey","warning")}else{return $.ajax({type:"POST",url:portal+"u2fregister/signature",data:{signature:JSON.stringify(g)},dataType:"json",success:function(h){if(h.error){return c("u2fFailed","warning")}else{if(h.result){return c("u2fSuccess","positive")}}},error:function(i,h,k){return console.log("error",k)}})}})}})};$(document).ready(function(){$("#u2fPermission").hide();$("#register").on("click",b);$("#verify").on("click",d);return $("#goback").attr("href",portal)})}).call(this);
(function(){var a,c,d,e,b;d=function(f,g){$("#msg").html(window.translate(f));$("#color").removeClass("message-positive message-warning alert-success alert-warning");$("#color").addClass("message-"+g);if(g==="positive"){g="success"}return $("#color").addClass("alert-"+g)};a=function(g,f,i){var h;console.log("Error",i);h=JSON.parse(g.responseText);if(h&&h.error){h=h.error.replace(/.* /,"");console.log("Returned error",h);return d(h,"warning")}};c=function(){return $.ajax({type:"POST",url:portal+"u2fregister/register",data:{},dataType:"json",error:a,success:function(f){var g;g=[{challenge:f.challenge,version:f.version}];d("touchU2fDevice","positive");$("#u2fPermission").show();return u2f.register(f.appId,g,[],function(h){$("#u2fPermission").hide();if(h.errorCode){return d("unableToGetU2FKey","warning")}else{return $.ajax({type:"POST",url:portal+"u2fregister/registration",data:{registration:JSON.stringify(h)},dataType:"json",success:function(i){if(i.error){return d("u2fFailed","warning")}else{if(i.result){return d("u2fRegistered","positive")}}},error:a})}})}})};b=function(){return $.ajax({type:"POST",url:portal+"u2fregister/unregister",data:{},dataType:"json",error:a,success:function(f){var g;g=[{challenge:f.challenge,version:f.version}];d("touchU2fDevice","positive");$("#u2fPermission").show();return u2f.register(f.appId,g,[],function(h){$("#u2fPermission").hide();if(h.errorCode){return d("unableToGetU2FKey","warning")}else{return $.ajax({type:"POST",url:portal+"u2fregister/unregistration",data:{registration:JSON.stringify(h)},dataType:"json",success:function(i){if(i.error){return d("u2fFailed","warning")}else{if(i.result){return d("u2fUnregistered","positive")}}},error:a})}})}})};e=function(){return $.ajax({type:"POST",url:portal+"u2fregister/verify",data:{},dataType:"json",error:a,success:function(f){var g;g=[{keyHandle:f.keyHandle,version:f.version}];d("touchU2fDevice","positive");return u2f.sign(f.appId,f.challenge,g,function(h){if(h.errorCode){return d("unableToGetU2FKey","warning")}else{return $.ajax({type:"POST",url:portal+"u2fregister/signature",data:{signature:JSON.stringify(h)},dataType:"json",success:function(i){if(i.error){return d("u2fFailed","warning")}else{if(i.result){return d("u2fSuccess","positive")}}},error:function(k,i,l){return console.log("error",l)}})}})}})};$(document).ready(function(){$("#u2fPermission").hide();$("#register").on("click",c);$("#verify").on("click",e);$("#unregister").on("click",b);return $("#goback").attr("href",portal)})}).call(this);

@ -176,7 +176,8 @@
"redirectionToIdp":"إعادة توجيهك إلى موفر الهوية الخاص بك",
"refreshrights": "قم بتحديث حقوقي",
"refuse":"رفض",
"register": "Register",
"register": "تسجيل",
"unregister": "إلغاء",
"registerRequestAlreadyIssued":"تم إصدار طلب تسجيل لهذا الحساب من قبل",
"rememberChoice":"تذكر اختياري",
"removeOtherSessions":"إزالة الجلسات الأخرى",
@ -197,6 +198,7 @@
"u2fFailed": "فشل التحقق من U2F. أعد محاولة الاتصال بالمشرف أو اتصل به",
"u2fPermission": "قد تتم مطالبتك بالسماح للموقع إذن الوصول إلى مفاتيح الأمان الخاصة بك.بعد منح الإذن، سيبدأ الجهاز في العملية.",
"u2fRegistered": "المفتاح الخاص بك تم تسجيله",
"u2fUnregistered": "تمت إزالة المفتاح",
"u2fSuccess": "تم اختبار المفتاح الخاص بك بنجاح",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "تعذر الوصول إلى المفتاح. أعد محاولة الاتصال بالمشرف أو اتصل به",

@ -176,7 +176,8 @@
"redirectionToIdp":"Redirection to your Identity Provider",
"refreshrights": "Refresh my rights",
"refuse":"Refuse",
"register": "Register",
"register": "Registrieren",
"unregister": "Abmelden",
"registerRequestAlreadyIssued":"A register request for this account was already issued on ",
"rememberChoice":"Remember my choice",
"removeOtherSessions":"Remove other sessions",
@ -197,6 +198,7 @@
"u2fFailed": "U2F verification failed. Retry or contact your administrator",
"u2fPermission": "You may be prompted to allow the site permission to access your security keys. After granting permission, the device will start to blink.",
"u2fRegistered": "Your key is registered",
"u2fUnregistered": "Your key has been registered",
"u2fSuccess": "Your key is successfully tested",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Unable to access to your key. Retry or contact your administrator",

@ -177,6 +177,7 @@
"refreshrights": "Refresh my rights",
"refuse":"Refuse",
"register": "Register",
"unregister": "Unregister",
"registerRequestAlreadyIssued":"A register request for this account was already issued on ",
"rememberChoice":"Remember my choice",
"removeOtherSessions":"Remove other sessions",
@ -196,7 +197,8 @@
"touchU2fDevice": "Please touch the flashing U2F device now.",
"u2fFailed": "U2F verification failed. Retry or contact your administrator",
"u2fPermission": "You may be prompted to allow the site permission to access your security keys. After granting permission, the device will start to blink.",
"u2fRegistered": "Your key is registered",
"u2fRegistered": "Your key is registered. Click to verify.",
"u2fUnregistered": "Your key has been unregistered.",
"u2fSuccess": "Your key is successfully tested",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Unable to access to your key. Retry or contact your administrator",

@ -176,7 +176,8 @@
"redirectionToIdp":"Redirection to your Identity Provider",
"refreshrights": "Refresh my rights",
"refuse":"Refuse",
"register": "Register",
"register": "Registro",
"unregister": "No Registrado",
"registerRequestAlreadyIssued":"A register request for this account was already issued on ",
"rememberChoice":"Remember my choice",
"removeOtherSessions":"Remove other sessions",
@ -197,6 +198,7 @@
"u2fFailed": "U2F verification failed. Retry or contact your administrator",
"u2fPermission": "You may be prompted to allow the site permission to access your security keys. After granting permission, the device will start to blink.",
"u2fRegistered": "Your key is registered",
"u2fUnregistered": "Your key is unregistered",
"u2fSuccess": "Your key is successfully tested",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Unable to access to your key. Retry or contact your administrator",

@ -177,6 +177,7 @@
"refreshrights": "Rafraîchir mes droits",
"refuse":"Refuser",
"register": "Enregistrer",
"unregister": "Supprimer",
"registerRequestAlreadyIssued":"Une demande de création pour ce compte a déjà été faite le ",
"rememberChoice":"Se souvenir de mon choix",
"removeOtherSessions":"Fermer les autres sessions",
@ -197,6 +198,7 @@
"u2fFailed": "La vérification U2F a échoué, réessayez ou contactez votre administrateur",
"u2fPermission": "Il est possible qu'on vous demande d'autoriser le site à accéder à votre clef. Après votre accord, la clef clignotera.",
"u2fRegistered": "Votre clef est enregistrée. Cliquez sur vérifier",
"u2fUnregistered": "Votre clef a été supprimée.",
"u2fSuccess": "Votre clef est vérifiée",
"u2fWelcome": "Gestion du périphérique U2F",
"unableToGetU2FKey": "Impossible d'accéder à la clef, réessayez ou contactez votre administrateur",

@ -177,6 +177,7 @@
"refreshrights": "Aggiorna i miei diritti",
"refuse":"Rifiuta",
"register": "Registra",
"unregister": "Non Registra",
"registerRequestAlreadyIssued":"Una richiesta di registrazione per questo conto é già stata rilasciata il",
"rememberChoice":"Ricordarsi della mia scelta",
"removeOtherSessions":"Rimuovere altre sessioni",
@ -197,6 +198,7 @@
"u2fFailed": "Verifica U2F non riuscita. Riprovare o contattare l'amministratore",
"u2fPermission": "È possibile che venga richiesto di consentire il permesso del sito per accedere alle chiavi di sicurezza. Dopo aver concesso il permesso, il dispositivo inizierà a lampeggiare.",
"u2fRegistered": "La vostra chiave è registrata",
"u2fUnregistered": "La vostra chiave è stata rimossa",
"u2fSuccess": "La tua chiave é stata testata con successo",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Impossibile accedere alla chiave. Riprovare o contattare l'amministratore",

@ -176,7 +176,8 @@
"redirectionToIdp":"Redirection to your Identity Provider",
"refreshrights": "Refresh my rights",
"refuse":"Refuse",
"register": "Register",
"register": "Registeren",
"unregister": "Uitschrijven",
"registerRequestAlreadyIssued":"A register request for this account was already issued on ",
"rememberChoice":"Remember my choice",
"removeOtherSessions":"Remove other sessions",
@ -197,6 +198,7 @@
"u2fFailed": "U2F verification failed. Retry or contact your administrator",
"u2fPermission": "You may be prompted to allow the site permission to access your security keys. After granting permission, the device will start to blink.",
"u2fRegistered": "Your key is registered",
"u2fUnregistered": "Your key has been unregistered",
"u2fSuccess": "Your key is successfully tested",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Unable to access to your key. Retry or contact your administrator",

@ -176,7 +176,8 @@
"redirectionToIdp":"Redirection to your Identity Provider",
"refreshrights": "Refresh my rights",
"refuse":"Refuse",
"register": "Register",
"register": "Registo",
"unregister": "Cancelar o Registro",
"registerRequestAlreadyIssued":"A register request for this account was already issued on ",
"rememberChoice":"Remember my choice",
"removeOtherSessions":"Remove other sessions",
@ -197,6 +198,7 @@
"u2fFailed": "U2F verification failed. Retry or contact your administrator",
"u2fPermission": "You may be prompted to allow the site permission to access your security keys. After granting permission, the device will start to blink.",
"u2fRegistered": "Your key is registered",
"u2fUnregistered": "Your key has been unregistered",
"u2fSuccess": "Your key is successfully tested",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Unable to access to your key. Retry or contact your administrator",

@ -177,6 +177,7 @@
"refreshrights": "Refresh my rights",
"refuse":"Refuse",
"register": "Register",
"unregister": "Unregister",
"registerRequestAlreadyIssued":"A register request for this account was already issued on ",
"rememberChoice":"Remember my choice",
"removeOtherSessions":"Remove other sessions",
@ -197,6 +198,7 @@
"u2fFailed": "U2F verification failed. Retry or contact your administrator",
"u2fPermission": "You may be prompted to allow the site permission to access your security keys. After granting permission, the device will start to blink.",
"u2fRegistered": "Your key is registered",
"u2fUnregistered": "Your key has been unregistered",
"u2fSuccess": "Your key is successfully tested",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Unable to access to your key. Retry or contact your administrator",

@ -177,6 +177,7 @@
"refreshrights": "Làm mới lại quyền của tôi",
"refuse":"Từ chối",
"register": "Đăng ký",
"unregister": "Hủy đăng ký",
"registerRequestAlreadyIssued":"Yêu cầu đăng ký cho tài khoản này đã được cấp phát",
"rememberChoice":"Hãy nhớ sự lựa chọn của tôi",
"removeOtherSessions":"Xóa các phiên khác",
@ -197,6 +198,7 @@
"u2fFailed": "Xác minh U2F không thành công. Thử lại hoặc liên hệ với quản trị viên của bạn ",
"u2fPermission": "Bạn có thể được nhắc cho phép trang web được phép truy cập vào các khóa bảo mật của bạn. Sau khi cho phép, thiết bị sẽ bắt đầu nhấp nháy. ",
"u2fRegistered": "Khóa của bạn đã được đăng ký",
"u2fUnregistered": "Khóa của bạn đã bị xóa",
"u2fSuccess": "Chìa khóa của bạn đã được kiểm tra thành công",
"u2fWelcome": "U2F device management",
"unableToGetU2FKey": "Không thể truy cập khóa của bạn. Thử lại hoặc liên hệ với quản trị viên của bạn ",

@ -18,6 +18,10 @@
<span class="glyphicon glyphicon-check"></span>&nbsp;
<span trspan="verify">Verify</span>
</span>
<span id="unregister" class="btn btn-danger" role="button">
<span class="glyphicon glyphicon-minus-sign"></span>&nbsp;
<span trspan="unregister">Unregister</span>
</span>
</div>
</div>
</div>

Loading…
Cancel
Save