Skip to content

Commit

Permalink
fix(account): client side validation for user creation (#3639)
Browse files Browse the repository at this point in the history
  • Loading branch information
josephmcg committed Jun 16, 2022
1 parent 4a586d1 commit 1b386d7
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 19 deletions.
7 changes: 7 additions & 0 deletions components/interactables/Input/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ export default Vue.extend({
internalText: this.text ? this.text : '',
}
},
watch: {
internalText(val) {
if (!val.trim().length) {
this.internalText = ''
}
},
},
mounted() {
if (this.autofocus) {
this.$nextTick(() => (this.$refs?.input as HTMLElement).focus())
Expand Down
13 changes: 11 additions & 2 deletions components/views/user/create/Create.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
type="primary"
:minLength="$Config.account.minLength"
:maxLength="$Config.account.maxLength"
:invalid="isInvalidName && Boolean(error)"
:invalid="isInvalidName && Boolean(error.length)"
/>
</div>

Expand All @@ -64,10 +64,19 @@
v-model="status"
input-kind="text"
type="primary"
:maxLength="$Config.account.statusMaxLength"
:invalid="isInvalidStatus && Boolean(error.length)"
/>
</div>

<p class="red" data-cy="error-message" v-if="error">{{error}}</p>
<template v-if="error.length">
<TypographyError
v-for="e in error"
:text="e"
:key="e"
data-cy="error-message"
/>
</template>
</div>

<!-- <hr class="divider"> -->
Expand Down
51 changes: 34 additions & 17 deletions components/views/user/create/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import { PlatformTypeEnum } from '~/libraries/Enums/enums'
const convert = require('heic-convert')
export default Vue.extend({
name: 'CreateUser',
data() {
return {
showCropper: false,
croppedImage: '',
imageUrl: '',
name: '',
error: '',
error: [] as string[],
status: '',
isLoading: false,
}
Expand All @@ -28,9 +27,8 @@ export default Vue.extend({
accountAddress: (state) => (state as RootState).accounts.active,
}),
/**
* @method accountValidLength
* @description If the account isn't the length specified in the config, this returns False, true if correct length
* @example this.accountValidLength
* @method isInvalidName
* @description returns boolean based on current name input
*/
isInvalidName(): boolean {
return (
Expand All @@ -39,6 +37,13 @@ export default Vue.extend({
this.name.trim().length > this.$Config.account.maxLength
)
},
/**
* @method isInvalidStatus
* @description returns boolean based on current status input
*/
isInvalidStatus(): boolean {
return this.status.trim().length > this.$Config.account.statusMaxLength
},
/**
* @method acceptableImageFormats
* @description embeddable types plus HEIC since we can convert
Expand Down Expand Up @@ -77,7 +82,7 @@ export default Vue.extend({
* @example
*/
async selectImage(e: Event) {
this.error = ''
this.error = []
this.isLoading = true
const target = e.target as HTMLInputElement
Expand All @@ -92,7 +97,7 @@ export default Vue.extend({
// stop upload if picture is too large for nsfw scan
if (file.size > this.$Config.nsfwPictureLimit) {
this.error = this.$t('errors.accounts.file_too_large') as string
this.error.push(this.$t('errors.accounts.file_too_large') as string)
this.isLoading = false
return
}
Expand All @@ -112,7 +117,7 @@ export default Vue.extend({
// if invalid file type, prevent upload. this needs to be added since safari mobile doesn't fully support <input> accept
if (!(await isEmbeddableImage(file))) {
this.error = this.$t('errors.accounts.invalid_file') as string
this.error.push(this.$t('errors.accounts.invalid_file') as string)
this.resetFileInput()
this.isLoading = false
return
Expand All @@ -121,14 +126,14 @@ export default Vue.extend({
// if nsfw, prevent upload
try {
if (await this.$Security.isNSFW(file)) {
this.error = this.$t('errors.chat.contains_nsfw') as string
this.error.push(this.$t('errors.chat.contains_nsfw') as string)
this.resetFileInput()
this.isLoading = false
return
}
} catch (e: any) {
this.$Logger.log('error', 'file upload error', e)
this.error = this.$t('errors.accounts.invalid_file') as string
this.error.push(this.$t('errors.accounts.invalid_file') as string)
this.resetFileInput()
this.isLoading = false
return
Expand Down Expand Up @@ -170,22 +175,34 @@ export default Vue.extend({
*/
confirm(e: Event) {
e.preventDefault()
this.error = []
if (this.isLoading) {
return
}
if (this.isInvalidName) {
this.error = this.$t('user.registration.username_error', {
min: this.$Config.account.minLength,
max: this.$Config.account.maxLength,
}) as string
this.error.push(
this.$t('user.registration.username_error', {
min: this.$Config.account.minLength,
max: this.$Config.account.maxLength,
}) as string,
)
}
// additional client side validation in case the user inspected and changed maxlength constraint
if (this.isInvalidStatus) {
this.error.push(
this.$t('user.registration.status_error', {
max: this.$Config.account.statusMaxLength,
}) as string,
)
}
if (this.error.length) {
return
}
this.error = ''
this.$emit('confirm', {
username: this.name,
username: this.name.trim(),
photoHash: this.croppedImage,
status: this.status,
status: this.status.trim(),
})
},
},
Expand Down
1 change: 1 addition & 0 deletions config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export const Config = {
account: {
minLength: 5,
maxLength: 32,
statusMaxLength: 128,
},
profile: {
noteMaxChars: 256,
Expand Down
1 change: 1 addition & 0 deletions locales/en-US.js
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ export default {
'Enter a username of at least {min} characters, up to {max}',
status: 'Status',
status_placeholder: 'Ready for launch...',
status_error: 'Status cannot exceed {max} characters',
reg_status: {
unknown: 'Not registered',
in_progress: "We're transporting your data to the Realm...",
Expand Down

0 comments on commit 1b386d7

Please sign in to comment.