UpdateById.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import Joi from "joi";
  2. import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
  3. import User from "../../User";
  4. import { UserAvatarType } from "../UserAvatarType";
  5. import { UserAvatarColor } from "../UserAvatarColor";
  6. import isAdmin from "@/modules/DataModule/permissions/isAdmin";
  7. import isSelf from "@/modules/DataModule/permissions/modelPermissions/isSelf";
  8. import { Op } from "sequelize";
  9. export default class UpdateById extends UpdateByIdJob {
  10. protected static _model = User;
  11. protected static _hasPermission = isAdmin;
  12. protected static _hasModelPermission = isSelf;
  13. protected static _payloadSchema = Joi.object({
  14. _id: Joi.string()
  15. .pattern(/^[0-9a-fA-F]{24}$/)
  16. .required(),
  17. query: Joi.object({
  18. username: Joi.string().min(2).max(32).regex(/^_*[a-zA-Z0-9][a-zA-Z0-9_]*$/).optional(),
  19. emailAddress: Joi.string().email().min(3).max(254).optional(), // TODO: Whitelist regex
  20. name: Joi.string().max(64).optional(),
  21. location: Joi.string().max(50).optional().allow(null, ""),
  22. bio: Joi.string().max(200).optional().allow(null, ""), // TODO: Nullify empty strings
  23. avatarType: Joi.valid(...Object.values(UserAvatarType)).optional(),
  24. avatarColor: Joi.valid(...Object.values(UserAvatarColor))
  25. .optional()
  26. .allow(null),
  27. nightmode: Joi.boolean().optional(),
  28. autoSkipDisliked: Joi.boolean().optional(),
  29. activityLogPublic: Joi.boolean().optional(),
  30. anonymousSongRequests: Joi.boolean().optional(),
  31. activityWatch: Joi.boolean().optional()
  32. }).required()
  33. })
  34. .external(async ({ _id, query }) => {
  35. if (query.emailAddress === undefined) return;
  36. const user = await User.findOne({
  37. where: {
  38. [Op.not]: {
  39. _id
  40. },
  41. username: query.username
  42. }
  43. });
  44. if (user instanceof User)
  45. throw new Error("A user with that username already exists.");
  46. }, "uniqueUsername")
  47. .external(async ({ _id, query }) => {
  48. if (query.emailAddress === undefined) return;
  49. const user = await User.findOne({
  50. where: {
  51. [Op.not]: {
  52. _id
  53. },
  54. emailAddress: query.emailAddress
  55. }
  56. });
  57. if (user instanceof User)
  58. throw new Error("A user with that email already exists.");
  59. }, "uniqueEmail");
  60. }