diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 3bf1da1cc86ac2129fb6878e5633be945e0d0a52..525e72334c7ffb57f8e03898ebcc8d4ef829e2ae 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -6,6 +6,29 @@ All notable changes to this project will be documented in this file.
 The format is based on `Keep a Changelog`_,
 and this project adheres to `Semantic Versioning`_.
 
+`2.0b2` - 2021-06-15
+--------------------
+
+Changed
+~~~~~~~
+
+* Add verbose names for all preference sections.
+* Add verbose names for all openid connect scopes and show them in grant
+  view.
+* Include public dashboard in navigation
+* Update German translations.
+
+Fixed
+~~~~~
+
+* Fix broken backup health check
+* Make error recovery in about page work
+
+Removed
+~~~~~~~
+
+* Drop all leftovers of DataTables.
+
 `2.0b1`_ - 2021-06-01
 ---------------------
 
@@ -229,3 +252,4 @@ Fixed
 .. _2.0a2: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.0a2
 .. _2.0b0: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.0b0
 .. _2.0b1: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.0b1
+.. _2.0b2: https://edugit.org/AlekSIS/Official/AlekSIS/-/tags/2.0b2
diff --git a/aleksis/core/health_checks.py b/aleksis/core/health_checks.py
index c3ad7b4b17a944acf9f2af00a0c461e958e140d8..200a6eaf0a35a75c29ca4cf7e8c564925b1e29e8 100644
--- a/aleksis/core/health_checks.py
+++ b/aleksis/core/health_checks.py
@@ -38,9 +38,9 @@ class BaseBackupHealthCheck(BaseHealthCheckBackend):
             self.add_error(_("The backup folder doesn't exist."))
             return
         if backups:
-            last_backup = backups[-1]
-            last_backup_time = dbbackup_utils.filename_to_date(last_backup)
-            time_gone_since_backup = last_backup_time - datetime.now()
+            last_backup = backups[:1]
+            last_backup_time = dbbackup_utils.filename_to_date(last_backup[0])
+            time_gone_since_backup = datetime.now() - last_backup_time
 
             # Check if backup is older than configured time
             if time_gone_since_backup.seconds > self.configured_seconds:
diff --git a/aleksis/core/locale/ar/LC_MESSAGES/django.po b/aleksis/core/locale/ar/LC_MESSAGES/django.po
index 08b161b39d2f0d6e24bd6cac0c5d1873713d7952..7b8eb8f9b3ab37aef635e2885704e8e091105f32 100644
--- a/aleksis/core/locale/ar/LC_MESSAGES/django.po
+++ b/aleksis/core/locale/ar/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: AlekSIS (School Information System) 0.1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -261,11 +261,13 @@ msgid "Preferences"
 msgstr ""
 
 #: aleksis/core/menus.py:97
-msgid "Social accounts"
+msgid "Third-party accounts"
 msgstr ""
 
 #: aleksis/core/menus.py:106
-msgid "Authorized tokens"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
+msgid "Authorized applications"
 msgstr ""
 
 #: aleksis/core/menus.py:117
@@ -355,7 +357,7 @@ msgstr ""
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:476
+#: aleksis/core/mixins.py:475
 msgid "Linked school term"
 msgstr ""
 
@@ -904,139 +906,143 @@ msgstr ""
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:39
+#: aleksis/core/preferences.py:41
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:48
+#: aleksis/core/preferences.py:52
 msgid "Site description"
 msgstr ""
 
-#: aleksis/core/preferences.py:57
+#: aleksis/core/preferences.py:63
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:67
+#: aleksis/core/preferences.py:75
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:86
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:84
+#: aleksis/core/preferences.py:96
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:92
+#: aleksis/core/preferences.py:106
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:101
+#: aleksis/core/preferences.py:117
 msgid "Mail out name"
 msgstr ""
 
-#: aleksis/core/preferences.py:110
+#: aleksis/core/preferences.py:128
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:120
+#: aleksis/core/preferences.py:140
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:130
+#: aleksis/core/preferences.py:152
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:140
+#: aleksis/core/preferences.py:164
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:154
+#: aleksis/core/preferences.py:180
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:164
+#: aleksis/core/preferences.py:192
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:173
+#: aleksis/core/preferences.py:203
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:185
+#: aleksis/core/preferences.py:215
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:194
+#: aleksis/core/preferences.py:224
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:203
+#: aleksis/core/preferences.py:235
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:212
+#: aleksis/core/preferences.py:246
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:220
+#: aleksis/core/preferences.py:256
+msgid "Enabled custom authentication backends"
+msgstr ""
+
+#: aleksis/core/preferences.py:268
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:228
+#: aleksis/core/preferences.py:276
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:237
+#: aleksis/core/preferences.py:287
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:249
+#: aleksis/core/preferences.py:299
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:260
+#: aleksis/core/preferences.py:310
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:271
+#: aleksis/core/preferences.py:321
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:280
+#: aleksis/core/preferences.py:330
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:289
+#: aleksis/core/preferences.py:339
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:300
+#: aleksis/core/preferences.py:350
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:314
+#: aleksis/core/preferences.py:364
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:327
+#: aleksis/core/preferences.py:377
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:337
+#: aleksis/core/preferences.py:387
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:338
+#: aleksis/core/preferences.py:388
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/settings.py:477
+#: aleksis/core/settings.py:470
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:478
+#: aleksis/core/settings.py:471
 msgid "German"
 msgstr ""
 
@@ -2110,25 +2116,20 @@ msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:5
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:6
-msgid "Revoke token"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
+msgid "Revoke access"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:12
-msgid "Are you sure to revoke this token?"
+msgid "Are you sure to revoke the access for this application?"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:20
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
 msgid "Revoke"
 msgstr ""
 
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
-msgid "Authorized applications"
-msgstr ""
-
 #: aleksis/core/templates/oauth2_provider/authorized-tokens.html:33
-msgid "No authorized tokens defined."
+msgid "No authorized applications."
 msgstr ""
 
 #: aleksis/core/templates/offline.html:5
@@ -2172,17 +2173,17 @@ msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:5
 #: aleksis/core/templates/socialaccount/authentication_error.html:6
-msgid "Social Network Login Failure"
+msgid "Third-party Account Login Failure"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:13
-msgid "Social Network Login Failure."
+msgid "Third-party Account Login Failure."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:15
 msgid ""
 "\n"
-"            An error occurred while attempting to login via your social network account.\n"
+"            An error occurred while attempting to login via your third-party account.\n"
 "            Please contact one of your site administrators.\n"
 "          "
 msgstr ""
@@ -2197,11 +2198,11 @@ msgid "Remove"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:34
-msgid "You currently have no social network accounts connected to this account."
+msgid "You currently have no third-party accounts connected to this account."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:37
-msgid "Add a 3rd Party Account"
+msgid "Add a Third-party Account"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/login_cancelled.html:5
@@ -2244,7 +2245,7 @@ msgstr ""
 #: aleksis/core/templates/socialaccount/snippets/provider_list.html:30
 msgid ""
 "\n"
-"          No 3rd party account providers available.\n"
+"          No third-party account providers available.\n"
 "        "
 msgstr ""
 
@@ -2709,107 +2710,107 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:195
+#: aleksis/core/views.py:249
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:207
+#: aleksis/core/views.py:261
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:352
+#: aleksis/core/views.py:406
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:413
+#: aleksis/core/views.py:467
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:452
+#: aleksis/core/views.py:506
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:549
+#: aleksis/core/views.py:603
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:565
+#: aleksis/core/views.py:619
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:649
+#: aleksis/core/views.py:703
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:673
+#: aleksis/core/views.py:727
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:687
+#: aleksis/core/views.py:741
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:719
+#: aleksis/core/views.py:773
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:753
+#: aleksis/core/views.py:807
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:778
+#: aleksis/core/views.py:832
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:808
+#: aleksis/core/views.py:862
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:895
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:842
+#: aleksis/core/views.py:896
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:843
+#: aleksis/core/views.py:897
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:844
+#: aleksis/core/views.py:898
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:860
+#: aleksis/core/views.py:914
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:902
+#: aleksis/core/views.py:956
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:932
+#: aleksis/core/views.py:986
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:942
+#: aleksis/core/views.py:996
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1009
+#: aleksis/core/views.py:1063
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1011
+#: aleksis/core/views.py:1065
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1137
-msgid "The social account could not be disconnected because it is the only login method available."
+#: aleksis/core/views.py:1191
+msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1144
-msgid "The social account has been successfully disconnected."
+#: aleksis/core/views.py:1198
+msgid "The third-party account has been successfully disconnected."
 msgstr ""
diff --git a/aleksis/core/locale/ar/LC_MESSAGES/djangojs.po b/aleksis/core/locale/ar/LC_MESSAGES/djangojs.po
index aa0f3532b1e660f5dc3ccc528e6144d8240b68a6..4a3d30e1766c01a47d0af190b00f484093f10159 100644
--- a/aleksis/core/locale/ar/LC_MESSAGES/djangojs.po
+++ b/aleksis/core/locale/ar/LC_MESSAGES/djangojs.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -30,6 +30,6 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
-#: aleksis/core/static/js/main.js:121
+#: aleksis/core/static/js/main.js:133
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr ""
diff --git a/aleksis/core/locale/de_DE/LC_MESSAGES/django.po b/aleksis/core/locale/de_DE/LC_MESSAGES/django.po
index fab84d7b72e4d3e4f82be558a89fa199924710cf..351ea2dcd10656baf1b0f4ff710d172d563cf75b 100644
--- a/aleksis/core/locale/de_DE/LC_MESSAGES/django.po
+++ b/aleksis/core/locale/de_DE/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: AlekSIS (School Information System) 0.1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
-"PO-Revision-Date: 2021-05-21 18:38+0000\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
+"PO-Revision-Date: 2021-06-12 10:28+0000\n"
 "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
 "Language-Team: German <https://translate.edugit.org/projects/aleksis/aleksis/"
 "de/>\n"
@@ -167,9 +167,7 @@ msgstr "Passwort wiederholen"
 #: aleksis/core/forms.py:436
 #, python-brace-format
 msgid "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree with them."
-msgstr ""
-"Ich habe die <a href='{privacy_policy}'>Datenschutzerklärung</a> gelesen und "
-"stimme ihr zu."
+msgstr "Ich habe die <a href='{privacy_policy}'>Datenschutzerklärung</a> gelesen und stimme ihr zu."
 
 #: aleksis/core/forms.py:460
 msgid "You must type the same password each time."
@@ -264,12 +262,14 @@ msgid "Preferences"
 msgstr "Einstellungen"
 
 #: aleksis/core/menus.py:97
-msgid "Social accounts"
-msgstr "Soziale Konten"
+msgid "Third-party accounts"
+msgstr "Drittanbieter-Konten"
 
 #: aleksis/core/menus.py:106
-msgid "Authorized tokens"
-msgstr "Autorisierte Tokens"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
+msgid "Authorized applications"
+msgstr "Autorisierte Anwendungen"
 
 #: aleksis/core/menus.py:117
 msgid "Admin"
@@ -358,7 +358,7 @@ msgstr "Zusätzliche Felder"
 msgid "Assign child groups to groups"
 msgstr "Kindgruppen zu Gruppen zuordnen"
 
-#: aleksis/core/mixins.py:476
+#: aleksis/core/mixins.py:475
 msgid "Linked school term"
 msgstr "Zugeordnetes Schuljahr"
 
@@ -907,139 +907,143 @@ msgstr "Authentifizierung"
 msgid "Internationalisation"
 msgstr "Internationalisierung"
 
-#: aleksis/core/preferences.py:39
+#: aleksis/core/preferences.py:41
 msgid "Site title"
 msgstr "Seitentitel"
 
-#: aleksis/core/preferences.py:48
+#: aleksis/core/preferences.py:52
 msgid "Site description"
 msgstr "Seitenbeschreibung"
 
-#: aleksis/core/preferences.py:57
+#: aleksis/core/preferences.py:63
 msgid "Primary colour"
 msgstr "Primärfarbe"
 
-#: aleksis/core/preferences.py:67
+#: aleksis/core/preferences.py:75
 msgid "Secondary colour"
 msgstr "Akzentfarbe"
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:86
 msgid "Logo"
 msgstr "Logo"
 
-#: aleksis/core/preferences.py:84
+#: aleksis/core/preferences.py:96
 msgid "Favicon"
 msgstr "Favicon"
 
-#: aleksis/core/preferences.py:92
+#: aleksis/core/preferences.py:106
 msgid "PWA-Icon"
 msgstr "PWA-Icon"
 
-#: aleksis/core/preferences.py:101
+#: aleksis/core/preferences.py:117
 msgid "Mail out name"
 msgstr "Ausgangsmailname"
 
-#: aleksis/core/preferences.py:110
+#: aleksis/core/preferences.py:128
 msgid "Mail out address"
 msgstr "E-Mail-Ausgangsadresse"
 
-#: aleksis/core/preferences.py:120
+#: aleksis/core/preferences.py:140
 msgid "Link to privacy policy"
 msgstr "Link zur Datenschutzerklärung"
 
-#: aleksis/core/preferences.py:130
+#: aleksis/core/preferences.py:152
 msgid "Link to imprint"
 msgstr "Link zum Impressum"
 
-#: aleksis/core/preferences.py:140
+#: aleksis/core/preferences.py:164
 msgid "Name format for addressing"
 msgstr "Namensformat für Anreden"
 
-#: aleksis/core/preferences.py:154
+#: aleksis/core/preferences.py:180
 msgid "Channels to use for notifications"
 msgstr "Aktivierte Benachrichtungskanäle"
 
-#: aleksis/core/preferences.py:164
+#: aleksis/core/preferences.py:192
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr "Regulärer Ausdruck um Primärgruppen zu finden, z. B.  '^Class .*'"
 
-#: aleksis/core/preferences.py:173
+#: aleksis/core/preferences.py:203
 msgid "Field on person to match primary group against"
 msgstr "Feld um Primärgruppen zu finden"
 
-#: aleksis/core/preferences.py:185
+#: aleksis/core/preferences.py:215
 msgid "Automatically create new persons for new users"
 msgstr "Erstelle automatisch neue Personen für neue Benutzer"
 
