From d85ab9c493284db988fbb1cf899cd739b61786e4 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 9 Dec 2025 14:13:08 +0100 Subject: [PATCH] fix: Allow email addresses as Nextcloud admin username MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The validation was too restrictive, only allowing alphanumeric usernames. Now accepts both: - Standard usernames (letters, numbers, underscores) - Valid email addresses šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .claude/settings.local.json | 6 +++++- app/routes/playbooks.py | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 848bf72..d5d5660 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -15,7 +15,11 @@ "Bash(python:*)", "Bash(git init:*)", "Bash(git remote add:*)", - "Bash(git add:*)" + "Bash(git add:*)", + "Bash(git commit -m \"$(cat <<''EOF''\nInitial commit: LetsBe Cloud Orchestrator\n\nFeatures:\n- FastAPI backend with SQLAlchemy 2.0 async ORM\n- Tenant management (CRUD operations)\n- Task management with types: FILE_WRITE, ENV_UPDATE, DOCKER_RELOAD, COMPOSITE\n- Agent registration, heartbeat, and task claiming (/tasks/next)\n- Chatwoot deployment playbook (COMPOSITE task with ENV_UPDATE + DOCKER_RELOAD)\n- Alembic migrations for Postgres\n- Docker Compose setup for local development\n\nšŸ¤– Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude \nEOF\n)\")", + "Bash(git push:*)", + "Bash(git remote set-url:*)", + "Bash(git commit:*)" ], "deny": [], "ask": [] diff --git a/app/routes/playbooks.py b/app/routes/playbooks.py index 8b9c95a..b051726 100644 --- a/app/routes/playbooks.py +++ b/app/routes/playbooks.py @@ -68,10 +68,12 @@ class NextcloudInitialSetupRequest(BaseModel): @field_validator("admin_username") @classmethod def validate_username(cls, v: str) -> str: - """Validate that username is alphanumeric (with underscores allowed).""" - if not re.match(r"^[a-zA-Z][a-zA-Z0-9_]*$", v): + """Validate that username is alphanumeric or a valid email address.""" + username_pattern = r"^[a-zA-Z][a-zA-Z0-9_]*$" + email_pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" + if not (re.match(username_pattern, v) or re.match(email_pattern, v)): raise ValueError( - "Username must start with a letter and contain only letters, numbers, and underscores" + "Username must be alphanumeric (starting with a letter) or a valid email address" ) return v