Commit 9076e335 authored by Grant's avatar Grant
Browse files

Merge branch '87-refined-admin-endpoint-permissions' into 'main'

Refine admin endpoint permissions

Closes #87

See merge request !106
parents 12961495 05658313
Loading
Loading
Loading
Loading
+307 −8
Original line number Diff line number Diff line
@@ -21,9 +21,11 @@
        "@quixo3/prisma-session-store": "^3.1.13",
        "@sentry/react": "^8.48.0",
        "next-themes": "^0.4.4",
        "openapi-fetch": "^0.14.0",
        "react": "^19.0.0",
        "react-dom": "^19.0.0",
        "react-toastify": "^11.0.2"
        "react-toastify": "^11.0.2",
        "swr-openapi": "^5.3.0"
      },
      "devDependencies": {
        "@sentry/cli": "^2.40.0",
@@ -45,6 +47,7 @@
        "eslint-plugin-simple-import-sort": "^12.1.1",
        "jest-fetch-mock": "^3.0.3",
        "nodemon": "^3.1.9",
        "openapi-typescript": "^7.8.0",
        "prettier": "^3.4.2",
        "tailwindcss": "^3.4.17",
        "ts-node": "^10.9.1",
@@ -91,7 +94,7 @@
      "version": "7.26.2",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
      "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
      "dev": true,
      "devOptional": true,
      "dependencies": {
        "@babel/helper-validator-identifier": "^7.25.9",
        "js-tokens": "^4.0.0",
@@ -505,7 +508,7 @@
      "version": "7.25.9",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
      "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
      "dev": true,
      "devOptional": true,
      "engines": {
        "node": ">=6.9.0"
      }
@@ -7310,6 +7313,121 @@
        "@redis/client": "^1.0.0"
      }
    },
    "node_modules/@redocly/ajv": {
      "version": "8.11.2",
      "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz",
      "integrity": "sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==",
      "devOptional": true,
      "dependencies": {
        "fast-deep-equal": "^3.1.1",
        "json-schema-traverse": "^1.0.0",
        "require-from-string": "^2.0.2",
        "uri-js-replace": "^1.0.1"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/@redocly/ajv/node_modules/json-schema-traverse": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
      "devOptional": true
    },
    "node_modules/@redocly/config": {
      "version": "0.22.2",
      "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.22.2.tgz",
      "integrity": "sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==",
      "devOptional": true
    },
    "node_modules/@redocly/openapi-core": {
      "version": "1.34.3",
      "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.34.3.tgz",
      "integrity": "sha512-3arRdUp1fNx55itnjKiUhO6t4Mf91TsrTIYINDNLAZPS0TPd5YpiXRctwjel0qqWoOOhjA34cZ3m4dksLDFUYg==",
      "devOptional": true,
      "dependencies": {
        "@redocly/ajv": "^8.11.2",
        "@redocly/config": "^0.22.0",
        "colorette": "^1.2.0",
        "https-proxy-agent": "^7.0.5",
        "js-levenshtein": "^1.1.6",
        "js-yaml": "^4.1.0",
        "minimatch": "^5.0.1",
        "pluralize": "^8.0.0",
        "yaml-ast-parser": "0.0.43"
      },
      "engines": {
        "node": ">=18.17.0",
        "npm": ">=9.5.0"
      }
    },
    "node_modules/@redocly/openapi-core/node_modules/agent-base": {
      "version": "7.1.3",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
      "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
      "devOptional": true,
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/@redocly/openapi-core/node_modules/brace-expansion": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
      "devOptional": true,
      "dependencies": {
        "balanced-match": "^1.0.0"
      }
    },
    "node_modules/@redocly/openapi-core/node_modules/debug": {
      "version": "4.4.1",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
      "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
      "devOptional": true,
      "dependencies": {
        "ms": "^2.1.3"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/@redocly/openapi-core/node_modules/https-proxy-agent": {
      "version": "7.0.6",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
      "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
      "devOptional": true,
      "dependencies": {
        "agent-base": "^7.1.2",
        "debug": "4"
      },
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/@redocly/openapi-core/node_modules/minimatch": {
      "version": "5.1.6",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
      "devOptional": true,
      "dependencies": {
        "brace-expansion": "^2.0.1"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/@redocly/openapi-core/node_modules/ms": {
      "version": "2.1.3",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
      "devOptional": true
    },
    "node_modules/@rollup/rollup-android-arm-eabi": {
      "version": "4.29.1",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz",
@@ -9567,6 +9685,15 @@
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/ansi-colors": {
      "version": "4.1.3",
      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
      "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
      "devOptional": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/ansi-escapes": {
      "version": "4.3.2",
      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@@ -9661,7 +9788,7 @@
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
      "dev": true
      "devOptional": true
    },
    "node_modules/aria-query": {
      "version": "5.3.2",
@@ -10431,6 +10558,12 @@
        "node": ">=8"
      }
    },
    "node_modules/change-case": {
      "version": "5.4.4",
      "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz",
      "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==",
      "devOptional": true
    },
    "node_modules/char-regex": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
@@ -10629,6 +10762,12 @@
      "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz",
      "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog=="
    },
    "node_modules/colorette": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
      "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==",
      "devOptional": true
    },
    "node_modules/colorspace": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
