diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index cf68dff51a9aa59c825fa21573aa4f3bc899223c..80a42efc21786e83bf03419dfed68e7295861df1 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,12 +9,19 @@ and this project adheres to `Semantic Versioning`_.
 Unreleased
 ----------
 
+Added
+~~~~~
+
+* Recursive helper methods for group hierarchies
+
 Fixed
 ~~~~~
 
 * Remove left-over reference to preferences in a form definition that caused
   form extensions in downstream apps to break
 * Allow non-LDAP users to authenticate if LDAP is used with password handling
+* Additional button on progress page for background tasks was shown even if the task failed.
+* Register preference for available allowed oauth grants.
 
 `2.4`_ – 2021-12-24
 -------------------
diff --git a/README.rst b/README.rst
index 20780a642a74b8560bc21d1137193e78f7681642..2ffdcdca8d82845a1d3cdf838d10ca1290118e1e 100644
--- a/README.rst
+++ b/README.rst
@@ -6,7 +6,7 @@ This is the core of the AlekSIS framework and the official distribution
 developers and administrators.
 
 If you are looking for the AlekSIS standard distribution, i.e. the complete
-software product ready for installation and usage, please visit the `AlekSIS`_
+software product ready for installation and usage, please visit the `AlekSIS®`_
 website or the distribution repository on `EduGit`_.
 
 Features
@@ -83,7 +83,7 @@ AlekSIS® is a registered trademark of the AlekSIS open source project, represen
 by Teckids e.V. Please refer to the `trademark policy`_ for hints on using the trademark
 AlekSIS®.
 
-.. _AlekSIS: https://aleksis.org
+.. _AlekSIS®: https://aleksis.org
 .. _European Union Public Licence: https://eupl.eu/
 .. _EduGit: https://edugit.org/AlekSIS/official/AlekSIS
 .. _trademark policy: https://aleksis.org/pages/about
diff --git a/aleksis/core/locale/ar/LC_MESSAGES/django.po b/aleksis/core/locale/ar/LC_MESSAGES/django.po
index 3a8e81f1671d3c77fb0aa45e2b2254a4dab854b4..1ec59a49caf44641b442796d8e1ec3ebd502344d 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:13+0100\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"
@@ -38,10 +38,10 @@ msgstr ""
 msgid "Home and mobile phone"
 msgstr ""
 
-#: aleksis/core/apps.py:157 aleksis/core/forms.py:222 aleksis/core/menus.py:267
-#: aleksis/core/models.py:412 aleksis/core/templates/core/group/list.html:8
+#: aleksis/core/apps.py:157 aleksis/core/forms.py:223 aleksis/core/menus.py:265
+#: aleksis/core/models.py:414 aleksis/core/templates/core/group/list.html:8
 #: aleksis/core/templates/core/group/list.html:9
-#: aleksis/core/templates/core/person/full.html:145
+#: aleksis/core/templates/core/person/full.html:152
 msgid "Groups"
 msgstr ""
 
@@ -91,149 +91,148 @@ msgstr ""
 msgid "Content type"
 msgstr ""
 
-#: aleksis/core/filters.py:112 aleksis/core/models.py:579
+#: aleksis/core/filters.py:112 aleksis/core/models.py:581
 msgid "User"
 msgstr ""
 
-#: aleksis/core/filters.py:134 aleksis/core/models.py:411
+#: aleksis/core/filters.py:134 aleksis/core/models.py:413
 msgid "Group"
 msgstr ""
 
-#: aleksis/core/forms.py:47 aleksis/core/forms.py:521
+#: aleksis/core/forms.py:48 aleksis/core/forms.py:559
 msgid "Base data"
 msgstr ""
 
-#: aleksis/core/forms.py:53
+#: aleksis/core/forms.py:54
 msgid "Address"
 msgstr ""
 
-#: aleksis/core/forms.py:54
+#: aleksis/core/forms.py:55 aleksis/core/forms.py:568
 msgid "Contact data"
 msgstr ""
 
-#: aleksis/core/forms.py:56
+#: aleksis/core/forms.py:57
 msgid "Advanced personal data"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "New user"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "Create a new account"
 msgstr ""
 
-#: aleksis/core/forms.py:135
+#: aleksis/core/forms.py:136
 msgid "You cannot set a new username when also selecting an existing user."
 msgstr ""
 
-#: aleksis/core/forms.py:139
+#: aleksis/core/forms.py:140
 msgid "This username is already in use."
 msgstr ""
 
-#: aleksis/core/forms.py:156 aleksis/core/models.py:125
+#: aleksis/core/forms.py:157 aleksis/core/models.py:129
 msgid "School term"
 msgstr ""
 
-#: aleksis/core/forms.py:157
+#: aleksis/core/forms.py:158
 msgid "Common data"
 msgstr ""
 
-#: aleksis/core/forms.py:158 aleksis/core/forms.py:209
-#: aleksis/core/menus.py:256 aleksis/core/models.py:148
+#: aleksis/core/forms.py:159 aleksis/core/forms.py:210
+#: aleksis/core/menus.py:254 aleksis/core/models.py:152
 #: aleksis/core/templates/core/person/list.html:8
 #: aleksis/core/templates/core/person/list.html:9
 msgid "Persons"
 msgstr ""
 
-#: aleksis/core/forms.py:159
+#: aleksis/core/forms.py:160 aleksis/core/forms.py:570
 msgid "Additional data"
 msgstr ""
 
-#: aleksis/core/forms.py:201 aleksis/core/forms.py:204
-#: aleksis/core/models.py:68
+#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
+#: aleksis/core/models.py:72
 msgid "Date"
 msgstr ""
 
-#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
-#: aleksis/core/models.py:76
+#: aleksis/core/forms.py:203 aleksis/core/forms.py:206
+#: aleksis/core/models.py:80
 msgid "Time"
 msgstr ""
 
-#: aleksis/core/forms.py:235
+#: aleksis/core/forms.py:236
 msgid "From when until when should the announcement be displayed?"
 msgstr ""
 
-#: aleksis/core/forms.py:238
+#: aleksis/core/forms.py:239
 msgid "Who should see the announcement?"
 msgstr ""
 
-#: aleksis/core/forms.py:239
+#: aleksis/core/forms.py:240
 msgid "Write your announcement:"
 msgstr ""
 
-#: aleksis/core/forms.py:278
+#: aleksis/core/forms.py:279
 msgid "You are not allowed to create announcements which are only valid in the past."
 msgstr ""
 
-#: aleksis/core/forms.py:282
+#: aleksis/core/forms.py:283
 msgid "The from date and time must be earlier then the until date and time."
 msgstr ""
 
-#: aleksis/core/forms.py:291
+#: aleksis/core/forms.py:292
 msgid "You need at least one recipient."
 msgstr ""
 
-#: aleksis/core/forms.py:412
+#: aleksis/core/forms.py:401
+msgid "Invitation code"
+msgstr ""
+
+#: aleksis/core/forms.py:402
+msgid "Please enter your invitation code."
+msgstr ""
+
+#: aleksis/core/forms.py:434
 msgid "Who should get the permission?"
 msgstr ""
 
-#: aleksis/core/forms.py:413
+#: aleksis/core/forms.py:435
 msgid "On what?"
 msgstr ""
 
-#: aleksis/core/forms.py:439
+#: aleksis/core/forms.py:461
 msgid "Select objects which the permission should be granted for:"
 msgstr ""
 
-#: aleksis/core/forms.py:442
+#: aleksis/core/forms.py:464
 msgid "Grant the permission for all objects"
 msgstr ""
 
-#: aleksis/core/forms.py:450
+#: aleksis/core/forms.py:472
 msgid "You must select at least one group or person which should get the permission."
 msgstr ""
 
-#: aleksis/core/forms.py:455
+#: aleksis/core/forms.py:477
 msgid "You must grant the permission to all objects and/or to some objects."
 msgstr ""
 
-#: aleksis/core/forms.py:525
-msgid "Account data"
+#: aleksis/core/forms.py:564
+msgid "Adress data"
 msgstr ""
 
-#: aleksis/core/forms.py:531
-msgid "Consents"
+#: aleksis/core/forms.py:576
+msgid "Account data"
 msgstr ""
 
-#: aleksis/core/forms.py:538
+#: aleksis/core/forms.py:583
 msgid "Password"
 msgstr ""
 
-#: aleksis/core/forms.py:544
+#: aleksis/core/forms.py:586
 msgid "Password (again)"
 msgstr ""
 
-#: aleksis/core/forms.py:557
-#, python-brace-format
-msgid "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree with them."
-msgstr ""
-
-#: aleksis/core/forms.py:582
-msgid "You must type the same password each time."
-msgstr ""
-
-#: aleksis/core/forms.py:727
+#: aleksis/core/forms.py:752
 msgid "No valid selection."
 msgstr ""
 
@@ -270,34 +269,38 @@ msgstr ""
 msgid "Sign up"
 msgstr ""
 
-#: aleksis/core/menus.py:24
+#: aleksis/core/menus.py:24 aleksis/core/templates/invitations/enter.html:7
+msgid "Accept invitation"
+msgstr ""
+
+#: aleksis/core/menus.py:33
 msgid "Dashboard"
 msgstr ""
 
-#: aleksis/core/menus.py:32 aleksis/core/models.py:625
-#: aleksis/core/preferences.py:27
+#: aleksis/core/menus.py:41 aleksis/core/models.py:627
+#: aleksis/core/preferences.py:28
 #: aleksis/core/templates/core/notifications.html:4
 #: aleksis/core/templates/core/notifications.html:5
 msgid "Notifications"
 msgstr ""
 
-#: aleksis/core/menus.py:44
+#: aleksis/core/menus.py:53
 msgid "Account"
 msgstr ""
 
-#: aleksis/core/menus.py:51
+#: aleksis/core/menus.py:60
 msgid "Stop impersonation"
 msgstr ""
 
-#: aleksis/core/menus.py:60 aleksis/core/templates/core/base.html:80
+#: aleksis/core/menus.py:69 aleksis/core/templates/core/base.html:80
 msgid "Logout"
 msgstr ""
 
-#: aleksis/core/menus.py:66
+#: aleksis/core/menus.py:75
 msgid "2FA"
 msgstr ""
 
-#: aleksis/core/menus.py:74
+#: aleksis/core/menus.py:83
 #: aleksis/core/templates/account/password_change.html:5
 #: aleksis/core/templates/account/password_change.html:6
 #: aleksis/core/templates/account/password_change.html:19
@@ -309,830 +312,850 @@ msgstr ""
 msgid "Change password"
 msgstr ""
 
-#: aleksis/core/menus.py:86
+#: aleksis/core/menus.py:95
 msgid "Me"
 msgstr ""
 
-#: aleksis/core/menus.py:95
+#: aleksis/core/menus.py:104
 #: aleksis/core/templates/dynamic_preferences/form.html:5
 msgid "Preferences"
 msgstr ""
 
-#: aleksis/core/menus.py:104
+#: aleksis/core/menus.py:113
 msgid "Third-party accounts"
 msgstr ""
 
-#: aleksis/core/menus.py:113
+#: aleksis/core/menus.py:122
 #: 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:124
+#: aleksis/core/menus.py:133
 msgid "Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:132 aleksis/core/models.py:725
+#: aleksis/core/menus.py:141 aleksis/core/models.py:727
 #: aleksis/core/templates/core/announcement/list.html:7
 #: aleksis/core/templates/core/announcement/list.html:8
 msgid "Announcements"
 msgstr ""
 
-#: aleksis/core/menus.py:143 aleksis/core/models.py:126
+#: aleksis/core/menus.py:152 aleksis/core/models.py:130
 #: aleksis/core/templates/core/school_term/list.html:8
 #: aleksis/core/templates/core/school_term/list.html:9
 msgid "School terms"
 msgstr ""
 
-#: aleksis/core/menus.py:154
+#: aleksis/core/menus.py:163
 #: aleksis/core/templates/core/dashboard_widget/list.html:8
 #: aleksis/core/templates/core/dashboard_widget/list.html:9
 msgid "Dashboard widgets"
 msgstr ""
 
-#: aleksis/core/menus.py:165
+#: aleksis/core/menus.py:174
 #: aleksis/core/templates/core/management/data_management.html:6
 #: aleksis/core/templates/core/management/data_management.html:7
 msgid "Data management"
 msgstr ""
 
-#: aleksis/core/menus.py:176
+#: aleksis/core/menus.py:185
 #: aleksis/core/templates/core/pages/system_status.html:5
 #: aleksis/core/templates/core/pages/system_status.html:7
 msgid "System status"
 msgstr ""
 
-#: aleksis/core/menus.py:187
-msgid "Impersonation"
-msgstr ""
-
-#: aleksis/core/menus.py:198
+#: aleksis/core/menus.py:196
 msgid "Configuration"
 msgstr ""
 
-#: aleksis/core/menus.py:209 aleksis/core/templates/core/data_check/list.html:9
+#: aleksis/core/menus.py:207 aleksis/core/templates/core/data_check/list.html:9
 #: aleksis/core/templates/core/data_check/list.html:10
 msgid "Data checks"
 msgstr ""
 
-#: aleksis/core/menus.py:215 aleksis/core/templates/core/perms/list.html:13
+#: aleksis/core/menus.py:213 aleksis/core/templates/core/perms/list.html:13
 #: aleksis/core/templates/core/perms/list.html:14
 msgid "Manage permissions"
 msgstr ""
 
-#: aleksis/core/menus.py:226
+#: aleksis/core/menus.py:224
 msgid "Backend Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:234
+#: aleksis/core/menus.py:232
 #: aleksis/core/templates/oauth2_provider/application/list.html:5
 #: aleksis/core/templates/oauth2_provider/application/list.html:6
 msgid "OAuth2 Applications"
 msgstr ""
 
-#: aleksis/core/menus.py:247
+#: aleksis/core/menus.py:245
 msgid "People"
 msgstr ""
 
-#: aleksis/core/menus.py:278 aleksis/core/models.py:979
+#: aleksis/core/menus.py:276 aleksis/core/models.py:981
 #: aleksis/core/templates/core/group_type/list.html:8
 #: aleksis/core/templates/core/group_type/list.html:9
 msgid "Group types"
 msgstr ""
 
-#: aleksis/core/menus.py:289
+#: aleksis/core/menus.py:287
 msgid "Groups and child groups"
 msgstr ""
 
-#: aleksis/core/menus.py:300 aleksis/core/models.py:460
+#: aleksis/core/menus.py:298 aleksis/core/models.py:462
 #: aleksis/core/templates/core/additional_field/list.html:8
 #: aleksis/core/templates/core/additional_field/list.html:9
 msgid "Additional fields"
 msgstr ""
 
-#: aleksis/core/menus.py:315
+#: aleksis/core/menus.py:309
+msgid "Invite person"
+msgstr ""
+
+#: aleksis/core/menus.py:322
 #: aleksis/core/templates/core/group/child_groups.html:7
 #: aleksis/core/templates/core/group/child_groups.html:9
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:508
+#: aleksis/core/mixins.py:511
 msgid "Linked school term"
 msgstr ""
 
-#: aleksis/core/models.py:66
+#: aleksis/core/models.py:70
 msgid "Boolean (Yes/No)"
 msgstr ""
 
-#: aleksis/core/models.py:67
+#: aleksis/core/models.py:71
 msgid "Text (one line)"
 msgstr ""
 
-#: aleksis/core/models.py:69
+#: aleksis/core/models.py:73
 msgid "Date and time"
 msgstr ""
 
-#: aleksis/core/models.py:70
+#: aleksis/core/models.py:74
 msgid "Decimal number"
 msgstr ""
 
-#: aleksis/core/models.py:71 aleksis/core/models.py:194
+#: aleksis/core/models.py:75 aleksis/core/models.py:198
 msgid "E-mail address"
 msgstr ""
 
-#: aleksis/core/models.py:72
+#: aleksis/core/models.py:76
 msgid "Integer"
 msgstr ""
 
-#: aleksis/core/models.py:73
+#: aleksis/core/models.py:77
 msgid "IP address"
 msgstr ""
 
-#: aleksis/core/models.py:74
+#: aleksis/core/models.py:78
 msgid "Boolean or empty (Yes/No/Neither)"
 msgstr ""
 
-#: aleksis/core/models.py:75
+#: aleksis/core/models.py:79
 msgid "Text (multi-line)"
 msgstr ""
 
-#: aleksis/core/models.py:77
+#: aleksis/core/models.py:81
 msgid "URL / Link"
 msgstr ""
 
-#: aleksis/core/models.py:89 aleksis/core/models.py:948
+#: aleksis/core/models.py:93 aleksis/core/models.py:950
 msgid "Name"
 msgstr ""
 
-#: aleksis/core/models.py:91
+#: aleksis/core/models.py:95
 msgid "Start date"
 msgstr ""
 
-#: aleksis/core/models.py:92
+#: aleksis/core/models.py:96
 msgid "End date"
 msgstr ""
 
-#: aleksis/core/models.py:111
+#: aleksis/core/models.py:115
 msgid "The start date must be earlier than the end date."
 msgstr ""
 
-#: aleksis/core/models.py:118
+#: aleksis/core/models.py:122
 msgid "There is already a school term for this time or a part of this time."
 msgstr ""
 
-#: aleksis/core/models.py:147 aleksis/core/models.py:897
+#: aleksis/core/models.py:151 aleksis/core/models.py:899
 msgid "Person"
 msgstr ""
 
-#: aleksis/core/models.py:150
+#: aleksis/core/models.py:154
 msgid "Can view address"
 msgstr ""
 
-#: aleksis/core/models.py:151
+#: aleksis/core/models.py:155
 msgid "Can view contact details"
 msgstr ""
 
-#: aleksis/core/models.py:152
+#: aleksis/core/models.py:156
 msgid "Can view photo"
 msgstr ""
 
-#: aleksis/core/models.py:153
+#: aleksis/core/models.py:157
 msgid "Can view persons groups"
 msgstr ""
 
-#: aleksis/core/models.py:154
+#: aleksis/core/models.py:158
 msgid "Can view personal details"
 msgstr ""
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "female"
 msgstr ""
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "male"
 msgstr ""
 
-#: aleksis/core/models.py:172
+#: aleksis/core/models.py:176 aleksis/core/models.py:1144
 msgid "Linked user"
 msgstr ""
 
-#: aleksis/core/models.py:174
+#: aleksis/core/models.py:178
 msgid "Is person active?"
 msgstr ""
 
-#: aleksis/core/models.py:176
+#: aleksis/core/models.py:180
 msgid "First name"
 msgstr ""
 
-#: aleksis/core/models.py:177
+#: aleksis/core/models.py:181
 msgid "Last name"
 msgstr ""
 
-#: aleksis/core/models.py:179
+#: aleksis/core/models.py:183
 msgid "Additional name(s)"
 msgstr ""
 
-#: aleksis/core/models.py:183 aleksis/core/models.py:429
+#: aleksis/core/models.py:187 aleksis/core/models.py:431
 msgid "Short name"
 msgstr ""
 
-#: aleksis/core/models.py:186
+#: aleksis/core/models.py:190
 msgid "Street"
 msgstr ""
 
-#: aleksis/core/models.py:187
+#: aleksis/core/models.py:191
 msgid "Street number"
 msgstr ""
 
-#: aleksis/core/models.py:188
+#: aleksis/core/models.py:192
 msgid "Postal code"
 msgstr ""
 
-#: aleksis/core/models.py:189
+#: aleksis/core/models.py:193
 msgid "Place"
 msgstr ""
 
-#: aleksis/core/models.py:191
+#: aleksis/core/models.py:195
 msgid "Home phone"
 msgstr ""
 
-#: aleksis/core/models.py:192
+#: aleksis/core/models.py:196
 msgid "Mobile phone"
 msgstr ""
 
-#: aleksis/core/models.py:196
+#: aleksis/core/models.py:200
 msgid "Date of birth"
 msgstr ""
 
-#: aleksis/core/models.py:198
+#: aleksis/core/models.py:201
 msgid "Place of birth"
 msgstr ""
 
-#: aleksis/core/models.py:200
+#: aleksis/core/models.py:202
 msgid "Sex"
 msgstr ""
 
-#: aleksis/core/models.py:202
+#: aleksis/core/models.py:204
 msgid "Photo"
 msgstr ""
 
-#: aleksis/core/models.py:206 aleksis/core/templates/core/person/full.html:138
+#: aleksis/core/models.py:208 aleksis/core/templates/core/person/full.html:145
 msgid "Guardians / Parents"
 msgstr ""
 
-#: aleksis/core/models.py:213
+#: aleksis/core/models.py:215
 msgid "Primary group"
 msgstr ""
 
-#: aleksis/core/models.py:216 aleksis/core/models.py:583
-#: aleksis/core/models.py:607 aleksis/core/models.py:692
-#: aleksis/core/models.py:972 aleksis/core/templates/core/person/full.html:121
+#: aleksis/core/models.py:218 aleksis/core/models.py:585
+#: aleksis/core/models.py:609 aleksis/core/models.py:694
+#: aleksis/core/models.py:974 aleksis/core/templates/core/person/full.html:128
 msgid "Description"
 msgstr ""
 
-#: aleksis/core/models.py:384
+#: aleksis/core/models.py:386
 msgid "Title of field"
 msgstr ""
 
-#: aleksis/core/models.py:386
+#: aleksis/core/models.py:388
 msgid "Type of field"
 msgstr ""
 
-#: aleksis/core/models.py:393
+#: aleksis/core/models.py:395
 msgid "Addtitional field for groups"
 msgstr ""
 
-#: aleksis/core/models.py:394
+#: aleksis/core/models.py:396
 msgid "Addtitional fields for groups"
 msgstr ""
 
-#: aleksis/core/models.py:414
+#: aleksis/core/models.py:416
 msgid "Can assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/models.py:415
+#: aleksis/core/models.py:417
 msgid "Can view statistics about group."
 msgstr ""
 
-#: aleksis/core/models.py:427
+#: aleksis/core/models.py:429
 msgid "Long name"
 msgstr ""
 
-#: aleksis/core/models.py:437 aleksis/core/templates/core/group/full.html:85
+#: aleksis/core/models.py:439 aleksis/core/templates/core/group/full.html:85
 msgid "Members"
 msgstr ""
 
-#: aleksis/core/models.py:440 aleksis/core/templates/core/group/full.html:82
+#: aleksis/core/models.py:442 aleksis/core/templates/core/group/full.html:82
 msgid "Owners"
 msgstr ""
 
-#: aleksis/core/models.py:447 aleksis/core/templates/core/group/full.html:55
+#: aleksis/core/models.py:449 aleksis/core/templates/core/group/full.html:55
 msgid "Parent groups"
 msgstr ""
 
-#: aleksis/core/models.py:455
+#: aleksis/core/models.py:457
 msgid "Type of group"
 msgstr ""
 
-#: aleksis/core/models.py:582 aleksis/core/models.py:606
-#: aleksis/core/models.py:691
+#: aleksis/core/models.py:584 aleksis/core/models.py:608
+#: aleksis/core/models.py:693
 #: aleksis/core/templates/core/announcement/list.html:18
 msgid "Title"
 msgstr ""
 
-#: aleksis/core/models.py:585
+#: aleksis/core/models.py:587
 msgid "Application"
 msgstr ""
 
-#: aleksis/core/models.py:591
+#: aleksis/core/models.py:593
 msgid "Activity"
 msgstr ""
 
-#: aleksis/core/models.py:592
+#: aleksis/core/models.py:594
 msgid "Activities"
 msgstr ""
 
-#: aleksis/core/models.py:598
+#: aleksis/core/models.py:600
 msgid "Sender"
 msgstr ""
 
-#: aleksis/core/models.py:603
+#: aleksis/core/models.py:605
 msgid "Recipient"
 msgstr ""
 
-#: aleksis/core/models.py:608 aleksis/core/models.py:949
+#: aleksis/core/models.py:610 aleksis/core/models.py:951
 msgid "Link"
 msgstr ""
 
-#: aleksis/core/models.py:610
+#: aleksis/core/models.py:612
 msgid "Read"
 msgstr ""
 
-#: aleksis/core/models.py:611
+#: aleksis/core/models.py:613
 msgid "Sent"
 msgstr ""
 
-#: aleksis/core/models.py:624
+#: aleksis/core/models.py:626
 msgid "Notification"
 msgstr ""
 
-#: aleksis/core/models.py:693
+#: aleksis/core/models.py:695
 msgid "Link to detailed view"
 msgstr ""
 
-#: aleksis/core/models.py:696
+#: aleksis/core/models.py:698
 msgid "Date and time from when to show"
 msgstr ""
 
-#: aleksis/core/models.py:699
+#: aleksis/core/models.py:701
 msgid "Date and time until when to show"
 msgstr ""
 
-#: aleksis/core/models.py:724
+#: aleksis/core/models.py:726
 msgid "Announcement"
 msgstr ""
 
-#: aleksis/core/models.py:762
+#: aleksis/core/models.py:764
 msgid "Announcement recipient"
 msgstr ""
 
-#: aleksis/core/models.py:763
+#: aleksis/core/models.py:765
 msgid "Announcement recipients"
 msgstr ""
 
-#: aleksis/core/models.py:818
+#: aleksis/core/models.py:820
 msgid "Widget Title"
 msgstr ""
 
-#: aleksis/core/models.py:819
+#: aleksis/core/models.py:821
 msgid "Activate Widget"
 msgstr ""
 
-#: aleksis/core/models.py:820
+#: aleksis/core/models.py:822
 msgid "Widget is broken"
 msgstr ""
 
-#: aleksis/core/models.py:823
+#: aleksis/core/models.py:825
 msgid "Size on mobile devices"
 msgstr ""
 
-#: aleksis/core/models.py:824
+#: aleksis/core/models.py:826
 msgid "<= 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:829
+#: aleksis/core/models.py:831
 msgid "Size on tablet devices"
 msgstr ""
 
-#: aleksis/core/models.py:830
+#: aleksis/core/models.py:832
 msgid "> 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:835
+#: aleksis/core/models.py:837
 msgid "Size on desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:836
+#: aleksis/core/models.py:838
 msgid "> 992 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:841
+#: aleksis/core/models.py:843
 msgid "Size on large desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:842
+#: aleksis/core/models.py:844
 msgid "> 1200 px>, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:873
+#: aleksis/core/models.py:875
 msgid "Can edit default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:874
+#: aleksis/core/models.py:876
 msgid "Dashboard Widget"
 msgstr ""
 
-#: aleksis/core/models.py:875
+#: aleksis/core/models.py:877
 msgid "Dashboard Widgets"
 msgstr ""
 
-#: aleksis/core/models.py:881
+#: aleksis/core/models.py:883
 msgid "URL"
 msgstr ""
 
-#: aleksis/core/models.py:882
+#: aleksis/core/models.py:884
 msgid "Icon URL"
 msgstr ""
 
-#: aleksis/core/models.py:888
+#: aleksis/core/models.py:890
 msgid "External link widget"
 msgstr ""
 
-#: aleksis/core/models.py:889
+#: aleksis/core/models.py:891
 msgid "External link widgets"
 msgstr ""
 
-#: aleksis/core/models.py:894
+#: aleksis/core/models.py:896
 msgid "Dashboard widget"
 msgstr ""
 
-#: aleksis/core/models.py:899
+#: aleksis/core/models.py:901
 msgid "Order"
 msgstr ""
 
-#: aleksis/core/models.py:900
+#: aleksis/core/models.py:902
 msgid "Part of the default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:915
+#: aleksis/core/models.py:917
 msgid "Dashboard widget order"
 msgstr ""
 
-#: aleksis/core/models.py:916
+#: aleksis/core/models.py:918
 msgid "Dashboard widget orders"
 msgstr ""
 
-#: aleksis/core/models.py:922
+#: aleksis/core/models.py:924
 msgid "Menu ID"
 msgstr ""
 
-#: aleksis/core/models.py:935
+#: aleksis/core/models.py:937
 msgid "Custom menu"
 msgstr ""
 
-#: aleksis/core/models.py:936
+#: aleksis/core/models.py:938
 msgid "Custom menus"
 msgstr ""
 
-#: aleksis/core/models.py:946
+#: aleksis/core/models.py:948
 msgid "Menu"
 msgstr ""
 
-#: aleksis/core/models.py:950
+#: aleksis/core/models.py:952
 msgid "Icon"
 msgstr ""
 
-#: aleksis/core/models.py:956
+#: aleksis/core/models.py:958
 msgid "Custom menu item"
 msgstr ""
 
-#: aleksis/core/models.py:957
+#: aleksis/core/models.py:959
 msgid "Custom menu items"
 msgstr ""
 
-#: aleksis/core/models.py:971
+#: aleksis/core/models.py:973
 msgid "Title of type"
 msgstr ""
 
-#: aleksis/core/models.py:978 aleksis/core/templates/core/group/full.html:47
+#: aleksis/core/models.py:980 aleksis/core/templates/core/group/full.html:47
 msgid "Group type"
 msgstr ""
 
-#: aleksis/core/models.py:992
+#: aleksis/core/models.py:994
 msgid "Can view system status"
 msgstr ""
 
-#: aleksis/core/models.py:993
+#: aleksis/core/models.py:995
 msgid "Can manage data"
 msgstr ""
 
-#: aleksis/core/models.py:994
+#: aleksis/core/models.py:996
 msgid "Can impersonate"
 msgstr ""
 
-#: aleksis/core/models.py:995
+#: aleksis/core/models.py:997
 msgid "Can use search"
 msgstr ""
 
-#: aleksis/core/models.py:996
+#: aleksis/core/models.py:998
 msgid "Can change site preferences"
 msgstr ""
 
-#: aleksis/core/models.py:997
+#: aleksis/core/models.py:999
 msgid "Can change person preferences"
 msgstr ""
 
-#: aleksis/core/models.py:998
+#: aleksis/core/models.py:1000
 msgid "Can change group preferences"
 msgstr ""
 
-#: aleksis/core/models.py:999
+#: aleksis/core/models.py:1001
 msgid "Can test PDF generation"
 msgstr ""
 
-#: aleksis/core/models.py:1035
+#: aleksis/core/models.py:1037
 msgid "Related data check task"
 msgstr ""
 
-#: aleksis/core/models.py:1043
+#: aleksis/core/models.py:1045
 msgid "Issue solved"
 msgstr ""
 
-#: aleksis/core/models.py:1044
+#: aleksis/core/models.py:1046
 msgid "Notification sent"
 msgstr ""
 
-#: aleksis/core/models.py:1057
+#: aleksis/core/models.py:1059
 msgid "Data check result"
 msgstr ""
 
-#: aleksis/core/models.py:1058
+#: aleksis/core/models.py:1060
 msgid "Data check results"
 msgstr ""
 
-#: aleksis/core/models.py:1060
+#: aleksis/core/models.py:1062
 msgid "Can run data checks"
 msgstr ""
 
-#: aleksis/core/models.py:1061
+#: aleksis/core/models.py:1063
 msgid "Can solve data check problems"
 msgstr ""
 
-#: aleksis/core/models.py:1076
+#: aleksis/core/models.py:1070
+msgid "E-Mail address"
+msgstr ""
+
+#: aleksis/core/models.py:1094
 msgid "Owner"
 msgstr ""
 
-#: aleksis/core/models.py:1080
+#: aleksis/core/models.py:1098
 msgid "File expires at"
 msgstr ""
 
-#: aleksis/core/models.py:1082
+#: aleksis/core/models.py:1100
 msgid "Generated HTML file"
 msgstr ""
 
-#: aleksis/core/models.py:1084
+#: aleksis/core/models.py:1102
 msgid "Generated PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1091
+#: aleksis/core/models.py:1109
 msgid "PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1092
+#: aleksis/core/models.py:1110
 msgid "PDF files"
 msgstr ""
 
-#: aleksis/core/models.py:1097
+#: aleksis/core/models.py:1115
 msgid "Task result"
 msgstr ""
 
-#: aleksis/core/models.py:1100
+#: aleksis/core/models.py:1118
 msgid "Task user"
 msgstr ""
 
-#: aleksis/core/models.py:1112
+#: aleksis/core/models.py:1130
 msgid "Task user assignment"
 msgstr ""
 
-#: aleksis/core/models.py:1113
+#: aleksis/core/models.py:1131
 msgid "Task user assignments"
 msgstr ""
 
-#: aleksis/core/models.py:1127
+#: aleksis/core/models.py:1147
+msgid "Additional attributes"
+msgstr ""
+
+#: aleksis/core/models.py:1185
 msgid "Allowed scopes that clients can request"
 msgstr ""
 
-#: aleksis/core/preferences.py:23
+#: aleksis/core/preferences.py:24
 msgid "General"
 msgstr ""
 
-#: aleksis/core/preferences.py:24
+#: aleksis/core/preferences.py:25
 msgid "School"
 msgstr ""
 
-#: aleksis/core/preferences.py:25
+#: aleksis/core/preferences.py:26
 msgid "Theme"
 msgstr ""
 
-#: aleksis/core/preferences.py:26
+#: aleksis/core/preferences.py:27
 msgid "Mail"
 msgstr ""
 
-#: aleksis/core/preferences.py:28
+#: aleksis/core/preferences.py:29
 msgid "Footer"
 msgstr ""
 
-#: aleksis/core/preferences.py:29
+#: aleksis/core/preferences.py:30
 msgid "Accounts"
 msgstr ""
 
-#: aleksis/core/preferences.py:30
+#: aleksis/core/preferences.py:31
 msgid "Authentication"
 msgstr ""
 
-#: aleksis/core/preferences.py:31
+#: aleksis/core/preferences.py:32
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:42
+#: aleksis/core/preferences.py:43
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:53
+#: aleksis/core/preferences.py:54
 msgid "Site description"
 msgstr ""
 
-#: aleksis/core/preferences.py:64
+#: aleksis/core/preferences.py:65
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:77
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:87
+#: aleksis/core/preferences.py:88
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:97
+#: aleksis/core/preferences.py:98
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:107
+#: aleksis/core/preferences.py:108
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:118
+#: aleksis/core/preferences.py:119
 msgid "Mail out name"
 msgstr ""
 
-#: aleksis/core/preferences.py:129
+#: aleksis/core/preferences.py:130
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:141
+#: aleksis/core/preferences.py:142
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:153
+#: aleksis/core/preferences.py:154
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:165
+#: aleksis/core/preferences.py:166
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:181
+#: aleksis/core/preferences.py:182
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:193
+#: aleksis/core/preferences.py:194
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:204
+#: aleksis/core/preferences.py:205
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:216
+#: aleksis/core/preferences.py:217
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:225
+#: aleksis/core/preferences.py:226
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:236
+#: aleksis/core/preferences.py:237
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:247
+#: aleksis/core/preferences.py:248
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:255
+#: aleksis/core/preferences.py:256
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:263
+#: aleksis/core/preferences.py:264
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:274
+#: aleksis/core/preferences.py:272
+msgid "Enable invitations"
+msgstr ""
+
+#: aleksis/core/preferences.py:280
+msgid "Length of invite code. (Default 3: abcde-acbde-abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:288
+msgid "Size of packets. (Default 5: abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:298
 msgid "Allowed Grant Flows for OAuth applications"
 msgstr ""
 
-#: aleksis/core/preferences.py:287
+#: aleksis/core/preferences.py:311
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:299
+#: aleksis/core/preferences.py:323
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:310
+#: aleksis/core/preferences.py:334
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:321
+#: aleksis/core/preferences.py:345
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:330
+#: aleksis/core/preferences.py:354
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:339
+#: aleksis/core/preferences.py:363
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:350
+#: aleksis/core/preferences.py:374
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:364
+#: aleksis/core/preferences.py:388
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:377
+#: aleksis/core/preferences.py:401
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:387
+#: aleksis/core/preferences.py:411
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:388
+#: aleksis/core/preferences.py:412
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/preferences.py:398
+#: aleksis/core/preferences.py:422
 msgid "Automatically update the dashboard and its widgets"
 msgstr ""
 
-#: aleksis/core/preferences.py:408
+#: aleksis/core/preferences.py:432
 msgid "Automatically update the dashboard and its widgets sitewide"
 msgstr ""
 
-#: aleksis/core/settings.py:482
+#: aleksis/core/settings.py:507
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:483
+#: aleksis/core/settings.py:508
 msgid "German"
 msgstr ""
 
-#: aleksis/core/tables.py:19
+#: aleksis/core/tables.py:24
 #: aleksis/core/templates/core/announcement/list.html:36
 #: aleksis/core/templates/core/group/full.html:24
-#: aleksis/core/templates/core/person/full.html:23
+#: aleksis/core/templates/core/person/full.html:24
 #: aleksis/core/templates/oauth2_provider/application/detail.html:17
 msgid "Edit"
 msgstr ""
 
-#: aleksis/core/tables.py:21 aleksis/core/tables.py:89
-#: aleksis/core/tables.py:105
+#: aleksis/core/tables.py:26 aleksis/core/tables.py:94
+#: aleksis/core/tables.py:137
 #: aleksis/core/templates/core/announcement/list.html:22
 msgid "Actions"
 msgstr ""
 
-#: aleksis/core/tables.py:56 aleksis/core/tables.py:57
-#: aleksis/core/tables.py:71 aleksis/core/tables.py:87
-#: aleksis/core/tables.py:103
+#: aleksis/core/tables.py:61 aleksis/core/tables.py:62
+#: aleksis/core/tables.py:76 aleksis/core/tables.py:92
+#: aleksis/core/tables.py:135
 #: aleksis/core/templates/core/announcement/list.html:42
 #: aleksis/core/templates/core/group/full.html:31
 #: aleksis/core/templates/core/pages/delete.html:22
-#: aleksis/core/templates/core/person/full.html:30
+#: aleksis/core/templates/core/person/full.html:31
 #: aleksis/core/templates/oauth2_provider/application/detail.html:21
 msgid "Delete"
 msgstr ""
@@ -1204,11 +1227,11 @@ msgstr ""
 msgid "Account inactive"
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:13
+#: aleksis/core/templates/account/account_inactive.html:14
 msgid "Account inactive."
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:15
+#: aleksis/core/templates/account/account_inactive.html:17
 msgid ""
 "\n"
 "            This account is currently inactive. If you think this is an\n"
