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:
40
caddyfile-docs-update.txt
Normal file
40
caddyfile-docs-update.txt
Normal 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
|
||||
47
create-claude-matrix-user.md
Normal file
47
create-claude-matrix-user.md
Normal 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
156
get-claude-token.py
Executable 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())
|
||||
Reference in New Issue
Block a user