@@ -12711,7 +12850,7 @@
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
      "dev": true
      "devOptional": true
    },
    "node_modules/fast-glob": {
      "version": "3.3.2",
@@ -13541,6 +13680,18 @@
        "node": ">=0.8.19"
      }
    },
    "node_modules/index-to-position": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.1.0.tgz",
      "integrity": "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==",
      "devOptional": true,
      "engines": {
        "node": ">=18"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -14871,6 +15022,15 @@
        "url": "https://github.com/sponsors/panva"
      }
    },
    "node_modules/js-levenshtein": {
      "version": "1.1.6",
      "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
      "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
      "devOptional": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/js-tokens": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -14880,7 +15040,7 @@
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
      "dev": true,
      "devOptional": true,
      "dependencies": {
        "argparse": "^2.0.1"
      },
@@ -15782,6 +15942,80 @@
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/openapi-fetch": {
      "version": "0.14.0",
      "resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.14.0.tgz",
      "integrity": "sha512-PshIdm1NgdLvb05zp8LqRQMNSKzIlPkyMxYFxwyHR+UlKD4t2nUjkDhNxeRbhRSEd3x5EUNh2w5sJYwkhOH4fg==",
      "dependencies": {
        "openapi-typescript-helpers": "^0.0.15"
      }
    },
    "node_modules/openapi-typescript": {
      "version": "7.8.0",
      "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-7.8.0.tgz",
      "integrity": "sha512-1EeVWmDzi16A+siQlo/SwSGIT7HwaFAVjvMA7/jG5HMLSnrUOzPL7uSTRZZa4v/LCRxHTApHKtNY6glApEoiUQ==",
      "devOptional": true,
      "dependencies": {
        "@redocly/openapi-core": "^1.34.3",
        "ansi-colors": "^4.1.3",
        "change-case": "^5.4.4",
        "parse-json": "^8.3.0",
        "supports-color": "^10.0.0",
        "yargs-parser": "^21.1.1"
      },
      "bin": {
        "openapi-typescript": "bin/cli.js"
      },
      "peerDependencies": {
        "typescript": "^5.x"
      }
    },
    "node_modules/openapi-typescript-helpers": {
      "version": "0.0.15",
      "resolved": "https://registry.npmjs.org/openapi-typescript-helpers/-/openapi-typescript-helpers-0.0.15.tgz",
      "integrity": "sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw=="
    },
    "node_modules/openapi-typescript/node_modules/parse-json": {
      "version": "8.3.0",
      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz",
      "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==",
      "devOptional": true,
      "dependencies": {
        "@babel/code-frame": "^7.26.2",
        "index-to-position": "^1.1.0",
        "type-fest": "^4.39.1"
      },
      "engines": {
        "node": ">=18"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/openapi-typescript/node_modules/supports-color": {
      "version": "10.0.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.0.0.tgz",
      "integrity": "sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==",
      "devOptional": true,
      "engines": {
        "node": ">=18"
      },
      "funding": {
        "url": "https://github.com/chalk/supports-color?sponsor=1"
      }
    },
    "node_modules/openapi-typescript/node_modules/type-fest": {
      "version": "4.41.0",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
      "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
      "devOptional": true,
      "engines": {
        "node": ">=16"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/openid-client": {
      "version": "6.1.7",
      "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.1.7.tgz",
@@ -16109,6 +16343,15 @@
        "node": ">=8"
      }
    },
    "node_modules/pluralize": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
      "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==",
      "devOptional": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/possible-typed-array-names": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@@ -16887,6 +17130,15 @@
        "node": ">=0.10.0"
      }
    },
    "node_modules/require-from-string": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
      "devOptional": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/require-in-the-middle": {
      "version": "7.4.0",
      "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.4.0.tgz",
