package repository import ( "database/sql" "fmt" "time" "devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/api/models" "devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/database" ) // DBUser represents a user from the database type DBUser struct { UserID int `db:"UserID"` UserEmail string `db:"UserEmail"` UserPassword string `db:"UserPassword"` UserRole string `db:"UserRole"` UserName string `db:"UserName"` UserCreatedAt time.Time `db:"UserCreatedAt"` UserUpdatedAt time.Time `db:"UserUpdatedAt"` } // DBRefreshToken represents a refresh token from the database type DBRefreshToken struct { ID int `db:"id"` Token string `db:"token"` UserID string `db:"user_id"` ExpiresAt time.Time `db:"expires_at"` IsRevoked bool `db:"is_revoked"` CreatedAt time.Time `db:"created_at"` } // UserRepository handles database operations related to users type UserRepository struct { *Repository } // NewUserRepository creates a new user repository func NewUserRepository() *UserRepository { return &UserRepository{ Repository: NewRepository(), } } // ToUser converts a DBUser to a User model func (u *DBUser) ToUser() *models.User { return &models.User{ ID: fmt.Sprintf("%d", u.UserID), Email: u.UserEmail, Password: u.UserPassword, Role: u.UserRole, Name: u.UserName, CreatedAt: u.UserCreatedAt.Format(time.RFC3339), UpdatedAt: u.UserUpdatedAt.Format(time.RFC3339), } } // GetUserByEmail retrieves a user by email func (r *UserRepository) GetUserByEmail(email string) (*models.User, error) { var dbUser DBUser query := `SELECT * FROM user WHERE UserEmail = ?` err := database.DB.Get(&dbUser, query, email) if err != nil { if err == sql.ErrNoRows { return nil, nil } return nil, fmt.Errorf("database error getting user by email: %w", err) } return dbUser.ToUser(), nil } // GetUserByID retrieves a user by ID func (r *UserRepository) GetUserByID(id string) (*models.User, error) { var dbUser DBUser query := `SELECT * FROM user WHERE UserID = ?` err := database.DB.Get(&dbUser, query, id) if err != nil { if err == sql.ErrNoRows { return nil, nil } return nil, fmt.Errorf("database error getting user by ID: %w", err) } return dbUser.ToUser(), nil } // StoreRefreshToken saves a refresh token to the database func (r *UserRepository) StoreRefreshToken(userID string, token string, expiresAt time.Time) error { query := `INSERT INTO refresh_tokens (token, user_id, expires_at, is_revoked, created_at) VALUES (?, ?, ?, false, NOW())` _, err := database.DB.Exec(query, token, userID, expiresAt) if err != nil { return fmt.Errorf("database error storing refresh token: %w", err) } return nil } // GetRefreshToken retrieves a refresh token from the database func (r *UserRepository) GetRefreshToken(token string) (*models.RefreshToken, error) { var dbToken DBRefreshToken query := `SELECT * FROM refresh_tokens WHERE token = ?` err := database.DB.Get(&dbToken, query, token) if err != nil { if err == sql.ErrNoRows { return nil, nil } return nil, fmt.Errorf("database error getting refresh token: %w", err) } return &models.RefreshToken{ ID: fmt.Sprintf("%d", dbToken.ID), UserID: dbToken.UserID, Token: dbToken.Token, ExpiresAt: dbToken.ExpiresAt.Format(time.RFC3339), IsRevoked: dbToken.IsRevoked, CreatedAt: dbToken.CreatedAt.Format(time.RFC3339), }, nil } // RevokeRefreshToken marks a refresh token as revoked func (r *UserRepository) RevokeRefreshToken(token string) error { query := `UPDATE refresh_tokens SET is_revoked = true WHERE token = ?` _, err := database.DB.Exec(query, token) if err != nil { return fmt.Errorf("database error revoking refresh token: %w", err) } return nil }