@@ -1360,11 +1383,11 @@ msgstr ""
 msgid "Signup closed"
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:13
+#: aleksis/core/templates/account/signup_closed.html:14
 msgid "Signup closed."
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:15
+#: aleksis/core/templates/account/signup_closed.html:17
 msgid ""
 "\n"
 "            This sign up is currently closed. If you think this is an\n"
@@ -1402,11 +1425,6 @@ msgid ""
 "          "
 msgstr ""
 
-#: 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 ""
-
 #: aleksis/core/templates/core/additional_field/edit.html:6
 #: aleksis/core/templates/core/additional_field/edit.html:7
 msgid "Edit additional field"
@@ -1459,7 +1477,7 @@ msgid "About AlekSIS® — The Free School Information System"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:183
-msgid "Impress"
+msgid "Imprint"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:191
@@ -1682,7 +1700,7 @@ msgid "Edit group"
 msgstr ""
 
 #: aleksis/core/templates/core/group/full.html:38
-#: aleksis/core/templates/core/person/full.html:37
+#: aleksis/core/templates/core/person/full.html:38
 msgid "Change preferences"
 msgstr ""
 
@@ -2076,17 +2094,19 @@ msgstr ""
 msgid "Edit person"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:44
-#: aleksis/core/templates/impersonate/list_users.html:7
-#: aleksis/core/templates/impersonate/list_users.html:8
+#: aleksis/core/templates/core/person/full.html:45
 msgid "Impersonate"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:50
+#: aleksis/core/templates/core/person/full.html:51
+msgid "Invite user"
+msgstr ""
+
+#: aleksis/core/templates/core/person/full.html:57
 msgid "Contact details"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:131
+#: aleksis/core/templates/core/person/full.html:138
 msgid "Children"
 msgstr ""
 
@@ -2126,6 +2146,49 @@ msgstr ""
 msgid "Save preferences"
 msgstr ""
 
+#: aleksis/core/templates/invitations/enter.html:21
+msgid "Accept your invitation"
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:25
+msgid ""
+"\n"
+"                Please enter your invitation code to register\n"
+"                your new user account:\n"
+"              "
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:37
+msgid "Accept invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:9
+#: aleksis/core/templates/invitations/forms/_invite.html:10
+#: aleksis/core/templates/invitations/forms/_invite.html:21
+msgid "Invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:17
+msgid "Invite by email address"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:26
+msgid "Generate invitation code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:29
+msgid "Generate code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:33
+msgid "Invitations"
+msgstr ""
+
+#: aleksis/core/templates/invitations/messages/invite_accepted.txt:3
+#, python-format
+msgid "The invitation for %(email)s has been accepted."
+msgstr ""
+
 #: aleksis/core/templates/oauth2_provider/application/create.html:5
 #: aleksis/core/templates/oauth2_provider/application/create.html:6
 msgid "Register OAuth2 Application"
@@ -2806,127 +2869,140 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:270
+#: aleksis/core/views.py:280
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:282
+#: aleksis/core/views.py:292
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:406
+#: aleksis/core/views.py:416
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:425 aleksis/core/views.py:435
+#: aleksis/core/views.py:435 aleksis/core/views.py:445
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:485
+#: aleksis/core/views.py:495
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:582
+#: aleksis/core/views.py:592
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:598
+#: aleksis/core/views.py:608
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:682
+#: aleksis/core/views.py:695
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:706
+#: aleksis/core/views.py:719
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:720
+#: aleksis/core/views.py:733
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:752
+#: aleksis/core/views.py:765
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:786
+#: aleksis/core/views.py:799
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:811
+#: aleksis/core/views.py:824
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:854
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:874
+#: aleksis/core/views.py:887
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:875
+#: aleksis/core/views.py:888
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:876
+#: aleksis/core/views.py:889
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:877
+#: aleksis/core/views.py:890
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:893
+#: aleksis/core/views.py:906
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:935
+#: aleksis/core/views.py:948
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:965
+#: aleksis/core/views.py:978
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:975
+#: aleksis/core/views.py:988
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1042
+#: aleksis/core/views.py:1055
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1044
+#: aleksis/core/views.py:1057
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1139
+#: aleksis/core/views.py:1127
+#, python-brace-format
+msgid "The invitation was successfully created. The invitation code is {code}"
+msgstr ""
+
+#: aleksis/core/views.py:1218
 msgid "We have successfully assigned the permissions."
 msgstr ""
 
-#: aleksis/core/views.py:1149
+#: aleksis/core/views.py:1228
 msgid "The global user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1159
+#: aleksis/core/views.py:1238
 msgid "The global group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1169
+#: aleksis/core/views.py:1248
 msgid "The object user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1179
+#: aleksis/core/views.py:1258
 msgid "The object group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1298
+#: aleksis/core/views.py:1377
 msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1305
+#: aleksis/core/views.py:1384
 msgid "The third-party account has been successfully disconnected."
 msgstr ""
+
+#: aleksis/core/views.py:1441
+msgid "Person was invited successfully."
+msgstr ""
+
+#: aleksis/core/views.py:1443
+msgid "Person was already invited."
+msgstr ""
diff --git a/aleksis/core/locale/ar/LC_MESSAGES/djangojs.po b/aleksis/core/locale/ar/LC_MESSAGES/djangojs.po
index 5b0bf573998d6fec316f20dc23dbb29e00e57118..ac0e765ef8e4c2d7ac490397fcd99e22fd921846 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:14+0100\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:127
+#: aleksis/core/static/js/main.js:128
 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 131825ad4c39fe0f14e7d34d4b12f373f41267ce..6a7afee49da25f0111b97b04ca8f4f51eb7aeba8 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-12-13 12:55+0100\n"
-"PO-Revision-Date: 2021-12-13 18:34+0000\n"
+"POT-Creation-Date: 2021-12-28 12:13+0100\n"
+"PO-Revision-Date: 2021-12-29 13:20+0000\n"
 "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
 "Language-Team: German <https://translate.edugit.org/projects/aleksis/"
 "aleksis-core/de/>\n"
@@ -39,10 +39,10 @@ msgstr "E-Mail-Adresse"
 msgid "Home and mobile phone"
 msgstr "Festnetz- und Mobilfunknummer"
 
-#: aleksis/core/apps.py:157 aleksis/core/forms.py:222 aleksis/core/menus.py:267
-#: aleksis/core/models.py:412 aleksis/core/templates/core/group/list.html:8
+#: aleksis/core/apps.py:157 aleksis/core/forms.py:223 aleksis/core/menus.py:265
+#: aleksis/core/models.py:414 aleksis/core/templates/core/group/list.html:8
 #: aleksis/core/templates/core/group/list.html:9
-#: aleksis/core/templates/core/person/full.html:145
+#: aleksis/core/templates/core/person/full.html:152
 msgid "Groups"
 msgstr "Gruppen"
 
@@ -92,149 +92,148 @@ msgstr "Berechtigung"
 msgid "Content type"
 msgstr "Inhaltstyp"
 
-#: aleksis/core/filters.py:112 aleksis/core/models.py:579
+#: aleksis/core/filters.py:112 aleksis/core/models.py:581
 msgid "User"
 msgstr "Benutzer"
 
-#: aleksis/core/filters.py:134 aleksis/core/models.py:411
+#: aleksis/core/filters.py:134 aleksis/core/models.py:413
 msgid "Group"
 msgstr "Gruppe"
 
-#: aleksis/core/forms.py:47 aleksis/core/forms.py:521
+#: aleksis/core/forms.py:48 aleksis/core/forms.py:559
 msgid "Base data"
 msgstr "Basisdaten"
 
-#: aleksis/core/forms.py:53
+#: aleksis/core/forms.py:54
 msgid "Address"
 msgstr "Adresse"
 
-#: aleksis/core/forms.py:54
+#: aleksis/core/forms.py:55 aleksis/core/forms.py:568
 msgid "Contact data"
 msgstr "Kontaktdaten"
 
-#: aleksis/core/forms.py:56
+#: aleksis/core/forms.py:57
 msgid "Advanced personal data"
 msgstr "Zusätzliche persönliche Daten"
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "New user"
 msgstr "Neuer Benutzer"
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "Create a new account"
 msgstr "Neues Benutzerkonto erstellen"
 
-#: aleksis/core/forms.py:135
+#: aleksis/core/forms.py:136
 msgid "You cannot set a new username when also selecting an existing user."
 msgstr "Sie können keine neuen Benutzer erstellen, wenn Sie gleichzeitig einen existierenden Benutzer auswählen."
 
-#: aleksis/core/forms.py:139
+#: aleksis/core/forms.py:140
 msgid "This username is already in use."
 msgstr "Dieser Benutzername wird bereits genutzt."
 
-#: aleksis/core/forms.py:156 aleksis/core/models.py:125
+#: aleksis/core/forms.py:157 aleksis/core/models.py:129
 msgid "School term"
 msgstr "Schuljahr"
 
-#: aleksis/core/forms.py:157
+#: aleksis/core/forms.py:158
 msgid "Common data"
 msgstr "Allgemeine Daten"
 
-#: aleksis/core/forms.py:158 aleksis/core/forms.py:209
-#: aleksis/core/menus.py:256 aleksis/core/models.py:148
+#: aleksis/core/forms.py:159 aleksis/core/forms.py:210
+#: aleksis/core/menus.py:254 aleksis/core/models.py:152
 #: aleksis/core/templates/core/person/list.html:8
 #: aleksis/core/templates/core/person/list.html:9
 msgid "Persons"
 msgstr "Personen"
 
-#: aleksis/core/forms.py:159
+#: aleksis/core/forms.py:160 aleksis/core/forms.py:570
 msgid "Additional data"
 msgstr "Zusätzliche Datne"
 
-#: aleksis/core/forms.py:201 aleksis/core/forms.py:204
-#: aleksis/core/models.py:68
+#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
+#: aleksis/core/models.py:72
 msgid "Date"
 msgstr "Datum"
 
-#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
-#: aleksis/core/models.py:76
+#: aleksis/core/forms.py:203 aleksis/core/forms.py:206
+#: aleksis/core/models.py:80
 msgid "Time"
 msgstr "Zeit"
 
-#: aleksis/core/forms.py:235
+#: aleksis/core/forms.py:236
 msgid "From when until when should the announcement be displayed?"
 msgstr "Von wann bis wann soll die Ankündigung angezeigt werden?"
 
-#: aleksis/core/forms.py:238
+#: aleksis/core/forms.py:239
 msgid "Who should see the announcement?"
 msgstr "Wer soll die Ankündigung sehen?"
 
-#: aleksis/core/forms.py:239
+#: aleksis/core/forms.py:240
 msgid "Write your announcement:"
 msgstr "Schreiben Sie ihre Ankündigung:"
 
-#: aleksis/core/forms.py:278
+#: aleksis/core/forms.py:279
 msgid "You are not allowed to create announcements which are only valid in the past."
 msgstr "Sie dürfen keine Ankündigungen erstellen, die nur für die Vergangenheit gültig sind."
 
-#: aleksis/core/forms.py:282
+#: aleksis/core/forms.py:283
 msgid "The from date and time must be earlier then the until date and time."
 msgstr "Das Startdatum und die Startzeit müssen vor dem Enddatum und der Endzeit sein."
 
-#: aleksis/core/forms.py:291
+#: aleksis/core/forms.py:292
 msgid "You need at least one recipient."
 msgstr "Sie benötigen mindestens einen Empfänger."
 
-#: aleksis/core/forms.py:412
+#: aleksis/core/forms.py:401
+msgid "Invitation code"
+msgstr "Einladungscode"
+
+#: aleksis/core/forms.py:402
+msgid "Please enter your invitation code."
+msgstr "Bitte geben Sie Ihren Einladungscode ein."
+
+#: aleksis/core/forms.py:434
 msgid "Who should get the permission?"
 msgstr "Wer soll die Berechtigung erhalten?"
 
-#: aleksis/core/forms.py:413
+#: aleksis/core/forms.py:435
 msgid "On what?"
 msgstr "Auf was?"
 
-#: aleksis/core/forms.py:439
+#: aleksis/core/forms.py:461
 msgid "Select objects which the permission should be granted for:"
 msgstr "Wählen Sie die Objekte aus, für welche die Berechtigung vergeben werden soll:"
 
-#: aleksis/core/forms.py:442
+#: aleksis/core/forms.py:464
 msgid "Grant the permission for all objects"
 msgstr "Vergebe die Berechtigung für alle Objekte"
 
-#: aleksis/core/forms.py:450
+#: aleksis/core/forms.py:472
 msgid "You must select at least one group or person which should get the permission."
 msgstr "Sie müssen mindestens eine Gruppe oder Person auswählen, welche die Berechtigung erhalten soll."
 
-#: aleksis/core/forms.py:455
+#: aleksis/core/forms.py:477
 msgid "You must grant the permission to all objects and/or to some objects."
 msgstr "Sie müssen die Berechtigung auf alle Objekte und/oder für einige Objekte vergeben."
 
-#: aleksis/core/forms.py:525
+#: aleksis/core/forms.py:564
+msgid "Adress data"
+msgstr "Adressdaten"
+
+#: aleksis/core/forms.py:576
 msgid "Account data"
 msgstr "Kontodaten"
 
-#: aleksis/core/forms.py:531
-msgid "Consents"
-msgstr "Zustimmungen"
-
-#: aleksis/core/forms.py:538
+#: aleksis/core/forms.py:583
 msgid "Password"
 msgstr "Passwort"
 
-#: aleksis/core/forms.py:544
+#: aleksis/core/forms.py:586
 msgid "Password (again)"
 msgstr "Passwort wiederholen"
 
-#: aleksis/core/forms.py:557
-#, 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."
-
-#: aleksis/core/forms.py:582
-msgid "You must type the same password each time."
-msgstr "Sie müssen zweimal das gleiche Passwort eingeben."
-
-#: aleksis/core/forms.py:727
+#: aleksis/core/forms.py:752
 msgid "No valid selection."
 msgstr "Keine gültige Auswahl."
 
@@ -271,34 +270,38 @@ msgstr "Anmelden"
 msgid "Sign up"
 msgstr "Registrieren"
 
-#: aleksis/core/menus.py:24
+#: aleksis/core/menus.py:24 aleksis/core/templates/invitations/enter.html:7
+msgid "Accept invitation"
+msgstr "Einladung akzeptieren"
+
+#: aleksis/core/menus.py:33
 msgid "Dashboard"
 msgstr "Dashboard"
 
-#: aleksis/core/menus.py:32 aleksis/core/models.py:625
-#: aleksis/core/preferences.py:27
+#: aleksis/core/menus.py:41 aleksis/core/models.py:627
+#: aleksis/core/preferences.py:28
 #: aleksis/core/templates/core/notifications.html:4
 #: aleksis/core/templates/core/notifications.html:5
 msgid "Notifications"
 msgstr "Benachrichtigungen"
 
-#: aleksis/core/menus.py:44
+#: aleksis/core/menus.py:53
 msgid "Account"
 msgstr "Konto"
 
-#: aleksis/core/menus.py:51
+#: aleksis/core/menus.py:60
 msgid "Stop impersonation"
 msgstr "Verkleidung beenden"
 
-#: aleksis/core/menus.py:60 aleksis/core/templates/core/base.html:80
+#: aleksis/core/menus.py:69 aleksis/core/templates/core/base.html:80
 msgid "Logout"
 msgstr "Abmelden"
 
-#: aleksis/core/menus.py:66
+#: aleksis/core/menus.py:75
 msgid "2FA"
 msgstr "2FA"
 
-#: aleksis/core/menus.py:74
+#: aleksis/core/menus.py:83
 #: aleksis/core/templates/account/password_change.html:5
 #: aleksis/core/templates/account/password_change.html:6
 #: aleksis/core/templates/account/password_change.html:19
@@ -310,830 +313,850 @@ msgstr "2FA"
 msgid "Change password"
 msgstr "Passwort ändern"
 
-#: aleksis/core/menus.py:86
+#: aleksis/core/menus.py:95
 msgid "Me"
 msgstr "Ich"
 
-#: aleksis/core/menus.py:95
+#: aleksis/core/menus.py:104
 #: aleksis/core/templates/dynamic_preferences/form.html:5
 msgid "Preferences"
 msgstr "Einstellungen"
 
-#: aleksis/core/menus.py:104
+#: aleksis/core/menus.py:113
 msgid "Third-party accounts"
 msgstr "Drittanbieter-Konten"
 
-#: aleksis/core/menus.py:113
+#: aleksis/core/menus.py:122
 #: 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:124
+#: aleksis/core/menus.py:133
 msgid "Admin"
 msgstr "Admin"
 
-#: aleksis/core/menus.py:132 aleksis/core/models.py:725
+#: aleksis/core/menus.py:141 aleksis/core/models.py:727
 #: aleksis/core/templates/core/announcement/list.html:7
 #: aleksis/core/templates/core/announcement/list.html:8
 msgid "Announcements"
 msgstr "Ankündigungen"
 
-#: aleksis/core/menus.py:143 aleksis/core/models.py:126
+#: aleksis/core/menus.py:152 aleksis/core/models.py:130
 #: aleksis/core/templates/core/school_term/list.html:8
 #: aleksis/core/templates/core/school_term/list.html:9
 msgid "School terms"
 msgstr "Schuljahre"
 
-#: aleksis/core/menus.py:154
+#: aleksis/core/menus.py:163
 #: aleksis/core/templates/core/dashboard_widget/list.html:8
 #: aleksis/core/templates/core/dashboard_widget/list.html:9
 msgid "Dashboard widgets"
 msgstr "Dashboard-Widgets"
 
-#: aleksis/core/menus.py:165
+#: aleksis/core/menus.py:174
 #: aleksis/core/templates/core/management/data_management.html:6
 #: aleksis/core/templates/core/management/data_management.html:7
 msgid "Data management"
 msgstr "Datenverwaltung"
 
-#: aleksis/core/menus.py:176
+#: aleksis/core/menus.py:185
 #: aleksis/core/templates/core/pages/system_status.html:5
 #: aleksis/core/templates/core/pages/system_status.html:7
 msgid "System status"
 msgstr "Systemstatus"
 
-#: aleksis/core/menus.py:187
-msgid "Impersonation"
-msgstr "Verkleidung"
-
-#: aleksis/core/menus.py:198
+#: aleksis/core/menus.py:196
 msgid "Configuration"
 msgstr "Konfiguration"
 
-#: aleksis/core/menus.py:209 aleksis/core/templates/core/data_check/list.html:9
+#: aleksis/core/menus.py:207 aleksis/core/templates/core/data_check/list.html:9
 #: aleksis/core/templates/core/data_check/list.html:10
 msgid "Data checks"
 msgstr "Datenprüfungen"
 
-#: aleksis/core/menus.py:215 aleksis/core/templates/core/perms/list.html:13
+#: aleksis/core/menus.py:213 aleksis/core/templates/core/perms/list.html:13
 #: aleksis/core/templates/core/perms/list.html:14
 msgid "Manage permissions"
 msgstr "Berechtigungen verwalten"
 
-#: aleksis/core/menus.py:226
+#: aleksis/core/menus.py:224
 msgid "Backend Admin"
 msgstr "Backend-Administration"
 
-#: aleksis/core/menus.py:234
+#: aleksis/core/menus.py:232
 #: aleksis/core/templates/oauth2_provider/application/list.html:5
 #: aleksis/core/templates/oauth2_provider/application/list.html:6
 msgid "OAuth2 Applications"
 msgstr "OAuth2-Anwendungen"
 
-#: aleksis/core/menus.py:247
+#: aleksis/core/menus.py:245
 msgid "People"
 msgstr "Leute"
 
-#: aleksis/core/menus.py:278 aleksis/core/models.py:979
+#: aleksis/core/menus.py:276 aleksis/core/models.py:981
 #: aleksis/core/templates/core/group_type/list.html:8
 #: aleksis/core/templates/core/group_type/list.html:9
 msgid "Group types"
 msgstr "Gruppentypen"
 
-#: aleksis/core/menus.py:289
+#: aleksis/core/menus.py:287
 msgid "Groups and child groups"
 msgstr "Gruppen und Kindgruppen"
 
-#: aleksis/core/menus.py:300 aleksis/core/models.py:460
+#: aleksis/core/menus.py:298 aleksis/core/models.py:462
 #: aleksis/core/templates/core/additional_field/list.html:8
 #: aleksis/core/templates/core/additional_field/list.html:9
 msgid "Additional fields"
 msgstr "Zusätzliche Felder"
 
-#: aleksis/core/menus.py:315
+#: aleksis/core/menus.py:309
+msgid "Invite person"
+msgstr "Person einladen"
+
+#: aleksis/core/menus.py:322
 #: aleksis/core/templates/core/group/child_groups.html:7
 #: aleksis/core/templates/core/group/child_groups.html:9
 msgid "Assign child groups to groups"
 msgstr "Kindgruppen zu Gruppen zuordnen"
 
-#: aleksis/core/mixins.py:508
+#: aleksis/core/mixins.py:511
 msgid "Linked school term"
 msgstr "Zugeordnetes Schuljahr"
 
-#: aleksis/core/models.py:66
+#: aleksis/core/models.py:70
 msgid "Boolean (Yes/No)"
 msgstr "Boolean (Ja/Nein)"
 
-#: aleksis/core/models.py:67
+#: aleksis/core/models.py:71
 msgid "Text (one line)"
 msgstr "Text (eine Zeile)"
 
-#: aleksis/core/models.py:69
+#: aleksis/core/models.py:73
 msgid "Date and time"
 msgstr "Datum und Uhrzeit"
 
-#: aleksis/core/models.py:70
+#: aleksis/core/models.py:74
 msgid "Decimal number"
 msgstr "Dezimalzahl"
 
-#: aleksis/core/models.py:71 aleksis/core/models.py:194
+#: aleksis/core/models.py:75 aleksis/core/models.py:198
 msgid "E-mail address"
 msgstr "E-Mail-Adresse"
 
-#: aleksis/core/models.py:72
+#: aleksis/core/models.py:76
 msgid "Integer"
 msgstr "Ganze Zahl"
 
-#: aleksis/core/models.py:73
+#: aleksis/core/models.py:77
 msgid "IP address"
 msgstr "IP-Adresse"
 
-#: aleksis/core/models.py:74
+#: aleksis/core/models.py:78
 msgid "Boolean or empty (Yes/No/Neither)"
 msgstr "Boolean oder leer (Ja/Nein/weder)"
 
-#: aleksis/core/models.py:75
+#: aleksis/core/models.py:79
 msgid "Text (multi-line)"
 msgstr "Text (mehrzeilig)"
 
-#: aleksis/core/models.py:77
+#: aleksis/core/models.py:81
 msgid "URL / Link"
 msgstr "URL / Link"
 
-#: aleksis/core/models.py:89 aleksis/core/models.py:948
+#: aleksis/core/models.py:93 aleksis/core/models.py:950
 msgid "Name"
 msgstr "Name"
 
-#: aleksis/core/models.py:91
+#: aleksis/core/models.py:95
 msgid "Start date"
 msgstr "Startdatum"
 
-#: aleksis/core/models.py:92
+#: aleksis/core/models.py:96
 msgid "End date"
 msgstr "Enddatum"
 
-#: aleksis/core/models.py:111
+#: aleksis/core/models.py:115
 msgid "The start date must be earlier than the end date."
 msgstr "Das Startdatum muss vor dem Enddatum liegen."
 
-#: aleksis/core/models.py:118
+#: aleksis/core/models.py:122
 msgid "There is already a school term for this time or a part of this time."
 msgstr "Es gibt bereits ein Schuljahr für diesen Zeitraum oder einen Teilzeitraum."
 
-#: aleksis/core/models.py:147 aleksis/core/models.py:897
+#: aleksis/core/models.py:151 aleksis/core/models.py:899
 msgid "Person"
 msgstr "Person"
 
-#: aleksis/core/models.py:150
+#: aleksis/core/models.py:154
 msgid "Can view address"
 msgstr "Kann Adresse sehen"
 
-#: aleksis/core/models.py:151
+#: aleksis/core/models.py:155
 msgid "Can view contact details"
 msgstr "Kann Kontaktdetails sehen"
 
-#: aleksis/core/models.py:152
+#: aleksis/core/models.py:156
 msgid "Can view photo"
 msgstr "Kann Foto sehen"
 
-#: aleksis/core/models.py:153
+#: aleksis/core/models.py:157
 msgid "Can view persons groups"
 msgstr "Kann Gruppen einer Person sehen"
 
-#: aleksis/core/models.py:154
+#: aleksis/core/models.py:158
 msgid "Can view personal details"
 msgstr "Kann persönliche Daten sehen"
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "female"
 msgstr "weiblich"
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "male"
 msgstr "männlich"
 
-#: aleksis/core/models.py:172
+#: aleksis/core/models.py:176 aleksis/core/models.py:1144
 msgid "Linked user"
 msgstr "Verknüpfter Benutzer"
 
-#: aleksis/core/models.py:174
+#: aleksis/core/models.py:178
 msgid "Is person active?"
 msgstr "Ist die Person aktiv?"
 
-#: aleksis/core/models.py:176
+#: aleksis/core/models.py:180
 msgid "First name"
 msgstr "Vorname"
 
-#: aleksis/core/models.py:177
+#: aleksis/core/models.py:181
 msgid "Last name"
 msgstr "Nachname"
 
-#: aleksis/core/models.py:179
+#: aleksis/core/models.py:183
 msgid "Additional name(s)"
 msgstr "Zusätzliche Namen"
 
-#: aleksis/core/models.py:183 aleksis/core/models.py:429
+#: aleksis/core/models.py:187 aleksis/core/models.py:431
 msgid "Short name"
 msgstr "Kurzname"
 
-#: aleksis/core/models.py:186
+#: aleksis/core/models.py:190
 msgid "Street"
 msgstr "Straße"
 
-#: aleksis/core/models.py:187
+#: aleksis/core/models.py:191
 msgid "Street number"
 msgstr "Hausnummer"
 
-#: aleksis/core/models.py:188
+#: aleksis/core/models.py:192
 msgid "Postal code"
 msgstr "Postleitzahl"
 
-#: aleksis/core/models.py:189
+#: aleksis/core/models.py:193
 msgid "Place"
 msgstr "Ort"
 
-#: aleksis/core/models.py:191
+#: aleksis/core/models.py:195
 msgid "Home phone"
 msgstr "Festnetz"
 
-#: aleksis/core/models.py:192
+#: aleksis/core/models.py:196
 msgid "Mobile phone"
 msgstr "Handy"
 
-#: aleksis/core/models.py:196
+#: aleksis/core/models.py:200
 msgid "Date of birth"
 msgstr "Geburtsdatum"
 
-#: aleksis/core/models.py:198
+#: aleksis/core/models.py:201
 msgid "Place of birth"
 msgstr "Geburtsort"
 
-#: aleksis/core/models.py:200
+#: aleksis/core/models.py:202
 msgid "Sex"
 msgstr "Geschlecht"
 
-#: aleksis/core/models.py:202
+#: aleksis/core/models.py:204
 msgid "Photo"
 msgstr "Foto"
 
-#: aleksis/core/models.py:206 aleksis/core/templates/core/person/full.html:138
+#: aleksis/core/models.py:208 aleksis/core/templates/core/person/full.html:145
 msgid "Guardians / Parents"
 msgstr "Erziehungsberechtigte / Eltern"
 
-#: aleksis/core/models.py:213
+#: aleksis/core/models.py:215
 msgid "Primary group"
 msgstr "Primärgruppe"
 
-#: aleksis/core/models.py:216 aleksis/core/models.py:583
-#: aleksis/core/models.py:607 aleksis/core/models.py:692
-#: aleksis/core/models.py:972 aleksis/core/templates/core/person/full.html:121
+#: aleksis/core/models.py:218 aleksis/core/models.py:585
+#: aleksis/core/models.py:609 aleksis/core/models.py:694
+#: aleksis/core/models.py:974 aleksis/core/templates/core/person/full.html:128
 msgid "Description"
 msgstr "Beschreibung"
 
-#: aleksis/core/models.py:384
+#: aleksis/core/models.py:386
 msgid "Title of field"
 msgstr "Feldtitel"
 
-#: aleksis/core/models.py:386
+#: aleksis/core/models.py:388
 msgid "Type of field"
 msgstr "Feldtyp"
 
-#: aleksis/core/models.py:393
+#: aleksis/core/models.py:395
 msgid "Addtitional field for groups"
 msgstr "Zusätzliche Felder für Gruppen"
 
-#: aleksis/core/models.py:394
+#: aleksis/core/models.py:396
 msgid "Addtitional fields for groups"
 msgstr "Zusätzliche Felder für Gruppen"
 
-#: aleksis/core/models.py:414
+#: aleksis/core/models.py:416
 msgid "Can assign child groups to groups"
 msgstr "Kann Kindgruppen zu Gruppen zuordnen"
 
-#: aleksis/core/models.py:415
+#: aleksis/core/models.py:417
 msgid "Can view statistics about group."
 msgstr "Kann Statistiken über Gruppen sehen."
 
-#: aleksis/core/models.py:427
+#: aleksis/core/models.py:429
 msgid "Long name"
 msgstr "Langname"
 
-#: aleksis/core/models.py:437 aleksis/core/templates/core/group/full.html:85
+#: aleksis/core/models.py:439 aleksis/core/templates/core/group/full.html:85
 msgid "Members"
 msgstr "Mitglieder"
 
-#: aleksis/core/models.py:440 aleksis/core/templates/core/group/full.html:82
+#: aleksis/core/models.py:442 aleksis/core/templates/core/group/full.html:82
 msgid "Owners"
 msgstr "Leiter/-innen"
 
-#: aleksis/core/models.py:447 aleksis/core/templates/core/group/full.html:55
+#: aleksis/core/models.py:449 aleksis/core/templates/core/group/full.html:55
 msgid "Parent groups"
 msgstr "Ãœbergeordnete Gruppen"
 
-#: aleksis/core/models.py:455
+#: aleksis/core/models.py:457
 msgid "Type of group"
 msgstr "Gruppentyp"
 
-#: aleksis/core/models.py:582 aleksis/core/models.py:606
-#: aleksis/core/models.py:691
+#: aleksis/core/models.py:584 aleksis/core/models.py:608
+#: aleksis/core/models.py:693
 #: aleksis/core/templates/core/announcement/list.html:18
 msgid "Title"
 msgstr "Titel"
 
-#: aleksis/core/models.py:585
+#: aleksis/core/models.py:587
 msgid "Application"
 msgstr "Anwendung"
 
-#: aleksis/core/models.py:591
+#: aleksis/core/models.py:593
 msgid "Activity"
 msgstr "Aktivität"
 
-#: aleksis/core/models.py:592
+#: aleksis/core/models.py:594
 msgid "Activities"
 msgstr "Aktivitäten"
 
-#: aleksis/core/models.py:598
+#: aleksis/core/models.py:600
 msgid "Sender"
 msgstr "Absender"
 
-#: aleksis/core/models.py:603
+#: aleksis/core/models.py:605
 msgid "Recipient"
 msgstr "Empfänger"
 
-#: aleksis/core/models.py:608 aleksis/core/models.py:949
+#: aleksis/core/models.py:610 aleksis/core/models.py:951
 msgid "Link"
 msgstr "Link"
 
-#: aleksis/core/models.py:610
+#: aleksis/core/models.py:612
 msgid "Read"
 msgstr "Gelesen"
 
-#: aleksis/core/models.py:611
+#: aleksis/core/models.py:613
 msgid "Sent"
 msgstr "Versandt"
 
-#: aleksis/core/models.py:624
+#: aleksis/core/models.py:626
 msgid "Notification"
 msgstr "Benachrichtigung"
 
-#: aleksis/core/models.py:693
+#: aleksis/core/models.py:695
 msgid "Link to detailed view"
 msgstr "Link zur detaillierten Ansicht"
 
-#: aleksis/core/models.py:696
+#: aleksis/core/models.py:698
 msgid "Date and time from when to show"
 msgstr "Datum und Uhrzeit des Anzeigestarts"
 
-#: aleksis/core/models.py:699
+#: aleksis/core/models.py:701
 msgid "Date and time until when to show"
 msgstr "Anzeigezeitraum"
 
-#: aleksis/core/models.py:724
+#: aleksis/core/models.py:726
 msgid "Announcement"
 msgstr "Ankündigung"
 
-#: aleksis/core/models.py:762
+#: aleksis/core/models.py:764
 msgid "Announcement recipient"
 msgstr "Empfänger der Ankündigung"
 
-#: aleksis/core/models.py:763
+#: aleksis/core/models.py:765
 msgid "Announcement recipients"
 msgstr "Empfänger der Ankündigung"
 
-#: aleksis/core/models.py:818
+#: aleksis/core/models.py:820
 msgid "Widget Title"
 msgstr "Widget-Titel"
 
-#: aleksis/core/models.py:819
+#: aleksis/core/models.py:821
 msgid "Activate Widget"
 msgstr "Widget aktivieren"
 
-#: aleksis/core/models.py:820
+#: aleksis/core/models.py:822
 msgid "Widget is broken"
 msgstr "Widget ist kaputt"
 
-#: aleksis/core/models.py:823
+#: aleksis/core/models.py:825
 msgid "Size on mobile devices"
 msgstr "Größe auf Mobilgeräten"
 
-#: aleksis/core/models.py:824
+#: aleksis/core/models.py:826
 msgid "<= 600 px, 12 columns"
 msgstr "<= 600 px, 12 Spalten"
 
-#: aleksis/core/models.py:829
+#: aleksis/core/models.py:831
 msgid "Size on tablet devices"
 msgstr "Größe auf Tablets"
 
-#: aleksis/core/models.py:830
+#: aleksis/core/models.py:832
 msgid "> 600 px, 12 columns"
 msgstr "> 600px, 12 Spalten"
 
-#: aleksis/core/models.py:835
+#: aleksis/core/models.py:837
 msgid "Size on desktop devices"
 msgstr "Größe auf Desktopgeräten"
 
-#: aleksis/core/models.py:836
+#: aleksis/core/models.py:838
 msgid "> 992 px, 12 columns"
 msgstr "> 992 px, 12 Spalten"
 
-#: aleksis/core/models.py:841
+#: aleksis/core/models.py:843
 msgid "Size on large desktop devices"
 msgstr "Größe auf großen Desktopgeräten"
 
-#: aleksis/core/models.py:842
+#: aleksis/core/models.py:844
 msgid "> 1200 px>, 12 columns"
 msgstr "> 1200 px, 12 Spalten"
 
-#: aleksis/core/models.py:873
+#: aleksis/core/models.py:875
 msgid "Can edit default dashboard"
 msgstr "Kann Standarddashboard bearbeiten"
 
-#: aleksis/core/models.py:874
+#: aleksis/core/models.py:876
 msgid "Dashboard Widget"
 msgstr "Dashboard-Widget"
 
-#: aleksis/core/models.py:875
+#: aleksis/core/models.py:877
 msgid "Dashboard Widgets"
 msgstr "Dashboard-Widgets"
 
-#: aleksis/core/models.py:881
+#: aleksis/core/models.py:883
 msgid "URL"
 msgstr "URL"
 
-#: aleksis/core/models.py:882
+#: aleksis/core/models.py:884
 msgid "Icon URL"
 msgstr "Symbol-URL"
 
-#: aleksis/core/models.py:888
+#: aleksis/core/models.py:890
 msgid "External link widget"
 msgstr "Externer-Link-Widget"
 
-#: aleksis/core/models.py:889
+#: aleksis/core/models.py:891
 msgid "External link widgets"
 msgstr "Externer-Link-Widgets"
 
-#: aleksis/core/models.py:894
+#: aleksis/core/models.py:896
 msgid "Dashboard widget"
 msgstr "Dashboard-Widget"
 
-#: aleksis/core/models.py:899
+#: aleksis/core/models.py:901
 msgid "Order"
 msgstr "Reihenfolge"
 
-#: aleksis/core/models.py:900
+#: aleksis/core/models.py:902
 msgid "Part of the default dashboard"
 msgstr "Teil des Standarddashboards"
 
-#: aleksis/core/models.py:915
+#: aleksis/core/models.py:917
 msgid "Dashboard widget order"
 msgstr "Reihenfolge der Dashboard-Widgets"
 
-#: aleksis/core/models.py:916
+#: aleksis/core/models.py:918
 msgid "Dashboard widget orders"
 msgstr "Reihenfolgen der Dashboard-Widgets"
 
-#: aleksis/core/models.py:922
+#: aleksis/core/models.py:924
 msgid "Menu ID"
 msgstr "Menü-ID"
 
-#: aleksis/core/models.py:935
+#: aleksis/core/models.py:937
 msgid "Custom menu"
 msgstr "Benutzerdefiniertes Menü"
 
-#: aleksis/core/models.py:936
+#: aleksis/core/models.py:938
 msgid "Custom menus"
 msgstr "Benutzerdefinierte Menüs"
 
-#: aleksis/core/models.py:946
+#: aleksis/core/models.py:948
 msgid "Menu"
 msgstr "Menü"
 
-#: aleksis/core/models.py:950
+#: aleksis/core/models.py:952
 msgid "Icon"
 msgstr "Symbol"
 
-#: aleksis/core/models.py:956
+#: aleksis/core/models.py:958
 msgid "Custom menu item"
 msgstr "Benutzerdefiniertes Menüelement"
 
-#: aleksis/core/models.py:957
+#: aleksis/core/models.py:959
 msgid "Custom menu items"
 msgstr "Benutzerdefinierte Menüelemente"
 
-#: aleksis/core/models.py:971
+#: aleksis/core/models.py:973
 msgid "Title of type"
 msgstr "Titel des Typs"
 
-#: aleksis/core/models.py:978 aleksis/core/templates/core/group/full.html:47
+#: aleksis/core/models.py:980 aleksis/core/templates/core/group/full.html:47
 msgid "Group type"
 msgstr "Gruppentyp"
 
