aboutsummaryrefslogtreecommitdiffhomepage
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/DoctrineMigrations/Version20181202073750.php76
-rw-r--r--app/Resources/static/themes/_global/index.js18
-rwxr-xr-xapp/Resources/static/themes/material/index.js5
-rw-r--r--app/config/config.yml11
-rw-r--r--app/config/routing.yml8
-rw-r--r--app/config/security.yml9
6 files changed, 125 insertions, 2 deletions
diff --git a/app/DoctrineMigrations/Version20181202073750.php b/app/DoctrineMigrations/Version20181202073750.php
new file mode 100644
index 00000000..5978291e
--- /dev/null
+++ b/app/DoctrineMigrations/Version20181202073750.php
@@ -0,0 +1,76 @@
1<?php
2
3namespace Application\Migrations;
4
5use Doctrine\DBAL\Schema\Schema;
6use Wallabag\CoreBundle\Doctrine\WallabagMigration;
7
8/**
9 * Add 2fa OTP stuff.
10 */
11final class Version20181202073750 extends WallabagMigration
12{
13 public function up(Schema $schema): void
14 {
15 switch ($this->connection->getDatabasePlatform()->getName()) {
16 case 'sqlite':
17 $this->addSql('DROP INDEX UNIQ_1D63E7E5C05FB297');
18 $this->addSql('DROP INDEX UNIQ_1D63E7E5A0D96FBF');
19 $this->addSql('DROP INDEX UNIQ_1D63E7E592FC23A8');
20 $this->addSql('CREATE TEMPORARY TABLE __temp__' . $this->getTable('user', true) . ' AS SELECT id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, twoFactorAuthentication FROM ' . $this->getTable('user', true) . '');
21 $this->addSql('DROP TABLE ' . $this->getTable('user', true) . '');
22 $this->addSql('CREATE TABLE ' . $this->getTable('user', true) . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username VARCHAR(180) NOT NULL COLLATE BINARY, username_canonical VARCHAR(180) NOT NULL COLLATE BINARY, email VARCHAR(180) NOT NULL COLLATE BINARY, email_canonical VARCHAR(180) NOT NULL COLLATE BINARY, enabled BOOLEAN NOT NULL, password VARCHAR(255) NOT NULL COLLATE BINARY, last_login DATETIME DEFAULT NULL, password_requested_at DATETIME DEFAULT NULL, name CLOB DEFAULT NULL COLLATE BINARY, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, authCode INTEGER DEFAULT NULL, emailTwoFactor BOOLEAN NOT NULL, salt VARCHAR(255) DEFAULT NULL, confirmation_token VARCHAR(180) DEFAULT NULL, roles CLOB NOT NULL --(DC2Type:array)
23 , googleAuthenticatorSecret VARCHAR(255) DEFAULT NULL, backupCodes CLOB DEFAULT NULL --(DC2Type:json_array)
24 )');
25 $this->addSql('INSERT INTO ' . $this->getTable('user', true) . ' (id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, emailTwoFactor) SELECT id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, twoFactorAuthentication FROM __temp__' . $this->getTable('user', true) . '');
26 $this->addSql('DROP TABLE __temp__' . $this->getTable('user', true) . '');
27 $this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5C05FB297 ON ' . $this->getTable('user', true) . ' (confirmation_token)');
28 $this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5A0D96FBF ON ' . $this->getTable('user', true) . ' (email_canonical)');
29 $this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E592FC23A8 ON ' . $this->getTable('user', true) . ' (username_canonical)');
30 break;
31 case 'mysql':
32 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' ADD googleAuthenticatorSecret VARCHAR(191) DEFAULT NULL');
33 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' CHANGE twoFactorAuthentication emailTwoFactor BOOLEAN NOT NULL');
34 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' DROP trusted');
35 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' ADD backupCodes LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json_array)\'');
36 break;
37 case 'postgresql':
38 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' ADD googleAuthenticatorSecret VARCHAR(191) DEFAULT NULL');
39 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' RENAME COLUMN twofactorauthentication TO emailTwoFactor');
40 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' DROP trusted');
41 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' ADD backupCodes TEXT DEFAULT NULL');
42 break;
43 }
44 }
45
46 public function down(Schema $schema): void
47 {
48 switch ($this->connection->getDatabasePlatform()->getName()) {
49 case 'sqlite':
50 $this->addSql('DROP INDEX UNIQ_1D63E7E592FC23A8');
51 $this->addSql('DROP INDEX UNIQ_1D63E7E5A0D96FBF');
52 $this->addSql('DROP INDEX UNIQ_1D63E7E5C05FB297');
53 $this->addSql('CREATE TEMPORARY TABLE __temp__' . $this->getTable('user', true) . ' AS SELECT id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, emailTwoFactor FROM "' . $this->getTable('user', true) . '"');
54 $this->addSql('DROP TABLE "' . $this->getTable('user', true) . '"');
55 $this->addSql('CREATE TABLE "' . $this->getTable('user', true) . '" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username VARCHAR(180) NOT NULL, username_canonical VARCHAR(180) NOT NULL, email VARCHAR(180) NOT NULL, email_canonical VARCHAR(180) NOT NULL, enabled BOOLEAN NOT NULL, password VARCHAR(255) NOT NULL, last_login DATETIME DEFAULT NULL, password_requested_at DATETIME DEFAULT NULL, name CLOB DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, authCode INTEGER DEFAULT NULL, twoFactorAuthentication BOOLEAN NOT NULL, salt VARCHAR(255) NOT NULL COLLATE BINARY, confirmation_token VARCHAR(255) DEFAULT NULL COLLATE BINARY, roles CLOB NOT NULL COLLATE BINARY, trusted CLOB DEFAULT NULL COLLATE BINARY)');
56 $this->addSql('INSERT INTO "' . $this->getTable('user', true) . '" (id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, twoFactorAuthentication) SELECT id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, emailTwoFactor FROM __temp__' . $this->getTable('user', true) . '');
57 $this->addSql('DROP TABLE __temp__' . $this->getTable('user', true) . '');
58 $this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E592FC23A8 ON "' . $this->getTable('user', true) . '" (username_canonical)');
59 $this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5A0D96FBF ON "' . $this->getTable('user', true) . '" (email_canonical)');
60 $this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5C05FB297 ON "' . $this->getTable('user', true) . '" (confirmation_token)');
61 break;
62 case 'mysql':
63 $this->addSql('ALTER TABLE `' . $this->getTable('user') . '` DROP googleAuthenticatorSecret');
64 $this->addSql('ALTER TABLE `' . $this->getTable('user') . '` CHANGE emailtwofactor twoFactorAuthentication BOOLEAN NOT NULL');
65 $this->addSql('ALTER TABLE `' . $this->getTable('user') . '` ADD trusted TEXT DEFAULT NULL');
66 $this->addSql('ALTER TABLE `' . $this->getTable('user') . '` DROP backupCodes');
67 break;
68 case 'postgresql':
69 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' DROP googleAuthenticatorSecret');
70 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' RENAME COLUMN emailTwoFactor TO twofactorauthentication');
71 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' ADD trusted TEXT DEFAULT NULL');
72 $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' DROP backupCodes');
73 break;
74 }
75 }
76}
diff --git a/app/Resources/static/themes/_global/index.js b/app/Resources/static/themes/_global/index.js
index bb3e95b6..9ad96fc0 100644
--- a/app/Resources/static/themes/_global/index.js
+++ b/app/Resources/static/themes/_global/index.js
@@ -89,4 +89,22 @@ $(document).ready(() => {
89 } 89 }
90 }; 90 };
91 }); 91 });
92
93 // mimic radio button because emailTwoFactor is a boolean
94 $('#update_user_googleTwoFactor').on('change', () => {
95 $('#update_user_emailTwoFactor').prop('checked', false);
96 });
97
98 $('#update_user_emailTwoFactor').on('change', () => {
99 $('#update_user_googleTwoFactor').prop('checked', false);
100 });
101
102 // same mimic for super admin
103 $('#user_googleTwoFactor').on('change', () => {
104 $('#user_emailTwoFactor').prop('checked', false);
105 });
106
107 $('#user_emailTwoFactor').on('change', () => {
108 $('#user_googleTwoFactor').prop('checked', false);
109 });
92}); 110});
diff --git a/app/Resources/static/themes/material/index.js b/app/Resources/static/themes/material/index.js
index 05794597..2926cad1 100755
--- a/app/Resources/static/themes/material/index.js
+++ b/app/Resources/static/themes/material/index.js
@@ -50,25 +50,30 @@ $(document).ready(() => {
50 $('#tag_label').focus(); 50 $('#tag_label').focus();
51 return false; 51 return false;
52 }); 52 });
53
53 $('#nav-btn-add').on('click', () => { 54 $('#nav-btn-add').on('click', () => {
54 toggleNav('.nav-panel-add', '#entry_url'); 55 toggleNav('.nav-panel-add', '#entry_url');
55 return false; 56 return false;
56 }); 57 });
58
57 const materialAddForm = $('.nav-panel-add'); 59 const materialAddForm = $('.nav-panel-add');
58 materialAddForm.on('submit', () => { 60 materialAddForm.on('submit', () => {
59 materialAddForm.addClass('disabled'); 61 materialAddForm.addClass('disabled');
60 $('input#entry_url', materialAddForm).prop('readonly', true).trigger('blur'); 62 $('input#entry_url', materialAddForm).prop('readonly', true).trigger('blur');
61 }); 63 });
64
62 $('#nav-btn-search').on('click', () => { 65 $('#nav-btn-search').on('click', () => {
63 toggleNav('.nav-panel-search', '#search_entry_term'); 66 toggleNav('.nav-panel-search', '#search_entry_term');
64 return false; 67 return false;
65 }); 68 });
69
66 $('.close').on('click', (e) => { 70 $('.close').on('click', (e) => {
67 $(e.target).parent('.nav-panel-item').hide(100); 71 $(e.target).parent('.nav-panel-item').hide(100);
68 $('.nav-panel-actions').show(100); 72 $('.nav-panel-actions').show(100);
69 $('.nav-panels').css('background', 'transparent'); 73 $('.nav-panels').css('background', 'transparent');
70 return false; 74 return false;
71 }); 75 });
76
72 $(window).scroll(() => { 77 $(window).scroll(() => {
73 const s = $(window).scrollTop(); 78 const s = $(window).scrollTop();
74 const d = $(document).height(); 79 const d = $(document).height();
diff --git a/app/config/config.yml b/app/config/config.yml
index 4b34af30..2d8f9bf0 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -198,10 +198,17 @@ fos_oauth_server:
198 refresh_token_lifetime: 1209600 198 refresh_token_lifetime: 1209600
199 199
200scheb_two_factor: 200scheb_two_factor:
201 trusted_computer: 201 trusted_device:
202 enabled: true 202 enabled: true
203 cookie_name: wllbg_trusted_computer 203 cookie_name: wllbg_trusted_computer
204 cookie_lifetime: 2592000 204 lifetime: 2592000
205
206 backup_codes:
207 enabled: "%twofactor_auth%"
208
209 google:
210 enabled: "%twofactor_auth%"
211 template: WallabagUserBundle:Authentication:form.html.twig
205 212
206 email: 213 email:
207 enabled: "%twofactor_auth%" 214 enabled: "%twofactor_auth%"
diff --git a/app/config/routing.yml b/app/config/routing.yml
index 0bd2d130..a7c0f7e9 100644
--- a/app/config/routing.yml
+++ b/app/config/routing.yml
@@ -51,3 +51,11 @@ craue_config_settings_modify:
51 51
52fos_js_routing: 52fos_js_routing:
53 resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml" 53 resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
54
552fa_login:
56 path: /2fa
57 defaults:
58 _controller: "scheb_two_factor.form_controller:form"
59
602fa_login_check:
61 path: /2fa_check
diff --git a/app/config/security.yml b/app/config/security.yml
index 96489e26..6a21b4e5 100644
--- a/app/config/security.yml
+++ b/app/config/security.yml
@@ -56,9 +56,17 @@ security:
56 path: /logout 56 path: /logout
57 target: / 57 target: /
58 58
59 two_factor:
60 provider: fos_userbundle
61 auth_form_path: 2fa_login
62 check_path: 2fa_login_check
63
59 access_control: 64 access_control:
60 - { path: ^/api/(doc|version|info|user), roles: IS_AUTHENTICATED_ANONYMOUSLY } 65 - { path: ^/api/(doc|version|info|user), roles: IS_AUTHENTICATED_ANONYMOUSLY }
61 - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 66 - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
67 # force role for logout otherwise when 2fa enable, you won't be able to logout
68 # https://github.com/scheb/two-factor-bundle/issues/168#issuecomment-430822478
69 - { path: ^/logout, roles: [IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_2FA_IN_PROGRESS] }
62 - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY } 70 - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
63 - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY } 71 - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
64 - { path: /(unread|starred|archive|all).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY } 72 - { path: /(unread|starred|archive|all).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
@@ -67,5 +75,6 @@ security:
67 - { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY } 75 - { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY }
68 - { path: ^/settings, roles: ROLE_SUPER_ADMIN } 76 - { path: ^/settings, roles: ROLE_SUPER_ADMIN }
69 - { path: ^/annotations, roles: ROLE_USER } 77 - { path: ^/annotations, roles: ROLE_USER }
78 - { path: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
70 - { path: ^/users, roles: ROLE_SUPER_ADMIN } 79 - { path: ^/users, roles: ROLE_SUPER_ADMIN }
71 - { path: ^/, roles: ROLE_USER } 80 - { path: ^/, roles: ROLE_USER }