mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
Merge remote-tracking branch 'origin/release/v1.46.0' into fix/v146-sec-review
This commit is contained in:
commit
722c6d1db5
15 files changed
+367
-245
No files matched your search
@@ -60,7 +60,7 @@ jobs:
|
||||
# minutes and can produce nothing actionable, because nobody edits
|
||||
# it and the fix for anything found there is `pnpm prisma generate`.
|
||||
- name: Initialise CodeQL
|
||||
uses: github/codeql-action/init@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
|
||||
with:
|
||||
languages: javascript-typescript
|
||||
build-mode: none
|
||||
@@ -75,6 +75,6 @@ jobs:
|
||||
- public
|
||||
|
||||
- name: Analyse
|
||||
uses: github/codeql-action/analyze@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
|
||||
with:
|
||||
category: "/language:javascript-typescript"
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
publish_results: true
|
||||
|
||||
- name: Upload results
|
||||
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
|
||||
with:
|
||||
sarif_file: scorecard-results.sarif
|
||||
category: scorecard
|
||||
@@ -88,7 +88,7 @@ jobs:
|
||||
skip-dirs: src/generated
|
||||
|
||||
- name: Upload results
|
||||
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
|
||||
with:
|
||||
sarif_file: trivy-filesystem.sarif
|
||||
category: trivy-filesystem
|
||||
@@ -145,7 +145,7 @@ jobs:
|
||||
exit-code: "0"
|
||||
|
||||
- name: Upload results
|
||||
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
|
||||
with:
|
||||
sarif_file: trivy-published-image.sarif
|
||||
category: trivy-published-image
|
||||
|
||||
@@ -87,7 +87,7 @@ curl -s http://localhost:3000/api/version # returns version + buildSha + built
|
||||
|
||||
`SESSION_COOKIE_SECURE=false` is the one setting plain-HTTP self-hosts must set: without it the session cookie carries the `Secure` flag, the browser drops it over HTTP, and login silently fails. Leave it unset (or `true`) only when a TLS reverse proxy serves HTTPS — and then set `NEXT_PUBLIC_APP_URL` and `APP_URL` to the public URL first (see the [self-hosting guide](https://docs.healthlog.dev/getting-started/self-host-in-10-minutes/)).
|
||||
|
||||
Persistent state lives in exactly one named volume (`postgres-data`, the Postgres data); the app container is stateless, so backing up the database backs up everything. An install from v1.45 or earlier moves its Postgres 16 database into it on the first start ([details](docs/ops/postgres-major-upgrade.md)).
|
||||
Persistent state lives in the database volume (`postgres-data`) and in `backups`, which holds the nightly database dumps; the app container is stateless. An install from v1.45 or earlier moves its Postgres 16 database from `pgdata` into the new volume on the first start ([details](docs/ops/postgres-major-upgrade.md)); recovering a lost server is in [disaster-recovery.md](docs/ops/disaster-recovery.md).
|
||||
|
||||
NAS and homelab users have ready-made paths: [Unraid Community Applications](docs/self-hosting/unraid.md), [Portainer app templates](docs/self-hosting/portainer/README.md) and [TrueNAS](docs/self-hosting/truenas.md) (the Community train app is pending catalog review).
|
||||
|
||||
|
||||
+33
-4
@@ -695,6 +695,10 @@ services:
|
||||
#
|
||||
# On every start it decides in a second and exits:
|
||||
# - no `pgdata` data (a new install): nothing to do;
|
||||
# - the database service runs Postgres 16 (after going back): nothing to
|
||||
# do, the live 16 volume is left alone;
|
||||
# - 16 was used again after an earlier move: refuses, so the app does not
|
||||
# start on the move-day copy;
|
||||
# - Postgres 18 already holds the database: nothing to do;
|
||||
# - otherwise it starts Postgres 16 inside this container on the old
|
||||
# volume, streams a dump into the new database in one transaction,
|
||||
@@ -752,14 +756,35 @@ services:
|
||||
log "no Postgres 16 database to move, nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
# The database service must be the new major. After going back to 16 the
|
||||
# service runs on this very volume: touching it then would wipe the live data.
|
||||
i=0
|
||||
until NEWVER=$$(new "SHOW server_version_num" 2>/dev/null); do
|
||||
i=$$((i + 1))
|
||||
[ "$$i" -lt 60 ] || { log "the database service did not answer for a minute"; exit 1; }
|
||||
sleep 1
|
||||
done
|
||||
if [ "$$NEWVER" -lt 180000 ]; then
|
||||
log "the database service runs Postgres $$((NEWVER / 10000)), not 18: nothing to move, the old volume is left alone"
|
||||
exit 0
|
||||
fi
|
||||
checkpoint() { pg_controldata "$$OLD" | awk -F': *' '/^Latest checkpoint location/ { print $$2 }'; }
|
||||
USER_TABLES="FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema')"
|
||||
TABLES=$$(new "SELECT count(*) $$USER_TABLES")
|
||||
if [ -e "$$MARK" ]; then
|
||||
MOVED_ON=$$(sed -n 1p "$$MARK")
|
||||
MOVED_CHECKPOINT=$$(sed -n 2p "$$MARK")
|
||||
if [ -n "$$MOVED_CHECKPOINT" ] && [ "$$(checkpoint)" != "$$MOVED_CHECKPOINT" ]; then
|
||||
log "the Postgres 16 database changed after it was moved on $$MOVED_ON: it was used again after going back to 16."
|
||||
log "Postgres 18 still holds the state of that day, so it is not started on. To move the current 16 database,"
|
||||
log "see docs/ops/postgres-major-upgrade.md, \"Updating again after going back\"."
|
||||
exit 1
|
||||
fi
|
||||
if [ "$$TABLES" != 0 ]; then
|
||||
log "the Postgres 16 database was moved on $$(cat "$$MARK"), nothing to do"
|
||||
log "the Postgres 16 database was moved on $$MOVED_ON, nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
log "the Postgres 16 database was moved on $$(cat "$$MARK"), but the Postgres 18 database is empty now."
|
||||
log "the Postgres 16 database was moved on $$MOVED_ON, but the Postgres 18 database is empty now."
|
||||
log "Not importing the old state again by itself. See docs/ops/postgres-major-upgrade.md, \"Starting over\"."
|
||||
exit 1
|
||||
fi
|
||||
@@ -778,8 +803,9 @@ services:
|
||||
fi
|
||||
NEED=$$(du -sk "$$OLD" | cut -f1)
|
||||
FREE=$$(df -Pk /var/lib/postgresql/next | awk 'NR == 2 { print $$4 }')
|
||||
if [ "$$FREE" -le "$$NEED" ]; then
|
||||
log "the move needs about $$((NEED / 1024)) MiB free for the new database, the disk has $$((FREE / 1024)) MiB."
|
||||
# Room for the copy, and for the dump the app takes before its first migration.
|
||||
if [ "$$FREE" -le $$((NEED * 3 / 2)) ]; then
|
||||
log "the move needs about $$((NEED * 3 / 2 / 1024)) MiB free for the new database and its first dump, the disk has $$((FREE / 1024)) MiB."
|
||||
log "Nothing was changed. Free some space and start the stack again."
|
||||
exit 1
|
||||
fi
|
||||
@@ -813,6 +839,9 @@ services:
|
||||
vacuumdb -h db -U healthlog -d healthlog --analyze-in-stages --quiet
|
||||
kill -INT "$$PID"
|
||||
wait "$$PID" || true
|
||||
# The marker keeps the old database's last checkpoint: a later start can tell
|
||||
# whether 16 was used again after the move.
|
||||
{ date -u +%Y-%m-%dT%H:%M:%SZ; checkpoint; } > "$$MOVING"
|
||||
mv "$$MOVING" "$$MARK"
|
||||
log "done. The old volume stays as it was, as a way back; see docs/ops/postgres-major-upgrade.md"
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@ Postgres 18 database is up and before the app, and it exits in a second when
|
||||
there is nothing to move. When the old `pgdata` volume holds a Postgres 16
|
||||
database and the new one is empty, it:
|
||||
|
||||
1. checks there is room on the disk for a second copy;
|
||||
1. checks that the database service runs Postgres 18, and that there is room
|
||||
on the disk for a second copy and for the dump the app takes before its
|
||||
first migration;
|
||||
2. starts Postgres 16 inside its own container on the old volume, reachable
|
||||
only from inside that container;
|
||||
3. streams a dump into Postgres 18 in a single transaction;
|
||||
@@ -34,8 +36,10 @@ If any step fails, the new database stays empty, the app does not start, and
|
||||
the log says what happened. A move cut short by a restart or a full disk is
|
||||
run again from scratch on the next `docker compose up -d`.
|
||||
|
||||
The old `pgdata` volume is read and never changed, apart from the marker
|
||||
file. That is the way back.
|
||||
The old `pgdata` volume keeps the database as it was. Postgres 16 runs on it
|
||||
during the move, so it writes a checkpoint there (and recovers first after an
|
||||
unclean stop), and the marker file is added; no data in it changes. That is
|
||||
the way back.
|
||||
|
||||
## Going back
|
||||
|
||||
@@ -55,6 +59,29 @@ HEALTHLOG_IMAGE_REF=:v1.45.0 docker compose up -d
|
||||
```
|
||||
|
||||
Anything written after the move lives only in the Postgres 18 volume.
|
||||
`db-upgrade` can stay in the file: it sees that the database service runs
|
||||
Postgres 16 and leaves that volume alone. This also holds after a move that
|
||||
stopped half-way.
|
||||
|
||||
## Updating again after going back
|
||||
|
||||
If you used Postgres 16 again after going back, the Postgres 18 volume holds
|
||||
the state of the day of the move, not what you wrote since. `db-upgrade`
|
||||
notices that the old database changed after the move and refuses to start on
|
||||
the old copy. To move the current 16 database, remove the old copy and the
|
||||
marker, then start again:
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
docker volume rm <project>_postgres-data
|
||||
docker compose run --rm --entrypoint rm db-upgrade \
|
||||
/var/lib/postgresql/data/HEALTHLOG_MOVED_TO_POSTGRES_18
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
`docker volume ls` shows the volume's full name. Removing it deletes what was
|
||||
written on Postgres 18 before you went back; take a dump of it first if any
|
||||
of that matters.
|
||||
|
||||
## Afterwards
|
||||
|
||||
|
||||
@@ -434,7 +434,9 @@ Keep the dump until the new version has run for a few days, and keep your
|
||||
encryption key with it: a dump without the key cannot be read.
|
||||
|
||||
The database image is a separate matter: a new Postgres minor is a change of
|
||||
the `image:` line, a new major (16 to 18) is a dump and restore, described in
|
||||
the `image:` line. The move from 16 to 18 runs by itself on the first start
|
||||
of the compose file from v1.46; a database you run yourself moves by dump
|
||||
and restore. Both are in
|
||||
[`docs/ops/postgres-major-upgrade.md`](../ops/postgres-major-upgrade.md).
|
||||
|
||||
The start log says what is about to happen before the migrations run:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"type": 3,
|
||||
"title": "HealthLog",
|
||||
"name": "healthlog",
|
||||
"description": "Self-hosted personal health tracker (PWA + native iOS client): weight, blood pressure, pulse, blood glucose, body composition, sleep, mood, menstrual cycle, and medications on one encrypted timeline. AES-256-GCM at rest, no vendor cloud, no telemetry. Ships app + PostgreSQL 16 as one stack.",
|
||||
"description": "Self-hosted personal health tracker (PWA + native iOS client): weight, blood pressure, pulse, blood glucose, body composition, sleep, mood, menstrual cycle, and medications on one encrypted timeline. AES-256-GCM at rest, no vendor cloud, no telemetry. Ships app + PostgreSQL 18 as one stack.",
|
||||
"note": "Generate each secret with: openssl rand -hex 32 (a 64-char hex string). For plain-HTTP / LAN access set SESSION_COOKIE_SECURE to false, or login fails. Set NEXT_PUBLIC_APP_URL and APP_URL to how you reach the app. Full guide: https://github.com/MBombeck/HealthLog/blob/main/docs/self-hosting/getting-started.md",
|
||||
"categories": ["Tools", "Other"],
|
||||
"platform": "linux",
|
||||
@@ -33,7 +33,7 @@
|
||||
{
|
||||
"name": "HEALTHLOG_PLATFORM",
|
||||
"label": "Platform hint",
|
||||
"description": "Opens the admin's encryption key backup step on the Portainer instructions.",
|
||||
"description": "Opens the admin's recovery kit on the Portainer instructions.",
|
||||
"default": "portainer"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -95,19 +95,31 @@ different things depending on which button you press.
|
||||
two actions below, the row stays. A start that was folded into a later
|
||||
cycle stays for as long as that cycle does, because deleting the later
|
||||
cycle gives it back.
|
||||
- **Settings → Advanced → Delete all data** removes the rows outright, tombstones
|
||||
- **Settings → Advanced → Delete all data** removes the rows, tombstones
|
||||
included. Everything the account owns goes except what you sign in
|
||||
with; the confirmation dialog lists it.
|
||||
- **Deleting the account** removes the account row, and the database
|
||||
cascades every record with it.
|
||||
with; the confirmation dialog lists it. Before it does, it keeps a copy
|
||||
of the account on the server for the deletion grace window (14 days by
|
||||
default), so a mistaken wipe can be restored; the copy is erased when
|
||||
the window ends.
|
||||
- **Deleting the account** locks it at once and erases it, with every
|
||||
record, when the grace window ends. Until then an admin can undo it.
|
||||
|
||||
Two consequences follow, and they matter for the seizure threat model
|
||||
`ACCOUNT_DELETION_GRACE_DAYS=0` makes both immediate again, without the
|
||||
copy and without an undo.
|
||||
|
||||
Three consequences follow, and they matter for the seizure threat model
|
||||
above. A host imaged while a per-entry deletion is the only deletion you
|
||||
have performed still holds that entry. And a backup taken before any of
|
||||
these actions still holds whatever it captured, because a backup is a
|
||||
copy of a moment. If your reason for deleting is that the data must not
|
||||
be recoverable from the machine, use one of the two whole-record actions
|
||||
and rotate your backups.
|
||||
have performed still holds that entry; so does a host imaged inside the
|
||||
grace window. A backup taken before any of these actions still holds
|
||||
whatever it captured, because a backup is a copy of a moment: the nightly
|
||||
database dumps keep a deleted record until they age out (`DB_BACKUP_KEEP`
|
||||
nights on the server, and your bucket's lifecycle rule for `database/`).
|
||||
And after the move to Postgres 18 the old `pgdata` volume is a full copy
|
||||
of the database from that day until you remove it. If your reason for
|
||||
deleting is that the data must not be recoverable from the machine, set
|
||||
the grace window to 0 or wait it out, remove the old volume, and let the
|
||||
dumps age out or delete them
|
||||
([backup-restore.md](../ops/backup-restore.md)).
|
||||
|
||||
## Practical hardening
|
||||
|
||||
|
||||
@@ -46,14 +46,14 @@
|
||||
|
||||
<Config Name="WebUI Port" Target="3000" Default="3000" Mode="tcp" Description="HTTP port HealthLog listens on." Type="Port" Display="always" Required="true" Mask="false">3000</Config>
|
||||
|
||||
<Config Name="DATABASE_URL" Target="DATABASE_URL" Default="postgresql://healthlog:CHANGE-ME@POSTGRES-HOST:5432/healthlog?schema=public" Mode="" Description="Connection string for your separately-installed PostgreSQL 16. Replace CHANGE-ME with the DB password and POSTGRES-HOST with the Postgres container IP or name." Type="Variable" Display="always" Required="true" Mask="true"/>
|
||||
<Config Name="DATABASE_URL" Target="DATABASE_URL" Default="postgresql://healthlog:CHANGE-ME@POSTGRES-HOST:5432/healthlog?schema=public" Mode="" Description="Connection string for your separately-installed PostgreSQL (18, or 16). Replace CHANGE-ME with the DB password and POSTGRES-HOST with the Postgres container IP or name." Type="Variable" Display="always" Required="true" Mask="true"/>
|
||||
|
||||
<Config Name="ENCRYPTION_KEY" Target="ENCRYPTION_KEY" Default="" Mode="" Description="AES-256-GCM key for data at rest. Generate with: openssl rand -hex 32 (64-char hex). Back this up — losing it makes encrypted data unrecoverable." Type="Variable" Display="always" Required="true" Mask="true"/>
|
||||
|
||||
<Config Name="API_TOKEN_HMAC_KEY" Target="API_TOKEN_HMAC_KEY" Default="" Mode="" Description="HMAC key for API token hashing. Generate with: openssl rand -hex 32 (64-char hex)." Type="Variable" Display="always" Required="true" Mask="true"/>
|
||||
|
||||
<Config Name="SESSION_COOKIE_SECURE" Target="SESSION_COOKIE_SECURE" Default="false" Mode="" Description="Set to false for LAN / plain-HTTP installs (http://tower:3000) or login fails. Set to true only behind an HTTPS reverse proxy." Type="Variable" Display="always" Required="true" Mask="false">false</Config>
|
||||
<Config Name="HEALTHLOG_PLATFORM" Target="HEALTHLOG_PLATFORM" Default="unraid" Mode="" Description="Where this server is configured. Opens the admin's encryption key backup step on the Unraid instructions." Type="Variable" Display="advanced" Required="false" Mask="false">unraid</Config>
|
||||
<Config Name="HEALTHLOG_PLATFORM" Target="HEALTHLOG_PLATFORM" Default="unraid" Mode="" Description="Where this server is configured. Opens the admin's recovery kit on the Unraid instructions." Type="Variable" Display="advanced" Required="false" Mask="false">unraid</Config>
|
||||
<Config Name="ENCRYPTION_KEY_CHECK" Target="ENCRYPTION_KEY_CHECK" Default="enforce" Mode="" Description="Start-up encryption key check. enforce refuses to serve when the key does not open the stored data. warn only logs it: a last resort for a refusal you are certain is false, and it disables a safety check." Type="Variable" Display="advanced" Required="false" Mask="false">enforce</Config>
|
||||
|
||||
<Config Name="NEXT_PUBLIC_APP_URL" Target="NEXT_PUBLIC_APP_URL" Default="http://tower:3000" Mode="" Description="Public URL users reach HealthLog at. Use the LAN URL (e.g. http://tower:3000) or your HTTPS domain behind a reverse proxy." Type="Variable" Display="always" Required="true" Mask="false"/>
|
||||
|
||||
+7
-7
@@ -54,13 +54,13 @@
|
||||
"mcp:stdio": "npx tsx src/cli/mcp-stdio.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.1153.0",
|
||||
"@aws-sdk/lib-storage": "3.1153.0",
|
||||
"@aws-sdk/client-s3": "^3.1155.0",
|
||||
"@aws-sdk/lib-storage": "3.1155.0",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@modelcontextprotocol/sdk": "^1.32.1",
|
||||
"@napi-rs/canvas": "1.0.11",
|
||||
"@napi-rs/canvas": "1.0.13",
|
||||
"@node-rs/argon2": "^2.2.2",
|
||||
"@parse/node-apn": "^8.1.0",
|
||||
"@prisma/adapter-pg": "^7.10.1",
|
||||
@@ -68,20 +68,20 @@
|
||||
"@simplewebauthn/browser": "^14.0.0",
|
||||
"@simplewebauthn/server": "^14.0.3",
|
||||
"@tanstack/react-query": "5.104.5",
|
||||
"@tanstack/react-virtual": "^3.14.21",
|
||||
"@tanstack/react-virtual": "^3.14.22",
|
||||
"@types/sax": "^1.2.7",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.4.0",
|
||||
"dotenv": "^18.0.8",
|
||||
"fflate": "^0.8.3",
|
||||
"jose": "^6.2.12",
|
||||
"jose": "^6.2.13",
|
||||
"jspdf": "^4.2.1",
|
||||
"jspdf-autotable": "^5.0.9",
|
||||
"lucide-react": "^1.59.0",
|
||||
"lucide-react": "^1.61.0",
|
||||
"mmdb-lib": "^3.0.3",
|
||||
"next": "16.4.2",
|
||||
"nodemailer": "10.1.7",
|
||||
"nodemailer": "10.2.1",
|
||||
"otpauth": "^9.5.2",
|
||||
"p-limit": "^7.3.3",
|
||||
"pg": "^8.23.1",
|
||||
|
||||
Generated
+205
-205
@@ -45,11 +45,11 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3':
|
||||
specifier: ^3.1153.0
|
||||
version: 3.1153.0
|
||||
specifier: ^3.1155.0
|
||||
version: 3.1155.0
|
||||
'@aws-sdk/lib-storage':
|
||||
specifier: 3.1153.0
|
||||
version: 3.1153.0(@aws-sdk/client-s3@3.1153.0)
|
||||
specifier: 3.1155.0
|
||||
version: 3.1155.0(@aws-sdk/client-s3@3.1155.0)
|
||||
'@dnd-kit/core':
|
||||
specifier: ^6.3.1
|
||||
version: 6.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||
@@ -63,8 +63,8 @@ importers:
|
||||
specifier: ^1.32.1
|
||||
version: 1.32.1(@cfworker/json-schema@4.1.1)(supports-color@7.2.0)(zod@4.6.7)
|
||||
'@napi-rs/canvas':
|
||||
specifier: 1.0.11
|
||||
version: 1.0.11
|
||||
specifier: 1.0.13
|
||||
version: 1.0.13
|
||||
'@node-rs/argon2':
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
@@ -87,8 +87,8 @@ importers:
|
||||
specifier: 5.104.5
|
||||
version: 5.104.5(@types/react@19.3.0)(react@19.3.1)
|
||||
'@tanstack/react-virtual':
|
||||
specifier: ^3.14.21
|
||||
version: 3.14.21(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||
specifier: ^3.14.22
|
||||
version: 3.14.22(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||
'@types/sax':
|
||||
specifier: ^1.2.7
|
||||
version: 1.2.7
|
||||
@@ -108,8 +108,8 @@ importers:
|
||||
specifier: ^0.8.3
|
||||
version: 0.8.3
|
||||
jose:
|
||||
specifier: ^6.2.12
|
||||
version: 6.2.12
|
||||
specifier: ^6.2.13
|
||||
version: 6.2.13
|
||||
jspdf:
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1
|
||||
@@ -117,8 +117,8 @@ importers:
|
||||
specifier: ^5.0.9
|
||||
version: 5.0.9(jspdf@4.2.1)
|
||||
lucide-react:
|
||||
specifier: ^1.59.0
|
||||
version: 1.59.0(@types/react@19.3.0)(react@19.3.1)
|
||||
specifier: ^1.61.0
|
||||
version: 1.61.0(@types/react@19.3.0)(react@19.3.1)
|
||||
mmdb-lib:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
@@ -126,8 +126,8 @@ importers:
|
||||
specifier: 16.4.2
|
||||
version: 16.4.2(@babel/core@7.29.7(supports-color@7.2.0))(@opentelemetry/api@1.9.1)(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||
nodemailer:
|
||||
specifier: 10.1.7
|
||||
version: 10.1.7
|
||||
specifier: 10.2.1
|
||||
version: 10.2.1
|
||||
otpauth:
|
||||
specifier: ^9.5.2
|
||||
version: 9.5.2
|
||||
@@ -301,74 +301,74 @@ packages:
|
||||
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
'@aws-sdk/checksums@3.1001.4':
|
||||
resolution: {integrity: sha512-H8BiG/2DnfwydVxD1uDPLa1s1sfhRnVTbD2OwzfTr3WlJzgbIzICDXxBTlTMjbWNNCe4VS9X55fco+JI34L9kw==}
|
||||
'@aws-sdk/checksums@3.1001.5':
|
||||
resolution: {integrity: sha512-6erto9nK2OZO/woEgmFIaPh5gChgdNd7nL6jgAf8TAXz3/QHC8Pan2TFe9GYp3IxOIKCCGWPylSjtOHKfNzQlw==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/client-s3@3.1153.0':
|
||||
resolution: {integrity: sha512-h0VScQZPfBApg1Qi4AedsOUSMZ7m758kZIg0JO0B5HtwSzQhB7Tgh6h1JoGEXELgrWADPusYMpMBDmrRAEx2yw==}
|
||||
'@aws-sdk/client-s3@3.1155.0':
|
||||
resolution: {integrity: sha512-l3uMeIlzWVgj/RTJTh5sKYKtQz1la3cvWLUPn1cwFH4UZpcqTH66SgJHCeB2FOE9bEAjOdbmCyPKt9aw867Fng==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/core@3.978.4':
|
||||
resolution: {integrity: sha512-JvGp6y9sPX8FSs2K/EmFMZcUfdkHxqGE45+oxwGC75OIh50j2e4cbx7zcR3BwNs2DSGqJdBja5h6Vy89iIDmRQ==}
|
||||
'@aws-sdk/core@3.978.5':
|
||||
resolution: {integrity: sha512-ruI0AWqcrfL20XDS6SwZIJFPOBZ6N0ADa9nLzWlBhxk1aoUjbUX3JkTR9vEmk7o35XpAHi68ahZ4T6RE2U9XyA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-env@3.972.75':
|
||||
resolution: {integrity: sha512-nc8Epg98PcYoKNx0VFlwtmZSCP+tuJ1FLWqpslET/gp4h/WYuULSJqtxppM6ywKKDdzNJPvLD7ceRfmxm3Qdxw==}
|
||||
'@aws-sdk/credential-provider-env@3.972.76':
|
||||
resolution: {integrity: sha512-YxmL1Ar7bV9ZkJvtv+lj+MF6le76NnZnbmgySyZuxpZaCv0/1lZ3KxKy6RIj1h9ui2hWnVjZxbmTMeO0y/NrQA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-http@3.972.77':
|
||||
resolution: {integrity: sha512-KkYFdIQwuw9IOHfEzK78slxmVWuhcm1w6YgE3V3WVxAeRRj9q5J9jlwzpY/oszWxd4SD96FTFkDdRGBdMFF2Mw==}
|
||||
'@aws-sdk/credential-provider-http@3.972.78':
|
||||
resolution: {integrity: sha512-3VHknDRngoebsaqyT1iR75b5cBT2zfEtODK6yYmYltljkK1HEAQLs2FEd1IpWqAeOYdMGaG9wikngWLTufY7RA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-ini@3.973.20':
|
||||
resolution: {integrity: sha512-OSl2R/0zLkoeKEIy6oP2tu/bsSdY+DGgro2eOffMD2CcP8POv7rS14FY5Jzc5bjnqB1G9wv/aM1akHC2mdlhZw==}
|
||||
'@aws-sdk/credential-provider-ini@3.973.21':
|
||||
resolution: {integrity: sha512-aLx9hbCX6mGAyv4ZZd8UagJ4RASHVJw6BFDSIyuKmLkqNL6H47EjBPK6qaJ4B5TDV6mc+vMa0SJFYyo4mkvVQg==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-login@3.972.82':
|
||||
resolution: {integrity: sha512-8jyDPtf1WPxeQ/5xlNpyxAD6P7YKwkYeNk8B2vFEDwkPWDvb7c3tQJG5/jbNWbF2yTMIH9tDTueBkdfovYIAPw==}
|
||||
'@aws-sdk/credential-provider-login@3.972.83':
|
||||
resolution: {integrity: sha512-9bJU6FjRacF4FK/QHf8Dyxhur7B1grRj8C1Yh4IkpoFW2exQflPdCv0VrbemLW9ZctLNle+AE7TETs9KNvuLYg==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-node@3.972.87':
|
||||
resolution: {integrity: sha512-TKj2C0x4IMPSSOAlmeryX8fCPvvPS2pFJz2ikV9IGqyh6Ehsg4leMalCTVfV2rvMTrlGAe7X7nK0HZ3P0KZR9g==}
|
||||
'@aws-sdk/credential-provider-node@3.972.88':
|
||||
resolution: {integrity: sha512-AG0KID5qhQPzrFkh5b0Cws1Amytvzo0L0Xj6hMgJXEwD6ZXAqninDhSNAWJiN5zU4YVVZnuidnqwPwYJ04IamA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-process@3.972.75':
|
||||
resolution: {integrity: sha512-ZNm8T/HJNhpS8MikDVAsym8QyUSUuOUGiCkmI3TTya7G6xhOgfRLd2iK91HhQQyvRM36eo6Xm845hHVyfToA2w==}
|
||||
'@aws-sdk/credential-provider-process@3.972.76':
|
||||
resolution: {integrity: sha512-pdhKFTXv1zPYhh92MTlp0jVbLWvUEV9v+rziuEkoskGGQ2iJskxHTO38nA8UAbT/N4IM3n8OZJ9rIY5IBO15/A==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-sso@3.973.19':
|
||||
resolution: {integrity: sha512-qHGDAGesyWtRw3BapyFkYSUzVNrC1CWPS6+S2lf/MLMEkWB2gR3Bl6imVHy1nhImXKS+gcuUDzbu39BnsHJc1Q==}
|
||||
'@aws-sdk/credential-provider-sso@3.973.20':
|
||||
resolution: {integrity: sha512-DlxrAB3MnjNLx/da7b89W+3DyJQYso/q7Ns15MsST2IV2nkAYQOYTUCaffNSjgrpMP99Dm2mV2jxzcbyF94ZfA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/credential-provider-web-identity@3.972.81':
|
||||
resolution: {integrity: sha512-nHkgkMIC6NHgqfI6UAQq5cCS4bUkNxkT+r9fXCq/X4IKfX/DHGZ8UM3T4b78OXpWK5OlzEzN4kxwyax0W/MUCA==}
|
||||
'@aws-sdk/credential-provider-web-identity@3.972.82':
|
||||
resolution: {integrity: sha512-LUo46IqPTJ4xKBsrLuoaxiv/D2GTBCcFDMD1y3jKIqPR/p7Rw14RJFZ0iRWftqZtyLPQX9JMGnSi3mBu4y/pNA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/lib-storage@3.1153.0':
|
||||
resolution: {integrity: sha512-zshL4tYVwTXfEOQ0iqNsXUPq/0aoZwOHrAsqlBmGcAij1+8qc79rm9LpzBuEV7KWiSMetZ+89n7mSYgcJKFgyA==}
|
||||
'@aws-sdk/lib-storage@3.1155.0':
|
||||
resolution: {integrity: sha512-ThvepKZILBOGCO1rsRsuAWps6hwfMfFVVhRpNrxup+o0q/Hyi50IaDSGZYxrZMPbWH/8pG2LFld//OYDmyr48A==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
peerDependencies:
|
||||
'@aws-sdk/client-s3': ^3.1153.0
|
||||
'@aws-sdk/client-s3': ^3.1155.0
|
||||
|
||||
'@aws-sdk/middleware-sdk-s3@3.972.80':
|
||||
resolution: {integrity: sha512-zX3lXN/9XOUAuGpxgt3wXwZrXhTjQYEgRsqa856PbZWpOtleUWmCMbhlkLfusPuhW24cOC/8JYR8hnRalrrIkQ==}
|
||||
'@aws-sdk/middleware-sdk-s3@3.972.81':
|
||||
resolution: {integrity: sha512-jfanv1pV0sJFZw6/DPiNjvK7B478god0zOum5yIWo+/+1Gy+CSXWpGBWx+3nBJyDvjcu/2kUMr4ADUp9BHH34Q==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/nested-clients@3.997.49':
|
||||
resolution: {integrity: sha512-zjqIqzTYLRKhT7TPJDUreK9vG9PjhmnfLCaTaqArkRT7j+Ogl0tuXB7MpSd8rlRfRT+xTOeyNFWaOfyNcf51hg==}
|
||||
'@aws-sdk/nested-clients@3.997.50':
|
||||
resolution: {integrity: sha512-nKb8qu4QsnpZTq/6JIXc72mzuzfh7BK4sUQkpQznPec2z4W7Ob2xYkcM4i5e1yGTBnbJVeFv/0sf3jcz85hclA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/signature-v4-multi-region@3.996.48':
|
||||
resolution: {integrity: sha512-cFDXfEbXaGwbnpvR/DyqfxfjxpjXVRVthQLgkwvcfDS5u3+8G9WSj1X1Ag/pTRg/QOeOno1Tq3ycEdrKsCUcOA==}
|
||||
'@aws-sdk/signature-v4-multi-region@3.996.49':
|
||||
resolution: {integrity: sha512-nvuAZNRrRRVCiARRKsYlQ0VnXiEQiq7vXPH+UA+LSo+kN3Djl9eo/V2r0udkw85PnsNshmv2Em1clld5M3j67w==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/token-providers@3.1153.0':
|
||||
resolution: {integrity: sha512-6bKJ2OfLboxhzeJ3hBDeB8L6emCYf9DfdrjBAharLrY42J1RV/6jA6G8jvfNghzID8Yb40BdSY7jQMtWx9Ot0Q==}
|
||||
'@aws-sdk/token-providers@3.1155.0':
|
||||
resolution: {integrity: sha512-iIcQnYLhWuq9qOLQbIWFrxF3PF0svVeZvHnUS4DUnO4zUFmFHIyGyjqrntXG+e/5PUgfavV0pYfDIKHxTzN2LA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/types@3.974.6':
|
||||
resolution: {integrity: sha512-v/clNZzZnDxGyvpHMOGpJKVXFAExJzUNAAjaWGdcx8QAcXLGwTaOkw33p5SHAi0YAioK32xB3hWwOekRVfmfKg==}
|
||||
'@aws-sdk/types@3.975.0':
|
||||
resolution: {integrity: sha512-WQlhs6juByzWOzj5fwxOx0mPJaEqMcG/sDpl3Id61B3XhKE63xY+0QWcnG+sWR/sCfprmreyUo1lM7IKZmHMzw==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/xml-builder@3.972.41':
|
||||
@@ -1237,79 +1237,79 @@ packages:
|
||||
resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@napi-rs/canvas-android-arm64@1.0.11':
|
||||
resolution: {integrity: sha512-dtJS4FQEfH9OwSYLtMrEnj7T8DzBbJc/97LI/OkiWOYpW/iW5t6R/gcxVrUXS8l45gCVpwMufgucRe/pe0ISqA==}
|
||||
'@napi-rs/canvas-android-arm64@1.0.13':
|
||||
resolution: {integrity: sha512-trn7AaDzQ+yeeA0ezhkC7cB1ZDPtp4UYk0EvB5F8qtYL9jEVWtVrU30WOpI52DszoTxaTsCgf5PP4ZVaOlOIHQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@napi-rs/canvas-darwin-arm64@1.0.11':
|
||||
resolution: {integrity: sha512-J/JylWoJTG8OQqZaiqly4IODyAxNofUlZo0wtSBJtHk6AdymbdIkPynAM1JvQaZpPaG5h+msk9QuK8y4i1ooqw==}
|
||||
'@napi-rs/canvas-darwin-arm64@1.0.13':
|
||||
resolution: {integrity: sha512-6Y2djEetL8copxfNK6hg7oig/xqTwOchv19hBOm+zBNdKc/02Z3kjZN5wrLzv/l5O04/bAQS6I/AlQpwBlXgPg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@napi-rs/canvas-darwin-x64@1.0.11':
|
||||
resolution: {integrity: sha512-nlecCk3xy06eAGC7krZtzNDm9UNTHKuHQYK8ZYegdjzgSL8anGt/eLJZm86OWaNgZkwQwvDqfSmG8Nqe6MPZNQ==}
|
||||
'@napi-rs/canvas-darwin-x64@1.0.13':
|
||||
resolution: {integrity: sha512-OZoPwwu4TMMg8GTCFBrg8UFExwQTU/55i3uTC/izDat6PHE+ro9dimyQoOboFf91+NY7Pnn70ScR8f8I8+eZXw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@napi-rs/canvas-linux-arm-gnueabihf@1.0.11':
|
||||
resolution: {integrity: sha512-DKImmG+sTPolE0kGPsYPBxTtOjb3INALp32O2lW2CfSr0bAzSEKKuu+GrQbtilClyoPOahUErS3OrznFDraoWA==}
|
||||
'@napi-rs/canvas-linux-arm-gnueabihf@1.0.13':
|
||||
resolution: {integrity: sha512-dZSYaKROuswU2eUWG5aBKndNVe68elo1YX93xtRax7q658tj8rYE+HwduovWJgs6qwv1r1/CLR60nDeBbyjvyg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@napi-rs/canvas-linux-arm64-gnu@1.0.11':
|
||||
resolution: {integrity: sha512-55sykACGENj5j1rhj+81AO8JbR9HYgGjRZ7/H+pNr4VE1DvINKYNMTcutk8ZmWxk276jAQvUKJ3+Kdj9GXU3lQ==}
|
||||
'@napi-rs/canvas-linux-arm64-gnu@1.0.13':
|
||||
resolution: {integrity: sha512-W6FzYE8ADHI93In1vi80KBL6btDtAMuj50Ch5ptkWS8xuntyzbR4h5JDUmXoakxZn2yMInksudTEqVSWoFqFGg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@napi-rs/canvas-linux-arm64-musl@1.0.11':
|
||||
resolution: {integrity: sha512-6Jz6jys17yXydO+WdJgu7JhoB4K7/w9sWHByzzTmLjQghUx3TDMWvLv+UcCdnWhg4oprET67EMymnrETdeGNAg==}
|
||||
'@napi-rs/canvas-linux-arm64-musl@1.0.13':
|
||||
resolution: {integrity: sha512-+6fQ+rR49hkAa4voh2stLIwQ+4t+gmoseM8Bc53/DlMXb73IKymDPWK9A/NtWeqTW4ijWppYuyuxS2hPI8tzNA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@napi-rs/canvas-linux-riscv64-gnu@1.0.11':
|
||||
resolution: {integrity: sha512-lf2XeEebWiUYVOVEjLXxF7dfXrBBSEOBn9AqBh39VYXrPt5cDqI+1t58IFSjn8npqkg5jIOs8TQbjKABbFW1gQ==}
|
||||
'@napi-rs/canvas-linux-riscv64-gnu@1.0.13':
|
||||
resolution: {integrity: sha512-17XEMO3t9RW/TtHtSFf2AkaSWuCWdzbPeidz7zrOFawHxoLSJCnpTI1hN5aUvrZNnkNNmt/vZVJCh0ryUaik3A==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@napi-rs/canvas-linux-x64-gnu@1.0.11':
|
||||
resolution: {integrity: sha512-iDapw7nFSE5tsmQxcH2+KotJhyfVPmHd6vUOQN/Em+8WNbkZJwJ/rDowlJMFnMl0SYSDSfgKCNUGi6Sn5++Smg==}
|
||||
'@napi-rs/canvas-linux-x64-gnu@1.0.13':
|
||||
resolution: {integrity: sha512-lc48IwknVHBsNzXn9Xs5OkUsRX38Ml3Z1aOybQ51mMEzZckm8+4A0qROlyYHEoBPzr1kL3IU8ZUAqDb7wtdX8w==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@napi-rs/canvas-linux-x64-musl@1.0.11':
|
||||
resolution: {integrity: sha512-26q26AyITo3CGZX4HWFIMgBMA1lu3YN07gxzBm4tW6Hglq/OVyTP50kDrmWuKybCX6dh3m8Ly+c7YhI+sqCgCQ==}
|
||||
'@napi-rs/canvas-linux-x64-musl@1.0.13':
|
||||
resolution: {integrity: sha512-bGY1r26S2bs8UNFJcPWcCSNdCFbKep5PATsvtgtC9A5u6SRgr2/jJE/RlhHL5m9ZpixNDhVkLY/5h16Kx5V9YA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@napi-rs/canvas-win32-arm64-msvc@1.0.11':
|
||||
resolution: {integrity: sha512-cUO96IdsfvIj2S+2PNcDSkTcLhjPj8pIOEWRV1Kj70MOP4wnE9zSk7N4C1EKHlFGRcgdR5AkbnBZj0dfHK9nbQ==}
|
||||
'@napi-rs/canvas-win32-arm64-msvc@1.0.13':
|
||||
resolution: {integrity: sha512-2vRPBZoaIvJrUkDhZTE2Hn0YrnpJRCWVM3EJACoBKjuWI6WgPxGtUoRMsxRviCsyks8bKTSFdyw14CellnG2qA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@napi-rs/canvas-win32-x64-msvc@1.0.11':
|
||||
resolution: {integrity: sha512-DFYp/ZQRdKunI/LPc0UkRXG1vlNjJKOJf8O8Ctb8+wm2Nt2ELg9Eamc31D2VoakkfGo8L+z0Iejz6WtFbQwyGw==}
|
||||
'@napi-rs/canvas-win32-x64-msvc@1.0.13':
|
||||
resolution: {integrity: sha512-DUlW3lZPz63kYsf8mxgyyZuevhlH0T3/BGP9l+NazhB0F1+gL6D4hqZdnhZpw24DlWmTpATDcyYSZlJOi+DdfQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@napi-rs/canvas@1.0.11':
|
||||
resolution: {integrity: sha512-vt5tog1cr+QKadIddGe+3LrcX0EmjEd0izF717Uwf92mBmgYfq2XRmL2r4bZU40spB69exxhrBn9I91HYEr/7w==}
|
||||
'@napi-rs/canvas@1.0.13':
|
||||
resolution: {integrity: sha512-b87ugZpQ5ViwqVBkjervxpwa0GmJPsKHLBNoZN6GpjWeHzTbDUGryriq+2DYW2XbB+xCqSIINQysC0/I87nPbw==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
'@napi-rs/wasm-runtime@1.2.5':
|
||||
@@ -2792,8 +2792,8 @@ packages:
|
||||
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@smithy/core@3.36.0':
|
||||
resolution: {integrity: sha512-3hJiwG1F5t1SoXqp/yOCmYXziyx7ZVqF63S5W6YU201e/qwVaHPex+E/3vvyY9a3ORq/b+BydeNZpP2saQ9X2g==}
|
||||
'@smithy/core@3.36.2':
|
||||
resolution: {integrity: sha512-oRw0rB9QSUiCZfEs23G5F4Af+b2rQt1lItIICWu5IejFNd+uPM8SWqiKLMpQ6bX1Q7slsLbjuoE2niErFtkVPQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@smithy/credential-provider-imds@4.5.2':
|
||||
@@ -2952,14 +2952,14 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@tanstack/react-virtual@3.14.21':
|
||||
resolution: {integrity: sha512-wWE/ZJDNNDp18JHWy7n5PQooqerHePVkEEu6Op0twKQ2InF9DPhYMQptQY0syDEviMd3/r8D0OUvKJibDGm9HQ==}
|
||||
'@tanstack/react-virtual@3.14.22':
|
||||
resolution: {integrity: sha512-zNiB9IF3prySTfAUrj9tPHjD/lonBYkfxrPP4v4ITUx+qwHajJR5cY/xirjvwc+KWkur10GX3TpsbKh7JkD8Lw==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
'@tanstack/virtual-core@3.19.6':
|
||||
resolution: {integrity: sha512-CsTW892z23gy7IyxYTTorVu1uZWB+0N349rSMgKz4rFLPpLza7F7TpcCKeI5iUAwYQCt8QUlOU67J+KXCxtpGw==}
|
||||
'@tanstack/virtual-core@3.19.7':
|
||||
resolution: {integrity: sha512-gxy5SvH0mFRJ0YujtrflB/1HAu9Wn1KGvL0bjZfQkYVVMsIpQiwcf1mR06/ViN4NjllUb4HNCjqE9FGwgTvMCQ==}
|
||||
|
||||
'@tesseract.js-data/deu@1.0.0':
|
||||
resolution: {integrity: sha512-3ter1p2gFAiCd5CMC+PodZ9YY2UDomkKj+ytlKeeZqOUmhLx1SDnYPf5zog0g5MBbxYveW+8omI3PUflqHfZ4Q==}
|
||||
@@ -5040,8 +5040,8 @@ packages:
|
||||
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
|
||||
hasBin: true
|
||||
|
||||
jose@6.2.12:
|
||||
resolution: {integrity: sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==}
|
||||
jose@6.2.13:
|
||||
resolution: {integrity: sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==}
|
||||
|
||||
js-md4@0.3.2:
|
||||
resolution: {integrity: sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==}
|
||||
@@ -5420,8 +5420,8 @@ packages:
|
||||
resolution: {integrity: sha512-5J9ysMYUpYIg9RF2vJpy9SinEmSviFSe0GyPpCQ4L5QSkLAgeLXlTAOu2ZwWUU5m+0SBl6gUU1R1ZQB3aKypfA==}
|
||||
engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'}
|
||||
|
||||
lucide-react@1.59.0:
|
||||
resolution: {integrity: sha512-5qgMyyCPU6OvnKpLS2t693+ZtiqA8oaSweWoUows0BLFKFf6V75m4+CptpmohZHpD5IuOVIBXHBBiv2vpLJmtw==}
|
||||
lucide-react@1.61.0:
|
||||
resolution: {integrity: sha512-v2SQPPPNjnr+BlhL9Spuzmo5yR+hLkftfuE4E3jaxdNPgSH0hJKPcLJBP7yAta87jQNPsSERS59PJjCJ/CorBA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
@@ -5633,8 +5633,8 @@ packages:
|
||||
resolution: {integrity: sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
nodemailer@10.1.7:
|
||||
resolution: {integrity: sha512-OQa6FDln5fLttmqSbjDiRYvFDOFNrBqfiOwHPlEbURil3b+vPB1v8xpi+Sp46drzNDlsTnNsS502vthmz56r4w==}
|
||||
nodemailer@10.2.1:
|
||||
resolution: {integrity: sha512-ZrDNsPFoDMwefNs7sJwrYiEJ/CG4ClJWDZv05iNJsEBWa8GRDry1QJHTJxsuTAY9eDDKjX4k+q3SxslXJOao7w==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
non-error@0.1.0:
|
||||
@@ -7268,170 +7268,170 @@ snapshots:
|
||||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
|
||||
'@aws-sdk/checksums@3.1001.4':
|
||||
'@aws-sdk/checksums@3.1001.5':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/client-s3@3.1153.0':
|
||||
'@aws-sdk/client-s3@3.1155.0':
|
||||
dependencies:
|
||||
'@aws-sdk/checksums': 3.1001.4
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/credential-provider-node': 3.972.87
|
||||
'@aws-sdk/middleware-sdk-s3': 3.972.80
|
||||
'@aws-sdk/signature-v4-multi-region': 3.996.48
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/checksums': 3.1001.5
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/credential-provider-node': 3.972.88
|
||||
'@aws-sdk/middleware-sdk-s3': 3.972.81
|
||||
'@aws-sdk/signature-v4-multi-region': 3.996.49
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/fetch-http-handler': 5.8.0
|
||||
'@smithy/node-http-handler': 4.12.1
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/core@3.978.4':
|
||||
'@aws-sdk/core@3.978.5':
|
||||
dependencies:
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@aws-sdk/xml-builder': 3.972.41
|
||||
'@aws/lambda-invoke-store': 0.3.0
|
||||
'@smithy/core': 3.36.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/signature-v4': 5.7.4
|
||||
'@smithy/types': 4.19.0
|
||||
bowser: 2.14.1
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-env@3.972.75':
|
||||
'@aws-sdk/credential-provider-env@3.972.76':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-http@3.972.77':
|
||||
'@aws-sdk/credential-provider-http@3.972.78':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/fetch-http-handler': 5.8.0
|
||||
'@smithy/node-http-handler': 4.12.1
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-ini@3.973.20':
|
||||
'@aws-sdk/credential-provider-ini@3.973.21':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/credential-provider-env': 3.972.75
|
||||
'@aws-sdk/credential-provider-http': 3.972.77
|
||||
'@aws-sdk/credential-provider-login': 3.972.82
|
||||
'@aws-sdk/credential-provider-process': 3.972.75
|
||||
'@aws-sdk/credential-provider-sso': 3.973.19
|
||||
'@aws-sdk/credential-provider-web-identity': 3.972.81
|
||||
'@aws-sdk/nested-clients': 3.997.49
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/credential-provider-env': 3.972.76
|
||||
'@aws-sdk/credential-provider-http': 3.972.78
|
||||
'@aws-sdk/credential-provider-login': 3.972.83
|
||||
'@aws-sdk/credential-provider-process': 3.972.76
|
||||
'@aws-sdk/credential-provider-sso': 3.973.20
|
||||
'@aws-sdk/credential-provider-web-identity': 3.972.82
|
||||
'@aws-sdk/nested-clients': 3.997.50
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/credential-provider-imds': 4.5.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-login@3.972.82':
|
||||
'@aws-sdk/credential-provider-login@3.972.83':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/nested-clients': 3.997.49
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/nested-clients': 3.997.50
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-node@3.972.87':
|
||||
'@aws-sdk/credential-provider-node@3.972.88':
|
||||
dependencies:
|
||||
'@aws-sdk/credential-provider-env': 3.972.75
|
||||
'@aws-sdk/credential-provider-http': 3.972.77
|
||||
'@aws-sdk/credential-provider-ini': 3.973.20
|
||||
'@aws-sdk/credential-provider-process': 3.972.75
|
||||
'@aws-sdk/credential-provider-sso': 3.973.19
|
||||
'@aws-sdk/credential-provider-web-identity': 3.972.81
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/credential-provider-env': 3.972.76
|
||||
'@aws-sdk/credential-provider-http': 3.972.78
|
||||
'@aws-sdk/credential-provider-ini': 3.973.21
|
||||
'@aws-sdk/credential-provider-process': 3.972.76
|
||||
'@aws-sdk/credential-provider-sso': 3.973.20
|
||||
'@aws-sdk/credential-provider-web-identity': 3.972.82
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/credential-provider-imds': 4.5.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-process@3.972.75':
|
||||
'@aws-sdk/credential-provider-process@3.972.76':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-sso@3.973.19':
|
||||
'@aws-sdk/credential-provider-sso@3.973.20':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/nested-clients': 3.997.49
|
||||
'@aws-sdk/token-providers': 3.1153.0
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/nested-clients': 3.997.50
|
||||
'@aws-sdk/token-providers': 3.1155.0
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/credential-provider-web-identity@3.972.81':
|
||||
'@aws-sdk/credential-provider-web-identity@3.972.82':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/nested-clients': 3.997.49
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/nested-clients': 3.997.50
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/lib-storage@3.1153.0(@aws-sdk/client-s3@3.1153.0)':
|
||||
'@aws-sdk/lib-storage@3.1155.0(@aws-sdk/client-s3@3.1155.0)':
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3': 3.1153.0
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/client-s3': 3.1155.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
buffer: 5.6.0
|
||||
events: 3.3.0
|
||||
stream-browserify: 3.0.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/middleware-sdk-s3@3.972.80':
|
||||
'@aws-sdk/middleware-sdk-s3@3.972.81':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/signature-v4-multi-region': 3.996.48
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/signature-v4-multi-region': 3.996.49
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/nested-clients@3.997.49':
|
||||
'@aws-sdk/nested-clients@3.997.50':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/signature-v4-multi-region': 3.996.48
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/signature-v4-multi-region': 3.996.49
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/fetch-http-handler': 5.8.0
|
||||
'@smithy/node-http-handler': 4.12.1
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/signature-v4-multi-region@3.996.48':
|
||||
'@aws-sdk/signature-v4-multi-region@3.996.49':
|
||||
dependencies:
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/signature-v4': 5.7.4
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/token-providers@3.1153.0':
|
||||
'@aws-sdk/token-providers@3.1155.0':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.978.4
|
||||
'@aws-sdk/nested-clients': 3.997.49
|
||||
'@aws-sdk/types': 3.974.6
|
||||
'@smithy/core': 3.36.0
|
||||
'@aws-sdk/core': 3.978.5
|
||||
'@aws-sdk/nested-clients': 3.997.50
|
||||
'@aws-sdk/types': 3.975.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/types@3.974.6':
|
||||
'@aws-sdk/types@3.975.0':
|
||||
dependencies:
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
@@ -8368,7 +8368,7 @@ snapshots:
|
||||
express: 5.2.1(supports-color@7.2.0)
|
||||
express-rate-limit: 8.6.2(express@5.2.1(supports-color@7.2.0))(supports-color@7.2.0)
|
||||
hono: 4.13.13
|
||||
jose: 6.2.12
|
||||
jose: 6.2.13
|
||||
json-schema-typed: 8.0.2
|
||||
pkce-challenge: 5.0.1
|
||||
raw-body: 3.0.2
|
||||
@@ -8389,52 +8389,52 @@ snapshots:
|
||||
strict-event-emitter: 0.5.1
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-android-arm64@1.0.11':
|
||||
'@napi-rs/canvas-android-arm64@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-darwin-arm64@1.0.11':
|
||||
'@napi-rs/canvas-darwin-arm64@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-darwin-x64@1.0.11':
|
||||
'@napi-rs/canvas-darwin-x64@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-linux-arm-gnueabihf@1.0.11':
|
||||
'@napi-rs/canvas-linux-arm-gnueabihf@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-linux-arm64-gnu@1.0.11':
|
||||
'@napi-rs/canvas-linux-arm64-gnu@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-linux-arm64-musl@1.0.11':
|
||||
'@napi-rs/canvas-linux-arm64-musl@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-linux-riscv64-gnu@1.0.11':
|
||||
'@napi-rs/canvas-linux-riscv64-gnu@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-linux-x64-gnu@1.0.11':
|
||||
'@napi-rs/canvas-linux-x64-gnu@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-linux-x64-musl@1.0.11':
|
||||
'@napi-rs/canvas-linux-x64-musl@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-win32-arm64-msvc@1.0.11':
|
||||
'@napi-rs/canvas-win32-arm64-msvc@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas-win32-x64-msvc@1.0.11':
|
||||
'@napi-rs/canvas-win32-x64-msvc@1.0.13':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/canvas@1.0.11':
|
||||
'@napi-rs/canvas@1.0.13':
|
||||
optionalDependencies:
|
||||
'@napi-rs/canvas-android-arm64': 1.0.11
|
||||
'@napi-rs/canvas-darwin-arm64': 1.0.11
|
||||
'@napi-rs/canvas-darwin-x64': 1.0.11
|
||||
'@napi-rs/canvas-linux-arm-gnueabihf': 1.0.11
|
||||
'@napi-rs/canvas-linux-arm64-gnu': 1.0.11
|
||||
'@napi-rs/canvas-linux-arm64-musl': 1.0.11
|
||||
'@napi-rs/canvas-linux-riscv64-gnu': 1.0.11
|
||||
'@napi-rs/canvas-linux-x64-gnu': 1.0.11
|
||||
'@napi-rs/canvas-linux-x64-musl': 1.0.11
|
||||
'@napi-rs/canvas-win32-arm64-msvc': 1.0.11
|
||||
'@napi-rs/canvas-win32-x64-msvc': 1.0.11
|
||||
'@napi-rs/canvas-android-arm64': 1.0.13
|
||||
'@napi-rs/canvas-darwin-arm64': 1.0.13
|
||||
'@napi-rs/canvas-darwin-x64': 1.0.13
|
||||
'@napi-rs/canvas-linux-arm-gnueabihf': 1.0.13
|
||||
'@napi-rs/canvas-linux-arm64-gnu': 1.0.13
|
||||
'@napi-rs/canvas-linux-arm64-musl': 1.0.13
|
||||
'@napi-rs/canvas-linux-riscv64-gnu': 1.0.13
|
||||
'@napi-rs/canvas-linux-x64-gnu': 1.0.13
|
||||
'@napi-rs/canvas-linux-x64-musl': 1.0.13
|
||||
'@napi-rs/canvas-win32-arm64-msvc': 1.0.13
|
||||
'@napi-rs/canvas-win32-x64-msvc': 1.0.13
|
||||
|
||||
'@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
|
||||
dependencies:
|
||||
@@ -9887,32 +9887,32 @@ snapshots:
|
||||
|
||||
'@sindresorhus/merge-streams@4.0.0': {}
|
||||
|
||||
'@smithy/core@3.36.0':
|
||||
'@smithy/core@3.36.2':
|
||||
dependencies:
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/credential-provider-imds@4.5.2':
|
||||
dependencies:
|
||||
'@smithy/core': 3.36.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/fetch-http-handler@5.8.0':
|
||||
dependencies:
|
||||
'@smithy/core': 3.36.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/node-http-handler@4.12.1':
|
||||
dependencies:
|
||||
'@smithy/core': 3.36.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/signature-v4@5.7.4':
|
||||
dependencies:
|
||||
'@smithy/core': 3.36.0
|
||||
'@smithy/core': 3.36.2
|
||||
'@smithy/types': 4.19.0
|
||||
tslib: 2.8.1
|
||||
|
||||
@@ -10072,13 +10072,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': 19.3.0
|
||||
|
||||
'@tanstack/react-virtual@3.14.21(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
|
||||
'@tanstack/react-virtual@3.14.22(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/virtual-core': 3.19.6
|
||||
'@tanstack/virtual-core': 3.19.7
|
||||
react: 19.3.1
|
||||
react-dom: 19.3.1(react@19.3.1)
|
||||
|
||||
'@tanstack/virtual-core@3.19.6': {}
|
||||
'@tanstack/virtual-core@3.19.7': {}
|
||||
|
||||
'@tesseract.js-data/deu@1.0.0': {}
|
||||
|
||||
@@ -12354,7 +12354,7 @@ snapshots:
|
||||
|
||||
jiti@2.7.0: {}
|
||||
|
||||
jose@6.2.12: {}
|
||||
jose@6.2.13: {}
|
||||
|
||||
js-md4@0.3.2: {}
|
||||
|
||||
@@ -12677,7 +12677,7 @@ snapshots:
|
||||
|
||||
lru.min@1.1.5: {}
|
||||
|
||||
lucide-react@1.59.0(@types/react@19.3.0)(react@19.3.1):
|
||||
lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1):
|
||||
dependencies:
|
||||
react: 19.3.1
|
||||
optionalDependencies:
|
||||
@@ -12868,7 +12868,7 @@ snapshots:
|
||||
|
||||
node-releases@2.0.58: {}
|
||||
|
||||
nodemailer@10.1.7: {}
|
||||
nodemailer@10.2.1: {}
|
||||
|
||||
non-error@0.1.0: {}
|
||||
|
||||
@@ -13113,7 +13113,7 @@ snapshots:
|
||||
|
||||
pdfjs-dist@6.4.299:
|
||||
optionalDependencies:
|
||||
'@napi-rs/canvas': 1.0.11
|
||||
'@napi-rs/canvas': 1.0.13
|
||||
|
||||
perfect-debounce@2.1.0: {}
|
||||
|
||||
|
||||
@@ -11,7 +11,11 @@
|
||||
# empty the new database and run the move again.
|
||||
# 5. Empty the new volume: it must refuse to import the old state again,
|
||||
# and move it once more after the marker is removed as the guide says.
|
||||
# 6. A new install with no old volume: nothing to do.
|
||||
# 6. Going back to 16 after a move that did not finish: db-upgrade leaves
|
||||
# the live 16 database alone.
|
||||
# 7. Using 16 again after a move, then updating: refused, not the old copy.
|
||||
# 8. Updating again as the guide says: the current 16 database moves.
|
||||
# 9. A new install with no old volume: nothing to do.
|
||||
#
|
||||
# Needs Docker and the repo's node_modules (for the migrations). Run it from
|
||||
# anywhere in the repo: `bash scripts/compose-db-upgrade-check.sh`.
|
||||
@@ -85,7 +89,7 @@ wait_for_port() {
|
||||
migrate_old() {
|
||||
local started=$SECONDS
|
||||
until DATABASE_URL="postgresql://healthlog:$POSTGRES_PASSWORD@127.0.0.1:$PORT/healthlog?schema=public" \
|
||||
node "$ROOT/node_modules/prisma/build/index.js" migrate deploy --schema "$ROOT/prisma/schema.prisma" >"$WORK/migrate.log" 2>&1; do
|
||||
node "$ROOT/node_modules/prisma/build/index.js" migrate deploy --schema "$WORK/old-prisma/prisma/schema.prisma" >"$WORK/migrate.log" 2>&1; do
|
||||
if [ $((SECONDS - started)) -ge 30 ] || ! grep -q "P1001" "$WORK/migrate.log"; then
|
||||
cat "$WORK/migrate.log" >&2
|
||||
return 1
|
||||
@@ -94,6 +98,18 @@ migrate_old() {
|
||||
done
|
||||
}
|
||||
|
||||
# The v1.45 schema, migrated with v1.45's own migrations.
|
||||
mkdir -p "$WORK/old-prisma"
|
||||
git -C "$ROOT" archive "$OLD_REF" prisma | tar -x -C "$WORK/old-prisma"
|
||||
# The current compose file with its database pointed back at Postgres 16, the
|
||||
# way docs/ops/postgres-major-upgrade.md "Going back" describes it.
|
||||
sed -e 's|image: postgres:18\.[0-9]*-alpine|image: postgres:16.15-alpine|' \
|
||||
-e 's|- postgres-data:/var/lib/postgresql$|- pgdata:/var/lib/postgresql/data|' \
|
||||
"$ROOT/docker-compose.yml" >"$WORK/back.yml"
|
||||
grep -q 'image: postgres:16.15-alpine' "$WORK/back.yml" && grep -q -- '- pgdata:/var/lib/postgresql/data' "$WORK/back.yml" ||
|
||||
{ echo "FAIL: could not derive the going-back compose file" >&2; exit 1; }
|
||||
back() { docker compose -p "$PROJECT" -f "$WORK/back.yml" "$@"; }
|
||||
|
||||
down_all
|
||||
step "a v1.45 database on Postgres 16"
|
||||
old up -d --wait db >"$WORK/up.log" 2>&1 || { cat "$WORK/up.log" >&2; fail "the v1.45 database did not start"; }
|
||||
@@ -157,10 +173,42 @@ CODE=$(run_upgrade)
|
||||
[ "$CODE" = 0 ] || fail "db-upgrade exited $CODE after the marker was removed"
|
||||
[ "$(probe docker exec healthlog-db)" = "$PROBE" ] || fail "the probe rows differ after starting over"
|
||||
|
||||
step "going back to 16 after a move that did not finish leaves 16 alone"
|
||||
new down >/dev/null 2>&1
|
||||
docker volume rm "${PROJECT}_postgres-data" >/dev/null
|
||||
docker run --rm -v "${PROJECT}_pgdata:/old" postgres:16.15-alpine \
|
||||
mv /old/HEALTHLOG_MOVED_TO_POSTGRES_18 /old/HEALTHLOG_MOVING_TO_POSTGRES_18
|
||||
back up -d db-upgrade >/dev/null 2>&1 || true
|
||||
CODE=$(docker wait healthlog-db-upgrade)
|
||||
upgrade_log
|
||||
[ "$CODE" = 0 ] || fail "db-upgrade exited $CODE beside a Postgres 16 database service"
|
||||
upgrade_log | grep -q 'not 18: nothing to move' || fail "db-upgrade did not recognise the Postgres 16 service"
|
||||
[ "$(probe docker exec healthlog-db)" = "$PROBE" ] || fail "the live Postgres 16 data changed beside db-upgrade"
|
||||
|
||||
step "using 16 again after a move, then updating, is refused instead of serving the old copy"
|
||||
back down >/dev/null 2>&1
|
||||
CODE=$(run_upgrade)
|
||||
[ "$CODE" = 0 ] || fail "the move after going back exited $CODE"
|
||||
back up -d db >/dev/null 2>&1
|
||||
back exec -T db psql -U healthlog -d healthlog -v ON_ERROR_STOP=1 -qc \
|
||||
"INSERT INTO check_probe.rows VALUES (50001, 'written on 16 after the move')"
|
||||
back down >/dev/null 2>&1
|
||||
CODE=$(run_upgrade)
|
||||
[ "$CODE" = 1 ] || fail "db-upgrade exited $CODE after 16 was used again, expected 1"
|
||||
upgrade_log | grep -q 'changed after it was moved' || fail "the refusal did not say that 16 changed"
|
||||
|
||||
step "updating again as the guide says moves the current 16 database"
|
||||
new down >/dev/null 2>&1
|
||||
docker volume rm "${PROJECT}_postgres-data" >/dev/null
|
||||
new run --rm --entrypoint rm db-upgrade /var/lib/postgresql/data/HEALTHLOG_MOVED_TO_POSTGRES_18 >/dev/null 2>&1
|
||||
CODE=$(run_upgrade)
|
||||
[ "$CODE" = 0 ] || fail "db-upgrade exited $CODE when moving the current 16 database"
|
||||
[ "$(sql "SELECT count(*) FROM check_probe.rows")" = 50001 ] || fail "the row written on 16 did not arrive"
|
||||
|
||||
step "a new install: nothing to do"
|
||||
new down -v >/dev/null 2>&1
|
||||
CODE=$(run_upgrade)
|
||||
[ "$CODE" = 0 ] || fail "db-upgrade exited $CODE on a new install"
|
||||
upgrade_log | tail -1 | grep -q 'no Postgres 16 database to move' || fail "the new install did not say there was nothing to move"
|
||||
|
||||
echo "OK: the Postgres 16 -> 18 move behaves in all six cases"
|
||||
echo "OK: the Postgres 16 -> 18 move behaves in all nine cases"
|
||||
@@ -77,6 +77,8 @@ describe("the Postgres 16 -> 18 move in docker-compose.yml", () => {
|
||||
// The checks run before the restore, in this order.
|
||||
const order = [
|
||||
"PG_VERSION",
|
||||
// Never touch the old volume while the database service runs on it.
|
||||
'if [ "$$NEWVER" -lt 180000 ]',
|
||||
"$$MARK",
|
||||
"$$MOVING",
|
||||
'elif [ "$$TABLES" != 0 ]',
|
||||
|
||||
@@ -105,7 +105,9 @@ describe("demo seed, short-window shape", () => {
|
||||
it("leaves the median of the window in the settled band", () => {
|
||||
// The usual range is the median ± 3 MAD of the last 30 days. A stretch
|
||||
// that fills half the window moves that median onto the stretch and
|
||||
// widens the band to something like 87-181 mmHg.
|
||||
// widens the band to something like 87-181 mmHg. The seed's own spread
|
||||
// reaches about ±22 in one run of 150, so the bound sits at 24, still far
|
||||
// below what a stretch that long produces.
|
||||
const sorted = [...systolic].sort((a, b) => a - b);
|
||||
const median = sorted[Math.floor(sorted.length / 2)];
|
||||
expect(median).toBeLessThanOrEqual(124);
|
||||
@@ -113,7 +115,7 @@ describe("demo seed, short-window shape", () => {
|
||||
.map((v) => Math.abs(v - median))
|
||||
.sort((a, b) => a - b);
|
||||
const mad = deviations[Math.floor(deviations.length / 2)];
|
||||
expect(3 * 1.4826 * mad).toBeLessThanOrEqual(20);
|
||||
expect(3 * 1.4826 * mad).toBeLessThanOrEqual(24);
|
||||
});
|
||||
|
||||
it("raises ramipril on the day the stretch turns", () => {
|
||||
|
||||
Reference in new issue
Block a user