-#: aleksis/core/models.py:992
+#: aleksis/core/models.py:994
 msgid "Can view system status"
 msgstr "Kann Systemstatus sehen"
 
-#: aleksis/core/models.py:993
+#: aleksis/core/models.py:995
 msgid "Can manage data"
 msgstr "Kann Daten verwalten"
 
-#: aleksis/core/models.py:994
+#: aleksis/core/models.py:996
 msgid "Can impersonate"
 msgstr "Kann sich verkleiden"
 
-#: aleksis/core/models.py:995
+#: aleksis/core/models.py:997
 msgid "Can use search"
 msgstr "Kann Suche benutzen"
 
-#: aleksis/core/models.py:996
+#: aleksis/core/models.py:998
 msgid "Can change site preferences"
 msgstr "Kann Konfiguration ändern"
 
-#: aleksis/core/models.py:997
+#: aleksis/core/models.py:999
 msgid "Can change person preferences"
 msgstr "Kann Einstellungen einer Person verändern"
 
-#: aleksis/core/models.py:998
+#: aleksis/core/models.py:1000
 msgid "Can change group preferences"
 msgstr "Kann Einstellungen einer Gruppe verändern"
 
-#: aleksis/core/models.py:999
+#: aleksis/core/models.py:1001
 msgid "Can test PDF generation"
 msgstr "Kann die PDF-Generierung testen"
 
-#: aleksis/core/models.py:1035
+#: aleksis/core/models.py:1037
 msgid "Related data check task"
 msgstr "Zugehörige Datenprüfungsaufgabe"
 
-#: aleksis/core/models.py:1043
+#: aleksis/core/models.py:1045
 msgid "Issue solved"
 msgstr "Problem gelöst"
 
-#: aleksis/core/models.py:1044
+#: aleksis/core/models.py:1046
 msgid "Notification sent"
 msgstr "Benachrichtigung gesendet"
 
-#: aleksis/core/models.py:1057
+#: aleksis/core/models.py:1059
 msgid "Data check result"
 msgstr "Datenprüfungsergebnis"
 
-#: aleksis/core/models.py:1058
+#: aleksis/core/models.py:1060
 msgid "Data check results"
 msgstr "Datenprüfungsergebnisse"
 
-#: aleksis/core/models.py:1060
+#: aleksis/core/models.py:1062
 msgid "Can run data checks"
 msgstr "Kann Datenprüfungen ausführen"
 
-#: aleksis/core/models.py:1061
+#: aleksis/core/models.py:1063
 msgid "Can solve data check problems"
 msgstr "Kann Datenprüfungsprobleme lösen"
 
-#: aleksis/core/models.py:1076
+#: aleksis/core/models.py:1070
+msgid "E-Mail address"
+msgstr "E-Mail-Adresse"
+
+#: aleksis/core/models.py:1094
 msgid "Owner"
 msgstr "Leiter"
 
-#: aleksis/core/models.py:1080
+#: aleksis/core/models.py:1098
 msgid "File expires at"
 msgstr "Datei abgelaufen am"
 
-#: aleksis/core/models.py:1082
+#: aleksis/core/models.py:1100
 msgid "Generated HTML file"
 msgstr "Generierte HTML-Datei"
 
-#: aleksis/core/models.py:1084
+#: aleksis/core/models.py:1102
 msgid "Generated PDF file"
 msgstr "Generierte PDF-Datei"
 
-#: aleksis/core/models.py:1091
+#: aleksis/core/models.py:1109
 msgid "PDF file"
 msgstr "PDF-Datei"
 
-#: aleksis/core/models.py:1092
+#: aleksis/core/models.py:1110
 msgid "PDF files"
 msgstr "PDF-Dateien"
 
-#: aleksis/core/models.py:1097
+#: aleksis/core/models.py:1115
 msgid "Task result"
 msgstr "Task-Ergebnis"
 
-#: aleksis/core/models.py:1100
+#: aleksis/core/models.py:1118
 msgid "Task user"
 msgstr "Task-Benutzer"
 
-#: aleksis/core/models.py:1112
+#: aleksis/core/models.py:1130
 msgid "Task user assignment"
 msgstr "Task-Benutzer-Zuordnung"
 
-#: aleksis/core/models.py:1113
+#: aleksis/core/models.py:1131
 msgid "Task user assignments"
 msgstr "Task-Benutzer-Zuordnungen"
 
-#: aleksis/core/models.py:1127
+#: aleksis/core/models.py:1147
+msgid "Additional attributes"
+msgstr "Zusätzliche Attribute"
+
+#: aleksis/core/models.py:1185
 msgid "Allowed scopes that clients can request"
 msgstr "Erlaubte Scopes, die ein Client anfordern kann"
 
-#: aleksis/core/preferences.py:23
+#: aleksis/core/preferences.py:24
 msgid "General"
 msgstr "Allgemein"
 
-#: aleksis/core/preferences.py:24
+#: aleksis/core/preferences.py:25
 msgid "School"
 msgstr "Schule"
 
-#: aleksis/core/preferences.py:25
+#: aleksis/core/preferences.py:26
 msgid "Theme"
 msgstr "Theme"
 
-#: aleksis/core/preferences.py:26
+#: aleksis/core/preferences.py:27
 msgid "Mail"
 msgstr "E-Mail"
 
-#: aleksis/core/preferences.py:28
+#: aleksis/core/preferences.py:29
 msgid "Footer"
 msgstr "Fußbereich"
 
-#: aleksis/core/preferences.py:29
+#: aleksis/core/preferences.py:30
 msgid "Accounts"
 msgstr "Konten"
 
-#: aleksis/core/preferences.py:30
+#: aleksis/core/preferences.py:31
 msgid "Authentication"
 msgstr "Authentifizierung"
 
-#: aleksis/core/preferences.py:31
+#: aleksis/core/preferences.py:32
 msgid "Internationalisation"
 msgstr "Internationalisierung"
 
-#: aleksis/core/preferences.py:42
+#: aleksis/core/preferences.py:43
 msgid "Site title"
 msgstr "Seitentitel"
 
-#: aleksis/core/preferences.py:53
+#: aleksis/core/preferences.py:54
 msgid "Site description"
 msgstr "Seitenbeschreibung"
 
-#: aleksis/core/preferences.py:64
+#: aleksis/core/preferences.py:65
 msgid "Primary colour"
 msgstr "Primärfarbe"
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:77
 msgid "Secondary colour"
 msgstr "Akzentfarbe"
 
-#: aleksis/core/preferences.py:87
+#: aleksis/core/preferences.py:88
 msgid "Logo"
 msgstr "Logo"
 
-#: aleksis/core/preferences.py:97
+#: aleksis/core/preferences.py:98
 msgid "Favicon"
 msgstr "Favicon"
 
-#: aleksis/core/preferences.py:107
+#: aleksis/core/preferences.py:108
 msgid "PWA-Icon"
 msgstr "PWA-Icon"
 
-#: aleksis/core/preferences.py:118
+#: aleksis/core/preferences.py:119
 msgid "Mail out name"
 msgstr "Ausgangsmailname"
 
-#: aleksis/core/preferences.py:129
+#: aleksis/core/preferences.py:130
 msgid "Mail out address"
 msgstr "E-Mail-Ausgangsadresse"
 
-#: aleksis/core/preferences.py:141
+#: aleksis/core/preferences.py:142
 msgid "Link to privacy policy"
 msgstr "Link zur Datenschutzerklärung"
 
-#: aleksis/core/preferences.py:153
+#: aleksis/core/preferences.py:154
 msgid "Link to imprint"
 msgstr "Link zum Impressum"
 
-#: aleksis/core/preferences.py:165
+#: aleksis/core/preferences.py:166
 msgid "Name format for addressing"
 msgstr "Namensformat für Anreden"
 
-#: aleksis/core/preferences.py:181
+#: aleksis/core/preferences.py:182
 msgid "Channels to use for notifications"
 msgstr "Aktivierte Benachrichtungskanäle"
 
-#: aleksis/core/preferences.py:193
+#: aleksis/core/preferences.py:194
 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:204
+#: aleksis/core/preferences.py:205
 msgid "Field on person to match primary group against"
 msgstr "Feld um Primärgruppen zu finden"
 
-#: aleksis/core/preferences.py:216
+#: aleksis/core/preferences.py:217
 msgid "Automatically create new persons for new users"
 msgstr "Erstelle automatisch neue Personen für neue Benutzer"
 
-#: aleksis/core/preferences.py:225
+#: aleksis/core/preferences.py:226
 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:236
+#: aleksis/core/preferences.py:237
 msgid "Display name of the school"
 msgstr "Sichtbarer Name der Schule"
 
-#: aleksis/core/preferences.py:247
+#: aleksis/core/preferences.py:248
 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:255
+#: aleksis/core/preferences.py:256
 msgid "Allow users to change their passwords"
 msgstr "Erlaube Benutzern, ihr Passwort zu ändern"
 
-#: aleksis/core/preferences.py:263
+#: aleksis/core/preferences.py:264
 msgid "Enable signup"
 msgstr "Registrierung aktivieren"
 
-#: aleksis/core/preferences.py:274
+#: aleksis/core/preferences.py:272
+msgid "Enable invitations"
+msgstr "Einladungen aktivieren"
+
+#: aleksis/core/preferences.py:280
+msgid "Length of invite code. (Default 3: abcde-acbde-abcde)"
+msgstr "Länge des Einladungscodes. (Standard: 3: abcde-acbde-abcde)"
+
+#: aleksis/core/preferences.py:288
+msgid "Size of packets. (Default 5: abcde)"
+msgstr "Größe der Pakete. (Standard 5: abcde)"
+
+#: aleksis/core/preferences.py:298
 msgid "Allowed Grant Flows for OAuth applications"
 msgstr "Erlaubte Grant Flows für OAuth-Anwendungen"
 
-#: aleksis/core/preferences.py:287
+#: aleksis/core/preferences.py:311
 msgid "Available languages"
 msgstr "Verfügbare Sprachen"
 
-#: aleksis/core/preferences.py:299
+#: aleksis/core/preferences.py:323
 msgid "Send emails if data checks detect problems"
 msgstr "E-Mails versenden, wenn Datenprüfungen Probleme finden"
 
-#: aleksis/core/preferences.py:310
+#: aleksis/core/preferences.py:334
 msgid "Email recipients for data checks problem emails"
 msgstr "E-Mailempfänger für Datenprüfungsproblem-E-Mails"
 
-#: aleksis/core/preferences.py:321
+#: aleksis/core/preferences.py:345
 msgid "Email recipient groups for data checks problem emails"
 msgstr "E-Mail-Empfängergruppen für Datenprüfungsproblem-E-Mails"
 
-#: aleksis/core/preferences.py:330
+#: aleksis/core/preferences.py:354
 msgid "Show dashboard to users without login"
 msgstr "Zeige Dashboard für Benutzer ohne Login"
 
-#: aleksis/core/preferences.py:339
+#: aleksis/core/preferences.py:363
 msgid "Allow users to edit their dashboard"
 msgstr "Erlaube Benutzern, ihr Dashboard zu bearbeiten"
 
-#: aleksis/core/preferences.py:350
+#: aleksis/core/preferences.py:374
 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:364
+#: aleksis/core/preferences.py:388
 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:377
+#: aleksis/core/preferences.py:401
 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:387
+#: aleksis/core/preferences.py:411
 msgid "PDF file expiration duration"
 msgstr "PDF-Datei-Ablaufdauer"
 
-#: aleksis/core/preferences.py:388
+#: aleksis/core/preferences.py:412
 msgid "in minutes"
 msgstr "in Minuten"
 
-#: aleksis/core/preferences.py:398
+#: aleksis/core/preferences.py:422
 msgid "Automatically update the dashboard and its widgets"
 msgstr "Automatisch das Dashboard und seine Widgets aktualisieren"
 
-#: aleksis/core/preferences.py:408
+#: aleksis/core/preferences.py:432
 msgid "Automatically update the dashboard and its widgets sitewide"
 msgstr "Automatisch das Dashboard und seine Widgets aktualisieren (auf der ganzen Seite)"
 
-#: aleksis/core/settings.py:482
+#: aleksis/core/settings.py:507
 msgid "English"
 msgstr "Englisch"
 
-#: aleksis/core/settings.py:483
+#: aleksis/core/settings.py:508
 msgid "German"
 msgstr "Deutsch"
 
-#: aleksis/core/tables.py:19
+#: aleksis/core/tables.py:24
 #: aleksis/core/templates/core/announcement/list.html:36
 #: aleksis/core/templates/core/group/full.html:24
-#: aleksis/core/templates/core/person/full.html:23
+#: aleksis/core/templates/core/person/full.html:24
 #: aleksis/core/templates/oauth2_provider/application/detail.html:17
 msgid "Edit"
 msgstr "Bearbeiten"
 
-#: aleksis/core/tables.py:21 aleksis/core/tables.py:89
-#: aleksis/core/tables.py:105
+#: aleksis/core/tables.py:26 aleksis/core/tables.py:94
+#: aleksis/core/tables.py:137
 #: aleksis/core/templates/core/announcement/list.html:22
 msgid "Actions"
 msgstr "Aktionen"
 
-#: aleksis/core/tables.py:56 aleksis/core/tables.py:57
-#: aleksis/core/tables.py:71 aleksis/core/tables.py:87
-#: aleksis/core/tables.py:103
+#: aleksis/core/tables.py:61 aleksis/core/tables.py:62
+#: aleksis/core/tables.py:76 aleksis/core/tables.py:92
+#: aleksis/core/tables.py:135
 #: aleksis/core/templates/core/announcement/list.html:42
 #: aleksis/core/templates/core/group/full.html:31
 #: aleksis/core/templates/core/pages/delete.html:22
-#: aleksis/core/templates/core/person/full.html:30
+#: aleksis/core/templates/core/person/full.html:31
 #: aleksis/core/templates/oauth2_provider/application/detail.html:21
 msgid "Delete"
 msgstr "Löschen"
@@ -1228,11 +1251,11 @@ msgstr ""
 msgid "Account inactive"
 msgstr "Konto inaktiv"
 
-#: aleksis/core/templates/account/account_inactive.html:13
+#: aleksis/core/templates/account/account_inactive.html:14
 msgid "Account inactive."
 msgstr "Konto inaktiv."
 
-#: aleksis/core/templates/account/account_inactive.html:15
+#: aleksis/core/templates/account/account_inactive.html:17
 msgid ""
 "\n"
 "            This account is currently inactive. If you think this is an\n"
@@ -1408,11 +1431,11 @@ msgstr "Haben Sie bereits ein Konto? Dann <a href=\"%(login_url)s\">melden Sie s
 msgid "Signup closed"
 msgstr "Registrierung geschlossen"
 
-#: aleksis/core/templates/account/signup_closed.html:13
+#: aleksis/core/templates/account/signup_closed.html:14
 msgid "Signup closed."
 msgstr "Registrierung geschlossen."
 
-#: aleksis/core/templates/account/signup_closed.html:15
+#: aleksis/core/templates/account/signup_closed.html:17
 msgid ""
 "\n"
 "            This sign up is currently closed. If you think this is an\n"
@@ -1463,11 +1486,6 @@ msgstr ""
 "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>"
-
 #: aleksis/core/templates/core/additional_field/edit.html:6
 #: aleksis/core/templates/core/additional_field/edit.html:7
 msgid "Edit additional field"
@@ -1520,7 +1538,7 @@ msgid "About AlekSIS® — The Free School Information System"
 msgstr "Über AlekSIS® — The Free School Information System"
 
 #: aleksis/core/templates/core/base.html:183
-msgid "Impress"
+msgid "Imprint"
 msgstr "Impressum"
 
 #: aleksis/core/templates/core/base.html:191
@@ -1755,7 +1773,7 @@ msgstr "Zurück"
 #: aleksis/core/templates/core/group/child_groups.html:134
 #: aleksis/core/templates/two_factor/_wizard_actions.html:26
 msgid "Next"
-msgstr "Weiter"
+msgstr "Nächste"
 
 #: aleksis/core/templates/core/group/child_groups.html:106
 #: aleksis/core/templates/core/group/child_groups.html:141
@@ -1774,7 +1792,7 @@ msgid "Edit group"
 msgstr "Gruppe editieren"
 
 #: aleksis/core/templates/core/group/full.html:38
-#: aleksis/core/templates/core/person/full.html:37
+#: aleksis/core/templates/core/person/full.html:38
 msgid "Change preferences"
 msgstr "Einstellungen ändern"
 
@@ -1887,10 +1905,8 @@ msgid ""
 "            "
 msgstr ""
 "\n"
-"              Diese Plattform wird mit AlekSIS®, einem webbasierten "
-"Schulinformationssystem (SIS), \n"
-"welches für die Verwaltung und/oder Veröffentlichung von "
-"Bildungseinrichtungen verwendet werden kann.\n"
+"              Diese Plattform wird mit AlekSIS®, einem webbasierten Schulinformationssystem (SIS), \n"
+"welches für die Verwaltung und/oder Veröffentlichung von Bildungseinrichtungen verwendet werden kann.\n"
 "AlekSIS ist freie Software und kann von jedem benutzt werden.\n"
 "            "
 
@@ -1901,8 +1917,7 @@ msgid ""
 "            "
 msgstr ""
 "\n"
-"              AlekSIS® ist eine eingetragene Wortmarke des Open-Source-"
-"Projektes AlekSIS, vertreten durch den Teckids e.V.\n"
+"              AlekSIS® ist eine eingetragene Wortmarke des Open-Source-Projektes AlekSIS, vertreten durch den Teckids e.V.\n"
 "            "
 
 #: aleksis/core/templates/core/pages/about.html:30
@@ -2227,17 +2242,19 @@ msgstr "Person erstellen"
 msgid "Edit person"
 msgstr "Person editieren"
 
-#: aleksis/core/templates/core/person/full.html:44
-#: aleksis/core/templates/impersonate/list_users.html:7
-#: aleksis/core/templates/impersonate/list_users.html:8
+#: aleksis/core/templates/core/person/full.html:45
 msgid "Impersonate"
 msgstr "Verkleiden"
 
-#: aleksis/core/templates/core/person/full.html:50
+#: aleksis/core/templates/core/person/full.html:51
+msgid "Invite user"
+msgstr "Benutzer einladen"
+
+#: aleksis/core/templates/core/person/full.html:57
 msgid "Contact details"
 msgstr "Kontaktdetails"
 
-#: aleksis/core/templates/core/person/full.html:131
+#: aleksis/core/templates/core/person/full.html:138
 msgid "Children"
 msgstr "Kinder"
 
@@ -2277,6 +2294,53 @@ msgstr "Einstellungen für %(instance)s"
 msgid "Save preferences"
 msgstr "Einstellungen speichern"
 
+#: aleksis/core/templates/invitations/enter.html:21
+msgid "Accept your invitation"
+msgstr "Ihre Einladung akzeptieren"
+
+#: aleksis/core/templates/invitations/enter.html:25
+msgid ""
+"\n"
+"                Please enter your invitation code to register\n"
+"                your new user account:\n"
+"              "
+msgstr ""
+"\n"
+"                Bitte geben Sie Ihren Einladungscode ein, \n"
+"um Ihr neues Benutzerkonto zu registrieren:\n"
+"              "
+
+#: aleksis/core/templates/invitations/enter.html:37
+msgid "Accept invite"
+msgstr "Einladung akzeptieren"
+
+#: aleksis/core/templates/invitations/forms/_invite.html:9
+#: aleksis/core/templates/invitations/forms/_invite.html:10
+#: aleksis/core/templates/invitations/forms/_invite.html:21
+msgid "Invite"
+msgstr "Einladen"
+
+#: aleksis/core/templates/invitations/forms/_invite.html:17
+msgid "Invite by email address"
+msgstr "Mit E-Mail-Adresse einladen"
+
+#: aleksis/core/templates/invitations/forms/_invite.html:26
+msgid "Generate invitation code"
+msgstr "Einladungscode generieren"
+
+#: aleksis/core/templates/invitations/forms/_invite.html:29
+msgid "Generate code"
+msgstr "Code generieren"
+
+#: aleksis/core/templates/invitations/forms/_invite.html:33
+msgid "Invitations"
+msgstr "Einladungen"
+
+#: aleksis/core/templates/invitations/messages/invite_accepted.txt:3
+#, python-format
+msgid "The invitation for %(email)s has been accepted."
+msgstr "Die Einladung für %(email)s wurde akzeptiert."
+
 #: aleksis/core/templates/oauth2_provider/application/create.html:5
 #: aleksis/core/templates/oauth2_provider/application/create.html:6
 msgid "Register OAuth2 Application"
@@ -3102,131 +3166,164 @@ msgstr "Es ist ein Fehler beim Generieren der PDF-Datei aufgetreten."
 msgid "Download PDF"
 msgstr "PDF herunterladen"
 
-#: aleksis/core/views.py:270
+#: aleksis/core/views.py:280
 msgid "The school term has been created."
 msgstr "Das Schuljahr wurde erstellt."
 
-#: aleksis/core/views.py:282
+#: aleksis/core/views.py:292
 msgid "The school term has been saved."
 msgstr "Das Schuljahr wurde gespeichert."
 
-#: aleksis/core/views.py:406
+#: aleksis/core/views.py:416
 msgid "The child groups were successfully saved."
 msgstr "Die Untergruppen wurden gespeichert."
 
-#: aleksis/core/views.py:425 aleksis/core/views.py:435
+#: aleksis/core/views.py:435 aleksis/core/views.py:445
 msgid "The person has been saved."
 msgstr "Die Person wurde gespeichert."
 
-#: aleksis/core/views.py:485
+#: aleksis/core/views.py:495
 msgid "The group has been saved."
 msgstr "Die Gruppe wurde gespeichert."
 
-#: aleksis/core/views.py:582
+#: aleksis/core/views.py:592
 msgid "The announcement has been saved."
 msgstr "Die Ankündigung wurde gespeichert."
 
-#: aleksis/core/views.py:598
+#: aleksis/core/views.py:608
 msgid "The announcement has been deleted."
 msgstr "Ankündigung wurde gelöscht."
 
-#: aleksis/core/views.py:682
+#: aleksis/core/views.py:695
 msgid "The preferences have been saved successfully."
 msgstr "Die Einstellungen wurde gespeichert."
 
-#: aleksis/core/views.py:706
+#: aleksis/core/views.py:719
 msgid "The person has been deleted."
 msgstr "Die Person wurde gelöscht."
 
-#: aleksis/core/views.py:720
+#: aleksis/core/views.py:733
 msgid "The group has been deleted."
 msgstr "Die Gruppe wurde gelöscht."
 
-#: aleksis/core/views.py:752
+#: aleksis/core/views.py:765
 msgid "The additional_field has been saved."
 msgstr "Das zusätzliche Feld wurde gespeichert."
 
-#: aleksis/core/views.py:786
+#: aleksis/core/views.py:799
 msgid "The additional field has been deleted."
 msgstr "Das zusätzliche Feld wurde gelöscht."
 
-#: aleksis/core/views.py:811
+#: aleksis/core/views.py:824
 msgid "The group type has been saved."
 msgstr "Der Gruppentyp wurde gespeichert."
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:854
 msgid "The group type has been deleted."
 msgstr "Der Gruppentyp wurde gelöscht."
 
-#: aleksis/core/views.py:874
+#: aleksis/core/views.py:887
 msgid "Progress: Run data checks"
 msgstr "Fortschritt: Datenprüfungen ausführen"
 
-#: aleksis/core/views.py:875
+#: aleksis/core/views.py:888
 msgid "Run data checks …"
 msgstr "Datenprüfungen laufen …"
 
-#: aleksis/core/views.py:876
+#: aleksis/core/views.py:889
 msgid "The data checks were run successfully."
 msgstr "Die Datenprüfungen wurden erfolgreich ausgeführt."
 
-#: aleksis/core/views.py:877
+#: aleksis/core/views.py:890
 msgid "There was a problem while running data checks."
 msgstr "Es gab ein Problem beim Ausführen der Datenprüfungen."
 
-#: aleksis/core/views.py:893
+#: aleksis/core/views.py:906
 #, 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:935
+#: aleksis/core/views.py:948
 msgid "The dashboard widget has been saved."
 msgstr "Das Dashboard-Widget wurde gespeichert."
 
-#: aleksis/core/views.py:965
+#: aleksis/core/views.py:978
 msgid "The dashboard widget has been created."
 msgstr "Das Dashboard-Widget wurde erstellt."
 
-#: aleksis/core/views.py:975
+#: aleksis/core/views.py:988
 msgid "The dashboard widget has been deleted."
 msgstr "Das Dashboard-Widget wurde gelöscht."
 
-#: aleksis/core/views.py:1042
+#: aleksis/core/views.py:1055
 msgid "Your dashboard configuration has been saved successfully."
 msgstr "Ihre Dashboardkonfiguration wurde erfolgreich gespeichert."
 
-#: aleksis/core/views.py:1044
+#: aleksis/core/views.py:1057
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr "Die Konfiguration des Standard-Dashboardes wurde erfolgreich gespeichert."
 
-#: aleksis/core/views.py:1139
+#: aleksis/core/views.py:1127
+#, python-brace-format
+msgid "The invitation was successfully created. The invitation code is {code}"
+msgstr "Die Einladung wurde erfolgreich erstellt. Der Einladungscode ist {code}"
+
+#: aleksis/core/views.py:1218
 msgid "We have successfully assigned the permissions."
 msgstr "Wir haben die Berechtigungen erfolgreich zugewiesen."
 
-#: aleksis/core/views.py:1149
+#: aleksis/core/views.py:1228
 msgid "The global user permission has been deleted."
 msgstr "Die globale Benutzerberechtigung wurde gelöscht."
 
-#: aleksis/core/views.py:1159
+#: aleksis/core/views.py:1238
 msgid "The global group permission has been deleted."
 msgstr "Die globale Gruppenberechtigung wurde gelöscht."
 
-#: aleksis/core/views.py:1169
+#: aleksis/core/views.py:1248
 msgid "The object user permission has been deleted."
 msgstr "Die Objekt-Benutzerberechtigung wurde gelöscht."
 
-#: aleksis/core/views.py:1179
+#: aleksis/core/views.py:1258
 msgid "The object group permission has been deleted."
 msgstr "Die Objekt-Gruppenberechtigung wurde gelöscht."
 
-#: aleksis/core/views.py:1298
+#: aleksis/core/views.py:1377
 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:1305
+#: aleksis/core/views.py:1384
 msgid "The third-party account has been successfully disconnected."
 msgstr "Das Drittanbieter-Konto wurde erfolgreich getrennt."
 
+#: aleksis/core/views.py:1441
+msgid "Person was invited successfully."
+msgstr "Person wurde erfolgreich eingeladen."
+
+#: aleksis/core/views.py:1443
+msgid "Person was already invited."
+msgstr "Person wurde bereits eingeladen."
+
+#~ msgid "Consents"
+#~ msgstr "Zustimmungen"
+
+#, 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."
+
+#~ msgid "You must type the same password each time."
+#~ msgstr "Sie müssen zweimal das gleiche Passwort eingeben."
+
+#~ msgid "Impersonation"
+#~ msgstr "Verkleidung"
+
+#, 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>"
+
+#~ msgid "Impress"
+#~ msgstr "Impressum"
+
 #~ msgid "The backup folder doesn't exist."
 #~ msgstr "Der Backup-Ordner existiert nicht."
 
@@ -3291,9 +3388,6 @@ msgstr "Das Drittanbieter-Konto wurde erfolgreich getrennt."
 #~ msgid "New account"
 #~ msgstr "Neues Konto"
 
-#~ msgid "Impersonate user"
-#~ msgstr "Als Benutzer verkleiden"
-
 #~ msgid "Authorized tokens"
 #~ msgstr "Autorisierte Tokens"
 
@@ -3558,9 +3652,6 @@ msgstr "Das Drittanbieter-Konto wurde erfolgreich getrennt."
 #~ msgid "Assorted"
 #~ msgstr "Unsortiert"
 
-#~ msgid "Administration"
-#~ msgstr "Verwaltung"
-
 #~ msgid "List of all groups"
 #~ msgstr "Liste aller Gruppen"
 
diff --git a/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po b/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po
index a7ec6ed158f46a4a450beafe334f702991f8b828..188d883c0746a8cb64414091b5e0fa2f8b247805 100644
--- a/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po
+++ b/aleksis/core/locale/de_DE/LC_MESSAGES/djangojs.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:14+0100\n"
 "PO-Revision-Date: 2021-10-28 14:37+0000\n"
 "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
 "Language-Team: German <https://translate.edugit.org/projects/aleksis/aleksis-core-js/de/>\n"
@@ -30,6 +30,6 @@ msgstr "Abbrechen"
 msgid "OK"
 msgstr "OK"
 
-#: aleksis/core/static/js/main.js:127
+#: aleksis/core/static/js/main.js:128
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr "Diese Seite enthält vielleicht veraltete Informationen, da es keine Internetverbindung gibt."
diff --git a/aleksis/core/locale/fr/LC_MESSAGES/django.po b/aleksis/core/locale/fr/LC_MESSAGES/django.po
index ce265871ee7c6fda20ae39d5a2cf7f778a2296a0..48ad0ea73dda60181ae19660fa021259b0f49ab0 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:13+0100\n"
 "PO-Revision-Date: 2021-06-16 12:00+0000\n"
 "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
 "Language-Team: French <https://translate.edugit.org/projects/aleksis/aleksis/fr/>\n"
@@ -40,10 +40,10 @@ msgstr "Détails de contact"
 msgid "Home and mobile phone"
 msgstr ""
 
-#: aleksis/core/apps.py:157 aleksis/core/forms.py:222 aleksis/core/menus.py:267
-#: aleksis/core/models.py:412 aleksis/core/templates/core/group/list.html:8
+#: aleksis/core/apps.py:157 aleksis/core/forms.py:223 aleksis/core/menus.py:265
+#: aleksis/core/models.py:414 aleksis/core/templates/core/group/list.html:8
 #: aleksis/core/templates/core/group/list.html:9
-#: aleksis/core/templates/core/person/full.html:145
+#: aleksis/core/templates/core/person/full.html:152
 #, fuzzy
 #| msgid "Group"
 msgid "Groups"
@@ -97,62 +97,62 @@ msgstr ""
 msgid "Content type"
 msgstr ""
 
-#: aleksis/core/filters.py:112 aleksis/core/models.py:579
+#: aleksis/core/filters.py:112 aleksis/core/models.py:581
 msgid "User"
 msgstr ""
 
-#: aleksis/core/filters.py:134 aleksis/core/models.py:411
+#: aleksis/core/filters.py:134 aleksis/core/models.py:413
 msgid "Group"
 msgstr "groupe"
 
-#: aleksis/core/forms.py:47 aleksis/core/forms.py:521
+#: aleksis/core/forms.py:48 aleksis/core/forms.py:559
 msgid "Base data"
 msgstr ""
 
-#: aleksis/core/forms.py:53
+#: aleksis/core/forms.py:54
 msgid "Address"
 msgstr ""
 
-#: aleksis/core/forms.py:54
+#: aleksis/core/forms.py:55 aleksis/core/forms.py:568
 #, fuzzy
 #| msgid "Contact details"
 msgid "Contact data"
 msgstr "Détails de contact"
 
-#: aleksis/core/forms.py:56
+#: aleksis/core/forms.py:57
 #, fuzzy
 #| msgid "Contact details"
 msgid "Advanced personal data"
 msgstr "Détails de contact"
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "New user"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "Create a new account"
 msgstr ""
 
-#: aleksis/core/forms.py:135
+#: aleksis/core/forms.py:136
 msgid "You cannot set a new username when also selecting an existing user."
 msgstr ""
 
-#: aleksis/core/forms.py:139
+#: aleksis/core/forms.py:140
 msgid "This username is already in use."
 msgstr "Cet nom est deja en utilisation."
 
-#: aleksis/core/forms.py:156 aleksis/core/models.py:125
+#: aleksis/core/forms.py:157 aleksis/core/models.py:129
 msgid "School term"
 msgstr ""
 
-#: aleksis/core/forms.py:157
+#: aleksis/core/forms.py:158
 #, fuzzy
 #| msgid "Contact details"
 msgid "Common data"
 msgstr "Détails de contact"
 
-#: aleksis/core/forms.py:158 aleksis/core/forms.py:209
-#: aleksis/core/menus.py:256 aleksis/core/models.py:148
+#: aleksis/core/forms.py:159 aleksis/core/forms.py:210
+#: aleksis/core/menus.py:254 aleksis/core/models.py:152
 #: aleksis/core/templates/core/person/list.html:8
 #: aleksis/core/templates/core/person/list.html:9
 #, fuzzy
@@ -160,98 +160,97 @@ msgstr "Détails de contact"
 msgid "Persons"
 msgstr "Personne"
 
-#: aleksis/core/forms.py:159
+#: aleksis/core/forms.py:160 aleksis/core/forms.py:570
 #, fuzzy
 #| msgid "Contact details"
 msgid "Additional data"
 msgstr "Détails de contact"
 
-#: aleksis/core/forms.py:201 aleksis/core/forms.py:204
-#: aleksis/core/models.py:68
+#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
+#: aleksis/core/models.py:72
 msgid "Date"
 msgstr "Date"
 
-#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
-#: aleksis/core/models.py:76
+#: aleksis/core/forms.py:203 aleksis/core/forms.py:206
+#: aleksis/core/models.py:80
 msgid "Time"
 msgstr ""
 
-#: aleksis/core/forms.py:235
+#: aleksis/core/forms.py:236
 msgid "From when until when should the announcement be displayed?"
 msgstr ""
 
-#: aleksis/core/forms.py:238
+#: aleksis/core/forms.py:239
 msgid "Who should see the announcement?"
 msgstr ""
 
-#: aleksis/core/forms.py:239
+#: aleksis/core/forms.py:240
 msgid "Write your announcement:"
 msgstr ""
 
-#: aleksis/core/forms.py:278
+#: aleksis/core/forms.py:279
 msgid "You are not allowed to create announcements which are only valid in the past."
 msgstr ""
 
-#: aleksis/core/forms.py:282
+#: aleksis/core/forms.py:283
 msgid "The from date and time must be earlier then the until date and time."
 msgstr ""
 
-#: aleksis/core/forms.py:291
+#: aleksis/core/forms.py:292
 msgid "You need at least one recipient."
 msgstr ""
 
-#: aleksis/core/forms.py:412
+#: aleksis/core/forms.py:401
+msgid "Invitation code"
+msgstr ""
+
+#: aleksis/core/forms.py:402
+msgid "Please enter your invitation code."
+msgstr ""
+
+#: aleksis/core/forms.py:434
 msgid "Who should get the permission?"
 msgstr ""
 
-#: aleksis/core/forms.py:413
+#: aleksis/core/forms.py:435
 msgid "On what?"
 msgstr ""
 
-#: aleksis/core/forms.py:439
+#: aleksis/core/forms.py:461
 msgid "Select objects which the permission should be granted for:"
 msgstr ""
 
-#: aleksis/core/forms.py:442
+#: aleksis/core/forms.py:464
 msgid "Grant the permission for all objects"
 msgstr ""
 
-#: aleksis/core/forms.py:450
+#: aleksis/core/forms.py:472
 msgid "You must select at least one group or person which should get the permission."
 msgstr ""
 
-#: aleksis/core/forms.py:455
+#: aleksis/core/forms.py:477
 msgid "You must grant the permission to all objects and/or to some objects."
 msgstr ""
 
-#: aleksis/core/forms.py:525
+#: aleksis/core/forms.py:564
+msgid "Adress data"
+msgstr ""
+
+#: aleksis/core/forms.py:576
 #, fuzzy
 #| msgid "Contact details"
 msgid "Account data"
 msgstr "Détails de contact"
 
-#: aleksis/core/forms.py:531
-msgid "Consents"
-msgstr ""
-
-#: aleksis/core/forms.py:538
+#: aleksis/core/forms.py:583
 msgid "Password"
 msgstr ""
 
-#: aleksis/core/forms.py:544
+#: aleksis/core/forms.py:586
 msgid "Password (again)"
 msgstr ""
 
-#: aleksis/core/forms.py:557
-#, python-brace-format
-msgid "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree with them."
-msgstr ""
-
-#: aleksis/core/forms.py:582
-msgid "You must type the same password each time."
-msgstr ""
-
-#: aleksis/core/forms.py:727
+#: aleksis/core/forms.py:752
 msgid "No valid selection."
 msgstr ""
 
@@ -288,34 +287,38 @@ msgstr ""
 msgid "Sign up"
 msgstr ""
 
-#: aleksis/core/menus.py:24
+#: aleksis/core/menus.py:24 aleksis/core/templates/invitations/enter.html:7
+msgid "Accept invitation"
+msgstr ""
+
+#: aleksis/core/menus.py:33
 msgid "Dashboard"
 msgstr ""
 
-#: aleksis/core/menus.py:32 aleksis/core/models.py:625
-#: aleksis/core/preferences.py:27
+#: aleksis/core/menus.py:41 aleksis/core/models.py:627
+#: aleksis/core/preferences.py:28
 #: aleksis/core/templates/core/notifications.html:4
 #: aleksis/core/templates/core/notifications.html:5
 msgid "Notifications"
 msgstr ""
 
-#: aleksis/core/menus.py:44
+#: aleksis/core/menus.py:53
 msgid "Account"
 msgstr ""
 
-#: aleksis/core/menus.py:51
+#: aleksis/core/menus.py:60
 msgid "Stop impersonation"
 msgstr ""
 
-#: aleksis/core/menus.py:60 aleksis/core/templates/core/base.html:80
+#: aleksis/core/menus.py:69 aleksis/core/templates/core/base.html:80
 msgid "Logout"
 msgstr ""
 
-#: aleksis/core/menus.py:66
+#: aleksis/core/menus.py:75
 msgid "2FA"
 msgstr ""
 
-#: aleksis/core/menus.py:74
+#: aleksis/core/menus.py:83
 #: aleksis/core/templates/account/password_change.html:5
 #: aleksis/core/templates/account/password_change.html:6
 #: aleksis/core/templates/account/password_change.html:19