-#: aleksis/core/preferences.py:194
+#: aleksis/core/preferences.py:224
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr "Verknüpfe existierende Personen automatisch mit neuen Personen anhand ihrer E-Mail-Adresse"
 
-#: aleksis/core/preferences.py:203
+#: aleksis/core/preferences.py:235
 msgid "Display name of the school"
 msgstr "Sichtbarer Name der Schule"
 
-#: aleksis/core/preferences.py:212
+#: aleksis/core/preferences.py:246
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr "Offizieller Name der Schule, wie er z.B. von der Behörde vorgegeben ist"
 
-#: aleksis/core/preferences.py:220
+#: aleksis/core/preferences.py:256
+msgid "Enabled custom authentication backends"
+msgstr "Benutzerdefinierte Authentifizierungsbackends aktivieren"
+
+#: aleksis/core/preferences.py:268
 msgid "Allow users to change their passwords"
 msgstr "Erlaube Benutzern, ihr Passwort zu ändern"
 
-#: aleksis/core/preferences.py:228
+#: aleksis/core/preferences.py:276
 msgid "Enable signup"
 msgstr "Registrierung aktivieren"
 
-#: aleksis/core/preferences.py:237
+#: aleksis/core/preferences.py:287
 msgid "Available languages"
 msgstr "Verfügbare Sprachen"
 
-#: aleksis/core/preferences.py:249
+#: aleksis/core/preferences.py:299
 msgid "Send emails if data checks detect problems"
 msgstr "E-Mails versenden, wenn Datenprüfungen Probleme finden"
 
-#: aleksis/core/preferences.py:260
+#: aleksis/core/preferences.py:310
 msgid "Email recipients for data checks problem emails"
 msgstr "E-Mailempfänger für Datenprüfungsproblem-E-Mails"
 
-#: aleksis/core/preferences.py:271
+#: aleksis/core/preferences.py:321
 msgid "Email recipient groups for data checks problem emails"
 msgstr "E-Mail-Empfängergruppen für Datenprüfungsproblem-E-Mails"
 
-#: aleksis/core/preferences.py:280
+#: aleksis/core/preferences.py:330
 msgid "Show dashboard to users without login"
 msgstr "Zeige Dashboard für Benutzer ohne Login"
 
-#: aleksis/core/preferences.py:289
+#: aleksis/core/preferences.py:339
 msgid "Allow users to edit their dashboard"
 msgstr "Erlaube Benutzern, ihr Dashboard zu bearbeiten"
 
-#: aleksis/core/preferences.py:300
+#: aleksis/core/preferences.py:350
 msgid "Fields on person model which are editable by themselves."
 msgstr "Felder des Personen-Models welche von ihnen selbst editierbar sind."
 
-#: aleksis/core/preferences.py:314
+#: aleksis/core/preferences.py:364
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr "Editierbare Felder des Personen-Models welche eine Benachrichtigung für Änderungen auslösen soll"
 
-#: aleksis/core/preferences.py:327
+#: aleksis/core/preferences.py:377
 msgid "Contact for notification if a person changes their data"
 msgstr "Kontakt für Benachrichtigung, wenn eine Person ihre Daten ändert"
 
-#: aleksis/core/preferences.py:337
+#: aleksis/core/preferences.py:387
 msgid "PDF file expiration duration"
 msgstr "PDF-Datei-Ablaufdauer"
 
-#: aleksis/core/preferences.py:338
+#: aleksis/core/preferences.py:388
 msgid "in minutes"
 msgstr "in Minuten"
 
-#: aleksis/core/settings.py:477
+#: aleksis/core/settings.py:470
 msgid "English"
 msgstr "Englisch"
 
-#: aleksis/core/settings.py:478
+#: aleksis/core/settings.py:471
 msgid "German"
 msgstr "Deutsch"
 
@@ -1192,22 +1196,16 @@ msgstr "Bestätigen"
 #: aleksis/core/templates/account/email_confirm.html:12
 #, python-format
 msgid "Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail address for user %(user_display)s."
-msgstr ""
-"Bitte bestätigen Sie, dass <a href=\"mailto:%(email)s\">%(email)s</a> eine E"
-"-Mail-Adresse für den Benutzer %(user_display)s ist."
+msgstr "Bitte bestätigen Sie, dass <a href=\"mailto:%(email)s\">%(email)s</a> eine E-Mail-Adresse für den Benutzer %(user_display)s ist."
 
 #: aleksis/core/templates/account/email_confirm.html:25
 #, python-format
 msgid "This e-mail confirmation link expired or is invalid. Please <a href=\"%(email_url)s\">issue a new e-mail confirmation request</a>."
-msgstr ""
-"Dieser E-Mail-Bestätigungslink ist abgelaufen oder nicht gültig. Bitte <a "
-"href=\"%(email_url)s\">fragen Sie eine neue E-Mail-Bestätigung an</a>."
+msgstr "Dieser E-Mail-Bestätigungslink ist abgelaufen oder nicht gültig. Bitte <a href=\"%(email_url)s\">fragen Sie eine neue E-Mail-Bestätigung an</a>."
 
 #: aleksis/core/templates/account/password_change.html:12
 msgid "Forgot your current password? Click here to reset it:"
-msgstr ""
-"Haben Sie Ihr aktuelles Passwort vergessen? Klicken Sie hier, um es "
-"zurückzusetzen:"
+msgstr "Haben Sie Ihr aktuelles Passwort vergessen? Klicken Sie hier, um es zurückzusetzen:"
 
 #: aleksis/core/templates/account/password_change.html:12
 msgid "Forgot Password?"
@@ -1230,8 +1228,7 @@ msgid ""
 "          "
 msgstr ""
 "\n"
-"            Benutzer dürfen ihre eigenen Passwörter nicht ändern. Wenn Sie "
-"denken, \n"
+"            Benutzer dürfen ihre eigenen Passwörter nicht ändern. Wenn Sie denken, \n"
 "dass dies ein Fehler ist, kontaktieren Sie bitte einen der Administratoren:\n"
 "          "
 
@@ -1247,9 +1244,7 @@ msgstr "Passwort zurücksetzen"
 
 #: aleksis/core/templates/account/password_reset.html:17
 msgid "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it."
-msgstr ""
-"Passwort vergessen? Geben Sie Ihre E-Mail-Adresse hier ein und wir werden "
-"Ihnen eine E-Mail zum Zurücksetzen des Passwortes schicken."
+msgstr "Passwort vergessen? Geben Sie Ihre E-Mail-Adresse hier ein und wir werden Ihnen eine E-Mail zum Zurücksetzen des Passwortes schicken."
 
 #: aleksis/core/templates/account/password_reset.html:30
 msgid ""
@@ -1272,8 +1267,7 @@ msgid ""
 "          "
 msgstr ""
 "\n"
-"            Wir haben Ihnen eine E-Mail gesendet. Bitte kontaktieren Sie "
-"einen der Administratoren,\n"
+"            Wir haben Ihnen eine E-Mail gesendet. Bitte kontaktieren Sie einen der Administratoren,\n"
 "wenn Sie diese nicht innerhalb weniger Minuten erhalten.\n"
 "          "
 
@@ -1290,10 +1284,7 @@ msgid ""
 "            "
 msgstr ""
 "\n"
-"              Der Link zum Zurücksetzen des Passwortes war falsch, "
-"wahrscheinlich, weil er bereits benutzt wurde. Bitte starten Sie eine neue "
-"Anfrage <a href=\"%(passwd_reset_url)s\"              class=\"blue-text text-"
-"lighten-2\">zum Zurücksetzen des Passwortes</a>.\n"
+"              Der Link zum Zurücksetzen des Passwortes war falsch, wahrscheinlich, weil er bereits benutzt wurde. Bitte starten Sie eine neue Anfrage <a href=\"%(passwd_reset_url)s\"              class=\"blue-text text-lighten-2\">zum Zurücksetzen des Passwortes</a>.\n"
 "            "
 
 #: aleksis/core/templates/account/password_reset_from_key.html:25
@@ -1343,9 +1334,7 @@ msgstr "Registrierung"
 #: aleksis/core/templates/account/signup.html:12
 #, python-format
 msgid "Already have an account? Then please <a href=\"%(login_url)s\">sign in</a>."
-msgstr ""
-"Haben Sie bereits ein Konto? Dann <a href=\"%(login_url)s\">melden Sie sich "
-"bitte an</a>."
+msgstr "Haben Sie bereits ein Konto? Dann <a href=\"%(login_url)s\">melden Sie sich bitte an</a>."
 
 #: aleksis/core/templates/account/signup_closed.html:5
 #: aleksis/core/templates/account/signup_closed.html:6
@@ -1364,8 +1353,7 @@ msgid ""
 "          "
 msgstr ""
 "\n"
-"            Die Registrierung ist aktuell geschlossen. Wenn Sie denken, dass "
-"dies ein Fehler ist,\n"
+"            Die Registrierung ist aktuell geschlossen. Wenn Sie denken, dass dies ein Fehler ist,\n"
 " kontaktieren Sie bitte einen Ihrer Systemadministratoren.\n"
 "          "
 
@@ -1390,10 +1378,8 @@ msgid ""
 "          "
 msgstr ""
 "\n"
-"            Dieser Teil der Anwendung setzt voraus, dass wir verifizieren, "
-"dass Sie die Person sind, die sie vorgeben, zu sein.\n"
-"Zu diesem Zweck setzen wir voraus, dass Sie die Inhaberschaft Ihrer E-Mail-"
-"Adresse bestätigen.\n"
+"            Dieser Teil der Anwendung setzt voraus, dass wir verifizieren, dass Sie die Person sind, die sie vorgeben, zu sein.\n"
+"Zu diesem Zweck setzen wir voraus, dass Sie die Inhaberschaft Ihrer E-Mail-Adresse bestätigen.\n"
 "          "
 
 #: aleksis/core/templates/account/verification_sent.html:22
@@ -1407,16 +1393,13 @@ msgstr ""
 "\n"
 "            Wir haben Ihnen eine E-Mail zur Verifizierung geschickt.\n"
 "Bitte klicken Sie auf den Link in dieser E-Mail.\n"
-"Bitte kontaktieren Sie uns, wenn Sie diese nicht binnen weniger Minuten "
-"erhalten.\n"
+"Bitte kontaktieren Sie uns, wenn Sie diese nicht binnen weniger Minuten erhalten.\n"
 "          "
 
 #: aleksis/core/templates/account/verification_sent.html:30
 #, python-format
 msgid "<strong>Note:</strong> you can still <a href=\"%(email_url)s\">change your e-mail address</a>"
-msgstr ""
-"<strong>Hinweis:</strong> Sie können immer noch <a href=\"%(email_url)s\"> "
-"Ihre E-Mail-Adresse ändern</a>"
+msgstr "<strong>Hinweis:</strong> Sie können immer noch <a href=\"%(email_url)s\"> Ihre E-Mail-Adresse ändern</a>"
 
 #: aleksis/core/templates/core/additional_field/edit.html:6
 #: aleksis/core/templates/core/additional_field/edit.html:7
@@ -1616,9 +1599,14 @@ msgid ""
 "        "
 msgstr ""
 "\n"
-"          Auf dieser Seite können Sie Ihr das Standard-Dashboard zusammenstallen, welches angezeigt wird, wenn ein Nutzer kein eigenes definiert. \n"
-"Sie können beliebige Elemente von den \"Verfügbaren Widgets\" in \"Standard-Dashboard\" ziehen oder die Reihenfolge verändern, indem Sie die Widgets bewegen. \n"
-"Wenn Sie fertig sind, vergessen Sie bitte nicht, auf \"Speichern\" zu drücken.\n"
+"          Auf dieser Seite können Sie Ihr das Standard-Dashboard "
+"zusammenstallen, welches angezeigt wird, wenn ein Benutzer kein eigenes "
+"definiert. \n"
+"Sie können beliebige Elemente von den \"Verfügbaren Widgets\" in \"Standard-"
+"Dashboard\" ziehen oder die Reihenfolge verändern, indem Sie die Widgets "
+"bewegen. \n"
+"Wenn Sie fertig sind, vergessen Sie bitte nicht, auf \"Speichern\" zu "
+"drücken.\n"
 "        "
 
 #: aleksis/core/templates/core/edit_dashboard.html:48
@@ -2284,26 +2272,23 @@ msgstr "Bitte gehen Sie zurück in Ihre Anwendung und geben Sie diesen Code ein:
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:5
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:6
-msgid "Revoke token"
-msgstr "Token zurückziehen"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
+msgid "Revoke access"
+msgstr "Zugriff zurückziehen"
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:12
-msgid "Are you sure to revoke this token?"
-msgstr "Sind Sie sicher, dass Sie dieses Token zurückziehen möchten?"
+msgid "Are you sure to revoke the access for this application?"
+msgstr ""
+"Sind Sie sicher, dass Sie den Zugriff für diese Anwendung zurückziehen "
+"möchten?"
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:20
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
 msgid "Revoke"
 msgstr "Zurückziehen"
 
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
-msgid "Authorized applications"
-msgstr "Autorisierte Anwendungen"
-
 #: aleksis/core/templates/oauth2_provider/authorized-tokens.html:33
-msgid "No authorized tokens defined."
-msgstr "Keine autorisierten Token definiert."
+msgid "No authorized applications."
+msgstr "Keine autorisierten Anwendungen."
 
 #: aleksis/core/templates/offline.html:5
 msgid "Network error"
@@ -2353,22 +2338,22 @@ msgstr "Bitte geben Sie einen Suchausdruck ein."
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:5
 #: aleksis/core/templates/socialaccount/authentication_error.html:6
-msgid "Social Network Login Failure"
-msgstr "Anmeldung über soziales Netzwerk fehlgeschlagen"
+msgid "Third-party Account Login Failure"
+msgstr "Anmeldung über Drittanbieter-Konto fehlgeschlagen"
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:13
-msgid "Social Network Login Failure."
-msgstr "Anmeldung über soziales Netzwerk fehlgeschlagen."
+msgid "Third-party Account Login Failure."
+msgstr "Anmeldung über Drittanbieter-Konto fehlgeschlagen."
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:15
 msgid ""
 "\n"
-"            An error occurred while attempting to login via your social network account.\n"
+"            An error occurred while attempting to login via your third-party account.\n"
 "            Please contact one of your site administrators.\n"
 "          "
 msgstr ""
 "\n"
