diff --git a/app/auth/forms.py b/app/auth/forms.py index d8ca5770..a6ce0017 100644 --- a/app/auth/forms.py +++ b/app/auth/forms.py @@ -43,6 +43,10 @@ class RegistrationForm(FlaskForm): EqualTo('password', message='Passwords must match') ] ) + terms_of_use_accepted = BooleanField( + 'I have read and accept the terms of use', + validators=[InputRequired()] + ) submit = SubmitField() def __init__(self, *args, **kwargs): diff --git a/app/auth/routes.py b/app/auth/routes.py index dc6140f2..54337d69 100644 --- a/app/auth/routes.py +++ b/app/auth/routes.py @@ -40,7 +40,8 @@ def register(): user = User.create( email=form.email.data.lower(), password=form.password.data, - username=form.username.data + username=form.username.data, + terms_of_use_accepted=form.terms_of_use_accepted.data ) except OSError: flash('Internal Server Error', category='error') diff --git a/app/models.py b/app/models.py index 07d648ad..34173d0f 100644 --- a/app/models.py +++ b/app/models.py @@ -522,6 +522,7 @@ class User(HashidMixin, UserMixin, db.Model): username_pattern = re.compile(r'^[A-Za-zÄÖÜäöüß0-9_.]*$') password_hash = db.Column(db.String(128)) confirmed = db.Column(db.Boolean, default=False) + terms_of_use_accepted = db.Column(db.Boolean, default=False) member_since = db.Column(db.DateTime(), default=datetime.utcnow) setting_job_status_mail_notification_level = db.Column( IntEnumColumn(UserSettingJobStatusMailNotificationLevel), diff --git a/app/static/js/Requests/users/settings.js b/app/static/js/Requests/users/settings.js index 0a92a09c..7584e9bb 100644 --- a/app/static/js/Requests/users/settings.js +++ b/app/static/js/Requests/users/settings.js @@ -13,4 +13,12 @@ Requests.users.entity.settings.profilePrivacy.update = (userId, profilePrivacySe body: JSON.stringify(enabled) }; return Requests.JSONfetch(input, init); -} +}; + +Requests.users.entity.settings.acceptTermsOfUse = () => { + let input = `/users/accept-terms-of-use`; + let init = { + method: 'POST' + }; + return Requests.JSONfetch(input, init); +}; diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2 index 9dd81933..5749d86b 100644 --- a/app/templates/_scripts.html.j2 +++ b/app/templates/_scripts.html.j2 @@ -107,4 +107,22 @@ for (let [category, message] of {{ get_flashed_messages(with_categories=True)|tojson }}) { app.flash(message, message); } + + // Initialize terms of use modal + const termsOfUseModal = document.getElementById('terms-of-use-modal'); + M.Modal.init( + termsOfUseModal, + { + dismissible: false, + onCloseEnd: () => { + Requests.users.entity.settings.acceptTermsOfUse(); + } + } + ); + {% if current_user.is_authenticated %} + {% if not current_user.terms_of_use_accepted %} + termsOfUseModal.M_Modal.open(); + {% endif %} + {% endif %} + diff --git a/app/templates/_terms_of_use_modal.html.j2 b/app/templates/_terms_of_use_modal.html.j2 new file mode 100644 index 00000000..ddd8985b --- /dev/null +++ b/app/templates/_terms_of_use_modal.html.j2 @@ -0,0 +1,115 @@ +
diff --git a/app/templates/auth/register.html.j2 b/app/templates/auth/register.html.j2 index d8e023a7..adfbc0af 100644 --- a/app/templates/auth/register.html.j2 +++ b/app/templates/auth/register.html.j2 @@ -23,6 +23,10 @@ {{ wtf.render_field(form.password, material_icon='vpn_key') }} {{ wtf.render_field(form.password_2, material_icon='vpn_key') }} {{ wtf.render_field(form.email, class_='validate', material_icon='email', type='email') }} +