Compare commits

...

3 Commits

Author SHA1 Message Date
mealie-commit-bot[bot]
e24187fefb chore: bump version to v3.19.2 2026-05-29 04:11:50 +00:00
Michael Genson
396fcd5ee4 fix: Ensure secret key is not empty (#7701) 2026-05-28 23:09:31 -05:00
renovate[bot]
5a3d202879 chore(deps): lock file maintenance (#7697)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-27 20:09:07 +00:00
9 changed files with 138 additions and 92 deletions

View File

@@ -31,7 +31,7 @@ To deploy mealie on your local network, it is highly recommended to use Docker t
We've gone through a few versions of Mealie v1 deployment targets. We have settled on a single container deployment, and we've begun publishing the nightly container on github containers. If you're looking to move from the old nightly (split containers _or_ the omni image) to the new nightly, there are a few things you need to do:
1. Take a backup just in case!
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.19.1`
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.19.2`
3. Take the external port from the frontend container and set that as the port mapped to port `9000` on the new container. The frontend is now served on port 9000 from the new container, so it will need to be mapped for you to have access.
4. Restart the container

View File

@@ -10,7 +10,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.19.1 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.19.2 # (3)
container_name: mealie
restart: always
ports:

View File

@@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.19.1 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.19.2 # (3)
container_name: mealie
restart: always
ports:

View File

@@ -1,6 +1,6 @@
{
"name": "mealie",
"version": "3.19.1",
"version": "3.19.2",
"private": true,
"scripts": {
"dev": "nuxt dev",

View File

@@ -3278,9 +3278,9 @@
integrity sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==
"@swc/helpers@^0.5.12":
version "0.5.22"
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.22.tgz#914130a189205cef611b75948c93b95adf6cf11b"
integrity sha512-/e2Ly3Docn9kYByap6TV4oquJ3wQuz3c+kC74riqtkwU9CwTMeuj6t2rW+bRr4pyOx/CYQM4wr0RgaKQwGEz0A==
version "0.5.23"
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.23.tgz#19287d0d86d962b111376039a50c792902c9a86a"
integrity sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==
dependencies:
tslib "^2.8.0"
@@ -3745,47 +3745,47 @@
"@babel/parser" "^7.28.4"
"@vue/compiler-sfc" "^3.5.22"
"@vue/compiler-core@3.5.34":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.34.tgz#6d84a46b7fdf1162cf8225aa2be42918a76ab827"
integrity sha512-s9cLyK5mLcvZ4Agva5QgRsQyLKvts9WbU9DB6NqiZkkGEdwmcEiylj5Jbwkp680drF/NNCV8OlAJSe+yMLxaJw==
"@vue/compiler-core@3.5.35":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.35.tgz#e789c89b0fee47683e5300c715bb9243c07a6bbd"
integrity sha512-BUmHaR1J+O+CKZ9uJucdVTEr1LHsdyvv7vG3eNRhK3CczEHeMd/LtsHAuD7PbrxvI2envCY2v7HI1vC1aBRzKw==
dependencies:
"@babel/parser" "^7.29.3"
"@vue/shared" "3.5.34"
"@vue/shared" "3.5.35"
entities "^7.0.1"
estree-walker "^2.0.2"
source-map-js "^1.2.1"
"@vue/compiler-dom@3.5.34", "@vue/compiler-dom@^3.2.45":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.34.tgz#6b943e8106822868e74d66c615432bbba6a589be"
integrity sha512-EbF/T++k0e2MMZlJsBhzK8Sgwt0HcIPOhzn1CTB/lv6sQcyk+OWf8YeiLxZp3ro7MbbLcAfAJ6sEvjFWuNgUCw==
"@vue/compiler-dom@3.5.35", "@vue/compiler-dom@^3.2.45":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.35.tgz#523a42dcc49af499588c51e3db52e672b9491325"
integrity sha512-k+bprkXxuqhVajgTx5mUHuir7TwQzUKOWR40ng1ncAqQRPnrLngGGgqVEEhOnTMlc8btHYVKmrP8s5Qyg0hvYA==
dependencies:
"@vue/compiler-core" "3.5.34"
"@vue/shared" "3.5.34"
"@vue/compiler-core" "3.5.35"
"@vue/shared" "3.5.35"
"@vue/compiler-sfc@3.5.34", "@vue/compiler-sfc@^3.5.13", "@vue/compiler-sfc@^3.5.22":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.34.tgz#93b6aeb3393cd7b3c71ff07f28879558f72e5f1d"
integrity sha512-D/ihr6uZeIt6r+pVZf46RWT1fAsLFMbUP7k8G1VkiiWexriED9GrX3echHd4Abbt17zjlfiFJ8z7a3BxZOPNjg==
"@vue/compiler-sfc@3.5.35", "@vue/compiler-sfc@^3.5.13", "@vue/compiler-sfc@^3.5.22":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.35.tgz#e0310f48a37cf326b5c926ef0006d75c87e34d33"
integrity sha512-G5VPMcXTSywXBgtFOZOnHKBxKSrwXUcvY1iaF5/hRcy7t0J6CH/d8ha9F4nzi00Fax1eLV0QHM7v4mQu68jydw==
dependencies:
"@babel/parser" "^7.29.3"
"@vue/compiler-core" "3.5.34"
"@vue/compiler-dom" "3.5.34"
"@vue/compiler-ssr" "3.5.34"
"@vue/shared" "3.5.34"
"@vue/compiler-core" "3.5.35"
"@vue/compiler-dom" "3.5.35"
"@vue/compiler-ssr" "3.5.35"
"@vue/shared" "3.5.35"
estree-walker "^2.0.2"
magic-string "^0.30.21"
postcss "^8.5.14"
postcss "^8.5.15"
source-map-js "^1.2.1"
"@vue/compiler-ssr@3.5.34":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.34.tgz#0561ae3f9b81564929a8544769eee9cc92a76c42"
integrity sha512-cDtTHKibkThKGHH1SP+WdccquNRYQDFH6rRjQCqT9G2ltFAfoR5pUftpab/z+aM5mW9HLLVQW7hfKKQe/1GBeQ==
"@vue/compiler-ssr@3.5.35":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.35.tgz#206cfc3d741c43d605ef0629509c00166022783b"
integrity sha512-rGhAeXgdM7/ffTJGXT69rCCdTmjDewnFuUZfBQQHTdcEBeWdT5HCGY60y2ytLJr9/Dsu7IntUi5z/w0h6Rjnzw==
dependencies:
"@vue/compiler-dom" "3.5.34"
"@vue/shared" "3.5.34"
"@vue/compiler-dom" "3.5.35"
"@vue/shared" "3.5.35"
"@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.6.4":
version "6.6.4"
@@ -3822,43 +3822,43 @@
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-8.1.2.tgz#1399660db04b7426a873b5985a548a6a7397fddd"
integrity sha512-X9RyVFYAdkBe4IUf5v48TxBF/6QPmF8CmWrDAjXzfUHrgQ/HGfTC1A6TqgXqZ03ye66l3AD51BAGD69IvKM9sw==
"@vue/reactivity@3.5.34":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.34.tgz#d41355f7e8b1784078ea498ec7d974e4e26d4b74"
integrity sha512-y9XDjCEuBp+98k+UL5dbYkh57AHU4o6cxZedOPXw3bmrZZYLQsVHguGurq7hVrPCSrQtrnz1f9dssyFr+dMXfQ==
"@vue/reactivity@3.5.35":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.35.tgz#45b9794ca77ff5ade2eee74bcdeacbc00ae8e7a2"
integrity sha512-tVc+SsHConvh/Lz64qq1pP3rYArBmK42xonovEcxY74SQtvctZodG/zhq54P5dr38cVuw25d27cPNRdlMidpGQ==
dependencies:
"@vue/shared" "3.5.34"
"@vue/shared" "3.5.35"
"@vue/runtime-core@3.5.34":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.34.tgz#1b4ce2ebf94d670acbd8f22d92e45908e2a2c96a"
integrity sha512-mKeBYvu8tcMSLhypAHBmriUFfWXKTCF/23Z4jiCoYK3UtWepkliViNLuR90V9XOyD62mUxs9p1jsrpK3CCGIzw==
"@vue/runtime-core@3.5.35":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.35.tgz#6f16679bc95ffe38af38c5d0bc1414ed4277458e"
integrity sha512-A/xFNX9loIcWDygeQuNCfKuh0CoYBzxhqEMNah5TSFg9Z53DrFYEN2qi5CU9necjM1OWYegYREUTHmXTmhfXtg==
dependencies:
"@vue/reactivity" "3.5.34"
"@vue/shared" "3.5.34"
"@vue/reactivity" "3.5.35"
"@vue/shared" "3.5.35"
"@vue/runtime-dom@3.5.34":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.34.tgz#1b4e5c009fe9d6ce682cfc2372da4abd40614d29"
integrity sha512-e8kZzERmCwUnBRVsgSQlAfrfU2rGoy0FFKPBXSlfEjc/O3KfA7QP0t1/2ZylrbchjmIKB4dPTd07A6WPr0eOrg==
"@vue/runtime-dom@3.5.35":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.35.tgz#473f0fbf97b82652780ac9e6bb5873f7c0dde7e7"
integrity sha512-odrJ1C391dbGnyDRh8U+rnP7J2amIEzfmRk5vXy7xi3aZhEXofTvpi0T4HJb6jlNqQZTNPR5MPHSB3RHNkIORA==
dependencies:
"@vue/reactivity" "3.5.34"
"@vue/runtime-core" "3.5.34"
"@vue/shared" "3.5.34"
"@vue/reactivity" "3.5.35"
"@vue/runtime-core" "3.5.35"
"@vue/shared" "3.5.35"
csstype "^3.2.3"
"@vue/server-renderer@3.5.34":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.34.tgz#e0776f839312b4111fb5bd742a70f435298a3e21"
integrity sha512-nHxmJoTrKsmrkbILRhkC9gY1G3moZbJTqCzDd7DOOzG5KH9oeJ0Unqrff5f9v0pW//jES05ZkJcNtfE8JjOIew==
"@vue/server-renderer@3.5.35":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.35.tgz#31c7b473de1000472444a0c0a336d1e799b209c3"
integrity sha512-NkebSOYdB97wi8OQcO3HqzZSlymJi/aWsN/7h74OSVhRTm6qGs3Jp3e0rCXynmWwSlKeRrnlIug+ilYoHBmQDA==
dependencies:
"@vue/compiler-ssr" "3.5.34"
"@vue/shared" "3.5.34"
"@vue/compiler-ssr" "3.5.35"
"@vue/shared" "3.5.35"
"@vue/shared@3.5.34", "@vue/shared@^3.5.22", "@vue/shared@^3.5.34":
version "3.5.34"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.34.tgz#665f2b2fd600f6c180668423909a6fde64cbfccd"
integrity sha512-24uqU4OIiX29ryC3MeWid/Xf2fa2EFRUVLb77nRhk+UrTVrh/XiGtFAFmJBAtBRbjwNdsPRP+jj/OL27Eg1NDA==
"@vue/shared@3.5.35", "@vue/shared@^3.5.22", "@vue/shared@^3.5.34":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.35.tgz#192eb3d720c40715db79313454c4937432a4e86d"
integrity sha512-zSbjL7gRXwks2ZQLRGCajBtBXEOXW9Ddhn/HvSdrGkE2dqGnumzW8XtusRrxrE9LvqtiqDXQ+A60Hp6mvdYxfA==
"@vuetify/loader-shared@^2.1.2":
version "2.1.2"
@@ -5027,9 +5027,9 @@ domhandler@^5.0.2, domhandler@^5.0.3:
domelementtype "^2.3.0"
dompurify@^3.4.5:
version "3.4.6"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.6.tgz#8f73010d14a46cd9781bbd3630f3bcef025a2111"
integrity sha512-+7gzEI8trIIQkVCvQ3ucGtNfH3nOmDgVTzc62rAAOlMxLth78pwpPoZCPc7CyRzAQF89MqcfPdEWkDwnjgqktg==
version "3.4.7"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.7.tgz#e2702ea4fd5d83467f1baef62309466ce7d44a82"
integrity sha512-2jBxDJY4RR06tQNy4w5FlFH7kfxsQZlufd0sbv+chfHCxeJwrFw2baUDsSwvBISD4K4RDbd0PTfy3uNXsR6siA==
optionalDependencies:
"@types/trusted-types" "^2.0.7"
@@ -7157,9 +7157,9 @@ lru-cache@^10.2.0:
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
lru-cache@^11.0.0, lru-cache@^11.2.7, lru-cache@^11.3.5:
version "11.5.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.5.0.tgz#14117229fd25bc9c67936e32de90ca047488c97a"
integrity sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==
version "11.5.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.5.1.tgz#f3daa3540847b9737ebc02499ddb36765e54db4a"
integrity sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==
lru-cache@^5.1.1:
version "5.1.1"
@@ -8281,7 +8281,7 @@ postcss-value-parser@^4.2.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.5.14, postcss@^8.5.6:
postcss@^8.5.14, postcss@^8.5.15, postcss@^8.5.6:
version "8.5.15"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.15.tgz#d1eaf677a324e9ec02196da2d3fecf4a0b9a735c"
integrity sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==
@@ -9514,9 +9514,9 @@ tinybench@^2.9.0:
integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==
tinyclip@^0.1.12:
version "0.1.12"
resolved "https://registry.yarnpkg.com/tinyclip/-/tinyclip-0.1.12.tgz#f3e91243f50c1a336103539b941782b417b9f1c0"
integrity sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==
version "0.1.13"
resolved "https://registry.yarnpkg.com/tinyclip/-/tinyclip-0.1.13.tgz#aafa818c5378f65fd375b9d3981eadd6c784b919"
integrity sha512-8OqlXQ35euK9+e7L68u8UwcODxkHoIkjbGsgXuARKNyQ5G6xt8nw1YPeMbxMLgCPFkToU+UEK5j05t2t8edKpQ==
tinyexec@^0.3.2:
version "0.3.2"
@@ -10387,15 +10387,15 @@ vue-router@^5.0.7:
yaml "^2.8.2"
vue@^3.4, vue@^3.5.13, vue@^3.5.34:
version "3.5.34"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.34.tgz#3b256eb30964416af6406a795fcfd7a5773a93c5"
integrity sha512-WdLBG9gm02OgJIG9axd5Hpx0TFLdzVgfG2evFFu8Rur5O/IoGc5cMjnjh3tPL6GnRGsYvUhBSKVPYVcxRKpMCA==
version "3.5.35"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.35.tgz#ba502479bd781825514c8af0f40744eeeb6223d6"
integrity sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==
dependencies:
"@vue/compiler-dom" "3.5.34"
"@vue/compiler-sfc" "3.5.34"
"@vue/runtime-dom" "3.5.34"
"@vue/server-renderer" "3.5.34"
"@vue/shared" "3.5.34"
"@vue/compiler-dom" "3.5.35"
"@vue/compiler-sfc" "3.5.35"
"@vue/runtime-dom" "3.5.35"
"@vue/server-renderer" "3.5.35"
"@vue/shared" "3.5.35"
vuetify-nuxt-module@^0.19.5:
version "0.19.5"

View File

@@ -50,12 +50,18 @@ def determine_secrets(data_dir: Path, secret: str, production: bool) -> str:
secrets_file = data_dir.joinpath(secret)
if secrets_file.is_file():
with open(secrets_file) as f:
return f.read()
else:
existing_secret = f.read().strip()
if existing_secret:
return existing_secret
data_dir.mkdir(parents=True, exist_ok=True)
with open(secrets_file, "w") as f:
new_secret = secrets.token_hex(32)
tmp_file = secrets_file.with_suffix(".tmp")
with open(tmp_file, "w") as f:
f.write(new_secret)
f.flush()
os.fsync(f.fileno())
tmp_file.replace(secrets_file)
return new_secret

View File

@@ -1,6 +1,6 @@
[project]
name = "mealie"
version = "3.19.1"
version = "3.19.2"
description = "A Recipe Manager"
authors = [{ name = "Hayden", email = "hay-kot@pm.me" }]
license = "AGPL-3.0-only"

View File

@@ -1,12 +1,13 @@
import json
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Any
import pytest
from mealie.core.config import get_app_settings
from mealie.core.settings.settings import AppSettings
from mealie.core.settings.settings import AppSettings, determine_secrets
def test_non_default_settings(monkeypatch):
@@ -367,3 +368,42 @@ def test_sensitive_settings_mask(monkeypatch: pytest.MonkeyPatch):
for setting in sensitive_settings:
assert settings[setting] == "*****"
assert settings_json[setting] == "*****"
class DetermineSecretsTests:
def test_non_production_returns_fixed_key(self, tmp_path: Path):
result = determine_secrets(tmp_path, ".secret", production=False)
assert result == "shh-secret-test-key"
def test_generates_secret_when_file_missing(self, tmp_path: Path):
result = determine_secrets(tmp_path, ".secret", production=True)
assert result
assert (tmp_path / ".secret").read_text() == result
def test_reuses_existing_secret(self, tmp_path: Path):
(tmp_path / ".secret").write_text("existing-secret")
result = determine_secrets(tmp_path, ".secret", production=True)
assert result == "existing-secret"
def test_regenerates_when_file_is_empty(self, tmp_path: Path):
(tmp_path / ".secret").write_text("")
result = determine_secrets(tmp_path, ".secret", production=True)
assert result
assert (tmp_path / ".secret").read_text() == result
def test_regenerates_when_file_is_whitespace_only(self, tmp_path: Path):
(tmp_path / ".secret").write_text(" \n ")
result = determine_secrets(tmp_path, ".secret", production=True)
assert result
assert (tmp_path / ".secret").read_text() == result
def test_generates_unique_secrets(self, tmp_path: Path):
dir_a = tmp_path / "a"
dir_b = tmp_path / "b"
result_a = determine_secrets(dir_a, ".secret", production=True)
result_b = determine_secrets(dir_b, ".secret", production=True)
assert result_a != result_b
def test_no_tmp_file_left_after_write(self, tmp_path: Path):
determine_secrets(tmp_path, ".secret", production=True)
assert not (tmp_path / ".tmp").exists()

8
uv.lock generated
View File

@@ -750,14 +750,14 @@ wheels = [
[[package]]
name = "joserfc"
version = "1.6.7"
version = "1.6.8"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cryptography" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1b/cb/52e479f20804904f5df20ac4539d292dcecd1287aaa33cba1d1def1d9d8e/joserfc-1.6.7.tar.gz", hash = "sha256:6999fe89457069ecacd8cc797c88a805f83054dd883333fa0409f74b46479fd7", size = 232158, upload-time = "2026-05-23T01:46:44.069Z" }
sdist = { url = "https://files.pythonhosted.org/packages/5d/ac/d4fd5b30f82900eac60d765f179f0ba005825ac462cc8ced6e13ec685ab3/joserfc-1.6.8.tar.gz", hash = "sha256:878620c553a6ebdd76ccdc356782fee3f735f21a356d079a546b42a4670ace5f", size = 232930, upload-time = "2026-05-27T03:22:37.819Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c5/e4/bcf6718b5662894c6831f46296b73cd4b1a2e90c20b6d437e20c4997388c/joserfc-1.6.7-py3-none-any.whl", hash = "sha256:9e51e4a64840aa1734a058258e80a4480e2ff2d5686e480e7c92c954a92fbe05", size = 70603, upload-time = "2026-05-23T01:46:42.129Z" },
{ url = "https://files.pythonhosted.org/packages/98/8c/5cdce2cf3ce8155849baf9a5e2ce77e89dc87ec3bdb38259e5d85fbc45bd/joserfc-1.6.8-py3-none-any.whl", hash = "sha256:22fb31a69094a5e6f44632002a9df2c30c941fc6c8ce1b037e92c03de954cf9f", size = 70927, upload-time = "2026-05-27T03:22:35.796Z" },
]
[[package]]
@@ -897,7 +897,7 @@ wheels = [
[[package]]
name = "mealie"
version = "3.19.1"
version = "3.19.2"
source = { editable = "." }
dependencies = [
{ name = "aiofiles" },