feat: Legal checkboxes #14

Open
Minecon724 wants to merge 2 commits from mod/legal into fgj
9 changed files with 51 additions and 5 deletions

View file

@ -2459,6 +2459,10 @@ LEVEL = Info
;ENABLE_SITEMAP = true ;ENABLE_SITEMAP = true
;; Enable/Disable RSS/Atom feed ;; Enable/Disable RSS/Atom feed
;ENABLE_FEED = true ;ENABLE_FEED = true
;; Terms of Service URL. If set, users will have to agree to the ToS during registration.
;TERMS_OF_SERVICE = /terms
;; Privacy Policy URL. If set, users will have to agree to the Privacy Policy during registration.
;PRIVACY_POLICY = /privacy
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -11,6 +11,8 @@ type OtherConfig struct {
ShowFooterPoweredBy bool ShowFooterPoweredBy bool
EnableFeed bool EnableFeed bool
EnableSitemap bool EnableSitemap bool
TermsOfServiceUrl string
PrivacyPolicyUrl string
} }
var Other = OtherConfig{ var Other = OtherConfig{
@ -19,6 +21,8 @@ var Other = OtherConfig{
ShowFooterPoweredBy: true, ShowFooterPoweredBy: true,
EnableSitemap: true, EnableSitemap: true,
EnableFeed: true, EnableFeed: true,
TermsOfServiceUrl: "",
PrivacyPolicyUrl: "",
} }
func loadOtherFrom(rootCfg ConfigProvider) { func loadOtherFrom(rootCfg ConfigProvider) {

View file

@ -53,6 +53,8 @@ func CommonTemplateContextData() ContextData {
"ShowMilestonesDashboardPage": setting.Service.ShowMilestonesDashboardPage, "ShowMilestonesDashboardPage": setting.Service.ShowMilestonesDashboardPage,
"ShowFooterVersion": setting.Other.ShowFooterVersion, "ShowFooterVersion": setting.Other.ShowFooterVersion,
"DisableDownloadSourceArchives": setting.Repository.DisableDownloadSourceArchives, "DisableDownloadSourceArchives": setting.Repository.DisableDownloadSourceArchives,
"TermsOfServiceURL": setting.Other.TermsOfServiceUrl,
"PrivacyPolicyURL": setting.Other.PrivacyPolicyUrl,
"EnableSwagger": setting.API.EnableSwagger, "EnableSwagger": setting.API.EnableSwagger,
"EnableOpenIDSignIn": setting.Service.EnableOpenIDSignIn, "EnableOpenIDSignIn": setting.Service.EnableOpenIDSignIn,

View file

@ -27,6 +27,8 @@ licenses = Licenses
return_to_forgejo = Return to Forgejo return_to_forgejo = Return to Forgejo
toggle_menu = Toggle menu toggle_menu = Toggle menu
more_items = More items more_items = More items
terms_of_service = Terms of Service
privacy_policy = Privacy Policy
username = Username username = Username
email = Email address email = Email address
@ -37,6 +39,8 @@ captcha = CAPTCHA
twofa = Two-factor authentication twofa = Two-factor authentication
twofa_scratch = Two-factor scratch code twofa_scratch = Two-factor scratch code
passcode = Passcode passcode = Passcode
consent.terms_of_service = I have read and agree to the <a href="%s">Terms of Service</a>
consent.privacy_policy = I have read and agree to the <a href="%s">Privacy Policy</a>
webauthn_insert_key = Insert your security key webauthn_insert_key = Insert your security key
webauthn_sign_in = Press the button on your security key. If your security key has no button, re-insert it. webauthn_sign_in = Press the button on your security key. If your security key has no button, re-insert it.
@ -479,6 +483,7 @@ password_pwned_err = Could not complete request to HaveIBeenPwned
last_admin = You cannot remove the last admin. There must be at least one admin. last_admin = You cannot remove the last admin. There must be at least one admin.
back_to_sign_in = Back to Sign in back_to_sign_in = Back to Sign in
sign_in_openid = Proceed with OpenID sign_in_openid = Proceed with OpenID
must_consent = You must agree to the Terms of Service and Privacy Policy to register an account.
[mail] [mail]
view_it_on = View it on %s view_it_on = View it on %s

View file

@ -448,6 +448,11 @@ func SignUpPost(ctx *context.Context) {
return return
} }
if !form.ConsentTerms || !form.ConsentPrivacy {
ctx.RenderWithErr(ctx.Tr("auth.must_consent"), tplSignUp, &form)
return
}
context.VerifyCaptcha(ctx, tplSignUp, form) context.VerifyCaptcha(ctx, tplSignUp, form)
if ctx.Written() { if ctx.Written() {
return return

View file

@ -92,10 +92,12 @@ func (f *InstallForm) Validate(req *http.Request, errs binding.Errors) binding.E
// RegisterForm form for registering // RegisterForm form for registering
type RegisterForm struct { type RegisterForm struct {
UserName string `binding:"Required;Username;MaxSize(40)"` UserName string `binding:"Required;Username;MaxSize(40)"`
Email string `binding:"Required;MaxSize(254)"` Email string `binding:"Required;MaxSize(254)"`
Password string `binding:"MaxSize(255)"` Password string `binding:"MaxSize(255)"`
Retype string Retype string
ConsentTerms bool
ConsentPrivacy bool
} }
// Validate validates the fields // Validate validates the fields

View file

@ -25,8 +25,9 @@
{{end}} {{end}}
</div> </div>
</div> </div>
{{if .TermsOfServiceURL}}<a href="{{.TermsOfServiceURL}}">{{ctx.Locale.Tr "terms_of_service"}}</a>{{end}}
{{if .PrivacyPolicyURL}}<a href="{{.PrivacyPolicyURL}}">{{ctx.Locale.Tr "privacy_policy"}}</a>{{end}}
<a href="{{AssetUrlPrefix}}/licenses.txt">{{ctx.Locale.Tr "licenses"}}</a> <a href="{{AssetUrlPrefix}}/licenses.txt">{{ctx.Locale.Tr "licenses"}}</a>
{{if .EnableSwagger}}<a href="{{AppSubUrl}}/api/swagger">API</a>{{end}}
{{template "custom/extra_links_footer" .}} {{template "custom/extra_links_footer" .}}
</div> </div>
</footer> </footer>

View file

@ -0,0 +1,21 @@
{{ if (.TermsOfServiceURL) }}
<div class="inline field required">
<div class="ui checkbox">
<input id="consent_terms" name="consent_terms" type="checkbox">
<label for="consent_terms">{{ ctx.Locale.Tr "consent.terms_of_service" .TermsOfServiceURL }}</label>
</div>
</div>
{{ else }}
<input id="consent_terms" name="consent_terms" type="checkbox" checked hidden>
{{ end }}
{{ if (.PrivacyPolicyURL) }}
<div class="inline field required">
<div class="ui checkbox">
<input id="consent_privacy" name="consent_privacy" type="checkbox">
<label for="consent_privacy">{{ ctx.Locale.Tr "consent.privacy_policy" .PrivacyPolicyURL }}</label>
</div>
</div>
{{ else }}
<input id="consent_privacy" name="consent_privacy" type="checkbox" checked hidden>
{{ end }}

View file

@ -37,6 +37,8 @@
{{template "user/auth/captcha" .}} {{template "user/auth/captcha" .}}
{{template "user/auth/consent" .}}
<div class="inline field"> <div class="inline field">
<button class="ui primary button tw-w-full"> <button class="ui primary button tw-w-full">
{{if .LinkAccountMode}} {{if .LinkAccountMode}}