user.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /* eslint no-param-reassign: 0 */
  2. /* eslint-disable import/no-cycle */
  3. import validation from "@/validation";
  4. import ws from "@/ws";
  5. import auth from "@/api/auth";
  6. const state = {};
  7. const getters = {};
  8. const actions = {};
  9. const mutations = {};
  10. const modules = {
  11. auth: {
  12. namespaced: true,
  13. state: {
  14. userIdMap: {},
  15. userIdRequested: {},
  16. pendingUserIdCallbacks: {},
  17. loggedIn: false,
  18. role: "",
  19. username: "",
  20. email: "",
  21. userId: "",
  22. banned: false,
  23. ban: {},
  24. gotData: false
  25. },
  26. actions: {
  27. /* eslint-disable-next-line no-unused-vars */
  28. register: ({ commit }, user) =>
  29. new Promise((resolve, reject) => {
  30. const { username, email, password } = user;
  31. if (!email || !username || !password)
  32. return reject(new Error("Please fill in all fields"));
  33. if (!validation.isLength(email, 3, 254))
  34. return reject(
  35. new Error(
  36. "Email must have between 3 and 254 characters."
  37. )
  38. );
  39. if (
  40. email.indexOf("@") !== email.lastIndexOf("@") ||
  41. !validation.regex.emailSimple.test(email)
  42. )
  43. return reject(new Error("Invalid email format."));
  44. if (!validation.isLength(username, 2, 32))
  45. return reject(
  46. new Error(
  47. "Username must have between 2 and 32 characters."
  48. )
  49. );
  50. if (!validation.regex.azAZ09_.test(username))
  51. return reject(
  52. new Error(
  53. "Invalid username format. Allowed characters: a-z, A-Z, 0-9 and _."
  54. )
  55. );
  56. if (!validation.isLength(password, 6, 200))
  57. return reject(
  58. new Error(
  59. "Password must have between 6 and 200 characters."
  60. )
  61. );
  62. if (!validation.regex.password.test(password))
  63. return reject(
  64. new Error(
  65. "Invalid password format. Must have one lowercase letter, one uppercase letter, one number and one special character."
  66. )
  67. );
  68. return auth
  69. .register(user)
  70. .then(res => resolve(res))
  71. .catch(err => reject(new Error(err.message)));
  72. }),
  73. /* eslint-disable-next-line no-unused-vars */
  74. login: ({ commit }, user) =>
  75. new Promise((resolve, reject) => {
  76. auth.login(user)
  77. .then(() =>
  78. resolve({
  79. status: "success",
  80. message: "Logged in!"
  81. })
  82. )
  83. .catch(err => reject(new Error(err.message)));
  84. }),
  85. logout: () =>
  86. new Promise((resolve, reject) =>
  87. auth
  88. .logout()
  89. .then(() => resolve())
  90. .catch(() => reject())
  91. ),
  92. getUsernameFromId: ({ commit, state }, userId) =>
  93. new Promise(resolve => {
  94. if (typeof state.userIdMap[`Z${userId}`] !== "string") {
  95. if (state.userIdRequested[`Z${userId}`] !== true) {
  96. commit("requestingUserId", userId);
  97. ws.socket.dispatch(
  98. "users.getUsernameFromId",
  99. userId,
  100. res => {
  101. if (res.status === "success") {
  102. const { username } = res.data;
  103. commit("mapUserId", {
  104. userId,
  105. username
  106. });
  107. state.pendingUserIdCallbacks[
  108. `Z${userId}`
  109. ].forEach(cb => cb(username));
  110. commit("clearPendingCallbacks", userId);
  111. return resolve(username);
  112. }
  113. return resolve();
  114. }
  115. );
  116. } else {
  117. commit("pendingUsername", {
  118. userId,
  119. callback: username => resolve(username)
  120. });
  121. }
  122. } else {
  123. resolve(state.userIdMap[`Z${userId}`]);
  124. }
  125. }),
  126. authData: ({ commit }, data) => {
  127. commit("authData", data);
  128. },
  129. banUser: ({ commit }, ban) => {
  130. commit("banUser", ban);
  131. },
  132. updateUsername: ({ commit }, username) => {
  133. commit("updateUsername", username);
  134. }
  135. },
  136. mutations: {
  137. mapUserId(state, data) {
  138. state.userIdMap[`Z${data.userId}`] = data.username;
  139. state.userIdRequested[`Z${data.userId}`] = false;
  140. },
  141. requestingUserId(state, userId) {
  142. state.userIdRequested[`Z${userId}`] = true;
  143. if (!state.pendingUserIdCallbacks[`Z${userId}`])
  144. state.pendingUserIdCallbacks[`Z${userId}`] = [];
  145. },
  146. pendingUsername(state, data) {
  147. state.pendingUserIdCallbacks[`Z${data.userId}`].push(
  148. data.callback
  149. );
  150. },
  151. clearPendingCallbacks(state, userId) {
  152. state.pendingUserIdCallbacks[`Z${userId}`] = [];
  153. },
  154. authData(state, data) {
  155. state.loggedIn = data.loggedIn;
  156. state.role = data.role;
  157. state.username = data.username;
  158. state.email = data.email;
  159. state.userId = data.userId;
  160. state.gotData = true;
  161. },
  162. banUser(state, ban) {
  163. state.banned = true;
  164. state.ban = ban;
  165. },
  166. updateUsername(state, username) {
  167. state.username = username;
  168. }
  169. }
  170. },
  171. playlists: {
  172. namespaced: true,
  173. state: {
  174. editing: "",
  175. playlists: [],
  176. fetchedPlaylists: false
  177. },
  178. actions: {
  179. editPlaylist: ({ commit }, id) => commit("editPlaylist", id),
  180. setPlaylists: ({ commit }, playlists) =>
  181. commit("setPlaylists", playlists),
  182. updatePlaylists: ({ commit }, playlists) =>
  183. commit("updatePlaylists", playlists),
  184. addPlaylist: ({ commit }, playlist) =>
  185. commit("addPlaylist", playlist),
  186. removePlaylist: ({ commit }, playlistId) =>
  187. commit("removePlaylist", playlistId)
  188. },
  189. mutations: {
  190. editPlaylist(state, id) {
  191. state.editing = id;
  192. },
  193. setPlaylists(state, playlists) {
  194. state.fetchedPlaylists = true;
  195. state.playlists = playlists;
  196. },
  197. updatePlaylists(state, playlists) {
  198. state.playlists = playlists;
  199. },
  200. addPlaylist(state, playlist) {
  201. state.playlists.push(playlist);
  202. },
  203. removePlaylist(state, playlistId) {
  204. state.playlists.forEach((playlist, index) => {
  205. if (playlist._id === playlistId)
  206. state.playlists.splice(index, 1);
  207. });
  208. }
  209. }
  210. },
  211. preferences: {
  212. namespaced: true,
  213. state: {
  214. nightmode: false,
  215. autoSkipDisliked: true,
  216. activityLogPublic: false,
  217. anonymousSongRequests: false,
  218. activityWatch: false
  219. },
  220. actions: {
  221. changeNightmode: ({ commit }, nightmode) => {
  222. commit("changeNightmode", nightmode);
  223. },
  224. changeAutoSkipDisliked: ({ commit }, autoSkipDisliked) => {
  225. commit("changeAutoSkipDisliked", autoSkipDisliked);
  226. },
  227. changeActivityLogPublic: ({ commit }, activityLogPublic) => {
  228. commit("changeActivityLogPublic", activityLogPublic);
  229. },
  230. changeAnonymousSongRequests: (
  231. { commit },
  232. anonymousSongRequests
  233. ) => {
  234. commit("changeAnonymousSongRequests", anonymousSongRequests);
  235. },
  236. changeActivityWatch: ({ commit }, activityWatch) => {
  237. commit("changeActivityWatch", activityWatch);
  238. }
  239. },
  240. mutations: {
  241. changeNightmode(state, nightmode) {
  242. state.nightmode = nightmode;
  243. },
  244. changeAutoSkipDisliked(state, autoSkipDisliked) {
  245. state.autoSkipDisliked = autoSkipDisliked;
  246. },
  247. changeActivityLogPublic(state, activityLogPublic) {
  248. state.activityLogPublic = activityLogPublic;
  249. },
  250. changeAnonymousSongRequests(state, anonymousSongRequests) {
  251. state.anonymousSongRequests = anonymousSongRequests;
  252. },
  253. changeActivityWatch(state, activityWatch) {
  254. state.activityWatch = activityWatch;
  255. }
  256. }
  257. }
  258. };
  259. export default {
  260. namespaced: true,
  261. state,
  262. getters,
  263. actions,
  264. mutations,
  265. modules
  266. };