allow auto setup without password through ingress
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Mon, 8 Dec 2025 20:00:51 +0000 (21:00 +0100)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Mon, 8 Dec 2025 20:00:51 +0000 (21:00 +0100)
music_assistant/controllers/webserver/controller.py
music_assistant/helpers/resources/setup.html

index 6baa54263df44809d6529dbed9a8bfbb44f689a5..b9f2fd26abc341a89d66105c155a899097c96aa8 100644 (file)
@@ -999,77 +999,61 @@ class WebserverController(CoreController):
         from_ingress = body.get("from_ingress", False)
         display_name = body.get("display_name")
 
+        # Check if this is a valid ingress request (from_ingress flag + actual ingress headers)
+        is_valid_ingress = from_ingress and is_request_from_ingress(request)
+
         # Validation
         if not username or len(username) < 2:
             return web.json_response(
                 {"success": False, "error": "Username must be at least 2 characters"}, status=400
             )
 
-        if not password or len(password) < 8:
+        # Password is only required for non-ingress users
+        if not is_valid_ingress and (not password or len(password) < 8):
             return web.json_response(
                 {"success": False, "error": "Password must be at least 8 characters"}, status=400
             )
 
         try:
-            # Get built-in provider
-            builtin_provider = self.auth.login_providers.get("builtin")
-            if not builtin_provider:
-                return web.json_response(
-                    {"success": False, "error": "Built-in auth provider not available"}, status=500
-                )
+            if is_valid_ingress:
+                # Ingress setup: Create user with HA provider link only (no password required)
+                ha_user_id = request.headers.get("X-Remote-User-ID")
+                if not ha_user_id:
+                    return web.json_response(
+                        {"success": False, "error": "Missing Home Assistant user ID"}, status=400
+                    )
 
-            if not isinstance(builtin_provider, BuiltinLoginProvider):
-                return web.json_response(
-                    {"success": False, "error": "Built-in provider configuration error"}, status=500
+                # Create admin user without password
+                user = await self.auth.create_user(
+                    username=username,
+                    role=UserRole.ADMIN,
+                    display_name=display_name,
                 )
 
-            # Check if this is an Ingress setup where user already exists
-            user = None
-            if from_ingress and is_request_from_ingress(request):
-                ha_user_id = request.headers.get("X-Remote-User-ID")
-                if ha_user_id:
-                    # Try to find existing auto-created Ingress user
-                    user = await self.auth.get_user_by_provider_link(
-                        AuthProviderType.HOME_ASSISTANT, ha_user_id
+                # Link to Home Assistant provider
+                await self.auth.link_user_to_provider(
+                    user, AuthProviderType.HOME_ASSISTANT, ha_user_id
+                )
+            else:
+                # Non-ingress setup: Create user with password
+                builtin_provider = self.auth.login_providers.get("builtin")
+                if not builtin_provider:
+                    return web.json_response(
+                        {"success": False, "error": "Built-in auth provider not available"},
+                        status=500,
                     )
-            if user:
-                # User already exists (auto-created from Ingress), update and add password
-                updates = {}
-                if display_name and not user.display_name:
-                    updates["display_name"] = display_name
-                    user.display_name = display_name
-
-                # Make user admin if not already
-                if user.role != UserRole.ADMIN:
-                    updates["role"] = UserRole.ADMIN.value
-                    user.role = UserRole.ADMIN
-
-                # Apply updates if any
-                if updates:
-                    await self.auth.database.update(
-                        "users",
-                        {"user_id": user.user_id},
-                        updates,
+
+                if not isinstance(builtin_provider, BuiltinLoginProvider):
+                    return web.json_response(
+                        {"success": False, "error": "Built-in provider configuration error"},
+                        status=500,
                     )
 
-                # Add password authentication to existing user
-                password_hash = builtin_provider._hash_password(password, user.user_id)
-                await self.auth.link_user_to_provider(user, AuthProviderType.BUILTIN, password_hash)
-            else:
-                # Create new admin user with password
+                # Create admin user with password
                 user = await builtin_provider.create_user_with_password(
                     username, password, role=UserRole.ADMIN, display_name=display_name
                 )
 
-                # If from Ingress, also link to HA provider
-                if from_ingress and is_request_from_ingress(request):
-                    ha_user_id = request.headers.get("X-Remote-User-ID")
-                    if ha_user_id:
-                        # Link user to Home Assistant provider
-                        await self.auth.link_user_to_provider(
-                            user, AuthProviderType.HOME_ASSISTANT, ha_user_id
-                        )
-
             # Create token for the new admin
             device_name = body.get(
                 "device_name", f"Setup ({request.headers.get('User-Agent', 'Unknown')[:50]})"
index 034c7a51d19debedddb04642e1c251e3e0e4ee22..d849dcbd542644a0cb8b95e1ddbffcfb1409a69f 100644 (file)
             </div>
 
             <div class="info-box ingress" id="ingressAccountInfo" style="display: none;">
-                <h3>About your login credentials</h3>
-                <p>While Home Assistant handles authentication for Ingress access, you'll need these credentials for:</p>
-                <ul>
-                    <li>Direct access to Music Assistant (outside Home Assistant)</li>
-                    <li>Music Assistant mobile apps</li>
-                    <li>API access and third-party integrations</li>
-                </ul>
+                <h3>Home Assistant Login</h3>
+                <p>You are automatically logged in using your Home Assistant account. If you ever want to access Music Assistant outside of Home Assistant, you can set up a password later in the profile settings.</p>
             </div>
 
             <div class="error-message" id="errorMessage"></div>
             const usernameField = document.getElementById('username');
             usernameField.value = ingressUsername;
             usernameField.disabled = true;
+
+            // Hide password fields for ingress users (they don't need to set a password)
+            document.querySelector('.form-group:has(#password)').style.display = 'none';
+            document.querySelector('.form-group:has(#confirmPassword)').style.display = 'none';
+
+            // Remove required attribute from password fields for HTML5 validation
+            document.getElementById('password').removeAttribute('required');
+            document.getElementById('confirmPassword').removeAttribute('required');
+
+            // Update step header for ingress users
+            const stepHeader = document.querySelector('.step[data-step="1"] .step-header');
+            stepHeader.querySelector('h2').textContent = 'Confirm Your Account';
+            stepHeader.querySelector('p').textContent = 'Your account will be linked to your Home Assistant user.';
+
+            // Update button text for ingress users
+            document.getElementById('createAccountBtn').textContent = 'Complete Setup';
         }
 
         function updateStepIndicator() {
                 return;
             }
 
-            if (password.length < 8) {
-                showError('Password must be at least 8 characters long');
-                return;
-            }
+            // Password validation only for non-ingress users
+            if (!isIngressSetup) {
+                if (password.length < 8) {
+                    showError('Password must be at least 8 characters long');
+                    return;
+                }
 
-            if (password !== confirmPassword) {
-                showError('Passwords do not match');
-                return;
+                if (password !== confirmPassword) {
+                    showError('Passwords do not match');
+                    return;
+                }
             }
 
             setLoading(true);