-"            Beim dem Versuch, die Anmeldung über Ihr soziales Netzwerk "
+"            Beim dem Versuch, die Anmeldung über Ihr Drittanbieter-Konto "
 "durchzuführen, ist ein Fehler aufgetreten.\n"
 "            Kontaktieren Sie bitte einen Ihrer Systemadministratoren:\n"
 "          "
@@ -2383,14 +2368,12 @@ msgid "Remove"
 msgstr "Löschen"
 
 #: aleksis/core/templates/socialaccount/connections.html:34
-msgid "You currently have no social network accounts connected to this account."
-msgstr ""
-"Sie haben aktuell keine Konten von sozialen Netzwerken mit Ihrem Konto "
-"verbunden."
+msgid "You currently have no third-party accounts connected to this account."
+msgstr "Sie haben aktuell keine Drittanbieter-Konten mit Ihrem Konto verbunden."
 
 #: aleksis/core/templates/socialaccount/connections.html:37
-msgid "Add a 3rd Party Account"
-msgstr "Ein Drittanbieterkonto hinzufügen"
+msgid "Add a Third-party Account"
+msgstr "Ein Drittanbieter-Konto hinzufügen"
 
 #: aleksis/core/templates/socialaccount/login_cancelled.html:5
 #: aleksis/core/templates/socialaccount/login_cancelled.html:6
@@ -2406,9 +2389,7 @@ msgid ""
 "          "
 msgstr ""
 "\n"
-"            Sie haben sich entschieden, die Anmeldung mit einem Ihrer "
-"bestehenden Konten bei uns abzubrechen. Wenn dies ein Fehler war, <a href=\""
-"%(login_url)s\">fahren Sie bitte mit dem Login fort</a>.\n"
+"            Sie haben sich entschieden, die Anmeldung mit einem Ihrer bestehenden Konten bei uns abzubrechen. Wenn dies ein Fehler war, <a href=\"%(login_url)s\">fahren Sie bitte mit dem Login fort</a>.\n"
 "          "
 
 #: aleksis/core/templates/socialaccount/signup.html:12
@@ -2417,8 +2398,7 @@ msgid ""
 "You are about to use your %(provider_name)s account to login to\n"
 "        %(site_name)s. As a final step, please complete the following form:"
 msgstr ""
-"Sie sind dabei, Ihr %(provider_name)s-Konto zur Anmeldung bei %(site_name)s "
-"zu nutzen. \n"
+"Sie sind dabei, Ihr %(provider_name)s-Konto zur Anmeldung bei %(site_name)s zu nutzen. \n"
 "Als ein letzter Schritt vervollständigen Sie bitte das folgende Formular:"
 
 #: aleksis/core/templates/socialaccount/snippets/provider_list.html:12
@@ -2446,7 +2426,7 @@ msgstr ""
 #: aleksis/core/templates/socialaccount/snippets/provider_list.html:30
 msgid ""
 "\n"
-"          No 3rd party account providers available.\n"
+"          No third-party account providers available.\n"
 "        "
 msgstr ""
 "\n"
@@ -2619,7 +2599,7 @@ msgstr "Tokens generieren"
 
 #: aleksis/core/templates/two_factor/core/login.html:18
 msgid "Login with username and password"
-msgstr "Anmeldung mit Nutzername und Passwort"
+msgstr "Anmeldung mit Benutzername und Passwort"
 
 #: aleksis/core/templates/two_factor/core/login.html:26
 msgid "You have no permission to view this page. Please login with an other account."
@@ -2674,10 +2654,8 @@ msgid ""
 "                  "
 msgstr ""
 "\n"
-"                    Nutzen Sie dieses Formular um Ihre Backup-Tokens zum "
-"Anmelden einzugeben.\n"
-"                Diese Tokens wurden für Sie generiert, um diese gut "
-"aufzubewahren. Bitte\n"
+"                    Nutzen Sie dieses Formular um Ihre Backup-Tokens zum Anmelden einzugeben.\n"
+"                Diese Tokens wurden für Sie generiert, um diese gut aufzubewahren. Bitte\n"
 "                geben Sie einen dieser Tokens ein, um sich einzuloggen.\n"
 "                  "
 
@@ -3034,112 +3012,121 @@ msgstr "Es ist ein Fehler beim Generieren der PDF-Datei aufgetreten."
 msgid "Download PDF"
 msgstr "PDF herunterladen"
 
-#: aleksis/core/views.py:195
+#: aleksis/core/views.py:249
 msgid "The school term has been created."
 msgstr "Das Schuljahr wurde erstellt."
 
-#: aleksis/core/views.py:207
+#: aleksis/core/views.py:261
 msgid "The school term has been saved."
 msgstr "Das Schuljahr wurde gespeichert."
 
-#: aleksis/core/views.py:352
+#: aleksis/core/views.py:406
 msgid "The child groups were successfully saved."
 msgstr "Die Untergruppen wurden gespeichert."
 
-#: aleksis/core/views.py:413
+#: aleksis/core/views.py:467
 msgid "The person has been saved."
 msgstr "Die Person wurde gespeichert."
 
-#: aleksis/core/views.py:452
+#: aleksis/core/views.py:506
 msgid "The group has been saved."
 msgstr "Die Gruppe wurde gespeichert."
 
-#: aleksis/core/views.py:549
+#: aleksis/core/views.py:603
 msgid "The announcement has been saved."
 msgstr "Die Ankündigung wurde gespeichert."
 
-#: aleksis/core/views.py:565
+#: aleksis/core/views.py:619
 msgid "The announcement has been deleted."
 msgstr "Ankündigung wurde gelöscht."
 
-#: aleksis/core/views.py:649
+#: aleksis/core/views.py:703
 msgid "The preferences have been saved successfully."
 msgstr "Die Einstellungen wurde gespeichert."
 
-#: aleksis/core/views.py:673
+#: aleksis/core/views.py:727
 msgid "The person has been deleted."
 msgstr "Die Person wurde gelöscht."
 
-#: aleksis/core/views.py:687
+#: aleksis/core/views.py:741
 msgid "The group has been deleted."
 msgstr "Die Gruppe wurde gelöscht."
 
-#: aleksis/core/views.py:719
+#: aleksis/core/views.py:773
 msgid "The additional_field has been saved."
 msgstr "Das zusätzliche Feld wurde gespeichert."
 
-#: aleksis/core/views.py:753
+#: aleksis/core/views.py:807
 msgid "The additional field has been deleted."
 msgstr "Das zusätzliche Feld wurde gelöscht."
 
-#: aleksis/core/views.py:778
+#: aleksis/core/views.py:832
 msgid "The group type has been saved."
 msgstr "Der Gruppentyp wurde gespeichert."
 
-#: aleksis/core/views.py:808
+#: aleksis/core/views.py:862
 msgid "The group type has been deleted."
 msgstr "Der Gruppentyp wurde gelöscht."
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:895
 msgid "Progress: Run data checks"
 msgstr "Fortschritt: Datenprüfungen ausführen"
 
-#: aleksis/core/views.py:842
+#: aleksis/core/views.py:896
 msgid "Run data checks …"
 msgstr "Datenprüfungen laufen …"
 
-#: aleksis/core/views.py:843
+#: aleksis/core/views.py:897
 msgid "The data checks were run successfully."
 msgstr "Die Datenprüfungen wurden erfolgreich ausgeführt."
 
-#: aleksis/core/views.py:844
+#: aleksis/core/views.py:898
 msgid "There was a problem while running data checks."
 msgstr "Es gab ein Problem beim Ausführen der Datenprüfungen."
 
-#: aleksis/core/views.py:860
+#: aleksis/core/views.py:914
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr "Die Lösungsoption \"{solve_option_obj.verbose_name}\" "
 
-#: aleksis/core/views.py:902
+#: aleksis/core/views.py:956
 msgid "The dashboard widget has been saved."
 msgstr "Das Dashboard-Widget wurde gespeichert."
 
-#: aleksis/core/views.py:932
+#: aleksis/core/views.py:986
 msgid "The dashboard widget has been created."
 msgstr "Das Dashboard-Widget wurde erstellt."
 
-#: aleksis/core/views.py:942
+#: aleksis/core/views.py:996
 msgid "The dashboard widget has been deleted."
 msgstr "Das Dashboard-Widget wurde gelöscht."
 
-#: aleksis/core/views.py:1009
+#: aleksis/core/views.py:1063
 msgid "Your dashboard configuration has been saved successfully."
 msgstr "Ihre Dashboardkonfiguration wurde erfolgreich gespeichert."
 
-#: aleksis/core/views.py:1011
+#: aleksis/core/views.py:1065
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr "Die Konfiguration des Standard-Dashboardes wurde erfolgreich gespeichert."
 
-#: aleksis/core/views.py:1137
-msgid "The social account could not be disconnected because it is the only login method available."
+#: aleksis/core/views.py:1191
+msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
+"Das Drittanbieter-Konto konnte nicht deaktiviert werden, weil es die einzige "
+"verfügbare Anmeldeoption ist."
 
-#: aleksis/core/views.py:1144
-#, fuzzy
-#| msgid "The child groups were successfully saved."
-msgid "The social account has been successfully disconnected."
-msgstr "Die Untergruppen wurden gespeichert."
+#: aleksis/core/views.py:1198
+msgid "The third-party account has been successfully disconnected."
+msgstr "Das Drittanbieter-Konto wurde erfolgreich getrennt."
+
+#~ msgid "Authorized tokens"
+#~ msgstr "Autorisierte Tokens"
+
+#~ msgid "No authorized tokens defined."
+#~ msgstr "Keine autorisierten Token definiert."
+
+#~ msgid "Social Network Login Failure"
+#~ msgstr "Anmeldung über soziales Netzwerk fehlgeschlagen"
 
 #~ msgid ""
 #~ "We are calling your phone right now, please enter the\n"
@@ -3155,9 +3142,6 @@ msgstr "Die Untergruppen wurden gespeichert."
 #~ "Wir haben Ihnen eine Textnachricht geschickt. Bitte geben Sie die Tokens ein,\n"
 #~ "              die wir Ihnen geschickt haben."
 
-#~ msgid "Enabled custom authentication backends"
-#~ msgstr "Benutzerdefinierte Authentifizierungsbackends aktivieren"
-
 #~ msgid "French"
 #~ msgstr "Französisch"
 
diff --git a/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po b/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po
index 98db6bb2bfffd75db556c259758c6667c64e4b8d..21ea82be5697cbfadc5dde4d7de1c9006da0569b 100644
--- a/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po
+++ b/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -29,6 +29,6 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
-#: aleksis/core/static/js/main.js:121
+#: aleksis/core/static/js/main.js:133
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr ""
diff --git a/aleksis/core/locale/fr/LC_MESSAGES/django.po b/aleksis/core/locale/fr/LC_MESSAGES/django.po
index 8702bd00a7cdc1ebeed37eacd5810f9da2c3e8aa..aae0ef35190bf82dcc7bea7df6060a16488fb649 100644
--- a/aleksis/core/locale/fr/LC_MESSAGES/django.po
+++ b/aleksis/core/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: AlekSIS (School Information System) 0.1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: 2020-04-27 13:03+0000\n"
 "Last-Translator: Marlene Grundey <grundema@katharineum.de>\n"
 "Language-Team: French <https://translate.edugit.org/projects/aleksis/aleksis/fr/>\n"
@@ -277,11 +277,13 @@ msgid "Preferences"
 msgstr ""
 
 #: aleksis/core/menus.py:97
-msgid "Social accounts"
+msgid "Third-party accounts"
 msgstr ""
 
 #: aleksis/core/menus.py:106
-msgid "Authorized tokens"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
+msgid "Authorized applications"
 msgstr ""
 
 #: aleksis/core/menus.py:117
@@ -373,7 +375,7 @@ msgstr ""
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:476
+#: aleksis/core/mixins.py:475
 msgid "Linked school term"
 msgstr ""
 
@@ -952,143 +954,147 @@ msgstr ""
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:39
+#: aleksis/core/preferences.py:41
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:48
+#: aleksis/core/preferences.py:52
 #, fuzzy
 #| msgid "Description"
 msgid "Site description"
 msgstr "Description"
 
-#: aleksis/core/preferences.py:57
+#: aleksis/core/preferences.py:63
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:67
+#: aleksis/core/preferences.py:75
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:86
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:84
+#: aleksis/core/preferences.py:96
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:92
+#: aleksis/core/preferences.py:106
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:101
+#: aleksis/core/preferences.py:117
 #, fuzzy
 #| msgid "Last name"
 msgid "Mail out name"
 msgstr "Nom de famille"
 
-#: aleksis/core/preferences.py:110
+#: aleksis/core/preferences.py:128
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:120
+#: aleksis/core/preferences.py:140
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:130
+#: aleksis/core/preferences.py:152
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:140
+#: aleksis/core/preferences.py:164
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:154
+#: aleksis/core/preferences.py:180
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:164
+#: aleksis/core/preferences.py:192
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:173
+#: aleksis/core/preferences.py:203
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:185
+#: aleksis/core/preferences.py:215
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:194
+#: aleksis/core/preferences.py:224
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:203
+#: aleksis/core/preferences.py:235
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:212
+#: aleksis/core/preferences.py:246
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:220
+#: aleksis/core/preferences.py:256
+msgid "Enabled custom authentication backends"
+msgstr ""
+
+#: aleksis/core/preferences.py:268
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:228
+#: aleksis/core/preferences.py:276
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:237
+#: aleksis/core/preferences.py:287
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:249
+#: aleksis/core/preferences.py:299
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:260
+#: aleksis/core/preferences.py:310
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:271
+#: aleksis/core/preferences.py:321
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:280
+#: aleksis/core/preferences.py:330
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:289
+#: aleksis/core/preferences.py:339
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:300
+#: aleksis/core/preferences.py:350
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:314
+#: aleksis/core/preferences.py:364
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:327
+#: aleksis/core/preferences.py:377
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:337
+#: aleksis/core/preferences.py:387
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:338
+#: aleksis/core/preferences.py:388
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/settings.py:477
+#: aleksis/core/settings.py:470
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:478
+#: aleksis/core/settings.py:471
 msgid "German"
 msgstr ""
 
