diff --git a/lnbits/core/services/users.py b/lnbits/core/services/users.py index cd0b4ea06..37f2c998c 100644 --- a/lnbits/core/services/users.py +++ b/lnbits/core/services/users.py @@ -199,8 +199,11 @@ async def init_admin_settings(super_user: str | None = None) -> SuperSettings: async def check_register_activation_settings(data: RegisterUser): if not settings.lnbits_require_user_activation: return None - code = data.invitation_code.strip() if data.invitation_code else None - if settings.lnbits_user_activation_by_invitation_code and code: + if settings.lnbits_user_activation_by_invitation_code: + code = data.invitation_code.strip() if data.invitation_code else "" + if len(code) == 0: + raise ValueError("Invitation code cannot be empty.") + if code == settings.lnbits_register_reusable_activation_code: return None if code in settings.lnbits_register_one_time_activation_codes: diff --git a/tests/api/test_auth.py b/tests/api/test_auth.py index 4504ffd78..cf50e575a 100644 --- a/tests/api/test_auth.py +++ b/tests/api/test_auth.py @@ -297,6 +297,42 @@ async def test_register_ok(http_client: AsyncClient): ), f"Expected 1 default wallet, not {len(user.wallets)}." +@pytest.mark.anyio +async def test_register_no_activation_code( + http_client: AsyncClient, settings: Settings +): + settings.lnbits_require_user_activation = True + + tiny_id = shortuuid.uuid()[:8] + response = await http_client.post( + "/api/v1/auth/register", + json={ + "username": f"u21.{tiny_id}", + "password": "secret1234", + "password_repeat": "secret1234", + "email": f"u21.{tiny_id}@lnbits.com", + }, + ) + + assert response.status_code == 400 + assert response.json().get("detail") == "No activation method provided." + + settings.lnbits_user_activation_by_invitation_code = True + + response = await http_client.post( + "/api/v1/auth/register", + json={ + "username": f"u21.{tiny_id}", + "password": "secret1234", + "password_repeat": "secret1234", + "email": f"u21.{tiny_id}@lnbits.com", + }, + ) + + assert response.status_code == 400, "User creation blocked without activation code." + assert response.json().get("detail") == "Invitation code cannot be empty." + + @pytest.mark.anyio async def test_register_email_twice(http_client: AsyncClient): tiny_id = shortuuid.uuid()[:8] diff --git a/tests/conftest.py b/tests/conftest.py index a76168a38..a677a225b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -341,3 +341,5 @@ def _settings_cleanup(settings: Settings): settings.lnbits_max_outgoing_payment_amount_sats = 10_000_000_100 settings.lnbits_max_incoming_payment_amount_sats = 10_000_000_200 settings.stripe_limits = FiatProviderLimits() + settings.lnbits_require_user_activation = False + settings.lnbits_user_activation_by_invitation_code = False