diff --git a/app/src/locales/en.json b/app/src/locales/en.json
index 136a57c5..f8e81f4f 100644
--- a/app/src/locales/en.json
+++ b/app/src/locales/en.json
@@ -119,6 +119,11 @@
"experimental_warning": "Warning: this feature is experimental and not consider stable, you shouldn't be using it except if you know what you are doing.",
"firewall": "Firewall",
"footer_version": "Powered by {ynh} {version} ({repo}).",
+ "form_errors": {
+ "username_syntax": "Invalid username: Must be lower-case alphanumeric and underscore characters only",
+ "username_exists": "The user '{user}' already exists",
+ "email_syntax": "Invalid email: Must be alphanumeric, underscore and dash characters only (e.g. someone@example.com, s0me-1@example.com)"
+ },
"form_input_example": "Example: %s",
"from_to": "from %s to %s",
"good_practices_about_admin_password": "You are now about to define a new admin password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
diff --git a/app/src/scss/main.scss b/app/src/scss/main.scss
index ef067c6d..84ea866b 100644
--- a/app/src/scss/main.scss
+++ b/app/src/scss/main.scss
@@ -30,6 +30,12 @@ body {
color: #333;
}
+.input-group.is-invalid {
+ ~ .invalid-feedback {
+ display: block;
+ }
+}
+
// Fork-awesome overrides
.fa-fw {
diff --git a/app/src/views/Login.vue b/app/src/views/Login.vue
index 493c2939..f27cebe2 100644
--- a/app/src/views/Login.vue
+++ b/app/src/views/Login.vue
@@ -58,9 +58,4 @@ export default {
diff --git a/app/src/views/user/UserCreate.vue b/app/src/views/user/UserCreate.vue
index 98967c1f..fa6516cb 100644
--- a/app/src/views/user/UserCreate.vue
+++ b/app/src/views/user/UserCreate.vue
@@ -8,9 +8,15 @@
label-cols-sm="5" label-cols-lg="4" label-cols-xl="3"
:label="$t('user_username')" label-for="input-username" label-class="test"
>
-
+
+ {{ this.error.username }}
+
@@ -51,12 +57,14 @@
@@ -67,6 +75,10 @@
+
+
+ {{ this.error.email }}
+
-
+
{{ $t('passwords_too_short') }}
@@ -103,13 +116,18 @@
>
-
+
{{ $t('passwords_dont_match') }}
+
+
+ {{ this.server.error }}
+
@@ -137,43 +155,86 @@ export default {
password: '',
confirmation: ''
},
- validation: {
+ isValid: {
+ username: null,
+ email: null,
password: null,
confirmation: null
+ },
+ error: {
+ username: '',
+ email: ''
+ },
+ server: {
+ isValid: null,
+ error: ''
}
}
},
+
computed: {
domains () {
return this.$store.state.data.domains
}
},
- watch: {
- domains (domains) {
- this.form.domain = domains[0]
- }
- },
+
methods: {
onSubmit () {
- const data = this.form
- for (const key in this.validation) {
- if (this.validation[key] === false) return
+ for (const key in this.isValid) {
+ if (this.isValid[key] === false) return
}
+
+ const data = JSON.parse(JSON.stringify(this.form))
const quota = data.mailbox_quota
data.mailbox_quota = parseInt(quota) ? quota + 'M' : 0
data.mail = `${data.email}@${data.domain}`
- // TODO post data
+
+ this.$store.dispatch('POST',
+ { uri: 'users', data, param: data.username, storeKey: '' }
+ ).catch(error => {
+ this.server.error = error.message
+ this.server.isValid = false
+ })
},
+
+ populateEmail () {
+ if (this.form.email === '') {
+ this.form.email = this.form.username
+ }
+ },
+
+ validateUsername () {
+ const username = this.form.username
+ let error = ''
+ if (!username.match('^[a-z0-9_]+$')) {
+ // FIXME check allowed characters
+ error = this.$i18n.t('form_errors.username_syntax')
+ } else if (Object.keys(this.$store.state.data.users).includes(username)) {
+ error = this.$i18n.t('form_errors.username_exists', { user: username })
+ }
+ this.error.username = error
+ this.isValid.username = error === '' ? null : false
+ },
+
+ validateEmail () {
+ // FIXME check allowed characters
+ const isValid = this.form.email.match('^[A-Za-z0-9-_]+$')
+ this.error.email = isValid ? '' : this.$i18n.t('form_errors.email_syntax')
+ this.isValid.email = isValid ? null : false
+ },
+
validatePassword () {
const { password, confirmation } = this.form
- this.validation.password = password.length >= 8 ? null : false
- this.validation.confirmation = password === confirmation ? null : false
+ this.isValid.password = password.length >= 8 ? null : false
+ this.isValid.confirmation = password === confirmation ? null : false
}
},
+
created () {
this.$store.dispatch('FETCH', { uri: 'domains' }).then(domains => {
this.form.domain = domains[0]
})
+ this.$store.dispatch('FETCH', { uri: 'users' })
}
}