Add Caddy authentication and Claude Matrix user setup

- Created caddyfile-docs-update.txt with Caddy basic auth configuration
- Fixed documentation path from /home/klas/langmem-docs to /home/klas/langmem/docs
- Added basic auth with credentials: langmem / langmem2025
- Created create-claude-matrix-user.md with user creation instructions
- Added get-claude-token.py script for automated Matrix setup
- Includes token retrieval, room joining, and configuration export

Manual steps required:
1. Update /etc/caddy/Caddyfile with new docs.klas.chat config
2. Reload Caddy: sudo systemctl reload caddy
3. Create Claude Matrix user via admin panel
4. Run get-claude-token.py to complete setup

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Docker Config Backup
2025-07-17 13:35:21 +02:00
parent e706ca593c
commit 103d68ffe2
3 changed files with 243 additions and 0 deletions

40
caddyfile-docs-update.txt Normal file
View File

@@ -0,0 +1,40 @@
# Updated docs.klas.chat configuration with authentication
# Replace the existing docs.klas.chat block in /etc/caddy/Caddyfile with this:
docs.klas.chat {
tls /certs/klas.chat/fullchain.cer /certs/klas.chat/klas.chat.key
# Basic Authentication
basicauth * {
langmem $2a$14$.1fx02QwkkmfezhZMLE4Iu2N/ub5vwDSAtcH9lAa5z11ChjiYy1PG
}
# Security headers
header {
X-Frame-Options "DENY"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
Referrer-Policy "strict-origin-when-cross-origin"
Strict-Transport-Security "max-age=31536000; includeSubDomains"
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https:; font-src 'self' data:;"
}
# Static file serving - UPDATED PATH
root * /home/klas/langmem/docs
file_server
# SPA routing fallback for clean URLs
try_files {path} {path}/ /index.html
# Enable compression
encode gzip
# Cache static assets
@static {
path *.css *.js *.png *.jpg *.jpeg *.gif *.svg *.ico *.woff *.woff2
}
header @static Cache-Control "public, max-age=31536000, immutable"
}
# Credentials: langmem / langmem2025

View File

@@ -0,0 +1,47 @@
# Creating Claude Matrix User
Since Matrix registration is disabled, you'll need to create the Claude user manually using admin tools.
## Option 1: Synapse Admin Panel
1. **Access Synapse Admin**: https://synapse.klas.chat/admin
2. **Login with admin credentials**
3. **Go to Users section**
4. **Create new user:**
- **Username**: `claude`
- **Password**: `claude_assistant_2025`
- **Display Name**: `Claude Assistant`
- **Admin**: `No`
## Option 2: Command Line (if you have access to Synapse container)
```bash
# Access synapse container
docker exec -it synapse /bin/bash
# Create user using register_new_matrix_user
register_new_matrix_user -u claude -p claude_assistant_2025 -c /data/homeserver.yaml https://matrix.klas.chat
```
## Option 3: Database Direct (if needed)
```sql
-- Connect to Matrix database and insert user manually
-- This requires knowledge of your Matrix database structure
```
## After Creating the User
1. **Get access token** for the claude user
2. **Join Home Assistant room** using the new account
3. **Update Claude's global configuration** with new credentials
## Next Steps
Once you've created the Claude user, I'll:
1. Get the access token
2. Join the Home Assistant room
3. Update my global Matrix configuration
4. Test sending messages as the Claude user
Let me know when the user is created!

156
get-claude-token.py Executable file
View File

