feat(ui): 🎉 More ui work
* 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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user