diff --git a/web/satellite/src/components/account/ChangePasswordPopup.vue b/web/satellite/src/components/account/ChangePasswordPopup.vue index 1d1d398f4..e0b82553a 100644 --- a/web/satellite/src/components/account/ChangePasswordPopup.vue +++ b/web/satellite/src/components/account/ChangePasswordPopup.vue @@ -82,7 +82,7 @@ import CloseCrossIcon from '@/../static/images/common/closeCross.svg'; import { AuthHttpApi } from '@/api/auth'; import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames'; -import { validatePassword } from '@/utils/validation'; +import { Validator } from '@/utils/validation'; @Component({ components: { @@ -142,7 +142,7 @@ export default class ChangePasswordPopup extends Vue { hasError = true; } - if (!validatePassword(this.newPassword)) { + if (!Validator.password(this.newPassword)) { this.newPasswordError = 'Invalid password. Use 6 or more characters'; hasError = true; } diff --git a/web/satellite/src/components/account/DeleteAccountPopup.vue b/web/satellite/src/components/account/DeleteAccountPopup.vue index 6c177f2e2..31422c974 100644 --- a/web/satellite/src/components/account/DeleteAccountPopup.vue +++ b/web/satellite/src/components/account/DeleteAccountPopup.vue @@ -55,7 +55,7 @@ import { AuthHttpApi } from '@/api/auth'; import { RouteConfig } from '@/router'; import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames'; import { SegmentEvent } from '@/utils/constants/analyticsEventNames'; -import { validatePassword } from '@/utils/validation'; +import { Validator } from '@/utils/validation'; @Component({ components: { @@ -87,7 +87,7 @@ export default class DeleteAccountPopup extends Vue { this.isLoading = true; - if (!validatePassword(this.password)) { + if (!Validator.password(this.password)) { this.passwordError = 'Invalid password. Must be 6 or more characters'; this.isLoading = false; diff --git a/web/satellite/src/components/onboardingTour/steps/CreateProjectStep.vue b/web/satellite/src/components/onboardingTour/steps/CreateProjectStep.vue index 2478c5884..89ca290fe 100644 --- a/web/satellite/src/components/onboardingTour/steps/CreateProjectStep.vue +++ b/web/satellite/src/components/onboardingTour/steps/CreateProjectStep.vue @@ -68,7 +68,7 @@ import { PROJECTS_ACTIONS } from '@/store/modules/projects'; import { CreateProjectModel, Project } from '@/types/projects'; import { PM_ACTIONS } from '@/utils/constants/actionNames'; import { SegmentEvent } from '@/utils/constants/analyticsEventNames'; -import { anyCharactersButSlash } from '@/utils/validation'; +import { Validator } from '@/utils/validation'; @Component({ components: { @@ -186,7 +186,7 @@ export default class CreateProjectStep extends Vue { return false; } - if (!anyCharactersButSlash(this.projectName)) { + if (!Validator.anyCharactersButSlash(this.projectName)) { this.nameError = 'Project name can\'t have forward slash'; return false; diff --git a/web/satellite/src/components/team/AddUserPopup.vue b/web/satellite/src/components/team/AddUserPopup.vue index 7afc03457..8ac4e0f17 100644 --- a/web/satellite/src/components/team/AddUserPopup.vue +++ b/web/satellite/src/components/team/AddUserPopup.vue @@ -86,7 +86,7 @@ import { RouteConfig } from '@/router'; import { EmailInput } from '@/types/EmailInput'; import { APP_STATE_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames'; import { SegmentEvent } from '@/utils/constants/analyticsEventNames'; -import { validateEmail } from '@/utils/validation'; +import { Validator } from '@/utils/validation'; @Component({ components: { @@ -125,7 +125,7 @@ export default class AddUserPopup extends Vue { for (let i = 0; i < length; i++) { const element = this.inputs[i]; - const isEmail = validateEmail(element.value); + const isEmail = Validator.email(element.value); if (isEmail) { emailArray.push(element.value); diff --git a/web/satellite/src/utils/validation.ts b/web/satellite/src/utils/validation.ts index d43548486..8daffa4c4 100644 --- a/web/satellite/src/utils/validation.ts +++ b/web/satellite/src/utils/validation.ts @@ -1,19 +1,33 @@ // Copyright (C) 2019 Storj Labs, Inc. // See LICENSE for copying information. -// TODO: move functions to Validator class -export function validateEmail(email: string): boolean { - const rgx = /.*@.*\..*$/; +/** + * Validator holds validation check methods for strings. + */ +export class Validator { - return rgx.test(email); -} - -export function validatePassword(password: string): boolean { - return typeof password !== 'undefined' && password.length >= 6; -} - -export function anyCharactersButSlash(string: string): boolean { - const rgx = /^[^\/]+$/; - - return rgx.test(string); + /** + * Checks string to satisfy email rules. + */ + public static email(email: string): boolean { + const rgx = /.*@.*\..*$/; + + return rgx.test(email); + } + + /** + * Checks string to satisfy password rules. + */ + public static password(password: string): boolean { + return typeof password !== 'undefined' && password.length >= 6; + } + + /** + * Checks string to not include slash. + */ + public static anyCharactersButSlash(string: string): boolean { + const rgx = /^[^\/]+$/; + + return rgx.test(string); + } } diff --git a/web/satellite/src/views/forgotPassword/ForgotPassword.vue b/web/satellite/src/views/forgotPassword/ForgotPassword.vue index edf517068..eaf827c8f 100644 --- a/web/satellite/src/views/forgotPassword/ForgotPassword.vue +++ b/web/satellite/src/views/forgotPassword/ForgotPassword.vue @@ -13,7 +13,7 @@ import LogoIcon from '@/../static/images/Logo.svg'; import { AuthHttpApi } from '@/api/auth'; import { RouteConfig } from '@/router'; -import { validateEmail } from '@/utils/validation'; +import { Validator } from '@/utils/validation'; @Component({ components: { @@ -90,7 +90,7 @@ export default class ForgotPassword extends Vue { } private validateFields(): boolean { - const isEmailValid = validateEmail(this.email.trim()); + const isEmailValid = Validator.email(this.email.trim()); if (!isEmailValid) { this.emailError = 'Invalid Email'; diff --git a/web/satellite/src/views/login/LoginArea.vue b/web/satellite/src/views/login/LoginArea.vue index 3a22646a6..bac4434e2 100644 --- a/web/satellite/src/views/login/LoginArea.vue +++ b/web/satellite/src/views/login/LoginArea.vue @@ -16,7 +16,7 @@ import { RouteConfig } from '@/router'; import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames'; import { SegmentEvent } from '@/utils/constants/analyticsEventNames'; import { AppState } from '@/utils/constants/appStateEnum'; -import { validateEmail, validatePassword } from '@/utils/validation'; +import { Validator } from '@/utils/validation'; @Component({ components: { @@ -133,12 +133,12 @@ export default class Login extends Vue { private validateFields(): boolean { let isNoErrors = true; - if (!validateEmail(this.email.trim())) { + if (!Validator.email(this.email.trim())) { this.emailError = 'Invalid Email'; isNoErrors = false; } - if (!validatePassword(this.password)) { + if (!Validator.password(this.password)) { this.passwordError = 'Invalid Password'; isNoErrors = false; } diff --git a/web/satellite/src/views/register/RegisterArea.vue b/web/satellite/src/views/register/RegisterArea.vue index b63bc01f9..56e4a7277 100644 --- a/web/satellite/src/views/register/RegisterArea.vue +++ b/web/satellite/src/views/register/RegisterArea.vue @@ -20,7 +20,7 @@ import { User } from '@/types/users'; import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames'; import { LocalData } from '@/utils/localData'; import { MetaUtils } from '@/utils/meta'; -import { validateEmail, validatePassword } from '@/utils/validation'; +import { Validator } from '@/utils/validation'; @Component({ components: { @@ -212,12 +212,12 @@ export default class RegisterArea extends Vue { isNoErrors = false; } - if (!validateEmail(this.user.email.trim())) { + if (!Validator.email(this.user.email.trim())) { this.emailError = 'Invalid Email'; isNoErrors = false; } - if (!validatePassword(this.password)) { + if (!Validator.password(this.password)) { this.passwordError = 'Invalid Password'; isNoErrors = false; } diff --git a/web/satellite/tests/unit/utils/validation.spec.ts b/web/satellite/tests/unit/utils/validation.spec.ts index a0da7c836..ac58332b5 100644 --- a/web/satellite/tests/unit/utils/validation.spec.ts +++ b/web/satellite/tests/unit/utils/validation.spec.ts @@ -1,13 +1,10 @@ // Copyright (C) 2019 Storj Labs, Inc. // See LICENSE for copying information. -import { - validateEmail, - validatePassword, -} from '@/utils/validation'; +import { Validator } from '@/utils/validation'; -describe('validation', () => { - it('validatePassword regex works correctly', () => { +describe('validation', (): void => { + it('password regex works correctly', (): void => { const testString1 = 'test'; const testString2 = ' '.trim(); const testString3 = 'test %%%'; @@ -16,16 +13,16 @@ describe('validation', () => { const testString6 = 'test1'; const testString7 = 'teSTt1123'; - expect(validatePassword(testString1)).toBe(false); - expect(validatePassword(testString2)).toBe(false); - expect(validatePassword(testString3)).toBe(true); - expect(validatePassword(testString4)).toBe(true); - expect(validatePassword(testString5)).toBe(true); - expect(validatePassword(testString6)).toBe(false); - expect(validatePassword(testString7)).toBe(true); + expect(Validator.password(testString1)).toBe(false); + expect(Validator.password(testString2)).toBe(false); + expect(Validator.password(testString3)).toBe(true); + expect(Validator.password(testString4)).toBe(true); + expect(Validator.password(testString5)).toBe(true); + expect(Validator.password(testString6)).toBe(false); + expect(Validator.password(testString7)).toBe(true); }); - it('validateEmail regex works correctly', () => { + it('email regex works correctly', () => { const testString1 = 'test'; const testString2 = ' '; const testString3 = 'test@'; @@ -34,12 +31,30 @@ describe('validation', () => { const testString6 = ''; const testString7 = '@teSTt.1123'; - expect(validateEmail(testString1)).toBe(false); - expect(validateEmail(testString2)).toBe(false); - expect(validateEmail(testString3)).toBe(false); - expect(validateEmail(testString4)).toBe(false); - expect(validateEmail(testString5)).toBe(true); - expect(validateEmail(testString6)).toBe(false); - expect(validateEmail(testString7)).toBe(true); + expect(Validator.email(testString1)).toBe(false); + expect(Validator.email(testString2)).toBe(false); + expect(Validator.email(testString3)).toBe(false); + expect(Validator.email(testString4)).toBe(false); + expect(Validator.email(testString5)).toBe(true); + expect(Validator.email(testString6)).toBe(false); + expect(Validator.email(testString7)).toBe(true); + }); + + it('anyCharactersButSlash regex works correctly', () => { + const testString1 = 'tGDFst/'; + const testString2 = '/ '; + const testString3 = 'tes/t@'; + const testString4 = 'test./test'; + const testString5 = '3gGD!@#$%^&*()-=+.,'; + const testString6 = ' /'; + const testString7 = '/teSTt1123'; + + expect(Validator.anyCharactersButSlash(testString1)).toBe(false); + expect(Validator.anyCharactersButSlash(testString2)).toBe(false); + expect(Validator.anyCharactersButSlash(testString3)).toBe(false); + expect(Validator.anyCharactersButSlash(testString4)).toBe(false); + expect(Validator.anyCharactersButSlash(testString5)).toBe(true); + expect(Validator.anyCharactersButSlash(testString6)).toBe(false); + expect(Validator.anyCharactersButSlash(testString7)).toBe(false); }); });