@@ -2178,26 +2184,23 @@ msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:5
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:6
-msgid "Revoke token"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
+msgid "Revoke access"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:12
-msgid "Are you sure to revoke this token?"
+msgid "Are you sure to revoke the access for this application?"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:20
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
 msgid "Revoke"
 msgstr ""
 
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
-msgid "Authorized applications"
-msgstr ""
-
 #: aleksis/core/templates/oauth2_provider/authorized-tokens.html:33
-msgid "No authorized tokens defined."
-msgstr ""
+#, fuzzy
+#| msgid "Contact details"
+msgid "No authorized applications."
+msgstr "Détails de contact"
 
 #: aleksis/core/templates/offline.html:5
 msgid "Network error"
@@ -2240,17 +2243,17 @@ msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:5
 #: aleksis/core/templates/socialaccount/authentication_error.html:6
-msgid "Social Network Login Failure"
+msgid "Third-party Account Login Failure"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:13
-msgid "Social Network Login Failure."
+msgid "Third-party Account Login Failure."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:15
 msgid ""
 "\n"
-"            An error occurred while attempting to login via your social network account.\n"
+"            An error occurred while attempting to login via your third-party account.\n"
 "            Please contact one of your site administrators.\n"
 "          "
 msgstr ""
@@ -2265,11 +2268,11 @@ msgid "Remove"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:34
-msgid "You currently have no social network accounts connected to this account."
+msgid "You currently have no third-party accounts connected to this account."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:37
-msgid "Add a 3rd Party Account"
+msgid "Add a Third-party Account"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/login_cancelled.html:5
@@ -2312,7 +2315,7 @@ msgstr ""
 #: aleksis/core/templates/socialaccount/snippets/provider_list.html:30
 msgid ""
 "\n"
-"          No 3rd party account providers available.\n"
+"          No third-party account providers available.\n"
 "        "
 msgstr ""
 
@@ -2775,107 +2778,107 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:195
+#: aleksis/core/views.py:249
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:207
+#: aleksis/core/views.py:261
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:352
+#: aleksis/core/views.py:406
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:413
+#: aleksis/core/views.py:467
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:452
+#: aleksis/core/views.py:506
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:549
+#: aleksis/core/views.py:603
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:565
+#: aleksis/core/views.py:619
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:649
+#: aleksis/core/views.py:703
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:673
+#: aleksis/core/views.py:727
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:687
+#: aleksis/core/views.py:741
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:719
+#: aleksis/core/views.py:773
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:753
+#: aleksis/core/views.py:807
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:778
+#: aleksis/core/views.py:832
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:808
+#: aleksis/core/views.py:862
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:895
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:842
+#: aleksis/core/views.py:896
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:843
+#: aleksis/core/views.py:897
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:844
+#: aleksis/core/views.py:898
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:860
+#: aleksis/core/views.py:914
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:902
+#: aleksis/core/views.py:956
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:932
+#: aleksis/core/views.py:986
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:942
+#: aleksis/core/views.py:996
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1009
+#: aleksis/core/views.py:1063
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1011
+#: aleksis/core/views.py:1065
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1137
-msgid "The social account could not be disconnected because it is the only login method available."
+#: aleksis/core/views.py:1191
+msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1144
-msgid "The social account has been successfully disconnected."
+#: aleksis/core/views.py:1198
+msgid "The third-party account has been successfully disconnected."
 msgstr ""
diff --git a/aleksis/core/locale/fr/LC_MESSAGES/djangojs.po b/aleksis/core/locale/fr/LC_MESSAGES/djangojs.po
index 092a17e7b7222f19ff5669f6d13363b04deaec9e..21e69364371e66818823069bb0a8232f9cadde70 100644
--- a/aleksis/core/locale/fr/LC_MESSAGES/djangojs.po
+++ b/aleksis/core/locale/fr/LC_MESSAGES/djangojs.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -30,6 +30,6 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
-#: aleksis/core/static/js/main.js:121
+#: aleksis/core/static/js/main.js:133
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr ""
diff --git a/aleksis/core/locale/la/LC_MESSAGES/django.po b/aleksis/core/locale/la/LC_MESSAGES/django.po
index 5985bab7c1f7034a474a5f9eff1199250d3cd93c..c93dfc4c84cc2d07cc3edcc772e59cfac8eb4eb1 100644
--- a/aleksis/core/locale/la/LC_MESSAGES/django.po
+++ b/aleksis/core/locale/la/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: 2020-12-19 12:57+0000\n"
 "Last-Translator: Julian <leuckerj@gmail.com>\n"
 "Language-Team: Latin <https://translate.edugit.org/projects/aleksis/aleksis/la/>\n"
@@ -279,12 +279,16 @@ msgstr ""
 #: aleksis/core/menus.py:97
 #, fuzzy
 #| msgid "Persons and accounts"
-msgid "Social accounts"
+msgid "Third-party accounts"
 msgstr "Personae et computi"
 
 #: aleksis/core/menus.py:106
-msgid "Authorized tokens"
-msgstr ""
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
+#, fuzzy
+#| msgid "Notifications"
+msgid "Authorized applications"
+msgstr "Nuntii"
 
 #: aleksis/core/menus.py:117
 msgid "Admin"
@@ -385,7 +389,7 @@ msgstr "addita nomines"
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:476
+#: aleksis/core/mixins.py:475
 #, fuzzy
 #| msgid "Edit school term"
 msgid "Linked school term"
@@ -1002,147 +1006,151 @@ msgstr "Nuntii"
 msgid "Internationalisation"
 msgstr "Simulare aliquem"
 
-#: aleksis/core/preferences.py:39
+#: aleksis/core/preferences.py:41
 msgid "Site title"
 msgstr "Titulus paginae"
 
-#: aleksis/core/preferences.py:48
+#: aleksis/core/preferences.py:52
 msgid "Site description"
 msgstr "Descriptio paginae"
 
-#: aleksis/core/preferences.py:57
+#: aleksis/core/preferences.py:63
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:67
+#: aleksis/core/preferences.py:75
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:86
 #, fuzzy
 #| msgid "Logout"
 msgid "Logo"
 msgstr "nomen retractare"
 
-#: aleksis/core/preferences.py:84
+#: aleksis/core/preferences.py:96
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:92
+#: aleksis/core/preferences.py:106
 #, fuzzy
 #| msgid "Icon"
 msgid "PWA-Icon"
 msgstr "Nota"
 
-#: aleksis/core/preferences.py:101
+#: aleksis/core/preferences.py:117
 #, fuzzy
 #| msgid "Last name"
 msgid "Mail out name"
 msgstr "Secondus nomen"
 
-#: aleksis/core/preferences.py:110
+#: aleksis/core/preferences.py:128
 #, fuzzy
 #| msgid "E-mail address"
 msgid "Mail out address"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/preferences.py:120
+#: aleksis/core/preferences.py:140
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:130
+#: aleksis/core/preferences.py:152
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:140
+#: aleksis/core/preferences.py:164
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:154
+#: aleksis/core/preferences.py:180
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:164
+#: aleksis/core/preferences.py:192
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:173
+#: aleksis/core/preferences.py:203
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:185
+#: aleksis/core/preferences.py:215
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:194
+#: aleksis/core/preferences.py:224
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:203
+#: aleksis/core/preferences.py:235
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:212
+#: aleksis/core/preferences.py:246
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr "Officialis nomen scolae, e. g."
 
-#: aleksis/core/preferences.py:220
+#: aleksis/core/preferences.py:256
+msgid "Enabled custom authentication backends"
+msgstr ""
+
+#: aleksis/core/preferences.py:268
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:228
+#: aleksis/core/preferences.py:276
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:237
+#: aleksis/core/preferences.py:287
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:249
+#: aleksis/core/preferences.py:299
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:260
+#: aleksis/core/preferences.py:310
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:271
+#: aleksis/core/preferences.py:321
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:280
+#: aleksis/core/preferences.py:330
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:289
+#: aleksis/core/preferences.py:339
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:300
+#: aleksis/core/preferences.py:350
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:314
+#: aleksis/core/preferences.py:364
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:327
+#: aleksis/core/preferences.py:377
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:337
+#: aleksis/core/preferences.py:387
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:338
+#: aleksis/core/preferences.py:388
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/settings.py:477
+#: aleksis/core/settings.py:470
 msgid "English"
 msgstr "Britannicus"
 
-#: aleksis/core/settings.py:478
+#: aleksis/core/settings.py:471
 msgid "German"
 msgstr "Germanus"
 
@@ -2286,29 +2294,24 @@ msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:5
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:6
-msgid "Revoke token"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
+msgid "Revoke access"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:12
-msgid "Are you sure to revoke this token?"
+msgid "Are you sure to revoke the access for this application?"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:20
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
 msgid "Revoke"
 msgstr ""
 
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:33
 #, fuzzy
 #| msgid "Notifications"
-msgid "Authorized applications"
+msgid "No authorized applications."
 msgstr "Nuntii"
 
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:33
-msgid "No authorized tokens defined."
-msgstr ""
-
 #: aleksis/core/templates/offline.html:5
 msgid "Network error"
 msgstr ""
@@ -2350,17 +2353,17 @@ msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:5
 #: aleksis/core/templates/socialaccount/authentication_error.html:6
-msgid "Social Network Login Failure"
+msgid "Third-party Account Login Failure"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:13
-msgid "Social Network Login Failure."
+msgid "Third-party Account Login Failure."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:15
 msgid ""
 "\n"
-"            An error occurred while attempting to login via your social network account.\n"
+"            An error occurred while attempting to login via your third-party account.\n"
 "            Please contact one of your site administrators.\n"
 "          "
 msgstr ""
@@ -2377,11 +2380,11 @@ msgid "Remove"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:34
-msgid "You currently have no social network accounts connected to this account."
+msgid "You currently have no third-party accounts connected to this account."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:37
-msgid "Add a 3rd Party Account"
+msgid "Add a Third-party Account"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/login_cancelled.html:5
@@ -2424,7 +2427,7 @@ msgstr ""
 #: aleksis/core/templates/socialaccount/snippets/provider_list.html:30
 msgid ""
 "\n"
-"          No 3rd party account providers available.\n"
+"          No third-party account providers available.\n"
 "        "
 msgstr ""
 
@@ -2894,111 +2897,111 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:195
+#: aleksis/core/views.py:249
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:207
+#: aleksis/core/views.py:261
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:352
+#: aleksis/core/views.py:406
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:413
+#: aleksis/core/views.py:467
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:452
+#: aleksis/core/views.py:506
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:549
+#: aleksis/core/views.py:603
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:565
+#: aleksis/core/views.py:619
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:649
+#: aleksis/core/views.py:703
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:673
+#: aleksis/core/views.py:727
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:687
+#: aleksis/core/views.py:741
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:719
+#: aleksis/core/views.py:773
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:753
+#: aleksis/core/views.py:807
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:778
+#: aleksis/core/views.py:832
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:808
+#: aleksis/core/views.py:862
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:895
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:842
+#: aleksis/core/views.py:896
 #, fuzzy
 #| msgid "System status"
 msgid "Run data checks …"
 msgstr "Status systemae"
 
-#: aleksis/core/views.py:843
+#: aleksis/core/views.py:897
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:844
+#: aleksis/core/views.py:898
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:860
+#: aleksis/core/views.py:914
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:902
+#: aleksis/core/views.py:956
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:932
+#: aleksis/core/views.py:986
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:942
+#: aleksis/core/views.py:996
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1009
+#: aleksis/core/views.py:1063
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1011
+#: aleksis/core/views.py:1065
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1137
-msgid "The social account could not be disconnected because it is the only login method available."
+#: aleksis/core/views.py:1191
+msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1144
-msgid "The social account has been successfully disconnected."
+#: aleksis/core/views.py:1198
+msgid "The third-party account has been successfully disconnected."
 msgstr ""
 
 #~ msgid "School logo"
diff --git a/aleksis/core/locale/la/LC_MESSAGES/djangojs.po b/aleksis/core/locale/la/LC_MESSAGES/djangojs.po
index 98db6bb2bfffd75db556c259758c6667c64e4b8d..21ea82be5697cbfadc5dde4d7de1c9006da0569b 100644
--- a/aleksis/core/locale/la/LC_MESSAGES/djangojs.po
+++ b/aleksis/core/locale/la/LC_MESSAGES/djangojs.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -29,6 +29,6 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
-#: aleksis/core/static/js/main.js:121
+#: aleksis/core/static/js/main.js:133
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr ""
diff --git a/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po b/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po
index 713e94c8eab8f22278f7d4aa931fba30408f03e7..7c6a52b38dae78aecca1ac6b79fdcb585b0573bf 100644
--- a/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po
+++ b/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: AlekSIS (School Information System) 0.1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -260,11 +260,13 @@ msgid "Preferences"
 msgstr ""
 
 #: aleksis/core/menus.py:97
-msgid "Social accounts"
+msgid "Third-party accounts"
 msgstr ""
 
 #: aleksis/core/menus.py:106
-msgid "Authorized tokens"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
+msgid "Authorized applications"
 msgstr ""
 
 #: aleksis/core/menus.py:117
@@ -354,7 +356,7 @@ msgstr ""
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:476
+#: aleksis/core/mixins.py:475
 msgid "Linked school term"
 msgstr ""
 
@@ -903,139 +905,143 @@ msgstr ""
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:39
+#: aleksis/core/preferences.py:41
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:48
+#: aleksis/core/preferences.py:52
 msgid "Site description"
 msgstr ""
 
-#: aleksis/core/preferences.py:57
+#: aleksis/core/preferences.py:63
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:67
+#: aleksis/core/preferences.py:75
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:86
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:84
+#: aleksis/core/preferences.py:96
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:92
+#: aleksis/core/preferences.py:106
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:101
+#: aleksis/core/preferences.py:117
 msgid "Mail out name"
 msgstr ""
 