@@ -327,92 +330,88 @@ msgstr ""
 msgid "Change password"
 msgstr ""
 
-#: aleksis/core/menus.py:86
+#: aleksis/core/menus.py:95
 msgid "Me"
 msgstr ""
 
-#: aleksis/core/menus.py:95
+#: aleksis/core/menus.py:104
 #: aleksis/core/templates/dynamic_preferences/form.html:5
 msgid "Preferences"
 msgstr ""
 
-#: aleksis/core/menus.py:104
+#: aleksis/core/menus.py:113
 msgid "Third-party accounts"
 msgstr ""
 
-#: aleksis/core/menus.py:113
+#: aleksis/core/menus.py:122
 #: 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:124
+#: aleksis/core/menus.py:133
 msgid "Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:132 aleksis/core/models.py:725
+#: aleksis/core/menus.py:141 aleksis/core/models.py:727
 #: aleksis/core/templates/core/announcement/list.html:7
 #: aleksis/core/templates/core/announcement/list.html:8
 msgid "Announcements"
 msgstr ""
 
-#: aleksis/core/menus.py:143 aleksis/core/models.py:126
+#: aleksis/core/menus.py:152 aleksis/core/models.py:130
 #: aleksis/core/templates/core/school_term/list.html:8
 #: aleksis/core/templates/core/school_term/list.html:9
 msgid "School terms"
 msgstr ""
 
-#: aleksis/core/menus.py:154
+#: aleksis/core/menus.py:163
 #: aleksis/core/templates/core/dashboard_widget/list.html:8
 #: aleksis/core/templates/core/dashboard_widget/list.html:9
 msgid "Dashboard widgets"
 msgstr ""
 
-#: aleksis/core/menus.py:165
+#: aleksis/core/menus.py:174
 #: aleksis/core/templates/core/management/data_management.html:6
 #: aleksis/core/templates/core/management/data_management.html:7
 msgid "Data management"
 msgstr ""
 
-#: aleksis/core/menus.py:176
+#: aleksis/core/menus.py:185
 #: aleksis/core/templates/core/pages/system_status.html:5
 #: aleksis/core/templates/core/pages/system_status.html:7
 msgid "System status"
 msgstr ""
 
-#: aleksis/core/menus.py:187
-msgid "Impersonation"
-msgstr ""
-
-#: aleksis/core/menus.py:198
+#: aleksis/core/menus.py:196
 msgid "Configuration"
 msgstr ""
 
-#: aleksis/core/menus.py:209 aleksis/core/templates/core/data_check/list.html:9
+#: aleksis/core/menus.py:207 aleksis/core/templates/core/data_check/list.html:9
 #: aleksis/core/templates/core/data_check/list.html:10
 msgid "Data checks"
 msgstr ""
 
-#: aleksis/core/menus.py:215 aleksis/core/templates/core/perms/list.html:13
+#: aleksis/core/menus.py:213 aleksis/core/templates/core/perms/list.html:13
 #: aleksis/core/templates/core/perms/list.html:14
 msgid "Manage permissions"
 msgstr ""
 
-#: aleksis/core/menus.py:226
+#: aleksis/core/menus.py:224
 msgid "Backend Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:234
+#: aleksis/core/menus.py:232
 #: aleksis/core/templates/oauth2_provider/application/list.html:5
 #: aleksis/core/templates/oauth2_provider/application/list.html:6
 msgid "OAuth2 Applications"
 msgstr ""
 
-#: aleksis/core/menus.py:247
+#: aleksis/core/menus.py:245
 msgid "People"
 msgstr ""
 
-#: aleksis/core/menus.py:278 aleksis/core/models.py:979
+#: aleksis/core/menus.py:276 aleksis/core/models.py:981
 #: aleksis/core/templates/core/group_type/list.html:8
 #: aleksis/core/templates/core/group_type/list.html:9
 #, fuzzy
@@ -420,775 +419,805 @@ msgstr ""
 msgid "Group types"
 msgstr "Groupe"
 
-#: aleksis/core/menus.py:289
+#: aleksis/core/menus.py:287
 msgid "Groups and child groups"
 msgstr ""
 
-#: aleksis/core/menus.py:300 aleksis/core/models.py:460
+#: aleksis/core/menus.py:298 aleksis/core/models.py:462
 #: aleksis/core/templates/core/additional_field/list.html:8
 #: aleksis/core/templates/core/additional_field/list.html:9
 msgid "Additional fields"
 msgstr ""
 
-#: aleksis/core/menus.py:315
+#: aleksis/core/menus.py:309
+#, fuzzy
+#| msgid "Contact details"
+msgid "Invite person"
+msgstr "Détails de contact"
+
+#: aleksis/core/menus.py:322
 #: aleksis/core/templates/core/group/child_groups.html:7
 #: aleksis/core/templates/core/group/child_groups.html:9
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:508
+#: aleksis/core/mixins.py:511
 msgid "Linked school term"
 msgstr ""
 
-#: aleksis/core/models.py:66
+#: aleksis/core/models.py:70
 msgid "Boolean (Yes/No)"
 msgstr ""
 
-#: aleksis/core/models.py:67
+#: aleksis/core/models.py:71
 msgid "Text (one line)"
 msgstr ""
 
-#: aleksis/core/models.py:69
+#: aleksis/core/models.py:73
 msgid "Date and time"
 msgstr ""
 
-#: aleksis/core/models.py:70
+#: aleksis/core/models.py:74
 msgid "Decimal number"
 msgstr ""
 
-#: aleksis/core/models.py:71 aleksis/core/models.py:194
+#: aleksis/core/models.py:75 aleksis/core/models.py:198
 msgid "E-mail address"
 msgstr ""
 
-#: aleksis/core/models.py:72
+#: aleksis/core/models.py:76
 msgid "Integer"
 msgstr ""
 
-#: aleksis/core/models.py:73
+#: aleksis/core/models.py:77
 msgid "IP address"
 msgstr ""
 
-#: aleksis/core/models.py:74
+#: aleksis/core/models.py:78
 msgid "Boolean or empty (Yes/No/Neither)"
 msgstr ""
 
-#: aleksis/core/models.py:75
+#: aleksis/core/models.py:79
 msgid "Text (multi-line)"
 msgstr ""
 
-#: aleksis/core/models.py:77
+#: aleksis/core/models.py:81
 msgid "URL / Link"
 msgstr ""
 
-#: aleksis/core/models.py:89 aleksis/core/models.py:948
+#: aleksis/core/models.py:93 aleksis/core/models.py:950
 msgid "Name"
 msgstr ""
 
-#: aleksis/core/models.py:91
+#: aleksis/core/models.py:95
 #, fuzzy
 #| msgid "Contact details"
 msgid "Start date"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:92
+#: aleksis/core/models.py:96
 msgid "End date"
 msgstr ""
 
-#: aleksis/core/models.py:111
+#: aleksis/core/models.py:115
 msgid "The start date must be earlier than the end date."
 msgstr ""
 
-#: aleksis/core/models.py:118
+#: aleksis/core/models.py:122
 msgid "There is already a school term for this time or a part of this time."
 msgstr ""
 
-#: aleksis/core/models.py:147 aleksis/core/models.py:897
+#: aleksis/core/models.py:151 aleksis/core/models.py:899
 msgid "Person"
 msgstr "Personne"
 
-#: aleksis/core/models.py:150
+#: aleksis/core/models.py:154
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can view address"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:151
+#: aleksis/core/models.py:155
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can view contact details"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:152
+#: aleksis/core/models.py:156
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can view photo"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:153
+#: aleksis/core/models.py:157
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can view persons groups"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:154
+#: aleksis/core/models.py:158
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can view personal details"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "female"
 msgstr ""
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "male"
 msgstr ""
 
-#: aleksis/core/models.py:172
+#: aleksis/core/models.py:176 aleksis/core/models.py:1144
 msgid "Linked user"
 msgstr ""
 
-#: aleksis/core/models.py:174
+#: aleksis/core/models.py:178
 msgid "Is person active?"
 msgstr ""
 
-#: aleksis/core/models.py:176
+#: aleksis/core/models.py:180
 msgid "First name"
 msgstr "Prénom"
 
-#: aleksis/core/models.py:177
+#: aleksis/core/models.py:181
 msgid "Last name"
 msgstr "Nom de famille"
 
-#: aleksis/core/models.py:179
+#: aleksis/core/models.py:183
 msgid "Additional name(s)"
 msgstr ""
 
-#: aleksis/core/models.py:183 aleksis/core/models.py:429
+#: aleksis/core/models.py:187 aleksis/core/models.py:431
 #, fuzzy
 #| msgid "First name"
 msgid "Short name"
 msgstr "Prénom"
 
-#: aleksis/core/models.py:186
+#: aleksis/core/models.py:190
 msgid "Street"
 msgstr ""
 
-#: aleksis/core/models.py:187
+#: aleksis/core/models.py:191
 msgid "Street number"
 msgstr ""
 
-#: aleksis/core/models.py:188
+#: aleksis/core/models.py:192
 msgid "Postal code"
 msgstr ""
 
-#: aleksis/core/models.py:189
+#: aleksis/core/models.py:193
 msgid "Place"
 msgstr ""
 
-#: aleksis/core/models.py:191
+#: aleksis/core/models.py:195
 msgid "Home phone"
 msgstr ""
 
-#: aleksis/core/models.py:192
+#: aleksis/core/models.py:196
 msgid "Mobile phone"
 msgstr ""
 
-#: aleksis/core/models.py:196
+#: aleksis/core/models.py:200
 msgid "Date of birth"
 msgstr "Date d'anniversaire"
 
-#: aleksis/core/models.py:198
+#: aleksis/core/models.py:201
 #, fuzzy
 #| msgid "Date of birth"
 msgid "Place of birth"
 msgstr "Date d'anniversaire"
 
-#: aleksis/core/models.py:200
+#: aleksis/core/models.py:202
 msgid "Sex"
 msgstr "Sexe"
 
-#: aleksis/core/models.py:202
+#: aleksis/core/models.py:204
 msgid "Photo"
 msgstr ""
 
-#: aleksis/core/models.py:206 aleksis/core/templates/core/person/full.html:138
+#: aleksis/core/models.py:208 aleksis/core/templates/core/person/full.html:145
 msgid "Guardians / Parents"
 msgstr ""
 
-#: aleksis/core/models.py:213
+#: aleksis/core/models.py:215
 msgid "Primary group"
 msgstr ""
 
-#: aleksis/core/models.py:216 aleksis/core/models.py:583
-#: aleksis/core/models.py:607 aleksis/core/models.py:692
-#: aleksis/core/models.py:972 aleksis/core/templates/core/person/full.html:121
+#: aleksis/core/models.py:218 aleksis/core/models.py:585
+#: aleksis/core/models.py:609 aleksis/core/models.py:694
+#: aleksis/core/models.py:974 aleksis/core/templates/core/person/full.html:128
 msgid "Description"
 msgstr "Description"
 
-#: aleksis/core/models.py:384
+#: aleksis/core/models.py:386
 msgid "Title of field"
 msgstr ""
 
-#: aleksis/core/models.py:386
+#: aleksis/core/models.py:388
 msgid "Type of field"
 msgstr ""
 
-#: aleksis/core/models.py:393
+#: aleksis/core/models.py:395
 msgid "Addtitional field for groups"
 msgstr ""
 
-#: aleksis/core/models.py:394
+#: aleksis/core/models.py:396
 msgid "Addtitional fields for groups"
 msgstr ""
 
-#: aleksis/core/models.py:414
+#: aleksis/core/models.py:416
 msgid "Can assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/models.py:415
+#: aleksis/core/models.py:417
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can view statistics about group."
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:427
+#: aleksis/core/models.py:429
 #, fuzzy
 #| msgid "Last name"
 msgid "Long name"
 msgstr "Nom de famille"
 
-#: aleksis/core/models.py:437 aleksis/core/templates/core/group/full.html:85
+#: aleksis/core/models.py:439 aleksis/core/templates/core/group/full.html:85
 msgid "Members"
 msgstr ""
 
-#: aleksis/core/models.py:440 aleksis/core/templates/core/group/full.html:82
+#: aleksis/core/models.py:442 aleksis/core/templates/core/group/full.html:82
 msgid "Owners"
 msgstr "Propriétaires"
 
-#: aleksis/core/models.py:447 aleksis/core/templates/core/group/full.html:55
+#: aleksis/core/models.py:449 aleksis/core/templates/core/group/full.html:55
 msgid "Parent groups"
 msgstr ""
 
-#: aleksis/core/models.py:455
+#: aleksis/core/models.py:457
 msgid "Type of group"
 msgstr ""
 
-#: aleksis/core/models.py:582 aleksis/core/models.py:606
-#: aleksis/core/models.py:691
+#: aleksis/core/models.py:584 aleksis/core/models.py:608
+#: aleksis/core/models.py:693
 #: aleksis/core/templates/core/announcement/list.html:18
 msgid "Title"
 msgstr ""
 
-#: aleksis/core/models.py:585
+#: aleksis/core/models.py:587
 msgid "Application"
 msgstr ""
 
-#: aleksis/core/models.py:591
+#: aleksis/core/models.py:593
 msgid "Activity"
 msgstr ""
 
-#: aleksis/core/models.py:592
+#: aleksis/core/models.py:594
 msgid "Activities"
 msgstr ""
 
-#: aleksis/core/models.py:598
+#: aleksis/core/models.py:600
 msgid "Sender"
 msgstr ""
 
-#: aleksis/core/models.py:603
+#: aleksis/core/models.py:605
 msgid "Recipient"
 msgstr ""
 
-#: aleksis/core/models.py:608 aleksis/core/models.py:949
+#: aleksis/core/models.py:610 aleksis/core/models.py:951
 msgid "Link"
 msgstr ""
 
-#: aleksis/core/models.py:610
+#: aleksis/core/models.py:612
 msgid "Read"
 msgstr ""
 
-#: aleksis/core/models.py:611
+#: aleksis/core/models.py:613
 msgid "Sent"
 msgstr ""
 
-#: aleksis/core/models.py:624
+#: aleksis/core/models.py:626
 msgid "Notification"
 msgstr ""
 
-#: aleksis/core/models.py:693
+#: aleksis/core/models.py:695
 msgid "Link to detailed view"
 msgstr ""
 
-#: aleksis/core/models.py:696
+#: aleksis/core/models.py:698
 msgid "Date and time from when to show"
 msgstr ""
 
-#: aleksis/core/models.py:699
+#: aleksis/core/models.py:701
 msgid "Date and time until when to show"
 msgstr ""
 
-#: aleksis/core/models.py:724
+#: aleksis/core/models.py:726
 msgid "Announcement"
 msgstr ""
 
-#: aleksis/core/models.py:762
+#: aleksis/core/models.py:764
 msgid "Announcement recipient"
 msgstr ""
 
-#: aleksis/core/models.py:763
+#: aleksis/core/models.py:765
 msgid "Announcement recipients"
 msgstr ""
 
-#: aleksis/core/models.py:818
+#: aleksis/core/models.py:820
 msgid "Widget Title"
 msgstr ""
 
-#: aleksis/core/models.py:819
+#: aleksis/core/models.py:821
 msgid "Activate Widget"
 msgstr ""
 
-#: aleksis/core/models.py:820
+#: aleksis/core/models.py:822
 msgid "Widget is broken"
 msgstr ""
 
-#: aleksis/core/models.py:823
+#: aleksis/core/models.py:825
 msgid "Size on mobile devices"
 msgstr ""
 
-#: aleksis/core/models.py:824
+#: aleksis/core/models.py:826
 msgid "<= 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:829
+#: aleksis/core/models.py:831
 msgid "Size on tablet devices"
 msgstr ""
 
-#: aleksis/core/models.py:830
+#: aleksis/core/models.py:832
 msgid "> 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:835
+#: aleksis/core/models.py:837
 msgid "Size on desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:836
+#: aleksis/core/models.py:838
 msgid "> 992 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:841
+#: aleksis/core/models.py:843
 msgid "Size on large desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:842
+#: aleksis/core/models.py:844
 msgid "> 1200 px>, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:873
+#: aleksis/core/models.py:875
 msgid "Can edit default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:874
+#: aleksis/core/models.py:876
 msgid "Dashboard Widget"
 msgstr ""
 
-#: aleksis/core/models.py:875
+#: aleksis/core/models.py:877
 msgid "Dashboard Widgets"
 msgstr ""
 
-#: aleksis/core/models.py:881
+#: aleksis/core/models.py:883
 msgid "URL"
 msgstr ""
 
-#: aleksis/core/models.py:882
+#: aleksis/core/models.py:884
 msgid "Icon URL"
 msgstr ""
 
-#: aleksis/core/models.py:888
+#: aleksis/core/models.py:890
 msgid "External link widget"
 msgstr ""
 
-#: aleksis/core/models.py:889
+#: aleksis/core/models.py:891
 msgid "External link widgets"
 msgstr ""
 
-#: aleksis/core/models.py:894
+#: aleksis/core/models.py:896
 msgid "Dashboard widget"
 msgstr ""
 
-#: aleksis/core/models.py:899
+#: aleksis/core/models.py:901
 msgid "Order"
 msgstr ""
 
-#: aleksis/core/models.py:900
+#: aleksis/core/models.py:902
 msgid "Part of the default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:915
+#: aleksis/core/models.py:917
 msgid "Dashboard widget order"
 msgstr ""
 
-#: aleksis/core/models.py:916
+#: aleksis/core/models.py:918
 msgid "Dashboard widget orders"
 msgstr ""
 
-#: aleksis/core/models.py:922
+#: aleksis/core/models.py:924
 msgid "Menu ID"
 msgstr ""
 
-#: aleksis/core/models.py:935
+#: aleksis/core/models.py:937
 msgid "Custom menu"
 msgstr ""
 
-#: aleksis/core/models.py:936
+#: aleksis/core/models.py:938
 msgid "Custom menus"
 msgstr ""
 
-#: aleksis/core/models.py:946
+#: aleksis/core/models.py:948
 msgid "Menu"
 msgstr ""
 
-#: aleksis/core/models.py:950
+#: aleksis/core/models.py:952
 msgid "Icon"
 msgstr ""
 
-#: aleksis/core/models.py:956
+#: aleksis/core/models.py:958
 msgid "Custom menu item"
 msgstr ""
 
-#: aleksis/core/models.py:957
+#: aleksis/core/models.py:959
 msgid "Custom menu items"
 msgstr ""
 
-#: aleksis/core/models.py:971
+#: aleksis/core/models.py:973
 msgid "Title of type"
 msgstr ""
 
-#: aleksis/core/models.py:978 aleksis/core/templates/core/group/full.html:47
+#: aleksis/core/models.py:980 aleksis/core/templates/core/group/full.html:47
 #, fuzzy
 #| msgid "Group"
 msgid "Group type"
 msgstr "Groupe"
 
-#: aleksis/core/models.py:992
+#: aleksis/core/models.py:994
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can view system status"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:993
+#: aleksis/core/models.py:995
 msgid "Can manage data"
 msgstr ""
 
-#: aleksis/core/models.py:994
+#: aleksis/core/models.py:996
 #, fuzzy
 #| msgid "Contact details"
 msgid "Can impersonate"
 msgstr "Détails de contact"
 
-#: aleksis/core/models.py:995
+#: aleksis/core/models.py:997
 msgid "Can use search"
 msgstr ""
 
-#: aleksis/core/models.py:996
+#: aleksis/core/models.py:998
 msgid "Can change site preferences"
 msgstr ""
 
-#: aleksis/core/models.py:997
+#: aleksis/core/models.py:999
 msgid "Can change person preferences"
 msgstr ""
 
-#: aleksis/core/models.py:998
+#: aleksis/core/models.py:1000
 msgid "Can change group preferences"
 msgstr ""
 
-#: aleksis/core/models.py:999
+#: aleksis/core/models.py:1001
 msgid "Can test PDF generation"
 msgstr ""
 
-#: aleksis/core/models.py:1035
+#: aleksis/core/models.py:1037
 msgid "Related data check task"
 msgstr ""
 
-#: aleksis/core/models.py:1043
+#: aleksis/core/models.py:1045
 msgid "Issue solved"
 msgstr ""
 
-#: aleksis/core/models.py:1044
+#: aleksis/core/models.py:1046
 msgid "Notification sent"
 msgstr ""
 
-#: aleksis/core/models.py:1057
+#: aleksis/core/models.py:1059
 msgid "Data check result"
 msgstr ""
 
-#: aleksis/core/models.py:1058
+#: aleksis/core/models.py:1060
 msgid "Data check results"
 msgstr ""
 
-#: aleksis/core/models.py:1060
+#: aleksis/core/models.py:1062
 msgid "Can run data checks"
 msgstr ""
 
-#: aleksis/core/models.py:1061
+#: aleksis/core/models.py:1063
 msgid "Can solve data check problems"
 msgstr ""
 
-#: aleksis/core/models.py:1076
+#: aleksis/core/models.py:1070
+#, fuzzy
+#| msgid "Contact details"
+msgid "E-Mail address"
+msgstr "Détails de contact"
+
+#: aleksis/core/models.py:1094
 #, fuzzy
 #| msgid "Owners"
 msgid "Owner"
 msgstr "Propriétaires"
 
-#: aleksis/core/models.py:1080
+#: aleksis/core/models.py:1098
 msgid "File expires at"
 msgstr ""
 
-#: aleksis/core/models.py:1082
+#: aleksis/core/models.py:1100
 msgid "Generated HTML file"
 msgstr ""
 
-#: aleksis/core/models.py:1084
+#: aleksis/core/models.py:1102
 msgid "Generated PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1091
+#: aleksis/core/models.py:1109
 msgid "PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1092
+#: aleksis/core/models.py:1110
 msgid "PDF files"
 msgstr ""
 
-#: aleksis/core/models.py:1097
+#: aleksis/core/models.py:1115
 msgid "Task result"
 msgstr ""
 
-#: aleksis/core/models.py:1100
+#: aleksis/core/models.py:1118
 msgid "Task user"
 msgstr ""
 
-#: aleksis/core/models.py:1112
+#: aleksis/core/models.py:1130
 msgid "Task user assignment"
 msgstr ""
 
-#: aleksis/core/models.py:1113
+#: aleksis/core/models.py:1131
 msgid "Task user assignments"
 msgstr ""
 
-#: aleksis/core/models.py:1127
+#: aleksis/core/models.py:1147
+#, fuzzy
+#| msgid "Contact details"
+msgid "Additional attributes"
+msgstr "Détails de contact"
+
+#: aleksis/core/models.py:1185
 msgid "Allowed scopes that clients can request"
 msgstr ""
 
-#: aleksis/core/preferences.py:23
+#: aleksis/core/preferences.py:24
 msgid "General"
 msgstr ""
 
-#: aleksis/core/preferences.py:24
+#: aleksis/core/preferences.py:25
 msgid "School"
 msgstr ""
 
-#: aleksis/core/preferences.py:25
+#: aleksis/core/preferences.py:26
 msgid "Theme"
 msgstr ""
 
-#: aleksis/core/preferences.py:26
+#: aleksis/core/preferences.py:27
 msgid "Mail"
 msgstr ""
 
-#: aleksis/core/preferences.py:28
+#: aleksis/core/preferences.py:29
 msgid "Footer"
 msgstr ""
 
-#: aleksis/core/preferences.py:29
+#: aleksis/core/preferences.py:30
 #, fuzzy
 #| msgid "Contact details"
 msgid "Accounts"
 msgstr "Détails de contact"
 
-#: aleksis/core/preferences.py:30
+#: aleksis/core/preferences.py:31
 msgid "Authentication"
 msgstr ""
 
-#: aleksis/core/preferences.py:31
+#: aleksis/core/preferences.py:32
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:42
+#: aleksis/core/preferences.py:43
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:53
+#: aleksis/core/preferences.py:54
 #, fuzzy
 #| msgid "Description"
 msgid "Site description"
 msgstr "Description"
 
-#: aleksis/core/preferences.py:64
+#: aleksis/core/preferences.py:65
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:77
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:87
+#: aleksis/core/preferences.py:88
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:97
+#: aleksis/core/preferences.py:98
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:107
+#: aleksis/core/preferences.py:108
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:118
+#: aleksis/core/preferences.py:119
 #, fuzzy
 #| msgid "Last name"
 msgid "Mail out name"
 msgstr "Nom de famille"
 
-#: aleksis/core/preferences.py:129
+#: aleksis/core/preferences.py:130
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:141
+#: aleksis/core/preferences.py:142
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:153
+#: aleksis/core/preferences.py:154
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:165
+#: aleksis/core/preferences.py:166
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:181
+#: aleksis/core/preferences.py:182
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:193
+#: aleksis/core/preferences.py:194
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:204
+#: aleksis/core/preferences.py:205
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:216
+#: aleksis/core/preferences.py:217
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:225
+#: aleksis/core/preferences.py:226
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:236
+#: aleksis/core/preferences.py:237
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:247
+#: aleksis/core/preferences.py:248
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:255
+#: aleksis/core/preferences.py:256
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:263
+#: aleksis/core/preferences.py:264
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:274
+#: aleksis/core/preferences.py:272
+msgid "Enable invitations"
+msgstr ""
+
+#: aleksis/core/preferences.py:280
+msgid "Length of invite code. (Default 3: abcde-acbde-abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:288
+msgid "Size of packets. (Default 5: abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:298
 #, fuzzy
 #| msgid "Contact details"
 msgid "Allowed Grant Flows for OAuth applications"
 msgstr "Détails de contact"
 
-#: aleksis/core/preferences.py:287
+#: aleksis/core/preferences.py:311
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:299
+#: aleksis/core/preferences.py:323
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:310
+#: aleksis/core/preferences.py:334
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:321
+#: aleksis/core/preferences.py:345
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:330
+#: aleksis/core/preferences.py:354
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:339
+#: aleksis/core/preferences.py:363
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:350
+#: aleksis/core/preferences.py:374
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:364
+#: aleksis/core/preferences.py:388
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:377
+#: aleksis/core/preferences.py:401
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:387
+#: aleksis/core/preferences.py:411
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:388
+#: aleksis/core/preferences.py:412
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/preferences.py:398
+#: aleksis/core/preferences.py:422
 msgid "Automatically update the dashboard and its widgets"
 msgstr ""
 
-#: aleksis/core/preferences.py:408
+#: aleksis/core/preferences.py:432
 msgid "Automatically update the dashboard and its widgets sitewide"
 msgstr ""
 
-#: aleksis/core/settings.py:482
+#: aleksis/core/settings.py:507
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:483
+#: aleksis/core/settings.py:508
 msgid "German"
 msgstr ""
 
-#: aleksis/core/tables.py:19
+#: aleksis/core/tables.py:24
 #: aleksis/core/templates/core/announcement/list.html:36
 #: aleksis/core/templates/core/group/full.html:24
-#: aleksis/core/templates/core/person/full.html:23
+#: aleksis/core/templates/core/person/full.html:24
 #: aleksis/core/templates/oauth2_provider/application/detail.html:17
 msgid "Edit"
 msgstr ""
 
-#: aleksis/core/tables.py:21 aleksis/core/tables.py:89
-#: aleksis/core/tables.py:105
+#: aleksis/core/tables.py:26 aleksis/core/tables.py:94
+#: aleksis/core/tables.py:137
 #: aleksis/core/templates/core/announcement/list.html:22
 msgid "Actions"
 msgstr ""
 
-#: aleksis/core/tables.py:56 aleksis/core/tables.py:57
-#: aleksis/core/tables.py:71 aleksis/core/tables.py:87
-#: aleksis/core/tables.py:103
+#: aleksis/core/tables.py:61 aleksis/core/tables.py:62
+#: aleksis/core/tables.py:76 aleksis/core/tables.py:92
+#: aleksis/core/tables.py:135
 #: aleksis/core/templates/core/announcement/list.html:42
 #: aleksis/core/templates/core/group/full.html:31
 #: aleksis/core/templates/core/pages/delete.html:22
-#: aleksis/core/templates/core/person/full.html:30
+#: aleksis/core/templates/core/person/full.html:31
 #: aleksis/core/templates/oauth2_provider/application/detail.html:21
 msgid "Delete"
 msgstr ""
@@ -1260,11 +1289,11 @@ msgstr ""
 msgid "Account inactive"
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:13
+#: aleksis/core/templates/account/account_inactive.html:14
 msgid "Account inactive."
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:15
+#: aleksis/core/templates/account/account_inactive.html:17
 msgid ""
 "\n"
 "            This account is currently inactive. If you think this is an\n"
@@ -1416,11 +1445,11 @@ msgstr ""
 msgid "Signup closed"
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:13
+#: aleksis/core/templates/account/signup_closed.html:14
 msgid "Signup closed."
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:15
+#: aleksis/core/templates/account/signup_closed.html:17
 msgid ""
 "\n"
 "            This sign up is currently closed. If you think this is an\n"
@@ -1458,11 +1487,6 @@ msgid ""
 "          "
 msgstr ""
 
-#: 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 ""
-
 #: aleksis/core/templates/core/additional_field/edit.html:6
 #: aleksis/core/templates/core/additional_field/edit.html:7
 msgid "Edit additional field"
@@ -1515,7 +1539,7 @@ msgid "About AlekSIS® — The Free School Information System"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:183
-msgid "Impress"
+msgid "Imprint"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:191
@@ -1744,7 +1768,7 @@ msgid "Edit group"
 msgstr ""
 
 #: aleksis/core/templates/core/group/full.html:38
-#: aleksis/core/templates/core/person/full.html:37
+#: aleksis/core/templates/core/person/full.html:38
 msgid "Change preferences"
 msgstr ""
 
@@ -2148,19 +2172,21 @@ msgstr "Détails de contact"
 msgid "Edit person"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:44
-#: aleksis/core/templates/impersonate/list_users.html:7
-#: aleksis/core/templates/impersonate/list_users.html:8
+#: aleksis/core/templates/core/person/full.html:45
 #, fuzzy
 #| msgid "Contact details"
 msgid "Impersonate"
 msgstr "Détails de contact"
 
-#: aleksis/core/templates/core/person/full.html:50
+#: aleksis/core/templates/core/person/full.html:51
+msgid "Invite user"
+msgstr ""
+
+#: aleksis/core/templates/core/person/full.html:57
 msgid "Contact details"
 msgstr "Détails de contact"
 
-#: aleksis/core/templates/core/person/full.html:131
+#: aleksis/core/templates/core/person/full.html:138
 msgid "Children"
 msgstr ""
 
@@ -2200,6 +2226,51 @@ msgstr ""
 msgid "Save preferences"
 msgstr ""
 
+#: aleksis/core/templates/invitations/enter.html:21
+msgid "Accept your invitation"
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:25
+msgid ""
+"\n"
+"                Please enter your invitation code to register\n"
+"                your new user account:\n"
+"              "
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:37
+msgid "Accept invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:9
+#: aleksis/core/templates/invitations/forms/_invite.html:10
+#: aleksis/core/templates/invitations/forms/_invite.html:21
+msgid "Invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:17
+#, fuzzy
+#| msgid "Contact details"
+msgid "Invite by email address"
+msgstr "Détails de contact"
+
+#: aleksis/core/templates/invitations/forms/_invite.html:26
+msgid "Generate invitation code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:29
+msgid "Generate code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:33
+msgid "Invitations"
+msgstr ""
+
+#: aleksis/core/templates/invitations/messages/invite_accepted.txt:3
+#, python-format
+msgid "The invitation for %(email)s has been accepted."
+msgstr ""
+
 #: aleksis/core/templates/oauth2_provider/application/create.html:5
 #: aleksis/core/templates/oauth2_provider/application/create.html:6
 #, fuzzy
@@ -2886,131 +2957,146 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:270
+#: aleksis/core/views.py:280
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:282
+#: aleksis/core/views.py:292
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:406
+#: aleksis/core/views.py:416
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:425 aleksis/core/views.py:435
+#: aleksis/core/views.py:435 aleksis/core/views.py:445
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:485
+#: aleksis/core/views.py:495
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:582
+#: aleksis/core/views.py:592
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:598
+#: aleksis/core/views.py:608
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:682
+#: aleksis/core/views.py:695
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:706
+#: aleksis/core/views.py:719
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:720
+#: aleksis/core/views.py:733
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:752
+#: aleksis/core/views.py:765
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:786
+#: aleksis/core/views.py:799
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:811
+#: aleksis/core/views.py:824
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:854
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:874
+#: aleksis/core/views.py:887
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:875
+#: aleksis/core/views.py:888
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:876
+#: aleksis/core/views.py:889
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:877
+#: aleksis/core/views.py:890
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:893
+#: aleksis/core/views.py:906
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:935
+#: aleksis/core/views.py:948
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:965
+#: aleksis/core/views.py:978
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:975
+#: aleksis/core/views.py:988
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1042
+#: aleksis/core/views.py:1055
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1044
+#: aleksis/core/views.py:1057
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1139
+#: aleksis/core/views.py:1127
+#, python-brace-format
+msgid "The invitation was successfully created. The invitation code is {code}"
+msgstr ""
+
+#: aleksis/core/views.py:1218
 msgid "We have successfully assigned the permissions."
 msgstr ""
 
-#: aleksis/core/views.py:1149
+#: aleksis/core/views.py:1228
 msgid "The global user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1159
+#: aleksis/core/views.py:1238
 msgid "The global group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1169
+#: aleksis/core/views.py:1248
 msgid "The object user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1179
+#: aleksis/core/views.py:1258
 msgid "The object group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1298
+#: aleksis/core/views.py:1377
 msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1305
+#: aleksis/core/views.py:1384
 msgid "The third-party account has been successfully disconnected."
 msgstr ""
 
+#: aleksis/core/views.py:1441
+msgid "Person was invited successfully."
+msgstr ""
+
+#: aleksis/core/views.py:1443
+#, fuzzy
+#| msgid "This username is already in use."
+msgid "Person was already invited."
+msgstr "Cet nom est deja en utilisation."
+
 #, fuzzy
 #~| msgid "Contact details"
 #~ msgid "Can link persons to accounts"
diff --git a/aleksis/core/locale/fr/LC_MESSAGES/djangojs.po b/aleksis/core/locale/fr/LC_MESSAGES/djangojs.po
index 7da12b4936edebe7889eee50f269c38dfbbfe3cc..8dd920515ef4b23a59c72cb6ec2809d27d03292a 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:14+0100\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:127
+#: aleksis/core/static/js/main.js:128
 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 4be66396809bdc0a6e052f159240117d9c45b5f6..b8f7f6b758f1520e97d0d96304f9205d2e356c9a 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:13+0100\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"
@@ -44,10 +44,10 @@ msgstr "Inscriptio electronica"
 msgid "Home and mobile phone"
 msgstr "Numerus telephoni mobilis"
 
-#: aleksis/core/apps.py:157 aleksis/core/forms.py:222 aleksis/core/menus.py:267
-#: aleksis/core/models.py:412 aleksis/core/templates/core/group/list.html:8
+#: aleksis/core/apps.py:157 aleksis/core/forms.py:223 aleksis/core/menus.py:265
+#: aleksis/core/models.py:414 aleksis/core/templates/core/group/list.html:8
 #: aleksis/core/templates/core/group/list.html:9
-#: aleksis/core/templates/core/person/full.html:145
+#: aleksis/core/templates/core/person/full.html:152
 msgid "Groups"
 msgstr "Greges"
 
@@ -101,161 +101,162 @@ msgstr ""
 msgid "Content type"
 msgstr ""
 
-#: aleksis/core/filters.py:112 aleksis/core/models.py:579
+#: aleksis/core/filters.py:112 aleksis/core/models.py:581
 msgid "User"
 msgstr ""
 
-#: aleksis/core/filters.py:134 aleksis/core/models.py:411
+#: aleksis/core/filters.py:134 aleksis/core/models.py:413
 msgid "Group"
 msgstr "Grex"
 
-#: aleksis/core/forms.py:47 aleksis/core/forms.py:521
+#: aleksis/core/forms.py:48 aleksis/core/forms.py:559
 msgid "Base data"
 msgstr ""
 
-#: aleksis/core/forms.py:53
+#: aleksis/core/forms.py:54
 #, fuzzy
 #| msgid "E-mail address"
 msgid "Address"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/forms.py:54
+#: aleksis/core/forms.py:55 aleksis/core/forms.py:568
 msgid "Contact data"
 msgstr ""
 
-#: aleksis/core/forms.py:56
+#: aleksis/core/forms.py:57
 msgid "Advanced personal data"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "New user"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 #, fuzzy
 #| msgid "Persons and accounts"
 msgid "Create a new account"
 msgstr "Personae et computi"
 
-#: aleksis/core/forms.py:135
+#: aleksis/core/forms.py:136
 msgid "You cannot set a new username when also selecting an existing user."
 msgstr ""
 
-#: aleksis/core/forms.py:139
+#: aleksis/core/forms.py:140
 msgid "This username is already in use."
 msgstr ""
 
-#: aleksis/core/forms.py:156 aleksis/core/models.py:125
+#: aleksis/core/forms.py:157 aleksis/core/models.py:129
 msgid "School term"
 msgstr "Anus scolae"
 
-#: aleksis/core/forms.py:157
+#: aleksis/core/forms.py:158
 #, fuzzy
 #| msgid "Data management"
 msgid "Common data"
 msgstr "Adminstratio datarum"
 
-#: aleksis/core/forms.py:158 aleksis/core/forms.py:209
-#: aleksis/core/menus.py:256 aleksis/core/models.py:148
+#: aleksis/core/forms.py:159 aleksis/core/forms.py:210
+#: aleksis/core/menus.py:254 aleksis/core/models.py:152
 #: aleksis/core/templates/core/person/list.html:8
 #: aleksis/core/templates/core/person/list.html:9
 msgid "Persons"
 msgstr "personae"
 
-#: aleksis/core/forms.py:159
+#: aleksis/core/forms.py:160 aleksis/core/forms.py:570
 #, fuzzy
 #| msgid "Additional name(s)"
 msgid "Additional data"
 msgstr "addita nomines"
 
