From b760e3f6e4651000e1f7cb7c685ef08ab27b111f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Tisza?= Date: Sat, 4 May 2024 20:37:39 +0200 Subject: [PATCH] Add download link for recovery codes Bug: T245027 Change-Id: I558fa2aaed90afee8488f8b68c71959e3c75331d --- extension.json | 8 ++++++- i18n/en.json | 1 + i18n/qqq.json | 1 + modules/totp/ext.oath.showqrcode.styles.css | 9 -------- modules/totp/ext.oath.showqrcode.styles.less | 18 +++++++++++++++ src/HTMLForm/TOTPEnableForm.php | 24 +++++++++++++++++++- 6 files changed, 50 insertions(+), 11 deletions(-) delete mode 100644 modules/totp/ext.oath.showqrcode.styles.css create mode 100644 modules/totp/ext.oath.showqrcode.styles.less diff --git a/extension.json b/extension.json index a4733c18..a5d4b251 100644 --- a/extension.json +++ b/extension.json @@ -102,8 +102,14 @@ }, "ResourceModules": { "ext.oath.totp.showqrcode.styles": { + "class": "MediaWiki\\ResourceLoader\\CodexModule", "styles": [ - "totp/ext.oath.showqrcode.styles.css" + "totp/ext.oath.showqrcode.styles.less" + ], + "codexStyleOnly": "true", + "codexComponents": [ + "CdxButton", + "CdxIcon" ] } }, diff --git a/i18n/en.json b/i18n/en.json index 6e5a39e5..c90709a1 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -14,6 +14,7 @@ "oathauth-enable": "Enable two-factor authentication", "oathauth-recoverycodes": "The following list is a list of one-time use recovery codes. These codes can only be used once, and are for emergency use when you don't have access to your device. Please write these down and keep them in a secure location. It is recommended that you mark each code as used when you have logged in using it. If you lose your device, these codes are the only way to rescue your account.\n\n'''These codes will never be shown again'''.", "oathauth-recoverycodes-important": "This step is important! Do not skip this step!", + "oathauth-recoverycodes-download": "Download recovery codes", "oathauth-disable": "Disable two-factor authentication", "oathauth-validatedoath": "Validated two-factor credentials. Two-factor authentication will now be enforced.", "oathauth-noscratchforvalidation": "You cannot use a recovery code to confirm two-factor authentication. Recovery codes are for backup and incidental use only. Please use a code from your two-factor authentication application (such as Google Authenticator).", diff --git a/i18n/qqq.json b/i18n/qqq.json index fe35c763..1042e79e 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -29,6 +29,7 @@ "oathauth-enable": "Page title on Special:OATH, when enabling OATH.\n\nSee [https://en.wikipedia.org/wiki/Two_factor_authentication two factor authentication]", "oathauth-recoverycodes": "Plain text, found on Special:OATH while enabling OATH.", "oathauth-recoverycodes-important": "Plain text, found on Special:OATH while enabling OATH.", + "oathauth-recoverycodes-download": "Plain text, text of the download link on Special:OATH while enabling OATH.", "oathauth-disable": "Page title on Special:OATH while disabling OATH.\n\nSee [https://en.wikipedia.org/wiki/Two_factor_authentication two factor authentication]", "oathauth-validatedoath": "Plain text found on Special:OATH after a token has been validated.\n\nSee [https://en.wikipedia.org/wiki/Two_factor_authentication two factor authentication]", "oathauth-noscratchforvalidation": "Plain text found on Special:OATH if the user used the incorrect type of token while enabling OATH.\n\nSee [https://en.wikipedia.org/wiki/Two_factor_authentication two factor authentication]", diff --git a/modules/totp/ext.oath.showqrcode.styles.css b/modules/totp/ext.oath.showqrcode.styles.css deleted file mode 100644 index 62afabef..00000000 --- a/modules/totp/ext.oath.showqrcode.styles.css +++ /dev/null @@ -1,9 +0,0 @@ -kbd { - font-family: monospace, monospace; - white-space: nowrap; - font-size: larger; -} - -fieldset { - page-break-inside: avoid; -} diff --git a/modules/totp/ext.oath.showqrcode.styles.less b/modules/totp/ext.oath.showqrcode.styles.less new file mode 100644 index 00000000..0484f947 --- /dev/null +++ b/modules/totp/ext.oath.showqrcode.styles.less @@ -0,0 +1,18 @@ +@import "mediawiki.skin.variables.less"; + +kbd { + font-family: monospace, monospace; + white-space: nowrap; + font-size: larger; +} + +fieldset { + page-break-inside: avoid; +} + +.cdx-button.mw-oathauth-recoverycodes-download { + margin-top: 1em; +} +.mw-oathauth-recoverycodes-download-icon { + .cdx-mixin-css-icon( @cdx-icon-download, @param-is-button-icon: true ); +} diff --git a/src/HTMLForm/TOTPEnableForm.php b/src/HTMLForm/TOTPEnableForm.php index d79137c7..2b391026 100644 --- a/src/HTMLForm/TOTPEnableForm.php +++ b/src/HTMLForm/TOTPEnableForm.php @@ -105,7 +105,8 @@ class TOTPEnableForm extends OATHAuthOOUIHTMLForm { 'default' => '' . $this->msg( 'oathauth-recoverycodes-important' )->escaped() . '
' . $this->msg( 'oathauth-recoverycodes' )->parse() - . $this->createResourceList( $this->getScratchTokensForDisplay( $key ) ), + . $this->createResourceList( $this->getScratchTokensForDisplay( $key ) ) + . $this->createDownloadLink( $this->getScratchTokensForDisplay( $key ) ), 'raw' => true, 'section' => 'step3', ], @@ -134,6 +135,27 @@ class TOTPEnableForm extends OATHAuthOOUIHTMLForm { return Html::rawElement( 'ul', [], $resourceList ); } + private function createDownloadLink( array $scratchTokensForDisplay ): string { + $icon = Html::element( 'span', [ + 'class' => [ 'mw-oathauth-recoverycodes-download-icon', 'cdx-button__icon' ], + 'aria-hidden' => 'true', + ] ); + return Html::rawElement( + 'a', + [ + 'href' => 'data:text/plain;charset=utf-8,' + // https://bugzilla.mozilla.org/show_bug.cgi?id=1895687 + . rawurlencode( implode( PHP_EOL, $scratchTokensForDisplay ) ), + 'download' => 'recovery-codes.txt', + 'class' => [ + 'mw-oathauth-recoverycodes-download', + 'cdx-button', 'cdx-button--fake-button', 'cdx-button--fake-button--enabled', + ], + ], + $icon . $this->msg( 'oathauth-recoverycodes-download' )->escaped() + ); + } + /** * Retrieve the current secret for display purposes *