4.21.3
This commit is contained in:
107
app/static/assets/js/core.js
Executable file
107
app/static/assets/js/core.js
Executable file
@ -0,0 +1,107 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
let hexToRgba = function(hex, opacity) {
|
||||
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
let rgb = result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
|
||||
return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + opacity + ')';
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
/** Constant div card */
|
||||
const DIV_CARD = 'div.card';
|
||||
|
||||
/** Initialize tooltips */
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
/** Initialize popovers */
|
||||
$('[data-toggle="popover"]').popover({
|
||||
html: true
|
||||
});
|
||||
|
||||
/** Function for remove card */
|
||||
$('[data-toggle="card-remove"]').on('click', function(e) {
|
||||
let $card = $(this).closest(DIV_CARD);
|
||||
|
||||
$card.remove();
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
/** Function for collapse card */
|
||||
$('[data-toggle="card-collapse"]').on('click', function(e) {
|
||||
let $card = $(this).closest(DIV_CARD);
|
||||
|
||||
$card.toggleClass('card-collapsed');
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
/** Function for fullscreen card */
|
||||
$('[data-toggle="card-fullscreen"]').on('click', function(e) {
|
||||
let $card = $(this).closest(DIV_CARD);
|
||||
|
||||
$card.toggleClass('card-fullscreen').removeClass('card-collapsed');
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
/** */
|
||||
if ($('[data-sparkline]').length) {
|
||||
let generateSparkline = function($elem, data, params) {
|
||||
$elem.sparkline(data, {
|
||||
type: $elem.attr('data-sparkline-type'),
|
||||
height: '100%',
|
||||
barColor: params.color,
|
||||
lineColor: params.color,
|
||||
fillColor: 'transparent',
|
||||
spotColor: params.color,
|
||||
spotRadius: 0,
|
||||
lineWidth: 2,
|
||||
highlightColor: hexToRgba(params.color, .6),
|
||||
highlightLineColor: '#666',
|
||||
defaultPixelsPerValue: 5
|
||||
});
|
||||
};
|
||||
|
||||
require(['sparkline'], function() {
|
||||
$('[data-sparkline]').each(function() {
|
||||
let $chart = $(this);
|
||||
|
||||
generateSparkline($chart, JSON.parse($chart.attr('data-sparkline')), {
|
||||
color: $chart.attr('data-sparkline-color')
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** */
|
||||
if ($('.chart-circle').length) {
|
||||
require(['circle-progress'], function() {
|
||||
$('.chart-circle').each(function() {
|
||||
let $this = $(this);
|
||||
|
||||
$this.circleProgress({
|
||||
fill: {
|
||||
color: tabler.colors[$this.attr('data-color')] || tabler.colors.blue
|
||||
},
|
||||
size: $this.height(),
|
||||
startAngle: -Math.PI / 4 * 2,
|
||||
emptyFill: '#F4F4F4',
|
||||
lineCap: 'round'
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
126
app/static/assets/js/dashboard.js
Executable file
126
app/static/assets/js/dashboard.js
Executable file
@ -0,0 +1,126 @@
|
||||
require.config({
|
||||
shim: {
|
||||
'bootstrap': ['jquery'],
|
||||
'sparkline': ['jquery'],
|
||||
'tablesorter': ['jquery'],
|
||||
'vector-map': ['jquery'],
|
||||
'vector-map-de': ['vector-map', 'jquery'],
|
||||
'vector-map-world': ['vector-map', 'jquery'],
|
||||
'core': ['bootstrap', 'jquery'],
|
||||
},
|
||||
paths: {
|
||||
'core': 'assets/js/core',
|
||||
'jquery': 'assets/js/vendors/jquery-3.2.1.min',
|
||||
'bootstrap': 'assets/js/vendors/bootstrap.bundle.min',
|
||||
'sparkline': 'assets/js/vendors/jquery.sparkline.min',
|
||||
'selectize': 'assets/js/vendors/selectize.min',
|
||||
'tablesorter': 'assets/js/vendors/jquery.tablesorter.min',
|
||||
'vector-map': 'assets/js/vendors/jquery-jvectormap-2.0.3.min',
|
||||
'vector-map-de': 'assets/js/vendors/jquery-jvectormap-de-merc',
|
||||
'vector-map-world': 'assets/js/vendors/jquery-jvectormap-world-mill',
|
||||
'circle-progress': 'assets/js/vendors/circle-progress.min',
|
||||
}
|
||||
});
|
||||
window.tabler = {
|
||||
colors: {
|
||||
'blue': '#467fcf',
|
||||
'blue-darkest': '#0e1929',
|
||||
'blue-darker': '#1c3353',
|
||||
'blue-dark': '#3866a6',
|
||||
'blue-light': '#7ea5dd',
|
||||
'blue-lighter': '#c8d9f1',
|
||||
'blue-lightest': '#edf2fa',
|
||||
'azure': '#45aaf2',
|
||||
'azure-darkest': '#0e2230',
|
||||
'azure-darker': '#1c4461',
|
||||
'azure-dark': '#3788c2',
|
||||
'azure-light': '#7dc4f6',
|
||||
'azure-lighter': '#c7e6fb',
|
||||
'azure-lightest': '#ecf7fe',
|
||||
'indigo': '#6574cd',
|
||||
'indigo-darkest': '#141729',
|
||||
'indigo-darker': '#282e52',
|
||||
'indigo-dark': '#515da4',
|
||||
'indigo-light': '#939edc',
|
||||
'indigo-lighter': '#d1d5f0',
|
||||
'indigo-lightest': '#f0f1fa',
|
||||
'purple': '#a55eea',
|
||||
'purple-darkest': '#21132f',
|
||||
'purple-darker': '#42265e',
|
||||
'purple-dark': '#844bbb',
|
||||
'purple-light': '#c08ef0',
|
||||
'purple-lighter': '#e4cff9',
|
||||
'purple-lightest': '#f6effd',
|
||||
'pink': '#f66d9b',
|
||||
'pink-darkest': '#31161f',
|
||||
'pink-darker': '#622c3e',
|
||||
'pink-dark': '#c5577c',
|
||||
'pink-light': '#f999b9',
|
||||
'pink-lighter': '#fcd3e1',
|
||||
'pink-lightest': '#fef0f5',
|
||||
'red': '#e74c3c',
|
||||
'red-darkest': '#2e0f0c',
|
||||
'red-darker': '#5c1e18',
|
||||
'red-dark': '#b93d30',
|
||||
'red-light': '#ee8277',
|
||||
'red-lighter': '#f8c9c5',
|
||||
'red-lightest': '#fdedec',
|
||||
'orange': '#fd9644',
|
||||
'orange-darkest': '#331e0e',
|
||||
'orange-darker': '#653c1b',
|
||||
'orange-dark': '#ca7836',
|
||||
'orange-light': '#feb67c',
|
||||
'orange-lighter': '#fee0c7',
|
||||
'orange-lightest': '#fff5ec',
|
||||
'yellow': '#f1c40f',
|
||||
'yellow-darkest': '#302703',
|
||||
'yellow-darker': '#604e06',
|
||||
'yellow-dark': '#c19d0c',
|
||||
'yellow-light': '#f5d657',
|
||||
'yellow-lighter': '#fbedb7',
|
||||
'yellow-lightest': '#fef9e7',
|
||||
'lime': '#7bd235',
|
||||
'lime-darkest': '#192a0b',
|
||||
'lime-darker': '#315415',
|
||||
'lime-dark': '#62a82a',
|
||||
'lime-light': '#a3e072',
|
||||
'lime-lighter': '#d7f2c2',
|
||||
'lime-lightest': '#f2fbeb',
|
||||
'green': '#5eba00',
|
||||
'green-darkest': '#132500',
|
||||
'green-darker': '#264a00',
|
||||
'green-dark': '#4b9500',
|
||||
'green-light': '#8ecf4d',
|
||||
'green-lighter': '#cfeab3',
|
||||
'green-lightest': '#eff8e6',
|
||||
'teal': '#2bcbba',
|
||||
'teal-darkest': '#092925',
|
||||
'teal-darker': '#11514a',
|
||||
'teal-dark': '#22a295',
|
||||
'teal-light': '#6bdbcf',
|
||||
'teal-lighter': '#bfefea',
|
||||
'teal-lightest': '#eafaf8',
|
||||
'cyan': '#17a2b8',
|
||||
'cyan-darkest': '#052025',
|
||||
'cyan-darker': '#09414a',
|
||||
'cyan-dark': '#128293',
|
||||
'cyan-light': '#5dbecd',
|
||||
'cyan-lighter': '#b9e3ea',
|
||||
'cyan-lightest': '#e8f6f8',
|
||||
'gray': '#868e96',
|
||||
'gray-darkest': '#1b1c1e',
|
||||
'gray-darker': '#36393c',
|
||||
'gray-dark': '#6b7278',
|
||||
'gray-light': '#aab0b6',
|
||||
'gray-lighter': '#dbdde0',
|
||||
'gray-lightest': '#f3f4f5',
|
||||
'gray-dark': '#343a40',
|
||||
'gray-dark-darkest': '#0a0c0d',
|
||||
'gray-dark-darker': '#15171a',
|
||||
'gray-dark-dark': '#2a2e33',
|
||||
'gray-dark-light': '#717579',
|
||||
'gray-dark-lighter': '#c2c4c6',
|
||||
'gray-dark-lightest': '#ebebec'
|
||||
}
|
||||
};
|
||||
require(['core']);
|
5
app/static/assets/js/require.min.js
vendored
Executable file
5
app/static/assets/js/require.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
122
app/static/assets/js/vendors/base64.js
vendored
Normal file
122
app/static/assets/js/vendors/base64.js
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
// Copyright (c) 2017 Duo Security, Inc. All rights reserved.
|
||||
// Under BSD 3-Clause "New" or "Revised" License
|
||||
// https://github.com/duo-labs/py_webauthn/
|
||||
|
||||
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
|
||||
;(function (exports) {
|
||||
'use strict'
|
||||
|
||||
var Arr = (typeof Uint8Array !== 'undefined')
|
||||
? Uint8Array
|
||||
: Array
|
||||
|
||||
var PLUS = '+'.charCodeAt(0)
|
||||
var SLASH = '/'.charCodeAt(0)
|
||||
var NUMBER = '0'.charCodeAt(0)
|
||||
var LOWER = 'a'.charCodeAt(0)
|
||||
var UPPER = 'A'.charCodeAt(0)
|
||||
var PLUS_URL_SAFE = '-'.charCodeAt(0)
|
||||
var SLASH_URL_SAFE = '_'.charCodeAt(0)
|
||||
|
||||
function decode (elt) {
|
||||
var code = elt.charCodeAt(0)
|
||||
if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+'
|
||||
if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/'
|
||||
if (code < NUMBER) return -1 // no match
|
||||
if (code < NUMBER + 10) return code - NUMBER + 26 + 26
|
||||
if (code < UPPER + 26) return code - UPPER
|
||||
if (code < LOWER + 26) return code - LOWER + 26
|
||||
}
|
||||
|
||||
function b64ToByteArray (b64) {
|
||||
var i, j, l, tmp, placeHolders, arr
|
||||
|
||||
if (b64.length % 4 > 0) {
|
||||
throw new Error('Invalid string. Length must be a multiple of 4')
|
||||
}
|
||||
|
||||
// the number of equal signs (place holders)
|
||||
// if there are two placeholders, than the two characters before it
|
||||
// represent one byte
|
||||
// if there is only one, then the three characters before it represent 2 bytes
|
||||
// this is just a cheap hack to not do indexOf twice
|
||||
var len = b64.length
|
||||
placeHolders = b64.charAt(len - 2) === '=' ? 2 : b64.charAt(len - 1) === '=' ? 1 : 0
|
||||
|
||||
// base64 is 4/3 + up to two characters of the original data
|
||||
arr = new Arr(b64.length * 3 / 4 - placeHolders)
|
||||
|
||||
// if there are placeholders, only get up to the last complete 4 chars
|
||||
l = placeHolders > 0 ? b64.length - 4 : b64.length
|
||||
|
||||
var L = 0
|
||||
|
||||
function push (v) {
|
||||
arr[L++] = v
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < l; i += 4, j += 3) {
|
||||
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
|
||||
push((tmp & 0xFF0000) >> 16)
|
||||
push((tmp & 0xFF00) >> 8)
|
||||
push(tmp & 0xFF)
|
||||
}
|
||||
|
||||
if (placeHolders === 2) {
|
||||
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
|
||||
push(tmp & 0xFF)
|
||||
} else if (placeHolders === 1) {
|
||||
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
|
||||
push((tmp >> 8) & 0xFF)
|
||||
push(tmp & 0xFF)
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
function uint8ToBase64 (uint8) {
|
||||
var i
|
||||
var extraBytes = uint8.length % 3 // if we have 1 byte left, pad 2 bytes
|
||||
var output = ''
|
||||
var temp, length
|
||||
|
||||
function encode (num) {
|
||||
return lookup.charAt(num)
|
||||
}
|
||||
|
||||
function tripletToBase64 (num) {
|
||||
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
|
||||
}
|
||||
|
||||
// go through the array every three bytes, we'll deal with trailing stuff later
|
||||
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
|
||||
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
|
||||
output += tripletToBase64(temp)
|
||||
}
|
||||
|
||||
// pad the end with zeros, but make sure to not forget the extra bytes
|
||||
switch (extraBytes) {
|
||||
case 1:
|
||||
temp = uint8[uint8.length - 1]
|
||||
output += encode(temp >> 2)
|
||||
output += encode((temp << 4) & 0x3F)
|
||||
output += '=='
|
||||
break
|
||||
case 2:
|
||||
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
|
||||
output += encode(temp >> 10)
|
||||
output += encode((temp >> 4) & 0x3F)
|
||||
output += encode((temp << 2) & 0x3F)
|
||||
output += '='
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
exports.toByteArray = b64ToByteArray
|
||||
exports.fromByteArray = uint8ToBase64
|
||||
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
|
7
app/static/assets/js/vendors/bootstrap.bundle.min.js
vendored
Executable file
7
app/static/assets/js/vendors/bootstrap.bundle.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
1
app/static/assets/js/vendors/bootstrap.bundle.min.js.map
vendored
Normal file
1
app/static/assets/js/vendors/bootstrap.bundle.min.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
10
app/static/assets/js/vendors/chart.bundle.min.js
vendored
Executable file
10
app/static/assets/js/vendors/chart.bundle.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
10
app/static/assets/js/vendors/circle-progress.min.js
vendored
Executable file
10
app/static/assets/js/vendors/circle-progress.min.js
vendored
Executable file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* jquery-circle-progress - jQuery Plugin to draw animated circular progress bars:
|
||||
* {@link http://kottenator.github.io/jquery-circle-progress/}
|
||||
*
|
||||
* @author Rostyslav Bryzgunov <kottenator@gmail.com>
|
||||
* @version 1.2.2
|
||||
* @licence MIT
|
||||
* @preserve
|
||||
*/
|
||||
!function(i){if("function"==typeof define&&define.amd)define(["jquery"],i);else if("object"==typeof module&&module.exports){var t=require("jquery");i(t),module.exports=t}else i(jQuery)}(function(i){function t(i){this.init(i)}t.prototype={value:0,size:100,startAngle:-Math.PI,thickness:"auto",fill:{gradient:["#3aeabb","#fdd250"]},emptyFill:"rgba(0, 0, 0, .1)",animation:{duration:1200,easing:"circleProgressEasing"},animationStartValue:0,reverse:!1,lineCap:"butt",insertMode:"prepend",constructor:t,el:null,canvas:null,ctx:null,radius:0,arcFill:null,lastFrameValue:0,init:function(t){i.extend(this,t),this.radius=this.size/2,this.initWidget(),this.initFill(),this.draw(),this.el.trigger("circle-inited")},initWidget:function(){this.canvas||(this.canvas=i("<canvas>")["prepend"==this.insertMode?"prependTo":"appendTo"](this.el)[0]);var t=this.canvas;if(t.width=this.size,t.height=this.size,this.ctx=t.getContext("2d"),window.devicePixelRatio>1){var e=window.devicePixelRatio;t.style.width=t.style.height=this.size+"px",t.width=t.height=this.size*e,this.ctx.scale(e,e)}},initFill:function(){function t(){var t=i("<canvas>")[0];t.width=e.size,t.height=e.size,t.getContext("2d").drawImage(g,0,0,r,r),e.arcFill=e.ctx.createPattern(t,"no-repeat"),e.drawFrame(e.lastFrameValue)}var e=this,a=this.fill,n=this.ctx,r=this.size;if(!a)throw Error("The fill is not specified!");if("string"==typeof a&&(a={color:a}),a.color&&(this.arcFill=a.color),a.gradient){var s=a.gradient;if(1==s.length)this.arcFill=s[0];else if(s.length>1){for(var l=a.gradientAngle||0,o=a.gradientDirection||[r/2*(1-Math.cos(l)),r/2*(1+Math.sin(l)),r/2*(1+Math.cos(l)),r/2*(1-Math.sin(l))],h=n.createLinearGradient.apply(n,o),c=0;c<s.length;c++){var d=s[c],u=c/(s.length-1);i.isArray(d)&&(u=d[1],d=d[0]),h.addColorStop(u,d)}this.arcFill=h}}if(a.image){var g;a.image instanceof Image?g=a.image:(g=new Image,g.src=a.image),g.complete?t():g.onload=t}},draw:function(){this.animation?this.drawAnimated(this.value):this.drawFrame(this.value)},drawFrame:function(i){this.lastFrameValue=i,this.ctx.clearRect(0,0,this.size,this.size),this.drawEmptyArc(i),this.drawArc(i)},drawArc:function(i){if(0!==i){var t=this.ctx,e=this.radius,a=this.getThickness(),n=this.startAngle;t.save(),t.beginPath(),this.reverse?t.arc(e,e,e-a/2,n-2*Math.PI*i,n):t.arc(e,e,e-a/2,n,n+2*Math.PI*i),t.lineWidth=a,t.lineCap=this.lineCap,t.strokeStyle=this.arcFill,t.stroke(),t.restore()}},drawEmptyArc:function(i){var t=this.ctx,e=this.radius,a=this.getThickness(),n=this.startAngle;i<1&&(t.save(),t.beginPath(),i<=0?t.arc(e,e,e-a/2,0,2*Math.PI):this.reverse?t.arc(e,e,e-a/2,n,n-2*Math.PI*i):t.arc(e,e,e-a/2,n+2*Math.PI*i,n),t.lineWidth=a,t.strokeStyle=this.emptyFill,t.stroke(),t.restore())},drawAnimated:function(t){var e=this,a=this.el,n=i(this.canvas);n.stop(!0,!1),a.trigger("circle-animation-start"),n.css({animationProgress:0}).animate({animationProgress:1},i.extend({},this.animation,{step:function(i){var n=e.animationStartValue*(1-i)+t*i;e.drawFrame(n),a.trigger("circle-animation-progress",[i,n])}})).promise().always(function(){a.trigger("circle-animation-end")})},getThickness:function(){return i.isNumeric(this.thickness)?this.thickness:this.size/14},getValue:function(){return this.value},setValue:function(i){this.animation&&(this.animationStartValue=this.lastFrameValue),this.value=i,this.draw()}},i.circleProgress={defaults:t.prototype},i.easing.circleProgressEasing=function(i){return i<.5?(i=2*i,.5*i*i*i):(i=2-2*i,1-.5*i*i*i)},i.fn.circleProgress=function(e,a){var n="circle-progress",r=this.data(n);if("widget"==e){if(!r)throw Error('Calling "widget" method on not initialized instance is forbidden');return r.canvas}if("value"==e){if(!r)throw Error('Calling "value" method on not initialized instance is forbidden');if("undefined"==typeof a)return r.getValue();var s=arguments[1];return this.each(function(){i(this).data(n).setValue(s)})}return this.each(function(){var a=i(this),r=a.data(n),s=i.isPlainObject(e)?e:{};if(r)r.init(s);else{var l=i.extend({},a.data());"string"==typeof l.fill&&(l.fill=JSON.parse(l.fill)),"string"==typeof l.animation&&(l.animation=JSON.parse(l.animation)),s=i.extend(l,s),s.el=a,r=new t(s),a.data(n,r)}})}});
|
4
app/static/assets/js/vendors/jquery-3.2.1.min.js
vendored
Executable file
4
app/static/assets/js/vendors/jquery-3.2.1.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
4
app/static/assets/js/vendors/jquery-3.2.1.slim.min.js
vendored
Executable file
4
app/static/assets/js/vendors/jquery-3.2.1.slim.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
2
app/static/assets/js/vendors/jquery-jvectormap-2.0.3.min.js
vendored
Executable file
2
app/static/assets/js/vendors/jquery-jvectormap-2.0.3.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
1
app/static/assets/js/vendors/jquery-jvectormap-de-merc.js
vendored
Executable file
1
app/static/assets/js/vendors/jquery-jvectormap-de-merc.js
vendored
Executable file
File diff suppressed because one or more lines are too long
1
app/static/assets/js/vendors/jquery-jvectormap-world-mill.js
vendored
Executable file
1
app/static/assets/js/vendors/jquery-jvectormap-world-mill.js
vendored
Executable file
File diff suppressed because one or more lines are too long
2
app/static/assets/js/vendors/jquery.sparkline.min.js
vendored
Executable file
2
app/static/assets/js/vendors/jquery.sparkline.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
4
app/static/assets/js/vendors/jquery.tablesorter.min.js
vendored
Executable file
4
app/static/assets/js/vendors/jquery.tablesorter.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
3829
app/static/assets/js/vendors/selectize.min.js
vendored
Executable file
3829
app/static/assets/js/vendors/selectize.min.js
vendored
Executable file
File diff suppressed because it is too large
Load Diff
138
app/static/assets/js/vendors/webauthn.js
vendored
Normal file
138
app/static/assets/js/vendors/webauthn.js
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2017 Duo Security, Inc. All rights reserved.
|
||||
// Under BSD 3-Clause "New" or "Revised" License
|
||||
// https://github.com/duo-labs/py_webauthn/
|
||||
|
||||
function b64enc(buf) {
|
||||
return base64js
|
||||
.fromByteArray(buf)
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=/g, "");
|
||||
}
|
||||
|
||||
function b64RawEnc(buf) {
|
||||
return base64js.fromByteArray(buf).replace(/\+/g, "-").replace(/\//g, "_");
|
||||
}
|
||||
|
||||
function hexEncode(buf) {
|
||||
return Array.from(buf)
|
||||
.map(function (x) {
|
||||
return ("0" + x.toString(16)).substr(-2);
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
const transformCredentialRequestOptions = (
|
||||
credentialRequestOptionsFromServer
|
||||
) => {
|
||||
let { challenge, allowCredentials } = credentialRequestOptionsFromServer;
|
||||
|
||||
challenge = Uint8Array.from(
|
||||
atob(challenge.replace(/\_/g, "/").replace(/\-/g, "+")),
|
||||
(c) => c.charCodeAt(0)
|
||||
);
|
||||
|
||||
allowCredentials = allowCredentials.map((credentialDescriptor) => {
|
||||
let { id } = credentialDescriptor;
|
||||
id = id.replace(/\_/g, "/").replace(/\-/g, "+");
|
||||
id = Uint8Array.from(atob(id), (c) => c.charCodeAt(0));
|
||||
return Object.assign({}, credentialDescriptor, { id });
|
||||
});
|
||||
|
||||
const transformedCredentialRequestOptions = Object.assign(
|
||||
{},
|
||||
credentialRequestOptionsFromServer,
|
||||
{ challenge, allowCredentials }
|
||||
);
|
||||
|
||||
return transformedCredentialRequestOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms items in the credentialCreateOptions generated on the server
|
||||
* into byte arrays expected by the navigator.credentials.create() call
|
||||
* @param {Object} credentialCreateOptionsFromServer
|
||||
*/
|
||||
const transformCredentialCreateOptions = (
|
||||
credentialCreateOptionsFromServer
|
||||
) => {
|
||||
let { challenge, user, excludeCredentials } = credentialCreateOptionsFromServer;
|
||||
user.id = Uint8Array.from(
|
||||
atob(
|
||||
credentialCreateOptionsFromServer.user.id
|
||||
.replace(/\_/g, "/")
|
||||
.replace(/\-/g, "+")
|
||||
),
|
||||
(c) => c.charCodeAt(0)
|
||||
);
|
||||
|
||||
challenge = Uint8Array.from(
|
||||
atob(
|
||||
credentialCreateOptionsFromServer.challenge
|
||||
.replace(/\_/g, "/")
|
||||
.replace(/\-/g, "+")
|
||||
),
|
||||
(c) => c.charCodeAt(0)
|
||||
);
|
||||
|
||||
excludeCredentials = excludeCredentials.map((credentialDescriptor) => {
|
||||
let { id } = credentialDescriptor;
|
||||
id = id.replace(/\_/g, "/").replace(/\-/g, "+");
|
||||
id = Uint8Array.from(atob(id), (c) => c.charCodeAt(0));
|
||||
return Object.assign({}, credentialDescriptor, { id });
|
||||
});
|
||||
|
||||
const transformedCredentialCreateOptions = Object.assign(
|
||||
{},
|
||||
credentialCreateOptionsFromServer,
|
||||
{ challenge, user, excludeCredentials }
|
||||
);
|
||||
|
||||
return transformedCredentialCreateOptions;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the binary data in the credential into base64 strings
|
||||
* for posting to the server.
|
||||
* @param {PublicKeyCredential} newAssertion
|
||||
*/
|
||||
const transformNewAssertionForServer = (newAssertion) => {
|
||||
const attObj = new Uint8Array(newAssertion.response.attestationObject);
|
||||
const clientDataJSON = new Uint8Array(newAssertion.response.clientDataJSON);
|
||||
const rawId = new Uint8Array(newAssertion.rawId);
|
||||
|
||||
const registrationClientExtensions = newAssertion.getClientExtensionResults();
|
||||
|
||||
return {
|
||||
id: newAssertion.id,
|
||||
rawId: b64enc(rawId),
|
||||
type: newAssertion.type,
|
||||
attObj: b64enc(attObj),
|
||||
clientData: b64enc(clientDataJSON),
|
||||
registrationClientExtensions: JSON.stringify(registrationClientExtensions),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encodes the binary data in the assertion into strings for posting to the server.
|
||||
* @param {PublicKeyCredential} newAssertion
|
||||
*/
|
||||
const transformAssertionForServer = (newAssertion) => {
|
||||
const authData = new Uint8Array(newAssertion.response.authenticatorData);
|
||||
const clientDataJSON = new Uint8Array(newAssertion.response.clientDataJSON);
|
||||
const rawId = new Uint8Array(newAssertion.rawId);
|
||||
const sig = new Uint8Array(newAssertion.response.signature);
|
||||
const assertionClientExtensions = newAssertion.getClientExtensionResults();
|
||||
|
||||
return {
|
||||
id: newAssertion.id,
|
||||
rawId: b64enc(rawId),
|
||||
type: newAssertion.type,
|
||||
authData: b64RawEnc(authData),
|
||||
clientData: b64RawEnc(clientDataJSON),
|
||||
signature: hexEncode(sig),
|
||||
assertionClientExtensions: JSON.stringify(assertionClientExtensions),
|
||||
};
|
||||
};
|
Reference in New Issue
Block a user