-#: aleksis/core/preferences.py:110
+#: aleksis/core/preferences.py:128
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:120
+#: aleksis/core/preferences.py:140
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:130
+#: aleksis/core/preferences.py:152
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:140
+#: aleksis/core/preferences.py:164
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:154
+#: aleksis/core/preferences.py:180
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:164
+#: aleksis/core/preferences.py:192
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:173
+#: aleksis/core/preferences.py:203
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:185
+#: aleksis/core/preferences.py:215
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:194
+#: aleksis/core/preferences.py:224
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:203
+#: aleksis/core/preferences.py:235
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:212
+#: aleksis/core/preferences.py:246
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:220
+#: aleksis/core/preferences.py:256
+msgid "Enabled custom authentication backends"
+msgstr ""
+
+#: aleksis/core/preferences.py:268
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:228
+#: aleksis/core/preferences.py:276
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:237
+#: aleksis/core/preferences.py:287
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:249
+#: aleksis/core/preferences.py:299
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:260
+#: aleksis/core/preferences.py:310
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:271
+#: aleksis/core/preferences.py:321
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:280
+#: aleksis/core/preferences.py:330
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:289
+#: aleksis/core/preferences.py:339
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:300
+#: aleksis/core/preferences.py:350
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:314
+#: aleksis/core/preferences.py:364
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:327
+#: aleksis/core/preferences.py:377
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:337
+#: aleksis/core/preferences.py:387
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:338
+#: aleksis/core/preferences.py:388
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/settings.py:477
+#: aleksis/core/settings.py:470
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:478
+#: aleksis/core/settings.py:471
 msgid "German"
 msgstr ""
 
@@ -2109,25 +2115,20 @@ msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:5
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:6
-msgid "Revoke token"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
+msgid "Revoke access"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:12
-msgid "Are you sure to revoke this token?"
+msgid "Are you sure to revoke the access for this application?"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:20
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
 msgid "Revoke"
 msgstr ""
 
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
-msgid "Authorized applications"
-msgstr ""
-
 #: aleksis/core/templates/oauth2_provider/authorized-tokens.html:33
-msgid "No authorized tokens defined."
+msgid "No authorized applications."
 msgstr ""
 
 #: aleksis/core/templates/offline.html:5
@@ -2171,17 +2172,17 @@ msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:5
 #: aleksis/core/templates/socialaccount/authentication_error.html:6
-msgid "Social Network Login Failure"
+msgid "Third-party Account Login Failure"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:13
-msgid "Social Network Login Failure."
+msgid "Third-party Account Login Failure."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:15
 msgid ""
 "\n"
-"            An error occurred while attempting to login via your social network account.\n"
+"            An error occurred while attempting to login via your third-party account.\n"
 "            Please contact one of your site administrators.\n"
 "          "
 msgstr ""
@@ -2196,11 +2197,11 @@ msgid "Remove"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:34
-msgid "You currently have no social network accounts connected to this account."
+msgid "You currently have no third-party accounts connected to this account."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:37
-msgid "Add a 3rd Party Account"
+msgid "Add a Third-party Account"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/login_cancelled.html:5
@@ -2243,7 +2244,7 @@ msgstr ""
 #: aleksis/core/templates/socialaccount/snippets/provider_list.html:30
 msgid ""
 "\n"
-"          No 3rd party account providers available.\n"
+"          No third-party account providers available.\n"
 "        "
 msgstr ""
 
@@ -2704,109 +2705,109 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:195
+#: aleksis/core/views.py:249
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:207
+#: aleksis/core/views.py:261
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:352
+#: aleksis/core/views.py:406
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:413
+#: aleksis/core/views.py:467
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:452
+#: aleksis/core/views.py:506
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:549
+#: aleksis/core/views.py:603
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:565
+#: aleksis/core/views.py:619
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:649
+#: aleksis/core/views.py:703
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:673
+#: aleksis/core/views.py:727
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:687
+#: aleksis/core/views.py:741
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:719
+#: aleksis/core/views.py:773
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:753
+#: aleksis/core/views.py:807
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:778
+#: aleksis/core/views.py:832
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:808
+#: aleksis/core/views.py:862
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:895
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:842
+#: aleksis/core/views.py:896
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:843
+#: aleksis/core/views.py:897
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:844
+#: aleksis/core/views.py:898
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:860
+#: aleksis/core/views.py:914
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:902
+#: aleksis/core/views.py:956
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:932
+#: aleksis/core/views.py:986
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:942
+#: aleksis/core/views.py:996
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1009
+#: aleksis/core/views.py:1063
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1011
+#: aleksis/core/views.py:1065
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1137
-msgid "The social account could not be disconnected because it is the only login method available."
+#: aleksis/core/views.py:1191
+msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1144
-msgid "The social account has been successfully disconnected."
+#: aleksis/core/views.py:1198
+msgid "The third-party account has been successfully disconnected."
 msgstr ""
 
 #~ msgid "Norwegian (bokmål)"
diff --git a/aleksis/core/locale/nb_NO/LC_MESSAGES/djangojs.po b/aleksis/core/locale/nb_NO/LC_MESSAGES/djangojs.po
index 98db6bb2bfffd75db556c259758c6667c64e4b8d..21ea82be5697cbfadc5dde4d7de1c9006da0569b 100644
--- a/aleksis/core/locale/nb_NO/LC_MESSAGES/djangojs.po
+++ b/aleksis/core/locale/nb_NO/LC_MESSAGES/djangojs.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -29,6 +29,6 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
-#: aleksis/core/static/js/main.js:121
+#: aleksis/core/static/js/main.js:133
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr ""
diff --git a/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po b/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po
index eacabc8470476a0a5a7fb95d69822e585f088458..4c442feb3e797a8acecb2178ea8d5837534700fd 100644
--- a/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po
+++ b/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: AlekSIS (School Information System) 0.1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -260,11 +260,13 @@ msgid "Preferences"
 msgstr ""
 
 #: aleksis/core/menus.py:97
-msgid "Social accounts"
+msgid "Third-party accounts"
 msgstr ""
 
 #: aleksis/core/menus.py:106
-msgid "Authorized tokens"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
+msgid "Authorized applications"
 msgstr ""
 
 #: aleksis/core/menus.py:117
@@ -354,7 +356,7 @@ msgstr ""
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:476
+#: aleksis/core/mixins.py:475
 msgid "Linked school term"
 msgstr ""
 
@@ -903,139 +905,143 @@ msgstr ""
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:39
+#: aleksis/core/preferences.py:41
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:48
+#: aleksis/core/preferences.py:52
 msgid "Site description"
 msgstr ""
 
-#: aleksis/core/preferences.py:57
+#: aleksis/core/preferences.py:63
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:67
+#: aleksis/core/preferences.py:75
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:86
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:84
+#: aleksis/core/preferences.py:96
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:92
+#: aleksis/core/preferences.py:106
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:101
+#: aleksis/core/preferences.py:117
 msgid "Mail out name"
 msgstr ""
 
-#: aleksis/core/preferences.py:110
+#: aleksis/core/preferences.py:128
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:120
+#: aleksis/core/preferences.py:140
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:130
+#: aleksis/core/preferences.py:152
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:140
+#: aleksis/core/preferences.py:164
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:154
+#: aleksis/core/preferences.py:180
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:164
+#: aleksis/core/preferences.py:192
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:173
+#: aleksis/core/preferences.py:203
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:185
+#: aleksis/core/preferences.py:215
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:194
+#: aleksis/core/preferences.py:224
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:203
+#: aleksis/core/preferences.py:235
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:212
+#: aleksis/core/preferences.py:246
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:220
+#: aleksis/core/preferences.py:256
+msgid "Enabled custom authentication backends"
+msgstr ""
+
+#: aleksis/core/preferences.py:268
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:228
+#: aleksis/core/preferences.py:276
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:237
+#: aleksis/core/preferences.py:287
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:249
+#: aleksis/core/preferences.py:299
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:260
+#: aleksis/core/preferences.py:310
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:271
+#: aleksis/core/preferences.py:321
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:280
+#: aleksis/core/preferences.py:330
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:289
+#: aleksis/core/preferences.py:339
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:300
+#: aleksis/core/preferences.py:350
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:314
+#: aleksis/core/preferences.py:364
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:327
+#: aleksis/core/preferences.py:377
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:337
+#: aleksis/core/preferences.py:387
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:338
+#: aleksis/core/preferences.py:388
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/settings.py:477
+#: aleksis/core/settings.py:470
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:478
+#: aleksis/core/settings.py:471
 msgid "German"
 msgstr ""
 
@@ -2109,25 +2115,20 @@ msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:5
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:6
-msgid "Revoke token"
+#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
+msgid "Revoke access"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:12
-msgid "Are you sure to revoke this token?"
+msgid "Are you sure to revoke the access for this application?"
 msgstr ""
 
 #: aleksis/core/templates/oauth2_provider/authorized-token-delete.html:20
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:23
 msgid "Revoke"
 msgstr ""
 
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
-#: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
-msgid "Authorized applications"
-msgstr ""
-
 #: aleksis/core/templates/oauth2_provider/authorized-tokens.html:33
-msgid "No authorized tokens defined."
+msgid "No authorized applications."
 msgstr ""
 
 #: aleksis/core/templates/offline.html:5
@@ -2171,17 +2172,17 @@ msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:5
 #: aleksis/core/templates/socialaccount/authentication_error.html:6
-msgid "Social Network Login Failure"
+msgid "Third-party Account Login Failure"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:13
-msgid "Social Network Login Failure."
+msgid "Third-party Account Login Failure."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/authentication_error.html:15
 msgid ""
 "\n"
-"            An error occurred while attempting to login via your social network account.\n"
+"            An error occurred while attempting to login via your third-party account.\n"
 "            Please contact one of your site administrators.\n"
 "          "
 msgstr ""
@@ -2196,11 +2197,11 @@ msgid "Remove"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:34
-msgid "You currently have no social network accounts connected to this account."
+msgid "You currently have no third-party accounts connected to this account."
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/connections.html:37
-msgid "Add a 3rd Party Account"
+msgid "Add a Third-party Account"
 msgstr ""
 
 #: aleksis/core/templates/socialaccount/login_cancelled.html:5
@@ -2243,7 +2244,7 @@ msgstr ""
 #: aleksis/core/templates/socialaccount/snippets/provider_list.html:30
 msgid ""
 "\n"
-"          No 3rd party account providers available.\n"
+"          No third-party account providers available.\n"
 "        "
 msgstr ""
 
@@ -2704,107 +2705,107 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:195
+#: aleksis/core/views.py:249
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:207
+#: aleksis/core/views.py:261
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:352
+#: aleksis/core/views.py:406
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:413
+#: aleksis/core/views.py:467
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:452
+#: aleksis/core/views.py:506
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:549
+#: aleksis/core/views.py:603
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:565
+#: aleksis/core/views.py:619
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:649
+#: aleksis/core/views.py:703
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:673
+#: aleksis/core/views.py:727
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:687
+#: aleksis/core/views.py:741
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:719
+#: aleksis/core/views.py:773
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:753
+#: aleksis/core/views.py:807
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:778
+#: aleksis/core/views.py:832
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:808
+#: aleksis/core/views.py:862
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:895
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:842
+#: aleksis/core/views.py:896
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:843
+#: aleksis/core/views.py:897
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:844
+#: aleksis/core/views.py:898
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:860
+#: aleksis/core/views.py:914
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:902
+#: aleksis/core/views.py:956
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:932
+#: aleksis/core/views.py:986
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:942
+#: aleksis/core/views.py:996
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1009
+#: aleksis/core/views.py:1063
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1011
+#: aleksis/core/views.py:1065
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1137
-msgid "The social account could not be disconnected because it is the only login method available."
+#: aleksis/core/views.py:1191
+msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1144
-msgid "The social account has been successfully disconnected."
+#: aleksis/core/views.py:1198
+msgid "The third-party account has been successfully disconnected."
 msgstr ""
diff --git a/aleksis/core/locale/tr_TR/LC_MESSAGES/djangojs.po b/aleksis/core/locale/tr_TR/LC_MESSAGES/djangojs.po
index 98db6bb2bfffd75db556c259758c6667c64e4b8d..21ea82be5697cbfadc5dde4d7de1c9006da0569b 100644
--- a/aleksis/core/locale/tr_TR/LC_MESSAGES/djangojs.po
+++ b/aleksis/core/locale/tr_TR/LC_MESSAGES/djangojs.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-21 19:54+0200\n"
+"POT-Creation-Date: 2021-06-08 16:49+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -29,6 +29,6 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
-#: aleksis/core/static/js/main.js:121
+#: aleksis/core/static/js/main.js:133
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr ""
diff --git a/aleksis/core/menus.py b/aleksis/core/menus.py
index 04cfb5689ef101b41f169b970f760aea95ae9338..b368a6c702e4b2514afc903fb5ff48417ef22bfa 100644
--- a/aleksis/core/menus.py
+++ b/aleksis/core/menus.py
@@ -24,7 +24,9 @@ MENUS = {
             "name": _("Dashboard"),
             "url": "index",
             "icon": "home",
-            "validators": ["menu_generator.validators.is_authenticated"],
+            "validators": [
+                ("aleksis.core.util.predicates.permission_validator", "core.view_dashboard_rule")
+            ],
         },
         {
             "name": _("Notifications"),
diff --git a/aleksis/core/preferences.py b/aleksis/core/preferences.py
index 4e1bd8a40744e8374a3c3df041b2832da3f7275d..2dc131eadf7de27b0979bbf347ea4320346701c9 100644
--- a/aleksis/core/preferences.py
+++ b/aleksis/core/preferences.py
@@ -19,13 +19,13 @@ from .models import Group, Person
 from .registries import person_preferences_registry, site_preferences_registry
 from .util.notifications import get_notification_choices_lazy
 
-general = Section("general")
-school = Section("school")
-theme = Section("theme")
-mail = Section("mail")
-notification = Section("notification")
-footer = Section("footer")
-account = Section("account")
+general = Section("general", verbose_name=_("General"))
+school = Section("school", verbose_name=_("School"))
+theme = Section("theme", verbose_name=_("Theme"))
+mail = Section("mail", verbose_name=_("Mail"))
+notification = Section("notification", verbose_name=_("Notifications"))
+footer = Section("footer", verbose_name=_("Footer"))
+account = Section("account", verbose_name=_("Accounts"))
 auth = Section("auth", verbose_name=_("Authentication"))
 internationalisation = Section("internationalisation", verbose_name=_("Internationalisation"))
 
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 4929c4004f4a6028be800866296f1ef8d741c01a..d4b986882fe3f45352622a4987c361093182261e 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -342,11 +342,11 @@ if _settings.get("oauth2.oidc.enabled", False):
     )
     OAUTH2_PROVIDER["SCOPES"].update(
         {
-            "openid": "OpenID Connect scope",
-            "profile": "Profile scope",
-            "phone": "Phone scope",
-            "email": "Email scope",
-            "address": "Address scope",
+            "openid": _("OpenID Connect scope"),
+            "profile": _("Given name, family name, link to profile and picture if existing."),
+            "address": _("Full home postal address"),
+            "email": _("Email address"),
+            "phone": _("Home and mobile phone"),
         }
     )
 
