Dependencies current: npm audit 0 (was 7, six of them high)

nodemailer and basic-ftp are only fixed in their next major, so this
takes both, along with argon2 0.45, ssh2-sftp-client 12, archiver 8,
@astrojs/react 7 and the minor bumps.

- archiver 8 has no default export any more, only `ZipArchive`. Our own
  `src/types/archiver.d.ts` still declared the old default, so `tsc` would
  have stayed green while every ZIP download threw at runtime. The local
  declaration is gone; `@types/archiver` 8 matches the real API now.
- nodemailer 10 ships its own types; `@types/nodemailer` is gone.
- Existing argon2 hashes still verify (hash made with 0.41, verified
  with 0.45).
- basic-ftp 6 no longer silently redirects the data connection when an
  FTP server behind NAT announces its private address. That is the
  library's deliberate secure default. If a delivery target that worked
  before fails now, press "Test connection" — the error names the cause.
- `baseUrl` is out of tsconfig.json (TypeScript 7 removed it; the `@/`
  alias was never used).
- engines: Node >= 22.12, which pg-boss and @astrojs/react now require.

Deliberately not taken: pg-boss 12 cannot migrate the v10 queue schema
in place, and TypeScript 7 is a toolchain switch with no security gain.
Both get their own change.
This commit is contained in:
till committed 2026-10-10 06:15:06 +00:00
1 parent dd8061d838
commit ec987dfc82
6 files changed
+838 -1750

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
import type { APIRoute } from 'astro';
import { buildSelectionZipName } from '../../../lib/naming';
import archiver from 'archiver';
import { ZipArchive } from 'archiver';
import { query } from '../../../lib/db';
import { getObject } from '../../../lib/storage';
@@ -17,7 +17,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
`SELECT id, result_path, filename FROM items WHERE id = ANY($1) AND result_path IS NOT NULL`, [ids]);
if (!rows.length) return new Response('No results.', { status: 404 });
const archive = archiver('zip', { zlib: { level: 6 } });
const archive = new ZipArchive({ zlib: { level: 6 } });
const seen: Record<string, number> = {};
for (const r of rows) {
try {
+2 -2
View File
@@ -1,5 +1,5 @@
import type { APIRoute } from 'astro';
import archiver from 'archiver';
import { ZipArchive } from 'archiver';
import { Readable } from 'node:stream';
import { once } from 'node:events';
import { query } from '../../../../lib/db';
@@ -66,7 +66,7 @@ export const GET: APIRoute = async ({ params, request, clientAddress }) => {
[images.map((b) => b.id)]);
const byId = new Map(paths.map((p) => [p.id, p]));
const archive = archiver('zip', { zlib: { level: 6 } });
const archive = new ZipArchive({ zlib: { level: 6 } });
// Errors must not take the process with them; the stream then breaks off.
archive.on('error', (e: any) => console.error('[share/zip]', e?.message || e));
archive.on('warning', (e: any) => console.error('[share/zip] warning:', e?.message || e));