-#: aleksis/core/forms.py:201 aleksis/core/forms.py:204
-#: aleksis/core/models.py:68
+#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
+#: aleksis/core/models.py:72
 msgid "Date"
 msgstr "dies"
 
-#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
-#: aleksis/core/models.py:76
+#: aleksis/core/forms.py:203 aleksis/core/forms.py:206
+#: aleksis/core/models.py:80
 msgid "Time"
 msgstr "tempus"
 
-#: aleksis/core/forms.py:235
+#: aleksis/core/forms.py:236
 msgid "From when until when should the announcement be displayed?"
 msgstr ""
 
-#: aleksis/core/forms.py:238
+#: aleksis/core/forms.py:239
 msgid "Who should see the announcement?"
 msgstr "Quis nuntium videatne?"
 
-#: aleksis/core/forms.py:239
+#: aleksis/core/forms.py:240
 msgid "Write your announcement:"
 msgstr "Scribe nuntium:"
 
-#: aleksis/core/forms.py:278
+#: aleksis/core/forms.py:279
 msgid "You are not allowed to create announcements which are only valid in the past."
 msgstr ""
 
-#: aleksis/core/forms.py:282
+#: aleksis/core/forms.py:283
 msgid "The from date and time must be earlier then the until date and time."
 msgstr ""
 
-#: aleksis/core/forms.py:291
+#: aleksis/core/forms.py:292
 msgid "You need at least one recipient."
 msgstr ""
 
-#: aleksis/core/forms.py:412
+#: aleksis/core/forms.py:401
+msgid "Invitation code"
+msgstr ""
+
+#: aleksis/core/forms.py:402
+msgid "Please enter your invitation code."
+msgstr ""
+
+#: aleksis/core/forms.py:434
 #, fuzzy
 #| msgid "Who should see the announcement?"
 msgid "Who should get the permission?"
 msgstr "Quis nuntium videatne?"
 
-#: aleksis/core/forms.py:413
+#: aleksis/core/forms.py:435
 msgid "On what?"
 msgstr ""
 
-#: aleksis/core/forms.py:439
+#: aleksis/core/forms.py:461
 msgid "Select objects which the permission should be granted for:"
 msgstr ""
 
-#: aleksis/core/forms.py:442
+#: aleksis/core/forms.py:464
 msgid "Grant the permission for all objects"
 msgstr ""
 
-#: aleksis/core/forms.py:450
+#: aleksis/core/forms.py:472
 msgid "You must select at least one group or person which should get the permission."
 msgstr ""
 
-#: aleksis/core/forms.py:455
+#: aleksis/core/forms.py:477
 msgid "You must grant the permission to all objects and/or to some objects."
 msgstr ""
 
-#: aleksis/core/forms.py:525
+#: aleksis/core/forms.py:564
+#, fuzzy
+#| msgid "E-mail address"
+msgid "Adress data"
+msgstr "Inscriptio electronica"
+
+#: aleksis/core/forms.py:576
 #, fuzzy
 #| msgid "Data management"
 msgid "Account data"
 msgstr "Adminstratio datarum"
 
-#: aleksis/core/forms.py:531
-msgid "Consents"
-msgstr ""
-
-#: aleksis/core/forms.py:538
+#: aleksis/core/forms.py:583
 msgid "Password"
 msgstr ""
 
-#: aleksis/core/forms.py:544
+#: aleksis/core/forms.py:586
 msgid "Password (again)"
 msgstr ""
 
-#: aleksis/core/forms.py:557
-#, python-brace-format
-msgid "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree with them."
-msgstr ""
-
-#: aleksis/core/forms.py:582
-msgid "You must type the same password each time."
-msgstr ""
-
-#: aleksis/core/forms.py:727
+#: aleksis/core/forms.py:752
 msgid "No valid selection."
 msgstr ""
 
@@ -294,34 +295,40 @@ msgstr "nomen profiteri"
 msgid "Sign up"
 msgstr ""
 
-#: aleksis/core/menus.py:24
+#: aleksis/core/menus.py:24 aleksis/core/templates/invitations/enter.html:7
+#, fuzzy
+#| msgid "Edit school information"
+msgid "Accept invitation"
+msgstr "Muta informationes scolae"
+
+#: aleksis/core/menus.py:33
 msgid "Dashboard"
 msgstr "Forum"
 
-#: aleksis/core/menus.py:32 aleksis/core/models.py:625
-#: aleksis/core/preferences.py:27
+#: aleksis/core/menus.py:41 aleksis/core/models.py:627
+#: aleksis/core/preferences.py:28
 #: aleksis/core/templates/core/notifications.html:4
 #: aleksis/core/templates/core/notifications.html:5
 msgid "Notifications"
 msgstr "Nuntii"
 
-#: aleksis/core/menus.py:44
+#: aleksis/core/menus.py:53
 msgid "Account"
 msgstr ""
 
-#: aleksis/core/menus.py:51
+#: aleksis/core/menus.py:60
 msgid "Stop impersonation"
 msgstr "Simulandum aliquem finire"
 
-#: aleksis/core/menus.py:60 aleksis/core/templates/core/base.html:80
+#: aleksis/core/menus.py:69 aleksis/core/templates/core/base.html:80
 msgid "Logout"
 msgstr "nomen retractare"
 
-#: aleksis/core/menus.py:66
+#: aleksis/core/menus.py:75
 msgid "2FA"
 msgstr ""
 
-#: aleksis/core/menus.py:74
+#: aleksis/core/menus.py:83
 #: aleksis/core/templates/account/password_change.html:5
 #: aleksis/core/templates/account/password_change.html:6
 #: aleksis/core/templates/account/password_change.html:19
@@ -333,22 +340,22 @@ msgstr ""
 msgid "Change password"
 msgstr ""
 
-#: aleksis/core/menus.py:86
+#: aleksis/core/menus.py:95
 msgid "Me"
 msgstr ""
 
-#: aleksis/core/menus.py:95
+#: aleksis/core/menus.py:104
 #: aleksis/core/templates/dynamic_preferences/form.html:5
 msgid "Preferences"
 msgstr ""
 
-#: aleksis/core/menus.py:104
+#: aleksis/core/menus.py:113
 #, fuzzy
 #| msgid "Persons and accounts"
 msgid "Third-party accounts"
 msgstr "Personae et computi"
 
-#: aleksis/core/menus.py:113
+#: aleksis/core/menus.py:122
 #: aleksis/core/templates/oauth2_provider/authorized-tokens.html:5
 #: aleksis/core/templates/oauth2_provider/authorized-tokens.html:6
 #, fuzzy
@@ -356,23 +363,23 @@ msgstr "Personae et computi"
 msgid "Authorized applications"
 msgstr "Nuntii"
 
-#: aleksis/core/menus.py:124
+#: aleksis/core/menus.py:133
 msgid "Admin"
 msgstr "Administratio"
 
-#: aleksis/core/menus.py:132 aleksis/core/models.py:725
+#: aleksis/core/menus.py:141 aleksis/core/models.py:727
 #: aleksis/core/templates/core/announcement/list.html:7
 #: aleksis/core/templates/core/announcement/list.html:8
 msgid "Announcements"
 msgstr "Nuntii"
 
-#: aleksis/core/menus.py:143 aleksis/core/models.py:126
+#: aleksis/core/menus.py:152 aleksis/core/models.py:130
 #: aleksis/core/templates/core/school_term/list.html:8
 #: aleksis/core/templates/core/school_term/list.html:9
 msgid "School terms"
 msgstr "ani scolae"
 
-#: aleksis/core/menus.py:154
+#: aleksis/core/menus.py:163
 #: aleksis/core/templates/core/dashboard_widget/list.html:8
 #: aleksis/core/templates/core/dashboard_widget/list.html:9
 #, fuzzy
@@ -380,45 +387,41 @@ msgstr "ani scolae"
 msgid "Dashboard widgets"
 msgstr "Forum"
 
-#: aleksis/core/menus.py:165
+#: aleksis/core/menus.py:174
 #: aleksis/core/templates/core/management/data_management.html:6
 #: aleksis/core/templates/core/management/data_management.html:7
 msgid "Data management"
 msgstr "Adminstratio datarum"
 
-#: aleksis/core/menus.py:176
+#: aleksis/core/menus.py:185
 #: aleksis/core/templates/core/pages/system_status.html:5
 #: aleksis/core/templates/core/pages/system_status.html:7
 msgid "System status"
 msgstr "Status systemae"
 
-#: aleksis/core/menus.py:187
-msgid "Impersonation"
-msgstr "Simulare aliquem"
-
-#: aleksis/core/menus.py:198
+#: aleksis/core/menus.py:196
 #, fuzzy
 #| msgid "Notification"
 msgid "Configuration"
 msgstr "Nuntius"
 
-#: aleksis/core/menus.py:209 aleksis/core/templates/core/data_check/list.html:9
+#: aleksis/core/menus.py:207 aleksis/core/templates/core/data_check/list.html:9
 #: aleksis/core/templates/core/data_check/list.html:10
 #, fuzzy
 #| msgid "System status"
 msgid "Data checks"
 msgstr "Status systemae"
 
-#: aleksis/core/menus.py:215 aleksis/core/templates/core/perms/list.html:13
+#: aleksis/core/menus.py:213 aleksis/core/templates/core/perms/list.html:13
 #: aleksis/core/templates/core/perms/list.html:14
 msgid "Manage permissions"
 msgstr ""
 
-#: aleksis/core/menus.py:226
+#: aleksis/core/menus.py:224
 msgid "Backend Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:234
+#: aleksis/core/menus.py:232
 #: aleksis/core/templates/oauth2_provider/application/list.html:5
 #: aleksis/core/templates/oauth2_provider/application/list.html:6
 #, fuzzy
@@ -426,11 +429,11 @@ msgstr ""
 msgid "OAuth2 Applications"
 msgstr "Nuntii"
 
-#: aleksis/core/menus.py:247
+#: aleksis/core/menus.py:245
 msgid "People"
 msgstr "Personae"
 
-#: aleksis/core/menus.py:278 aleksis/core/models.py:979
+#: aleksis/core/menus.py:276 aleksis/core/models.py:981
 #: aleksis/core/templates/core/group_type/list.html:8
 #: aleksis/core/templates/core/group_type/list.html:9
 #, fuzzy
@@ -438,11 +441,11 @@ msgstr "Personae"
 msgid "Group types"
 msgstr "Greges"
 
-#: aleksis/core/menus.py:289
+#: aleksis/core/menus.py:287
 msgid "Groups and child groups"
 msgstr ""
 
-#: aleksis/core/menus.py:300 aleksis/core/models.py:460
+#: aleksis/core/menus.py:298 aleksis/core/models.py:462
 #: aleksis/core/templates/core/additional_field/list.html:8
 #: aleksis/core/templates/core/additional_field/list.html:9
 #, fuzzy
@@ -450,809 +453,839 @@ msgstr ""
 msgid "Additional fields"
 msgstr "addita nomines"
 
-#: aleksis/core/menus.py:315
+#: aleksis/core/menus.py:309
+#, fuzzy
+#| msgid "Stop impersonation"
+msgid "Invite person"
+msgstr "Simulandum aliquem finire"
+
+#: aleksis/core/menus.py:322
 #: aleksis/core/templates/core/group/child_groups.html:7
 #: aleksis/core/templates/core/group/child_groups.html:9
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:508
+#: aleksis/core/mixins.py:511
 #, fuzzy
 #| msgid "Edit school term"
 msgid "Linked school term"
 msgstr "Muta anum scolae"
 
-#: aleksis/core/models.py:66
+#: aleksis/core/models.py:70
 msgid "Boolean (Yes/No)"
 msgstr ""
 
-#: aleksis/core/models.py:67
+#: aleksis/core/models.py:71
 msgid "Text (one line)"
 msgstr ""
 
-#: aleksis/core/models.py:69
+#: aleksis/core/models.py:73
 msgid "Date and time"
 msgstr "Dies et hora"
 
-#: aleksis/core/models.py:70
+#: aleksis/core/models.py:74
 msgid "Decimal number"
 msgstr ""
 
-#: aleksis/core/models.py:71 aleksis/core/models.py:194
+#: aleksis/core/models.py:75 aleksis/core/models.py:198
 msgid "E-mail address"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/models.py:72
+#: aleksis/core/models.py:76
 msgid "Integer"
 msgstr ""
 
-#: aleksis/core/models.py:73
+#: aleksis/core/models.py:77
 #, fuzzy
 #| msgid "E-mail address"
 msgid "IP address"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/models.py:74
+#: aleksis/core/models.py:78
 msgid "Boolean or empty (Yes/No/Neither)"
 msgstr ""
 
-#: aleksis/core/models.py:75
+#: aleksis/core/models.py:79
 msgid "Text (multi-line)"
 msgstr ""
 
-#: aleksis/core/models.py:77
+#: aleksis/core/models.py:81
 msgid "URL / Link"
 msgstr ""
 
-#: aleksis/core/models.py:89 aleksis/core/models.py:948
+#: aleksis/core/models.py:93 aleksis/core/models.py:950
 msgid "Name"
 msgstr "Nomen"
 
-#: aleksis/core/models.py:91
+#: aleksis/core/models.py:95
 msgid "Start date"
 msgstr ""
 
-#: aleksis/core/models.py:92
+#: aleksis/core/models.py:96
 msgid "End date"
 msgstr ""
 
-#: aleksis/core/models.py:111
+#: aleksis/core/models.py:115
 msgid "The start date must be earlier than the end date."
 msgstr ""
 
-#: aleksis/core/models.py:118
+#: aleksis/core/models.py:122
 msgid "There is already a school term for this time or a part of this time."
 msgstr ""
 
-#: aleksis/core/models.py:147 aleksis/core/models.py:897
+#: aleksis/core/models.py:151 aleksis/core/models.py:899
 msgid "Person"
 msgstr "Persona"
 
-#: aleksis/core/models.py:150
+#: aleksis/core/models.py:154
 #, fuzzy
 #| msgid "E-mail address"
 msgid "Can view address"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/models.py:151
+#: aleksis/core/models.py:155
 #, fuzzy
 #| msgid "E-mail address"
 msgid "Can view contact details"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/models.py:152
+#: aleksis/core/models.py:156
 #, fuzzy
 #| msgid "E-mail address"
 msgid "Can view photo"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/models.py:153
+#: aleksis/core/models.py:157
 #, fuzzy
 #| msgid "Persons and accounts"
 msgid "Can view persons groups"
 msgstr "Personae et computi"
 
-#: aleksis/core/models.py:154
+#: aleksis/core/models.py:158
 #, fuzzy
 #| msgid "Stop impersonation"
 msgid "Can view personal details"
 msgstr "Simulandum aliquem finire"
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "female"
 msgstr "femininum"
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "male"
 msgstr "maskulinum"
 
-#: aleksis/core/models.py:172
+#: aleksis/core/models.py:176 aleksis/core/models.py:1144
 msgid "Linked user"
 msgstr ""
 
-#: aleksis/core/models.py:174
+#: aleksis/core/models.py:178
 #, fuzzy
 #| msgid "Impersonation"
 msgid "Is person active?"
 msgstr "Simulare aliquem"
 
-#: aleksis/core/models.py:176
+#: aleksis/core/models.py:180
 msgid "First name"
 msgstr "Primus nomen"
 
-#: aleksis/core/models.py:177
+#: aleksis/core/models.py:181
 msgid "Last name"
 msgstr "Secondus nomen"
 
-#: aleksis/core/models.py:179
+#: aleksis/core/models.py:183
 msgid "Additional name(s)"
 msgstr "addita nomines"
 
-#: aleksis/core/models.py:183 aleksis/core/models.py:429
+#: aleksis/core/models.py:187 aleksis/core/models.py:431
 msgid "Short name"
 msgstr "Breve nomen"
 
-#: aleksis/core/models.py:186
+#: aleksis/core/models.py:190
 msgid "Street"
 msgstr "Via"
 
-#: aleksis/core/models.py:187
+#: aleksis/core/models.py:191
 msgid "Street number"
 msgstr "Numerus domini"
 
-#: aleksis/core/models.py:188
+#: aleksis/core/models.py:192
 msgid "Postal code"
 msgstr "Numerus directorius"
 
-#: aleksis/core/models.py:189
+#: aleksis/core/models.py:193
 msgid "Place"
 msgstr "Urbs"
 
-#: aleksis/core/models.py:191
+#: aleksis/core/models.py:195
 msgid "Home phone"
 msgstr "Numerus telephoni domi"
 
-#: aleksis/core/models.py:192
+#: aleksis/core/models.py:196
 msgid "Mobile phone"
 msgstr "Numerus telephoni mobilis"
 
-#: aleksis/core/models.py:196
+#: aleksis/core/models.py:200
 msgid "Date of birth"
 msgstr "Dies natalis"
 
-#: aleksis/core/models.py:198
+#: aleksis/core/models.py:201
 #, fuzzy
 #| msgid "Date of birth"
 msgid "Place of birth"
 msgstr "Dies natalis"
 
-#: aleksis/core/models.py:200
+#: aleksis/core/models.py:202
 msgid "Sex"
 msgstr "Genus"
 
-#: aleksis/core/models.py:202
+#: aleksis/core/models.py:204
 msgid "Photo"
 msgstr "Photographia"
 
-#: aleksis/core/models.py:206 aleksis/core/templates/core/person/full.html:138
+#: aleksis/core/models.py:208 aleksis/core/templates/core/person/full.html:145
 msgid "Guardians / Parents"
 msgstr "Parentes"
 
-#: aleksis/core/models.py:213
+#: aleksis/core/models.py:215
 msgid "Primary group"
 msgstr ""
 
-#: aleksis/core/models.py:216 aleksis/core/models.py:583
-#: aleksis/core/models.py:607 aleksis/core/models.py:692
-#: aleksis/core/models.py:972 aleksis/core/templates/core/person/full.html:121
+#: aleksis/core/models.py:218 aleksis/core/models.py:585
+#: aleksis/core/models.py:609 aleksis/core/models.py:694
+#: aleksis/core/models.py:974 aleksis/core/templates/core/person/full.html:128
 msgid "Description"
 msgstr "Descriptio"
 
-#: aleksis/core/models.py:384
+#: aleksis/core/models.py:386
 msgid "Title of field"
 msgstr ""
 
-#: aleksis/core/models.py:386
+#: aleksis/core/models.py:388
 msgid "Type of field"
 msgstr ""
 
-#: aleksis/core/models.py:393
+#: aleksis/core/models.py:395
 #, fuzzy
 #| msgid "Additional name(s)"
 msgid "Addtitional field for groups"
 msgstr "addita nomines"
 
-#: aleksis/core/models.py:394
+#: aleksis/core/models.py:396
 #, fuzzy
 #| msgid "Additional name(s)"
 msgid "Addtitional fields for groups"
 msgstr "addita nomines"
 
-#: aleksis/core/models.py:414
+#: aleksis/core/models.py:416
 msgid "Can assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/models.py:415
+#: aleksis/core/models.py:417
 #, fuzzy
 #| msgid "Persons and accounts"
 msgid "Can view statistics about group."
 msgstr "Personae et computi"
 
-#: aleksis/core/models.py:427
+#: aleksis/core/models.py:429
 #, fuzzy
 #| msgid "Last name"
 msgid "Long name"
 msgstr "Secondus nomen"
 
-#: aleksis/core/models.py:437 aleksis/core/templates/core/group/full.html:85
+#: aleksis/core/models.py:439 aleksis/core/templates/core/group/full.html:85
 msgid "Members"
 msgstr ""
 
-#: aleksis/core/models.py:440 aleksis/core/templates/core/group/full.html:82
+#: aleksis/core/models.py:442 aleksis/core/templates/core/group/full.html:82
 msgid "Owners"
 msgstr ""
 
-#: aleksis/core/models.py:447 aleksis/core/templates/core/group/full.html:55
+#: aleksis/core/models.py:449 aleksis/core/templates/core/group/full.html:55
 msgid "Parent groups"
 msgstr ""
 
-#: aleksis/core/models.py:455
+#: aleksis/core/models.py:457
 msgid "Type of group"
 msgstr ""
 
-#: aleksis/core/models.py:582 aleksis/core/models.py:606
-#: aleksis/core/models.py:691
+#: aleksis/core/models.py:584 aleksis/core/models.py:608
+#: aleksis/core/models.py:693
 #: aleksis/core/templates/core/announcement/list.html:18
 msgid "Title"
 msgstr "Titulus"
 
-#: aleksis/core/models.py:585
+#: aleksis/core/models.py:587
 msgid "Application"
 msgstr ""
 
-#: aleksis/core/models.py:591
+#: aleksis/core/models.py:593
 msgid "Activity"
 msgstr ""
 
-#: aleksis/core/models.py:592
+#: aleksis/core/models.py:594
 msgid "Activities"
 msgstr ""
 
-#: aleksis/core/models.py:598
+#: aleksis/core/models.py:600
 msgid "Sender"
 msgstr "Mittens"
 
-#: aleksis/core/models.py:603
+#: aleksis/core/models.py:605
 msgid "Recipient"
 msgstr ""
 
-#: aleksis/core/models.py:608 aleksis/core/models.py:949
+#: aleksis/core/models.py:610 aleksis/core/models.py:951
 msgid "Link"
 msgstr ""
 
-#: aleksis/core/models.py:610
+#: aleksis/core/models.py:612
 msgid "Read"
 msgstr ""
 
-#: aleksis/core/models.py:611
+#: aleksis/core/models.py:613
 msgid "Sent"
 msgstr ""
 
-#: aleksis/core/models.py:624
+#: aleksis/core/models.py:626
 #, fuzzy
 #| msgid "Notifications"
 msgid "Notification"
 msgstr "Nuntii"
 
-#: aleksis/core/models.py:693
+#: aleksis/core/models.py:695
 msgid "Link to detailed view"
 msgstr ""
 
-#: aleksis/core/models.py:696
+#: aleksis/core/models.py:698
 msgid "Date and time from when to show"
 msgstr ""
 
-#: aleksis/core/models.py:699
+#: aleksis/core/models.py:701
 msgid "Date and time until when to show"
 msgstr ""
 
-#: aleksis/core/models.py:724
+#: aleksis/core/models.py:726
 #, fuzzy
 #| msgid "Announcements"
 msgid "Announcement"
 msgstr "Nuntii"
 
-#: aleksis/core/models.py:762
+#: aleksis/core/models.py:764
 #, fuzzy
 #| msgid "Announcements"
 msgid "Announcement recipient"
 msgstr "Nuntii"
 
-#: aleksis/core/models.py:763
+#: aleksis/core/models.py:765
 #, fuzzy
 #| msgid "Announcements"
 msgid "Announcement recipients"
 msgstr "Nuntii"
 
-#: aleksis/core/models.py:818
+#: aleksis/core/models.py:820
 #, fuzzy
 #| msgid "Site title"
 msgid "Widget Title"
 msgstr "Titulus paginae"
 
-#: aleksis/core/models.py:819
+#: aleksis/core/models.py:821
 msgid "Activate Widget"
 msgstr ""
 
-#: aleksis/core/models.py:820
+#: aleksis/core/models.py:822
 #, fuzzy
 #| msgid "Site title"
 msgid "Widget is broken"
 msgstr "Titulus paginae"
 
-#: aleksis/core/models.py:823
+#: aleksis/core/models.py:825
 msgid "Size on mobile devices"
 msgstr ""
 
-#: aleksis/core/models.py:824
+#: aleksis/core/models.py:826
 msgid "<= 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:829
+#: aleksis/core/models.py:831
 msgid "Size on tablet devices"
 msgstr ""
 
-#: aleksis/core/models.py:830
+#: aleksis/core/models.py:832
 msgid "> 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:835
+#: aleksis/core/models.py:837
 msgid "Size on desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:836
+#: aleksis/core/models.py:838
 msgid "> 992 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:841
+#: aleksis/core/models.py:843
 msgid "Size on large desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:842
+#: aleksis/core/models.py:844
 msgid "> 1200 px>, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:873
+#: aleksis/core/models.py:875
 #, fuzzy
 #| msgid "Dashboard"
 msgid "Can edit default dashboard"
 msgstr "Forum"
 
-#: aleksis/core/models.py:874
+#: aleksis/core/models.py:876
 #, fuzzy
 #| msgid "Dashboard"
 msgid "Dashboard Widget"
 msgstr "Forum"
 
-#: aleksis/core/models.py:875
+#: aleksis/core/models.py:877
 #, fuzzy
 #| msgid "Dashboard"
 msgid "Dashboard Widgets"
 msgstr "Forum"
 
-#: aleksis/core/models.py:881
+#: aleksis/core/models.py:883
 msgid "URL"
 msgstr ""
 
-#: aleksis/core/models.py:882
+#: aleksis/core/models.py:884
 #, fuzzy
 #| msgid "Icon"
 msgid "Icon URL"
 msgstr "Nota"
 
-#: aleksis/core/models.py:888
+#: aleksis/core/models.py:890
 msgid "External link widget"
 msgstr ""
 
-#: aleksis/core/models.py:889
+#: aleksis/core/models.py:891
 msgid "External link widgets"
 msgstr ""
 
-#: aleksis/core/models.py:894
+#: aleksis/core/models.py:896
 #, fuzzy
 #| msgid "Dashboard"
 msgid "Dashboard widget"
 msgstr "Forum"
 
-#: aleksis/core/models.py:899
+#: aleksis/core/models.py:901
 msgid "Order"
 msgstr ""
 
-#: aleksis/core/models.py:900
+#: aleksis/core/models.py:902
 msgid "Part of the default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:915
+#: aleksis/core/models.py:917
 #, fuzzy
 #| msgid "Dashboard"
 msgid "Dashboard widget order"
 msgstr "Forum"
 
-#: aleksis/core/models.py:916
+#: aleksis/core/models.py:918
 #, fuzzy
 #| msgid "Dashboard"
 msgid "Dashboard widget orders"
 msgstr "Forum"
 
-#: aleksis/core/models.py:922
+#: aleksis/core/models.py:924
 msgid "Menu ID"
 msgstr ""
 
-#: aleksis/core/models.py:935
+#: aleksis/core/models.py:937
 msgid "Custom menu"
 msgstr ""
 
-#: aleksis/core/models.py:936
+#: aleksis/core/models.py:938
 msgid "Custom menus"
 msgstr ""
 
-#: aleksis/core/models.py:946
+#: aleksis/core/models.py:948
 msgid "Menu"
 msgstr ""
 
-#: aleksis/core/models.py:950
+#: aleksis/core/models.py:952
 msgid "Icon"
 msgstr "Nota"
 
-#: aleksis/core/models.py:956
+#: aleksis/core/models.py:958
 msgid "Custom menu item"
 msgstr ""
 
-#: aleksis/core/models.py:957
+#: aleksis/core/models.py:959
 msgid "Custom menu items"
 msgstr ""
 
-#: aleksis/core/models.py:971
+#: aleksis/core/models.py:973
 msgid "Title of type"
 msgstr ""
 
-#: aleksis/core/models.py:978 aleksis/core/templates/core/group/full.html:47
+#: aleksis/core/models.py:980 aleksis/core/templates/core/group/full.html:47
 #, fuzzy
 #| msgid "Group"
 msgid "Group type"
 msgstr "Grex"
 
-#: aleksis/core/models.py:992
+#: aleksis/core/models.py:994
 #, fuzzy
 #| msgid "System status"
 msgid "Can view system status"
 msgstr "Status systemae"
 
-#: aleksis/core/models.py:993
+#: aleksis/core/models.py:995
 #, fuzzy
 #| msgid "Data management"
 msgid "Can manage data"
 msgstr "Adminstratio datarum"
 
-#: aleksis/core/models.py:994
+#: aleksis/core/models.py:996
 #, fuzzy
 #| msgid "Stop impersonation"
 msgid "Can impersonate"
 msgstr "Simulandum aliquem finire"
 
-#: aleksis/core/models.py:995
+#: aleksis/core/models.py:997
 msgid "Can use search"
 msgstr ""
 
-#: aleksis/core/models.py:996
+#: aleksis/core/models.py:998
 msgid "Can change site preferences"
 msgstr ""
 
-#: aleksis/core/models.py:997
+#: aleksis/core/models.py:999
 msgid "Can change person preferences"
 msgstr ""
 
-#: aleksis/core/models.py:998
+#: aleksis/core/models.py:1000
 msgid "Can change group preferences"
 msgstr ""
 
-#: aleksis/core/models.py:999
+#: aleksis/core/models.py:1001
 msgid "Can test PDF generation"
 msgstr ""
 
-#: aleksis/core/models.py:1035
+#: aleksis/core/models.py:1037
 msgid "Related data check task"
 msgstr ""
 
-#: aleksis/core/models.py:1043
+#: aleksis/core/models.py:1045
 msgid "Issue solved"
 msgstr ""
 
-#: aleksis/core/models.py:1044
+#: aleksis/core/models.py:1046
 #, fuzzy
 #| msgid "Notifications"
 msgid "Notification sent"
 msgstr "Nuntii"
 
-#: aleksis/core/models.py:1057
+#: aleksis/core/models.py:1059
 msgid "Data check result"
 msgstr ""
 
-#: aleksis/core/models.py:1058
+#: aleksis/core/models.py:1060
 msgid "Data check results"
 msgstr ""
 
-#: aleksis/core/models.py:1060
+#: aleksis/core/models.py:1062
 msgid "Can run data checks"
 msgstr ""
 
-#: aleksis/core/models.py:1061
+#: aleksis/core/models.py:1063
 msgid "Can solve data check problems"
 msgstr ""
 
-#: aleksis/core/models.py:1076
+#: aleksis/core/models.py:1070
+#, fuzzy
+#| msgid "E-mail address"
+msgid "E-Mail address"
+msgstr "Inscriptio electronica"
+
+#: aleksis/core/models.py:1094
 msgid "Owner"
 msgstr ""
 
-#: aleksis/core/models.py:1080
+#: aleksis/core/models.py:1098
 msgid "File expires at"
 msgstr ""
 
-#: aleksis/core/models.py:1082
+#: aleksis/core/models.py:1100
 msgid "Generated HTML file"
 msgstr ""
 
-#: aleksis/core/models.py:1084
+#: aleksis/core/models.py:1102
 msgid "Generated PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1091
+#: aleksis/core/models.py:1109
 msgid "PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1092
+#: aleksis/core/models.py:1110
 msgid "PDF files"
 msgstr ""
 
-#: aleksis/core/models.py:1097
+#: aleksis/core/models.py:1115
 msgid "Task result"
 msgstr ""
 
-#: aleksis/core/models.py:1100
+#: aleksis/core/models.py:1118
 msgid "Task user"
 msgstr ""
 
-#: aleksis/core/models.py:1112
+#: aleksis/core/models.py:1130
 msgid "Task user assignment"
 msgstr ""
 
-#: aleksis/core/models.py:1113
+#: aleksis/core/models.py:1131
 msgid "Task user assignments"
 msgstr ""
 
-#: aleksis/core/models.py:1127
+#: aleksis/core/models.py:1147
+#, fuzzy
+#| msgid "Additional name(s)"
+msgid "Additional attributes"
+msgstr "addita nomines"
+
+#: aleksis/core/models.py:1185
 msgid "Allowed scopes that clients can request"
 msgstr ""
 
-#: aleksis/core/preferences.py:23
+#: aleksis/core/preferences.py:24
 msgid "General"
 msgstr ""
 
-#: aleksis/core/preferences.py:24
+#: aleksis/core/preferences.py:25
 msgid "School"
 msgstr "Scola"
 
-#: aleksis/core/preferences.py:25
+#: aleksis/core/preferences.py:26
 msgid "Theme"
 msgstr ""
 
-#: aleksis/core/preferences.py:26
+#: aleksis/core/preferences.py:27
 msgid "Mail"
 msgstr ""
 
-#: aleksis/core/preferences.py:28
+#: aleksis/core/preferences.py:29
 msgid "Footer"
 msgstr ""
 
-#: aleksis/core/preferences.py:29
+#: aleksis/core/preferences.py:30
 #, fuzzy
 #| msgid "Data management"
 msgid "Accounts"
 msgstr "Adminstratio datarum"
 
-#: aleksis/core/preferences.py:30
+#: aleksis/core/preferences.py:31
 #, fuzzy
 #| msgid "Notifications"
 msgid "Authentication"
 msgstr "Nuntii"
 
-#: aleksis/core/preferences.py:31
+#: aleksis/core/preferences.py:32
 #, fuzzy
 #| msgid "Impersonation"
 msgid "Internationalisation"
 msgstr "Simulare aliquem"
 
-#: aleksis/core/preferences.py:42
+#: aleksis/core/preferences.py:43
 msgid "Site title"
 msgstr "Titulus paginae"
 
-#: aleksis/core/preferences.py:53
+#: aleksis/core/preferences.py:54
 msgid "Site description"
 msgstr "Descriptio paginae"
 
-#: aleksis/core/preferences.py:64
+#: aleksis/core/preferences.py:65
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:77
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:87
+#: aleksis/core/preferences.py:88
 #, fuzzy
 #| msgid "Logout"
 msgid "Logo"
 msgstr "nomen retractare"
 
-#: aleksis/core/preferences.py:97
+#: aleksis/core/preferences.py:98
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:107
+#: aleksis/core/preferences.py:108
 #, fuzzy
 #| msgid "Icon"
 msgid "PWA-Icon"
 msgstr "Nota"
 
-#: aleksis/core/preferences.py:118
+#: aleksis/core/preferences.py:119
 #, fuzzy
 #| msgid "Last name"
 msgid "Mail out name"
 msgstr "Secondus nomen"
 
-#: aleksis/core/preferences.py:129
+#: aleksis/core/preferences.py:130
 #, fuzzy
 #| msgid "E-mail address"
 msgid "Mail out address"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/preferences.py:141
+#: aleksis/core/preferences.py:142
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:153
+#: aleksis/core/preferences.py:154
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:165
+#: aleksis/core/preferences.py:166
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:181
+#: aleksis/core/preferences.py:182
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:193
+#: aleksis/core/preferences.py:194
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:204
+#: aleksis/core/preferences.py:205
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:216
+#: aleksis/core/preferences.py:217
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:225
+#: aleksis/core/preferences.py:226
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:236
+#: aleksis/core/preferences.py:237
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:247
+#: aleksis/core/preferences.py:248
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr "Officialis nomen scolae, e. g."
 
-#: aleksis/core/preferences.py:255
+#: aleksis/core/preferences.py:256
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:263
+#: aleksis/core/preferences.py:264
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:274
+#: aleksis/core/preferences.py:272
+msgid "Enable invitations"
+msgstr ""
+
+#: aleksis/core/preferences.py:280
+msgid "Length of invite code. (Default 3: abcde-acbde-abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:288
+msgid "Size of packets. (Default 5: abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:298
 #, fuzzy
 #| msgid "E-mail address"
 msgid "Allowed Grant Flows for OAuth applications"
 msgstr "Inscriptio electronica"
 
-#: aleksis/core/preferences.py:287
+#: aleksis/core/preferences.py:311
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:299
+#: aleksis/core/preferences.py:323
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:310
+#: aleksis/core/preferences.py:334
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:321
+#: aleksis/core/preferences.py:345
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:330
+#: aleksis/core/preferences.py:354
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:339
+#: aleksis/core/preferences.py:363
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:350
+#: aleksis/core/preferences.py:374
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:364
+#: aleksis/core/preferences.py:388
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:377
+#: aleksis/core/preferences.py:401
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:387
+#: aleksis/core/preferences.py:411
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:388
+#: aleksis/core/preferences.py:412
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/preferences.py:398
+#: aleksis/core/preferences.py:422
 msgid "Automatically update the dashboard and its widgets"
 msgstr ""
 
-#: aleksis/core/preferences.py:408
+#: aleksis/core/preferences.py:432
 msgid "Automatically update the dashboard and its widgets sitewide"
 msgstr ""
 
-#: aleksis/core/settings.py:482
+#: aleksis/core/settings.py:507
 msgid "English"
 msgstr "Britannicus"
 
-#: aleksis/core/settings.py:483
+#: aleksis/core/settings.py:508
 msgid "German"
 msgstr "Germanus"
 
-#: aleksis/core/tables.py:19
+#: aleksis/core/tables.py:24
 #: aleksis/core/templates/core/announcement/list.html:36
 #: aleksis/core/templates/core/group/full.html:24
-#: aleksis/core/templates/core/person/full.html:23
+#: aleksis/core/templates/core/person/full.html:24
 #: aleksis/core/templates/oauth2_provider/application/detail.html:17
 msgid "Edit"
 msgstr ""
 
-#: aleksis/core/tables.py:21 aleksis/core/tables.py:89
-#: aleksis/core/tables.py:105
+#: aleksis/core/tables.py:26 aleksis/core/tables.py:94
+#: aleksis/core/tables.py:137
 #: aleksis/core/templates/core/announcement/list.html:22
 #, fuzzy
 #| msgid "Notifications"
 msgid "Actions"
 msgstr "Nuntii"
 
-#: aleksis/core/tables.py:56 aleksis/core/tables.py:57
-#: aleksis/core/tables.py:71 aleksis/core/tables.py:87
-#: aleksis/core/tables.py:103
+#: aleksis/core/tables.py:61 aleksis/core/tables.py:62
+#: aleksis/core/tables.py:76 aleksis/core/tables.py:92
+#: aleksis/core/tables.py:135
 #: aleksis/core/templates/core/announcement/list.html:42
 #: aleksis/core/templates/core/group/full.html:31
 #: aleksis/core/templates/core/pages/delete.html:22
-#: aleksis/core/templates/core/person/full.html:30
+#: aleksis/core/templates/core/person/full.html:31
 #: aleksis/core/templates/oauth2_provider/application/detail.html:21
 msgid "Delete"
 msgstr ""
@@ -1324,11 +1357,11 @@ msgstr ""
 msgid "Account inactive"
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:13
+#: aleksis/core/templates/account/account_inactive.html:14
 msgid "Account inactive."
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:15
+#: aleksis/core/templates/account/account_inactive.html:17
 msgid ""
 "\n"
 "            This account is currently inactive. If you think this is an\n"