@@ -492,7 +492,6 @@ NODE_MODULES_ROOT = _settings.get("node_modules.root", os.path.join(BASE_DIR, "n
 
 YARN_INSTALLED_APPS = [
     "@fontsource/roboto",
-    "datatables",
     "jquery",
     "materialize-css",
     "material-design-icons-iconfont",
@@ -513,7 +512,6 @@ SELECT2_JS = JS_URL + "/select2/dist/js/select2.min.js"
 SELECT2_I18N_PATH = JS_URL + "/select2/dist/js/i18n"
 
 ANY_JS = {
-    "DataTables": {"js_url": JS_URL + "/datatables/media/js/jquery.dataTables.min.js"},
     "materialize": {"js_url": JS_URL + "/materialize-css/dist/js/materialize.min.js"},
     "jQuery": {"js_url": JS_URL + "/jquery/dist/jquery.min.js"},
     "material-design-icons": {
diff --git a/aleksis/core/static/js/main.js b/aleksis/core/static/js/main.js
index 0447bbda10f8120460831706e1c3569d0a7a2d62..1d2a2fe28e3c4304e72d8abfc398f0fda3908586 100644
--- a/aleksis/core/static/js/main.js
+++ b/aleksis/core/static/js/main.js
@@ -91,12 +91,6 @@ $(document).ready(function () {
         $("#" + $(this).data("preview")).css("color", $(this).val());
     });
 
-    $('table.datatable').each(function (index) {
-        $(this).DataTable({
-            "paging": false
-        });
-    });
-
     // Initialise auto-completion for search bar
     window.autocomplete = new Autocomplete({minimum_length: 2});
     window.autocomplete.setup();
diff --git a/aleksis/core/static/style.scss b/aleksis/core/static/style.scss
index bb8af0da25a60b355eaebe66c5d56473eef961a3..2b30ab8960949c564ec8a48bc04f7dd1f4beb3b9 100644
--- a/aleksis/core/static/style.scss
+++ b/aleksis/core/static/style.scss
@@ -513,6 +513,16 @@ th.orderable.desc > a {
   margin: 0;
 }
 
+.alert strong {
+  font-weight: 700;
+}
+
+.alert h1 {
+  font-weight: 700;
+  font-size: 17px;
+  margin: auto;
+}
+
 .alert > p, .alert > div {
   margin: 10px;
   padding: 10px;
diff --git a/aleksis/core/templates/core/index.html b/aleksis/core/templates/core/index.html
index 6bbbab8ecfbe2768d12eb139fae110ac5cf62371..d1606fca9be70a4d4a98c1b6974f2b84f22948f5 100644
--- a/aleksis/core/templates/core/index.html
+++ b/aleksis/core/templates/core/index.html
@@ -30,7 +30,7 @@
           </a>
         </div>
 
-        <strong>{{ notification.title }}</strong>
+        <h1>{{ notification.title }}</h1>
         <p>{{ notification.description|linebreaks }}</p>
       </div>
     </div>
diff --git a/aleksis/core/templates/core/partials/announcements.html b/aleksis/core/templates/core/partials/announcements.html
index 2c74bead64e6c0f0f9da1753114d76357c2994e1..b0032d0dd6888f9ebcd7e6f881501178fc17e2a9 100644
--- a/aleksis/core/templates/core/partials/announcements.html
+++ b/aleksis/core/templates/core/partials/announcements.html
@@ -26,7 +26,7 @@
       {% endif %}
 
       <p>
-        <strong>{{ announcement.title }}</strong> <br/>
+        <h1>{{ announcement.title }}</h1>
         {{ announcement.description }}
       </p>
 
diff --git a/aleksis/core/templates/oauth2_provider/authorize.html b/aleksis/core/templates/oauth2_provider/authorize.html
index 53c005d2c7d983bd2e98557104d8eccc24cc68cd..5eaf3151021c27fd24b8e19e195a4a2e14d5279a 100644
--- a/aleksis/core/templates/oauth2_provider/authorize.html
+++ b/aleksis/core/templates/oauth2_provider/authorize.html
@@ -16,7 +16,7 @@
             {% trans "Authorize" %} {{ application.name }}
           </div>
           <p class="margin-bottom">{% trans "The application requests access to the following scopes:" %}</p>
-          {% for scope in scopes %}
+          {% for scope in scopes_descriptions %}
             <p class="margin-bottom">
               <i class="material-icons left">check</i>
               {{ scope }}
diff --git a/aleksis/core/util/apps.py b/aleksis/core/util/apps.py
index dad5878cad301ab00b443d2bc10b9a8246034cdb..5f597af29b10363ca003622e347bc76380864efd 100644
--- a/aleksis/core/util/apps.py
+++ b/aleksis/core/util/apps.py
@@ -46,7 +46,7 @@ class AppConfig(django.apps.AppConfig):
         if dist_name:
             try:
                 dist = metadata.distribution(dist_name)
-            except PackageNotFoundError:
+            except metadata.PackageNotFoundError:
                 return None
 
             return dist
diff --git a/docs/conf.py b/docs/conf.py
index 136f619aebbbcefc457b9e1d316c6aa70b670e7a..d9c69295a6c39129874192df57b4f0facd442609 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -31,7 +31,7 @@ author = "AlekSIS team"
 # The short X.Y version
 version = "2.0"
 # The full version, including alpha/beta/rc tags
-release = "2.0b0"
+release = "2.0b2"
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/poetry.lock b/poetry.lock
index d3234cf58b7f5080a361249ee9f6e85f2eae8d57..cf8c75e8b9bfe09eb20e9e1c159591ec08d702f2 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -215,20 +215,20 @@ python-versions = "*"
 
 [[package]]
 name = "boto3"
-version = "1.17.83"
+version = "1.17.94"
 description = "The AWS SDK for Python"
 category = "main"
 optional = true
 python-versions = ">= 2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
 
 [package.dependencies]
-botocore = ">=1.20.83,<1.21.0"
+botocore = ">=1.20.94,<1.21.0"
 jmespath = ">=0.7.1,<1.0.0"
 s3transfer = ">=0.4.0,<0.5.0"
 
 [[package]]
 name = "botocore"
-version = "1.20.83"
+version = "1.20.94"
 description = "Low-level, data-driven core of boto 3."
 category = "main"
 optional = true
@@ -345,7 +345,7 @@ websockets = ["channels"]
 
 [[package]]
 name = "certifi"
-version = "2020.12.5"
+version = "2021.5.30"
 description = "Python package for providing Mozilla's CA Bundle."
 category = "main"
 optional = false
@@ -405,7 +405,7 @@ dev = ["pytest (>=3.6)", "pytest-cov", "wheel", "coveralls"]
 
 [[package]]
 name = "click-repl"
-version = "0.1.6"
+version = "0.2.0"
 description = "REPL plugin for Click"
 category = "main"
 optional = false
@@ -454,9 +454,6 @@ category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
 
-[package.dependencies]
-toml = {version = "*", optional = true, markers = "extra == \"toml\""}
-
 [package.extras]
 toml = ["toml"]
 
@@ -513,6 +510,20 @@ category = "main"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
+[[package]]
+name = "deprecated"
+version = "1.2.12"
+description = "Python @deprecated decorator to deprecate old python classes, functions or methods."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[package.dependencies]
+wrapt = ">=1.10,<2"
+
+[package.extras]
+dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"]
+
 [[package]]
 name = "dj-database-url"
 version = "0.5.0"
@@ -523,7 +534,7 @@ python-versions = "*"
 
 [[package]]
 name = "django"
-version = "3.2.3"
+version = "3.2.4"
 description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
 category = "main"
 optional = false
@@ -661,18 +672,18 @@ django-appconf = "*"
 
 [[package]]
 name = "django-celery-results"
-version = "2.0.1"
+version = "2.1.0"
 description = "Celery result backends for Django."
 category = "main"
 optional = false
 python-versions = "*"
 
 [package.dependencies]
-celery = ">=4.4,<6.0"
+celery = ">=5.0,<6.0"
 
 [[package]]
 name = "django-ckeditor"
-version = "6.0.0"
+version = "6.1.0"
 description = "Django admin CKEditor integration."
 category = "main"
 optional = false
@@ -930,7 +941,7 @@ six = "*"
 
 [[package]]
 name = "django-otp"
-version = "1.0.5"
+version = "1.0.6"
 description = "A pluggable framework for adding two-factor authentication to Django using one-time passwords."
 category = "main"
 optional = false
@@ -1112,7 +1123,7 @@ tablib = ["tablib"]
 
 [[package]]
 name = "django-templated-email"
-version = "2.4.0"
+version = "3.0.0"
 description = "A Django oriented templated / transaction email abstraction"
 category = "main"
 optional = false
@@ -1262,7 +1273,7 @@ yaml = ["ruamel.yaml"]
 
 [[package]]
 name = "faker"
-version = "8.4.0"
+version = "8.8.0"
 description = "Faker is a Python package that generates fake data for you."
 category = "main"
 optional = false
@@ -1489,7 +1500,7 @@ python-versions = "*"
 
 [[package]]
 name = "ipython"
-version = "7.23.1"
+version = "7.24.1"
 description = "IPython: Productive Interactive Computing"
 category = "main"
 optional = false
@@ -1509,7 +1520,7 @@ pygments = "*"
 traitlets = ">=4.2"
 
 [package.extras]
-all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.16)", "pygments", "qtconsole", "requests", "testpath"]
+all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"]
 doc = ["Sphinx (>=1.3)"]
 kernel = ["ipykernel"]
 nbconvert = ["nbconvert"]
@@ -1517,7 +1528,7 @@ nbformat = ["nbformat"]
 notebook = ["notebook", "ipywidgets"]
 parallel = ["ipyparallel"]
 qtconsole = ["qtconsole"]
-test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.16)"]
+test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"]
 
 [[package]]
 name = "ipython-genutils"
@@ -1579,7 +1590,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 
 [[package]]
 name = "jwcrypto"
-version = "0.8"
+version = "0.9.1"
 description = "Implementation of JOSE Web standards"
 category = "main"
 optional = false
@@ -1587,6 +1598,8 @@ python-versions = "*"
 
 [package.dependencies]
 cryptography = ">=2.3"
+deprecated = "*"
+six = "*"
 
 [[package]]
 name = "kombu"
@@ -1667,7 +1680,7 @@ python-versions = "*"
 
 [[package]]
 name = "mypy"
-version = "0.812"
+version = "0.902"
 description = "Optional static typing for Python"
 category = "dev"
 optional = false
@@ -1675,11 +1688,12 @@ python-versions = ">=3.5"
 
 [package.dependencies]
 mypy-extensions = ">=0.4.3,<0.5.0"
-typed-ast = ">=1.4.0,<1.5.0"
+toml = "*"
 typing-extensions = ">=3.7.4"
 
 [package.extras]
 dmypy = ["psutil (>=4.0)"]
+python2 = ["typed-ast (>=1.4.0,<1.5.0)"]
 
 [[package]]
 name = "mypy-extensions"
@@ -1691,16 +1705,16 @@ python-versions = "*"
 
 [[package]]
 name = "oauthlib"
-version = "3.1.0"
+version = "3.1.1"
 description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
 category = "main"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.6"
 
 [package.extras]
-rsa = ["cryptography"]
-signals = ["blinker"]
-signedtoken = ["cryptography", "pyjwt (>=1.0.0)"]
+rsa = ["cryptography (>=3.0.0,<4)"]
+signals = ["blinker (>=1.4.0)"]
+signedtoken = ["cryptography (>=3.0.0,<4)", "pyjwt (>=2.0.0,<3)"]
 
 [[package]]
 name = "packaging"
@@ -1816,7 +1830,7 @@ dev = ["pre-commit", "tox"]
 
 [[package]]
 name = "prometheus-client"
-version = "0.10.1"
+version = "0.11.0"
 description = "Python client for the Prometheus monitoring system."
 category = "main"
 optional = false
@@ -1992,22 +2006,23 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm
 
 [[package]]
 name = "pytest-cov"
-version = "2.12.0"
+version = "2.12.1"
 description = "Pytest plugin for measuring coverage."
 category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [package.dependencies]
-coverage = {version = ">=5.2.1", extras = ["toml"]}
+coverage = ">=5.2.1"
 pytest = ">=4.6"
+toml = "*"
 
 [package.extras]
-testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"]
+testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"]
 
 [[package]]
 name = "pytest-django"
-version = "4.3.0"
+version = "4.4.0"
 description = "A Django plugin for pytest."
 category = "dev"
 optional = false
@@ -2197,7 +2212,7 @@ docutils = ">=0.11,<1.0"
 
 [[package]]
 name = "ruamel.yaml"
-version = "0.17.4"
+version = "0.17.9"
 description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
 category = "main"
 optional = false
@@ -2533,7 +2548,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 
 [[package]]
 name = "tqdm"
-version = "4.61.0"
+version = "4.61.1"
 description = "Fast, Extensible Progress Meter"
 category = "main"
 optional = false
@@ -2641,6 +2656,14 @@ category = "main"
 optional = false
 python-versions = "*"
 
+[[package]]
+name = "wrapt"
+version = "1.12.1"
+description = "Module for decorators, wrappers and monkey patching."
+category = "main"
+optional = false
+python-versions = "*"
+
 [[package]]
 name = "yubiotp"
 version = "1.0.0.post1"
@@ -2659,7 +2682,7 @@ s3 = ["boto3", "django-storages"]
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.9"
-content-hash = "90224f9149be3a385e33e37cec650a35637055343fe58e28f4e7e5041de1a0ab"
+content-hash = "477a29a1861c9fd3bdeec9acfe0b2ec23e3f0fd10942673c290bc13a677c8144"
 
 [metadata.files]
 alabaster = [
@@ -2668,7 +2691,6 @@ alabaster = [
 ]
 aleksis-builddeps = [
     {file = "AlekSIS-Builddeps-4.tar.gz", hash = "sha256:aaaa22965228b9b9b7de812e3e7fa9cbfdbf8635bb22d6f3a201dc0cc6d8d307"},
-    {file = "AlekSIS_Builddeps-4-py3-none-any.whl", hash = "sha256:02a93e503f5810e6c93a8bc829bc8cbda735ccbf78b91954d2f6507dfea3d01f"},
 ]
 amqp = [
     {file = "amqp-5.0.6-py3-none-any.whl", hash = "sha256:493a2ac6788ce270a2f6a765b017299f60c1998f5a8617908ee9be082f7300fb"},
@@ -2732,12 +2754,12 @@ bleach = [
     {file = "boolean.py-3.8.tar.gz", hash = "sha256:cc24e20f985d60cd4a3a5a1c0956dd12611159d32a75081dabd0c9ab981acaa4"},
 ]
 boto3 = [
-    {file = "boto3-1.17.83-py2.py3-none-any.whl", hash = "sha256:40ccb6ec2d7e5e4d250d630a245aae7aa1fcd43c3519e9808b444f083ca4014a"},
-    {file = "boto3-1.17.83.tar.gz", hash = "sha256:e6fa13cd8f16a6c222104ab17e0439e24b6974f60e7af113a38a80f252457cb0"},
+    {file = "boto3-1.17.94-py2.py3-none-any.whl", hash = "sha256:6180272094030bda3ee5c242881892cd3d9d19c05cb513945f530e396c7de1e4"},
+    {file = "boto3-1.17.94.tar.gz", hash = "sha256:95d814d16fe55ae55e1e4a3db248596f9647a0c42f4796c6e05be0bfaffb1830"},
 ]
 botocore = [
-    {file = "botocore-1.20.83-py2.py3-none-any.whl", hash = "sha256:b36c14cfe208969ee9f658b645cfc718c1700c593313787a3fd59b335f7a6e2c"},
-    {file = "botocore-1.20.83.tar.gz", hash = "sha256:55d450b6bf0df642809fe88a6840d90dab6b6ad5ff3dccaa1faf9e085dfd864a"},
+    {file = "botocore-1.20.94-py2.py3-none-any.whl", hash = "sha256:ba8a7951be535e25219a82dea15c30d7bdf0c51e7c1623c3306248493c1616ac"},
+    {file = "botocore-1.20.94.tar.gz", hash = "sha256:60a382a5b2f7d77b1b575d54fba819097526e3fdd0f3004f4d1142d50af0d642"},
 ]
 bs4 = [
     {file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"},
@@ -2758,8 +2780,8 @@ celery-progress = [
     {file = "celery_progress-0.1.0-py3-none-any.whl", hash = "sha256:01bc7ecb2483ed7085b957413a392f85b7e1002fc8ce6d24f3d1ff264173002d"},
 ]
 certifi = [
-    {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"},
-    {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"},
+    {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"},
+    {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"},
 ]
 cffi = [
     {file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"},
@@ -2828,8 +2850,8 @@ click-plugins = [
     {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"},
 ]
 click-repl = [
-    {file = "click-repl-0.1.6.tar.gz", hash = "sha256:b9f29d52abc4d6059f8e276132a111ab8d94980afe6a5432b9d996544afa95d5"},
-    {file = "click_repl-0.1.6-py3-none-any.whl", hash = "sha256:9c4c3d022789cae912aad8a3f5e1d7c2cdd016ee1225b5212ad3e8691563cda5"},
+    {file = "click-repl-0.2.0.tar.gz", hash = "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8"},
+    {file = "click_repl-0.2.0-py3-none-any.whl", hash = "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b"},
 ]
 colorama = [
     {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
@@ -2922,13 +2944,17 @@ defusedxml = [
     {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
     {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
 ]
+deprecated = [
+    {file = "Deprecated-1.2.12-py2.py3-none-any.whl", hash = "sha256:08452d69b6b5bc66e8330adde0a4f8642e969b9e1702904d137eeb29c8ffc771"},
+    {file = "Deprecated-1.2.12.tar.gz", hash = "sha256:6d2de2de7931a968874481ef30208fd4e08da39177d61d3d4ebdf4366e7dbca1"},
+]
 dj-database-url = [
     {file = "dj-database-url-0.5.0.tar.gz", hash = "sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163"},
     {file = "dj_database_url-0.5.0-py2.py3-none-any.whl", hash = "sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9"},
 ]
 django = [
-    {file = "Django-3.2.3-py3-none-any.whl", hash = "sha256:7e0a1393d18c16b503663752a8b6790880c5084412618990ce8a81cc908b4962"},
-    {file = "Django-3.2.3.tar.gz", hash = "sha256:13ac78dbfd189532cad8f383a27e58e18b3d33f80009ceb476d7fcbfc5dcebd8"},
+    {file = "Django-3.2.4-py3-none-any.whl", hash = "sha256:ea735cbbbb3b2fba6d4da4784a0043d84c67c92f1fdf15ad6db69900e792c10f"},
+    {file = "Django-3.2.4.tar.gz", hash = "sha256:66c9d8db8cc6fe938a28b7887c1596e42d522e27618562517cc8929eb7e7f296"},
 ]
 django-allauth = [
     {file = "django-allauth-0.44.0.tar.gz", hash = "sha256:e51af457466022f52154d74c8523ac69375120fad2acce6e239635d85e610b25"},
@@ -2970,12 +2996,12 @@ django-celery-email = [
     {file = "django_celery_email-3.0.0-py2.py3-none-any.whl", hash = "sha256:0f72da39cb2ea83c69440566e87f27cd72f68f247f98ce99fb29889fcf329406"},
 ]
 django-celery-results = [
-    {file = "django_celery_results-2.0.1-py2.py3-none-any.whl", hash = "sha256:a2f7d172f7f57dd972538acc6e80a5bf50c673fb4d82fe027189c8659c60dfce"},
-    {file = "django_celery_results-2.0.1.tar.gz", hash = "sha256:d625e324138e5b2ef46ffa9e89fa353c16d619420066ac8b240ef9247b293a84"},
+    {file = "django_celery_results-2.1.0-py2.py3-none-any.whl", hash = "sha256:f0965bf43f7d09ffe792806a2a36f6874256fb0bd56037528676dfb051be0794"},
+    {file = "django_celery_results-2.1.0.tar.gz", hash = "sha256:b5abe0c03c91dc8fe657e0c2a34c9604175838af13cb8c7f64654b3ad27febcf"},
 ]
 django-ckeditor = [
-    {file = "django-ckeditor-6.0.0.tar.gz", hash = "sha256:29fd1a333cb9741ac2c3fd4e427a5c00115ed33a2389716a09af7656022dcdde"},
-    {file = "django_ckeditor-6.0.0-py2.py3-none-any.whl", hash = "sha256:cc2d377f1bdcd4ca1540caeebe85f7e2cd006198d57328ef6c718d3eaa5a0846"},
+    {file = "django-ckeditor-6.1.0.tar.gz", hash = "sha256:f0d108f67a81a04e26d8de11255fe314f51026eaf8eb0534a807512ae3c21620"},
+    {file = "django_ckeditor-6.1.0-py2.py3-none-any.whl", hash = "sha256:346b26b9d60dc8a88524d0eaaf406f4e91a4b3c22d208ae87aa032bf500b251c"},
 ]
 django-cleanup = [
     {file = "django-cleanup-5.2.0.tar.gz", hash = "sha256:909d10ff574f5ce1a40fa63bd5c94c9ed866fd7ae770994c46cdf66c3db3e846"},
@@ -3065,8 +3091,8 @@ django-oauth-toolkit = [
     {file = "django_oauth_toolkit-1.5.0-py3-none-any.whl", hash = "sha256:b2e346a7c1e222774bfb370f21b556b92b408395b4c23914e2d1b241b2e5376a"},
 ]
 django-otp = [
-    {file = "django-otp-1.0.5.tar.gz", hash = "sha256:cc657a0e7266cda6ab42f861bdc3840ed24f7e441bc7f249916174dd1a6375a0"},
-    {file = "django_otp-1.0.5-py3-none-any.whl", hash = "sha256:75a815747a0542cc5442e3a6396dfd272c49a0866bee2149ac57ecc36ddd3961"},
+    {file = "django-otp-1.0.6.tar.gz", hash = "sha256:0d56dd2a7fbb6ee6e54557e036ca64add0bd3596f471794bad673b7637d5e935"},
+    {file = "django_otp-1.0.6-py3-none-any.whl", hash = "sha256:01b5888f0bde5125e139433aacb947e52d5c406fa56c9db43c3e8d75b5c323c4"},
 ]
 django-otp-yubikey = [
     {file = "django-otp-yubikey-1.0.0.post1.tar.gz", hash = "sha256:1da060257611d06e681848b7923fd788d878a79e8c358a373374deab13a085af"},
@@ -3121,7 +3147,8 @@ django-tables2 = [
     {file = "django_tables2-2.4.0-py2.py3-none-any.whl", hash = "sha256:0f10ecef25708385a9d32d68d7c9478ca8dda31569410cb05a025be3f2c57593"},
 ]
 django-templated-email = [
-    {file = "django-templated-email-2.4.0.tar.gz", hash = "sha256:3bcd95cb806070b13c9919a72fec944b5ce319e30e8828a08180767bb1f84027"},
+    {file = "django-templated-email-3.0.0.tar.gz", hash = "sha256:49d61840ec551e640adaf341146e94d6f9058ae01df964480850bf988046e5eb"},
+    {file = "django_templated_email-3.0.0-py3-none-any.whl", hash = "sha256:bf1b68ffe6c8794c0c50e2ce20e3a166c6d511b3879abbd3cf059a3fc2fe2e60"},
 ]
 django-timezone-field = [
     {file = "django-timezone-field-4.1.2.tar.gz", hash = "sha256:cffac62452d060e365938aa9c9f7b72d70d8b26b9c60243bce227b35abd1b9df"},
@@ -3163,8 +3190,8 @@ dynaconf = [
     {file = "dynaconf-3.1.4.tar.gz", hash = "sha256:b2f472d83052f809c5925565b8a2ba76a103d5dc1dbb9748b693ed67212781b9"},
 ]
 faker = [
-    {file = "Faker-8.4.0-py3-none-any.whl", hash = "sha256:5b1c0781c0c2f6b177adf4018feec265bbcd0118b301dbec64a1908c29124ed6"},
-    {file = "Faker-8.4.0.tar.gz", hash = "sha256:c94240c40073400b269c50b14da765fd4d3b4dda8ae25c2753afc809c72f1062"},
+    {file = "Faker-8.8.0-py3-none-any.whl", hash = "sha256:0129599c0d35e79471d116460b1c51d8c183980f28e14517228be4601cf87192"},
+    {file = "Faker-8.8.0.tar.gz", hash = "sha256:7be0d9309bde6624e1a6062d0dc37859f95ca883fa047a11db8e5e305b1446a1"},
 ]
 flake8 = [
     {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
@@ -3242,8 +3269,8 @@ iniconfig = [
     {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
 ]
 ipython = [
-    {file = "ipython-7.23.1-py3-none-any.whl", hash = "sha256:f78c6a3972dde1cc9e4041cbf4de583546314ba52d3c97208e5b6b2221a9cb7d"},
-    {file = "ipython-7.23.1.tar.gz", hash = "sha256:714810a5c74f512b69d5f3b944c86e592cee0a5fb9c728e582f074610f6cf038"},
+    {file = "ipython-7.24.1-py3-none-any.whl", hash = "sha256:d513e93327cf8657d6467c81f1f894adc125334ffe0e4ddd1abbb1c78d828703"},
+    {file = "ipython-7.24.1.tar.gz", hash = "sha256:9bc24a99f5d19721fb8a2d1408908e9c0520a17fff2233ffe82620847f17f1b6"},
 ]
 ipython-genutils = [
     {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"},
@@ -3266,8 +3293,8 @@ jmespath = [
     {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"},
 ]
 jwcrypto = [
-    {file = "jwcrypto-0.8-py2.py3-none-any.whl", hash = "sha256:16e17faa4dce36551ade3a3ccb06236a61e5924ea1db163c9be9827acf935a82"},
-    {file = "jwcrypto-0.8.tar.gz", hash = "sha256:b7fee2635bbefdf145399392f5be26ad54161c8271c66b5fe107b4b452f06c24"},
+    {file = "jwcrypto-0.9.1-py2.py3-none-any.whl", hash = "sha256:12976a09895ec0076ce17c49ab7be64d6e63bcd7fd9a773e3fedf8011537a5f6"},
+    {file = "jwcrypto-0.9.1.tar.gz", hash = "sha256:63531529218ba9869e14ef8c9e7b516865ede3facf9b0ef3d3ba68014da211f9"},
 ]
 kombu = [
     {file = "kombu-5.1.0-py3-none-any.whl", hash = "sha256:e2dedd8a86c9077c350555153825a31e456a0dc20c15d5751f00137ec9c75f0a"},
@@ -3333,36 +3360,37 @@ mccabe = [
     {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
 ]
 mypy = [
-    {file = "mypy-0.812-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a26f8ec704e5a7423c8824d425086705e381b4f1dfdef6e3a1edab7ba174ec49"},
-    {file = "mypy-0.812-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:28fb5479c494b1bab244620685e2eb3c3f988d71fd5d64cc753195e8ed53df7c"},
-    {file = "mypy-0.812-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:9743c91088d396c1a5a3c9978354b61b0382b4e3c440ce83cf77994a43e8c521"},
-    {file = "mypy-0.812-cp35-cp35m-win_amd64.whl", hash = "sha256:d7da2e1d5f558c37d6e8c1246f1aec1e7349e4913d8fb3cb289a35de573fe2eb"},
-    {file = "mypy-0.812-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4eec37370483331d13514c3f55f446fc5248d6373e7029a29ecb7b7494851e7a"},
-    {file = "mypy-0.812-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d65cc1df038ef55a99e617431f0553cd77763869eebdf9042403e16089fe746c"},
-    {file = "mypy-0.812-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:61a3d5b97955422964be6b3baf05ff2ce7f26f52c85dd88db11d5e03e146a3a6"},
-    {file = "mypy-0.812-cp36-cp36m-win_amd64.whl", hash = "sha256:25adde9b862f8f9aac9d2d11971f226bd4c8fbaa89fb76bdadb267ef22d10064"},
-    {file = "mypy-0.812-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:552a815579aa1e995f39fd05dde6cd378e191b063f031f2acfe73ce9fb7f9e56"},
-    {file = "mypy-0.812-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:499c798053cdebcaa916eef8cd733e5584b5909f789de856b482cd7d069bdad8"},
-    {file = "mypy-0.812-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:5873888fff1c7cf5b71efbe80e0e73153fe9212fafdf8e44adfe4c20ec9f82d7"},
-    {file = "mypy-0.812-cp37-cp37m-win_amd64.whl", hash = "sha256:9f94aac67a2045ec719ffe6111df543bac7874cee01f41928f6969756e030564"},
-    {file = "mypy-0.812-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d23e0ea196702d918b60c8288561e722bf437d82cb7ef2edcd98cfa38905d506"},
-    {file = "mypy-0.812-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:674e822aa665b9fd75130c6c5f5ed9564a38c6cea6a6432ce47eafb68ee578c5"},
-    {file = "mypy-0.812-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:abf7e0c3cf117c44d9285cc6128856106183938c68fd4944763003decdcfeb66"},
-    {file = "mypy-0.812-cp38-cp38-win_amd64.whl", hash = "sha256:0d0a87c0e7e3a9becdfbe936c981d32e5ee0ccda3e0f07e1ef2c3d1a817cf73e"},
-    {file = "mypy-0.812-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7ce3175801d0ae5fdfa79b4f0cfed08807af4d075b402b7e294e6aa72af9aa2a"},
-    {file = "mypy-0.812-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b09669bcda124e83708f34a94606e01b614fa71931d356c1f1a5297ba11f110a"},
-    {file = "mypy-0.812-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:33f159443db0829d16f0a8d83d94df3109bb6dd801975fe86bacb9bf71628e97"},
-    {file = "mypy-0.812-cp39-cp39-win_amd64.whl", hash = "sha256:3f2aca7f68580dc2508289c729bd49ee929a436208d2b2b6aab15745a70a57df"},
-    {file = "mypy-0.812-py3-none-any.whl", hash = "sha256:2f9b3407c58347a452fc0736861593e105139b905cca7d097e413453a1d650b4"},
-    {file = "mypy-0.812.tar.gz", hash = "sha256:cd07039aa5df222037005b08fbbfd69b3ab0b0bd7a07d7906de75ae52c4e3119"},
+    {file = "mypy-0.902-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3f12705eabdd274b98f676e3e5a89f247ea86dc1af48a2d5a2b080abac4e1243"},
+    {file = "mypy-0.902-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:2f9fedc1f186697fda191e634ac1d02f03d4c260212ccb018fabbb6d4b03eee8"},
+    {file = "mypy-0.902-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:0756529da2dd4d53d26096b7969ce0a47997123261a5432b48cc6848a2cb0bd4"},
+    {file = "mypy-0.902-cp35-cp35m-win_amd64.whl", hash = "sha256:68a098c104ae2b75e946b107ef69dd8398d54cb52ad57580dfb9fc78f7f997f0"},
+    {file = "mypy-0.902-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cd01c599cf9f897b6b6c6b5d8b182557fb7d99326bcdf5d449a0fbbb4ccee4b9"},
+    {file = "mypy-0.902-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e89880168c67cf4fde4506b80ee42f1537ad66ad366c101d388b3fd7d7ce2afd"},
+    {file = "mypy-0.902-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ebe2bc9cb638475f5d39068d2dbe8ae1d605bb8d8d3ff281c695df1670ab3987"},
+    {file = "mypy-0.902-cp36-cp36m-win_amd64.whl", hash = "sha256:f89bfda7f0f66b789792ab64ce0978e4a991a0e4dd6197349d0767b0f1095b21"},
+    {file = "mypy-0.902-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:746e0b0101b8efec34902810047f26a8c80e1efbb4fc554956d848c05ef85d76"},
+    {file = "mypy-0.902-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0190fb77e93ce971954c9e54ea61de2802065174e5e990c9d4c1d0f54fbeeca2"},
+    {file = "mypy-0.902-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:b5dfcd22c6bab08dfeded8d5b44bdcb68c6f1ab261861e35c470b89074f78a70"},
+    {file = "mypy-0.902-cp37-cp37m-win_amd64.whl", hash = "sha256:b5ba1f0d5f9087e03bf5958c28d421a03a4c1ad260bf81556195dffeccd979c4"},
+    {file = "mypy-0.902-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9ef5355eaaf7a23ab157c21a44c614365238a7bdb3552ec3b80c393697d974e1"},
+    {file = "mypy-0.902-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:517e7528d1be7e187a5db7f0a3e479747307c1b897d9706b1c662014faba3116"},
+    {file = "mypy-0.902-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:fd634bc17b1e2d6ce716f0e43446d0d61cdadb1efcad5c56ca211c22b246ebc8"},
+    {file = "mypy-0.902-cp38-cp38-win_amd64.whl", hash = "sha256:fc4d63da57ef0e8cd4ab45131f3fe5c286ce7dd7f032650d0fbc239c6190e167"},
+    {file = "mypy-0.902-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:353aac2ce41ddeaf7599f1c73fed2b75750bef3b44b6ad12985a991bc002a0da"},
+    {file = "mypy-0.902-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae94c31bb556ddb2310e4f913b706696ccbd43c62d3331cd3511caef466871d2"},
+    {file = "mypy-0.902-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:8be7bbd091886bde9fcafed8dd089a766fa76eb223135fe5c9e9798f78023a20"},
+    {file = "mypy-0.902-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:4efc67b9b3e2fddbe395700f91d5b8deb5980bfaaccb77b306310bd0b9e002eb"},
+    {file = "mypy-0.902-cp39-cp39-win_amd64.whl", hash = "sha256:9f1d74eeb3f58c7bd3f3f92b8f63cb1678466a55e2c4612bf36909105d0724ab"},
+    {file = "mypy-0.902-py3-none-any.whl", hash = "sha256:a26d0e53e90815c765f91966442775cf03b8a7514a4e960de7b5320208b07269"},
+    {file = "mypy-0.902.tar.gz", hash = "sha256:9236c21194fde5df1b4d8ebc2ef2c1f2a5dc7f18bcbea54274937cae2e20a01c"},
 ]
 mypy-extensions = [
     {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
     {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
 ]
 oauthlib = [
-    {file = "oauthlib-3.1.0-py2.py3-none-any.whl", hash = "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"},
-    {file = "oauthlib-3.1.0.tar.gz", hash = "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889"},
+    {file = "oauthlib-3.1.1-py2.py3-none-any.whl", hash = "sha256:42bf6354c2ed8c6acb54d971fce6f88193d97297e18602a3a886603f9d7730cc"},
+    {file = "oauthlib-3.1.1.tar.gz", hash = "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3"},
 ]
 packaging = [
     {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"},
@@ -3436,6 +3464,7 @@ pillow = [
     {file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_i686.whl", hash = "sha256:aac00e4bc94d1b7813fe882c28990c1bc2f9d0e1aa765a5f2b516e8a6a16a9e4"},
     {file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:22fd0f42ad15dfdde6c581347eaa4adb9a6fc4b865f90b23378aa7914895e120"},
     {file = "Pillow-8.2.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:e98eca29a05913e82177b3ba3d198b1728e164869c613d76d0de4bde6768a50e"},
+    {file = "Pillow-8.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8b56553c0345ad6dcb2e9b433ae47d67f95fc23fe28a0bde15a120f25257e291"},
     {file = "Pillow-8.2.0.tar.gz", hash = "sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1"},
 ]
 pluggy = [
@@ -3443,8 +3472,8 @@ pluggy = [
     {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
 ]
 prometheus-client = [
-    {file = "prometheus_client-0.10.1-py2.py3-none-any.whl", hash = "sha256:030e4f9df5f53db2292eec37c6255957eb76168c6f974e4176c711cf91ed34aa"},
-    {file = "prometheus_client-0.10.1.tar.gz", hash = "sha256:b6c5a9643e3545bcbfd9451766cbaa5d9c67e7303c7bc32c750b6fa70ecb107d"},
+    {file = "prometheus_client-0.11.0-py2.py3-none-any.whl", hash = "sha256:b014bc76815eb1399da8ce5fc84b7717a3e63652b0c0f8804092c9363acab1b2"},
+    {file = "prometheus_client-0.11.0.tar.gz", hash = "sha256:3a8baade6cb80bcfe43297e33e7623f3118d660d41387593758e2fb1ea173a86"},
 ]
 prompt-toolkit = [
     {file = "prompt_toolkit-3.0.18-py3-none-any.whl", hash = "sha256:bf00f22079f5fadc949f42ae8ff7f05702826a97059ffcc6281036ad40ac6f04"},
@@ -3600,12 +3629,12 @@ pytest = [
     {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"},
 ]
 pytest-cov = [
-    {file = "pytest-cov-2.12.0.tar.gz", hash = "sha256:8535764137fecce504a49c2b742288e3d34bc09eed298ad65963616cc98fd45e"},
-    {file = "pytest_cov-2.12.0-py2.py3-none-any.whl", hash = "sha256:95d4933dcbbacfa377bb60b29801daa30d90c33981ab2a79e9ab4452c165066e"},
+    {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"},
+    {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"},
 ]
 pytest-django = [
-    {file = "pytest-django-4.3.0.tar.gz", hash = "sha256:d1c6758a592fb0ef8abaa2fe12dd28858c1dcfc3d466102ffe52aa8934733dca"},
-    {file = "pytest_django-4.3.0-py3-none-any.whl", hash = "sha256:f96c4556f4e7b15d987dd1dcc1d1526df81d40c1548d31ce840d597ed2be8c46"},
+    {file = "pytest-django-4.4.0.tar.gz", hash = "sha256:b5171e3798bf7e3fc5ea7072fe87324db67a4dd9f1192b037fed4cc3c1b7f455"},
+    {file = "pytest_django-4.4.0-py3-none-any.whl", hash = "sha256:65783e78382456528bd9d79a35843adde9e6a47347b20464eb2c885cb0f1f606"},
 ]
 pytest-django-testing-postgresql = [
     {file = "pytest-django-testing-postgresql-0.1.post0.tar.gz", hash = "sha256:78b0c58930084cb4393407b2e5a2a3b8734c627b841ecef7d62d39bbfb8e8a45"},
@@ -3727,8 +3756,8 @@ restructuredtext-lint = [
     {file = "restructuredtext_lint-1.3.2.tar.gz", hash = "sha256:d3b10a1fe2ecac537e51ae6d151b223b78de9fafdd50e5eb6b08c243df173c80"},
 ]
 "ruamel.yaml" = [
-    {file = "ruamel.yaml-0.17.4-py3-none-any.whl", hash = "sha256:ac79fb25f5476e8e9ed1c53b8a2286d2c3f5dde49eb37dbcee5c7eb6a8415a22"},
-    {file = "ruamel.yaml-0.17.4.tar.gz", hash = "sha256:44bc6b54fddd45e4bc0619059196679f9e8b79c027f4131bb072e6a22f4d5e28"},
+    {file = "ruamel.yaml-0.17.9-py3-none-any.whl", hash = "sha256:8873a6f5516e0d848c92418b0b006519c0566b6cd0dcee7deb9bf399e2bd204f"},
+    {file = "ruamel.yaml-0.17.9.tar.gz", hash = "sha256:374373b4743aee9f6d9f40bea600fe020a7ac7ae36b838b4a6a93f72b584a14c"},
 ]
 "ruamel.yaml.clib" = [
     {file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:28116f204103cb3a108dfd37668f20abe6e3cafd0d3fd40dba126c732457b3cc"},
@@ -3873,8 +3902,8 @@ toml = [
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
 ]
 tqdm = [
-    {file = "tqdm-4.61.0-py2.py3-none-any.whl", hash = "sha256:736524215c690621b06fc89d0310a49822d75e599fcd0feb7cc742b98d692493"},
-    {file = "tqdm-4.61.0.tar.gz", hash = "sha256:cd5791b5d7c3f2f1819efc81d36eb719a38e0906a7380365c556779f585ea042"},
+    {file = "tqdm-4.61.1-py2.py3-none-any.whl", hash = "sha256:aa0c29f03f298951ac6318f7c8ce584e48fa22ec26396e6411e43d038243bdb2"},
+    {file = "tqdm-4.61.1.tar.gz", hash = "sha256:24be966933e942be5f074c29755a95b315c69a91f839a29139bf26ffffe2d3fd"},
 ]
 traitlets = [
     {file = "traitlets-5.0.5-py3-none-any.whl", hash = "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426"},
@@ -3944,6 +3973,9 @@ whoosh = [
     {file = "Whoosh-2.7.4.tar.gz", hash = "sha256:7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83"},
     {file = "Whoosh-2.7.4.zip", hash = "sha256:e0857375f63e9041e03fedd5b7541f97cf78917ac1b6b06c1fcc9b45375dda69"},
 ]
+wrapt = [
+    {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},
+]
 yubiotp = [
     {file = "YubiOTP-1.0.0.post1-py2.py3-none-any.whl", hash = "sha256:7ad57011866e0bc6c6d179ffbc3926fcc0e82d410178a6d01ba4da0f88332878"},
     {file = "YubiOTP-1.0.0.post1.tar.gz", hash = "sha256:c13825f7b76a69afb92f19521f4dea9f5031d70f45123b505dc2e0ac03132065"},
diff --git a/pyproject.toml b/pyproject.toml
index 3204db03ddc4abe440720dba6a90fe41b15443ef..e5b19add2571b38e921cc0ba0019f2a7ceda854a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "AlekSIS-Core"
-version = "2.0b1"
+version = "2.0b2"
 packages = [
     { include = "aleksis" }
 ]
@@ -70,7 +70,7 @@ django-material = "^1.6.0"
 django-dynamic-preferences = "^1.9"
 django_widget_tweaks = "^1.4.5"
 django-filter = "^2.2.0"
-django-templated-email = "^2.3.0"
+django-templated-email = "^3.0.0"
 html2text = "^2020.0.0"
 django-ckeditor = "^6.0.0"
 django-js-reverse = "^0.9.1"