From e9b2c1b51a37c726480aa6fb07d4759559660ae2 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Wed, 18 Jun 2025 14:24:38 +0200 Subject: [PATCH] restructure admin pages --- package-lock.json | 72 ----------------- package.json | 4 +- test/api/unit/middlewares/blocker.test.js | 78 +++++++++++++++++++ test/api/unit/middlewares/ipBlocker.test.js | 76 ------------------ .../admin-panel/filters/formatDate.js | 0 .../{ => admin}/admin-panel/index.vue | 4 +- .../admin-panel/mixins/getItemDescription.js | 0 .../admin-panel/mixins/saveHero.js | 0 .../{ => admin}/admin-panel/search.vue | 0 .../admin-panel/user-support/achievements.vue | 0 .../user-support/avatarAndDrops.vue | 0 .../admin-panel/user-support/basicDetails.vue | 0 .../user-support/contributorDetails.vue | 2 +- .../admin-panel/user-support/cronAndAuth.vue | 0 .../user-support/customizationsOwned.vue | 0 .../admin-panel/user-support/index.vue | 2 +- .../admin-panel/user-support/itemsOwned.vue | 0 .../user-support/partyAndQuest.vue | 0 .../user-support/privilegesAndGems.vue | 0 .../admin-panel/user-support/stats-row.vue | 0 .../admin-panel/user-support/stats.vue | 2 +- .../user-support/subscriptionAndPerks.vue | 2 +- .../admin-panel/user-support/transactions.vue | 4 +- .../admin-panel/user-support/userHistory.vue | 2 +- .../admin-panel/user-support/userProfile.vue | 2 +- .../{ => admin}/blocker/blocker_form.vue | 3 +- .../components/{ => admin}/blocker/index.vue | 14 +++- .../client/src/components/admin/container.vue | 30 +++++++ website/client/src/components/hall/heroes.vue | 2 +- website/client/src/components/header/menu.vue | 53 +++++++++++-- website/client/src/router/index.js | 71 +++++++++-------- website/common/locales/en/admin.json | 5 ++ .../common/script/errors/apiErrorMessages.js | 1 + .../middlewares/{ipBlocker.js => blocker.js} | 30 ++++--- website/server/middlewares/index.js | 4 +- website/server/models/blocker.js | 1 + 36 files changed, 246 insertions(+), 218 deletions(-) create mode 100644 test/api/unit/middlewares/blocker.test.js delete mode 100644 test/api/unit/middlewares/ipBlocker.test.js rename website/client/src/components/{ => admin}/admin-panel/filters/formatDate.js (100%) rename website/client/src/components/{ => admin}/admin-panel/index.vue (97%) rename website/client/src/components/{ => admin}/admin-panel/mixins/getItemDescription.js (100%) rename website/client/src/components/{ => admin}/admin-panel/mixins/saveHero.js (100%) rename website/client/src/components/{ => admin}/admin-panel/search.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/achievements.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/avatarAndDrops.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/basicDetails.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/contributorDetails.vue (98%) rename website/client/src/components/{ => admin}/admin-panel/user-support/cronAndAuth.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/customizationsOwned.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/index.vue (99%) rename website/client/src/components/{ => admin}/admin-panel/user-support/itemsOwned.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/partyAndQuest.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/privilegesAndGems.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/stats-row.vue (100%) rename website/client/src/components/{ => admin}/admin-panel/user-support/stats.vue (99%) rename website/client/src/components/{ => admin}/admin-panel/user-support/subscriptionAndPerks.vue (99%) rename website/client/src/components/{ => admin}/admin-panel/user-support/transactions.vue (91%) rename website/client/src/components/{ => admin}/admin-panel/user-support/userHistory.vue (99%) rename website/client/src/components/{ => admin}/admin-panel/user-support/userProfile.vue (97%) rename website/client/src/components/{ => admin}/blocker/blocker_form.vue (91%) rename website/client/src/components/{ => admin}/blocker/index.vue (94%) create mode 100644 website/client/src/components/admin/container.vue create mode 100644 website/common/locales/en/admin.json rename website/server/middlewares/{ipBlocker.js => blocker.js} (60%) diff --git a/package-lock.json b/package-lock.json index a998a40d36..7154e0a136 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,6 @@ "morgan": "^1.10.0", "nconf": "^0.12.1", "node-gcm": "^1.0.5", - "nodemon": "^3.1.9", "on-headers": "^1.0.2", "passport": "^0.5.3", "passport-facebook": "^3.0.0", @@ -16011,55 +16010,6 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, - "node_modules/nodemon": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", - "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", @@ -19423,28 +19373,6 @@ "is-arrayish": "^0.3.1" } }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/sinon": { "version": "15.2.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", diff --git a/package.json b/package.json index 22c7c191ed..c108755113 100644 --- a/package.json +++ b/package.json @@ -106,8 +106,8 @@ "start": "node --watch ./website/server/index.js", "start:simple": "node ./website/server/index.js", "debug": "node --watch --inspect ./website/server/index.js", - "mongo:dev": "run-rs -v 5.0.23 -l ubuntu1804 --keep --dbpath mongodb-data --number 1 --quiet", - "mongo:test": "run-rs -v 5.0.23 -l ubuntu1804 --keep --dbpath mongodb-data-testing --number 1 --quiet", + "mongo:dev": "run-rs -v 7.0.20 -l ubuntu2404 --keep --dbpath mongodb-data --number 1 --quiet", + "mongo:test": "run-rs -v 7.0.23 -l ubuntu2404 --keep --dbpath mongodb-data-testing --number 1 --quiet", "postinstall": "git config --global url.\"https://\".insteadOf git:// && gulp build && cd website/client && npm install", "apidoc": "gulp apidoc", "heroku-postbuild": ".heroku/report_deploy.sh" diff --git a/test/api/unit/middlewares/blocker.test.js b/test/api/unit/middlewares/blocker.test.js new file mode 100644 index 0000000000..2236eb5d58 --- /dev/null +++ b/test/api/unit/middlewares/blocker.test.js @@ -0,0 +1,78 @@ +import nconf from 'nconf'; +import requireAgain from 'require-again'; +import { + generateRes, + generateReq, + generateNext, +} from '../../../helpers/api-unit.helper'; +import { Forbidden } from '../../../../website/server/libs/errors'; +import { apiError } from '../../../../website/server/libs/apiError'; + +function checkIPBlockedErrorThrown (next) { + expect(next).to.have.been.calledOnce; + const calledWith = next.getCall(0).args; + expect(calledWith[0].message).to.equal(apiError('ipAddressBlocked')); + expect(calledWith[0] instanceof Forbidden).to.equal(true); +} + +function checkErrorNotThrown (next) { + expect(next).to.have.been.calledOnce; + const calledWith = next.getCall(0).args; + expect(typeof calledWith[0] === 'undefined').to.equal(true); +} + +describe('Blocker middleware', () => { + const pathToBlocker = '../../../../website/server/middlewares/blocker'; + + let res; let req; let next; + + beforeEach(() => { + res = generateRes(); + req = generateReq(); + next = generateNext(); + }); + + describe('Blocking IPs', () => { + it('is disabled when the env var is not defined', () => { + sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(undefined); + const attachIpBlocker = requireAgain(pathToBlocker).default; + attachIpBlocker(req, res, next); + + checkErrorNotThrown(next); + }); + + it('is disabled when the env var is an empty string', () => { + sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(''); + const attachIpBlocker = requireAgain(pathToBlocker).default; + attachIpBlocker(req, res, next); + + checkErrorNotThrown(next); + }); + + it('is disabled when the env var contains comma separated empty strings', () => { + sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(' , , '); + const attachIpBlocker = requireAgain(pathToBlocker).default; + attachIpBlocker(req, res, next); + + checkErrorNotThrown(next); + }); + + it('does not throw when the ip does not match', () => { + req.ip = '192.168.1.1'; + sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.2'); + const attachIpBlocker = requireAgain(pathToBlocker).default; + attachIpBlocker(req, res, next); + + checkErrorNotThrown(next); + }); + + it('throws when the ip is blocked', () => { + req.ip = '192.168.1.1'; + sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1'); + const attachIpBlocker = requireAgain(pathToBlocker).default; + attachIpBlocker(req, res, next); + + checkIPBlockedErrorThrown(next); + }); + }); +}); diff --git a/test/api/unit/middlewares/ipBlocker.test.js b/test/api/unit/middlewares/ipBlocker.test.js deleted file mode 100644 index e75994bfb9..0000000000 --- a/test/api/unit/middlewares/ipBlocker.test.js +++ /dev/null @@ -1,76 +0,0 @@ -import nconf from 'nconf'; -import requireAgain from 'require-again'; -import { - generateRes, - generateReq, - generateNext, -} from '../../../helpers/api-unit.helper'; -import { Forbidden } from '../../../../website/server/libs/errors'; -import { apiError } from '../../../../website/server/libs/apiError'; - -function checkErrorThrown (next) { - expect(next).to.have.been.calledOnce; - const calledWith = next.getCall(0).args; - expect(calledWith[0].message).to.equal(apiError('ipAddressBlocked')); - expect(calledWith[0] instanceof Forbidden).to.equal(true); -} - -function checkErrorNotThrown (next) { - expect(next).to.have.been.calledOnce; - const calledWith = next.getCall(0).args; - expect(typeof calledWith[0] === 'undefined').to.equal(true); -} - -describe('ipBlocker middleware', () => { - const pathToIpBlocker = '../../../../website/server/middlewares/ipBlocker'; - - let res; let req; let next; - - beforeEach(() => { - res = generateRes(); - req = generateReq(); - next = generateNext(); - }); - - it('is disabled when the env var is not defined', () => { - sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(undefined); - const attachIpBlocker = requireAgain(pathToIpBlocker).default; - attachIpBlocker(req, res, next); - - checkErrorNotThrown(next); - }); - - it('is disabled when the env var is an empty string', () => { - sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(''); - const attachIpBlocker = requireAgain(pathToIpBlocker).default; - attachIpBlocker(req, res, next); - - checkErrorNotThrown(next); - }); - - it('is disabled when the env var contains comma separated empty strings', () => { - sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(' , , '); - const attachIpBlocker = requireAgain(pathToIpBlocker).default; - attachIpBlocker(req, res, next); - - checkErrorNotThrown(next); - }); - - it('does not throw when the ip does not match', () => { - req.ip = '192.168.1.1'; - sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.2'); - const attachIpBlocker = requireAgain(pathToIpBlocker).default; - attachIpBlocker(req, res, next); - - checkErrorNotThrown(next); - }); - - it('throws when the ip is blocked', () => { - req.ip = '192.168.1.1'; - sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1'); - const attachIpBlocker = requireAgain(pathToIpBlocker).default; - attachIpBlocker(req, res, next); - - checkErrorThrown(next); - }); -}); diff --git a/website/client/src/components/admin-panel/filters/formatDate.js b/website/client/src/components/admin/admin-panel/filters/formatDate.js similarity index 100% rename from website/client/src/components/admin-panel/filters/formatDate.js rename to website/client/src/components/admin/admin-panel/filters/formatDate.js diff --git a/website/client/src/components/admin-panel/index.vue b/website/client/src/components/admin/admin-panel/index.vue similarity index 97% rename from website/client/src/components/admin-panel/index.vue rename to website/client/src/components/admin/admin-panel/index.vue index e9c9436153..a39f7ffcad 100644 --- a/website/client/src/components/admin-panel/index.vue +++ b/website/client/src/components/admin/admin-panel/index.vue @@ -1,7 +1,7 @@