diff --git a/frontend/src/app/models/forms/default-validators.ts b/frontend/src/app/models/forms/default-validators.ts new file mode 100644 index 0000000..8813785 --- /dev/null +++ b/frontend/src/app/models/forms/default-validators.ts @@ -0,0 +1,61 @@ +import { ValidationErrors, Validators } from '@angular/forms'; + +// Match this with user entity in shared lib +// (Security is not handled here, this is only for the user) + +function errorsToError(errors: ValidationErrors | null): string { + if (errors) { + const error = Object.keys(errors)[0]; + return error; + } + return 'unkown'; +} + +export const UsernameValidators = [ + Validators.required, + Validators.minLength(4), + Validators.maxLength(32), + Validators.pattern('^[a-zA-Z0-9]+$'), +]; + +export const CreateUsernameError = ( + errors: ValidationErrors | null +): string => { + const error = errorsToError(errors); + switch (error) { + case 'required': + return 'Username is required'; + case 'minlength': + return 'Username is too short'; + case 'maxlength': + return 'Username is too long'; + case 'pattern': + return 'Username can only contain letters and numbers'; + default: + return 'Invalid username'; + } +}; + +export const PasswordValidators = [ + Validators.required, + Validators.minLength(4), + Validators.maxLength(1024), +]; + +export const CreatePasswordError = ( + errors: ValidationErrors | null +): string => { + const error = errorsToError(errors); + switch (error) { + case 'required': + return 'Password is required'; + case 'minlength': + return 'Password is too short'; + case 'maxlength': + return 'Password is too long'; + case 'compare': + return 'Password does not match'; + default: + return 'Invalid password'; + } +}; diff --git a/frontend/src/app/models/forms/login.model.ts b/frontend/src/app/models/forms/login.model.ts index dbdb1fd..0cb7946 100644 --- a/frontend/src/app/models/forms/login.model.ts +++ b/frontend/src/app/models/forms/login.model.ts @@ -1,43 +1,29 @@ -import { FormControl, Validators } from '@angular/forms'; +import { FormControl } from '@angular/forms'; import { Fail, Failable } from 'picsur-shared/dist/types'; +import { + CreatePasswordError, + CreateUsernameError, + PasswordValidators, + UsernameValidators +} from './default-validators'; import { UserPassModel } from './userpass'; export class LoginControl { - public username = new FormControl('', [ - Validators.required, - Validators.minLength(3), - ]); - - public password = new FormControl('', [ - Validators.required, - Validators.minLength(3), - ]); + public username = new FormControl('', UsernameValidators); + public password = new FormControl('', PasswordValidators); public get usernameError() { - return this.username.hasError('required') - ? 'Username is required' - : this.username.hasError('minlength') - ? 'Username is too short' - : ''; + return CreateUsernameError(this.username.errors); } public get passwordError() { - return this.password.hasError('required') - ? 'Password is required' - : this.password.hasError('minlength') - ? 'Password is too short' - : ''; + return CreatePasswordError(this.password.errors); } public getData(): Failable { - if (this.username.errors || this.password.errors) { + if (this.username.errors || this.password.errors) return Fail('Invalid username or password'); - } else { - return { - username: this.username.value, - password: this.password.value, - }; - } + else return this.getRawData(); } public getRawData(): UserPassModel { diff --git a/frontend/src/app/models/forms/register.model.ts b/frontend/src/app/models/forms/register.model.ts index a02c5c5..5397a9b 100644 --- a/frontend/src/app/models/forms/register.model.ts +++ b/frontend/src/app/models/forms/register.model.ts @@ -1,49 +1,32 @@ -import { FormControl, Validators } from '@angular/forms'; +import { FormControl } from '@angular/forms'; import { Fail, Failable } from 'picsur-shared/dist/types'; import { Compare } from './compare.validator'; +import { + CreatePasswordError, + CreateUsernameError, + PasswordValidators, + UsernameValidators +} from './default-validators'; import { UserPassModel } from './userpass'; export class RegisterControl { - public username = new FormControl('', [ - Validators.required, - Validators.minLength(3), - ]); - - public password = new FormControl('', [ - Validators.required, - Validators.minLength(3), - ]); - + public username = new FormControl('', UsernameValidators); + public password = new FormControl('', PasswordValidators); public passwordConfirm = new FormControl('', [ - Validators.required, - Validators.minLength(3), + ...PasswordValidators, Compare(this.password), ]); public get usernameError() { - return this.username.hasError('required') - ? 'Username is required' - : this.username.hasError('minlength') - ? 'Username is too short' - : ''; + return CreateUsernameError(this.username.errors); } public get passwordError() { - return this.password.hasError('required') - ? 'Password is required' - : this.password.hasError('minlength') - ? 'Password is too short' - : ''; + return CreatePasswordError(this.password.errors); } public get passwordConfirmError() { - return this.passwordConfirm.hasError('required') - ? 'Password confirmation is required' - : this.passwordConfirm.hasError('minlength') - ? 'Password confirmation is too short' - : this.passwordConfirm.hasError('compare') - ? 'Password confirmation does not match' - : ''; + return CreatePasswordError(this.passwordConfirm.errors); } public getData(): Failable { @@ -51,14 +34,9 @@ export class RegisterControl { this.username.errors || this.password.errors || this.passwordConfirm.errors - ) { + ) return Fail('Invalid username or password'); - } else { - return { - username: this.username.value, - password: this.password.value, - }; - } + else return this.getRawData(); } public getRawData(): UserPassModel { diff --git a/frontend/src/app/routes/settings/settings-users/settings-users.component.html b/frontend/src/app/routes/settings/settings-users/settings-users.component.html index 09fc67b..f542268 100644 --- a/frontend/src/app/routes/settings/settings-users/settings-users.component.html +++ b/frontend/src/app/routes/settings/settings-users/settings-users.component.html @@ -1,19 +1,30 @@

Users

- + - - + ID + {{ user.id }} - - + Username + {{ user.username }} - - -
ID{{ user.id }} Username{{ user.username }}
+ + Actions + + + + + + + + pog + +