Skip to content

Commit 17acf17

Browse files
committed
Implement authentication system with JWT and user management
- Added Authenticator for handling JWT generation, validation, and user authentication. - Created CredentialsStore for managing user credentials in JSON format. - Implemented user registration, password update, and authentication methods. - Developed API endpoints for login, token refresh, and password change. - Added middleware for JWT validation in HTTP requests. - Designed web interface for user login, command execution, and password management. - Integrated frontend JavaScript for handling authentication and API interactions. - Styled web interface using Tailwind CSS and custom styles.
1 parent 0a2e754 commit 17acf17

22 files changed

Lines changed: 2623 additions & 513 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Lumo is an intelligent CLI assistant that interprets natural language to help yo
3535
- **System Monitoring**: Track system health and performance
3636
- **Pipe Support**: Analyze and explain command outputs
3737
- **Web Interface**: Access Lumo through a browser-based interface
38+
- **Secure Authentication**: JWT-based authentication for the REST API
3839
- **Multiple AI Providers**: Support for Google Gemini, OpenAI, and Ollama
3940

4041
## 🚀 Installation
@@ -83,10 +84,16 @@ lumo desktop:"launch terminal"
8384
# Web interface - start the server and access via browser
8485
lumo server:start
8586
# Then open http://localhost:7531 in your browser
87+
# Default credentials: admin / lumo
88+
89+
# Enable authentication for the REST API
90+
lumo config:server auth enable
8691
```
8792

8893
**For complete usage documentation and examples, visit [getlumo.dev/documentation](https://getlumo.dev/documentation)**
8994

95+
**For information about the authentication system, see [Authentication Documentation](docs/authentication.md)**
96+
9097

9198
## 🛠️ Development
9299

docs/authentication.md

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
# Lumo Authentication System
2+
3+
This document provides detailed information about Lumo's authentication system for the REST API.
4+
5+
## Overview
6+
7+
Lumo's REST API includes a robust authentication system that protects all endpoints from unauthorized access. The authentication system uses JWT (JSON Web Tokens) for secure, stateless authentication and includes features like token refresh, password management, and secure credential storage.
8+
9+
## Default Credentials
10+
11+
When the authentication system is first initialized, a default user is created with the following credentials:
12+
13+
- **Username**: `admin`
14+
- **Password**: `lumo`
15+
16+
**Important**: For security reasons, it is strongly recommended to change the default password immediately after the first login.
17+
18+
## Authentication Configuration
19+
20+
You can configure the authentication system using the following commands:
21+
22+
```bash
23+
# Enable authentication for the REST server
24+
lumo config:server auth enable
25+
26+
# Disable authentication for the REST server
27+
lumo config:server auth disable
28+
29+
# Change the default admin password
30+
lumo config:server auth password
31+
```
32+
33+
The authentication settings are stored in the Lumo configuration file (`~/.config/lumo/config.json`) with the following options:
34+
35+
```json
36+
{
37+
"enable_auth": true,
38+
"jwt_secret": "your-secret-key",
39+
"token_expiration_hours": 24,
40+
"refresh_expiration_days": 7
41+
}
42+
```
43+
44+
## Authentication Endpoints
45+
46+
The authentication system provides the following endpoints:
47+
48+
### Login
49+
50+
```bash
51+
# Login to get a JWT token
52+
curl -X POST -H "Content-Type: application/json" \
53+
-d '{"username":"admin","password":"lumo"}' \
54+
http://localhost:7531/api/v1/auth/login
55+
```
56+
57+
Response:
58+
59+
```json
60+
{
61+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
62+
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
63+
"username": "admin",
64+
"expires_in": 86400
65+
}
66+
```
67+
68+
### Refresh Token
69+
70+
```bash
71+
# Refresh an expired token
72+
curl -X POST -H "Content-Type: application/json" \
73+
-d '{"refresh_token":"your-refresh-token"}' \
74+
http://localhost:7531/api/v1/auth/refresh
75+
```
76+
77+
Response:
78+
79+
```json
80+
{
81+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
82+
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
83+
"username": "admin",
84+
"expires_in": 86400
85+
}
86+
```
87+
88+
### Change Password
89+
90+
```bash
91+
# Change password (requires authentication)
92+
curl -X POST -H "Content-Type: application/json" \
93+
-H "Authorization: Bearer your-jwt-token" \
94+
-d '{"current_password":"lumo","new_password":"new-secure-password"}' \
95+
http://localhost:7531/api/v1/auth/change-password
96+
```
97+
98+
Response:
99+
100+
```json
101+
{
102+
"success": true,
103+
"message": "Password updated successfully"
104+
}
105+
```
106+
107+
## Using Authentication with API Endpoints
108+
109+
All API endpoints (except for `/ping` and `/api/v1/status`) require authentication when the authentication system is enabled. To authenticate, include the JWT token in the `Authorization` header:
110+
111+
```bash
112+
# Execute a command with authentication
113+
curl -X POST -H "Content-Type: application/json" \
114+
-H "Authorization: Bearer your-jwt-token" \
115+
-d '{"command":"What is the capital of France?"}' \
116+
http://localhost:7531/api/v1/execute
117+
```
118+
119+
## Web Interface Authentication
120+
121+
The web interface includes a login page that authenticates the user using the same credentials as the API. After successful authentication, the web interface stores the JWT token in the browser's localStorage and includes it in all API requests.
122+
123+
## Security Considerations
124+
125+
1. **Change Default Password**: Always change the default password immediately after the first login.
126+
2. **Secure JWT Secret**: The JWT secret is automatically generated on first run, but you can set a custom secret in the configuration file.
127+
3. **Token Expiration**: Tokens expire after 24 hours by default, but you can configure the expiration time in the configuration file.
128+
4. **HTTPS**: For production use, it's recommended to use HTTPS to encrypt the communication between the client and the server.
129+
5. **Firewall**: Configure your firewall to restrict access to the Lumo server port (7531 by default).
130+
131+
## Credential Storage
132+
133+
User credentials are stored locally in the `~/.config/lumo/credentials.json` file. Passwords are securely hashed using bcrypt with a cost factor of 12.
134+
135+
## Implementation Details
136+
137+
The authentication system is implemented using the following components:
138+
139+
1. **JWT Tokens**: JSON Web Tokens are used for stateless authentication.
140+
2. **Bcrypt**: Passwords are hashed using bcrypt with a cost factor of 12.
141+
3. **Middleware**: All API endpoints are protected by an authentication middleware.
142+
4. **Local Storage**: Credentials are stored locally in the user's config directory.
143+
5. **Token Refresh**: Refresh tokens are used to obtain new access tokens without requiring the user to log in again.
144+
145+
## Troubleshooting
146+
147+
If you encounter authentication issues, try the following:
148+
149+
1. **Check Credentials**: Verify that you're using the correct username and password.
150+
2. **Check Token Expiration**: Tokens expire after 24 hours by default. Use the refresh token to obtain a new token.
151+
3. **Check Server Status**: Make sure the Lumo server is running.
152+
4. **Check Authentication Status**: Verify that authentication is enabled using `lumo config:server show`.
153+
5. **Reset Credentials**: If you've forgotten your password, you can reset the credentials by deleting the `~/.config/lumo/credentials.json` file. This will recreate the default user on the next server start.
154+
155+
## Examples
156+
157+
### Python Example
158+
159+
```python
160+
import requests
161+
import json
162+
163+
# Base URL for the Lumo REST API
164+
base_url = "http://localhost:7531"
165+
166+
# Login to get authentication tokens
167+
login_payload = {
168+
"username": "admin",
169+
"password": "lumo" # Replace with your actual password
170+
}
171+
login_response = requests.post(
172+
f"{base_url}/api/v1/auth/login",
173+
headers={"Content-Type": "application/json"},
174+
data=json.dumps(login_payload)
175+
)
176+
auth_data = login_response.json()
177+
token = auth_data["token"]
178+
refresh_token = auth_data["refresh_token"]
179+
print(f"Logged in as: {auth_data['username']}")
180+
181+
# Execute a command with authentication
182+
payload = {
183+
"command": "What is the capital of France?"
184+
}
185+
response = requests.post(
186+
f"{base_url}/api/v1/execute",
187+
headers={
188+
"Content-Type": "application/json",
189+
"Authorization": f"Bearer {token}"
190+
},
191+
data=json.dumps(payload)
192+
)
193+
print("Response:", response.json()["output"])
194+
```
195+
196+
### JavaScript Example
197+
198+
```javascript
199+
// Login to get authentication tokens
200+
async function login(username, password) {
201+
const response = await fetch('http://localhost:7531/api/v1/auth/login', {
202+
method: 'POST',
203+
headers: {
204+
'Content-Type': 'application/json'
205+
},
206+
body: JSON.stringify({ username, password })
207+
});
208+
209+
if (!response.ok) {
210+
throw new Error('Login failed');
211+
}
212+
213+
return await response.json();
214+
}
215+
216+
// Execute a command with authentication
217+
async function executeCommand(token, command) {
218+
const response = await fetch('http://localhost:7531/api/v1/execute', {
219+
method: 'POST',
220+
headers: {
221+
'Content-Type': 'application/json',
222+
'Authorization': `Bearer ${token}`
223+
},
224+
body: JSON.stringify({ command })
225+
});
226+
227+
if (!response.ok) {
228+
throw new Error('Command execution failed');
229+
}
230+
231+
return await response.json();
232+
}
233+
234+
// Usage example
235+
async function main() {
236+
try {
237+
const auth = await login('admin', 'lumo');
238+
console.log(`Logged in as: ${auth.username}`);
239+
240+
const result = await executeCommand(auth.token, 'What is the capital of France?');
241+
console.log('Response:', result.output);
242+
} catch (error) {
243+
console.error('Error:', error.message);
244+
}
245+
}
246+
247+
main();
248+
```

0 commit comments

Comments
 (0)