From 826eef93bdf37d46230ae5c48d1978d546e3dcc7 Mon Sep 17 00:00:00 2001 From: gaspard Date: Wed, 7 Aug 2024 13:55:55 +0200 Subject: [PATCH] fix: restrict userName characters --- .../admin/users/newUser/validation.test.ts | 23 +++++++++++++++++-- .../admin/users/newUser/validation.ts | 12 +++++++--- src/resources/i18n/en.json | 3 ++- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/components/accessories/admin/users/newUser/validation.test.ts b/src/components/accessories/admin/users/newUser/validation.test.ts index d10e4597f..cf00897e9 100644 --- a/src/components/accessories/admin/users/newUser/validation.test.ts +++ b/src/components/accessories/admin/users/newUser/validation.test.ts @@ -1,8 +1,8 @@ -import { passwordRules } from "./validation"; +import { passwordRules, userNameRules } from "./validation"; describe("password rules", () => { it("should pass when all rules are matched", () => { - expect(passwordRules.test("ThisPassw0rdIsCorrect")); + expect(passwordRules.test("ThisPassw0rdIsCorrect")).toBeTruthy(); }); it("should be 5 characters long", () => { expect(passwordRules.test("aA4")).toBeFalsy(); @@ -17,3 +17,22 @@ describe("password rules", () => { expect(passwordRules.test("ThisPasswordIsNotCorrect")).toBeFalsy(); }); }); + +describe("userName rules", () => { + it("should pass", () => { + expect(userNameRules.test("johndoe")).toBeTruthy(); + expect(userNameRules.test("johndoe42")).toBeTruthy(); + expect(userNameRules.test("42")).toBeTruthy(); + expect(userNameRules.test("john.doe")).toBeTruthy(); + expect(userNameRules.test("john-doe")).toBeTruthy(); + expect(userNameRules.test("john_doe")).toBeTruthy(); + }); + it("should filter out", () => { + expect(userNameRules.test("Johndoe")).toBeFalsy(); + expect(userNameRules.test("johnDoe")).toBeFalsy(); + expect(userNameRules.test("john doe")).toBeFalsy(); + expect(userNameRules.test("john/doe")).toBeFalsy(); + expect(userNameRules.test("すず")).toBeFalsy(); + expect(userNameRules.test("j̵̨̨̧͖̠̩̤̗̟̲̯̭̫̰͆͛̏͛͒́̂̔̅͘͘̚̕͝͝ȯ̵̫̭̮̖̀̓̾̉͋͋̌̇͘h̶̡̢̡̜̻̥͙̳͉̰̟̬͚̍̃̽̎͒̋̄̔͋͘͝͝ͅn̷̜̠̰͍̤̰̺̠͌̌̒͑̓̌̂̒͗͒͗̐͝͝͠")).toBeFalsy(); + }); +}); diff --git a/src/components/accessories/admin/users/newUser/validation.ts b/src/components/accessories/admin/users/newUser/validation.ts index 54b219eb7..3e13775c8 100644 --- a/src/components/accessories/admin/users/newUser/validation.ts +++ b/src/components/accessories/admin/users/newUser/validation.ts @@ -1,13 +1,19 @@ -import { object, string, ref } from "yup"; -import { UserGroupDTO } from "../../../../../generated"; import { TFunction } from "react-i18next"; +import { object, ref, string } from "yup"; +import { UserGroupDTO } from "../../../../../generated"; import { FormProps } from "./NewUser"; // min 5 characters, 1 upper case letter, 1 lower case letter, 1 numeric digit. export const passwordRules = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{5,}$/; +export const userNameRules = /^[a-z0-9-._]+$/; + export const userSchema = (t: TFunction<"translation">) => object().shape({ - userName: string().min(2).required(t("user.validateUserName")), + userName: string() + .min(2) + .max(50) + .matches(userNameRules, t("user.validateUserNameRegex")) + .required(t("user.validateUserName")), userGroupName: object({ code: string().required(t("user.validateUserNeedsGroup")), desc: string(), diff --git a/src/resources/i18n/en.json b/src/resources/i18n/en.json index 14841dae9..e7d72be51 100644 --- a/src/resources/i18n/en.json +++ b/src/resources/i18n/en.json @@ -34,7 +34,8 @@ "validatePasswordTooShort": "Password is too short - should be 5 chars minimum.", "validatePasswordTooWeak": "Please create a stronger password: 1 upper case letter, 1 lower case letter, 1 numeric digit", "validatePasswordMustMatch": "Passwords must match", - "validateUserName": "You need to specify a user name" + "validateUserName": "You need to specify a user name", + "validateUserNameRegex": "Allowed characters: lowercase letters(abc), numbers(123), dot(.), dash (-) and underscore (_)" }, "hospital": { "address": "Address",