From 77b27a56f7fd9dc2b58151e03026068957f03bec Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Thu, 23 Jul 2026 05:34:28 +0200 Subject: [PATCH] Determining location with restrictions disabled, cleaned up. --- components/settings/notifications.vue | 2 - components/user/account.vue | 4 + eslint.config.js | 12 + package-lock.json | 478 +++++++++++++++++- package.json | 1 + pages/auth/login/+Page.vue | 4 + pages/auth/signup/+Page.vue | 1 + pages/entities/+onBeforeRender.js | 2 +- pages/entities/@entitySlug/+onBeforeRender.js | 6 +- pages/movies/+onBeforeRender.js | 2 +- pages/movies/@movieId/+onBeforeRender.js | 4 +- pages/scenes/+onBeforeRender.js | 2 +- pages/scenes/@sceneId/+onBeforeRender.js | 2 +- pages/search/+onBeforeRender.js | 8 +- pages/tags/+onBeforeRender.js | 6 +- pages/tags/@tagId/+onBeforeRender.js | 6 +- pages/updates/+onBeforeRender.js | 2 +- renderer/+config.h.js | 2 +- src/auth.js | 2 +- src/get-path.js | 6 +- src/web/auth.js | 4 +- src/web/main.js | 2 +- src/web/movies.js | 6 +- src/web/restrictions.js | 84 ++- src/web/scenes.js | 6 +- src/web/tags.js | 2 +- tools/scene_tag_revision_fix.js | 2 +- utils/runtime-id.js | 3 + 28 files changed, 590 insertions(+), 71 deletions(-) create mode 100644 utils/runtime-id.js diff --git a/components/settings/notifications.vue b/components/settings/notifications.vue index 0193c45..401a52a 100644 --- a/components/settings/notifications.vue +++ b/components/settings/notifications.vue @@ -1,6 +1,4 @@ diff --git a/components/user/account.vue b/components/user/account.vue index 2c78a45..4d0896a 100644 --- a/components/user/account.vue +++ b/components/user/account.vue @@ -49,6 +49,10 @@ async function updateAccount() { appendErrorMessage: true, }); + currentPassword.value = null; + credentials.email = null; + credentials.password = null; + submitted.value = true; } finally { diff --git a/eslint.config.js b/eslint.config.js index 7e4944c..465f2ba 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,4 +1,5 @@ import antfu from '@antfu/eslint-config'; +import importX, { createNodeResolver } from 'eslint-plugin-import-x'; export default antfu( { @@ -18,11 +19,21 @@ export default antfu( }, }, { + plugins: { 'import-x': importX }, languageOptions: { globals: { CONFIG: 'readonly', }, }, + settings: { + // mirrors the '#'/'#root' aliases in vite.config.js, which is what actually resolves these at build/runtime + 'import-x/resolver-next': [createNodeResolver({ + alias: { + '#': [import.meta.dirname], + '#root': [import.meta.dirname], + }, + })], + }, rules: { 'default-param-last': 'off', 'no-underscore-dangle': 'off', @@ -33,6 +44,7 @@ export default antfu( ignorePropertyModificationsFor: ['state', 'acc', 'req'], }], 'prefer-destructuring': 'off', + 'import-x/no-unresolved': 'error', 'import/prefer-default-export': 'off', 'unused-imports/no-unused-vars': ['error', { args: 'after-used', diff --git a/package-lock.json b/package-lock.json index fc36cfd..b2b689b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "ejs": "^6.0.1", "error-stack-parser": "^2.1.4", "escape-string-regexp": "^5.0.0", + "eslint-plugin-import-x": "^4.17.1", "express": "^5.2.1", "express-session": "^1.19.0", "floating-vue": "^5.2.2", @@ -6113,7 +6114,7 @@ "version": "8.63.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz", "integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.63.0", @@ -6339,7 +6340,7 @@ "version": "8.63.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz", "integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.63.0", @@ -6357,7 +6358,7 @@ "version": "8.63.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz", "integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6399,7 +6400,6 @@ "version": "8.63.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz", "integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==", - "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6413,7 +6413,7 @@ "version": "8.63.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz", "integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@typescript-eslint/project-service": "8.63.0", @@ -6441,7 +6441,7 @@ "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -6454,7 +6454,7 @@ "version": "8.63.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.63.0.tgz", "integrity": "sha512-fUKaeAvrTuQg/Tgt3nliAUSZHJM6DlCcfyEmxCvlX8kieWSStBX+5O5Fnidtc3i2JrH+9c/GL4RY2iasd/GPTA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", @@ -6478,7 +6478,7 @@ "version": "8.63.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz", "integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.63.0", @@ -6496,7 +6496,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" @@ -6663,6 +6663,328 @@ "@universal-middleware/core": "^0.4.18" } }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@videojs/http-streaming": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.17.5.tgz", @@ -8363,7 +8685,6 @@ "version": "1.4.5", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.5.tgz", "integrity": "sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 12.0.0" @@ -9756,6 +10077,30 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", @@ -9932,6 +10277,54 @@ "eslint": "^9.0.0 || ^10.0.0" } }, + "node_modules/eslint-plugin-import-x": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.17.1.tgz", + "integrity": "sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "^8.56.0", + "comment-parser": "^1.4.1", + "debug": "^4.4.1", + "eslint-import-context": "^0.1.9", + "is-glob": "^4.0.3", + "minimatch": "^9.0.3 || ^10.1.2", + "semver": "^7.7.2", + "stable-hash-x": "^0.2.0", + "unrs-resolver": "^1.9.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-import-x" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^8.56.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "eslint-import-resolver-node": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/utils": { + "optional": true + }, + "eslint-import-resolver-node": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-import-x/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-plugin-jsdoc": { "version": "63.0.13", "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-63.0.13.tgz", @@ -11318,7 +11711,6 @@ "version": "4.14.0", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", - "dev": true, "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -15871,6 +16263,21 @@ "optional": true, "peer": true }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -17694,7 +18101,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -18478,6 +18884,15 @@ "node": ">=20.16.0" } }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -19412,7 +19827,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=18.12" @@ -20320,6 +20735,43 @@ "node": ">=8" } }, + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", diff --git a/package.json b/package.json index a47fd1f..4e1b8ba 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "ejs": "^6.0.1", "error-stack-parser": "^2.1.4", "escape-string-regexp": "^5.0.0", + "eslint-plugin-import-x": "^4.17.1", "express": "^5.2.1", "express-session": "^1.19.0", "floating-vue": "^5.2.2", diff --git a/pages/auth/login/+Page.vue b/pages/auth/login/+Page.vue index 67c8ccc..8175b7f 100644 --- a/pages/auth/login/+Page.vue +++ b/pages/auth/login/+Page.vue @@ -191,4 +191,8 @@ onMounted(() => { font-weight: bold; text-align: center; } + +.button-submit { + padding: .75rem 1rem; +} diff --git a/pages/auth/signup/+Page.vue b/pages/auth/signup/+Page.vue index 9bac649..f4e5ba7 100644 --- a/pages/auth/signup/+Page.vue +++ b/pages/auth/signup/+Page.vue @@ -221,6 +221,7 @@ onMounted(() => { } .button-submit { + padding: .75rem 1rem; margin-top: .5rem; } diff --git a/pages/entities/+onBeforeRender.js b/pages/entities/+onBeforeRender.js index 69c423c..f931fd4 100644 --- a/pages/entities/+onBeforeRender.js +++ b/pages/entities/+onBeforeRender.js @@ -4,7 +4,7 @@ export async function onBeforeRender(pageContext) { const networks = await fetchEntities(pageContext.urlParsed.search.q ? { query: pageContext.urlParsed.search.q } : { type: 'primary' }, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }); return { diff --git a/pages/entities/@entitySlug/+onBeforeRender.js b/pages/entities/@entitySlug/+onBeforeRender.js index bd32350..2377c87 100644 --- a/pages/entities/@entitySlug/+onBeforeRender.js +++ b/pages/entities/@entitySlug/+onBeforeRender.js @@ -21,7 +21,7 @@ async function fetchReleases(pageContext, entityId) { limit: Number(pageContext.urlParsed.search.limit) || 30, aggregate: true, }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }); } @@ -35,7 +35,7 @@ async function fetchReleases(pageContext, entityId) { limit: Number(pageContext.urlParsed.search.limit) || 30, aggregate: true, }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }); } @@ -52,7 +52,7 @@ export async function onBeforeRender(pageContext) { entityReleases, ] = await Promise.all([ fetchEntitiesById([Number(entityId)], { includeChildren: true }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }), fetchReleases(pageContext, entityId), ]); diff --git a/pages/movies/+onBeforeRender.js b/pages/movies/+onBeforeRender.js index 6bdd7dd..0d92069 100644 --- a/pages/movies/+onBeforeRender.js +++ b/pages/movies/+onBeforeRender.js @@ -10,7 +10,7 @@ export async function onBeforeRender(pageContext) { limit: Number(pageContext.urlParsed.search.limit) || 50, dedupe: true, }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }); return { diff --git a/pages/movies/@movieId/+onBeforeRender.js b/pages/movies/@movieId/+onBeforeRender.js index 27dce7f..b25c9c9 100644 --- a/pages/movies/@movieId/+onBeforeRender.js +++ b/pages/movies/@movieId/+onBeforeRender.js @@ -18,7 +18,7 @@ function getTitle(movie) { export async function onBeforeRender(pageContext) { const [[movie], movieScenes] = await Promise.all([ - fetchMoviesById([Number(pageContext.routeParams.movieId)], pageContext.user, { restriction: pageContext.restriction }), + fetchMoviesById([Number(pageContext.routeParams.movieId)], pageContext.user, { restriction: pageContext.geo.restriction }), fetchScenes(await curateScenesQuery({ ...pageContext.urlQuery, scope: 'oldest', @@ -28,7 +28,7 @@ export async function onBeforeRender(pageContext) { limit: Number(pageContext.urlParsed.search.limit) || 30, aggregate: true, }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }), ]); diff --git a/pages/scenes/+onBeforeRender.js b/pages/scenes/+onBeforeRender.js index 74718c9..88bcf45 100644 --- a/pages/scenes/+onBeforeRender.js +++ b/pages/scenes/+onBeforeRender.js @@ -18,7 +18,7 @@ export async function onBeforeRender(pageContext) { aggregate: true, dedupe: true, }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }), getRandomCampaigns([ { minRatio: 0.75, maxRatio: 1.25 }, diff --git a/pages/scenes/@sceneId/+onBeforeRender.js b/pages/scenes/@sceneId/+onBeforeRender.js index 7394664..52a46ff 100644 --- a/pages/scenes/@sceneId/+onBeforeRender.js +++ b/pages/scenes/@sceneId/+onBeforeRender.js @@ -25,7 +25,7 @@ export async function onBeforeRender(pageContext) { includeAssets: true, includePartOf: true, actorStashes: true, - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }); if (!scene) { diff --git a/pages/search/+onBeforeRender.js b/pages/search/+onBeforeRender.js index cf7b058..3fb3f08 100644 --- a/pages/search/+onBeforeRender.js +++ b/pages/search/+onBeforeRender.js @@ -16,24 +16,24 @@ export async function onBeforeRender(pageContext) { }), { page: Number(pageContext.routeParams.page) || 1, limit: Number(pageContext.urlParsed.search.limit) || 15, - }, pageContext.user, { restriction: pageContext.restriction }), + }, pageContext.user, { restriction: pageContext.geo.restriction }), fetchActors(curateActorsQuery(pageContext.urlQuery), { page: Number(pageContext.routeParams.page) || 1, limit: Number(pageContext.urlParsed.search.limit) || 10, order: ['results', 'desc'], - }, pageContext.user, { restriction: pageContext.restriction }), + }, pageContext.user, { restriction: pageContext.geo.restriction }), fetchMovies(await curateMoviesQuery({ ...pageContext.urlQuery, scope: pageContext.routeParams.scope || 'results', }), { page: Number(pageContext.routeParams.page) || 1, limit: Number(pageContext.urlParsed.search.limit) || 5, - }, pageContext.user, { restriction: pageContext.restriction }), + }, pageContext.user, { restriction: pageContext.geo.restriction }), fetchEntities({ query: pageContext.urlParsed.search.q, limit: 5, }, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }), ]); diff --git a/pages/tags/+onBeforeRender.js b/pages/tags/+onBeforeRender.js index af8cea8..385710e 100644 --- a/pages/tags/+onBeforeRender.js +++ b/pages/tags/+onBeforeRender.js @@ -118,7 +118,7 @@ const tagSlugs = { }; async function searchTags(pageContext) { - const tags = await fetchTags({ query: pageContext.urlParsed.search.q }, { restriction: pageContext.restriction }); + const tags = await fetchTags({ query: pageContext.urlParsed.search.q }, { restriction: pageContext.geo.restriction }); return { pageContext: { @@ -137,13 +137,13 @@ export async function onBeforeRender(pageContext) { return searchTags(pageContext); } - const tags = await fetchTagsById(Object.values(tagSlugs).flat(), {}, pageContext.user, { restriction: pageContext.restriction }); + const tags = await fetchTagsById(Object.values(tagSlugs).flat(), {}, pageContext.user, { restriction: pageContext.geo.restriction }); const filteredTags = tags.filter((tag) => !pageContext.tagFilter.includes(tag.name) && !pageContext.tagFilter.includes(tag.slug)); const tagsBySlug = Object.fromEntries(filteredTags.map((tag) => [tag.slug, tag])); const tagShowcase = Object.fromEntries(Object.entries(tagSlugs).map(([category, categorySlugs]) => [ - censor(category, pageContext.restriction), + censor(category, pageContext.geo.restriction), categorySlugs.map((slug) => tagsBySlug[slug]).filter(Boolean), ])); diff --git a/pages/tags/@tagId/+onBeforeRender.js b/pages/tags/@tagId/+onBeforeRender.js index a9cd8ff..c1b104d 100644 --- a/pages/tags/@tagId/+onBeforeRender.js +++ b/pages/tags/@tagId/+onBeforeRender.js @@ -23,7 +23,7 @@ async function fetchReleases(pageContext) { limit: Number(pageContext.urlParsed.search.limit) || 30, aggregate: true, }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }); } @@ -37,13 +37,13 @@ async function fetchReleases(pageContext) { limit: Number(pageContext.urlParsed.search.limit) || 30, aggregate: true, }, pageContext.user, { - restriction: pageContext.restriction, + restriction: pageContext.geo.restriction, }); } export async function onBeforeRender(pageContext) { const tagSlug = pageContext.routeParams.tagSlug; - const [tag] = await fetchTagsById([tagSlug], {}, pageContext.user, { restriction: pageContext.restriction }); + const [tag] = await fetchTagsById([tagSlug], {}, pageContext.user, { restriction: pageContext.geo.restriction }); if (tag.aliasFor) { throw redirect(`/tag/${tag.aliasFor}`); diff --git a/pages/updates/+onBeforeRender.js b/pages/updates/+onBeforeRender.js index 253161e..51b8018 100644 --- a/pages/updates/+onBeforeRender.js +++ b/pages/updates/+onBeforeRender.js @@ -19,7 +19,7 @@ export async function onBeforeRender(pageContext) { limit: Number(pageContext.urlParsed.search.limit) || 29, aggregate: withQuery, dedupe: true, - }, pageContext.user, { restriction: pageContext.restriction }), + }, pageContext.user, { restriction: pageContext.geo.restriction }), getRandomCampaigns([ { minRatio: 2.0, maxRatio: 5 }, { minRatio: 0.75, maxRatio: 1.25 }, diff --git a/renderer/+config.h.js b/renderer/+config.h.js index 4bfc823..e349ff7 100644 --- a/renderer/+config.h.js +++ b/renderer/+config.h.js @@ -9,6 +9,6 @@ export default { 'assets', 'campaigns', 'meta', - 'restriction', + 'geo', ], }; diff --git a/src/auth.js b/src/auth.js index 7e4c5fd..fac4c94 100755 --- a/src/auth.js +++ b/src/auth.js @@ -423,7 +423,7 @@ async function updatePassword(password, reqUser, reqSession) { .where('id', reqUser.id) .update('password', storedPassword); - const country = reqSession.country && await knex('countries').where('alpha2', reqSession.country).first(); + const country = reqSession.geo?.country && await knex('countries').where('alpha2', reqSession.geo.country).first(); await sendEmails([{ template: 'password', diff --git a/src/get-path.js b/src/get-path.js index 02564b0..df7a13a 100644 --- a/src/get-path.js +++ b/src/get-path.js @@ -1,7 +1,7 @@ import { pageContext } from '../renderer/usePageContext.js'; function getBasePath(media, options) { - if (pageContext.restriction) { + if (pageContext.geo.restriction) { return pageContext.env.media.assetPath; } @@ -17,11 +17,11 @@ function getBasePath(media, options) { } function getFilename(media, type, options) { - if (pageContext.restriction && type && !options?.original) { + if (pageContext.geo.restriction && type && !options?.original) { return media.sfw?.[type]; } - if (pageContext.restriction) { + if (pageContext.geo.restriction) { return media.sfw?.path; } diff --git a/src/web/auth.js b/src/web/auth.js index 5383eb2..f207c2a 100755 --- a/src/web/auth.js +++ b/src/web/auth.js @@ -1,6 +1,7 @@ -import crypto from 'node:crypto'; import { Router } from 'express'; import IPCIDR from 'ip-cidr'; + +import runtimeId from '../../utils/runtime-id.js'; import argv from '../argv.js'; import { @@ -24,7 +25,6 @@ import { // changes every time the process restarts, so a deploy invalidates all cached session users // even if they're within the staleness window below -const runtimeId = crypto.randomUUID(); const sessionStaleThreshold = 5 * 60 * 1000; // spread into a new object rather than mutating the user we're about to hand back to the diff --git a/src/web/main.js b/src/web/main.js index 4ed1961..bd6cad6 100644 --- a/src/web/main.js +++ b/src/web/main.js @@ -60,7 +60,7 @@ export default async function mainHandler(req, res, next) { siteKey: config.auth.captcha.siteKey, }, }, - restriction: req.restriction, + geo: req.geo, meta: { now: new Date().toISOString(), }, diff --git a/src/web/movies.js b/src/web/movies.js index 1333b69..c671608 100644 --- a/src/web/movies.js +++ b/src/web/movies.js @@ -31,7 +31,7 @@ export async function fetchMoviesApi(req, res) { } = await fetchMovies(await curateMoviesQuery(req.query), { page: Number(req.query.page) || 1, limit: Number(req.query.limit) || 30, - }, req.user, { restriction: req.restriction }); + }, req.user, { restriction: req.geo.restriction }); res.send({ movies, @@ -45,7 +45,7 @@ export async function fetchMoviesApi(req, res) { } export async function fetchMovieApi(req, res) { - const [movie] = await fetchMoviesById([Number(req.params.movieId)], { reqUser: req.user }, { restriction: req.restriction }); + const [movie] = await fetchMoviesById([Number(req.params.movieId)], { reqUser: req.user }, { restriction: req.geo.restriction }); if (!movie) { throw new HttpError(`No movie with ID ${req.params.movieId} found`, 404); @@ -135,7 +135,7 @@ export async function fetchMoviesGraphql(query, req) { page: query.page || 1, limit: query.limit || 30, aggregate: false, - }, req.user, { restriction: req.restriction }); + }, req.user, { restriction: req.geo.restriction }); return { nodes: movies, diff --git a/src/web/restrictions.js b/src/web/restrictions.js index 66024e0..5de2221 100644 --- a/src/web/restrictions.js +++ b/src/web/restrictions.js @@ -2,6 +2,7 @@ import path from 'node:path'; import { Reader } from '@maxmind/geoip2-node'; import config from 'config'; +import runtimeId from '../../utils/runtime-id.js'; import initLogger from '../logger.js'; const logger = initLogger(); @@ -11,22 +12,47 @@ export default async function initRestrictionHandler() { const reader = await Reader.open('assets/GeoLite2-City.mmdb'); function getRestriction(req) { - if (Object.hasOwn(req.session, 'restriction') && Object.hasOwn(req.session, 'country') && req.session.restrictionIp === req.userIp) { - return { - restriction: req.session.restriction, - country: req.session.country, - }; + if (req.session.geo + && Object.hasOwn(req.session.geo, 'country') + && req.session.geo.ip === req.userIp + && req.session.geo.runtimeId === runtimeId) { + const { country, subdivision } = req.session.geo; + + if (!config.restrictions.enabled) { + return { + restriction: 0, + country, + subdivision, + }; + } + + if (Object.hasOwn(req.session.geo, 'restriction')) { + return { + restriction: req.session.geo.restriction, + country, + subdivision, + }; + } } const location = reader.city(req.userIp); const country = location.country.isoCode; const subdivision = location.subdivisions?.[0]?.isoCode; + if (!config.restrictions.enabled) { + return { + restriction: 0, + country, + subdivision, + }; + } + if (regions[country]?.[subdivision]) { // state or province restriction return { restriction: config.restrictions.modes[regions[country][subdivision]], country, + subdivision, }; } @@ -35,23 +61,24 @@ export default async function initRestrictionHandler() { return { restriction: config.restrictions.modes[regions[country]], country, + subdivision, }; } return { restriction: null, country, + subdivision, }; } function restrictionHandler(req, res, next) { - if (!config.restrictions.enabled) { - next(); - return; - } - try { - const { restriction, country } = getRestriction(req); + const { + restriction, + country, + subdivision, + } = getRestriction(req); if (restriction === 'block' || req.path === '/sfw/') { res.render(path.join(import.meta.dirname, '../../assets/sfw.ejs'), { @@ -61,21 +88,38 @@ export default async function initRestrictionHandler() { return; } - if (req.session.restriction !== restriction) { - req.session.restrictionIp = req.userIp; - req.session.restriction = restriction; - req.session.country = country; + if (req.session.geo?.restriction !== restriction) { + req.session.geo = { + ip: req.userIp, + runtimeId, + restriction, + country, + subdivision, + }; } - req.restriction = restriction; - req.country = country; + req.geo = { + restriction, + country, + subdivision, + }; } catch (error) { logger.error(`Failed Maxmind IP lookup for ${req.ip}: ${error.message}`); - req.session.restrictionIp = req.userIp; - req.session.restriction = 0; - req.session.country = null; + req.session.geo = { + ip: req.userIp, + runtimeId, + restriction: 0, + country: null, + subdivision: null, + }; + + req.geo = { + restriction: 0, + country: null, + subdivision: null, + }; } next(); diff --git a/src/web/scenes.js b/src/web/scenes.js index b220a0e..be2082a 100644 --- a/src/web/scenes.js +++ b/src/web/scenes.js @@ -70,7 +70,7 @@ async function fetchScenesApi(req, res) { page: Number(req.query.page) || 1, limit: Number(req.query.limit) || 30, }, req.user, { - restriction: req.restriction, + restriction: req.geo.restriction, }); res.send({ @@ -254,7 +254,7 @@ export async function fetchScenesGraphql(query, req) { } async function fetchSceneApi(req, res) { - const [scene] = await fetchScenesById([Number(req.params.sceneId)], { reqUser: req.user }, { restriction: req.restriction }); + const [scene] = await fetchScenesById([Number(req.params.sceneId)], { reqUser: req.user }, { restriction: req.geo.restriction }); if (!scene) { throw new HttpError(`No scene with ID ${req.params.sceneId} found`, 404); @@ -267,7 +267,7 @@ export async function fetchScenesByIdGraphql(query, req) { const scenes = await fetchScenesById([].concat(query.id, query.ids).filter(Boolean), { reqUser: req.user, includePartOf: true, - restriction: req.restriction, + restriction: req.geo.restriction, }); if (query.ids) { diff --git a/src/web/tags.js b/src/web/tags.js index 5a452f5..40cf697 100644 --- a/src/web/tags.js +++ b/src/web/tags.js @@ -4,7 +4,7 @@ export async function fetchTagsApi(req, res) { const tags = await fetchTags({ query: req.query.query, }, { - restriction: req.restriction, + restriction: req.geo.restriction, }); res.send(tags); diff --git a/tools/scene_tag_revision_fix.js b/tools/scene_tag_revision_fix.js index b8497d5..dcf8898 100644 --- a/tools/scene_tag_revision_fix.js +++ b/tools/scene_tag_revision_fix.js @@ -1,6 +1,6 @@ import { MerkleJson } from 'merkle-json'; -import knex from '../knex.js'; +import knex from '../src/knex.js'; const mj = new MerkleJson(); diff --git a/utils/runtime-id.js b/utils/runtime-id.js new file mode 100644 index 0000000..6e22d4a --- /dev/null +++ b/utils/runtime-id.js @@ -0,0 +1,3 @@ +import crypto from 'node:crypto'; + +export default crypto.randomUUID();