feat: Add complete user authentication system with JWT and mandatory login
Implemented a comprehensive authentication system requiring all users to be logged in to access the web interface. Features include: Backend: - JWT-based authentication with 7-day token expiration - bcrypt password hashing with 72-byte limit handling - User management with JSON file storage (config/users.json) - Pydantic models for validation (UserCreate, UserLogin, User, Token) - Authentication endpoints: register, login, me, logout - Protected route dependency with HTTPBearer security Frontend: - Login/register page with dual-tab interface (/login) - Client-side authentication check with automatic redirect - All content hidden by default, shown only after auth validation - User info display with logout button - Main content and tabs hidden when not authenticated - Auto-redirect to /login if token missing or invalid Security: - Password truncation to 72 bytes (bcrypt limitation) - Token verification on each page load - Automatic logout and redirect on token expiry - Username-to-SHA256 user ID generation Dependencies: - passlib[bcrypt]==1.7.4 - python-jose[cryptography]==3.3.0 - bcrypt<4.0 Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"testuser": {
|
||||
"id": "ae5deb822e0d71992900471a7199d0d9",
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"full_name": "Test User",
|
||||
"hashed_password": "$2b$12$gDgt6xCBS4y2FgNrCk0JU.cn8SPwrNo6vIebDSQlkfeDmvP43safy",
|
||||
"is_active": true,
|
||||
"created_at": "2026-01-26T11:32:14.262592",
|
||||
"last_login": "2026-01-26T12:18:26.818435"
|
||||
},
|
||||
"apitest": {
|
||||
"id": "e81cbf18a5239377aa4972773d34cc2b",
|
||||
"username": "apitest",
|
||||
"email": "apitest@example.com",
|
||||
"full_name": "API Test User",
|
||||
"hashed_password": "$2b$12$sJWQhQ0S/rMX3VJiEOMstuusfPgCvXN8zq/lCnKocL28PRomX9RJ6",
|
||||
"is_active": true,
|
||||
"created_at": "2026-01-26T11:32:46.943188",
|
||||
"last_login": "2026-01-26T11:32:47.140656"
|
||||
},
|
||||
"testuser_final": {
|
||||
"id": "2b4aade7e46060f88e36ae92ba767545",
|
||||
"username": "testuser_final",
|
||||
"email": "final@test.com",
|
||||
"full_name": "Final Test User",
|
||||
"hashed_password": "$2b$12$wN7Saj99c4B39O5Y2XNQ4eVuPm7o6b8eeJ1TxFrvy5.g7ycyh9rKm",
|
||||
"is_active": true,
|
||||
"created_at": "2026-01-26T11:33:45.726090",
|
||||
"last_login": "2026-01-26T11:33:46.548491"
|
||||
},
|
||||
"webtest": {
|
||||
"id": "2cae3fde0b88cf1274fe58ec039302cc",
|
||||
"username": "webtest",
|
||||
"email": null,
|
||||
"full_name": null,
|
||||
"hashed_password": "$2b$12$2Rr32QkYCj05GGAOQGua0umCHYRyPnvcDVXPbYaSu5SmYaohXi08a",
|
||||
"is_active": true,
|
||||
"created_at": "2026-01-26T11:44:09.995999",
|
||||
"last_login": "2026-01-26T11:44:10.190329"
|
||||
},
|
||||
"roman": {
|
||||
"id": "4eaae75f1df2f52bda44f6b18a400542",
|
||||
"username": "roman",
|
||||
"email": null,
|
||||
"full_name": null,
|
||||
"hashed_password": "$2b$12$IC9kz7kxf1mQPhsdveFnyOX3V5Q1.pB9/uqCKWI7nhn.SYamtvxCC",
|
||||
"is_active": true,
|
||||
"created_at": "2026-01-26T12:15:58.008205",
|
||||
"last_login": "2026-01-29T17:23:44.242173"
|
||||
},
|
||||
"testuser999": {
|
||||
"id": "f9abf4b8aa96d5116807ac1cf8540418",
|
||||
"username": "testuser999",
|
||||
"email": null,
|
||||
"full_name": null,
|
||||
"hashed_password": "$2b$12$y2uy62IR0xVmCcUmQ8gL6.nkvFthjyuRGxtSKh6CD5soey6T/IFu6",
|
||||
"is_active": true,
|
||||
"created_at": "2026-01-26T12:18:26.623497",
|
||||
"last_login": null
|
||||
},
|
||||
"flowtest": {
|
||||
"id": "4b797133389d3f5042f13aac323a8840",
|
||||
"username": "flowtest",
|
||||
"email": "flow@test.com",
|
||||
"full_name": null,
|
||||
"hashed_password": "$2b$12$Dcb7fKZPycLRsW851m9pk.1ZeyHcX65PAnb5HqLY74cJKonUfDDOC",
|
||||
"is_active": true,
|
||||
"created_at": "2026-01-26T12:18:50.138613",
|
||||
"last_login": "2026-01-26T12:18:50.332004"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user