@@ -18104,6 +18356,42 @@
        "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
      }
    },
    "node_modules/swr-openapi": {
      "version": "5.3.0",
      "resolved": "https://registry.npmjs.org/swr-openapi/-/swr-openapi-5.3.0.tgz",
      "integrity": "sha512-E//wBSuJPMAfRle6K1CdWpodxS5cRgQ4UboM4AKlP57/xfw8sHZgyLs9VNXki+X7FktjihfryqvQT5QWna26Iw==",
      "dependencies": {
        "openapi-typescript-helpers": "^0.0.15",
        "type-fest": "^4.40.1"
      },
      "funding": {
        "type": "buymeacoffee",
        "url": "https://buymeacoffee.com/htunnicliff"
      },
      "peerDependencies": {
        "openapi-fetch": "0.14.0",
        "openapi-typescript": "7.8.0",
        "react": "18 || 19",
        "swr": "2",
        "typescript": "^5.x"
      },
      "peerDependenciesMeta": {
        "openapi-typescript": {
          "optional": true
        }
      }
    },
    "node_modules/swr-openapi/node_modules/type-fest": {
      "version": "4.41.0",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
      "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
      "engines": {
        "node": ">=16"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/tailwind-merge": {
      "version": "2.6.0",
      "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz",
@@ -19073,7 +19361,6 @@
      "version": "5.7.2",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
      "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
      "devOptional": true,
      "bin": {
        "tsc": "bin/tsc",
        "tsserver": "bin/tsserver"
@@ -19229,6 +19516,12 @@
        "punycode": "^2.1.0"
      }
    },
    "node_modules/uri-js-replace": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz",
      "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==",
      "devOptional": true
    },
    "node_modules/use-composed-ref": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz",
