Browse Source

Refine input validation

Signed-off-by: Christopher Ng <chrng8@gmail.com>
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
tags/v23.0.0beta1
Christopher Ng 2 years ago
parent
commit
f6119b7f23
30 changed files with 221 additions and 189 deletions
  1. 9
    9
      apps/settings/js/vue-settings-admin-security.js
  2. 1
    1
      apps/settings/js/vue-settings-admin-security.js.map
  3. 5
    5
      apps/settings/js/vue-settings-apps-users-management.js
  4. 1
    1
      apps/settings/js/vue-settings-apps-users-management.js.map
  5. 2
    2
      apps/settings/js/vue-settings-apps.js
  6. 1
    1
      apps/settings/js/vue-settings-apps.js.map
  7. 2
    2
      apps/settings/js/vue-settings-nextcloud-pdf.js
  8. 1
    1
      apps/settings/js/vue-settings-nextcloud-pdf.js.map
  9. 34
    12
      apps/settings/js/vue-settings-personal-info.js
  10. 1
    1
      apps/settings/js/vue-settings-personal-info.js.map
  11. 18
    18
      apps/settings/js/vue-settings-personal-security.js
  12. 1
    1
      apps/settings/js/vue-settings-personal-security.js.map
  13. 8
    8
      apps/settings/js/vue-settings-personal-webauthn.js
  14. 1
    1
      apps/settings/js/vue-settings-personal-webauthn.js.map
  15. 3
    3
      apps/settings/js/vue-settings-users.js
  16. 1
    1
      apps/settings/js/vue-settings-users.js.map
  17. 14
    14
      apps/settings/js/vue-vendors-settings-apps-settings-users.js
  18. 1
    1
      apps/settings/js/vue-vendors-settings-apps-settings-users.js.map
  19. 6
    6
      apps/settings/js/vue-vendors-settings-apps.js
  20. 1
    1
      apps/settings/js/vue-vendors-settings-apps.js.map
  21. 20
    20
      apps/settings/js/vue-vendors-settings-users.js
  22. 1
    1
      apps/settings/js/vue-vendors-settings-users.js.map
  23. 13
    13
      apps/settings/src/components/PersonalInfo/DisplayNameSection/DisplayName.vue
  24. 4
    5
      apps/settings/src/components/PersonalInfo/DisplayNameSection/DisplayNameSection.vue
  25. 13
    18
      apps/settings/src/components/PersonalInfo/EmailSection/Email.vue
  26. 4
    5
      apps/settings/src/components/PersonalInfo/EmailSection/EmailSection.vue
  27. 19
    2
      apps/settings/src/components/PersonalInfo/LanguageSection/Language.vue
  28. 11
    23
      apps/settings/src/components/PersonalInfo/LanguageSection/LanguageSection.vue
  29. 8
    13
      apps/settings/src/components/PersonalInfo/shared/HeaderBar.vue
  30. 17
    0
      apps/settings/src/utils/validate.js

+ 9
- 9
apps/settings/js/vue-settings-admin-security.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-admin-security.js.map
File diff suppressed because it is too large
View File


+ 5
- 5
apps/settings/js/vue-settings-apps-users-management.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-apps-users-management.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
apps/settings/js/vue-settings-apps.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-apps.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
apps/settings/js/vue-settings-nextcloud-pdf.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-nextcloud-pdf.js.map
File diff suppressed because it is too large
View File


+ 34
- 12
apps/settings/js/vue-settings-personal-info.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-personal-info.js.map
File diff suppressed because it is too large
View File


+ 18
- 18
apps/settings/js/vue-settings-personal-security.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-personal-security.js.map
File diff suppressed because it is too large
View File


+ 8
- 8
apps/settings/js/vue-settings-personal-webauthn.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-personal-webauthn.js.map
File diff suppressed because it is too large
View File


+ 3
- 3
apps/settings/js/vue-settings-users.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-settings-users.js.map
File diff suppressed because it is too large
View File


+ 14
- 14
apps/settings/js/vue-vendors-settings-apps-settings-users.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-vendors-settings-apps-settings-users.js.map
File diff suppressed because it is too large
View File


+ 6
- 6
apps/settings/js/vue-vendors-settings-apps.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-vendors-settings-apps.js.map
File diff suppressed because it is too large
View File


+ 20
- 20
apps/settings/js/vue-vendors-settings-users.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/settings/js/vue-vendors-settings-users.js.map
File diff suppressed because it is too large
View File


