+
![{alt}]()
imageRatio,
- "w-full h-auto": containerRatio <= imageRatio,
- },
- )}
- src={blobUrl}
+ className="h-full w-full object-cover"
+ src={src}
/>
);
})}
diff --git a/application/server/src/routes/static.ts b/application/server/src/routes/static.ts
index b5820c986e..9296b8d3b2 100644
--- a/application/server/src/routes/static.ts
+++ b/application/server/src/routes/static.ts
@@ -2,34 +2,16 @@ import history from "connect-history-api-fallback";
import { Router } from "express";
import serveStatic from "serve-static";
-import {
- CLIENT_DIST_PATH,
- PUBLIC_PATH,
- UPLOAD_PATH,
-} from "@web-speed-hackathon-2026/server/src/paths";
+import { CLIENT_DIST_PATH, PUBLIC_PATH, UPLOAD_PATH } from "@web-speed-hackathon-2026/server/src/paths";
export const staticRouter = Router();
-// SPA 対応のため、ファイルが存在しないときに index.html を返す
+// 拡張子がついてるリクエストは index.html に書き換えて CLIENT_DIST_PATH に引っかける
+// ついてないリクエストはそのまま通して他のルーターに引っかける
staticRouter.use(history());
-staticRouter.use(
- serveStatic(UPLOAD_PATH, {
- etag: false,
- lastModified: false,
- }),
-);
+staticRouter.use(serveStatic(UPLOAD_PATH));
-staticRouter.use(
- serveStatic(PUBLIC_PATH, {
- etag: false,
- lastModified: false,
- }),
-);
+staticRouter.use(serveStatic(PUBLIC_PATH));
-staticRouter.use(
- serveStatic(CLIENT_DIST_PATH, {
- etag: false,
- lastModified: false,
- }),
-);
+staticRouter.use(serveStatic(CLIENT_DIST_PATH));
From 34ab60f5a757a54630e610a57ae27a4b8d9c76d4 Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Fri, 20 Mar 2026 18:12:34 +0900
Subject: [PATCH 04/11] =?UTF-8?q?=E7=94=BB=E5=83=8F=E3=81=AE=20Cache-Contr?=
=?UTF-8?q?ol=20=E3=82=92=E4=B8=8D=E5=A4=89=E3=81=AB=E8=A8=AD=E5=AE=9A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/server/package.json | 1 +
application/server/pnpm-lock.yaml | 315 ++++++++++++++++++++++++
application/server/src/routes/static.ts | 37 ++-
3 files changed, 351 insertions(+), 2 deletions(-)
create mode 100644 application/server/pnpm-lock.yaml
diff --git a/application/server/package.json b/application/server/package.json
index 9482575df7..155632ed62 100644
--- a/application/server/package.json
+++ b/application/server/package.json
@@ -25,6 +25,7 @@
"music-metadata": "11.10.3",
"sequelize": "6.37.7",
"serve-static": "2.2.0",
+ "sharp": "^0.34.5",
"sqlite3": "5.1.7",
"tsx": "4.20.6",
"uuid": "13.0.0",
diff --git a/application/server/pnpm-lock.yaml b/application/server/pnpm-lock.yaml
new file mode 100644
index 0000000000..8a54e70d33
--- /dev/null
+++ b/application/server/pnpm-lock.yaml
@@ -0,0 +1,315 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@web-speed-hackathon-2026/server':
+ specifier: workspace:*
+ version: 'link:'
+ sharp:
+ specifier: ^0.34.5
+ version: 0.34.5
+
+packages:
+
+ '@emnapi/runtime@1.9.1':
+ resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==}
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ semver@7.7.4:
+ resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+snapshots:
+
+ '@emnapi/runtime@1.9.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@img/colour@1.1.0': {}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.9.1
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
+ detect-libc@2.1.2: {}
+
+ semver@7.7.4: {}
+
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.7.4
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+
+ tslib@2.8.1:
+ optional: true
diff --git a/application/server/src/routes/static.ts b/application/server/src/routes/static.ts
index 9296b8d3b2..2691413aad 100644
--- a/application/server/src/routes/static.ts
+++ b/application/server/src/routes/static.ts
@@ -1,15 +1,48 @@
+import { promises as fs } from "fs";
+import path from "path";
+
import history from "connect-history-api-fallback";
import { Router } from "express";
+import sharp from "sharp";
import serveStatic from "serve-static";
import { CLIENT_DIST_PATH, PUBLIC_PATH, UPLOAD_PATH } from "@web-speed-hackathon-2026/server/src/paths";
export const staticRouter = Router();
-// 拡張子がついてるリクエストは index.html に書き換えて CLIENT_DIST_PATH に引っかける
-// ついてないリクエストはそのまま通して他のルーターに引っかける
+// SPA 対応のため、ファイルが存在しないときに index.html を返す
staticRouter.use(history());
+const IMAGE_CACHE_PATH = path.resolve(UPLOAD_PATH, "cache/images");
+
+staticRouter.get("/images/*relativePath", async (req, res, next) => {
+ const relativePath = (req.params as Record
)["relativePath"];
+ if (relativePath === undefined) return next();
+ const originalPath = path.resolve(UPLOAD_PATH, "images", relativePath);
+
+ try {
+ await fs.access(originalPath);
+ } catch {
+ return next();
+ }
+
+ const cachedPath = path.resolve(IMAGE_CACHE_PATH, relativePath.replace(/\.jpg$/, ".webp"));
+
+ try {
+ await fs.access(cachedPath);
+ } catch {
+ await fs.mkdir(path.dirname(cachedPath), { recursive: true });
+ await sharp(originalPath)
+ .resize({ width: 800, withoutEnlargement: true })
+ .webp({ quality: 80 })
+ .toFile(cachedPath);
+ }
+
+ res.setHeader("Content-Type", "image/webp");
+ res.setHeader("Cache-Control", "max-age=31536000, immutable");
+ return res.sendFile(cachedPath);
+});
+
staticRouter.use(serveStatic(UPLOAD_PATH));
staticRouter.use(serveStatic(PUBLIC_PATH));
From 1671d761a994db4220b3ba017df5843e08bca153 Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Fri, 20 Mar 2026 18:16:17 +0900
Subject: [PATCH 05/11] =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E4=BF=AE?=
=?UTF-8?q?=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/server/src/routes/static.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/application/server/src/routes/static.ts b/application/server/src/routes/static.ts
index 2691413aad..9c91012131 100644
--- a/application/server/src/routes/static.ts
+++ b/application/server/src/routes/static.ts
@@ -16,8 +16,9 @@ staticRouter.use(history());
const IMAGE_CACHE_PATH = path.resolve(UPLOAD_PATH, "cache/images");
staticRouter.get("/images/*relativePath", async (req, res, next) => {
- const relativePath = (req.params as Record)["relativePath"];
- if (relativePath === undefined) return next();
+ const relativePathParam = (req.params as Record)["relativePath"];
+ if (relativePathParam === undefined) return next();
+ const relativePath = Array.isArray(relativePathParam) ? relativePathParam.join("/") : relativePathParam;
const originalPath = path.resolve(UPLOAD_PATH, "images", relativePath);
try {
From eb24d75d0deb5bf78f09645e867cb71be6255249 Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Fri, 20 Mar 2026 22:27:17 +0900
Subject: [PATCH 06/11] =?UTF-8?q?=E3=83=90=E3=82=A4=E3=83=8A=E3=83=AA?=
=?UTF-8?q?=E3=81=AE=E9=9D=9E=E5=90=8C=E6=9C=9F=E8=AA=AD=E3=81=BF=E8=BE=BC?=
=?UTF-8?q?=E3=81=BF=E3=81=A8=E3=82=B9=E3=82=AF=E3=83=AD=E3=83=BC=E3=83=AB?=
=?UTF-8?q?=E3=83=8F=E3=83=B3=E3=83=89=E3=83=AA=E3=83=B3=E3=82=B0=E3=81=AE?=
=?UTF-8?q?=E5=89=8A=E9=99=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/components/foundation/InfiniteScroll.tsx | 15 +++++++--------
.../client/src/hooks/use_infinite_fetch.ts | 12 +++++-------
application/client/src/utils/fetchers.ts | 4 ----
3 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/application/client/src/components/foundation/InfiniteScroll.tsx b/application/client/src/components/foundation/InfiniteScroll.tsx
index 408f24c107..dc4ba43207 100644
--- a/application/client/src/components/foundation/InfiniteScroll.tsx
+++ b/application/client/src/components/foundation/InfiniteScroll.tsx
@@ -13,10 +13,7 @@ export const InfiniteScroll = ({ children, fetchMore, items }: Props) => {
useEffect(() => {
const handler = () => {
- // 念の為 2の18乗 回、最下部かどうかを確認する
- const hasReached = Array.from(Array(2 ** 18), () => {
- return window.innerHeight + Math.ceil(window.scrollY) >= document.body.offsetHeight;
- }).every(Boolean);
+ const hasReached = window.innerHeight + Math.ceil(window.scrollY) >= document.body.offsetHeight;
// 画面最下部にスクロールしたタイミングで、登録したハンドラを呼び出す
if (hasReached && !prevReachedRef.current) {
@@ -33,10 +30,12 @@ export const InfiniteScroll = ({ children, fetchMore, items }: Props) => {
prevReachedRef.current = false;
handler();
- document.addEventListener("wheel", handler, { passive: false });
- document.addEventListener("touchmove", handler, { passive: false });
- document.addEventListener("resize", handler, { passive: false });
- document.addEventListener("scroll", handler, { passive: false });
+ // passive: false はブラウザに「このハンドラが preventDefault() を呼ぶかもしれない」と伝えるフラグ
+ // ブラウザがスクロールを遅延させてハンドラの完了を待つ原因になる
+ document.addEventListener("wheel", handler, { passive: true });
+ document.addEventListener("touchmove", handler, { passive: true });
+ document.addEventListener("resize", handler, { passive: true });
+ document.addEventListener("scroll", handler, { passive: true });
return () => {
document.removeEventListener("wheel", handler);
document.removeEventListener("touchmove", handler);
diff --git a/application/client/src/hooks/use_infinite_fetch.ts b/application/client/src/hooks/use_infinite_fetch.ts
index 394fccd9ea..9612fe2c76 100644
--- a/application/client/src/hooks/use_infinite_fetch.ts
+++ b/application/client/src/hooks/use_infinite_fetch.ts
@@ -9,10 +9,7 @@ interface ReturnValues {
fetchMore: () => void;
}
-export function useInfiniteFetch(
- apiPath: string,
- fetcher: (apiPath: string) => Promise,
-): ReturnValues {
+export function useInfiniteFetch(apiPath: string, fetcher: (apiPath: string) => Promise): ReturnValues {
const internalRef = useRef({ isLoading: false, offset: 0 });
const [result, setResult] = useState, "fetchMore">>({
@@ -36,11 +33,12 @@ export function useInfiniteFetch(
offset,
};
- void fetcher(apiPath).then(
- (allData) => {
+ const separator = apiPath.includes("?") ? "&" : "?";
+ void fetcher(`${apiPath}${separator}limit=${LIMIT}&offset=${offset}`).then(
+ (pageData) => {
setResult((cur) => ({
...cur,
- data: [...cur.data, ...allData.slice(offset, offset + LIMIT)],
+ data: [...cur.data, ...pageData],
isLoading: false,
}));
internalRef.current = {
diff --git a/application/client/src/utils/fetchers.ts b/application/client/src/utils/fetchers.ts
index 92a14f408f..c4615071b6 100644
--- a/application/client/src/utils/fetchers.ts
+++ b/application/client/src/utils/fetchers.ts
@@ -3,7 +3,6 @@ import { gzip } from "pako";
export async function fetchBinary(url: string): Promise {
const result = await $.ajax({
- async: false,
dataType: "binary",
method: "GET",
responseType: "arraybuffer",
@@ -14,7 +13,6 @@ export async function fetchBinary(url: string): Promise {
export async function fetchJSON(url: string): Promise {
const result = await $.ajax({
- async: false,
dataType: "json",
method: "GET",
url,
@@ -24,7 +22,6 @@ export async function fetchJSON(url: string): Promise {
export async function sendFile(url: string, file: File): Promise {
const result = await $.ajax({
- async: false,
data: file,
dataType: "json",
headers: {
@@ -43,7 +40,6 @@ export async function sendJSON(url: string, data: object): Promise {
const compressed = gzip(uint8Array);
const result = await $.ajax({
- async: false,
data: compressed,
dataType: "json",
headers: {
From 6c0ea88472874bdceff2b1b689f495be106059f4 Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Fri, 20 Mar 2026 23:00:29 +0900
Subject: [PATCH 07/11] =?UTF-8?q?ReDoS=20=E3=82=92=E8=A7=A3=E6=B6=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/client/src/search/services.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/application/client/src/search/services.ts b/application/client/src/search/services.ts
index 77f9de5de9..e8713b9bb0 100644
--- a/application/client/src/search/services.ts
+++ b/application/client/src/search/services.ts
@@ -10,8 +10,8 @@ export const sanitizeSearchText = (input: string): string => {
};
export const parseSearchQuery = (query: string) => {
- const sincePattern = /since:((\d|\d\d|\d\d\d\d-\d\d-\d\d)+)+$/;
- const untilPattern = /until:((\d|\d\d|\d\d\d\d-\d\d-\d\d)+)+$/;
+ const sincePattern = /since:(\d{4}-\d{2}-\d{2})/;
+ const untilPattern = /until:(\d{4}-\d{2}-\d{2})/;
const sincePart = query.match(/since:[^\s]*/)?.[0] || "";
const untilPart = query.match(/until:[^\s]*/)?.[0] || "";
@@ -38,7 +38,7 @@ export const parseSearchQuery = (query: string) => {
};
export const isValidDate = (dateStr: string): boolean => {
- const slowDateLike = /^(\d+)+-(\d+)+-(\d+)+$/;
+ const slowDateLike = /^\d+-\d+-\d+$/;
if (!slowDateLike.test(dateStr)) return false;
const date = new Date(dateStr);
From 9bd3211ec3df0883c6e841a07f686e4fcf6c170b Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Sat, 21 Mar 2026 15:22:17 +0900
Subject: [PATCH 08/11] =?UTF-8?q?DM=E8=A9=B3=E7=B4=B0=E3=83=9A=E3=83=BC?=
=?UTF-8?q?=E3=82=B8=E3=83=BBCrok=20AI=E3=83=81=E3=83=A3=E3=83=83=E3=83=88?=
=?UTF-8?q?=E3=82=92=E9=80=9A=E3=81=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/client/src/containers/AuthModalContainer.tsx | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/application/client/src/containers/AuthModalContainer.tsx b/application/client/src/containers/AuthModalContainer.tsx
index 8d159f3528..3d466c4566 100644
--- a/application/client/src/containers/AuthModalContainer.tsx
+++ b/application/client/src/containers/AuthModalContainer.tsx
@@ -43,8 +43,10 @@ export const AuthModalContainer = ({ id, onUpdateActiveUser }: Props) => {
const element = ref.current;
const handleToggle = () => {
- // モーダル開閉時にkeyを更新することでフォームの状態をリセットする
- setResetKey((key) => key + 1);
+ // ダイアログが閉じた時だけフォームをリセット(開いた時はリセットしない)
+ if (!element.open) {
+ setResetKey((key) => key + 1);
+ }
};
element.addEventListener("toggle", handleToggle);
return () => {
From fafeede244566534adc27ff0c8da21a3810dd5c0 Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Sat, 21 Mar 2026 15:35:47 +0900
Subject: [PATCH 09/11] =?UTF-8?q?=E3=83=91=E3=82=B9=E3=83=AF=E3=83=BC?=
=?UTF-8?q?=E3=83=89=E3=81=A7=E3=82=82=20ReDos=20=E3=82=92=E7=99=BA?=
=?UTF-8?q?=E8=A6=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/client/src/auth/validation.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/application/client/src/auth/validation.ts b/application/client/src/auth/validation.ts
index 2a83bbfb15..12425260af 100644
--- a/application/client/src/auth/validation.ts
+++ b/application/client/src/auth/validation.ts
@@ -13,7 +13,7 @@ export const validate = (values: AuthFormData): FormErrors => {
errors.name = "名前を入力してください";
}
- if (/^(?:[^\P{Letter}&&\P{Number}]*){16,}$/v.test(normalizedPassword)) {
+ if (/^[\p{Letter}\p{Number}]+$/v.test(normalizedPassword)) {
errors.password = "パスワードには記号を含める必要があります";
}
if (normalizedPassword.length === 0) {
From faea7e04185bcdc6f65688fa096583bd6e33d376 Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Sat, 21 Mar 2026 17:18:34 +0900
Subject: [PATCH 10/11] =?UTF-8?q?pnpm-lock=20=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/pnpm-lock.yaml | 295 +++++++++++++++++++++++++++++++++++++
1 file changed, 295 insertions(+)
diff --git a/application/pnpm-lock.yaml b/application/pnpm-lock.yaml
index 1572002b24..6e721a40f8 100644
--- a/application/pnpm-lock.yaml
+++ b/application/pnpm-lock.yaml
@@ -304,6 +304,9 @@ importers:
serve-static:
specifier: 2.2.0
version: 2.2.0
+ sharp:
+ specifier: ^0.34.5
+ version: 0.34.5
sqlite3:
specifier: 5.1.7
version: 5.1.7
@@ -1197,6 +1200,9 @@ packages:
peerDependencies:
react: '19'
+ '@emnapi/runtime@1.9.1':
+ resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==}
+
'@esbuild/aix-ppc64@0.25.11':
resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==}
engines: {node: '>=18'}
@@ -1375,6 +1381,159 @@ packages:
'@imagemagick/magick-wasm@0.0.37':
resolution: {integrity: sha512-tVs9hcWu9u7I3Jz/XvUYVvCEniuxAR+JjZEzI+yKtQmYAtNsLF1WjoH1HZGCKPumaB9jAHZlcf2RGT9+1l3nxQ==}
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
'@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
@@ -4252,6 +4411,10 @@ packages:
resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==}
engines: {node: '>=8'}
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -5787,6 +5950,11 @@ snapshots:
'@babel/runtime': 7.28.4
react: 19.2.0
+ '@emnapi/runtime@1.9.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
'@esbuild/aix-ppc64@0.25.11':
optional: true
@@ -5880,6 +6048,102 @@ snapshots:
'@imagemagick/magick-wasm@0.0.37': {}
+ '@img/colour@1.1.0': {}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.9.1
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
'@jridgewell/gen-mapping@0.3.13':
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -9238,6 +9502,37 @@ snapshots:
dependencies:
kind-of: 6.0.3
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.7.3
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
From ba5421f5084638727285933e760626fe0f903cec Mon Sep 17 00:00:00 2001
From: kitsne241 <169665926+kitsne241@users.noreply.github.com>
Date: Sat, 21 Mar 2026 18:29:19 +0900
Subject: [PATCH 11/11] =?UTF-8?q?=E6=9C=80=E7=B5=82=E6=8F=90=E5=87=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/containers/AuthModalContainer.tsx | 6 +-----
application/server/src/app.ts | 4 ++++
application/server/src/routes/api/auth.ts | 8 +++++++-
scoring-tool/signin-failure.png | Bin 0 -> 106120 bytes
.../scoring/calculate_user_auth_flow_action.ts | 8 ++++++++
5 files changed, 20 insertions(+), 6 deletions(-)
create mode 100644 scoring-tool/signin-failure.png
diff --git a/application/client/src/containers/AuthModalContainer.tsx b/application/client/src/containers/AuthModalContainer.tsx
index 3d466c4566..5cdddb699e 100644
--- a/application/client/src/containers/AuthModalContainer.tsx
+++ b/application/client/src/containers/AuthModalContainer.tsx
@@ -81,11 +81,7 @@ export const AuthModalContainer = ({ id, onUpdateActiveUser }: Props) => {
return (
-
+
);
};
diff --git a/application/server/src/app.ts b/application/server/src/app.ts
index 671fb424cc..7244eb0dc4 100644
--- a/application/server/src/app.ts
+++ b/application/server/src/app.ts
@@ -21,5 +21,9 @@ app.use((_req, res, next) => {
return next();
});
+app.use((req, _res, next) => {
+ console.log(`[req] ${req.method} ${req.url} content-type=${req.headers["content-type"]} content-encoding=${req.headers["content-encoding"]}`);
+ next();
+});
app.use("/api/v1", apiRouter);
app.use(staticRouter);
diff --git a/application/server/src/routes/api/auth.ts b/application/server/src/routes/api/auth.ts
index f313e87bbb..0a0c5f3a66 100644
--- a/application/server/src/routes/api/auth.ts
+++ b/application/server/src/routes/api/auth.ts
@@ -25,20 +25,26 @@ authRouter.post("/signup", async (req, res) => {
});
authRouter.post("/signin", async (req, res) => {
+ console.log("[signin] body:", req.body);
const user = await User.findOne({
where: {
username: req.body.username,
},
});
+ console.log("[signin] user found:", user?.username ?? null);
if (user === null) {
+ console.log("[signin] user not found");
throw new httpErrors.BadRequest();
}
- if (!user.validPassword(req.body.password)) {
+ const valid = user.validPassword(req.body.password);
+ console.log("[signin] password valid:", valid);
+ if (!valid) {
throw new httpErrors.BadRequest();
}
req.session.userId = user.id;
+ console.log("[signin] success");
return res.status(200).type("application/json").send(user);
});
diff --git a/scoring-tool/signin-failure.png b/scoring-tool/signin-failure.png
new file mode 100644
index 0000000000000000000000000000000000000000..4bb9866eea7d1058d83cc3d8cb4de1b4d19a5d78
GIT binary patch
literal 106120
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