hooks.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { throwError } from "./utils.js";
  2. export const ownerOrAdminOrNewHooks = async (context) => {
  3. let existingGame = null;
  4. const { userId, store, resourceId, body, boxId, method } = context;
  5. // Is it the `game` box ?
  6. if (boxId !== "game") {
  7. return context;
  8. }
  9. // Is it a modification action ?
  10. if (!["POST", "UPDATE", "DELETE"].includes(method)) {
  11. return context;
  12. }
  13. // It's a game modification...
  14. if (!userId) {
  15. throwError(
  16. "Game creation/modification not allowed for unauthenticated users",
  17. 403
  18. );
  19. }
  20. const nextContext = {
  21. ...context,
  22. allow: true,
  23. body: { ...body, owner: userId },
  24. };
  25. if (!resourceId) {
  26. // Creation
  27. return nextContext;
  28. }
  29. try {
  30. existingGame = await store.get("game", resourceId);
  31. } catch {
  32. console.log("Game not found");
  33. // Creation but with resourceId
  34. return nextContext;
  35. }
  36. let isAdmin = false;
  37. try {
  38. const currentUser = await store.get("user", userId);
  39. isAdmin = Boolean(currentUser?.isAdmin);
  40. } catch (e) {
  41. if (e.statusCode !== 404) {
  42. throw e;
  43. }
  44. }
  45. if (existingGame.owner !== userId && !isAdmin) {
  46. throwError("Modification allowed only for owner or Admin", 403);
  47. }
  48. const owner = existingGame.owner || userId;
  49. // Update with good user (and force user)
  50. return {
  51. ...nextContext,
  52. body: { ...body, owner: owner },
  53. };
  54. };
  55. export const onlySelfOrPublicGames = async (context) => {
  56. const { boxId, userId, method, response, resourceId, store } = context;
  57. if (boxId !== "game") {
  58. return context;
  59. }
  60. if (!["GET"].includes(method) || resourceId) {
  61. return context;
  62. }
  63. // Get current user account
  64. let userIsAdmin = false;
  65. try {
  66. const { isAdmin = false } = await store.get("user", userId);
  67. userIsAdmin = isAdmin;
  68. } catch (e) {
  69. if (e.statusCode !== 404) {
  70. throw e;
  71. }
  72. }
  73. const newContext = { ...context };
  74. newContext.response = response.filter(
  75. ({ board: { published }, owner }) =>
  76. published || owner === userId || userIsAdmin
  77. );
  78. return newContext;
  79. };
  80. export const onlySelfUser = async (context) => {
  81. const { boxId, userId, method, resourceId, store } = context;
  82. if (boxId !== "user") {
  83. return context;
  84. }
  85. if (method !== "GET") {
  86. throwError("Method not allowed", 405);
  87. }
  88. if (resourceId !== userId) {
  89. throwError("You can only access your account", 403);
  90. }
  91. // Create user account if missing
  92. try {
  93. await store.get("user", userId);
  94. } catch (e) {
  95. if (e.statusCode === 404) {
  96. await store.save("user", userId, {});
  97. } else {
  98. throw e;
  99. }
  100. }
  101. return { ...context, allow: true };
  102. };