@@ -19791,6 +20084,12 @@
        "node": ">= 14"
      }
    },
    "node_modules/yaml-ast-parser": {
      "version": "0.0.43",
      "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz",
      "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==",
      "devOptional": true
    },
    "node_modules/yargs": {
      "version": "17.7.2",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@@ -19814,7 +20113,7 @@
      "version": "21.1.1",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
      "dev": true,
      "devOptional": true,
      "license": "ISC",
      "engines": {
        "node": ">=12"
+5 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
  "main": "src/index.ts",
  "scripts": {
    "lint": "eslint",
    "build-api-schema": "openapi-typescript packages/server/src/api/openapi.yml -o packages/lib/src/api-schema.ts",
    "dev:admin": "npm run dev -w packages/admin",
    "dev:client": "npm run dev -w packages/client",
    "dev:server": "npm run dev -w packages/server",
@@ -45,6 +46,7 @@
    "eslint-plugin-simple-import-sort": "^12.1.1",
    "jest-fetch-mock": "^3.0.3",
    "nodemon": "^3.1.9",
    "openapi-typescript": "^7.8.0",
    "prettier": "^3.4.2",
    "tailwindcss": "^3.4.17",
    "ts-node": "^10.9.1",
@@ -60,8 +62,10 @@
    "@quixo3/prisma-session-store": "^3.1.13",
    "@sentry/react": "^8.48.0",
    "next-themes": "^0.4.4",
    "openapi-fetch": "^0.14.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "react-toastify": "^11.0.2"
    "react-toastify": "^11.0.2",
    "swr-openapi": "^5.3.0"
  }
}
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ export const HeatmapOverlay = () => {
  const updateHeatmap = useCallback(() => {
    setHeatmapOverlay((v) => ({ ...v, loading: true }));

    api<{ heatmap: string }, "heatmap_not_generated">("/api/heatmap")
    api<{ heatmap: string }, "heatmap_not_generated">("/api/canvas/heatmap")
      .then(({ status, data }) => {
        if (status === 200 && data.success) {
          drawHeatmap(data.heatmap);
+39 −30
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ import { useAppContext } from "../../contexts/AppContext";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faXmark } from "@fortawesome/free-solid-svg-icons";
import { useEffect, useState } from "react";
import { api } from "../../lib/utils";
import { oapi } from "../../lib/utils";
import { UserCard } from "../Profile/UserCard";
import { SmallCanvas } from "./SmallCanvas";
import { ReportPixelModal } from "./ReportPixelModal";
@@ -20,20 +20,30 @@ interface IPixel {
interface IUser {
  sub: string;
  username: string;
  display_name?: string;
  picture_url?: string;
  profile_url?: string;
  display_name: string | null;
  picture_url: string | null;
  profile_url: string | null;
  isAdmin: boolean;
  isModerator: boolean;
}

interface IInstance {
  hostname: string;
  name?: string;
  logo_url?: string;
  banner_url?: string;
  name: string | null;
  logo_url: string | null;
  banner_url: string | null;
}

const parsePixelResponse = (
  input: Omit<IPixel, "createdAt"> & { createdAt: string }
): IPixel => {
  const { createdAt, ...rest } = input;
  return {
    ...rest,
    createdAt: new Date(createdAt),
  };
};

export const PixelWhoisSidebar = () => {
  const { pixelWhois, setPixelWhois, user } = useAppContext();
  const [loading, setLoading] = useState(true);
@@ -50,29 +60,28 @@ export const PixelWhoisSidebar = () => {
    setLoading(true);
    setWhois(undefined);

    api<
      {
        pixel: IPixel;
        otherPixels: number;
        user: IUser | null;
        instance: IInstance | null;
    oapi
      .GET("/canvas/pixel/{x}/{y}", {
        params: {
          path: {
            x: pixelWhois.x,
            y: pixelWhois.y,
          },
        },
      "no_pixel"
    >(`/api/canvas/pixel/${pixelWhois.x}/${pixelWhois.y}`)
      .then(({ status, data }) => {
        if (status === 200) {
          if (data.success) {
      })
      .then(({ data, error, response }) => {
        if (data) {
          const pixel = parsePixelResponse(data.pixel);

          setWhois({
              pixel: data.pixel,
            pixel,
            otherPixels: data.otherPixels,
            user: data.user,
            instance: data.instance,
          });
          } else {
            // error wahhhhhh
        }
        } else {
          // error wahhhh
        if (error) {
          console.error("Error while fetching whois", response);
        }
      })
      .finally(() => {
+34 −8
Original line number Diff line number Diff line
@@ -7,9 +7,9 @@ import {
  ModalHeader,
} from "@nextui-org/react";
import { useAppContext } from "../../contexts/AppContext";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { IUser, UserCard } from "./UserCard";
import { api, handleError } from "../../lib/utils";
import { handleError, oapi } from "../../lib/utils";

export const ProfileModal = () => {
  const { profile, setProfile } = useAppContext();
@@ -21,15 +21,40 @@ export const ProfileModal = () => {
      return;
    }

    api<{ user: IUser }>("/api/user/" + encodeURIComponent(profile)).then(
      ({ status, data }) => {
        if (status === 200 && data.success) {
    oapi
      .GET("/user/{sub}", {
        params: {
          path: {
            sub: profile,
          },
        },
      })
      .then(({ data, response }) => {
        if (data) {
          setUser(data.user);
        } else {
          handleError({ status, data });
          handleError({ status: response.status, data: response.body });
        }
      });
  }, [profile]);

  const test_getIPs = useCallback(() => {
    if (!profile) {
      alert("profile not found? wat");
      return;
    }
    );

    oapi
      .GET("/mod/user/{sub}/ips", {
        params: {
          path: {
            sub: profile,
          },
        },
      })
      .then(({ data }) => {
        console.log("get ips", data);
      });
  }, [profile]);

  return (
@@ -40,6 +65,7 @@ export const ProfileModal = () => {
            <ModalHeader className="flex flex-col gap-1">Profile</ModalHeader>
            <ModalBody>
              {user ? <UserCard user={user} /> : <>Loading...</>}
              <Button onPress={test_getIPs}>test get ips</Button>
            </ModalBody>
            <ModalFooter>
              <Button onPress={onClose}>Close</Button>
Loading