fix: resolve user dashboard field mapping and session consistency
Some checks failed
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled

Added JSON tags to the User struct to match frontend expectations and excluded sensitive fields.
Updated session management to include and persist DisplayName.
Unified user field names (using display_name) across backend, sessions, and frontend UI.
This commit is contained in:
2026-03-19 14:01:59 -04:00
parent 0ea2a3a985
commit 0f0486d8d4
4 changed files with 43 additions and 42 deletions

View File

@@ -244,13 +244,13 @@ type ModelConfig struct {
}
type User struct {
ID int `db:"id"`
Username string `db:"username"`
PasswordHash string `db:"password_hash"`
DisplayName *string `db:"display_name"`
Role string `db:"role"`
MustChangePassword bool `db:"must_change_password"`
CreatedAt time.Time `db:"created_at"`
ID int `db:"id" json:"id"`
Username string `db:"username" json:"username"`
PasswordHash string `db:"password_hash" json:"-"`
DisplayName *string `db:"display_name" json:"display_name"`
Role string `db:"role" json:"role"`
MustChangePassword bool `db:"must_change_password" json:"must_change_password"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
}
type ClientToken struct {

View File

@@ -83,25 +83,21 @@ func (s *Server) handleLogin(c *gin.Context) {
return
}
token, err := s.sessions.CreateSession(user.Username, user.Role)
if err != nil {
c.JSON(http.StatusInternalServerError, ErrorResponse("Failed to create session"))
return
}
displayName := user.Username
if user.DisplayName != nil {
displayName = *user.DisplayName
}
token, err := s.sessions.CreateSession(user.Username, displayName, user.Role)
if err != nil {
c.JSON(http.StatusInternalServerError, ErrorResponse("Failed to create session"))
return
}
c.JSON(http.StatusOK, SuccessResponse(gin.H{
"token": token,
"must_change_password": user.MustChangePassword,
"user": gin.H{
"username": user.Username,
"name": displayName,
"role": user.Role,
},
"user": user,
}))
}
@@ -118,6 +114,7 @@ func (s *Server) handleAuthStatus(c *gin.Context) {
"user": gin.H{
"username": session.Username,
"role": session.Role,
"display_name": session.DisplayName,
},
}))
}

View File

@@ -15,6 +15,7 @@ import (
type Session struct {
Username string `json:"username"`
DisplayName string `json:"display_name"`
Role string `json:"role"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
@@ -31,6 +32,7 @@ type SessionManager struct {
type sessionPayload struct {
SessionID string `json:"session_id"`
Username string `json:"username"`
DisplayName string `json:"display_name"`
Role string `json:"role"`
Exp int64 `json:"exp"`
}
@@ -43,7 +45,7 @@ func NewSessionManager(secret []byte, ttl time.Duration) *SessionManager {
}
}
func (m *SessionManager) CreateSession(username, role string) (string, error) {
func (m *SessionManager) CreateSession(username, displayName, role string) (string, error) {
sessionID := uuid.New().String()
now := time.Now()
expiresAt := now.Add(m.ttl)
@@ -51,6 +53,7 @@ func (m *SessionManager) CreateSession(username, role string) (string, error) {
m.mu.Lock()
m.sessions[sessionID] = Session{
Username: username,
DisplayName: displayName,
Role: role,
CreatedAt: now,
ExpiresAt: expiresAt,
@@ -58,13 +61,14 @@ func (m *SessionManager) CreateSession(username, role string) (string, error) {
}
m.mu.Unlock()
return m.createSignedToken(sessionID, username, role, expiresAt.Unix())
return m.createSignedToken(sessionID, username, displayName, role, expiresAt.Unix())
}
func (m *SessionManager) createSignedToken(sessionID, username, role string, exp int64) (string, error) {
func (m *SessionManager) createSignedToken(sessionID, username, displayName, role string, exp int64) (string, error) {
payload := sessionPayload{
SessionID: sessionID,
Username: username,
DisplayName: displayName,
Role: role,
Exp: exp,
}

View File

@@ -167,7 +167,7 @@ class AuthManager {
const userRoleElement = document.querySelector('.user-role');
if (userNameElement && this.user) {
userNameElement.textContent = this.user.name || this.user.username || 'User';
userNameElement.textContent = this.user.display_name || this.user.username || 'User';
}
if (userRoleElement && this.user) {