@@ -1482,11 +1515,11 @@ msgstr ""
 msgid "Signup closed"
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:13
+#: aleksis/core/templates/account/signup_closed.html:14
 msgid "Signup closed."
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:15
+#: aleksis/core/templates/account/signup_closed.html:17
 msgid ""
 "\n"
 "            This sign up is currently closed. If you think this is an\n"
@@ -1526,11 +1559,6 @@ msgid ""
 "          "
 msgstr ""
 
-#: 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 ""
-
 #: aleksis/core/templates/core/additional_field/edit.html:6
 #: aleksis/core/templates/core/additional_field/edit.html:7
 #, fuzzy
@@ -1597,7 +1625,7 @@ msgid "About AlekSIS® — The Free School Information System"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:183
-msgid "Impress"
+msgid "Imprint"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:191
@@ -1834,7 +1862,7 @@ msgid "Edit group"
 msgstr ""
 
 #: aleksis/core/templates/core/group/full.html:38
-#: aleksis/core/templates/core/person/full.html:37
+#: aleksis/core/templates/core/person/full.html:38
 msgid "Change preferences"
 msgstr ""
 
@@ -2254,19 +2282,23 @@ msgstr "Simulandum aliquem finire"
 msgid "Edit person"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:44
-#: aleksis/core/templates/impersonate/list_users.html:7
-#: aleksis/core/templates/impersonate/list_users.html:8
+#: aleksis/core/templates/core/person/full.html:45
 #, fuzzy
 #| msgid "Impersonation"
 msgid "Impersonate"
 msgstr "Simulare aliquem"
 
-#: aleksis/core/templates/core/person/full.html:50
+#: aleksis/core/templates/core/person/full.html:51
+#, fuzzy
+#| msgid "Impersonation"
+msgid "Invite user"
+msgstr "Simulare aliquem"
+
+#: aleksis/core/templates/core/person/full.html:57
 msgid "Contact details"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:131
+#: aleksis/core/templates/core/person/full.html:138
 msgid "Children"
 msgstr ""
 
@@ -2308,6 +2340,51 @@ msgstr ""
 msgid "Save preferences"
 msgstr ""
 
+#: aleksis/core/templates/invitations/enter.html:21
+msgid "Accept your invitation"
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:25
+msgid ""
+"\n"
+"                Please enter your invitation code to register\n"
+"                your new user account:\n"
+"              "
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:37
+msgid "Accept invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:9
+#: aleksis/core/templates/invitations/forms/_invite.html:10
+#: aleksis/core/templates/invitations/forms/_invite.html:21
+msgid "Invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:17
+#, fuzzy
+#| msgid "E-mail address"
+msgid "Invite by email address"
+msgstr "Inscriptio electronica"
+
+#: aleksis/core/templates/invitations/forms/_invite.html:26
+msgid "Generate invitation code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:29
+msgid "Generate code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:33
+msgid "Invitations"
+msgstr ""
+
+#: aleksis/core/templates/invitations/messages/invite_accepted.txt:3
+#, python-format
+msgid "The invitation for %(email)s has been accepted."
+msgstr ""
+
 #: aleksis/core/templates/oauth2_provider/application/create.html:5
 #: aleksis/core/templates/oauth2_provider/application/create.html:6
 #, fuzzy
@@ -3007,133 +3084,149 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:270
+#: aleksis/core/views.py:280
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:282
+#: aleksis/core/views.py:292
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:406
+#: aleksis/core/views.py:416
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:425 aleksis/core/views.py:435
+#: aleksis/core/views.py:435 aleksis/core/views.py:445
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:485
+#: aleksis/core/views.py:495
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:582
+#: aleksis/core/views.py:592
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:598
+#: aleksis/core/views.py:608
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:682
+#: aleksis/core/views.py:695
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:706
+#: aleksis/core/views.py:719
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:720
+#: aleksis/core/views.py:733
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:752
+#: aleksis/core/views.py:765
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:786
+#: aleksis/core/views.py:799
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:811
+#: aleksis/core/views.py:824
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:854
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:874
+#: aleksis/core/views.py:887
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:875
+#: aleksis/core/views.py:888
 #, fuzzy
 #| msgid "System status"
 msgid "Run data checks …"
 msgstr "Status systemae"
 
-#: aleksis/core/views.py:876
+#: aleksis/core/views.py:889
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:877
+#: aleksis/core/views.py:890
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:893
+#: aleksis/core/views.py:906
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:935
+#: aleksis/core/views.py:948
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:965
+#: aleksis/core/views.py:978
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:975
+#: aleksis/core/views.py:988
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1042
+#: aleksis/core/views.py:1055
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1044
+#: aleksis/core/views.py:1057
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1139
+#: aleksis/core/views.py:1127
+#, python-brace-format
+msgid "The invitation was successfully created. The invitation code is {code}"
+msgstr ""
+
+#: aleksis/core/views.py:1218
 msgid "We have successfully assigned the permissions."
 msgstr ""
 
-#: aleksis/core/views.py:1149
+#: aleksis/core/views.py:1228
 msgid "The global user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1159
+#: aleksis/core/views.py:1238
 msgid "The global group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1169
+#: aleksis/core/views.py:1248
 msgid "The object user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1179
+#: aleksis/core/views.py:1258
 msgid "The object group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1298
+#: aleksis/core/views.py:1377
 msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1305
+#: aleksis/core/views.py:1384
 msgid "The third-party account has been successfully disconnected."
 msgstr ""
 
+#: aleksis/core/views.py:1441
+msgid "Person was invited successfully."
+msgstr ""
+
+#: aleksis/core/views.py:1443
+msgid "Person was already invited."
+msgstr ""
+
+#~ msgid "Impersonation"
+#~ msgstr "Simulare aliquem"
+
 #, fuzzy
 #~| msgid "Notifications"
 #~ msgid "OAuth2 applications"
@@ -3152,11 +3245,6 @@ msgstr ""
 #~ msgid "Link persons to accounts"
 #~ msgstr "Personae et computi"
 
-#, fuzzy
-#~| msgid "Impersonation"
-#~ msgid "Impersonate user"
-#~ msgstr "Simulare aliquem"
-
 #~ msgid "School logo"
 #~ msgstr "Imago scolae"
 
diff --git a/aleksis/core/locale/la/LC_MESSAGES/djangojs.po b/aleksis/core/locale/la/LC_MESSAGES/djangojs.po
index 42571d39e1fdfd5750cf094335d8718cd90c2cde..d67bdb0055bf1ee96915909ce9e21023085c466b 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:14+0100\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:127
+#: aleksis/core/static/js/main.js:128
 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 9d1457dd53915b9b50dc7c72dc10ccba8dd33a03..e40c13ef84618ccb0eb3bd58c524f81e00fe8834 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:13+0100\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"
@@ -37,10 +37,10 @@ msgstr ""
 msgid "Home and mobile phone"
 msgstr ""
 
-#: aleksis/core/apps.py:157 aleksis/core/forms.py:222 aleksis/core/menus.py:267
-#: aleksis/core/models.py:412 aleksis/core/templates/core/group/list.html:8
+#: aleksis/core/apps.py:157 aleksis/core/forms.py:223 aleksis/core/menus.py:265
+#: aleksis/core/models.py:414 aleksis/core/templates/core/group/list.html:8
 #: aleksis/core/templates/core/group/list.html:9
-#: aleksis/core/templates/core/person/full.html:145
+#: aleksis/core/templates/core/person/full.html:152
 msgid "Groups"
 msgstr ""
 
@@ -90,149 +90,148 @@ msgstr ""
 msgid "Content type"
 msgstr ""
 
-#: aleksis/core/filters.py:112 aleksis/core/models.py:579
+#: aleksis/core/filters.py:112 aleksis/core/models.py:581
 msgid "User"
 msgstr ""
 
-#: aleksis/core/filters.py:134 aleksis/core/models.py:411
+#: aleksis/core/filters.py:134 aleksis/core/models.py:413
 msgid "Group"
 msgstr ""
 
-#: aleksis/core/forms.py:47 aleksis/core/forms.py:521
+#: aleksis/core/forms.py:48 aleksis/core/forms.py:559
 msgid "Base data"
 msgstr ""
 
-#: aleksis/core/forms.py:53
+#: aleksis/core/forms.py:54
 msgid "Address"
 msgstr ""
 
-#: aleksis/core/forms.py:54
+#: aleksis/core/forms.py:55 aleksis/core/forms.py:568
 msgid "Contact data"
 msgstr ""
 
-#: aleksis/core/forms.py:56
+#: aleksis/core/forms.py:57
 msgid "Advanced personal data"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "New user"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "Create a new account"
 msgstr ""
 
-#: aleksis/core/forms.py:135
+#: aleksis/core/forms.py:136
 msgid "You cannot set a new username when also selecting an existing user."
 msgstr ""
 
-#: aleksis/core/forms.py:139
+#: aleksis/core/forms.py:140
 msgid "This username is already in use."
 msgstr ""
 
-#: aleksis/core/forms.py:156 aleksis/core/models.py:125
+#: aleksis/core/forms.py:157 aleksis/core/models.py:129
 msgid "School term"
 msgstr ""
 
-#: aleksis/core/forms.py:157
+#: aleksis/core/forms.py:158
 msgid "Common data"
 msgstr ""
 
-#: aleksis/core/forms.py:158 aleksis/core/forms.py:209
-#: aleksis/core/menus.py:256 aleksis/core/models.py:148
+#: aleksis/core/forms.py:159 aleksis/core/forms.py:210
+#: aleksis/core/menus.py:254 aleksis/core/models.py:152
 #: aleksis/core/templates/core/person/list.html:8
 #: aleksis/core/templates/core/person/list.html:9
 msgid "Persons"
 msgstr ""
 
-#: aleksis/core/forms.py:159
+#: aleksis/core/forms.py:160 aleksis/core/forms.py:570
 msgid "Additional data"
 msgstr ""
 
-#: aleksis/core/forms.py:201 aleksis/core/forms.py:204
-#: aleksis/core/models.py:68
+#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
+#: aleksis/core/models.py:72
 msgid "Date"
 msgstr ""
 
-#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
-#: aleksis/core/models.py:76
+#: aleksis/core/forms.py:203 aleksis/core/forms.py:206
+#: aleksis/core/models.py:80
 msgid "Time"
 msgstr ""
 
-#: aleksis/core/forms.py:235
+#: aleksis/core/forms.py:236
 msgid "From when until when should the announcement be displayed?"
 msgstr ""
 
-#: aleksis/core/forms.py:238
+#: aleksis/core/forms.py:239
 msgid "Who should see the announcement?"
 msgstr ""
 
-#: aleksis/core/forms.py:239
+#: aleksis/core/forms.py:240
 msgid "Write your announcement:"
 msgstr ""
 
-#: aleksis/core/forms.py:278
+#: aleksis/core/forms.py:279
 msgid "You are not allowed to create announcements which are only valid in the past."
 msgstr ""
 
-#: aleksis/core/forms.py:282
+#: aleksis/core/forms.py:283
 msgid "The from date and time must be earlier then the until date and time."
 msgstr ""
 
-#: aleksis/core/forms.py:291
+#: aleksis/core/forms.py:292
 msgid "You need at least one recipient."
 msgstr ""
 
-#: aleksis/core/forms.py:412
+#: aleksis/core/forms.py:401
+msgid "Invitation code"
+msgstr ""
+
+#: aleksis/core/forms.py:402
+msgid "Please enter your invitation code."
+msgstr ""
+
+#: aleksis/core/forms.py:434
 msgid "Who should get the permission?"
 msgstr ""
 
-#: aleksis/core/forms.py:413
+#: aleksis/core/forms.py:435
 msgid "On what?"
 msgstr ""
 
-#: aleksis/core/forms.py:439
+#: aleksis/core/forms.py:461
 msgid "Select objects which the permission should be granted for:"
 msgstr ""
 
-#: aleksis/core/forms.py:442
+#: aleksis/core/forms.py:464
 msgid "Grant the permission for all objects"
 msgstr ""
 
-#: aleksis/core/forms.py:450
+#: aleksis/core/forms.py:472
 msgid "You must select at least one group or person which should get the permission."
 msgstr ""
 
-#: aleksis/core/forms.py:455
+#: aleksis/core/forms.py:477
 msgid "You must grant the permission to all objects and/or to some objects."
 msgstr ""
 
-#: aleksis/core/forms.py:525
-msgid "Account data"
+#: aleksis/core/forms.py:564
+msgid "Adress data"
 msgstr ""
 
-#: aleksis/core/forms.py:531
-msgid "Consents"
+#: aleksis/core/forms.py:576
+msgid "Account data"
 msgstr ""
 
-#: aleksis/core/forms.py:538
+#: aleksis/core/forms.py:583
 msgid "Password"
 msgstr ""
 
-#: aleksis/core/forms.py:544
+#: aleksis/core/forms.py:586
 msgid "Password (again)"
 msgstr ""
 
-#: aleksis/core/forms.py:557
-#, python-brace-format
-msgid "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree with them."
-msgstr ""
-
-#: aleksis/core/forms.py:582
-msgid "You must type the same password each time."
-msgstr ""
-
-#: aleksis/core/forms.py:727
+#: aleksis/core/forms.py:752
 msgid "No valid selection."
 msgstr ""
 
@@ -269,34 +268,38 @@ msgstr ""
 msgid "Sign up"
 msgstr ""
 
-#: aleksis/core/menus.py:24
+#: aleksis/core/menus.py:24 aleksis/core/templates/invitations/enter.html:7
+msgid "Accept invitation"
+msgstr ""
+
+#: aleksis/core/menus.py:33
 msgid "Dashboard"
 msgstr ""
 
-#: aleksis/core/menus.py:32 aleksis/core/models.py:625
-#: aleksis/core/preferences.py:27
+#: aleksis/core/menus.py:41 aleksis/core/models.py:627
+#: aleksis/core/preferences.py:28
 #: aleksis/core/templates/core/notifications.html:4
 #: aleksis/core/templates/core/notifications.html:5
 msgid "Notifications"
 msgstr ""
 
-#: aleksis/core/menus.py:44
+#: aleksis/core/menus.py:53
 msgid "Account"
 msgstr ""
 
-#: aleksis/core/menus.py:51
+#: aleksis/core/menus.py:60
 msgid "Stop impersonation"
 msgstr ""
 
-#: aleksis/core/menus.py:60 aleksis/core/templates/core/base.html:80
+#: aleksis/core/menus.py:69 aleksis/core/templates/core/base.html:80
 msgid "Logout"
 msgstr ""
 
-#: aleksis/core/menus.py:66
+#: aleksis/core/menus.py:75
 msgid "2FA"
 msgstr ""
 
-#: aleksis/core/menus.py:74
+#: aleksis/core/menus.py:83
 #: aleksis/core/templates/account/password_change.html:5
 #: aleksis/core/templates/account/password_change.html:6
 #: aleksis/core/templates/account/password_change.html:19
@@ -308,830 +311,850 @@ msgstr ""
 msgid "Change password"
 msgstr ""
 
-#: aleksis/core/menus.py:86
+#: aleksis/core/menus.py:95
 msgid "Me"
 msgstr ""
 
-#: aleksis/core/menus.py:95
+#: aleksis/core/menus.py:104
 #: aleksis/core/templates/dynamic_preferences/form.html:5
 msgid "Preferences"
 msgstr ""
 
-#: aleksis/core/menus.py:104
+#: aleksis/core/menus.py:113
 msgid "Third-party accounts"
 msgstr ""
 
-#: aleksis/core/menus.py:113
+#: aleksis/core/menus.py:122
 #: 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:124
+#: aleksis/core/menus.py:133
 msgid "Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:132 aleksis/core/models.py:725
+#: aleksis/core/menus.py:141 aleksis/core/models.py:727
 #: aleksis/core/templates/core/announcement/list.html:7
 #: aleksis/core/templates/core/announcement/list.html:8
 msgid "Announcements"
 msgstr ""
 
-#: aleksis/core/menus.py:143 aleksis/core/models.py:126
+#: aleksis/core/menus.py:152 aleksis/core/models.py:130
 #: aleksis/core/templates/core/school_term/list.html:8
 #: aleksis/core/templates/core/school_term/list.html:9
 msgid "School terms"
 msgstr ""
 
-#: aleksis/core/menus.py:154
+#: aleksis/core/menus.py:163
 #: aleksis/core/templates/core/dashboard_widget/list.html:8
 #: aleksis/core/templates/core/dashboard_widget/list.html:9
 msgid "Dashboard widgets"
 msgstr ""
 
-#: aleksis/core/menus.py:165
+#: aleksis/core/menus.py:174
 #: aleksis/core/templates/core/management/data_management.html:6
 #: aleksis/core/templates/core/management/data_management.html:7
 msgid "Data management"
 msgstr ""
 
-#: aleksis/core/menus.py:176
+#: aleksis/core/menus.py:185
 #: aleksis/core/templates/core/pages/system_status.html:5
 #: aleksis/core/templates/core/pages/system_status.html:7
 msgid "System status"
 msgstr ""
 
-#: aleksis/core/menus.py:187
-msgid "Impersonation"
-msgstr ""
-
-#: aleksis/core/menus.py:198
+#: aleksis/core/menus.py:196
 msgid "Configuration"
 msgstr ""
 
-#: aleksis/core/menus.py:209 aleksis/core/templates/core/data_check/list.html:9
+#: aleksis/core/menus.py:207 aleksis/core/templates/core/data_check/list.html:9
 #: aleksis/core/templates/core/data_check/list.html:10
 msgid "Data checks"
 msgstr ""
 
-#: aleksis/core/menus.py:215 aleksis/core/templates/core/perms/list.html:13
+#: aleksis/core/menus.py:213 aleksis/core/templates/core/perms/list.html:13
 #: aleksis/core/templates/core/perms/list.html:14
 msgid "Manage permissions"
 msgstr ""
 
-#: aleksis/core/menus.py:226
+#: aleksis/core/menus.py:224
 msgid "Backend Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:234
+#: aleksis/core/menus.py:232
 #: aleksis/core/templates/oauth2_provider/application/list.html:5
 #: aleksis/core/templates/oauth2_provider/application/list.html:6
 msgid "OAuth2 Applications"
 msgstr ""
 
-#: aleksis/core/menus.py:247
+#: aleksis/core/menus.py:245
 msgid "People"
 msgstr ""
 
-#: aleksis/core/menus.py:278 aleksis/core/models.py:979
+#: aleksis/core/menus.py:276 aleksis/core/models.py:981
 #: aleksis/core/templates/core/group_type/list.html:8
 #: aleksis/core/templates/core/group_type/list.html:9
 msgid "Group types"
 msgstr ""
 
-#: aleksis/core/menus.py:289
+#: aleksis/core/menus.py:287
 msgid "Groups and child groups"
 msgstr ""
 
-#: aleksis/core/menus.py:300 aleksis/core/models.py:460
+#: aleksis/core/menus.py:298 aleksis/core/models.py:462
 #: aleksis/core/templates/core/additional_field/list.html:8
 #: aleksis/core/templates/core/additional_field/list.html:9
 msgid "Additional fields"
 msgstr ""
 
-#: aleksis/core/menus.py:315
+#: aleksis/core/menus.py:309
+msgid "Invite person"
+msgstr ""
+
+#: aleksis/core/menus.py:322
 #: aleksis/core/templates/core/group/child_groups.html:7
 #: aleksis/core/templates/core/group/child_groups.html:9
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:508
+#: aleksis/core/mixins.py:511
 msgid "Linked school term"
 msgstr ""
 
-#: aleksis/core/models.py:66
+#: aleksis/core/models.py:70
 msgid "Boolean (Yes/No)"
 msgstr ""
 
-#: aleksis/core/models.py:67
+#: aleksis/core/models.py:71
 msgid "Text (one line)"
 msgstr ""
 
-#: aleksis/core/models.py:69
+#: aleksis/core/models.py:73
 msgid "Date and time"
 msgstr ""
 
-#: aleksis/core/models.py:70
+#: aleksis/core/models.py:74
 msgid "Decimal number"
 msgstr ""
 
-#: aleksis/core/models.py:71 aleksis/core/models.py:194
+#: aleksis/core/models.py:75 aleksis/core/models.py:198
 msgid "E-mail address"
 msgstr ""
 
-#: aleksis/core/models.py:72
+#: aleksis/core/models.py:76
 msgid "Integer"
 msgstr ""
 
-#: aleksis/core/models.py:73
+#: aleksis/core/models.py:77
 msgid "IP address"
 msgstr ""
 
-#: aleksis/core/models.py:74
+#: aleksis/core/models.py:78
 msgid "Boolean or empty (Yes/No/Neither)"
 msgstr ""
 
-#: aleksis/core/models.py:75
+#: aleksis/core/models.py:79
 msgid "Text (multi-line)"
 msgstr ""
 
-#: aleksis/core/models.py:77
+#: aleksis/core/models.py:81
 msgid "URL / Link"
 msgstr ""
 
-#: aleksis/core/models.py:89 aleksis/core/models.py:948
+#: aleksis/core/models.py:93 aleksis/core/models.py:950
 msgid "Name"
 msgstr ""
 
-#: aleksis/core/models.py:91
+#: aleksis/core/models.py:95
 msgid "Start date"
 msgstr ""
 
-#: aleksis/core/models.py:92
+#: aleksis/core/models.py:96
 msgid "End date"
 msgstr ""
 
-#: aleksis/core/models.py:111
+#: aleksis/core/models.py:115
 msgid "The start date must be earlier than the end date."
 msgstr ""
 
-#: aleksis/core/models.py:118
+#: aleksis/core/models.py:122
 msgid "There is already a school term for this time or a part of this time."
 msgstr ""
 
-#: aleksis/core/models.py:147 aleksis/core/models.py:897
+#: aleksis/core/models.py:151 aleksis/core/models.py:899
 msgid "Person"
 msgstr ""
 
-#: aleksis/core/models.py:150
+#: aleksis/core/models.py:154
 msgid "Can view address"
 msgstr ""
 
-#: aleksis/core/models.py:151
+#: aleksis/core/models.py:155
 msgid "Can view contact details"
 msgstr ""
 
-#: aleksis/core/models.py:152
+#: aleksis/core/models.py:156
 msgid "Can view photo"
 msgstr ""
 
-#: aleksis/core/models.py:153
+#: aleksis/core/models.py:157
 msgid "Can view persons groups"
 msgstr ""
 
-#: aleksis/core/models.py:154
+#: aleksis/core/models.py:158
 msgid "Can view personal details"
 msgstr ""
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "female"
 msgstr ""
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "male"
 msgstr ""
 
-#: aleksis/core/models.py:172
+#: aleksis/core/models.py:176 aleksis/core/models.py:1144
 msgid "Linked user"
 msgstr ""
 
-#: aleksis/core/models.py:174
+#: aleksis/core/models.py:178
 msgid "Is person active?"
 msgstr ""
 
-#: aleksis/core/models.py:176
+#: aleksis/core/models.py:180
 msgid "First name"
 msgstr ""
 
-#: aleksis/core/models.py:177
+#: aleksis/core/models.py:181
 msgid "Last name"
 msgstr ""
 
-#: aleksis/core/models.py:179
+#: aleksis/core/models.py:183
 msgid "Additional name(s)"
 msgstr ""
 
-#: aleksis/core/models.py:183 aleksis/core/models.py:429
+#: aleksis/core/models.py:187 aleksis/core/models.py:431
 msgid "Short name"
 msgstr ""
 
-#: aleksis/core/models.py:186
+#: aleksis/core/models.py:190
 msgid "Street"
 msgstr ""
 
-#: aleksis/core/models.py:187
+#: aleksis/core/models.py:191
 msgid "Street number"
 msgstr ""
 
-#: aleksis/core/models.py:188
+#: aleksis/core/models.py:192
 msgid "Postal code"
 msgstr ""
 
-#: aleksis/core/models.py:189
+#: aleksis/core/models.py:193
 msgid "Place"
 msgstr ""
 
-#: aleksis/core/models.py:191
+#: aleksis/core/models.py:195
 msgid "Home phone"
 msgstr ""
 
-#: aleksis/core/models.py:192
+#: aleksis/core/models.py:196
 msgid "Mobile phone"
 msgstr ""
 
-#: aleksis/core/models.py:196
+#: aleksis/core/models.py:200
 msgid "Date of birth"
 msgstr ""
 
-#: aleksis/core/models.py:198
+#: aleksis/core/models.py:201
 msgid "Place of birth"
 msgstr ""
 
-#: aleksis/core/models.py:200
+#: aleksis/core/models.py:202
 msgid "Sex"
 msgstr ""
 
-#: aleksis/core/models.py:202
+#: aleksis/core/models.py:204
 msgid "Photo"
 msgstr ""
 
-#: aleksis/core/models.py:206 aleksis/core/templates/core/person/full.html:138
+#: aleksis/core/models.py:208 aleksis/core/templates/core/person/full.html:145
 msgid "Guardians / Parents"
 msgstr ""
 
-#: aleksis/core/models.py:213
+#: aleksis/core/models.py:215
 msgid "Primary group"
 msgstr ""
 
-#: aleksis/core/models.py:216 aleksis/core/models.py:583
-#: aleksis/core/models.py:607 aleksis/core/models.py:692
-#: aleksis/core/models.py:972 aleksis/core/templates/core/person/full.html:121
+#: aleksis/core/models.py:218 aleksis/core/models.py:585
+#: aleksis/core/models.py:609 aleksis/core/models.py:694
+#: aleksis/core/models.py:974 aleksis/core/templates/core/person/full.html:128
 msgid "Description"
 msgstr ""
 
-#: aleksis/core/models.py:384
+#: aleksis/core/models.py:386
 msgid "Title of field"
 msgstr ""
 
-#: aleksis/core/models.py:386
+#: aleksis/core/models.py:388
 msgid "Type of field"
 msgstr ""
 
-#: aleksis/core/models.py:393
+#: aleksis/core/models.py:395
 msgid "Addtitional field for groups"
 msgstr ""
 
-#: aleksis/core/models.py:394
+#: aleksis/core/models.py:396
 msgid "Addtitional fields for groups"
 msgstr ""
 
-#: aleksis/core/models.py:414
+#: aleksis/core/models.py:416
 msgid "Can assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/models.py:415
+#: aleksis/core/models.py:417
 msgid "Can view statistics about group."
 msgstr ""
 
-#: aleksis/core/models.py:427
+#: aleksis/core/models.py:429
 msgid "Long name"
 msgstr ""
 
-#: aleksis/core/models.py:437 aleksis/core/templates/core/group/full.html:85
+#: aleksis/core/models.py:439 aleksis/core/templates/core/group/full.html:85
 msgid "Members"
 msgstr ""
 
-#: aleksis/core/models.py:440 aleksis/core/templates/core/group/full.html:82
+#: aleksis/core/models.py:442 aleksis/core/templates/core/group/full.html:82
 msgid "Owners"
 msgstr ""
 
-#: aleksis/core/models.py:447 aleksis/core/templates/core/group/full.html:55
+#: aleksis/core/models.py:449 aleksis/core/templates/core/group/full.html:55
 msgid "Parent groups"
 msgstr ""
 
-#: aleksis/core/models.py:455
+#: aleksis/core/models.py:457
 msgid "Type of group"
 msgstr ""
 
-#: aleksis/core/models.py:582 aleksis/core/models.py:606
-#: aleksis/core/models.py:691
+#: aleksis/core/models.py:584 aleksis/core/models.py:608
+#: aleksis/core/models.py:693
 #: aleksis/core/templates/core/announcement/list.html:18
 msgid "Title"
 msgstr ""
 
-#: aleksis/core/models.py:585
+#: aleksis/core/models.py:587
 msgid "Application"
 msgstr ""
 
-#: aleksis/core/models.py:591
+#: aleksis/core/models.py:593
 msgid "Activity"
 msgstr ""
 
-#: aleksis/core/models.py:592
+#: aleksis/core/models.py:594
 msgid "Activities"
 msgstr ""
 
-#: aleksis/core/models.py:598
+#: aleksis/core/models.py:600
 msgid "Sender"
 msgstr ""
 
-#: aleksis/core/models.py:603
+#: aleksis/core/models.py:605
 msgid "Recipient"
 msgstr ""
 
-#: aleksis/core/models.py:608 aleksis/core/models.py:949
+#: aleksis/core/models.py:610 aleksis/core/models.py:951
 msgid "Link"
 msgstr ""
 
-#: aleksis/core/models.py:610
+#: aleksis/core/models.py:612
 msgid "Read"
 msgstr ""
 
-#: aleksis/core/models.py:611
+#: aleksis/core/models.py:613
 msgid "Sent"
 msgstr ""
 
-#: aleksis/core/models.py:624
+#: aleksis/core/models.py:626
 msgid "Notification"
 msgstr ""
 
-#: aleksis/core/models.py:693
+#: aleksis/core/models.py:695
 msgid "Link to detailed view"
 msgstr ""
 
-#: aleksis/core/models.py:696
+#: aleksis/core/models.py:698
 msgid "Date and time from when to show"
 msgstr ""
 
-#: aleksis/core/models.py:699
+#: aleksis/core/models.py:701
 msgid "Date and time until when to show"
 msgstr ""
 
-#: aleksis/core/models.py:724
+#: aleksis/core/models.py:726
 msgid "Announcement"
 msgstr ""
 
-#: aleksis/core/models.py:762
+#: aleksis/core/models.py:764
 msgid "Announcement recipient"
 msgstr ""
 
-#: aleksis/core/models.py:763
+#: aleksis/core/models.py:765
 msgid "Announcement recipients"
 msgstr ""
 
-#: aleksis/core/models.py:818
+#: aleksis/core/models.py:820
 msgid "Widget Title"
 msgstr ""
 
-#: aleksis/core/models.py:819
+#: aleksis/core/models.py:821
 msgid "Activate Widget"
 msgstr ""
 
-#: aleksis/core/models.py:820
+#: aleksis/core/models.py:822
 msgid "Widget is broken"
 msgstr ""
 
-#: aleksis/core/models.py:823
+#: aleksis/core/models.py:825
 msgid "Size on mobile devices"
 msgstr ""
 
-#: aleksis/core/models.py:824
+#: aleksis/core/models.py:826
 msgid "<= 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:829
+#: aleksis/core/models.py:831
 msgid "Size on tablet devices"
 msgstr ""
 
-#: aleksis/core/models.py:830
+#: aleksis/core/models.py:832
 msgid "> 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:835
+#: aleksis/core/models.py:837
 msgid "Size on desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:836
+#: aleksis/core/models.py:838
 msgid "> 992 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:841
+#: aleksis/core/models.py:843
 msgid "Size on large desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:842
+#: aleksis/core/models.py:844
 msgid "> 1200 px>, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:873
+#: aleksis/core/models.py:875
 msgid "Can edit default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:874
+#: aleksis/core/models.py:876
 msgid "Dashboard Widget"
 msgstr ""
 
-#: aleksis/core/models.py:875
+#: aleksis/core/models.py:877
 msgid "Dashboard Widgets"
 msgstr ""
 
-#: aleksis/core/models.py:881
+#: aleksis/core/models.py:883
 msgid "URL"
 msgstr ""
 
-#: aleksis/core/models.py:882
+#: aleksis/core/models.py:884
 msgid "Icon URL"
 msgstr ""
 
-#: aleksis/core/models.py:888
+#: aleksis/core/models.py:890
 msgid "External link widget"
 msgstr ""
 
-#: aleksis/core/models.py:889
+#: aleksis/core/models.py:891
 msgid "External link widgets"
 msgstr ""
 
-#: aleksis/core/models.py:894
+#: aleksis/core/models.py:896
 msgid "Dashboard widget"
 msgstr ""
 
-#: aleksis/core/models.py:899
+#: aleksis/core/models.py:901
 msgid "Order"
 msgstr ""
 
-#: aleksis/core/models.py:900
+#: aleksis/core/models.py:902
 msgid "Part of the default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:915
+#: aleksis/core/models.py:917
 msgid "Dashboard widget order"
 msgstr ""
 
-#: aleksis/core/models.py:916
+#: aleksis/core/models.py:918
 msgid "Dashboard widget orders"
 msgstr ""
 
-#: aleksis/core/models.py:922
+#: aleksis/core/models.py:924
 msgid "Menu ID"
 msgstr ""
 
-#: aleksis/core/models.py:935
+#: aleksis/core/models.py:937
 msgid "Custom menu"
 msgstr ""
 
-#: aleksis/core/models.py:936
+#: aleksis/core/models.py:938
 msgid "Custom menus"
 msgstr ""
 
-#: aleksis/core/models.py:946
+#: aleksis/core/models.py:948
 msgid "Menu"
 msgstr ""
 
-#: aleksis/core/models.py:950
+#: aleksis/core/models.py:952
 msgid "Icon"
 msgstr ""
 
-#: aleksis/core/models.py:956
+#: aleksis/core/models.py:958
 msgid "Custom menu item"
 msgstr ""
 
-#: aleksis/core/models.py:957
+#: aleksis/core/models.py:959
 msgid "Custom menu items"
 msgstr ""
 
-#: aleksis/core/models.py:971
+#: aleksis/core/models.py:973
 msgid "Title of type"
 msgstr ""
 
-#: aleksis/core/models.py:978 aleksis/core/templates/core/group/full.html:47
+#: aleksis/core/models.py:980 aleksis/core/templates/core/group/full.html:47
 msgid "Group type"
 msgstr ""
 
-#: aleksis/core/models.py:992
+#: aleksis/core/models.py:994
 msgid "Can view system status"
 msgstr ""
 
-#: aleksis/core/models.py:993
+#: aleksis/core/models.py:995
 msgid "Can manage data"
 msgstr ""
 
-#: aleksis/core/models.py:994
+#: aleksis/core/models.py:996
 msgid "Can impersonate"
 msgstr ""
 
-#: aleksis/core/models.py:995
+#: aleksis/core/models.py:997
 msgid "Can use search"
 msgstr ""
 
-#: aleksis/core/models.py:996
+#: aleksis/core/models.py:998
 msgid "Can change site preferences"
 msgstr ""
 
-#: aleksis/core/models.py:997
+#: aleksis/core/models.py:999
 msgid "Can change person preferences"
 msgstr ""
 
-#: aleksis/core/models.py:998
+#: aleksis/core/models.py:1000
 msgid "Can change group preferences"
 msgstr ""
 
-#: aleksis/core/models.py:999
+#: aleksis/core/models.py:1001
 msgid "Can test PDF generation"
 msgstr ""
 
-#: aleksis/core/models.py:1035
+#: aleksis/core/models.py:1037
 msgid "Related data check task"
 msgstr ""
 
-#: aleksis/core/models.py:1043
+#: aleksis/core/models.py:1045
 msgid "Issue solved"
 msgstr ""
 
-#: aleksis/core/models.py:1044
+#: aleksis/core/models.py:1046
 msgid "Notification sent"
 msgstr ""
 
-#: aleksis/core/models.py:1057
+#: aleksis/core/models.py:1059
 msgid "Data check result"
 msgstr ""
 
-#: aleksis/core/models.py:1058
+#: aleksis/core/models.py:1060
 msgid "Data check results"
 msgstr ""
 
-#: aleksis/core/models.py:1060
+#: aleksis/core/models.py:1062
 msgid "Can run data checks"
 msgstr ""
 
-#: aleksis/core/models.py:1061
+#: aleksis/core/models.py:1063
 msgid "Can solve data check problems"
 msgstr ""
 
-#: aleksis/core/models.py:1076
+#: aleksis/core/models.py:1070
+msgid "E-Mail address"
+msgstr ""
+
+#: aleksis/core/models.py:1094
 msgid "Owner"
 msgstr ""
 
-#: aleksis/core/models.py:1080
+#: aleksis/core/models.py:1098
 msgid "File expires at"
 msgstr ""
 
-#: aleksis/core/models.py:1082
+#: aleksis/core/models.py:1100
 msgid "Generated HTML file"
 msgstr ""
 
-#: aleksis/core/models.py:1084
+#: aleksis/core/models.py:1102
 msgid "Generated PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1091
+#: aleksis/core/models.py:1109
 msgid "PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1092
+#: aleksis/core/models.py:1110
 msgid "PDF files"
 msgstr ""
 
-#: aleksis/core/models.py:1097
+#: aleksis/core/models.py:1115
 msgid "Task result"
 msgstr ""
 
-#: aleksis/core/models.py:1100
+#: aleksis/core/models.py:1118
 msgid "Task user"
 msgstr ""
 
-#: aleksis/core/models.py:1112
+#: aleksis/core/models.py:1130
 msgid "Task user assignment"
 msgstr ""
 
-#: aleksis/core/models.py:1113
+#: aleksis/core/models.py:1131
 msgid "Task user assignments"
 msgstr ""
 
-#: aleksis/core/models.py:1127
+#: aleksis/core/models.py:1147
+msgid "Additional attributes"
+msgstr ""
+
+#: aleksis/core/models.py:1185
 msgid "Allowed scopes that clients can request"
 msgstr ""
 
-#: aleksis/core/preferences.py:23
+#: aleksis/core/preferences.py:24
 msgid "General"
 msgstr ""
 
-#: aleksis/core/preferences.py:24
+#: aleksis/core/preferences.py:25
 msgid "School"
 msgstr ""
 
-#: aleksis/core/preferences.py:25
+#: aleksis/core/preferences.py:26
 msgid "Theme"
 msgstr ""
 
-#: aleksis/core/preferences.py:26
+#: aleksis/core/preferences.py:27
 msgid "Mail"
 msgstr ""
 
-#: aleksis/core/preferences.py:28
+#: aleksis/core/preferences.py:29
 msgid "Footer"
 msgstr ""
 
-#: aleksis/core/preferences.py:29
+#: aleksis/core/preferences.py:30
 msgid "Accounts"
 msgstr ""
 
-#: aleksis/core/preferences.py:30
+#: aleksis/core/preferences.py:31
 msgid "Authentication"
 msgstr ""
 
-#: aleksis/core/preferences.py:31
+#: aleksis/core/preferences.py:32
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:42
+#: aleksis/core/preferences.py:43
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:53
+#: aleksis/core/preferences.py:54
 msgid "Site description"
 msgstr ""
 
