mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/OATHAuth
synced 2024-11-23 15:56:59 +00:00
Switch from client- to server-side generated QR codes
Use the same PHP library as UrlShortener (endroid/qr-code) to generate QR codes, rather than the out-of-date JS library. Bug: T348590 Change-Id: I560ac1b384e249aad1866752deac753c764ec553
This commit is contained in:
parent
972c9bc00f
commit
fbe2f875c4
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"require": {
|
||||
"christian-riesen/base32": "^1.4.0",
|
||||
"endroid/qr-code": "4.5.2",
|
||||
"jakobo/hotp-php": "2.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
|
@ -100,17 +100,6 @@
|
|||
}
|
||||
},
|
||||
"ResourceModules": {
|
||||
"ext.oath.totp.showqrcode": {
|
||||
"scripts": [
|
||||
"totp/jquery.qrcode.js",
|
||||
"totp/qrcode.js",
|
||||
"totp/ext.oath.showqrcode.js"
|
||||
],
|
||||
"targets": [
|
||||
"desktop",
|
||||
"mobile"
|
||||
]
|
||||
},
|
||||
"ext.oath.totp.showqrcode.styles": {
|
||||
"styles": [
|
||||
"totp/ext.oath.showqrcode.styles.css"
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
$( function () {
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
var $elm = $( '.mw-display-qrcode' );
|
||||
$elm.qrcode( $elm.data( 'mw-qrcode-url' ) );
|
||||
} );
|
|
@ -1,7 +1,3 @@
|
|||
.client-nojs .mw-display-qrcode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
kbd {
|
||||
font-family: monospace, monospace;
|
||||
white-space: nowrap;
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
/* global QRCode, QRErrorCorrectLevel */
|
||||
|
||||
( function () {
|
||||
$.fn.qrcode = function ( options ) {
|
||||
var createCanvas, createTable;
|
||||
|
||||
// if options is string,
|
||||
if ( typeof options === 'string' ) {
|
||||
options = { text: options };
|
||||
}
|
||||
|
||||
// set default values
|
||||
// typeNumber < 1 for automatic calculation
|
||||
options = $.extend( {}, {
|
||||
render: 'canvas',
|
||||
width: 256,
|
||||
height: 256,
|
||||
typeNumber: -1,
|
||||
correctLevel: QRErrorCorrectLevel.H,
|
||||
background: '#ffffff',
|
||||
foreground: '#000000'
|
||||
}, options );
|
||||
|
||||
createCanvas = function () {
|
||||
var qrcode, canvas, ctx, tileW, tileH, row, col, w, h;
|
||||
|
||||
// create the qrcode itself
|
||||
qrcode = new QRCode( options.typeNumber, options.correctLevel );
|
||||
qrcode.addData( options.text );
|
||||
qrcode.make();
|
||||
|
||||
// create canvas element
|
||||
canvas = document.createElement( 'canvas' );
|
||||
canvas.width = options.width;
|
||||
canvas.height = options.height;
|
||||
ctx = canvas.getContext( '2d' );
|
||||
|
||||
// compute tileW/tileH based on options.width/options.height
|
||||
tileW = options.width / qrcode.getModuleCount();
|
||||
tileH = options.height / qrcode.getModuleCount();
|
||||
|
||||
// draw in the canvas
|
||||
for ( row = 0; row < qrcode.getModuleCount(); row++ ) {
|
||||
for ( col = 0; col < qrcode.getModuleCount(); col++ ) {
|
||||
ctx.fillStyle = qrcode.isDark( row, col ) ?
|
||||
options.foreground :
|
||||
options.background;
|
||||
|
||||
w = ( Math.ceil( ( col + 1 ) * tileW ) - Math.floor( col * tileW ) );
|
||||
h = ( Math.ceil( ( row + 1 ) * tileW ) - Math.floor( row * tileW ) );
|
||||
ctx.fillRect( Math.round( col * tileW ), Math.round( row * tileH ), w, h );
|
||||
}
|
||||
}
|
||||
// return just built canvas
|
||||
return canvas;
|
||||
};
|
||||
|
||||
// from Jon-Carlos Rivera (https://github.com/imbcmdth)
|
||||
createTable = function () {
|
||||
var qrcode, $table, tileW, tileH, row, col, $row;
|
||||
|
||||
// create the qrcode itself
|
||||
qrcode = new QRCode( options.typeNumber, options.correctLevel );
|
||||
qrcode.addData( options.text );
|
||||
qrcode.make();
|
||||
|
||||
// create table element
|
||||
$table = $( '<table>' )
|
||||
.css( 'width', options.width + 'px' )
|
||||
.css( 'height', options.height + 'px' )
|
||||
.css( 'border', '0' )
|
||||
.css( 'border-collapse', 'collapse' )
|
||||
.css( 'background-color', options.background );
|
||||
|
||||
// compute tileS percentage
|
||||
tileW = options.width / qrcode.getModuleCount();
|
||||
tileH = options.height / qrcode.getModuleCount();
|
||||
|
||||
// draw in the table
|
||||
for ( row = 0; row < qrcode.getModuleCount(); row++ ) {
|
||||
$row = $( '<tr>' ).css( 'height', tileH + 'px' ).appendTo( $table );
|
||||
|
||||
for ( col = 0; col < qrcode.getModuleCount(); col++ ) {
|
||||
$( '<td>' )
|
||||
.css( 'width', tileW + 'px' )
|
||||
.css( 'background-color', qrcode.isDark( row, col ) ? options.foreground : options.background )
|
||||
.appendTo( $row );
|
||||
}
|
||||
}
|
||||
// return just built canvas
|
||||
return $table;
|
||||
};
|
||||
|
||||
return this.each( function () {
|
||||
var element = options.render === 'canvas' ? createCanvas() : createTable();
|
||||
$( element ).appendTo( this );
|
||||
} );
|
||||
};
|
||||
}() );
|
File diff suppressed because it is too large
Load diff
|
@ -3,6 +3,11 @@
|
|||
namespace MediaWiki\Extension\OATHAuth\HTMLForm;
|
||||
|
||||
use ConfigException;
|
||||
use Endroid\QrCode\Builder\Builder;
|
||||
use Endroid\QrCode\Encoding\Encoding;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeNone;
|
||||
use Endroid\QrCode\Writer\SvgWriter;
|
||||
use Html;
|
||||
use MediaWiki\Extension\OATHAuth\Key\TOTPKey;
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
|
@ -15,7 +20,6 @@ class TOTPEnableForm extends OATHAuthOOUIHTMLForm {
|
|||
* @return string
|
||||
*/
|
||||
public function getHTML( $submitResult ) {
|
||||
$this->getOutput()->addModules( 'ext.oath.totp.showqrcode' );
|
||||
$this->getOutput()->addModuleStyles( 'ext.oath.totp.showqrcode.styles' );
|
||||
|
||||
return parent::getHTML( $submitResult );
|
||||
|
@ -51,13 +55,16 @@ class TOTPEnableForm extends OATHAuthOOUIHTMLForm {
|
|||
. "&issuer="
|
||||
. rawurlencode( $this->oathUser->getIssuer() );
|
||||
|
||||
$qrcodeElement = Html::element( 'div', [
|
||||
'data-mw-qrcode-url' => $qrcodeUrl,
|
||||
'class' => 'mw-display-qrcode',
|
||||
// Include width/height, so js won't re-arrange layout
|
||||
// And non-js users will have this hidden with CSS
|
||||
'style' => 'width: 256px; height: 256px;'
|
||||
] );
|
||||
$qrCode = Builder::create()
|
||||
->writer( new SvgWriter() )
|
||||
->writerOptions( [ SvgWriter::WRITER_OPTION_EXCLUDE_XML_DECLARATION => true ] )
|
||||
->data( $qrcodeUrl )
|
||||
->encoding( new Encoding( 'UTF-8' ) )
|
||||
->errorCorrectionLevel( new ErrorCorrectionLevelHigh() )
|
||||
->roundBlockSizeMode( new RoundBlockSizeModeNone() )
|
||||
->size( 256 )
|
||||
->margin( 0 )
|
||||
->build();
|
||||
|
||||
return [
|
||||
'app' => [
|
||||
|
@ -68,7 +75,7 @@ class TOTPEnableForm extends OATHAuthOOUIHTMLForm {
|
|||
],
|
||||
'qrcode' => [
|
||||
'type' => 'info',
|
||||
'default' => $qrcodeElement,
|
||||
'default' => $qrCode->getString(),
|
||||
'raw' => true,
|
||||
'section' => 'step2',
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue