summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPuyodead1 <puyodead@proton.me>2023-06-14 11:37:17 -0400
committerRory& <root@rory.gay>2026-01-21 07:10:10 +0100
commit08fcec36ba6dd2b49941c367d52c333c055e0eb7 (patch)
tree47a7856a4df3193423fe3e6de11f7dfa98e3dc23 /src
parentadd legacy_username user field (diff)
downloadserver-ts-08fcec36ba6dd2b49941c367d52c333c055e0eb7.tar.xz
update user modify for unique usernames
Diffstat (limited to 'src')
-rw-r--r--src/api/routes/users/@me/index.ts67
-rw-r--r--src/schemas/uncategorised/UserModifySchema.ts22
-rwxr-xr-xsrc/util/config/types/UsersConfiguration.ts2
-rw-r--r--src/util/config/types/subconfigurations/limits/UserLimits.ts1
-rw-r--r--src/util/entities/User.ts13
5 files changed, 75 insertions, 30 deletions
diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts

index 796d5629..99ff2b24 100644 --- a/src/api/routes/users/@me/index.ts +++ b/src/api/routes/users/@me/index.ts
@@ -61,6 +61,8 @@ router.patch( }), async (req: Request, res: Response) => { const body = req.body as UserModifySchema; + const { uniqueUsernames } = Config.get().general; + const { minUsername, maxUsername } = Config.get().limits.user; const user = await User.findOneOrFail({ where: { id: req.user_id }, @@ -120,9 +122,53 @@ router.patch( newToken = (await generateToken(user.id)) as string; } - // TODO: uniqueUsernames: disallow if uniqueUsernames is enabled if (body.username) { - const check_username = body?.username?.replace(/\s/g, "").trim(); + // password is required to update username + if (!body.password) + throw FieldErrors({ + password: { + message: req.t("common:field.PASSWORD_DOES_NOT_MATCH"), + code: "PASSWORD_DOES_NOT_MATCH", + }, + }); + + // handle username changes (pomelo) + if (uniqueUsernames) { + body.username = body.username.toLowerCase(); + // validate username length + if ( + body.username.length < minUsername || + body.username.length > maxUsername + ) { + throw FieldErrors({ + username: { + code: "BASE_TYPE_BAD_LENGTH", + message: req.t( + "common:field.BASE_TYPE_BAD_LENGTH", + { length: `${minUsername} and ${maxUsername}` }, + ), + }, + }); + } + + // check if username is already taken (pomelo only) + const userCount = await User.count({ + where: { username: body.username }, + }); + if (userCount > 0) { + throw FieldErrors({ + username: { + code: "USERNAME_ALREADY_TAKEN", + message: req.t( + "common:field.USERNAME_ALREADY_TAKEN", + ), + }, + }); + } + } + + // handle username changes (old username system) + const check_username = body?.username?.replace(/\s/g, ""); if (!check_username) { throw FieldErrors({ username: { @@ -132,8 +178,7 @@ router.patch( }); } - const { maxUsername } = Config.get().limits.user; - if (check_username.length > maxUsername || check_username.length < 2) { + if (check_username.length > maxUsername) { throw FieldErrors({ username: { code: "BASE_TYPE_BAD_LENGTH", @@ -152,8 +197,18 @@ router.patch( } } - // TODO: uniqueUsernames: disallow if uniqueUsernames is enabled if (body.discriminator) { + if (uniqueUsernames) { + throw FieldErrors({ + username: { + code: "DISCRIMINATOR_UPDATE_BLOCKED", + message: req.t( + "common:field.DISCRIMINATOR_UPDATE_BLOCKED", + ), + }, + }); + } + if ( await User.findOne({ where: { @@ -165,7 +220,7 @@ router.patch( throw FieldErrors({ discriminator: { code: "INVALID_DISCRIMINATOR", - message: "This discriminator is already in use.", + message: req.t("common.field.INVALID_DISCRIMINATOR"), }, }); } diff --git a/src/schemas/uncategorised/UserModifySchema.ts b/src/schemas/uncategorised/UserModifySchema.ts
index c7228e7b..a135d8b1 100644 --- a/src/schemas/uncategorised/UserModifySchema.ts +++ b/src/schemas/uncategorised/UserModifySchema.ts
@@ -18,35 +18,25 @@ export interface UserModifySchema { /** - * @minLength 2 + * @minLength 1 + * @maxLength 100 */ username?: string; avatar?: string | null; + /** + * @maxLength 1024 + */ bio?: string; accent_color?: number; banner?: string | null; - /** - * @minLength 1 - * @maxLength 72 - */ password?: string; - /** - * @minLength 1 - * @maxLength 72 - */ new_password?: string; - /** - * @minLength 6 - * @maxLength 6 - */ code?: string; - /** - * @TJS-format email - */ email?: string; /** * @minLength 4 * @maxLength 4 */ discriminator?: string; + global_name?: string; } diff --git a/src/util/config/types/UsersConfiguration.ts b/src/util/config/types/UsersConfiguration.ts
index 2ac058e9..6b61637e 100755 --- a/src/util/config/types/UsersConfiguration.ts +++ b/src/util/config/types/UsersConfiguration.ts
@@ -19,4 +19,4 @@ export class UserConfiguration { blockedContains: string[] = ["discord", "clyde", "spacebar", "steam", "community", "support", "ticket"]; blockedEquals: string[] = ["everyone", "here"]; -} +} \ No newline at end of file diff --git a/src/util/config/types/subconfigurations/limits/UserLimits.ts b/src/util/config/types/subconfigurations/limits/UserLimits.ts
index cbe686d1..6fe4d8d8 100644 --- a/src/util/config/types/subconfigurations/limits/UserLimits.ts +++ b/src/util/config/types/subconfigurations/limits/UserLimits.ts
@@ -18,6 +18,7 @@ export class UserLimits { maxGuilds: number = 1048576; + minUsername: number = 2; maxUsername: number = 32; maxFriends: number = 5000; maxBio: number = 190; diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index e955bd00..1d232fb0 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts
@@ -32,7 +32,6 @@ import { ChannelType, PrivateUserProjection, PublicUser, PublicUserProjection, U export enum PublicUserEnum { username, global_name, - legacy_username, discriminator, id, public_flags, @@ -195,7 +194,7 @@ export class User extends BaseClass { // TODO: I don't like this method? validate() { - if (this.discriminator) { + if (this.discriminator && this.discriminator !== "0") { const discrim = Number(this.discriminator); if (isNaN(discrim) || !(typeof discrim == "number") || !Number.isInteger(discrim) || discrim <= 0 || discrim >= 10000) throw FieldErrors({ @@ -273,9 +272,8 @@ export class User extends BaseClass { public get tag(): string { const { uniqueUsernames } = Config.get().general; - // if uniqueUsernames is enabled, global_name should be set return uniqueUsernames - ? (this.global_name as string) + ? this.username : `${this.username}#${this.discriminator}`; } @@ -325,7 +323,7 @@ export class User extends BaseClass { }); const user = User.create({ - username: username, + username: uniqueUsernames ? username.toLowerCase() : username, discriminator, id: id || Snowflake.generate(), email: email, @@ -334,8 +332,9 @@ export class User extends BaseClass { valid_tokens_since: new Date(), }, settings: settings, - - premium_since: Config.get().defaults.user.premium ? new Date() : undefined, + premium_since: Config.get().defaults.user.premium + ? new Date() + : undefined, rights: Config.get().register.defaultRights, premium: Config.get().defaults.user.premium ?? false, premium_type: Config.get().defaults.user.premiumType ?? 0,