-#: aleksis/core/preferences.py:64
+#: aleksis/core/preferences.py:65
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:77
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:87
+#: aleksis/core/preferences.py:88
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:97
+#: aleksis/core/preferences.py:98
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:107
+#: aleksis/core/preferences.py:108
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:118
+#: aleksis/core/preferences.py:119
 msgid "Mail out name"
 msgstr ""
 
-#: aleksis/core/preferences.py:129
+#: aleksis/core/preferences.py:130
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:141
+#: aleksis/core/preferences.py:142
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:153
+#: aleksis/core/preferences.py:154
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:165
+#: aleksis/core/preferences.py:166
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:181
+#: aleksis/core/preferences.py:182
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:193
+#: aleksis/core/preferences.py:194
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:204
+#: aleksis/core/preferences.py:205
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:216
+#: aleksis/core/preferences.py:217
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:225
+#: aleksis/core/preferences.py:226
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:236
+#: aleksis/core/preferences.py:237
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:247
+#: aleksis/core/preferences.py:248
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:255
+#: aleksis/core/preferences.py:256
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:263
+#: aleksis/core/preferences.py:264
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:274
+#: aleksis/core/preferences.py:272
+msgid "Enable invitations"
+msgstr ""
+
+#: aleksis/core/preferences.py:280
+msgid "Length of invite code. (Default 3: abcde-acbde-abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:288
+msgid "Size of packets. (Default 5: abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:298
 msgid "Allowed Grant Flows for OAuth applications"
 msgstr ""
 
-#: aleksis/core/preferences.py:287
+#: aleksis/core/preferences.py:311
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:299
+#: aleksis/core/preferences.py:323
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:310
+#: aleksis/core/preferences.py:334
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:321
+#: aleksis/core/preferences.py:345
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:330
+#: aleksis/core/preferences.py:354
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:339
+#: aleksis/core/preferences.py:363
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:350
+#: aleksis/core/preferences.py:374
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:364
+#: aleksis/core/preferences.py:388
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:377
+#: aleksis/core/preferences.py:401
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:387
+#: aleksis/core/preferences.py:411
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:388
+#: aleksis/core/preferences.py:412
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/preferences.py:398
+#: aleksis/core/preferences.py:422
 msgid "Automatically update the dashboard and its widgets"
 msgstr ""
 
-#: aleksis/core/preferences.py:408
+#: aleksis/core/preferences.py:432
 msgid "Automatically update the dashboard and its widgets sitewide"
 msgstr ""
 
-#: aleksis/core/settings.py:482
+#: aleksis/core/settings.py:507
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:483
+#: aleksis/core/settings.py:508
 msgid "German"
 msgstr ""
 
-#: aleksis/core/tables.py:19
+#: aleksis/core/tables.py:24
 #: aleksis/core/templates/core/announcement/list.html:36
 #: aleksis/core/templates/core/group/full.html:24
-#: aleksis/core/templates/core/person/full.html:23
+#: aleksis/core/templates/core/person/full.html:24
 #: aleksis/core/templates/oauth2_provider/application/detail.html:17
 msgid "Edit"
 msgstr ""
 
-#: aleksis/core/tables.py:21 aleksis/core/tables.py:89
-#: aleksis/core/tables.py:105
+#: aleksis/core/tables.py:26 aleksis/core/tables.py:94
+#: aleksis/core/tables.py:137
 #: aleksis/core/templates/core/announcement/list.html:22
 msgid "Actions"
 msgstr ""
 
-#: aleksis/core/tables.py:56 aleksis/core/tables.py:57
-#: aleksis/core/tables.py:71 aleksis/core/tables.py:87
-#: aleksis/core/tables.py:103
+#: aleksis/core/tables.py:61 aleksis/core/tables.py:62
+#: aleksis/core/tables.py:76 aleksis/core/tables.py:92
+#: aleksis/core/tables.py:135
 #: aleksis/core/templates/core/announcement/list.html:42
 #: aleksis/core/templates/core/group/full.html:31
 #: aleksis/core/templates/core/pages/delete.html:22
-#: aleksis/core/templates/core/person/full.html:30
+#: aleksis/core/templates/core/person/full.html:31
 #: aleksis/core/templates/oauth2_provider/application/detail.html:21
 msgid "Delete"
 msgstr ""
@@ -1203,11 +1226,11 @@ msgstr ""
 msgid "Account inactive"
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:13
+#: aleksis/core/templates/account/account_inactive.html:14
 msgid "Account inactive."
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:15
+#: aleksis/core/templates/account/account_inactive.html:17
 msgid ""
 "\n"
 "            This account is currently inactive. If you think this is an\n"
@@ -1359,11 +1382,11 @@ msgstr ""
 msgid "Signup closed"
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:13
+#: aleksis/core/templates/account/signup_closed.html:14
 msgid "Signup closed."
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:15
+#: aleksis/core/templates/account/signup_closed.html:17
 msgid ""
 "\n"
 "            This sign up is currently closed. If you think this is an\n"
@@ -1401,11 +1424,6 @@ msgid ""
 "          "
 msgstr ""
 
-#: 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 ""
-
 #: aleksis/core/templates/core/additional_field/edit.html:6
 #: aleksis/core/templates/core/additional_field/edit.html:7
 msgid "Edit additional field"
@@ -1458,7 +1476,7 @@ msgid "About AlekSIS® — The Free School Information System"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:183
-msgid "Impress"
+msgid "Imprint"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:191
@@ -1681,7 +1699,7 @@ msgid "Edit group"
 msgstr ""
 
 #: aleksis/core/templates/core/group/full.html:38
-#: aleksis/core/templates/core/person/full.html:37
+#: aleksis/core/templates/core/person/full.html:38
 msgid "Change preferences"
 msgstr ""
 
@@ -2075,17 +2093,19 @@ msgstr ""
 msgid "Edit person"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:44
-#: aleksis/core/templates/impersonate/list_users.html:7
-#: aleksis/core/templates/impersonate/list_users.html:8
+#: aleksis/core/templates/core/person/full.html:45
 msgid "Impersonate"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:50
+#: aleksis/core/templates/core/person/full.html:51
+msgid "Invite user"
+msgstr ""
+
+#: aleksis/core/templates/core/person/full.html:57
 msgid "Contact details"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:131
+#: aleksis/core/templates/core/person/full.html:138
 msgid "Children"
 msgstr ""
 
@@ -2125,6 +2145,49 @@ msgstr ""
 msgid "Save preferences"
 msgstr ""
 
+#: aleksis/core/templates/invitations/enter.html:21
+msgid "Accept your invitation"
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:25
+msgid ""
+"\n"
+"                Please enter your invitation code to register\n"
+"                your new user account:\n"
+"              "
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:37
+msgid "Accept invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:9
+#: aleksis/core/templates/invitations/forms/_invite.html:10
+#: aleksis/core/templates/invitations/forms/_invite.html:21
+msgid "Invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:17
+msgid "Invite by email address"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:26
+msgid "Generate invitation code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:29
+msgid "Generate code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:33
+msgid "Invitations"
+msgstr ""
+
+#: aleksis/core/templates/invitations/messages/invite_accepted.txt:3
+#, python-format
+msgid "The invitation for %(email)s has been accepted."
+msgstr ""
+
 #: aleksis/core/templates/oauth2_provider/application/create.html:5
 #: aleksis/core/templates/oauth2_provider/application/create.html:6
 msgid "Register OAuth2 Application"
@@ -2801,130 +2864,143 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:270
+#: aleksis/core/views.py:280
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:282
+#: aleksis/core/views.py:292
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:406
+#: aleksis/core/views.py:416
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:425 aleksis/core/views.py:435
+#: aleksis/core/views.py:435 aleksis/core/views.py:445
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:485
+#: aleksis/core/views.py:495
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:582
+#: aleksis/core/views.py:592
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:598
+#: aleksis/core/views.py:608
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:682
+#: aleksis/core/views.py:695
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:706
+#: aleksis/core/views.py:719
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:720
+#: aleksis/core/views.py:733
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:752
+#: aleksis/core/views.py:765
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:786
+#: aleksis/core/views.py:799
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:811
+#: aleksis/core/views.py:824
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:854
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:874
+#: aleksis/core/views.py:887
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:875
+#: aleksis/core/views.py:888
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:876
+#: aleksis/core/views.py:889
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:877
+#: aleksis/core/views.py:890
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:893
+#: aleksis/core/views.py:906
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:935
+#: aleksis/core/views.py:948
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:965
+#: aleksis/core/views.py:978
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:975
+#: aleksis/core/views.py:988
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1042
+#: aleksis/core/views.py:1055
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1044
+#: aleksis/core/views.py:1057
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1139
+#: aleksis/core/views.py:1127
+#, python-brace-format
+msgid "The invitation was successfully created. The invitation code is {code}"
+msgstr ""
+
+#: aleksis/core/views.py:1218
 msgid "We have successfully assigned the permissions."
 msgstr ""
 
-#: aleksis/core/views.py:1149
+#: aleksis/core/views.py:1228
 msgid "The global user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1159
+#: aleksis/core/views.py:1238
 msgid "The global group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1169
+#: aleksis/core/views.py:1248
 msgid "The object user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1179
+#: aleksis/core/views.py:1258
 msgid "The object group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1298
+#: aleksis/core/views.py:1377
 msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1305
+#: aleksis/core/views.py:1384
 msgid "The third-party account has been successfully disconnected."
 msgstr ""
 
+#: aleksis/core/views.py:1441
+msgid "Person was invited successfully."
+msgstr ""
+
+#: aleksis/core/views.py:1443
+msgid "Person was already invited."
+msgstr ""
+
 #~ msgid "Norwegian (bokmål)"
 #~ msgstr "Norsk (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 42571d39e1fdfd5750cf094335d8718cd90c2cde..d67bdb0055bf1ee96915909ce9e21023085c466b 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:14+0100\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:127
+#: aleksis/core/static/js/main.js:128
 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 5212d35ee30deb157c488b57c94113b6d002422a..1738a0918a91e64c2eb5421ef10b70dac77a6b90 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:13+0100\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"
@@ -37,10 +37,10 @@ msgstr ""
 msgid "Home and mobile phone"
 msgstr ""
 
-#: aleksis/core/apps.py:157 aleksis/core/forms.py:222 aleksis/core/menus.py:267
-#: aleksis/core/models.py:412 aleksis/core/templates/core/group/list.html:8
+#: aleksis/core/apps.py:157 aleksis/core/forms.py:223 aleksis/core/menus.py:265
+#: aleksis/core/models.py:414 aleksis/core/templates/core/group/list.html:8
 #: aleksis/core/templates/core/group/list.html:9
-#: aleksis/core/templates/core/person/full.html:145
+#: aleksis/core/templates/core/person/full.html:152
 msgid "Groups"
 msgstr ""
 
@@ -90,149 +90,148 @@ msgstr ""
 msgid "Content type"
 msgstr ""
 
-#: aleksis/core/filters.py:112 aleksis/core/models.py:579
+#: aleksis/core/filters.py:112 aleksis/core/models.py:581
 msgid "User"
 msgstr ""
 
-#: aleksis/core/filters.py:134 aleksis/core/models.py:411
+#: aleksis/core/filters.py:134 aleksis/core/models.py:413
 msgid "Group"
 msgstr ""
 
-#: aleksis/core/forms.py:47 aleksis/core/forms.py:521
+#: aleksis/core/forms.py:48 aleksis/core/forms.py:559
 msgid "Base data"
 msgstr ""
 
-#: aleksis/core/forms.py:53
+#: aleksis/core/forms.py:54
 msgid "Address"
 msgstr ""
 
-#: aleksis/core/forms.py:54
+#: aleksis/core/forms.py:55 aleksis/core/forms.py:568
 msgid "Contact data"
 msgstr ""
 
-#: aleksis/core/forms.py:56
+#: aleksis/core/forms.py:57
 msgid "Advanced personal data"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "New user"
 msgstr ""
 
-#: aleksis/core/forms.py:104
+#: aleksis/core/forms.py:105
 msgid "Create a new account"
 msgstr ""
 
-#: aleksis/core/forms.py:135
+#: aleksis/core/forms.py:136
 msgid "You cannot set a new username when also selecting an existing user."
 msgstr ""
 
-#: aleksis/core/forms.py:139
+#: aleksis/core/forms.py:140
 msgid "This username is already in use."
 msgstr ""
 
-#: aleksis/core/forms.py:156 aleksis/core/models.py:125
+#: aleksis/core/forms.py:157 aleksis/core/models.py:129
 msgid "School term"
 msgstr ""
 
-#: aleksis/core/forms.py:157
+#: aleksis/core/forms.py:158
 msgid "Common data"
 msgstr ""
 
-#: aleksis/core/forms.py:158 aleksis/core/forms.py:209
-#: aleksis/core/menus.py:256 aleksis/core/models.py:148
+#: aleksis/core/forms.py:159 aleksis/core/forms.py:210
+#: aleksis/core/menus.py:254 aleksis/core/models.py:152
 #: aleksis/core/templates/core/person/list.html:8
 #: aleksis/core/templates/core/person/list.html:9
 msgid "Persons"
 msgstr ""
 
-#: aleksis/core/forms.py:159
+#: aleksis/core/forms.py:160 aleksis/core/forms.py:570
 msgid "Additional data"
 msgstr ""
 
-#: aleksis/core/forms.py:201 aleksis/core/forms.py:204
-#: aleksis/core/models.py:68
+#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
+#: aleksis/core/models.py:72
 msgid "Date"
 msgstr ""
 
-#: aleksis/core/forms.py:202 aleksis/core/forms.py:205
-#: aleksis/core/models.py:76
+#: aleksis/core/forms.py:203 aleksis/core/forms.py:206
+#: aleksis/core/models.py:80
 msgid "Time"
 msgstr ""
 
-#: aleksis/core/forms.py:235
+#: aleksis/core/forms.py:236
 msgid "From when until when should the announcement be displayed?"
 msgstr ""
 
-#: aleksis/core/forms.py:238
+#: aleksis/core/forms.py:239
 msgid "Who should see the announcement?"
 msgstr ""
 
-#: aleksis/core/forms.py:239
+#: aleksis/core/forms.py:240
 msgid "Write your announcement:"
 msgstr ""
 
-#: aleksis/core/forms.py:278
+#: aleksis/core/forms.py:279
 msgid "You are not allowed to create announcements which are only valid in the past."
 msgstr ""
 
-#: aleksis/core/forms.py:282
+#: aleksis/core/forms.py:283
 msgid "The from date and time must be earlier then the until date and time."
 msgstr ""
 
-#: aleksis/core/forms.py:291
+#: aleksis/core/forms.py:292
 msgid "You need at least one recipient."
 msgstr ""
 
-#: aleksis/core/forms.py:412
+#: aleksis/core/forms.py:401
+msgid "Invitation code"
+msgstr ""
+
+#: aleksis/core/forms.py:402
+msgid "Please enter your invitation code."
+msgstr ""
+
+#: aleksis/core/forms.py:434
 msgid "Who should get the permission?"
 msgstr ""
 
-#: aleksis/core/forms.py:413
+#: aleksis/core/forms.py:435
 msgid "On what?"
 msgstr ""
 
-#: aleksis/core/forms.py:439
+#: aleksis/core/forms.py:461
 msgid "Select objects which the permission should be granted for:"
 msgstr ""
 
-#: aleksis/core/forms.py:442
+#: aleksis/core/forms.py:464
 msgid "Grant the permission for all objects"
 msgstr ""
 
-#: aleksis/core/forms.py:450
+#: aleksis/core/forms.py:472
 msgid "You must select at least one group or person which should get the permission."
 msgstr ""
 
-#: aleksis/core/forms.py:455
+#: aleksis/core/forms.py:477
 msgid "You must grant the permission to all objects and/or to some objects."
 msgstr ""
 
-#: aleksis/core/forms.py:525
-msgid "Account data"
+#: aleksis/core/forms.py:564
+msgid "Adress data"
 msgstr ""
 
-#: aleksis/core/forms.py:531
-msgid "Consents"
+#: aleksis/core/forms.py:576
+msgid "Account data"
 msgstr ""
 
-#: aleksis/core/forms.py:538
+#: aleksis/core/forms.py:583
 msgid "Password"
 msgstr ""
 
-#: aleksis/core/forms.py:544
+#: aleksis/core/forms.py:586
 msgid "Password (again)"
 msgstr ""
 
-#: aleksis/core/forms.py:557
-#, python-brace-format
-msgid "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree with them."
-msgstr ""
-
-#: aleksis/core/forms.py:582
-msgid "You must type the same password each time."
-msgstr ""
-
-#: aleksis/core/forms.py:727
+#: aleksis/core/forms.py:752
 msgid "No valid selection."
 msgstr ""
 
@@ -269,34 +268,38 @@ msgstr ""
 msgid "Sign up"
 msgstr ""
 
-#: aleksis/core/menus.py:24
+#: aleksis/core/menus.py:24 aleksis/core/templates/invitations/enter.html:7
+msgid "Accept invitation"
+msgstr ""
+
+#: aleksis/core/menus.py:33
 msgid "Dashboard"
 msgstr ""
 
-#: aleksis/core/menus.py:32 aleksis/core/models.py:625
-#: aleksis/core/preferences.py:27
+#: aleksis/core/menus.py:41 aleksis/core/models.py:627
+#: aleksis/core/preferences.py:28
 #: aleksis/core/templates/core/notifications.html:4
 #: aleksis/core/templates/core/notifications.html:5
 msgid "Notifications"
 msgstr ""
 
-#: aleksis/core/menus.py:44
+#: aleksis/core/menus.py:53
 msgid "Account"
 msgstr ""
 
-#: aleksis/core/menus.py:51
+#: aleksis/core/menus.py:60
 msgid "Stop impersonation"
 msgstr ""
 
-#: aleksis/core/menus.py:60 aleksis/core/templates/core/base.html:80
+#: aleksis/core/menus.py:69 aleksis/core/templates/core/base.html:80
 msgid "Logout"
 msgstr ""
 
-#: aleksis/core/menus.py:66
+#: aleksis/core/menus.py:75
 msgid "2FA"
 msgstr ""
 
-#: aleksis/core/menus.py:74
+#: aleksis/core/menus.py:83
 #: aleksis/core/templates/account/password_change.html:5
 #: aleksis/core/templates/account/password_change.html:6
 #: aleksis/core/templates/account/password_change.html:19
@@ -308,830 +311,850 @@ msgstr ""
 msgid "Change password"
 msgstr ""
 
-#: aleksis/core/menus.py:86
+#: aleksis/core/menus.py:95
 msgid "Me"
 msgstr ""
 
-#: aleksis/core/menus.py:95
+#: aleksis/core/menus.py:104
 #: aleksis/core/templates/dynamic_preferences/form.html:5
 msgid "Preferences"
 msgstr ""
 
-#: aleksis/core/menus.py:104
+#: aleksis/core/menus.py:113
 msgid "Third-party accounts"
 msgstr ""
 
-#: aleksis/core/menus.py:113
+#: aleksis/core/menus.py:122
 #: 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:124
+#: aleksis/core/menus.py:133
 msgid "Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:132 aleksis/core/models.py:725
+#: aleksis/core/menus.py:141 aleksis/core/models.py:727
 #: aleksis/core/templates/core/announcement/list.html:7
 #: aleksis/core/templates/core/announcement/list.html:8
 msgid "Announcements"
 msgstr ""
 
-#: aleksis/core/menus.py:143 aleksis/core/models.py:126
+#: aleksis/core/menus.py:152 aleksis/core/models.py:130
 #: aleksis/core/templates/core/school_term/list.html:8
 #: aleksis/core/templates/core/school_term/list.html:9
 msgid "School terms"
 msgstr ""
 
-#: aleksis/core/menus.py:154
+#: aleksis/core/menus.py:163
 #: aleksis/core/templates/core/dashboard_widget/list.html:8
 #: aleksis/core/templates/core/dashboard_widget/list.html:9
 msgid "Dashboard widgets"
 msgstr ""
 
-#: aleksis/core/menus.py:165
+#: aleksis/core/menus.py:174
 #: aleksis/core/templates/core/management/data_management.html:6
 #: aleksis/core/templates/core/management/data_management.html:7
 msgid "Data management"
 msgstr ""
 
-#: aleksis/core/menus.py:176
+#: aleksis/core/menus.py:185
 #: aleksis/core/templates/core/pages/system_status.html:5
 #: aleksis/core/templates/core/pages/system_status.html:7
 msgid "System status"
 msgstr ""
 
-#: aleksis/core/menus.py:187
-msgid "Impersonation"
-msgstr ""
-
-#: aleksis/core/menus.py:198
+#: aleksis/core/menus.py:196
 msgid "Configuration"
 msgstr ""
 
-#: aleksis/core/menus.py:209 aleksis/core/templates/core/data_check/list.html:9
+#: aleksis/core/menus.py:207 aleksis/core/templates/core/data_check/list.html:9
 #: aleksis/core/templates/core/data_check/list.html:10
 msgid "Data checks"
 msgstr ""
 
-#: aleksis/core/menus.py:215 aleksis/core/templates/core/perms/list.html:13
+#: aleksis/core/menus.py:213 aleksis/core/templates/core/perms/list.html:13
 #: aleksis/core/templates/core/perms/list.html:14
 msgid "Manage permissions"
 msgstr ""
 
-#: aleksis/core/menus.py:226
+#: aleksis/core/menus.py:224
 msgid "Backend Admin"
 msgstr ""
 
-#: aleksis/core/menus.py:234
+#: aleksis/core/menus.py:232
 #: aleksis/core/templates/oauth2_provider/application/list.html:5
 #: aleksis/core/templates/oauth2_provider/application/list.html:6
 msgid "OAuth2 Applications"
 msgstr ""
 
-#: aleksis/core/menus.py:247
+#: aleksis/core/menus.py:245
 msgid "People"
 msgstr ""
 
-#: aleksis/core/menus.py:278 aleksis/core/models.py:979
+#: aleksis/core/menus.py:276 aleksis/core/models.py:981
 #: aleksis/core/templates/core/group_type/list.html:8
 #: aleksis/core/templates/core/group_type/list.html:9
 msgid "Group types"
 msgstr ""
 
-#: aleksis/core/menus.py:289
+#: aleksis/core/menus.py:287
 msgid "Groups and child groups"
 msgstr ""
 
-#: aleksis/core/menus.py:300 aleksis/core/models.py:460
+#: aleksis/core/menus.py:298 aleksis/core/models.py:462
 #: aleksis/core/templates/core/additional_field/list.html:8
 #: aleksis/core/templates/core/additional_field/list.html:9
 msgid "Additional fields"
 msgstr ""
 
-#: aleksis/core/menus.py:315
+#: aleksis/core/menus.py:309
+msgid "Invite person"
+msgstr ""
+
+#: aleksis/core/menus.py:322
 #: aleksis/core/templates/core/group/child_groups.html:7
 #: aleksis/core/templates/core/group/child_groups.html:9
 msgid "Assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/mixins.py:508
+#: aleksis/core/mixins.py:511
 msgid "Linked school term"
 msgstr ""
 
-#: aleksis/core/models.py:66
+#: aleksis/core/models.py:70
 msgid "Boolean (Yes/No)"
 msgstr ""
 
-#: aleksis/core/models.py:67
+#: aleksis/core/models.py:71
 msgid "Text (one line)"
 msgstr ""
 
-#: aleksis/core/models.py:69
+#: aleksis/core/models.py:73
 msgid "Date and time"
 msgstr ""
 
-#: aleksis/core/models.py:70
+#: aleksis/core/models.py:74
 msgid "Decimal number"
 msgstr ""
 
-#: aleksis/core/models.py:71 aleksis/core/models.py:194
+#: aleksis/core/models.py:75 aleksis/core/models.py:198
 msgid "E-mail address"
 msgstr ""
 
-#: aleksis/core/models.py:72
+#: aleksis/core/models.py:76
 msgid "Integer"
 msgstr ""
 
-#: aleksis/core/models.py:73
+#: aleksis/core/models.py:77
 msgid "IP address"
 msgstr ""
 
-#: aleksis/core/models.py:74
+#: aleksis/core/models.py:78
 msgid "Boolean or empty (Yes/No/Neither)"
 msgstr ""
 
-#: aleksis/core/models.py:75
+#: aleksis/core/models.py:79
 msgid "Text (multi-line)"
 msgstr ""
 
-#: aleksis/core/models.py:77
+#: aleksis/core/models.py:81
 msgid "URL / Link"
 msgstr ""
 
-#: aleksis/core/models.py:89 aleksis/core/models.py:948
+#: aleksis/core/models.py:93 aleksis/core/models.py:950
 msgid "Name"
 msgstr ""
 
-#: aleksis/core/models.py:91
+#: aleksis/core/models.py:95
 msgid "Start date"
 msgstr ""
 
-#: aleksis/core/models.py:92
+#: aleksis/core/models.py:96
 msgid "End date"
 msgstr ""
 
-#: aleksis/core/models.py:111
+#: aleksis/core/models.py:115
 msgid "The start date must be earlier than the end date."
 msgstr ""
 
-#: aleksis/core/models.py:118
+#: aleksis/core/models.py:122
 msgid "There is already a school term for this time or a part of this time."
 msgstr ""
 
-#: aleksis/core/models.py:147 aleksis/core/models.py:897
+#: aleksis/core/models.py:151 aleksis/core/models.py:899
 msgid "Person"
 msgstr ""
 
-#: aleksis/core/models.py:150
+#: aleksis/core/models.py:154
 msgid "Can view address"
 msgstr ""
 
-#: aleksis/core/models.py:151
+#: aleksis/core/models.py:155
 msgid "Can view contact details"
 msgstr ""
 
-#: aleksis/core/models.py:152
+#: aleksis/core/models.py:156
 msgid "Can view photo"
 msgstr ""
 
-#: aleksis/core/models.py:153
+#: aleksis/core/models.py:157
 msgid "Can view persons groups"
 msgstr ""
 
-#: aleksis/core/models.py:154
+#: aleksis/core/models.py:158
 msgid "Can view personal details"
 msgstr ""
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "female"
 msgstr ""
 
-#: aleksis/core/models.py:164
+#: aleksis/core/models.py:168
 msgid "male"
 msgstr ""
 
-#: aleksis/core/models.py:172
+#: aleksis/core/models.py:176 aleksis/core/models.py:1144
 msgid "Linked user"
 msgstr ""
 
-#: aleksis/core/models.py:174
+#: aleksis/core/models.py:178
 msgid "Is person active?"
 msgstr ""
 
-#: aleksis/core/models.py:176
+#: aleksis/core/models.py:180
 msgid "First name"
 msgstr ""
 
-#: aleksis/core/models.py:177
+#: aleksis/core/models.py:181
 msgid "Last name"
 msgstr ""
 
-#: aleksis/core/models.py:179
+#: aleksis/core/models.py:183
 msgid "Additional name(s)"
 msgstr ""
 
-#: aleksis/core/models.py:183 aleksis/core/models.py:429
+#: aleksis/core/models.py:187 aleksis/core/models.py:431
 msgid "Short name"
 msgstr ""
 
-#: aleksis/core/models.py:186
+#: aleksis/core/models.py:190
 msgid "Street"
 msgstr ""
 
-#: aleksis/core/models.py:187
+#: aleksis/core/models.py:191
 msgid "Street number"
 msgstr ""
 
-#: aleksis/core/models.py:188
+#: aleksis/core/models.py:192
 msgid "Postal code"
 msgstr ""
 
-#: aleksis/core/models.py:189
+#: aleksis/core/models.py:193
 msgid "Place"
 msgstr ""
 
-#: aleksis/core/models.py:191
+#: aleksis/core/models.py:195
 msgid "Home phone"
 msgstr ""
 
-#: aleksis/core/models.py:192
+#: aleksis/core/models.py:196
 msgid "Mobile phone"
 msgstr ""
 
-#: aleksis/core/models.py:196
+#: aleksis/core/models.py:200
 msgid "Date of birth"
 msgstr ""
 
-#: aleksis/core/models.py:198
+#: aleksis/core/models.py:201
 msgid "Place of birth"
 msgstr ""
 
-#: aleksis/core/models.py:200
+#: aleksis/core/models.py:202
 msgid "Sex"
 msgstr ""
 
-#: aleksis/core/models.py:202
+#: aleksis/core/models.py:204
 msgid "Photo"
 msgstr ""
 
-#: aleksis/core/models.py:206 aleksis/core/templates/core/person/full.html:138
+#: aleksis/core/models.py:208 aleksis/core/templates/core/person/full.html:145
 msgid "Guardians / Parents"
 msgstr ""
 
-#: aleksis/core/models.py:213
+#: aleksis/core/models.py:215
 msgid "Primary group"
 msgstr ""
 
-#: aleksis/core/models.py:216 aleksis/core/models.py:583
-#: aleksis/core/models.py:607 aleksis/core/models.py:692
-#: aleksis/core/models.py:972 aleksis/core/templates/core/person/full.html:121
+#: aleksis/core/models.py:218 aleksis/core/models.py:585
+#: aleksis/core/models.py:609 aleksis/core/models.py:694
+#: aleksis/core/models.py:974 aleksis/core/templates/core/person/full.html:128
 msgid "Description"
 msgstr ""
 
-#: aleksis/core/models.py:384
+#: aleksis/core/models.py:386
 msgid "Title of field"
 msgstr ""
 
-#: aleksis/core/models.py:386
+#: aleksis/core/models.py:388
 msgid "Type of field"
 msgstr ""
 
-#: aleksis/core/models.py:393
+#: aleksis/core/models.py:395
 msgid "Addtitional field for groups"
 msgstr ""
 
-#: aleksis/core/models.py:394
+#: aleksis/core/models.py:396
 msgid "Addtitional fields for groups"
 msgstr ""
 
-#: aleksis/core/models.py:414
+#: aleksis/core/models.py:416
 msgid "Can assign child groups to groups"
 msgstr ""
 
-#: aleksis/core/models.py:415
+#: aleksis/core/models.py:417
 msgid "Can view statistics about group."
 msgstr ""
 
-#: aleksis/core/models.py:427
+#: aleksis/core/models.py:429
 msgid "Long name"
 msgstr ""
 
-#: aleksis/core/models.py:437 aleksis/core/templates/core/group/full.html:85
+#: aleksis/core/models.py:439 aleksis/core/templates/core/group/full.html:85
 msgid "Members"
 msgstr ""
 
-#: aleksis/core/models.py:440 aleksis/core/templates/core/group/full.html:82
+#: aleksis/core/models.py:442 aleksis/core/templates/core/group/full.html:82
 msgid "Owners"
 msgstr ""
 
-#: aleksis/core/models.py:447 aleksis/core/templates/core/group/full.html:55
+#: aleksis/core/models.py:449 aleksis/core/templates/core/group/full.html:55
 msgid "Parent groups"
 msgstr ""
 
-#: aleksis/core/models.py:455
+#: aleksis/core/models.py:457
 msgid "Type of group"
 msgstr ""
 
-#: aleksis/core/models.py:582 aleksis/core/models.py:606
-#: aleksis/core/models.py:691
+#: aleksis/core/models.py:584 aleksis/core/models.py:608
+#: aleksis/core/models.py:693
 #: aleksis/core/templates/core/announcement/list.html:18
 msgid "Title"
 msgstr ""
 
-#: aleksis/core/models.py:585
+#: aleksis/core/models.py:587
 msgid "Application"
 msgstr ""
 
-#: aleksis/core/models.py:591
+#: aleksis/core/models.py:593
 msgid "Activity"
 msgstr ""
 
-#: aleksis/core/models.py:592
+#: aleksis/core/models.py:594
 msgid "Activities"
 msgstr ""
 
-#: aleksis/core/models.py:598
+#: aleksis/core/models.py:600
 msgid "Sender"
 msgstr ""
 
-#: aleksis/core/models.py:603
+#: aleksis/core/models.py:605
 msgid "Recipient"
 msgstr ""
 
-#: aleksis/core/models.py:608 aleksis/core/models.py:949
+#: aleksis/core/models.py:610 aleksis/core/models.py:951
 msgid "Link"
 msgstr ""
 
-#: aleksis/core/models.py:610
+#: aleksis/core/models.py:612
 msgid "Read"
 msgstr ""
 
-#: aleksis/core/models.py:611
+#: aleksis/core/models.py:613
 msgid "Sent"
 msgstr ""
 
-#: aleksis/core/models.py:624
+#: aleksis/core/models.py:626
 msgid "Notification"
 msgstr ""
 
-#: aleksis/core/models.py:693
+#: aleksis/core/models.py:695
 msgid "Link to detailed view"
 msgstr ""
 
-#: aleksis/core/models.py:696
+#: aleksis/core/models.py:698
 msgid "Date and time from when to show"
 msgstr ""
 
-#: aleksis/core/models.py:699
+#: aleksis/core/models.py:701
 msgid "Date and time until when to show"
 msgstr ""
 
-#: aleksis/core/models.py:724
+#: aleksis/core/models.py:726
 msgid "Announcement"
 msgstr ""
 
-#: aleksis/core/models.py:762
+#: aleksis/core/models.py:764
 msgid "Announcement recipient"
 msgstr ""
 
-#: aleksis/core/models.py:763
+#: aleksis/core/models.py:765
 msgid "Announcement recipients"
 msgstr ""
 
-#: aleksis/core/models.py:818
+#: aleksis/core/models.py:820
 msgid "Widget Title"
 msgstr ""
 
-#: aleksis/core/models.py:819
+#: aleksis/core/models.py:821
 msgid "Activate Widget"
 msgstr ""
 
-#: aleksis/core/models.py:820
+#: aleksis/core/models.py:822
 msgid "Widget is broken"
 msgstr ""
 
-#: aleksis/core/models.py:823
+#: aleksis/core/models.py:825
 msgid "Size on mobile devices"
 msgstr ""
 
-#: aleksis/core/models.py:824
+#: aleksis/core/models.py:826
 msgid "<= 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:829
+#: aleksis/core/models.py:831
 msgid "Size on tablet devices"
 msgstr ""
 
-#: aleksis/core/models.py:830
+#: aleksis/core/models.py:832
 msgid "> 600 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:835
+#: aleksis/core/models.py:837
 msgid "Size on desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:836
+#: aleksis/core/models.py:838
 msgid "> 992 px, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:841
+#: aleksis/core/models.py:843
 msgid "Size on large desktop devices"
 msgstr ""
 
-#: aleksis/core/models.py:842
+#: aleksis/core/models.py:844
 msgid "> 1200 px>, 12 columns"
 msgstr ""
 
-#: aleksis/core/models.py:873
+#: aleksis/core/models.py:875
 msgid "Can edit default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:874
+#: aleksis/core/models.py:876
 msgid "Dashboard Widget"
 msgstr ""
 
-#: aleksis/core/models.py:875
+#: aleksis/core/models.py:877
 msgid "Dashboard Widgets"
 msgstr ""
 
-#: aleksis/core/models.py:881
+#: aleksis/core/models.py:883
 msgid "URL"
 msgstr ""
 
-#: aleksis/core/models.py:882
+#: aleksis/core/models.py:884
 msgid "Icon URL"
 msgstr ""
 
-#: aleksis/core/models.py:888
+#: aleksis/core/models.py:890
 msgid "External link widget"
 msgstr ""
 
-#: aleksis/core/models.py:889
+#: aleksis/core/models.py:891
 msgid "External link widgets"
 msgstr ""
 
-#: aleksis/core/models.py:894
+#: aleksis/core/models.py:896
 msgid "Dashboard widget"
 msgstr ""
 
-#: aleksis/core/models.py:899
+#: aleksis/core/models.py:901
 msgid "Order"
 msgstr ""
 
-#: aleksis/core/models.py:900
+#: aleksis/core/models.py:902
 msgid "Part of the default dashboard"
 msgstr ""
 
-#: aleksis/core/models.py:915
+#: aleksis/core/models.py:917
 msgid "Dashboard widget order"
 msgstr ""
 
-#: aleksis/core/models.py:916
+#: aleksis/core/models.py:918
 msgid "Dashboard widget orders"
 msgstr ""
 
-#: aleksis/core/models.py:922
+#: aleksis/core/models.py:924
 msgid "Menu ID"
 msgstr ""
 
-#: aleksis/core/models.py:935
+#: aleksis/core/models.py:937
 msgid "Custom menu"
 msgstr ""
 
-#: aleksis/core/models.py:936
+#: aleksis/core/models.py:938
 msgid "Custom menus"
 msgstr ""
 
-#: aleksis/core/models.py:946
+#: aleksis/core/models.py:948
 msgid "Menu"
 msgstr ""
 
-#: aleksis/core/models.py:950
+#: aleksis/core/models.py:952
 msgid "Icon"
 msgstr ""
 
-#: aleksis/core/models.py:956
+#: aleksis/core/models.py:958
 msgid "Custom menu item"
 msgstr ""
 
-#: aleksis/core/models.py:957
+#: aleksis/core/models.py:959
 msgid "Custom menu items"
 msgstr ""
 
-#: aleksis/core/models.py:971
+#: aleksis/core/models.py:973
 msgid "Title of type"
 msgstr ""
 
-#: aleksis/core/models.py:978 aleksis/core/templates/core/group/full.html:47
+#: aleksis/core/models.py:980 aleksis/core/templates/core/group/full.html:47
 msgid "Group type"
 msgstr ""
 
-#: aleksis/core/models.py:992
+#: aleksis/core/models.py:994
 msgid "Can view system status"
 msgstr ""
 
-#: aleksis/core/models.py:993
+#: aleksis/core/models.py:995
 msgid "Can manage data"
 msgstr ""
 
-#: aleksis/core/models.py:994
+#: aleksis/core/models.py:996
 msgid "Can impersonate"
 msgstr ""
 
-#: aleksis/core/models.py:995
+#: aleksis/core/models.py:997
 msgid "Can use search"
 msgstr ""
 
-#: aleksis/core/models.py:996
+#: aleksis/core/models.py:998
 msgid "Can change site preferences"
 msgstr ""
 
