diff --git a/composer.json b/composer.json index 9f41333..075840b 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "require": { - "christian-riesen/otp": "1.*" + "christian-riesen/otp": "1.*", + "endroid/qrcode": "^1.7" } } diff --git a/composer.lock b/composer.lock index 0ad65ea..8b12acb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "67d801295df32f7541a878252e8a72d7", - "content-hash": "3ecd28d69556d0f4621b7b7bb4f96bb6", + "hash": "544fb333da3676eccc95c69b5417a2cf", + "content-hash": "0b92e480772ba07f8827be4e0efd1c94", "packages": [ { "name": "christian-riesen/base32", @@ -111,6 +111,111 @@ "totp" ], "time": "2015-10-08 08:17:59" + }, + { + "name": "endroid/qrcode", + "version": "1.7.2", + "source": { + "type": "git", + "url": "https://github.com/endroid/QrCode.git", + "reference": "4638f11b6944cccce997db7fa7508b5a7ad1a61b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/endroid/QrCode/zipball/4638f11b6944cccce997db7fa7508b5a7ad1a61b", + "reference": "4638f11b6944cccce997db7fa7508b5a7ad1a61b", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "php": ">=5.3.0", + "symfony/options-resolver": "^2.3|^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl", + "homepage": "http://endroid.nl/" + } + ], + "description": "Endroid QR Code", + "homepage": "https://github.com/endroid/QrCode", + "keywords": [ + "code", + "endroid", + "qr", + "qrcode" + ], + "time": "2016-05-31 12:48:19" + }, + { + "name": "symfony/options-resolver", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "30605874d99af0cde6c41fd39e18546330c38100" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/30605874d99af0cde6c41fd39e18546330c38100", + "reference": "30605874d99af0cde6c41fd39e18546330c38100", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2016-05-12 15:59:27" } ], "packages-dev": [], diff --git a/js/settingsview.js b/js/settingsview.js index 7da1397..ce3fda5 100644 --- a/js/settingsview.js +++ b/js/settingsview.js @@ -7,14 +7,17 @@ OC.Settings.TwoFactorTotp = OC.Settings.TwoFactorTotp || {}; var TEMPLATE = '
' - + '' - + '' + + ' ' + + ' ' + '
' - + '{{#if qr}}' + + '{{#if secret}}' + + '
' + + ' ' + t('twofactor_totp', 'This is your new TOTP secret:') + ' {{secret}}' + + '
' + '
' - + 'Scan QR code with your TOTP app
' - + '' + + '
' + '{{/if}}'; var View = Backbone.View.extend({ @@ -68,7 +71,7 @@ var _this = this; $.when(updating).done(function(data) { _this._enabled = data.enabled; - _this._showQr(data.qr); + _this._showQr(data); _this.$('#totp-enabled').attr('checked', data.enabled); }); $.when(updating).always(function () { @@ -77,9 +80,10 @@ this._enabled = enabled; } }, - _showQr: function(qr) { + _showQr: function(data) { this.render({ - qr: qr + secret: data.secret, + qr: data.qr }); } }); diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index ef0be0e..1d93beb 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -21,6 +21,7 @@ namespace OCA\TwoFactor_Totp\Controller; +use Endroid\QrCode\QrCode; use OCA\TwoFactor_Totp\Service\ITotp; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; @@ -29,55 +30,61 @@ use OCP\IUserSession; class SettingsController extends Controller { - /** @var ITotp */ - private $totp; + /** @var ITotp */ + private $totp; - /** @var IUserSession */ - private $userSession; + /** @var IUserSession */ + private $userSession; - /** - * @param string $appName - * @param IRequest $request - * @param IUserSession $userSession - * @param ITotp $totp - */ - public function __construct($appName, IRequest $request, IUserSession $userSession, ITotp $totp) { - parent::__construct($appName, $request); - $this->userSession = $userSession; - $this->totp = $totp; - } + /** + * @param string $appName + * @param IRequest $request + * @param IUserSession $userSession + * @param ITotp $totp + */ + public function __construct($appName, IRequest $request, IUserSession $userSession, ITotp $totp) { + parent::__construct($appName, $request); + $this->userSession = $userSession; + $this->totp = $totp; + } - /** - * @NoAdminRequired - * @return JSONResponse - */ - public function state() { - $user = $this->userSession->getUser(); - return [ - 'enabled' => $this->totp->hasSecret($user), - ]; - } + /** + * @NoAdminRequired + * @return JSONResponse + */ + public function state() { + $user = $this->userSession->getUser(); + return [ + 'enabled' => $this->totp->hasSecret($user), + ]; + } - /** - * @NoAdminRequired - * @param bool $state - * @return JSONResponse - */ - public function enable($state) { - $user = $this->userSession->getUser(); - if ($state) { - $qr = $this->totp->createSecret($user); - return [ - 'enabled' => true, - 'qr' => $qr, - ]; - } + /** + * @NoAdminRequired + * @param bool $state + * @return JSONResponse + */ + public function enable($state) { + $user = $this->userSession->getUser(); + if ($state) { + $secret = $this->totp->createSecret($user); + + $qrCode = new QrCode(); + $qr = $qrCode->setText("otpauth://totp/ownCloud%20TOTP?secret=$secret") + ->setSize(150) + ->getDataUri(); + return [ + 'enabled' => true, + 'secret' => $secret, + 'qr' => $qr, + ]; + } - $this->totp->deleteSecret($user); - return [ - 'enabled' => false, - 'qr' => null, - ]; - } + $this->totp->deleteSecret($user); + return [ + 'enabled' => false, + 'qr' => null, + ]; + } } diff --git a/lib/Service/ITotp.php b/lib/Service/ITotp.php index 5923088..81bd501 100644 --- a/lib/Service/ITotp.php +++ b/lib/Service/ITotp.php @@ -33,6 +33,7 @@ interface ITotp { /** * @param IUser $user + * @return string the newly created secret * @throws TotpSecretAlreadySet */ public function createSecret(IUser $user); diff --git a/lib/Service/Totp.php b/lib/Service/Totp.php index ec59ef5..e684a60 100644 --- a/lib/Service/Totp.php +++ b/lib/Service/Totp.php @@ -67,7 +67,7 @@ class Totp implements ITotp { $this->secretMapper->insert($dbSecret); - return GoogleAuthenticator::getQrCodeUrl('totp', 'ownCloud TOTP', $secret); + return $secret; } public function deleteSecret(IUser $user) {