diff --git a/app/src/App.vue b/app/src/App.vue index 6020ab7c7..c7b3239b0 100644 --- a/app/src/App.vue +++ b/app/src/App.vue @@ -138,6 +138,13 @@ onMounted(() => { > {{ $t('footer.help') }} + + {{ $t('footer.tos') }} + () :state="state" switch > - {{ label || $t(labels[modelValue ? 'true' : 'false']) }} + diff --git a/app/src/helpers/validators/customValidators.ts b/app/src/helpers/validators/customValidators.ts index 77a9f3157..5d4a287de 100644 --- a/app/src/helpers/validators/customValidators.ts +++ b/app/src/helpers/validators/customValidators.ts @@ -56,6 +56,8 @@ const unique = (items: MaybeRef) => return items_ ? !helpers.req(item) || !items_.includes(item) : true }) +const checked = (value: boolean) => value === true + export { alphalownumdot_, domain, @@ -67,4 +69,5 @@ export { appRepoUrl, name, unique, + checked, } diff --git a/app/src/i18n/locales/en.json b/app/src/i18n/locales/en.json index d9773dcdd..002444417 100644 --- a/app/src/i18n/locales/en.json +++ b/app/src/i18n/locales/en.json @@ -326,7 +326,8 @@ "footer": { "documentation": "Documentation", "donate": "Donate", - "help": "Need help?" + "help": "Need help?", + "tos": "Terms of Services" }, "footer_version": "Powered by YunoHost {version} ({repo}).", "form": { @@ -337,6 +338,7 @@ "alphalownumdot_": "Value must be lower-case alphanumeric, dots and underscore characters only.", "appRepoUrl": "YunoHost app repository URLs are expected to look like https://domain.tld/path/to/repo_ynh", "between": "Value must be between {min} and {max}.", + "checked": "Checkbox must be checked.", "domain": "Invalid domain name: Must be lower-case alphanumeric, dot and dash characters only", "dynDomain": "Invalid domain name: Must be lower-case alphanumeric and dash characters only", "email": "Invalid email: must be alphanumeric and _.- characters only (e.g. someone@example.com, s0me-1@example.com)", @@ -649,6 +651,12 @@ }, "tools_webadmin_settings": "Web-admin settings", "tools_yunohost_settings": "YunoHost settings", + "tos": { + "acknowledgement": "TOS acknowledgement", + "i_agree": "I agree", + "i_have_read": "I have read and understand the Terms of Services", + "postinstall_acknowledgement": "The YunoHost project is a team of volunteers who have made common cause to create a free operating system for servers, called YunoHost. The YunoHost software is published under [the AGPLv3 license](https://www.gnu.org/licenses/agpl-3.0.txt). In connection with this software, the project administers and makes available several technical and community services for various purposes. By using these services, you agree to be bound by the following [Terms of Services](https://yunohost.org/terms_of_services)." + }, "traceback": "Traceback", "udp": "UDP", "unauthorized": "Unauthorized", diff --git a/app/src/views/PostInstall.vue b/app/src/views/PostInstall.vue index fc170a3af..00330d944 100644 --- a/app/src/views/PostInstall.vue +++ b/app/src/views/PostInstall.vue @@ -31,6 +31,7 @@ if (installed.value) { type Steps = 'start' | 'domain' | 'user' | 'rootfsspace-error' | 'login' const step = ref('start') const serverError = ref('') +const tosAcknowledged = ref(false) const domain = ref('') const dyndns_recovery_password = ref() @@ -150,17 +151,30 @@ async function performPostInstall(force = false) {
diff --git a/app/src/views/_partials/DomainForm.vue b/app/src/views/_partials/DomainForm.vue index 0c4d27ddd..99c2b3530 100644 --- a/app/src/views/_partials/DomainForm.vue +++ b/app/src/views/_partials/DomainForm.vue @@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n' import { useForm } from '@/composables/form' import { + checked, domain, dynDomain, minLength, @@ -51,6 +52,7 @@ type Form = { dynDomain: AdressModelValue dynDomainPassword: string dynDomainPasswordConfirmation: string + tosAcknowledged: boolean localDomain: AdressModelValue } const form = ref
({ @@ -58,6 +60,7 @@ const form = ref({ dynDomain: { localPart: '', separator: '.', domain: 'nohost.me' }, dynDomainPassword: '', dynDomainPasswordConfirmation: '', + tosAcknowledged: false, localDomain: { localPart: '', separator: '.', domain: 'local' }, }) const fields = { @@ -118,6 +121,18 @@ const fields = { }, }) satisfies FieldProps<'InputItem', Form['dynDomainPasswordConfirmation']>, + tosAcknowledged: reactive({ + component: 'CheckboxItem', + label: t('tos.acknowledgement'), + rules: computed(() => + selected.value === 'dynDomain' ? { checked } : undefined, + ), + cProps: { + id: 'tos-acknowledged', + label: t('tos.i_have_read'), + }, + }) satisfies FieldProps<'CheckboxItem', Form['tosAcknowledged']>, + localDomain: reactive({ component: 'AdressItem', label: t('domain_name'), @@ -150,6 +165,7 @@ const dynKeys = [ 'dynDomain', 'dynDomainPassword', 'dynDomainPasswordConfirmation', + 'tosAcknowledged', ] as (keyof Form)[] const domainIsVisible = computed(() => {