-#: aleksis/core/models.py:997
+#: aleksis/core/models.py:999
 msgid "Can change person preferences"
 msgstr ""
 
-#: aleksis/core/models.py:998
+#: aleksis/core/models.py:1000
 msgid "Can change group preferences"
 msgstr ""
 
-#: aleksis/core/models.py:999
+#: aleksis/core/models.py:1001
 msgid "Can test PDF generation"
 msgstr ""
 
-#: aleksis/core/models.py:1035
+#: aleksis/core/models.py:1037
 msgid "Related data check task"
 msgstr ""
 
-#: aleksis/core/models.py:1043
+#: aleksis/core/models.py:1045
 msgid "Issue solved"
 msgstr ""
 
-#: aleksis/core/models.py:1044
+#: aleksis/core/models.py:1046
 msgid "Notification sent"
 msgstr ""
 
-#: aleksis/core/models.py:1057
+#: aleksis/core/models.py:1059
 msgid "Data check result"
 msgstr ""
 
-#: aleksis/core/models.py:1058
+#: aleksis/core/models.py:1060
 msgid "Data check results"
 msgstr ""
 
-#: aleksis/core/models.py:1060
+#: aleksis/core/models.py:1062
 msgid "Can run data checks"
 msgstr ""
 
-#: aleksis/core/models.py:1061
+#: aleksis/core/models.py:1063
 msgid "Can solve data check problems"
 msgstr ""
 
-#: aleksis/core/models.py:1076
+#: aleksis/core/models.py:1070
+msgid "E-Mail address"
+msgstr ""
+
+#: aleksis/core/models.py:1094
 msgid "Owner"
 msgstr ""
 
-#: aleksis/core/models.py:1080
+#: aleksis/core/models.py:1098
 msgid "File expires at"
 msgstr ""
 
-#: aleksis/core/models.py:1082
+#: aleksis/core/models.py:1100
 msgid "Generated HTML file"
 msgstr ""
 
-#: aleksis/core/models.py:1084
+#: aleksis/core/models.py:1102
 msgid "Generated PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1091
+#: aleksis/core/models.py:1109
 msgid "PDF file"
 msgstr ""
 
-#: aleksis/core/models.py:1092
+#: aleksis/core/models.py:1110
 msgid "PDF files"
 msgstr ""
 
-#: aleksis/core/models.py:1097
+#: aleksis/core/models.py:1115
 msgid "Task result"
 msgstr ""
 
-#: aleksis/core/models.py:1100
+#: aleksis/core/models.py:1118
 msgid "Task user"
 msgstr ""
 
-#: aleksis/core/models.py:1112
+#: aleksis/core/models.py:1130
 msgid "Task user assignment"
 msgstr ""
 
-#: aleksis/core/models.py:1113
+#: aleksis/core/models.py:1131
 msgid "Task user assignments"
 msgstr ""
 
-#: aleksis/core/models.py:1127
+#: aleksis/core/models.py:1147
+msgid "Additional attributes"
+msgstr ""
+
+#: aleksis/core/models.py:1185
 msgid "Allowed scopes that clients can request"
 msgstr ""
 
-#: aleksis/core/preferences.py:23
+#: aleksis/core/preferences.py:24
 msgid "General"
 msgstr ""
 
-#: aleksis/core/preferences.py:24
+#: aleksis/core/preferences.py:25
 msgid "School"
 msgstr ""
 
-#: aleksis/core/preferences.py:25
+#: aleksis/core/preferences.py:26
 msgid "Theme"
 msgstr ""
 
-#: aleksis/core/preferences.py:26
+#: aleksis/core/preferences.py:27
 msgid "Mail"
 msgstr ""
 
-#: aleksis/core/preferences.py:28
+#: aleksis/core/preferences.py:29
 msgid "Footer"
 msgstr ""
 
-#: aleksis/core/preferences.py:29
+#: aleksis/core/preferences.py:30
 msgid "Accounts"
 msgstr ""
 
-#: aleksis/core/preferences.py:30
+#: aleksis/core/preferences.py:31
 msgid "Authentication"
 msgstr ""
 
-#: aleksis/core/preferences.py:31
+#: aleksis/core/preferences.py:32
 msgid "Internationalisation"
 msgstr ""
 
-#: aleksis/core/preferences.py:42
+#: aleksis/core/preferences.py:43
 msgid "Site title"
 msgstr ""
 
-#: aleksis/core/preferences.py:53
+#: aleksis/core/preferences.py:54
 msgid "Site description"
 msgstr ""
 
-#: aleksis/core/preferences.py:64
+#: aleksis/core/preferences.py:65
 msgid "Primary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:76
+#: aleksis/core/preferences.py:77
 msgid "Secondary colour"
 msgstr ""
 
-#: aleksis/core/preferences.py:87
+#: aleksis/core/preferences.py:88
 msgid "Logo"
 msgstr ""
 
-#: aleksis/core/preferences.py:97
+#: aleksis/core/preferences.py:98
 msgid "Favicon"
 msgstr ""
 
-#: aleksis/core/preferences.py:107
+#: aleksis/core/preferences.py:108
 msgid "PWA-Icon"
 msgstr ""
 
-#: aleksis/core/preferences.py:118
+#: aleksis/core/preferences.py:119
 msgid "Mail out name"
 msgstr ""
 
-#: aleksis/core/preferences.py:129
+#: aleksis/core/preferences.py:130
 msgid "Mail out address"
 msgstr ""
 
-#: aleksis/core/preferences.py:141
+#: aleksis/core/preferences.py:142
 msgid "Link to privacy policy"
 msgstr ""
 
-#: aleksis/core/preferences.py:153
+#: aleksis/core/preferences.py:154
 msgid "Link to imprint"
 msgstr ""
 
-#: aleksis/core/preferences.py:165
+#: aleksis/core/preferences.py:166
 msgid "Name format for addressing"
 msgstr ""
 
-#: aleksis/core/preferences.py:181
+#: aleksis/core/preferences.py:182
 msgid "Channels to use for notifications"
 msgstr ""
 
-#: aleksis/core/preferences.py:193
+#: aleksis/core/preferences.py:194
 msgid "Regular expression to match primary group, e.g. '^Class .*'"
 msgstr ""
 
-#: aleksis/core/preferences.py:204
+#: aleksis/core/preferences.py:205
 msgid "Field on person to match primary group against"
 msgstr ""
 
-#: aleksis/core/preferences.py:216
+#: aleksis/core/preferences.py:217
 msgid "Automatically create new persons for new users"
 msgstr ""
 
-#: aleksis/core/preferences.py:225
+#: aleksis/core/preferences.py:226
 msgid "Automatically link existing persons to new users by their e-mail address"
 msgstr ""
 
-#: aleksis/core/preferences.py:236
+#: aleksis/core/preferences.py:237
 msgid "Display name of the school"
 msgstr ""
 
-#: aleksis/core/preferences.py:247
+#: aleksis/core/preferences.py:248
 msgid "Official name of the school, e.g. as given by supervisory authority"
 msgstr ""
 
-#: aleksis/core/preferences.py:255
+#: aleksis/core/preferences.py:256
 msgid "Allow users to change their passwords"
 msgstr ""
 
-#: aleksis/core/preferences.py:263
+#: aleksis/core/preferences.py:264
 msgid "Enable signup"
 msgstr ""
 
-#: aleksis/core/preferences.py:274
+#: aleksis/core/preferences.py:272
+msgid "Enable invitations"
+msgstr ""
+
+#: aleksis/core/preferences.py:280
+msgid "Length of invite code. (Default 3: abcde-acbde-abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:288
+msgid "Size of packets. (Default 5: abcde)"
+msgstr ""
+
+#: aleksis/core/preferences.py:298
 msgid "Allowed Grant Flows for OAuth applications"
 msgstr ""
 
-#: aleksis/core/preferences.py:287
+#: aleksis/core/preferences.py:311
 msgid "Available languages"
 msgstr ""
 
-#: aleksis/core/preferences.py:299
+#: aleksis/core/preferences.py:323
 msgid "Send emails if data checks detect problems"
 msgstr ""
 
-#: aleksis/core/preferences.py:310
+#: aleksis/core/preferences.py:334
 msgid "Email recipients for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:321
+#: aleksis/core/preferences.py:345
 msgid "Email recipient groups for data checks problem emails"
 msgstr ""
 
-#: aleksis/core/preferences.py:330
+#: aleksis/core/preferences.py:354
 msgid "Show dashboard to users without login"
 msgstr ""
 
-#: aleksis/core/preferences.py:339
+#: aleksis/core/preferences.py:363
 msgid "Allow users to edit their dashboard"
 msgstr ""
 
-#: aleksis/core/preferences.py:350
+#: aleksis/core/preferences.py:374
 msgid "Fields on person model which are editable by themselves."
 msgstr ""
 
-#: aleksis/core/preferences.py:364
+#: aleksis/core/preferences.py:388
 msgid "Editable fields on person model which should trigger a notification on change"
 msgstr ""
 
-#: aleksis/core/preferences.py:377
+#: aleksis/core/preferences.py:401
 msgid "Contact for notification if a person changes their data"
 msgstr ""
 
-#: aleksis/core/preferences.py:387
+#: aleksis/core/preferences.py:411
 msgid "PDF file expiration duration"
 msgstr ""
 
-#: aleksis/core/preferences.py:388
+#: aleksis/core/preferences.py:412
 msgid "in minutes"
 msgstr ""
 
-#: aleksis/core/preferences.py:398
+#: aleksis/core/preferences.py:422
 msgid "Automatically update the dashboard and its widgets"
 msgstr ""
 
-#: aleksis/core/preferences.py:408
+#: aleksis/core/preferences.py:432
 msgid "Automatically update the dashboard and its widgets sitewide"
 msgstr ""
 
-#: aleksis/core/settings.py:482
+#: aleksis/core/settings.py:507
 msgid "English"
 msgstr ""
 
-#: aleksis/core/settings.py:483
+#: aleksis/core/settings.py:508
 msgid "German"
 msgstr ""
 
-#: aleksis/core/tables.py:19
+#: aleksis/core/tables.py:24
 #: aleksis/core/templates/core/announcement/list.html:36
 #: aleksis/core/templates/core/group/full.html:24
-#: aleksis/core/templates/core/person/full.html:23
+#: aleksis/core/templates/core/person/full.html:24
 #: aleksis/core/templates/oauth2_provider/application/detail.html:17
 msgid "Edit"
 msgstr ""
 
-#: aleksis/core/tables.py:21 aleksis/core/tables.py:89
-#: aleksis/core/tables.py:105
+#: aleksis/core/tables.py:26 aleksis/core/tables.py:94
+#: aleksis/core/tables.py:137
 #: aleksis/core/templates/core/announcement/list.html:22
 msgid "Actions"
 msgstr ""
 
-#: aleksis/core/tables.py:56 aleksis/core/tables.py:57
-#: aleksis/core/tables.py:71 aleksis/core/tables.py:87
-#: aleksis/core/tables.py:103
+#: aleksis/core/tables.py:61 aleksis/core/tables.py:62
+#: aleksis/core/tables.py:76 aleksis/core/tables.py:92
+#: aleksis/core/tables.py:135
 #: aleksis/core/templates/core/announcement/list.html:42
 #: aleksis/core/templates/core/group/full.html:31
 #: aleksis/core/templates/core/pages/delete.html:22
-#: aleksis/core/templates/core/person/full.html:30
+#: aleksis/core/templates/core/person/full.html:31
 #: aleksis/core/templates/oauth2_provider/application/detail.html:21
 msgid "Delete"
 msgstr ""
@@ -1203,11 +1226,11 @@ msgstr ""
 msgid "Account inactive"
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:13
+#: aleksis/core/templates/account/account_inactive.html:14
 msgid "Account inactive."
 msgstr ""
 
-#: aleksis/core/templates/account/account_inactive.html:15
+#: aleksis/core/templates/account/account_inactive.html:17
 msgid ""
 "\n"
 "            This account is currently inactive. If you think this is an\n"
@@ -1359,11 +1382,11 @@ msgstr ""
 msgid "Signup closed"
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:13
+#: aleksis/core/templates/account/signup_closed.html:14
 msgid "Signup closed."
 msgstr ""
 
-#: aleksis/core/templates/account/signup_closed.html:15
+#: aleksis/core/templates/account/signup_closed.html:17
 msgid ""
 "\n"
 "            This sign up is currently closed. If you think this is an\n"
@@ -1401,11 +1424,6 @@ msgid ""
 "          "
 msgstr ""
 
-#: 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 ""
-
 #: aleksis/core/templates/core/additional_field/edit.html:6
 #: aleksis/core/templates/core/additional_field/edit.html:7
 msgid "Edit additional field"
@@ -1458,7 +1476,7 @@ msgid "About AlekSIS® — The Free School Information System"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:183
-msgid "Impress"
+msgid "Imprint"
 msgstr ""
 
 #: aleksis/core/templates/core/base.html:191
@@ -1681,7 +1699,7 @@ msgid "Edit group"
 msgstr ""
 
 #: aleksis/core/templates/core/group/full.html:38
-#: aleksis/core/templates/core/person/full.html:37
+#: aleksis/core/templates/core/person/full.html:38
 msgid "Change preferences"
 msgstr ""
 
@@ -2075,17 +2093,19 @@ msgstr ""
 msgid "Edit person"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:44
-#: aleksis/core/templates/impersonate/list_users.html:7
-#: aleksis/core/templates/impersonate/list_users.html:8
+#: aleksis/core/templates/core/person/full.html:45
 msgid "Impersonate"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:50
+#: aleksis/core/templates/core/person/full.html:51
+msgid "Invite user"
+msgstr ""
+
+#: aleksis/core/templates/core/person/full.html:57
 msgid "Contact details"
 msgstr ""
 
-#: aleksis/core/templates/core/person/full.html:131
+#: aleksis/core/templates/core/person/full.html:138
 msgid "Children"
 msgstr ""
 
@@ -2125,6 +2145,49 @@ msgstr ""
 msgid "Save preferences"
 msgstr ""
 
+#: aleksis/core/templates/invitations/enter.html:21
+msgid "Accept your invitation"
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:25
+msgid ""
+"\n"
+"                Please enter your invitation code to register\n"
+"                your new user account:\n"
+"              "
+msgstr ""
+
+#: aleksis/core/templates/invitations/enter.html:37
+msgid "Accept invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:9
+#: aleksis/core/templates/invitations/forms/_invite.html:10
+#: aleksis/core/templates/invitations/forms/_invite.html:21
+msgid "Invite"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:17
+msgid "Invite by email address"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:26
+msgid "Generate invitation code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:29
+msgid "Generate code"
+msgstr ""
+
+#: aleksis/core/templates/invitations/forms/_invite.html:33
+msgid "Invitations"
+msgstr ""
+
+#: aleksis/core/templates/invitations/messages/invite_accepted.txt:3
+#, python-format
+msgid "The invitation for %(email)s has been accepted."
+msgstr ""
+
 #: aleksis/core/templates/oauth2_provider/application/create.html:5
 #: aleksis/core/templates/oauth2_provider/application/create.html:6
 msgid "Register OAuth2 Application"
@@ -2801,127 +2864,140 @@ msgstr ""
 msgid "Download PDF"
 msgstr ""
 
-#: aleksis/core/views.py:270
+#: aleksis/core/views.py:280
 msgid "The school term has been created."
 msgstr ""
 
-#: aleksis/core/views.py:282
+#: aleksis/core/views.py:292
 msgid "The school term has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:406
+#: aleksis/core/views.py:416
 msgid "The child groups were successfully saved."
 msgstr ""
 
-#: aleksis/core/views.py:425 aleksis/core/views.py:435
+#: aleksis/core/views.py:435 aleksis/core/views.py:445
 msgid "The person has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:485
+#: aleksis/core/views.py:495
 msgid "The group has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:582
+#: aleksis/core/views.py:592
 msgid "The announcement has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:598
+#: aleksis/core/views.py:608
 msgid "The announcement has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:682
+#: aleksis/core/views.py:695
 msgid "The preferences have been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:706
+#: aleksis/core/views.py:719
 msgid "The person has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:720
+#: aleksis/core/views.py:733
 msgid "The group has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:752
+#: aleksis/core/views.py:765
 msgid "The additional_field has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:786
+#: aleksis/core/views.py:799
 msgid "The additional field has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:811
+#: aleksis/core/views.py:824
 msgid "The group type has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:841
+#: aleksis/core/views.py:854
 msgid "The group type has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:874
+#: aleksis/core/views.py:887
 msgid "Progress: Run data checks"
 msgstr ""
 
-#: aleksis/core/views.py:875
+#: aleksis/core/views.py:888
 msgid "Run data checks …"
 msgstr ""
 
-#: aleksis/core/views.py:876
+#: aleksis/core/views.py:889
 msgid "The data checks were run successfully."
 msgstr ""
 
-#: aleksis/core/views.py:877
+#: aleksis/core/views.py:890
 msgid "There was a problem while running data checks."
 msgstr ""
 
-#: aleksis/core/views.py:893
+#: aleksis/core/views.py:906
 #, python-brace-format
 msgid "The solve option '{solve_option_obj.verbose_name}' "
 msgstr ""
 
-#: aleksis/core/views.py:935
+#: aleksis/core/views.py:948
 msgid "The dashboard widget has been saved."
 msgstr ""
 
-#: aleksis/core/views.py:965
+#: aleksis/core/views.py:978
 msgid "The dashboard widget has been created."
 msgstr ""
 
-#: aleksis/core/views.py:975
+#: aleksis/core/views.py:988
 msgid "The dashboard widget has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1042
+#: aleksis/core/views.py:1055
 msgid "Your dashboard configuration has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1044
+#: aleksis/core/views.py:1057
 msgid "The configuration of the default dashboard has been saved successfully."
 msgstr ""
 
-#: aleksis/core/views.py:1139
+#: aleksis/core/views.py:1127
+#, python-brace-format
+msgid "The invitation was successfully created. The invitation code is {code}"
+msgstr ""
+
+#: aleksis/core/views.py:1218
 msgid "We have successfully assigned the permissions."
 msgstr ""
 
-#: aleksis/core/views.py:1149
+#: aleksis/core/views.py:1228
 msgid "The global user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1159
+#: aleksis/core/views.py:1238
 msgid "The global group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1169
+#: aleksis/core/views.py:1248
 msgid "The object user permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1179
+#: aleksis/core/views.py:1258
 msgid "The object group permission has been deleted."
 msgstr ""
 
-#: aleksis/core/views.py:1298
+#: aleksis/core/views.py:1377
 msgid "The third-party account could not be disconnected because it is the only login method available."
 msgstr ""
 
-#: aleksis/core/views.py:1305
+#: aleksis/core/views.py:1384
 msgid "The third-party account has been successfully disconnected."
 msgstr ""
+
+#: aleksis/core/views.py:1441
+msgid "Person was invited successfully."
+msgstr ""
+
+#: aleksis/core/views.py:1443
+msgid "Person was already invited."
+msgstr ""
diff --git a/aleksis/core/locale/tr_TR/LC_MESSAGES/djangojs.po b/aleksis/core/locale/tr_TR/LC_MESSAGES/djangojs.po
index 42571d39e1fdfd5750cf094335d8718cd90c2cde..d67bdb0055bf1ee96915909ce9e21023085c466b 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-12-13 12:55+0100\n"
+"POT-Creation-Date: 2021-12-28 12:14+0100\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:127
+#: aleksis/core/static/js/main.js:128
 msgid "This page may contain outdated information since there is no internet connection."
 msgstr ""
diff --git a/aleksis/core/managers.py b/aleksis/core/managers.py
index aed4cab72d4b0cd53d3544b20f0180a7087dfd2c..a3feacc6cf17731a6d6f38ca5ace42677ed230f1 100644
--- a/aleksis/core/managers.py
+++ b/aleksis/core/managers.py
@@ -7,6 +7,7 @@ from django.db.models import QuerySet
 from django.db.models.manager import Manager
 
 from calendarweek import CalendarWeek
+from django_cte import CTEManager, CTEQuerySet
 from polymorphic.managers import PolymorphicManager
 
 
@@ -84,7 +85,7 @@ class SchoolTermRelatedQuerySet(QuerySet):
             return None
 
 
-class GroupManager(CurrentSiteManagerWithoutMigrations):
+class GroupManager(CurrentSiteManagerWithoutMigrations, CTEManager):
     """Manager adding specific methods to groups."""
 
     def get_queryset(self):
@@ -92,7 +93,7 @@ class GroupManager(CurrentSiteManagerWithoutMigrations):
         return super().get_queryset().select_related("school_term")
 
 
-class GroupQuerySet(SchoolTermRelatedQuerySet):
+class GroupQuerySet(SchoolTermRelatedQuerySet, CTEQuerySet):
     pass
 
 
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 73ffab18ab217e1698ccc4fbdea9b25c1de97dfb..133af202290421dd215b568cd6a1133adc239571 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -14,7 +14,7 @@ from django.contrib.sites.models import Site
 from django.core.exceptions import ValidationError
 from django.core.validators import MaxValueValidator
 from django.db import models, transaction
-from django.db.models import QuerySet
+from django.db.models import Q, QuerySet
 from django.db.models.signals import m2m_changed
 from django.dispatch import receiver
 from django.forms.widgets import Media
@@ -28,6 +28,7 @@ import jsonstore
 from cachalot.api import cachalot_disabled
 from cache_memoize import cache_memoize
 from django_celery_results.models import TaskResult
+from django_cte import CTEQuerySet, With
 from dynamic_preferences.models import PerInstancePreferenceModel
 from invitations import signals
 from invitations.adapters import get_invitations_adapter
@@ -299,6 +300,22 @@ class Person(ExtensibleModel):
 
     user_info_tracker = FieldTracker(fields=("first_name", "last_name", "email"))
 
+    @property
+    def member_of_recursive(self) -> QuerySet:
+        """Get all groups this person is a member of, recursively."""
+        q = self.member_of
+        for group in q.all():
+            q = q.union(group.parent_groups_recursive)
+        return q
+
+    @property
+    def owner_of_recursive(self) -> QuerySet:
+        """Get all groups this person is a member of, recursively."""
+        q = self.owner_of
+        for group in q.all():
+            q = q.union(group.child_groups_recursive)
+        return q
+
     def save(self, *args, **kwargs):
         # Determine all fields that were changed since last load
         dirty = self.pk is None or bool(self.user_info_tracker.changed())
@@ -486,6 +503,50 @@ class Group(SchoolTermRelatedExtensibleModel):
 
         return stats
 
+    @property
+    def parent_groups_recursive(self) -> CTEQuerySet:
+        """Get all parent groups recursively."""
+
+        def _make_cte(cte):
+            Through = self.parent_groups.through
+            return (
+                Through.objects.values("to_group_id")
+                .filter(from_group=self)
+                .union(cte.join(Through, from_group=cte.col.to_group_id), all=True)
+            )
+
+        cte = With.recursive(_make_cte)
+        return cte.join(Group, id=cte.col.to_group_id).with_cte(cte)
+
+    @property
+    def child_groups_recursive(self) -> CTEQuerySet:
+        """Get all child groups recursively."""
+
+        def _make_cte(cte):
+            Through = self.child_groups.through
+            return (
+                Through.objects.values("from_group_id")
+                .filter(to_group=self)
+                .union(cte.join(Through, to_group=cte.col.from_group_id), all=True)
+            )
+
+        cte = With.recursive(_make_cte)
+        return cte.join(Group, id=cte.col.from_group_id).with_cte(cte)
+
+    @property
+    def members_recursive(self) -> QuerySet:
+        """Get all members of this group and its child groups."""
+        return Person.objects.filter(
+            Q(member_of=self) | Q(member_of__in=self.child_groups_recursive)
+        )
+
+    @property
+    def owners_recursive(self) -> QuerySet:
+        """Get all ownerss of this group and its parent groups."""
+        return Person.objects.filter(
+            Q(owner_of=self) | Q(owner_of__in=self.parent_groups_recursive)
+        )
+
     def __str__(self) -> str:
         if self.school_term:
             return f"{self.name} ({self.short_name}) ({self.school_term})"
diff --git a/aleksis/core/preferences.py b/aleksis/core/preferences.py
index 15ca0e67478ed6483a8cd0df03aa38c1529b8762..afd38c9658e605a91e67f5cb25379186f3feb3bc 100644
--- a/aleksis/core/preferences.py
+++ b/aleksis/core/preferences.py
@@ -288,6 +288,7 @@ class InviteCodePacketSize(IntegerPreference):
     verbose_name = _("Size of packets. (Default 5: abcde)")
 
 
+@site_preferences_registry.register
 class OAuthAllowedGrants(MultipleChoicePreference):
     """Grant Flows allowed for OAuth applications."""
 
diff --git a/aleksis/core/static/js/progress.js b/aleksis/core/static/js/progress.js
index 9be718b7e67f30e8cc77a436755e50f08b540fd3..0b2509006029421273159617c9ff2646bb12800b 100644
--- a/aleksis/core/static/js/progress.js
+++ b/aleksis/core/static/js/progress.js
@@ -47,6 +47,7 @@ function customSuccess(progressBarElement, progressBarMessageElement) {
     $("#result-icon").text("check_circle");
     $("#result-text").text(OPTIONS.success);
     $("#result-box").show();
+    $("#result-button").show();
     const redirect = "redirect_on_success" in OPTIONS && OPTIONS.redirect_on_success;
     if (redirect) {
         window.location.replace(OPTIONS.redirect_on_success);
diff --git a/aleksis/core/templates/core/pages/progress.html b/aleksis/core/templates/core/pages/progress.html
index 799f1f93648ab1de05be3f9432653b8c4e8b1466..fca1ddfc2ebe5980ee132de77bdf1baafce24ae0 100644
--- a/aleksis/core/templates/core/pages/progress.html
+++ b/aleksis/core/templates/core/pages/progress.html
@@ -47,7 +47,7 @@
           {% trans "Go back" %}
         </a>
         {% if additional_button %}
-          <a class="btn waves-effect waves-light" href="{{ additional_button.href }}">
+          <a class="btn waves-effect waves-light" href="{{ additional_button.href }}" id="result-button" style="display: none;">
             <i class="material-icons left">{{ additional_button.icon|default:"" }}</i>
             {{ additional_button.caption }}
           </a>
diff --git a/aleksis/core/tests/models/test_group.py b/aleksis/core/tests/models/test_group.py
new file mode 100644
index 0000000000000000000000000000000000000000..8849a842d043b6bd3c91d04393cf5ccc695d2cf3
--- /dev/null
+++ b/aleksis/core/tests/models/test_group.py
@@ -0,0 +1,163 @@
+import pytest
+
+from aleksis.core.models import Group, Person
+
+pytestmark = pytest.mark.django_db
+
+
+def test_child_groups_recursive():
+    g_1st_grade = Group.objects.create(name="1st grade")
+    g_1a = Group.objects.create(name="1a")
+    g_1b = Group.objects.create(name="1b")
+    g_2nd_grade = Group.objects.create(name="2nd grade")
+    g_2a = Group.objects.create(name="2a")
+    g_2b = Group.objects.create(name="2b")
+    g_2c = Group.objects.create(name="2c")
+    g_2nd_grade_french = Group.objects.create(name="2nd grade French")
+
+    g_1a.parent_groups.set([g_1st_grade])
+    g_1b.parent_groups.set([g_1st_grade])
+    g_2a.parent_groups.set([g_2nd_grade])
+    g_2b.parent_groups.set([g_2nd_grade])
+    g_2c.parent_groups.set([g_2nd_grade])
+    g_2nd_grade_french.parent_groups.set([g_2b, g_2c])
+
+    assert g_2nd_grade_french in g_2nd_grade.child_groups_recursive
+    assert g_2nd_grade_french in g_2b.child_groups_recursive
+    assert g_2nd_grade_french in g_2c.child_groups_recursive
+    assert g_2nd_grade_french not in g_2a.child_groups_recursive
+    assert g_2nd_grade_french not in g_1st_grade.child_groups_recursive
+
+
+def test_parent_groups_recursive():
+    g_1st_grade = Group.objects.create(name="1st grade")
+    g_1a = Group.objects.create(name="1a")
+    g_1b = Group.objects.create(name="1b")
+    g_2nd_grade = Group.objects.create(name="2nd grade")
+    g_2a = Group.objects.create(name="2a")
+    g_2b = Group.objects.create(name="2b")
+    g_2c = Group.objects.create(name="2c")
+    g_2nd_grade_french = Group.objects.create(name="2nd grade French")
+
+    g_1a.parent_groups.set([g_1st_grade])
+    g_1b.parent_groups.set([g_1st_grade])
+    g_2a.parent_groups.set([g_2nd_grade])
+    g_2b.parent_groups.set([g_2nd_grade])
+    g_2c.parent_groups.set([g_2nd_grade])
+    g_2nd_grade_french.parent_groups.set([g_2b, g_2c])
+
+    assert g_1st_grade in g_1a.parent_groups_recursive
+    assert g_2nd_grade in g_2a.parent_groups_recursive
+    assert g_2nd_grade in g_2nd_grade_french.parent_groups_recursive
+    assert g_1st_grade not in g_2nd_grade_french.parent_groups_recursive
+
+
+def test_members_recursive():
+    g_2nd_grade = Group.objects.create(name="2nd grade")
+    g_2a = Group.objects.create(name="2a")
+    g_2b = Group.objects.create(name="2b")
+    g_2c = Group.objects.create(name="2c")
+    g_2nd_grade_french = Group.objects.create(name="2nd grade French")
+
+    g_2a.parent_groups.set([g_2nd_grade])
+    g_2b.parent_groups.set([g_2nd_grade])
+    g_2c.parent_groups.set([g_2nd_grade])
+    g_2nd_grade_french.parent_groups.set([g_2b, g_2c])
+
+    p_2a_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2a_2 = Person.objects.create(first_name="A", last_name="B")
+    p_2b_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2b_2 = Person.objects.create(first_name="A", last_name="B")
+    p_2c_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2c_2 = Person.objects.create(first_name="A", last_name="B")
+    p_french_only = Person.objects.create(first_name="A", last_name="B")
+
+    g_2a.members.set([p_2a_1, p_2a_2])
+    g_2b.members.set([p_2b_1, p_2b_2])
+    g_2c.members.set([p_2c_1, p_2c_2])
+    g_2nd_grade_french.members.set([p_2b_1, p_2c_1, p_french_only])
+
+    assert p_2a_1 in g_2nd_grade.members_recursive
+    assert p_2a_2 in g_2nd_grade.members_recursive
+    assert p_2b_1 in g_2nd_grade.members_recursive
+    assert p_2b_2 in g_2nd_grade.members_recursive
+    assert p_2c_1 in g_2nd_grade.members_recursive
+    assert p_2c_2 in g_2nd_grade.members_recursive
+    assert p_french_only in g_2nd_grade.members_recursive
+    assert p_french_only in g_2b.members_recursive
+    assert p_french_only in g_2c.members_recursive
+    assert p_french_only not in g_2a.members_recursive
+
+
+def test_member_of_recursive():
+    g_2nd_grade = Group.objects.create(name="2nd grade")
+    g_2a = Group.objects.create(name="2a")
+    g_2b = Group.objects.create(name="2b")
+    g_2c = Group.objects.create(name="2c")
+    g_2nd_grade_french = Group.objects.create(name="2nd grade French")
+
+    g_2a.parent_groups.set([g_2nd_grade])
+    g_2b.parent_groups.set([g_2nd_grade])
+    g_2c.parent_groups.set([g_2nd_grade])
+    g_2nd_grade_french.parent_groups.set([g_2b, g_2c])
+
+    p_2a_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2a_2 = Person.objects.create(first_name="A", last_name="B")
+    p_2b_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2b_2 = Person.objects.create(first_name="A", last_name="B")
+    p_2c_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2c_2 = Person.objects.create(first_name="A", last_name="B")
+    p_french_only = Person.objects.create(first_name="A", last_name="B")
+
+    g_2a.members.set([p_2a_1, p_2a_2])
+    g_2b.members.set([p_2b_1, p_2b_2])
+    g_2c.members.set([p_2c_1, p_2c_2])
+    g_2nd_grade_french.members.set([p_2b_1, p_2c_1, p_french_only])
+
+    assert g_2nd_grade in p_2a_1.member_of_recursive
+    assert g_2nd_grade in p_2a_2.member_of_recursive
+    assert g_2nd_grade in p_2b_1.member_of_recursive
+    assert g_2nd_grade in p_2b_2.member_of_recursive
+    assert g_2nd_grade in p_2c_1.member_of_recursive
+    assert g_2nd_grade in p_2c_2.member_of_recursive
+    assert g_2nd_grade in p_french_only.member_of_recursive
+    assert g_2b in p_french_only.member_of_recursive
+    assert g_2c in p_french_only.member_of_recursive
+
+
+def test_owners_recursive():
+    g_2nd_grade = Group.objects.create(name="2nd grade")
+    g_2a = Group.objects.create(name="2a")
+    g_2b = Group.objects.create(name="2b")
+
+    g_2a.parent_groups.set([g_2nd_grade])
+    g_2b.parent_groups.set([g_2nd_grade])
+
+    p_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2 = Person.objects.create(first_name="A", last_name="B")
+
+    g_2nd_grade.owners.set([p_1])
+
+    assert p_1 in g_2a.owners_recursive
+    assert p_1 in g_2b.owners_recursive
+    assert p_2 not in g_2a.owners_recursive
+    assert p_2 not in g_2b.owners_recursive
+
+
+def test_owner_of_recursive():
+    g_2nd_grade = Group.objects.create(name="2nd grade")
+    g_2a = Group.objects.create(name="2a")
+    g_2b = Group.objects.create(name="2b")
+
+    g_2a.parent_groups.set([g_2nd_grade])
+    g_2b.parent_groups.set([g_2nd_grade])
+
+    p_1 = Person.objects.create(first_name="A", last_name="B")
+    p_2 = Person.objects.create(first_name="A", last_name="B")
+
+    g_2nd_grade.owners.set([p_1])
+
+    assert g_2a in p_1.owner_of_recursive.all()
+    assert g_2b in p_1.owner_of_recursive.all()
+    assert g_2a not in p_2.owner_of_recursive.all()
+    assert g_2b not in p_2.owner_of_recursive.all()
diff --git a/aleksis/core/tests/regression/test_regression.py b/aleksis/core/tests/regression/test_regression.py
new file mode 100644
index 0000000000000000000000000000000000000000..163fd9d4a65ae81fd5ce345dbb1ac33d804b5be7
--- /dev/null
+++ b/aleksis/core/tests/regression/test_regression.py
@@ -0,0 +1,21 @@
+def test_all_settigns_registered():
+    """Tests for regressions of preferences not being registered.
+
+    https://edugit.org/AlekSIS/official/AlekSIS-Core/-/issues/592
+    """
+
+    from dynamic_preferences.types import BasePreferenceType
+
+    from aleksis.core import preferences
+    from aleksis.core.preferences import person_preferences_registry, site_preferences_registry
+
+    for obj in preferences.__dict__.values():
+        if not isinstance(obj, BasePreferenceType):
+            continue
+
+        in_site_reg = site_preferences_registry.get(obj.section.name, {}).get(obj.name, None) is obj
+        in_person_reg = (
+            person_preferences_registry.get(obj.section.name, {}).get(obj.name, None) is obj
+        )
+
+        assert in_site_reg != in_person_reg
diff --git a/docs/dev/01_setup.rst b/docs/dev/01_setup.rst
index dd3121a822e53c603b21511b790f5ef6950f295a..24a64dbf7b7536193f7691538b2846409782519d 100644
--- a/docs/dev/01_setup.rst
+++ b/docs/dev/01_setup.rst
@@ -20,7 +20,7 @@ AlekSIS requires `PostgreSQL`_ (version 13 or newer) as database
 backend. To provide a database names `aleksis` with a user named
 `aleksis` on Debian::
 
-  sudo apt install postgresql-13
+  sudo apt install postgresql
   sudo -u postgres createuser -P aleksis
   sudo -u postgres createdb -O aleksis aleksis
 
@@ -86,16 +86,15 @@ some maintenance tasks need to be done:
 2. Collect static files
 3. Run database migrations
 
-All three steps can be done with the ``poetry run`` command and
+All three steps can be done with the ``poetry shell`` command and
 ``aleksis-admin``::
 
-  poetry run aleksis-admin yarn install
-  poetry run aleksis-admin collectstatic
-  poetry run aleksis-admin compilemessages
-  poetry run aleksis-admin migrate
-  poetry run aleksis-admin createinitialrevisions
-
-(You might need database settings for the `migrate` command; see below.)
+  ALEKSIS_maintenance__debug=true ALEKSIS_database__password=aleksis poetry shell
+   poetry run aleksis-admin yarn install
+   poetry run aleksis-admin collectstatic
+   poetry run aleksis-admin compilemessages
+   poetry run aleksis-admin migrate
+   poetry run aleksis-admin createinitialrevisions
 
 Running the development server
 ------------------------------
@@ -108,7 +107,7 @@ basic settings in as environment variable. Here is an example that runs the
 development server against a local PostgreSQL database with password
 `aleksis` (all else remains default) and with the `debug` setting enabled::
 
-  ALEKSIS_debug=true ALEKSIS_database__password=aleksis poetry run aleksis-admin runuwsgi
+  ALEKSIS_maintenance__debug=true ALEKSIS_database__password=aleksis poetry run aleksis-admin runuwsgi
 
 .. figure:: /screenshots/index.png
    :scale: 50%
diff --git a/pyproject.toml b/pyproject.toml
index 03015c02b2e1307558c7e956d77449a5017af82a..01c9cce24050735530c33d99a4246f56b7632d37 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -116,6 +116,7 @@ django-titofisto = "^0.2.0"
 haystack-redis = "^0.0.1"
 python-gnupg = "^0.4.7"
 sentry-sdk = {version = "^1.4.3", optional = true}
+django-cte = "^1.1.5"
 
 [tool.poetry.extras]
 ldap = ["django-auth-ldap"]