updated plugin Two Factor version 0.16.0

This commit is contained in:
2026-06-03 21:29:19 +00:00
committed by Gitium
parent bc89bee944
commit 57bccfdbd1
33 changed files with 1920 additions and 2942 deletions

View File

@ -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 ) );

View File

@ -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 ) );

View File

@ -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 ) );

View File

@ -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 ) );

View File

@ -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 );
}
}() );

View 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 ) );

View File

@ -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;
}
}
}
}
);
}
}() );

View File

@ -0,0 +1,11 @@
/* global document, setTimeout */
( function() {
setTimeout( function() {
var d;
try {
d = document.getElementById( 'authcode' );
d.value = '';
d.focus();
} catch ( e ) {}
}, 200 );
}() );