@@ -0,0 +1,156 @@
#!/usr/bin/env python3
"""
Get access token for Claude Matrix user and join Home Assistant room
"""
import asyncio
import httpx
import json
MATRIX_HOMESERVER = "https://matrix.klas.chat"
CLAUDE_USERNAME = "claude"
CLAUDE_PASSWORD = "claude_assistant_2025"
HOME_ASSISTANT_ROOM_ID = "!xZkScMybPseErYMJDz:matrix.klas.chat"
async def login_and_get_token():
"""Login as Claude user and get access token"""
try:
async with httpx.AsyncClient() as client:
# Login request
response = await client.post(
f"{MATRIX_HOMESERVER}/_matrix/client/v3/login",
json={
"type": "m.login.password",
"user": CLAUDE_USERNAME,
"password": CLAUDE_PASSWORD
}
)
if response.status_code == 200:
data = response.json()
access_token = data["access_token"]
user_id = data["user_id"]
print(f"✅ Successfully logged in as {user_id}")
print(f"🔑 Access Token: {access_token}")
return access_token, user_id
else:
print(f"❌ Login failed: {response.status_code}")
print(f"Response: {response.text}")
return None, None
except Exception as e:
print(f"❌ Error during login: {e}")
return None, None
async def join_home_assistant_room(access_token):
"""Join the Home Assistant room"""
try:
async with httpx.AsyncClient() as client:
headers = {"Authorization": f"Bearer {access_token}"}
# Join room
response = await client.post(
f"{MATRIX_HOMESERVER}/_matrix/client/v3/join/{HOME_ASSISTANT_ROOM_ID}",
headers=headers
)
if response.status_code == 200:
print(f"✅ Successfully joined Home Assistant room")
return True
else:
print(f"❌ Failed to join room: {response.status_code}")
print(f"Response: {response.text}")
return False
except Exception as e:
print(f"❌ Error joining room: {e}")
return False
async def send_test_message(access_token):
"""Send a test message to verify everything works"""
try:
async with httpx.AsyncClient() as client:
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
message = "🤖 Hello! Claude Assistant is now connected to Matrix and ready to send you updates about your projects."
response = await client.post(
f"{MATRIX_HOMESERVER}/_matrix/client/v3/rooms/{HOME_ASSISTANT_ROOM_ID}/send/m.room.message",
headers=headers,
json={
"msgtype": "m.text",
"body": message
}
)
if response.status_code == 200:
print(f"✅ Test message sent successfully!")
return True
else:
print(f"❌ Failed to send test message: {response.status_code}")
print(f"Response: {response.text}")
return False
except Exception as e:
print(f"❌ Error sending test message: {e}")
return False
async def main():
"""Main function"""
print("🤖 Setting up Claude Matrix Integration")
print("=" * 50)
# Step 1: Login and get token
print("\n1. Logging in as Claude user...")
access_token, user_id = await login_and_get_token()
if not access_token:
print("\n❌ Cannot proceed without access token.")
print("Make sure the Claude user has been created first!")
return
# Step 2: Join Home Assistant room
print("\n2. Joining Home Assistant room...")
joined = await join_home_assistant_room(access_token)
if not joined:
print("\n❌ Cannot proceed without joining the room.")
return
# Step 3: Send test message
print("\n3. Sending test message...")
message_sent = await send_test_message(access_token)
# Step 4: Output configuration for Claude
print("\n" + "=" * 50)
print("🎉 Claude Matrix Setup Complete!")
print("\n📋 Configuration for Claude's global config:")
print(f" Matrix Homeserver: {MATRIX_HOMESERVER}")
print(f" Claude User ID: {user_id}")
print(f" Claude Access Token: {access_token}")
print(f" Home Assistant Room: {HOME_ASSISTANT_ROOM_ID}")
# Save to file for easy copying
config = {
"matrix_homeserver": MATRIX_HOMESERVER,
"claude_user_id": user_id,
"claude_access_token": access_token,
"home_assistant_room_id": HOME_ASSISTANT_ROOM_ID,
"credentials": {
"username": CLAUDE_USERNAME,
"password": CLAUDE_PASSWORD
}
}
with open("/home/klas/langmem/claude-matrix-config.json", "w") as f:
json.dump(config, f, indent=2)
print(f"\n💾 Configuration saved to: /home/klas/langmem/claude-matrix-config.json")
if __name__ == "__main__":
asyncio.run(main())