Webauthn frontend code (#1411)
This commit is contained in:
parent
1054af21e4
commit
596e2f1f3d
|
@ -27,9 +27,11 @@ delete2F = (device, epoch) ->
|
|||
device = 'u'
|
||||
else if device == 'UBK'
|
||||
device = 'yubikey'
|
||||
else if device == 'TOTP'
|
||||
device = 'totp'
|
||||
else setMsg 'u2fFailed', 'warning'
|
||||
else if device == 'TOTP'
|
||||
device = 'totp'
|
||||
else if device == 'WebAuthn'
|
||||
device = 'webauthn'
|
||||
else setMsg 'u2fFailed', 'warning'
|
||||
$.ajax
|
||||
type: "POST"
|
||||
url: "#{portal}2fregisters/#{device}/delete"
|
||||
|
|
30
lemonldap-ng-portal/site/coffee/webauthncheck.coffee
Normal file
30
lemonldap-ng-portal/site/coffee/webauthncheck.coffee
Normal file
|
@ -0,0 +1,30 @@
|
|||
###
|
||||
LemonLDAP::NG WebAuthn verify 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}"
|
||||
level = 'success' if level == 'positive'
|
||||
$('#color').addClass "alert-#{level}"
|
||||
|
||||
webAuthnError = (error) ->
|
||||
switch (error.name)
|
||||
when 'unsupported' then setMsg 'webAuthnUnsupported', 'warning'
|
||||
else setMsg 'webAuthnBrowserFailed', 'danger'
|
||||
|
||||
check = ->
|
||||
setMsg 'webAuthnBrowserInProgress', 'warning'
|
||||
request = window.datas.request
|
||||
WebAuthnUI.WebAuthnUI.getCredential request
|
||||
. then (response) ->
|
||||
$('#credential').val JSON.stringify response
|
||||
$('#verify-form').submit()
|
||||
. catch (error) ->
|
||||
webAuthnError(error)
|
||||
|
||||
$(document).ready ->
|
||||
setTimeout check, 1000
|
||||
$('#retrybutton').on 'click', check
|
97
lemonldap-ng-portal/site/coffee/webauthnregistration.coffee
Normal file
97
lemonldap-ng-portal/site/coffee/webauthnregistration.coffee
Normal file
|
@ -0,0 +1,97 @@
|
|||
###
|
||||
LemonLDAP::NG WebAuthn 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}"
|
||||
level = 'success' if level == 'positive'
|
||||
$('#color').addClass "alert-#{level}"
|
||||
|
||||
displayError = (j, status, err) ->
|
||||
console.log 'Error', err
|
||||
res = JSON.parse j.responseText
|
||||
if res and res.error
|
||||
res = res.error.replace(/.* /, '')
|
||||
console.log 'Returned error', res
|
||||
setMsg res, 'danger'
|
||||
|
||||
webAuthnError = (error) ->
|
||||
switch (error.name)
|
||||
when 'unsupported' then setMsg 'webAuthnUnsupported', 'warning'
|
||||
else setMsg 'webAuthnBrowserFailed', 'danger'
|
||||
|
||||
# Registration function (launched by "register" button)
|
||||
register = ->
|
||||
# 1 get registration token
|
||||
$.ajax
|
||||
type: "POST",
|
||||
url: "#{portal}2fregisters/webauthn/registrationchallenge"
|
||||
data: {}
|
||||
dataType: 'json'
|
||||
error: displayError
|
||||
success: (ch) ->
|
||||
# 2 build response
|
||||
request = ch.request
|
||||
setMsg 'webAuthnRegisterInProgress', 'warning'
|
||||
$('#u2fPermission').show()
|
||||
WebAuthnUI.WebAuthnUI.createCredential request
|
||||
. then (response) ->
|
||||
$.ajax
|
||||
type: "POST"
|
||||
url: "#{portal}2fregisters/webauthn/registration"
|
||||
data:
|
||||
state_id: ch.state_id
|
||||
credential: JSON.stringify response
|
||||
keyName: $('#keyName').val()
|
||||
dataType: 'json'
|
||||
success: (resp) ->
|
||||
if resp.error
|
||||
if resp.error.match /badName/
|
||||
setMsg resp.error, 'danger'
|
||||
else setMsg 'webAuthnRegisterFailed', 'danger'
|
||||
else if resp.result
|
||||
setMsg 'yourKeyIsRegistered', 'positive'
|
||||
error: displayError
|
||||
. catch (error) ->
|
||||
webAuthnError(error)
|
||||
|
||||
# Verification function (launched by "verify" button)
|
||||
verify = ->
|
||||
# 1 get challenge
|
||||
$.ajax
|
||||
type: "POST",
|
||||
url: "#{portal}2fregisters/webauthn/verificationchallenge"
|
||||
data: {}
|
||||
dataType: 'json'
|
||||
error: displayError
|
||||
success: (ch) ->
|
||||
# 2 build response
|
||||
request = ch.request
|
||||
setMsg 'webAuthnBrowserInProgress', 'warning'
|
||||
WebAuthnUI.WebAuthnUI.getCredential request
|
||||
. then (response) ->
|
||||
$.ajax
|
||||
type: "POST"
|
||||
url: "#{portal}2fregisters/webauthn/verification"
|
||||
data:
|
||||
state_id: ch.state_id
|
||||
credential: JSON.stringify response
|
||||
dataType: 'json'
|
||||
success: (resp) ->
|
||||
if resp.error
|
||||
setMsg 'webAuthnFailed', 'danger'
|
||||
else if resp.result
|
||||
setMsg 'yourKeyIsVerified', 'positive'
|
||||
error: displayError
|
||||
. catch (error) ->
|
||||
webAuthnError(error)
|
||||
|
||||
# Register "click" events
|
||||
$(document).ready ->
|
||||
$('#u2fPermission').hide()
|
||||
$('#register').on 'click', register
|
||||
$('#verify').on 'click', verify
|
||||
$('#goback').attr 'href', portal
|
BIN
lemonldap-ng-portal/site/htdocs/static/bootstrap/webauthn.png
Normal file
BIN
lemonldap-ng-portal/site/htdocs/static/bootstrap/webauthn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -40,6 +40,8 @@ LemonLDAP::NG 2F registration script
|
|||
device = 'yubikey';
|
||||
} else if (device === 'TOTP') {
|
||||
device = 'totp';
|
||||
} else if (device === 'WebAuthn') {
|
||||
device = 'webauthn';
|
||||
} else {
|
||||
setMsg('u2fFailed', 'warning');
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var e,t,n;n=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){var o;if(console.log("Error",t),(o=JSON.parse(e.responseText))&&o.error)return o=o.error.replace(/.* /,""),console.log("Returned error",o),o.match(/module/)?n("notAuthorized","warning"):n(o,"warning")},e=function(e,r){return"U2F"===e?e="u":"UBK"===e?e="yubikey":"TOTP"===e?e="totp":n("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/)?n("notAuthorized","warning"):n("unknownAction","warning"):e.result?($("#delete-"+r).hide(),n("yourKeyIsUnregistered","positive")):void 0},error:t})},$(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;return e=new Date(1e3*$(this).text()),$(this).text(e.toLocaleString())})})}).call(this);
|
||||
!function(){var n=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/)?n("notAuthorized","warning"):n(e,"warning")},e=function(e,r){return"U2F"===e?e="u":"UBK"===e?e="yubikey":"TOTP"===e?e="totp":"WebAuthn"===e?e="webauthn":n("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/)?n("notAuthorized","warning"):n("unknownAction","warning"):e.result?($("#delete-"+r).hide(),n("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":["delete2F","displayError","setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","match","device","epoch","ajax","type","url","portal","data","dataType","success","resp","result","hide","document","ready","on","this","each","myDate","Date","text","toLocaleString","call"],"mappings":"CAMA,WACE,IAAIA,EAAUC,EAAcC,EAE5BA,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,IAGzCH,EAAe,SAASW,EAAGC,EAAQC,GACjC,IAAIC,EAGJ,GAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,OAFAN,EAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GAC1BA,EAAIQ,MAAM,UACLrB,EAAO,gBAAiB,WAExBA,EAAOa,EAAK,YAKzBf,EAAW,SAASwB,EAAQC,GAU1B,MATe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OAETtB,EAAO,YAAa,WAEfG,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,eAAiBL,EAAS,UACxCM,KAAM,CACJL,MAAOA,GAETM,SAAU,OACVV,MAAOpB,EACP+B,QAAS,SAASC,GAChB,OAAIA,EAAKZ,MACHY,EAAKZ,MAAME,MAAM,iBACZrB,EAAO,gBAAiB,WAExBA,EAAO,gBAAiB,WAExB+B,EAAKC,QACd7B,EAAE,WAAaoB,GAAOU,OACfjC,EAAO,wBAAyB,kBAFlC,GAKTmB,MAAOpB,KAIXI,EAAE+B,UAAUC,MAAM,WAKhB,OAJAhC,EAAE,QAAQiC,GAAG,QAAS,YAAa,WACjC,OAAOtC,EAASK,EAAEkC,MAAMjC,KAAK,UAAWD,EAAEkC,MAAMjC,KAAK,YAEvDD,EAAE,WAAWC,KAAK,OAAQuB,QACnBxB,EAAE,eAAemC,KAAK,WAC3B,IAAIC,EAEJ,OADAA,EAAS,IAAIC,KAAsB,IAAjBrC,EAAEkC,MAAMI,QACnBtC,EAAEkC,MAAMI,KAAKF,EAAOG,wBAI9BC,KAAKN"}
|
||||
{"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,GAY1B,MAXe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OACW,aAAXA,EACTA,EAAS,WAETxB,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"}
|
561
lemonldap-ng-portal/site/htdocs/static/common/js/webauthn-ui.js
Normal file
561
lemonldap-ng-portal/site/htdocs/static/common/js/webauthn-ui.js
Normal file
|
@ -0,0 +1,561 @@
|
|||
/*! webauthn-ui library (C) 2018 - 2020 Thomas Bleeker (www.madwizard.org) - MIT license */
|
||||
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.WebAuthnUI = {}));
|
||||
}(this, (function (exports) { 'use strict';
|
||||
|
||||
/* Microsoft tslib 0BSD licensed */
|
||||
/* global Reflect, Promise */
|
||||
|
||||
var extendStatics = function(d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
|
||||
function __extends(d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
}
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
function __generator(thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
}
|
||||
|
||||
function waitReadyState(alreadyDone, eventDispatcher, eventName) {
|
||||
if (alreadyDone) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return new Promise(function (resolve) {
|
||||
var readyFunc = function () {
|
||||
eventDispatcher.removeEventListener(eventName, readyFunc);
|
||||
resolve();
|
||||
};
|
||||
eventDispatcher.addEventListener(eventName, readyFunc);
|
||||
});
|
||||
}
|
||||
function ready() {
|
||||
return waitReadyState(document.readyState !== 'loading', document, 'DOMContentLoaded');
|
||||
}
|
||||
function loaded() {
|
||||
return waitReadyState(document.readyState === 'complete', window, 'load');
|
||||
}
|
||||
|
||||
var WebAuthnError = /** @class */ (function (_super) {
|
||||
__extends(WebAuthnError, _super);
|
||||
function WebAuthnError(name, message, innerError) {
|
||||
var _newTarget = this.constructor;
|
||||
var _this = _super.call(this, "WebAuthnUI error: " + (message !== undefined ? message : name)) || this;
|
||||
Object.setPrototypeOf(_this, _newTarget.prototype); // restore prototype chain
|
||||
_this.name = name;
|
||||
_this.innerError = innerError;
|
||||
return _this;
|
||||
}
|
||||
WebAuthnError.fromError = function (error) {
|
||||
var type = 'unknown';
|
||||
var message;
|
||||
if (error instanceof DOMException) {
|
||||
var map = {
|
||||
NotAllowedError: 'dom-not-allowed',
|
||||
SecurityError: 'dom-security',
|
||||
NotSupportedError: 'dom-not-supported',
|
||||
AbortError: 'dom-abort',
|
||||
InvalidStateError: 'dom-invalid-state',
|
||||
};
|
||||
type = map[error.name] || 'dom-unknown';
|
||||
message = type;
|
||||
}
|
||||
else {
|
||||
message = "unknown (" + error.toString() + ")";
|
||||
}
|
||||
return new WebAuthnError(type, message, error instanceof Error ? error : undefined);
|
||||
};
|
||||
return WebAuthnError;
|
||||
}(Error));
|
||||
|
||||
function encode(arraybuffer) {
|
||||
var buffer = new Uint8Array(arraybuffer);
|
||||
var binary = '';
|
||||
for (var i_1 = 0; i_1 < buffer.length; i_1++) {
|
||||
binary += String.fromCharCode(buffer[i_1]);
|
||||
}
|
||||
var encoded = window.btoa(binary);
|
||||
var i = encoded.length - 1;
|
||||
while (i > 0 && encoded[i] === '=') {
|
||||
i--;
|
||||
}
|
||||
encoded = encoded.substr(0, i + 1);
|
||||
encoded = encoded.replace(/\+/g, '-').replace(/\//g, '_');
|
||||
return encoded;
|
||||
}
|
||||
function decode(base64) {
|
||||
var converted = base64.replace(/-/g, '+').replace(/_/g, '/');
|
||||
switch (converted.length % 4) {
|
||||
case 2:
|
||||
converted += '==';
|
||||
break;
|
||||
case 3:
|
||||
converted += '=';
|
||||
break;
|
||||
case 1:
|
||||
throw new WebAuthnError('parse-error');
|
||||
}
|
||||
var bin = window.atob(converted);
|
||||
var buffer = new Uint8Array(bin.length);
|
||||
for (var i = 0; i < bin.length; i++) {
|
||||
buffer[i] = bin.charCodeAt(i);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function map(src, mapper) {
|
||||
var dest = {};
|
||||
var keys = Object.keys(mapper);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var k = keys[i];
|
||||
var action = mapper[k];
|
||||
var val = src[k];
|
||||
if (val !== undefined) {
|
||||
if (action === 0 /* Copy */) {
|
||||
dest[k] = val;
|
||||
}
|
||||
else if (action === 1 /* Base64Decode */) {
|
||||
dest[k] = val === null ? null : decode(val);
|
||||
}
|
||||
else if (action === 2 /* Base64Encode */) {
|
||||
dest[k] = val === null ? null : encode(val);
|
||||
}
|
||||
else if (typeof action === 'object') {
|
||||
dest[k] = map(val, action);
|
||||
}
|
||||
else {
|
||||
dest[k] = action(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
function arrayMap(mapper) {
|
||||
return function (src) {
|
||||
var dest = [];
|
||||
for (var i = 0; i < src.length; i++) {
|
||||
dest[i] = map(src[i], mapper);
|
||||
}
|
||||
return dest;
|
||||
};
|
||||
}
|
||||
function getCredentialDescListMap() {
|
||||
return arrayMap({
|
||||
type: 0 /* Copy */,
|
||||
id: 1 /* Base64Decode */,
|
||||
transports: 0 /* Copy */,
|
||||
});
|
||||
}
|
||||
function addExtensionOutputs(dest, pkc) {
|
||||
var clientExtensionResults = pkc.getClientExtensionResults();
|
||||
if (Object.keys(clientExtensionResults).length > 0) {
|
||||
dest.clientExtensionResults = map(clientExtensionResults, {
|
||||
appid: 0 /* Copy */,
|
||||
});
|
||||
}
|
||||
}
|
||||
var Converter = /** @class */ (function () {
|
||||
function Converter() {
|
||||
}
|
||||
Converter.convertCreationOptions = function (options) {
|
||||
return map(options, {
|
||||
rp: 0 /* Copy */,
|
||||
user: {
|
||||
id: 1 /* Base64Decode */,
|
||||
name: 0 /* Copy */,
|
||||
displayName: 0 /* Copy */,
|
||||
icon: 0 /* Copy */,
|
||||
},
|
||||
challenge: 1 /* Base64Decode */,
|
||||
pubKeyCredParams: 0 /* Copy */,
|
||||
timeout: 0 /* Copy */,
|
||||
excludeCredentials: getCredentialDescListMap(),
|
||||
authenticatorSelection: 0 /* Copy */,
|
||||
attestation: 0 /* Copy */,
|
||||
extensions: {
|
||||
appid: 0 /* Copy */,
|
||||
},
|
||||
});
|
||||
};
|
||||
Converter.convertCreationResponse = function (pkc) {
|
||||
var response = map(pkc, {
|
||||
type: 0 /* Copy */,
|
||||
id: 0 /* Copy */,
|
||||
rawId: 2 /* Base64Encode */,
|
||||
response: {
|
||||
clientDataJSON: 2 /* Base64Encode */,
|
||||
attestationObject: 2 /* Base64Encode */,
|
||||
},
|
||||
});
|
||||
addExtensionOutputs(response, pkc);
|
||||
return response;
|
||||
};
|
||||
Converter.convertRequestOptions = function (options) {
|
||||
return map(options, {
|
||||
challenge: 1 /* Base64Decode */,
|
||||
timeout: 0 /* Copy */,
|
||||
rpId: 0 /* Copy */,
|
||||
allowCredentials: getCredentialDescListMap(),
|
||||
userVerification: 0 /* Copy */,
|
||||
extensions: {
|
||||
appid: 0 /* Copy */,
|
||||
},
|
||||
});
|
||||
};
|
||||
Converter.convertRequestResponse = function (pkc) {
|
||||
var response = map(pkc, {
|
||||
type: 0 /* Copy */,
|
||||
id: 0 /* Copy */,
|
||||
rawId: 2 /* Base64Encode */,
|
||||
response: {
|
||||
clientDataJSON: 2 /* Base64Encode */,
|
||||
authenticatorData: 2 /* Base64Encode */,
|
||||
signature: 2 /* Base64Encode */,
|
||||
userHandle: 2 /* Base64Encode */,
|
||||
},
|
||||
});
|
||||
addExtensionOutputs(response, pkc);
|
||||
return response;
|
||||
};
|
||||
return Converter;
|
||||
}());
|
||||
|
||||
var loadEvents = { loaded: loaded, ready: ready };
|
||||
function elementSelector(selector) {
|
||||
var items;
|
||||
if (typeof selector === 'string') {
|
||||
items = document.querySelectorAll(selector);
|
||||
}
|
||||
else {
|
||||
items = [selector];
|
||||
}
|
||||
return items;
|
||||
}
|
||||
var WebAuthnUI = /** @class */ (function () {
|
||||
function WebAuthnUI() {
|
||||
}
|
||||
WebAuthnUI.isSupported = function () {
|
||||
return typeof window.PublicKeyCredential !== 'undefined';
|
||||
};
|
||||
WebAuthnUI.isUVPASupported = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
if (this.isSupported()) {
|
||||
return [2 /*return*/, window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()];
|
||||
}
|
||||
return [2 /*return*/, false];
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.checkSupport = function () {
|
||||
if (!WebAuthnUI.isSupported()) {
|
||||
throw new WebAuthnError('unsupported');
|
||||
}
|
||||
};
|
||||
WebAuthnUI.createCredential = function (options) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var request, credential, e_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
WebAuthnUI.checkSupport();
|
||||
request = {
|
||||
publicKey: Converter.convertCreationOptions(options),
|
||||
};
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, navigator.credentials.create(request)];
|
||||
case 2:
|
||||
credential = (_a.sent());
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
e_1 = _a.sent();
|
||||
throw WebAuthnError.fromError(e_1);
|
||||
case 4: return [2 /*return*/, Converter.convertCreationResponse(credential)];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.getCredential = function (options) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var request, credential, e_2;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
WebAuthnUI.checkSupport();
|
||||
request = {
|
||||
publicKey: Converter.convertRequestOptions(options),
|
||||
};
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, navigator.credentials.get(request)];
|
||||
case 2:
|
||||
credential = (_a.sent());
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
e_2 = _a.sent();
|
||||
throw WebAuthnError.fromError(e_2);
|
||||
case 4: return [2 /*return*/, Converter.convertRequestResponse(credential)];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.setFeatureCssClasses = function (selector) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var items, applyClass;
|
||||
return __generator(this, function (_a) {
|
||||
items = elementSelector(selector);
|
||||
applyClass = function (cls) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i].classList.add(cls);
|
||||
}
|
||||
};
|
||||
applyClass("webauthn-" + (WebAuthnUI.isSupported() ? '' : 'un') + "supported");
|
||||
return [2 /*return*/, WebAuthnUI.isUVPASupported().then(function (available) {
|
||||
applyClass("webauthn-uvpa-" + (available ? '' : 'un') + "supported");
|
||||
})];
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.loadConfig = function (config) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var field, el, submit, response, newField;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
// Wait for DOM ready
|
||||
return [4 /*yield*/, ready()];
|
||||
case 1:
|
||||
// Wait for DOM ready
|
||||
_a.sent();
|
||||
field = config.formField;
|
||||
if (typeof field === 'string') {
|
||||
el = document.querySelector(field);
|
||||
if (el === null) {
|
||||
throw new WebAuthnError('bad-config', 'Could not find formField.');
|
||||
}
|
||||
field = el;
|
||||
}
|
||||
if (!(field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement)) {
|
||||
throw new WebAuthnError('bad-config', 'formField does not refer to an input element.');
|
||||
}
|
||||
submit = config.submitForm !== false;
|
||||
if (!this.isSupported() && config.postUnsupportedImmediately === true) {
|
||||
response = { status: 'failed', error: 'unsupported' };
|
||||
this.setForm(field, response, submit);
|
||||
return [2 /*return*/, response];
|
||||
}
|
||||
newField = field;
|
||||
return [2 /*return*/, new Promise(function (resolve) {
|
||||
var trigger = config.trigger;
|
||||
var resolved = false;
|
||||
if (trigger.event === 'click') {
|
||||
var targets = elementSelector(config.trigger.element);
|
||||
var handler = function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.runAutoConfig(config)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
this.setForm(newField, response, submit);
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
resolve(response);
|
||||
}
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
for (var i = 0; i < targets.length; i++) {
|
||||
targets[i].addEventListener('click', handler);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new WebAuthnError('bad-config');
|
||||
}
|
||||
})];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.startConfig = function (config) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var credential;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!(config.type === 'get')) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, this.getCredential(config.request)];
|
||||
case 1:
|
||||
credential = _a.sent();
|
||||
return [3 /*break*/, 5];
|
||||
case 2:
|
||||
if (!(config.type === 'create')) return [3 /*break*/, 4];
|
||||
return [4 /*yield*/, this.createCredential(config.request)];
|
||||
case 3:
|
||||
credential = _a.sent();
|
||||
return [3 /*break*/, 5];
|
||||
case 4: throw new WebAuthnError('bad-config', "Invalid config.type " + config.type);
|
||||
case 5: return [2 /*return*/, {
|
||||
status: 'ok',
|
||||
credential: credential,
|
||||
}];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.runAutoConfig = function (config) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var response, e_3, waError;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
_a.trys.push([0, 2, , 3]);
|
||||
return [4 /*yield*/, this.startConfig(config)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
return [3 /*break*/, 3];
|
||||
case 2:
|
||||
e_3 = _a.sent();
|
||||
waError = (e_3 instanceof WebAuthnError);
|
||||
if (config.debug === true) {
|
||||
console.error(e_3); // eslint-disable-line no-console
|
||||
if (waError && e_3.innerError) {
|
||||
console.error(e_3.innerError); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
response = {
|
||||
status: 'failed',
|
||||
error: (waError ? e_3.name : WebAuthnError.fromError(e_3).name),
|
||||
};
|
||||
return [3 /*break*/, 3];
|
||||
case 3: return [2 /*return*/, response];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.setForm = function (field, response, submit) {
|
||||
field.value = JSON.stringify(response);
|
||||
if (submit && field.form) {
|
||||
field.form.submit();
|
||||
}
|
||||
};
|
||||
WebAuthnUI.autoConfig = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var promises, list, i, el, isScript, rawJson, json;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
promises = [];
|
||||
list = document.querySelectorAll('input[data-webauthn],textarea[data-webauthn],script[data-webauthn]');
|
||||
for (i = 0; i < list.length; i++) {
|
||||
el = list[i];
|
||||
isScript = el.tagName === 'SCRIPT';
|
||||
if (isScript && el.type !== 'application/json') {
|
||||
throw new WebAuthnError('bad-config', 'Expecting application/json script with data-webauthn');
|
||||
}
|
||||
rawJson = isScript ? el.textContent : (el).getAttribute('data-webauthn');
|
||||
if (rawJson === null) {
|
||||
throw new WebAuthnError('bad-config', 'Missing JSON in data-webauthn');
|
||||
}
|
||||
json = void 0;
|
||||
try {
|
||||
json = JSON.parse(rawJson);
|
||||
}
|
||||
catch (e) {
|
||||
throw new WebAuthnError('bad-config', 'invalid JSON in data-webauthn on element');
|
||||
}
|
||||
if (!isScript && json.formField === undefined) {
|
||||
json.formField = el;
|
||||
}
|
||||
promises.push(this.loadConfig(json));
|
||||
}
|
||||
return [4 /*yield*/, Promise.all(promises)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
WebAuthnUI.inProgress = false;
|
||||
return WebAuthnUI;
|
||||
}());
|
||||
function auto() {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var list, i;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, ready()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
list = document.querySelectorAll('.webauthn-detect');
|
||||
for (i = 0; i < list.length; i++) {
|
||||
WebAuthnUI.setFeatureCssClasses(list[i]);
|
||||
}
|
||||
return [2 /*return*/, WebAuthnUI.autoConfig()];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
var autoPromise = auto().catch(function (e) {
|
||||
if (console && console.error) { // eslint-disable-line no-console
|
||||
console.error(e); // eslint-disable-line no-console
|
||||
}
|
||||
});
|
||||
|
||||
exports.WebAuthnError = WebAuthnError;
|
||||
exports.WebAuthnUI = WebAuthnUI;
|
||||
exports.autoPromise = autoPromise;
|
||||
exports.loadEvents = loadEvents;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
})));
|
2
lemonldap-ng-portal/site/htdocs/static/common/js/webauthn-ui.min.js
vendored
Normal file
2
lemonldap-ng-portal/site/htdocs/static/common/js/webauthn-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,47 @@
|
|||
// Generated by CoffeeScript 1.12.8
|
||||
|
||||
/*
|
||||
LemonLDAP::NG WebAuthn verify script
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var check, setMsg, webAuthnError;
|
||||
|
||||
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);
|
||||
if (level === 'positive') {
|
||||
level = 'success';
|
||||
}
|
||||
return $('#color').addClass("alert-" + level);
|
||||
};
|
||||
|
||||
webAuthnError = function(error) {
|
||||
switch (error.name) {
|
||||
case 'unsupported':
|
||||
return setMsg('webAuthnUnsupported', 'warning');
|
||||
default:
|
||||
return setMsg('webAuthnBrowserFailed', 'danger');
|
||||
}
|
||||
};
|
||||
|
||||
check = function() {
|
||||
var request;
|
||||
setMsg('webAuthnBrowserInProgress', 'warning');
|
||||
request = window.datas.request;
|
||||
return WebAuthnUI.WebAuthnUI.getCredential(request).then(function(response) {
|
||||
$('#credential').val(JSON.stringify(response));
|
||||
return $('#verify-form').submit();
|
||||
})["catch"](function(error) {
|
||||
return webAuthnError(error);
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
setTimeout(check, 1000);
|
||||
return $('#retrybutton').on('click', check);
|
||||
});
|
||||
|
||||
}).call(this);
|
1
lemonldap-ng-portal/site/htdocs/static/common/js/webauthncheck.min.js
vendored
Normal file
1
lemonldap-ng-portal/site/htdocs/static/common/js/webauthncheck.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
!function(){var n=function(e,n){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-"+n),"positive"===n&&(n="success"),$("#color").addClass("alert-"+n)},r=function(e){return"unsupported"!==e.name?n("webAuthnBrowserFailed","danger"):n("webAuthnUnsupported","warning")},e=function(){var e;return n("webAuthnBrowserInProgress","warning"),e=window.datas.request,WebAuthnUI.WebAuthnUI.getCredential(e).then(function(e){return $("#credential").val(JSON.stringify(e)),$("#verify-form").submit()}).catch(r)};$(document).ready(function(){return setTimeout(e,1e3),$("#retrybutton").on("click",e)})}.call(this);
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webauthncheck.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","webAuthnError","error","name","check","request","datas","WebAuthnUI","getCredential","then","response","val","JSON","stringify","submit","document","ready","setTimeout","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,EAAgB,SAASC,GACvB,MACO,gBADCA,EAAMC,KAIHZ,EAAO,wBAAyB,UAFhCA,EAAO,sBAAuB,YAM3Ca,EAAQ,WACN,IAAIC,EAGJ,OAFAd,EAAO,4BAA6B,WACpCc,EAAUR,OAAOS,MAAMD,QAChBE,WAAWA,WAAWC,cAAcH,GAASI,KAAK,SAASC,GAEhE,OADAhB,EAAE,eAAeiB,IAAIC,KAAKC,UAAUH,IAC7BhB,EAAE,gBAAgBoB,WACjB,MACDb,IAIXP,EAAEqB,UAAUC,MAAM,WAEhB,OADAC,WAAWb,EAAO,KACXV,EAAE,gBAAgBwB,GAAG,QAASd,MAGtCe,KAAKC"}
|
|
@ -0,0 +1,126 @@
|
|||
// Generated by CoffeeScript 1.12.8
|
||||
|
||||
/*
|
||||
LemonLDAP::NG WebAuthn registration script
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var displayError, register, setMsg, verify, webAuthnError;
|
||||
|
||||
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);
|
||||
if (level === 'positive') {
|
||||
level = 'success';
|
||||
}
|
||||
return $('#color').addClass("alert-" + level);
|
||||
};
|
||||
|
||||
displayError = function(j, status, err) {
|
||||
var res;
|
||||
console.log('Error', err);
|
||||
res = JSON.parse(j.responseText);
|
||||
if (res && res.error) {
|
||||
res = res.error.replace(/.* /, '');
|
||||
console.log('Returned error', res);
|
||||
return setMsg(res, 'danger');
|
||||
}
|
||||
};
|
||||
|
||||
webAuthnError = function(error) {
|
||||
switch (error.name) {
|
||||
case 'unsupported':
|
||||
return setMsg('webAuthnUnsupported', 'warning');
|
||||
default:
|
||||
return setMsg('webAuthnBrowserFailed', 'danger');
|
||||
}
|
||||
};
|
||||
|
||||
register = function() {
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
url: portal + "2fregisters/webauthn/registrationchallenge",
|
||||
data: {},
|
||||
dataType: 'json',
|
||||
error: displayError,
|
||||
success: function(ch) {
|
||||
var request;
|
||||
request = ch.request;
|
||||
setMsg('webAuthnRegisterInProgress', 'warning');
|
||||
$('#u2fPermission').show();
|
||||
return WebAuthnUI.WebAuthnUI.createCredential(request).then(function(response) {
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
url: portal + "2fregisters/webauthn/registration",
|
||||
data: {
|
||||
state_id: ch.state_id,
|
||||
credential: JSON.stringify(response),
|
||||
keyName: $('#keyName').val()
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(resp) {
|
||||
if (resp.error) {
|
||||
if (resp.error.match(/badName/)) {
|
||||
return setMsg(resp.error, 'danger');
|
||||
} else {
|
||||
return setMsg('webAuthnRegisterFailed', 'danger');
|
||||
}
|
||||
} else if (resp.result) {
|
||||
return setMsg('yourKeyIsRegistered', 'positive');
|
||||
}
|
||||
},
|
||||
error: displayError
|
||||
});
|
||||
})["catch"](function(error) {
|
||||
return webAuthnError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
verify = function() {
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
url: portal + "2fregisters/webauthn/verificationchallenge",
|
||||
data: {},
|
||||
dataType: 'json',
|
||||
error: displayError,
|
||||
success: function(ch) {
|
||||
var request;
|
||||
request = ch.request;
|
||||
setMsg('webAuthnBrowserInProgress', 'warning');
|
||||
return WebAuthnUI.WebAuthnUI.getCredential(request).then(function(response) {
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
url: portal + "2fregisters/webauthn/verification",
|
||||
data: {
|
||||
state_id: ch.state_id,
|
||||
credential: JSON.stringify(response)
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(resp) {
|
||||
if (resp.error) {
|
||||
return setMsg('webAuthnFailed', 'danger');
|
||||
} else if (resp.result) {
|
||||
return setMsg('yourKeyIsVerified', 'positive');
|
||||
}
|
||||
},
|
||||
error: displayError
|
||||
});
|
||||
})["catch"](function(error) {
|
||||
return webAuthnError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#u2fPermission').hide();
|
||||
$('#register').on('click', register);
|
||||
$('#verify').on('click', verify);
|
||||
return $('#goback').attr('href', portal);
|
||||
});
|
||||
|
||||
}).call(this);
|
1
lemonldap-ng-portal/site/htdocs/static/common/js/webauthnregistration.min.js
vendored
Normal file
1
lemonldap-ng-portal/site/htdocs/static/common/js/webauthnregistration.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
!function(){var n=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)},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),n(e,"danger")},a=function(e){return"unsupported"!==e.name?n("webAuthnBrowserFailed","danger"):n("webAuthnUnsupported","warning")},e=function(){return $.ajax({type:"POST",url:portal+"2fregisters/webauthn/registrationchallenge",data:{},dataType:"json",error:t,success:function(r){var e=r.request;return n("webAuthnRegisterInProgress","warning"),$("#u2fPermission").show(),WebAuthnUI.WebAuthnUI.createCredential(e).then(function(e){return $.ajax({type:"POST",url:portal+"2fregisters/webauthn/registration",data:{state_id:r.state_id,credential:JSON.stringify(e),keyName:$("#keyName").val()},dataType:"json",success:function(e){return e.error?e.error.match(/badName/)?n(e.error,"danger"):n("webAuthnRegisterFailed","danger"):e.result?n("yourKeyIsRegistered","positive"):void 0},error:t})}).catch(a)}})},r=function(){return $.ajax({type:"POST",url:portal+"2fregisters/webauthn/verificationchallenge",data:{},dataType:"json",error:t,success:function(r){var e=r.request;return n("webAuthnBrowserInProgress","warning"),WebAuthnUI.WebAuthnUI.getCredential(e).then(function(e){return $.ajax({type:"POST",url:portal+"2fregisters/webauthn/verification",data:{state_id:r.state_id,credential:JSON.stringify(e)},dataType:"json",success:function(e){return e.error?n("webAuthnFailed","danger"):e.result?n("yourKeyIsVerified","positive"):void 0},error:t})}).catch(a)}})};$(document).ready(function(){return $("#u2fPermission").hide(),$("#register").on("click",e),$("#verify").on("click",r),$("#goback").attr("href",portal)})}.call(this);
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webauthnregistration.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","webAuthnError","name","register","ajax","type","url","portal","data","dataType","success","ch","request","show","WebAuthnUI","createCredential","then","response","state_id","credential","stringify","keyName","val","resp","match","result","verify","getCredential","document","ready","hide","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,WAIvBM,EAAgB,SAASF,GACvB,MACO,gBADCA,EAAMG,KAIHvB,EAAO,wBAAyB,UAFhCA,EAAO,sBAAuB,YAM3CwB,EAAW,WACT,OAAOrB,EAAEsB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,6CACdC,KAAM,GACNC,SAAU,OACVV,MAAOV,EACPqB,QAAS,SAASC,GAChB,IACAC,EAAUD,EAAGC,QAGb,OAFAjC,EAAO,6BAA8B,WACrCG,EAAE,kBAAkB+B,OACbC,WAAWA,WAAWC,iBAAiBH,GAASI,KAAK,SAASC,GACnE,OAAOnC,EAAEsB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,oCACdC,KAAM,CACJU,SAAUP,EAAGO,SACbC,WAAYvB,KAAKwB,UAAUH,GAC3BI,QAASvC,EAAE,YAAYwC,OAEzBb,SAAU,OACVC,QAAS,SAASa,GAChB,OAAIA,EAAKxB,MACHwB,EAAKxB,MAAMyB,MAAM,WACZ7C,EAAO4C,EAAKxB,MAAO,UAEnBpB,EAAO,yBAA0B,UAEjC4C,EAAKE,OACP9C,EAAO,sBAAuB,iBADhC,GAIToB,MAAOV,MAED,MACDY,OAMfyB,EAAS,WACP,OAAO5C,EAAEsB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,6CACdC,KAAM,GACNC,SAAU,OACVV,MAAOV,EACPqB,QAAS,SAASC,GAChB,IACAC,EAAUD,EAAGC,QAEb,OADAjC,EAAO,4BAA6B,WAC7BmC,WAAWA,WAAWa,cAAcf,GAASI,KAAK,SAASC,GAChE,OAAOnC,EAAEsB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,oCACdC,KAAM,CACJU,SAAUP,EAAGO,SACbC,WAAYvB,KAAKwB,UAAUH,IAE7BR,SAAU,OACVC,QAAS,SAASa,GAChB,OAAIA,EAAKxB,MACApB,EAAO,iBAAkB,UACvB4C,EAAKE,OACP9C,EAAO,oBAAqB,iBAD9B,GAIToB,MAAOV,MAED,MACDY,OAMfnB,EAAE8C,UAAUC,MAAM,WAIhB,OAHA/C,EAAE,kBAAkBgD,OACpBhD,EAAE,aAAaiD,GAAG,QAAS5B,GAC3BrB,EAAE,WAAWiD,GAAG,QAASL,GAClB5C,EAAE,WAAWC,KAAK,OAAQwB,WAGlCyB,KAAKC"}
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"هل تريد إعادة إرسال رسالة التأكيد؟",
|
||||
"resetPwd":"إعادة تعيين كلمة المرور الخاصة بي",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":" إعادة تحميل الحقوق تحتاج إلى تسجيل الخروج وتسجيل الدخول مرة أخرى",
|
||||
"rules":"RULES",
|
||||
"scope":"نطاق",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"انتظر",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"تحذير",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"مرحبا بك على بوابة إثبات الهوية الآمنة.",
|
||||
"yesResendMail":"نعم، أعد إرسال البريد",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Möchtest du, dass die Bestätigungsmail erneut gesendet wird ?",
|
||||
"resetPwd":"Mein Passwort zurücksetzen",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Zum Neuladen der Rechte musst du dich ab- und wieder anmelden",
|
||||
"rules":"RULES",
|
||||
"scope":"Scope",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Warten",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"Warnung",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Willkommen in Ihrem gesicherten Authentifizierungsportal.",
|
||||
"yesResendMail":"Ja, Mail erneut senden.",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Do you want the confirmation mail to be resent?",
|
||||
"resetPwd":"Reset my password",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"rules":"RULES",
|
||||
"scope":"Scope",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Wait",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"Warning",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
"yesResendMail":"Yes, resend the mail",
|
||||
"yourAddress":"Know your address",
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"¿Desea que el e-mail de confirmación sea reenviado?",
|
||||
"resetPwd":"Reiniciar mi contraseña",
|
||||
"rest2f":"Código de verificación",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"La recarga de derechos necesita desconectarse y conectarse de nuevo",
|
||||
"rules":"RULES",
|
||||
"scope":"Alcance",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Esperar",
|
||||
"waitingmessage":"Autenticación en progreso, espere por favor",
|
||||
"warning":"Precaución",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Bienvenido a su portal de autenticación.",
|
||||
"yesResendMail":"Sí, reenviar el e-mail",
|
||||
"yourAddress":"Conozca su dirección",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Conozca su perfil",
|
||||
"yourTotpKey":"Su llave TOTP",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Do you want the confirmation mail to be resent?",
|
||||
"resetPwd":"Palauta salasanani?",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"rules":"RULES",
|
||||
"scope":"Scope",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Odota",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"Varoitus",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
"yesResendMail":"Kyllä, uudelleen lähetä sähköposti",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Voulez-vous que le message de confirmation soit renvoyé ?",
|
||||
"resetPwd":"Réinitialiser mon mot de passe",
|
||||
"rest2f":"Code de vérification",
|
||||
"retry":"Réessayer",
|
||||
"rightsReloadNeedsLogout":"Le rechargement des droits nécessite une déconnexion",
|
||||
"rules":"REGLES",
|
||||
"scope":"Informations",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Attendre",
|
||||
"waitingmessage":"Authentification en cours, merci de patienter",
|
||||
"warning":"Attention",
|
||||
"webAuthnBrowserFailed":"Le navigateur n'a pas pu obtenir d'assertion WebAuthn",
|
||||
"webAuthnBrowserInProgress":"Authentification WebAuthn en cours, veuillez suivre les instructions de votre navigateur",
|
||||
"webAuthnFailed":"L'authentification WebAuthn a échoué",
|
||||
"webAuthnRegisterFailed":"L'enregistrement WebAuthn a échoué",
|
||||
"webAuthnRegisterInProgress":"Enregistrement WebAuthn en cours, veuillez suivre les instructions de votre navigateur",
|
||||
"webAuthnRequired":"Authentification WebAuthn nécessaire",
|
||||
"webAuthnUnsupported":"Votre navigateur ne supporte pas WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Enregistrement d'un périphérique de sécurité",
|
||||
"webauthnAlreadyRegistered":"Ce périphérique est déjà enregistré",
|
||||
"welcomeOnPortal":"Bienvenue sur votre portail d'authentification sécurisée.",
|
||||
"yesResendMail":"Oui, renvoyer le mail",
|
||||
"yourAddress":"Connaître votre adresse",
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"האם לשלוח שוב את הודעת האימות בדוא״ל?",
|
||||
"resetPwd":"איפוס הסיסמה שלי",
|
||||
"rest2f":"קוד אימות",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"רענוני זכויות דורשים יציאה וכניסה מחדש",
|
||||
"rules":"כללים",
|
||||
"scope":"היקף",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"המתנה",
|
||||
"waitingmessage":"מתבצע אימות, נא להמתין",
|
||||
"warning":"אזהרה",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"ברוך בואך לשער האימות המאובטח שלך.",
|
||||
"yesResendMail":"כן, לשלוח את ההודעה שוב",
|
||||
"yourAddress":"היכרות עם הכתובת שלך",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"היכרות עם הפרופיל שלך",
|
||||
"yourTotpKey":"מפתח ה־TOTP שלך",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Vuoi inviare di nuovo la mail di conferma?",
|
||||
"resetPwd":"Reimpostare la password",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Le ricariche dei diritti necessitano di disconnettersi e di riconnettersi",
|
||||
"rules":"RULES",
|
||||
"scope":"Ambito",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Attendere",
|
||||
"waitingmessage":"Autenticazione in corso, attendere prego",
|
||||
"warning":"Avvertimento",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Benvenuto sul tuo portale di autenticazione protetta.",
|
||||
"yesResendMail":"Sì, rinvia e-mail",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"La tua chiave TOTP",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Do you want the confirmation mail to be resent?",
|
||||
"resetPwd":"Reset my password",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"rules":"RULES",
|
||||
"scope":"Scope",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Wait",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"Warning",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
"yesResendMail":"Yes, resend the mail",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Czy chcesz, aby wiadomość z potwierdzeniem została ponownie wysłana?",
|
||||
"resetPwd":"Zresetuj moje hasło",
|
||||
"rest2f":"Kod weryfikacyjny",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Przeładowania uprawnień wymaga wylogowania i ponownego zalogowania",
|
||||
"rules":"RULES",
|
||||
"scope":"Zakres",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Czekaj",
|
||||
"waitingmessage":"Uwierzytelnianie w toku, proszę czekać",
|
||||
"warning":"Ostrzeżenie",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Witamy w portalu z bezpiecznym uwierzytelnianiem.",
|
||||
"yesResendMail":"Tak, wyślij ponownie pocztę",
|
||||
"yourAddress":"Twój adres",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Twój profil",
|
||||
"yourTotpKey":"Twój klucz TOTP",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Do you want the confirmation mail to be resent?",
|
||||
"resetPwd":"Reset my password",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"rules":"RULES",
|
||||
"scope":"Scope",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Wait",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"Warning",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
"yesResendMail":"Yes, resend the mail",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Você deseja que o e-mail de confirmação seja reenviado?",
|
||||
"resetPwd":"Redefinir minha senha",
|
||||
"rest2f":"Código de verificação",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Recarregamentos de direitos precisam que saia e faça login novamente",
|
||||
"rules":"REGRAS",
|
||||
"scope":"Escopo",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Espere",
|
||||
"waitingmessage":"Autenticação em progresso. Por favor, aguarde",
|
||||
"warning":"Aviso",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Bem-vindo ao seu portal de autenticação seguro.",
|
||||
"yesResendMail":"Sim, reenvie o e-mail",
|
||||
"yourAddress":"Saiba o seu endereço",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Saiba o seu perfil",
|
||||
"yourTotpKey":"Sua chave TOTP",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Do you want the confirmation mail to be resent?",
|
||||
"resetPwd":"Reset my password",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"rules":"RULES",
|
||||
"scope":"Scope",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Wait",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"Warning",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
"yesResendMail":"Yes, resend the mail",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Onay e-postasının tekrar gönderilmesini ister misiniz?",
|
||||
"resetPwd":"Parolamı sıfırla",
|
||||
"rest2f":"Doğrulama kodu",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Yetkiler yeniden yüklendiğinde çıkış yapıp tekrar giriş yapmanız gerekir",
|
||||
"rules":"KURALLAR",
|
||||
"scope":"Kapsam",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Bekleyin",
|
||||
"waitingmessage":"Kimlik doğrulama işlemi devam ediyor, lütfen bekleyin",
|
||||
"warning":"Uyarı",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Güvenli kimlik doğrulama portalına hoş geldiniz.",
|
||||
"yesResendMail":"Evet, tekrar e-posta gönder",
|
||||
"yourAddress":"Adresini bil",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Profilini bil",
|
||||
"yourTotpKey":"TOTP anahtarınız",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"Bạn có muốn gửi lại thư xác nhận không?",
|
||||
"resetPwd":"Đặt lại mật khẩu của tôi",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"Tải lại quyền cần đăng xuất và đăng nhập lại",
|
||||
"rules":"RULES",
|
||||
"scope":"Phạm vi",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"Hãy đợi",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"Cảnh báo",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"Chào mừng bạn đến với cổng thông tin xác thực được bảo mật của bạn.",
|
||||
"yesResendMail":"Có, gửi lại thư",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"您想确认邮件被重新发送吗?",
|
||||
"resetPwd":"重置我的密码",
|
||||
"rest2f":"Verification code",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"重新加载权限需要登出并且再次登录",
|
||||
"rules":"RULES",
|
||||
"scope":"Scope",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"等待",
|
||||
"waitingmessage":"Authentication in progress, please wait",
|
||||
"warning":"警告",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"欢迎来到您的加密认证 portal",
|
||||
"yesResendMail":"好的,重新发送邮件",
|
||||
"yourAddress":"Know your address",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@
|
|||
"resentConfirm":"您是否要重新傳送確認郵件?",
|
||||
"resetPwd":"重設我的密碼",
|
||||
"rest2f":"驗證代碼",
|
||||
"retry":"Retry",
|
||||
"rightsReloadNeedsLogout":"重新載入權限需要登出然後再次登入",
|
||||
"rules":"RULES",
|
||||
"scope":"範圍",
|
||||
|
@ -320,6 +321,16 @@
|
|||
"wait":"等待",
|
||||
"waitingmessage":"正在進行驗證,請稍候",
|
||||
"warning":"警告",
|
||||
"webAuthnBrowserFailed":"Browser failed to obtain WebAuthn credential",
|
||||
"webAuthnBrowserInProgress":"WebAuthn authentication in progress. Please follow your browser's instructions",
|
||||
"webAuthnFailed":"WebAuthn authentication failed",
|
||||
"webAuthnRegisterFailed":"WebAuthn registration failed",
|
||||
"webAuthnRegisterInProgress":"WebAuthn registration in progress. Please follow your browser's instructions",
|
||||
"webAuthnRequired":"WebAuthn authentication required",
|
||||
"webAuthnUnsupported":"Your web browser does not support WebAuthn",
|
||||
"webauthn2f":"WebAuthn",
|
||||
"webauthn2fWelcome":"Security device registration",
|
||||
"webauthnAlreadyRegistered":"This device is already registered",
|
||||
"welcomeOnPortal":"歡迎使用您的安全驗證首頁。",
|
||||
"yesResendMail":"是的,重新傳送電子郵件",
|
||||
"yourAddress":"知道您的地址",
|
||||
|
@ -337,4 +348,4 @@
|
|||
"yourProfile":"知道您的個人檔案",
|
||||
"yourTotpKey":"您的 TOTP 金鑰",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<TMPL_INCLUDE NAME="header.tpl">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<TMPL_IF NAME="AUTH_ERROR">
|
||||
<div class="message message-<TMPL_VAR NAME="AUTH_ERROR_TYPE"> alert"><span trmsg="<TMPL_VAR NAME="AUTH_ERROR">"></span></div>
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="DATA">
|
||||
<div id="color" class="message message-positive alert"><span id="msg" trspan="webAuthnRequired"></span></div>
|
||||
<form id="verify-form" action="/webauthn2fcheck" method="post">
|
||||
<input type="hidden" id="credential" name="credential" value="" />
|
||||
<input type="hidden" id="token" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
<input type="hidden" id="checkLogins" name="checkLogins" value="<TMPL_VAR NAME="CHECKLOGINS">" />
|
||||
<input type="hidden" id="stayconnected" name="stayconnected" value="<TMPL_VAR NAME="STAYCONNECTED">" />
|
||||
<input type="hidden" name="skin" value="<TMPL_VAR NAME="SKIN">" />
|
||||
</form>
|
||||
<script type="application/init">
|
||||
<TMPL_VAR NAME="DATA">
|
||||
</script>
|
||||
<!-- //if:jsminified
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthn-ui.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthncheck.min.js"></script>
|
||||
//else -->
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthn-ui.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthncheck.js"></script>
|
||||
<!-- //endif -->
|
||||
</TMPL_IF>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<div class="btn btn-primary" role="button" id="retrybutton">
|
||||
<span class="fa fa-repeat"></span>
|
||||
<span trspan="retry">Retry</span>
|
||||
</div>
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">?cancel=1&skin=<TMPL_VAR NAME="SKIN">" class="btn btn-secondary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="cancel">Cancel</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<TMPL_INCLUDE NAME="footer.tpl">
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<TMPL_INCLUDE NAME="header.tpl">
|
||||
|
||||
<main id="menucontent" class="container">
|
||||
|
||||
<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 class="card-body">
|
||||
<div id="u2fPermission" trspan="u2fPermission" class="alert alert-info">You may be prompted to allow the site permission to access your security keys. After granting permission, the device will start to blink.</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 text-center">
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX"><TMPL_VAR NAME="SKIN">/webauthn.png" alt="WebAuthn" title="WebAuthn" />
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="keyName"><span trspan="name">Name</span></label>
|
||||
<input type="text" class="form-control" id="keyName" name="keyName" value="MyFidoKey" trplaceholder="name" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<span id="verify" class="btn btn-info" role="button">
|
||||
<span class="fa fa-check-circle"></span>
|
||||
<span trspan="verify">Verify</span>
|
||||
</span>
|
||||
<span id="register" class="btn btn-success" role="button">
|
||||
<span class="fa fa-floppy-o"></span>
|
||||
<span trspan="register">Register</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="buttons">
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">2fregisters?skin=<TMPL_VAR NAME="SKIN">" class="btn btn-info" role="button">
|
||||
<span class="fa fa-shield"></span>
|
||||
<span trspan="sfaManager">sfaManager</span>
|
||||
</a>
|
||||
|
||||
<a id="goback" href="<TMPL_VAR NAME="PORTAL_URL">?cancel=1&skin=<TMPL_VAR NAME="SKIN"><TMPL_IF NAME="AUTH_URL">&url=<TMPL_VAR NAME="AUTH_URL"></TMPL_IF>" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- //if:jsminified
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthn-ui.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthnregistration.min.js"></script>
|
||||
//else -->
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthn-ui.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/webauthnregistration.js"></script>
|
||||
<!-- //endif -->
|
||||
<TMPL_INCLUDE NAME="footer.tpl">
|
Loading…
Reference in New Issue
Block a user