+ 13
- 13
apps/settings/src/components/PersonalInfo/DisplayNameSection/DisplayName.vue View File

display: grid; display: grid;
align-items: center; align-items: center;


input {
grid-area: 1 / 1;
height: 34px;
width: 100%;
margin: 3px 3px 3px 0;
padding: 7px 6px;
cursor: text;
font-family: var(--font-face);
border: 1px solid var(--color-border-dark);
border-radius: var(--border-radius);
background-color: var(--color-main-background);
color: var(--color-main-text);
}
input {
grid-area: 1 / 1;
width: 100%;
height: 34px;
margin: 3px 3px 3px 0;
padding: 7px 6px;
color: var(--color-main-text);
border: 1px solid var(--color-border-dark);
border-radius: var(--border-radius);
background-color: var(--color-main-background);
font-family: var(--font-face);
cursor: text;
}


.displayname__actions-container { .displayname__actions-container {
grid-area: 1 / 1; grid-area: 1 / 1;

+ 4
- 5
apps/settings/src/components/PersonalInfo/DisplayNameSection/DisplayNameSection.vue View File

</script> </script>


<style lang="scss" scoped> <style lang="scss" scoped>
section {
padding: 10px 10px;
section {
padding: 10px 10px;


&::v-deep button:disabled {
cursor: default;
}
&::v-deep button:disabled {
cursor: default;
} }
} }
</style> </style>

+ 13
- 18
apps/settings/src/components/PersonalInfo/EmailSection/Email.vue View File

display: grid; display: grid;
align-items: center; align-items: center;


input {
grid-area: 1 / 1;
height: 34px;
width: 100%;
margin: 3px 3px 3px 0;
padding: 7px 6px;
cursor: text;
font-family: var(--font-face);
border: 1px solid var(--color-border-dark);
border-radius: var(--border-radius);
background-color: var(--color-main-background);
color: var(--color-main-text);
}

.email__actions-container {
grid-area: 1 / 1;
justify-self: flex-end;
height: 30px;
input {
grid-area: 1 / 1;
width: 100%;
height: 34px;
margin: 3px 3px 3px 0;
padding: 7px 6px;
color: var(--color-main-text);
border: 1px solid var(--color-border-dark);
border-radius: var(--border-radius);
background-color: var(--color-main-background);
font-family: var(--font-face);
cursor: text;
}


.email__actions-container { .email__actions-container {
grid-area: 1 / 1; grid-area: 1 / 1;

+ 4
- 5
apps/settings/src/components/PersonalInfo/EmailSection/EmailSection.vue View File

</script> </script>


<style lang="scss" scoped> <style lang="scss" scoped>
section {
padding: 10px 10px;
section {
padding: 10px 10px;


&::v-deep button:disabled {
cursor: default;
}
&::v-deep button:disabled {
cursor: default;
} }
} }
</style> </style>

+ 19
- 2
apps/settings/src/components/PersonalInfo/LanguageSection/Language.vue View File

name="language" name="language"
:placeholder="t('settings', 'Language')" :placeholder="t('settings', 'Language')"
required required
@input="onLanguageChange">
@change="onLanguageChange">
<option v-for="commonLanguage in commonLanguages" <option v-for="commonLanguage in commonLanguages"
:key="commonLanguage.code" :key="commonLanguage.code"
:selected="language.code === commonLanguage.code" :selected="language.code === commonLanguage.code"
import { showError } from '@nextcloud/dialogs' import { showError } from '@nextcloud/dialogs'


import { saveLanguage } from '../../../service/PersonalInfo/LanguageService' import { saveLanguage } from '../../../service/PersonalInfo/LanguageService'
import { validateLanguage } from '../../../utils/validate'


export default { export default {
name: 'Language', name: 'Language',
const language = this.constructLanguage(e.target.value) const language = this.constructLanguage(e.target.value)
this.$emit('update:language', language) this.$emit('update:language', language)


if (this.$refs.language?.checkValidity()) {
if (validateLanguage(language)) {
await this.updateLanguage(language) await this.updateLanguage(language)
} }
}, },
.language { .language {
display: grid; display: grid;


select {
width: 100%;
height: 34px;
margin: 3px 3px 3px 0;
padding: 6px 16px;
color: var(--color-main-text);
border: 1px solid var(--color-border-dark);
border-radius: var(--border-radius);
background: var(--icon-triangle-s-000) no-repeat right 4px center;
font-family: var(--font-face);
appearance: none;
cursor: pointer;
}

a { a {
color: var(--color-main-text);
text-decoration: none;
width: max-content; width: max-content;
} }
} }

+ 11
- 23
apps/settings/src/components/PersonalInfo/LanguageSection/LanguageSection.vue View File

--> -->


<template> <template>
<form
ref="form"
class="section"
@submit.stop.prevent="() => {}">
<section>
<HeaderBar <HeaderBar
:account-property="accountProperty" :account-property="accountProperty"
label-for="language" label-for="language"
:is-valid-form="isValidForm" />
:is-valid-section="isValidSection" />


<template v-if="isEditable"> <template v-if="isEditable">
<Language <Language
:common-languages="commonLanguages" :common-languages="commonLanguages"
:other-languages="otherLanguages" :other-languages="otherLanguages"
:language.sync="language"
@update:language="onUpdateLanguage" />
:language.sync="language" />
</template> </template>


<span v-else> <span v-else>
{{ t('settings', 'No language set') }} {{ t('settings', 'No language set') }}
</span> </span>
</form>
</section>
</template> </template>


<script> <script>
import HeaderBar from '../shared/HeaderBar' import HeaderBar from '../shared/HeaderBar'


import { SETTING_PROPERTY_READABLE_ENUM } from '../../../constants/AccountPropertyConstants' import { SETTING_PROPERTY_READABLE_ENUM } from '../../../constants/AccountPropertyConstants'
import { validateLanguage } from '../../../utils/validate'


const { languages: { activeLanguage, commonLanguages, otherLanguages } } = loadState('settings', 'personalInfoParameters', {}) const { languages: { activeLanguage, commonLanguages, otherLanguages } } = loadState('settings', 'personalInfoParameters', {})


data() { data() {
return { return {
accountProperty: SETTING_PROPERTY_READABLE_ENUM.LANGUAGE, accountProperty: SETTING_PROPERTY_READABLE_ENUM.LANGUAGE,
isValidForm: true,
commonLanguages, commonLanguages,
otherLanguages, otherLanguages,
language: activeLanguage, language: activeLanguage,
isEditable() { isEditable() {
return Boolean(this.language) return Boolean(this.language)
}, },
},

mounted() {
this.$nextTick(() => this.updateFormValidity())
},


methods: {
onUpdateLanguage() {
this.$nextTick(() => this.updateFormValidity())
},

updateFormValidity() {
this.isValidForm = this.$refs.form?.checkValidity()
isValidSection() {
return validateLanguage(this.language)
}, },
}, },
} }
</script> </script>


<style lang="scss" scoped> <style lang="scss" scoped>
form::v-deep button {
&:disabled {
section {
padding: 10px 10px;

&::v-deep button:disabled {
cursor: default; cursor: default;
} }
} }

+ 8
- 13
apps/settings/src/components/PersonalInfo/shared/HeaderBar.vue View File



<style lang="scss" scoped> <style lang="scss" scoped>
h3 { h3 {
display: inline-flex;
width: 100%;
margin: 12px 0 0 0;
display: inline-flex;
width: 100%;
margin: 12px 0 0 0;
font-size: 16px; font-size: 16px;
color: var(--color-text-light);
color: var(--color-text-light);

&.setting-property {
height: 38px;
}


label { label {
cursor: pointer; cursor: pointer;
} }
} }


h3.setting-property {
width: 100%;
min-height: 38px;
display: inline-flex;
position: relative;
flex-wrap: nowrap;
justify-content: flex-start;
}

.federation-control { .federation-control {
margin: -12px 0 0 8px; margin: -12px 0 0 8px;
} }

+ 17
- 0
apps/settings/src/utils/validate.js View File

* *
*/ */


/*
* Frontend validators, less strict than backend validators
*
* TODO add nice validation errors for Profile page settings modal
*/

import { VALIDATE_EMAIL_REGEX } from '../constants/AccountPropertyConstants' import { VALIDATE_EMAIL_REGEX } from '../constants/AccountPropertyConstants'


/** /**
&& input.length <= 320 && input.length <= 320
&& encodeURIComponent(input).replace(/%../g, 'x').length <= 320 && encodeURIComponent(input).replace(/%../g, 'x').length <= 320
} }

/**
* Validate the language input
*
* @param {string} input the input
* @returns {boolean}
*/
export function validateLanguage(input) {
return input.code !== ''
&& input.name
}

Loading…
Cancel
Save