|
@@ -5,6 +5,7 @@ import { UserAvatarType } from "../UserAvatarType";
|
|
import { UserAvatarColor } from "../UserAvatarColor";
|
|
import { UserAvatarColor } from "../UserAvatarColor";
|
|
import isAdmin from "@/modules/DataModule/permissions/isAdmin";
|
|
import isAdmin from "@/modules/DataModule/permissions/isAdmin";
|
|
import isSelf from "@/modules/DataModule/permissions/modelPermissions/isSelf";
|
|
import isSelf from "@/modules/DataModule/permissions/modelPermissions/isSelf";
|
|
|
|
+import { Op } from "sequelize";
|
|
|
|
|
|
export default class UpdateById extends UpdateByIdJob {
|
|
export default class UpdateById extends UpdateByIdJob {
|
|
protected static _model = User;
|
|
protected static _model = User;
|
|
@@ -18,8 +19,8 @@ export default class UpdateById extends UpdateByIdJob {
|
|
.pattern(/^[0-9a-fA-F]{24}$/)
|
|
.pattern(/^[0-9a-fA-F]{24}$/)
|
|
.required(),
|
|
.required(),
|
|
query: Joi.object({
|
|
query: Joi.object({
|
|
- username: Joi.string().max(64).optional(), // TODO: format and unique validation
|
|
|
|
- emailAddress: Joi.string().max(64).optional(), // TODO: format and unique validation
|
|
|
|
|
|
+ username: Joi.string().min(2).max(32).regex(/^_*[a-zA-Z0-9][a-zA-Z0-9_]*$/).optional(),
|
|
|
|
+ emailAddress: Joi.string().email().min(3).max(254).optional(), // TODO: Whitelist regex
|
|
name: Joi.string().max(64).optional(),
|
|
name: Joi.string().max(64).optional(),
|
|
location: Joi.string().max(50).optional().allow(null, ""),
|
|
location: Joi.string().max(50).optional().allow(null, ""),
|
|
bio: Joi.string().max(200).optional().allow(null, ""), // TODO: Nullify empty strings
|
|
bio: Joi.string().max(200).optional().allow(null, ""), // TODO: Nullify empty strings
|
|
@@ -33,5 +34,35 @@ export default class UpdateById extends UpdateByIdJob {
|
|
anonymousSongRequests: Joi.boolean().optional(),
|
|
anonymousSongRequests: Joi.boolean().optional(),
|
|
activityWatch: Joi.boolean().optional()
|
|
activityWatch: Joi.boolean().optional()
|
|
}).required()
|
|
}).required()
|
|
- });
|
|
|
|
|
|
+ })
|
|
|
|
+ .external(async ({ _id, query }) => {
|
|
|
|
+ if (query.emailAddress === undefined) return;
|
|
|
|
+
|
|
|
|
+ const user = await User.findOne({
|
|
|
|
+ where: {
|
|
|
|
+ [Op.not]: {
|
|
|
|
+ _id
|
|
|
|
+ },
|
|
|
|
+ username: query.username
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (user instanceof User)
|
|
|
|
+ throw new Error("A user with that username already exists.");
|
|
|
|
+ }, "uniqueUsername")
|
|
|
|
+ .external(async ({ _id, query }) => {
|
|
|
|
+ if (query.emailAddress === undefined) return;
|
|
|
|
+
|
|
|
|
+ const user = await User.findOne({
|
|
|
|
+ where: {
|
|
|
|
+ [Op.not]: {
|
|
|
|
+ _id
|
|
|
|
+ },
|
|
|
|
+ emailAddress: query.emailAddress
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (user instanceof User)
|
|
|
|
+ throw new Error("A user with that email already exists.");
|
|
|
|
+ }, "uniqueEmail");
|
|
}
|
|
}
|