updated plugin Two Factor version 0.16.0
This commit is contained in:
@ -0,0 +1,49 @@
|
||||
/* global twoFactorBackupCodes, wp, navigator, document, jQuery */
|
||||
( function( $ ) {
|
||||
$( '.button-two-factor-backup-codes-copy' ).click( function() {
|
||||
var csvCodes = $( '.two-factor-backup-codes-wrapper' ).data( 'codesCsv' ),
|
||||
$temp;
|
||||
|
||||
if ( ! csvCodes ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( navigator.clipboard && navigator.clipboard.writeText ) {
|
||||
navigator.clipboard.writeText( csvCodes );
|
||||
return;
|
||||
}
|
||||
|
||||
$temp = $( '<textarea>' ).val( csvCodes ).css( { position: 'absolute', left: '-9999px' } );
|
||||
$( 'body' ).append( $temp );
|
||||
$temp[0].select();
|
||||
document.execCommand( 'copy' );
|
||||
$temp.remove();
|
||||
} );
|
||||
|
||||
$( '.button-two-factor-backup-codes-generate' ).click( function() {
|
||||
wp.apiRequest( {
|
||||
method: 'POST',
|
||||
path: twoFactorBackupCodes.restPath,
|
||||
data: {
|
||||
user_id: parseInt( twoFactorBackupCodes.userId, 10 )
|
||||
}
|
||||
} ).then( function( response ) {
|
||||
var $codesList = $( '.two-factor-backup-codes-unused-codes' ),
|
||||
i;
|
||||
|
||||
$( '.two-factor-backup-codes-wrapper' ).show();
|
||||
$codesList.html( '' );
|
||||
$codesList.css( { 'column-count': 2, 'column-gap': '80px', 'max-width': '420px' } );
|
||||
$( '.two-factor-backup-codes-wrapper' ).data( 'codesCsv', response.codes.join( ',' ) );
|
||||
|
||||
// Append the codes.
|
||||
for ( i = 0; i < response.codes.length; i++ ) {
|
||||
$codesList.append( '<li class="two-factor-backup-codes-token">' + response.codes[ i ] + '</li>' );
|
||||
}
|
||||
|
||||
// Update counter.
|
||||
$( '.two-factor-backup-codes-count' ).html( response.i18n.count );
|
||||
$( '#two-factor-backup-codes-download-link' ).attr( 'href', response.download_link );
|
||||
} );
|
||||
} );
|
||||
}( jQuery ) );
|
||||
@ -1,150 +0,0 @@
|
||||
/* global window, document, jQuery, inlineEditL10n, ajaxurl */
|
||||
var inlineEditKey;
|
||||
|
||||
( function( $ ) {
|
||||
inlineEditKey = {
|
||||
|
||||
init: function() {
|
||||
var t = this,
|
||||
row = $( '#security-keys-section #inline-edit' );
|
||||
|
||||
t.what = '#key-';
|
||||
|
||||
$( '#security-keys-section #the-list' ).on( 'click', 'a.editinline', function() {
|
||||
inlineEditKey.edit( this );
|
||||
return false;
|
||||
} );
|
||||
|
||||
// Prepare the edit row.
|
||||
row.keyup( function( event ) {
|
||||
if ( 27 === event.which ) {
|
||||
return inlineEditKey.revert();
|
||||
}
|
||||
} );
|
||||
|
||||
$( 'a.cancel', row ).click( function() {
|
||||
return inlineEditKey.revert();
|
||||
} );
|
||||
|
||||
$( 'a.save', row ).click( function() {
|
||||
return inlineEditKey.save( this );
|
||||
} );
|
||||
|
||||
$( 'input, select', row ).keydown( function( event ) {
|
||||
if ( 13 === event.which ) {
|
||||
return inlineEditKey.save( this );
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
toggle: function( el ) {
|
||||
var t = this;
|
||||
|
||||
if ( 'none' === $( t.what + t.getId( el ) ).css( 'display' ) ) {
|
||||
t.revert();
|
||||
} else {
|
||||
t.edit( el );
|
||||
}
|
||||
},
|
||||
|
||||
edit: function( id ) {
|
||||
var editRow, rowData, val,
|
||||
t = this;
|
||||
t.revert();
|
||||
|
||||
if ( 'object' === typeof id ) {
|
||||
id = t.getId( id );
|
||||
}
|
||||
|
||||
editRow = $( '#inline-edit' ).clone( true );
|
||||
rowData = $( '#inline_' + id );
|
||||
|
||||
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '#security-keys-section .widefat thead' ).length );
|
||||
|
||||
$( t.what + id ).hide().after( editRow ).after( '<tr class="hidden"></tr>' );
|
||||
|
||||
val = $( '.name', rowData );
|
||||
val.find( 'img' ).replaceWith( function() {
|
||||
return this.alt;
|
||||
} );
|
||||
val = val.text();
|
||||
$( ':input[name="name"]', editRow ).val( val );
|
||||
|
||||
$( editRow ).attr( 'id', 'edit-' + id ).addClass( 'inline-editor' ).show();
|
||||
$( '.ptitle', editRow ).eq( 0 ).focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
save: function( id ) {
|
||||
var params, fields;
|
||||
|
||||
if ( 'object' === typeof id ) {
|
||||
id = this.getId( id );
|
||||
}
|
||||
|
||||
$( '#security-keys-section table.widefat .spinner' ).addClass( 'is-active' );
|
||||
|
||||
params = {
|
||||
action: 'inline-save-key',
|
||||
keyHandle: id,
|
||||
user_id: window.u2fL10n.user_id
|
||||
};
|
||||
|
||||
fields = $( '#edit-' + id ).find( ':input' ).serialize();
|
||||
params = fields + '&' + $.param( params );
|
||||
|
||||
// Make ajax request.
|
||||
$.post( ajaxurl, params,
|
||||
function( r ) {
|
||||
var row, newID;
|
||||
$( '#security-keys-section table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
|
||||
if ( r ) {
|
||||
if ( -1 !== r.indexOf( '<tr' ) ) {
|
||||
$( inlineEditKey.what + id ).siblings( 'tr.hidden' ).addBack().remove();
|
||||
newID = $( r ).attr( 'id' );
|
||||
|
||||
$( '#edit-' + id ).before( r ).remove();
|
||||
|
||||
if ( newID ) {
|
||||
row = $( '#' + newID );
|
||||
} else {
|
||||
row = $( inlineEditKey.what + id );
|
||||
}
|
||||
|
||||
row.hide().fadeIn();
|
||||
} else {
|
||||
$( '#edit-' + id + ' .inline-edit-save .error' ).html( r ).show();
|
||||
}
|
||||
} else {
|
||||
$( '#edit-' + id + ' .inline-edit-save .error' ).html( inlineEditL10n.error ).show();
|
||||
}
|
||||
}
|
||||
);
|
||||
return false;
|
||||
},
|
||||
|
||||
revert: function() {
|
||||
var id = $( '#security-keys-section table.widefat tr.inline-editor' ).attr( 'id' );
|
||||
|
||||
if ( id ) {
|
||||
$( '#security-keys-section table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
$( '#' + id ).siblings( 'tr.hidden' ).addBack().remove();
|
||||
id = id.replace( /\w+\-/, '' );
|
||||
$( this.what + id ).show();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
getId: function( o ) {
|
||||
var id = 'TR' === o.tagName ? o.id : $( o ).parents( 'tr' ).attr( 'id' );
|
||||
return id.replace( /\w+\-/, '' );
|
||||
}
|
||||
};
|
||||
|
||||
$( document ).ready( function() {
|
||||
inlineEditKey.init();
|
||||
} );
|
||||
}( jQuery ) );
|
||||
@ -1,48 +0,0 @@
|
||||
/* global window, u2fL10n, jQuery */
|
||||
( function( $ ) {
|
||||
var $button = $( '#register_security_key' );
|
||||
var $statusNotice = $( '#security-keys-section .security-key-status' );
|
||||
var u2fSupported = ( window.u2f && 'register' in window.u2f );
|
||||
|
||||
if ( ! u2fSupported ) {
|
||||
$statusNotice.text( u2fL10n.text.u2f_not_supported );
|
||||
}
|
||||
|
||||
$button.click( function() {
|
||||
var registerRequest;
|
||||
|
||||
if ( $( this ).prop( 'disabled' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$( this ).prop( 'disabled', true );
|
||||
$( '.register-security-key .spinner' ).addClass( 'is-active' );
|
||||
$statusNotice.text( '' );
|
||||
|
||||
registerRequest = {
|
||||
version: u2fL10n.register.request.version,
|
||||
challenge: u2fL10n.register.request.challenge
|
||||
};
|
||||
|
||||
window.u2f.register( u2fL10n.register.request.appId, [ registerRequest ], u2fL10n.register.sigs, function( data ) {
|
||||
$( '.register-security-key .spinner' ).removeClass( 'is-active' );
|
||||
$button.prop( 'disabled', false );
|
||||
|
||||
if ( data.errorCode ) {
|
||||
if ( u2fL10n.text.error_codes[ data.errorCode ] ) {
|
||||
$statusNotice.text( u2fL10n.text.error_codes[ data.errorCode ] );
|
||||
} else {
|
||||
$statusNotice.text( u2fL10n.text.error_codes[ u2fL10n.text.error ] );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$( '#do_new_security_key' ).val( 'true' );
|
||||
$( '#u2f_response' ).val( JSON.stringify( data ) );
|
||||
|
||||
// See: http://stackoverflow.com/questions/833032/submit-is-not-a-function-error-in-javascript
|
||||
$( '<form>' )[0].submit.call( $( '#your-profile' )[0] );
|
||||
} );
|
||||
} );
|
||||
}( jQuery ) );
|
||||
@ -1,16 +0,0 @@
|
||||
/* global window, u2f, u2fL10n, jQuery */
|
||||
( function( $ ) {
|
||||
if ( ! window.u2fL10n ) {
|
||||
window.console.error( 'u2fL10n is not defined' );
|
||||
return;
|
||||
}
|
||||
|
||||
u2f.sign( u2fL10n.request[0].appId, u2fL10n.request[0].challenge, u2fL10n.request, function( data ) {
|
||||
if ( data.errorCode ) {
|
||||
window.console.error( 'Registration Failed', data.errorCode );
|
||||
} else {
|
||||
$( '#u2f_response' ).val( JSON.stringify( data ) );
|
||||
$( '#loginform' ).submit();
|
||||
}
|
||||
} );
|
||||
}( jQuery ) );
|
||||
@ -0,0 +1,35 @@
|
||||
/* global twoFactorTotpQrcode, qrcode, document, window */
|
||||
( function() {
|
||||
var qrGenerator = function() {
|
||||
/*
|
||||
* 0 = Automatically select the version, to avoid going over the limit of URL
|
||||
* length.
|
||||
* L = Least amount of error correction, because it's not needed when scanning
|
||||
* on a monitor, and it lowers the image size.
|
||||
*/
|
||||
var qr = qrcode( 0, 'L' ),
|
||||
svg,
|
||||
title;
|
||||
|
||||
qr.addData( twoFactorTotpQrcode.totpUrl );
|
||||
qr.make();
|
||||
|
||||
document.querySelector( '#two-factor-qr-code a' ).innerHTML = qr.createSvgTag( 5 );
|
||||
|
||||
// For accessibility, markup the SVG with a title and role.
|
||||
svg = document.querySelector( '#two-factor-qr-code a svg' );
|
||||
title = document.createElement( 'title' );
|
||||
|
||||
svg.setAttribute( 'role', 'img' );
|
||||
svg.setAttribute( 'aria-label', twoFactorTotpQrcode.qrCodeLabel );
|
||||
title.innerText = twoFactorTotpQrcode.qrCodeLabel;
|
||||
svg.appendChild( title );
|
||||
};
|
||||
|
||||
// Run now if the document is loaded, otherwise on DOMContentLoaded.
|
||||
if ( document.readyState === 'complete' ) {
|
||||
qrGenerator();
|
||||
} else {
|
||||
window.addEventListener( 'DOMContentLoaded', qrGenerator );
|
||||
}
|
||||
}() );
|
||||
95
wp-content/plugins/two-factor/providers/js/totp-admin.js
Normal file
95
wp-content/plugins/two-factor/providers/js/totp-admin.js
Normal file
@ -0,0 +1,95 @@
|
||||
/* global twoFactorTotpAdmin, qrcode, wp, document, jQuery */
|
||||
( function( $ ) {
|
||||
var generateQrCode = function( totpUrl ) {
|
||||
var $qrLink = $( '#two-factor-qr-code a' ),
|
||||
qr,
|
||||
svg,
|
||||
title;
|
||||
|
||||
if ( ! $qrLink.length || typeof qrcode === 'undefined' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
qr = qrcode( 0, 'L' );
|
||||
|
||||
qr.addData( totpUrl );
|
||||
qr.make();
|
||||
$qrLink.html( qr.createSvgTag( 5 ) );
|
||||
|
||||
svg = $qrLink.find( 'svg' )[ 0 ];
|
||||
if ( svg ) {
|
||||
var ariaLabel = ( typeof twoFactorTotpAdmin !== 'undefined' && twoFactorTotpAdmin && twoFactorTotpAdmin.qrCodeAriaLabel ) ? twoFactorTotpAdmin.qrCodeAriaLabel : 'Authenticator App QR Code';
|
||||
title = document.createElement( 'title' );
|
||||
svg.setAttribute( 'role', 'img' );
|
||||
svg.setAttribute( 'aria-label', ariaLabel );
|
||||
title.innerText = ariaLabel;
|
||||
svg.appendChild( title );
|
||||
}
|
||||
};
|
||||
|
||||
var checkbox = document.getElementById( 'enabled-Two_Factor_Totp' );
|
||||
|
||||
// Focus the auth code input when the checkbox is clicked.
|
||||
if ( checkbox ) {
|
||||
checkbox.addEventListener( 'click', function( e ) {
|
||||
if ( e.target.checked ) {
|
||||
document.getElementById( 'two-factor-totp-authcode' ).focus();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
$( '.totp-submit' ).click( function( e ) {
|
||||
var key = $( '#two-factor-totp-key' ).val(),
|
||||
code = $( '#two-factor-totp-authcode' ).val();
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
wp.apiRequest( {
|
||||
method: 'POST',
|
||||
path: twoFactorTotpAdmin.restPath,
|
||||
data: {
|
||||
user_id: parseInt( twoFactorTotpAdmin.userId, 10 ),
|
||||
key: key,
|
||||
code: code,
|
||||
enable_provider: true
|
||||
}
|
||||
} ).fail( function( response, status ) {
|
||||
var errorMessage = ( response && response.responseJSON && response.responseJSON.message ) || ( response && response.statusText ) || status || '',
|
||||
$error = $( '#totp-setup-error' );
|
||||
|
||||
if ( ! $error.length ) {
|
||||
$error = $( '<div class="error" id="totp-setup-error"><p></p></div>' ).insertAfter( $( '.totp-submit' ) );
|
||||
}
|
||||
|
||||
$error.find( 'p' ).text( errorMessage );
|
||||
|
||||
$( '#enabled-Two_Factor_Totp' ).prop( 'checked', false ).trigger( 'change' );
|
||||
$( '#two-factor-totp-authcode' ).val( '' );
|
||||
} ).then( function( response ) {
|
||||
$( '#enabled-Two_Factor_Totp' ).prop( 'checked', true ).trigger( 'change' );
|
||||
$( '#two-factor-totp-options' ).html( response.html );
|
||||
} );
|
||||
} );
|
||||
|
||||
$( '.button.reset-totp-key' ).click( function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
wp.apiRequest( {
|
||||
method: 'DELETE',
|
||||
path: twoFactorTotpAdmin.restPath,
|
||||
data: {
|
||||
user_id: parseInt( twoFactorTotpAdmin.userId, 10 )
|
||||
}
|
||||
} ).then( function( response ) {
|
||||
var totpUrl;
|
||||
|
||||
$( '#enabled-Two_Factor_Totp' ).prop( 'checked', false );
|
||||
$( '#two-factor-totp-options' ).html( response.html );
|
||||
|
||||
totpUrl = $( '#two-factor-qr-code a' ).attr( 'href' );
|
||||
if ( totpUrl ) {
|
||||
generateQrCode( totpUrl );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}( jQuery ) );
|
||||
@ -0,0 +1,38 @@
|
||||
/* global document */
|
||||
( function() {
|
||||
// Enforce numeric-only input for numeric inputmode elements.
|
||||
var form = document.querySelector( '#loginform' ),
|
||||
inputEl = document.querySelector( 'input.authcode[inputmode="numeric"]' ),
|
||||
expectedLength = ( inputEl && inputEl.dataset ) ? inputEl.dataset.digits : 0,
|
||||
spaceInserted = false;
|
||||
|
||||
if ( inputEl ) {
|
||||
inputEl.addEventListener(
|
||||
'input',
|
||||
function() {
|
||||
var value = this.value.replace( /[^0-9 ]/g, '' ).replace( /^\s+/, '' ),
|
||||
submitControl;
|
||||
|
||||
if ( ! spaceInserted && expectedLength && value.length === Math.floor( expectedLength / 2 ) ) {
|
||||
value += ' ';
|
||||
spaceInserted = true;
|
||||
} else if ( spaceInserted && ! this.value ) {
|
||||
spaceInserted = false;
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
|
||||
// Auto-submit if it's the expected length.
|
||||
if ( expectedLength && value.replace( / /g, '' ).length === parseInt( expectedLength, 10 ) ) {
|
||||
if ( form && typeof form.requestSubmit === 'function' ) {
|
||||
form.requestSubmit();
|
||||
submitControl = form.querySelector( '[type="submit"]' );
|
||||
if ( submitControl ) {
|
||||
submitControl.disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}() );
|
||||
@ -0,0 +1,11 @@
|
||||
/* global document, setTimeout */
|
||||
( function() {
|
||||
setTimeout( function() {
|
||||
var d;
|
||||
try {
|
||||
d = document.getElementById( 'authcode' );
|
||||
d.value = '';
|
||||
d.focus();
|
||||
} catch ( e ) {}
|
||||
}, 200 );
|
||||
}() );
|
||||
Reference in New Issue
Block a user