feat(ui): 🎉 More ui work
Some checks failed
CI / Test (1.23) (push) Failing after -22m35s
CI / Test (1.22) (push) Failing after -22m33s
CI / Build (push) Failing after -23m42s
CI / Lint (push) Failing after -23m17s

* Implement EventLogsPage for viewing system activity logs with search and filter capabilities.
* Create HooksPage for managing webhook configurations with create, edit, and delete functionalities.
* Develop LoginPage for user authentication with error handling and loading states.
* Add UsersPage for managing system users, including role assignment and status toggling.
* Introduce authStore for managing user authentication state and actions.
* Define TypeScript types for User, Hook, EventLog, and other entities.
* Set up TypeScript configuration for the project.
* Configure Vite for development with proxy settings for API calls.
* Update dependencies for improved functionality and security.
This commit is contained in:
Hein
2026-02-05 19:41:49 +02:00
parent f9773bd07f
commit 8b1eed6c42
32 changed files with 7293 additions and 38 deletions

View File

@@ -35,14 +35,14 @@ func NewSecurityProvider(jwtSecret string, db *bun.DB, cfg *config.Config) secur
// Claims represents JWT claims
type Claims struct {
UserID int `json:"user_id"`
UserID string `json:"user_id"` // Changed from int to string for UUID support
Username string `json:"username"`
Role string `json:"role"`
jwt.RegisteredClaims
}
// GenerateToken generates a JWT token
func (sp *SecurityProvider) GenerateToken(userID int, username, role string) (string, error) {
func (sp *SecurityProvider) GenerateToken(userID string, username, role string) (string, error) {
expirationTime := time.Now().Add(24 * time.Hour)
claims := &Claims{
@@ -54,7 +54,7 @@ func (sp *SecurityProvider) GenerateToken(userID int, username, role string) (st
IssuedAt: jwt.NewNumericDate(time.Now()),
NotBefore: jwt.NewNumericDate(time.Now()),
Issuer: "whatshooked",
Subject: fmt.Sprintf("%d", userID),
Subject: userID,
},
}
@@ -101,19 +101,20 @@ func (sp *SecurityProvider) Login(ctx context.Context, req security.LoginRequest
}
// Generate JWT token
token, err := sp.GenerateToken(int(user.ID.Int64()), req.Username, user.Role.String())
token, err := sp.GenerateToken(user.ID.String(), req.Username, user.Role.String())
if err != nil {
return nil, fmt.Errorf("failed to generate token: %w", err)
}
// Build user context
userCtx := &security.UserContext{
UserID: int(user.ID.Int64()),
UserID: 0, // Keep as 0 for compatibility, actual ID is in claims
UserName: req.Username,
Email: user.Email.String(),
Roles: []string{user.Role.String()},
Claims: map[string]any{
"role": user.Role.String(),
"role": user.Role.String(),
"user_id": user.ID.String(), // Store actual UUID here
},
}
@@ -139,15 +140,16 @@ func (sp *SecurityProvider) Authenticate(r *http.Request) (*security.UserContext
claims, err := sp.ValidateToken(token)
if err == nil {
// Get user from database
user, err := sp.userRepo.GetByID(r.Context(), fmt.Sprintf("%d", claims.UserID))
user, err := sp.userRepo.GetByID(r.Context(), claims.UserID)
if err == nil && user.Active {
return &security.UserContext{
UserID: claims.UserID,
UserID: 0, // Keep as 0 for compatibility
UserName: claims.Username,
Email: user.Email.String(),
Roles: []string{user.Role.String()},
Claims: map[string]any{
"role": user.Role.String(),
"role": user.Role.String(),
"user_id": claims.UserID, // Store actual UUID here
},
}, nil
}
@@ -231,6 +233,13 @@ func (sp *SecurityProvider) GetColumnSecurity(ctx context.Context, userID int, s
// GetRowSecurity returns row security rules (implements security.RowSecurityProvider)
func (sp *SecurityProvider) GetRowSecurity(ctx context.Context, userID int, schema, table string) (security.RowSecurity, error) {
// If userID is 0, it's JWT auth with UUID - allow admin access for now
if userID == 0 {
return security.RowSecurity{
Template: "", // Empty template means no filtering (admin access)
}, nil
}
// Get user to check role
user, err := sp.userRepo.GetByID(ctx, fmt.Sprintf("%d", userID))
if err != nil {