Skip to content

fix(linters): add golangci-lint configuration and update logging permissions#25

Merged
adcondev merged 1 commit into
ci/ghfrom
fix/lint
Feb 12, 2026
Merged

fix(linters): add golangci-lint configuration and update logging permissions#25
adcondev merged 1 commit into
ci/ghfrom
fix/lint

Conversation

@adcondev

Copy link
Copy Markdown
Owner

This pull request introduces several improvements to code structure, security, and dependency management for the scale daemon project. The most important changes include the addition of a comprehensive golangci-lint configuration, enhanced log file security, improved error handling, and a switch to a new WebSocket library. Additionally, package-level documentation comments have been added for clarity, and several dependencies have been removed or replaced.

Linting and CI Improvements:

  • Added a detailed .golangci.yml configuration to enforce best practices, security checks, and modern Go idioms across the codebase. The CI workflow now uses this config and sets a 5-minute timeout for linting. [1] [2]

Logging and Security Enhancements:

  • Changed log file and directory permissions from world-readable to user-only (0750 for directories, 0600 for files) to improve security. (Fd8cca64L77R77, Fd8cca64L91R91, Fd8cca64L149R149, F12eec34L32R32, F12eec34L106R106)
  • Introduced a secureFilepath function in internal/logging/loaders.go to prevent directory traversal attacks when accessing log files.
  • Updated log file reading and closing logic to use secure paths and improved error handling. (F12eec34L32R32)

Dependency and WebSocket Changes:

  • Replaced the nhooyr.io/websocket library with github.com/coder/websocket, and removed several unused dependencies from go.mod. [1] [2] F43a394bL12R12)
  • Renamed internal/server/handler.go to internal/server/server.go for clarity and consistency.

Error Handling and Code Quality:

  • Improved error handling by using errors.Is for more robust comparisons in multiple places, including WebSocket and HTTP server shutdown scenarios. (internal/daemon/program.goR1-R625, Fef23d11R206, F43a394bL157R157)
  • Updated several handler functions to ignore unused request parameters and clarified their purpose. (F43a394bL240R240, F43a394bL251R251)

Documentation and Code Structure:

  • Added package-level documentation comments to all major packages for clarity and maintainability. [1] [2] [3] [4] [5] [6] [7]

These changes collectively improve the security, maintainability, and reliability of the project.

…issions

Signed-off-by: Adrián Constante <ad_con.reload@proton.me>
@adcondev adcondev added the enhancement New feature or request label Feb 12, 2026
Copilot AI review requested due to automatic review settings February 12, 2026 20:07
@adcondev adcondev moved this to In progress in POS RED2000 Feb 12, 2026
@github-actions

Copy link
Copy Markdown

👋 Thanks for opening this PR, @adcondev!

Here's what will happen next:

  • 🤖 Automated checks will run
  • 🏷️ Labels will be added automatically
  • 👀 A maintainer will review your changes

Please make sure:

  • ✅ All tests pass
  • 📝 Code follows project conventions
  • 📋 Changes are well documented

@adcondev adcondev merged commit 1cca0a3 into ci/gh Feb 12, 2026
7 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in POS RED2000 Feb 12, 2026
@adcondev adcondev deleted the fix/lint branch February 12, 2026 20:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR strengthens project hygiene and security by formalizing linting rules, tightening log-file permissions, and migrating the WebSocket implementation to a new library.

Changes:

  • Add .golangci.yml and update CI lint job to use it with a 5-minute timeout.
  • Harden logging by restricting directory/file permissions and adding secure path handling for log reads.
  • Replace nhooyr.io/websocket with github.com/coder/websocket and clean up module dependencies.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/server/server.go Switch WebSocket imports; improve error handling and handler signatures.
internal/server/broadcaster.go Switch WebSocket imports to github.com/coder/websocket.
internal/scale/scale.go Add package docs, constants docs, errors.Is usage, and gosec suppressions for simulated randomness.
internal/logging/logging.go Tighten log dir/file permissions to 0750/0600.
internal/logging/rotation.go Tighten write permissions; add secure log read path usage and close-error logging.
internal/logging/loaders.go Add secureFilepath helper for traversal-resistant log access.
internal/daemon/program.go Add package docs; use errors.Is for http.ErrServerClosed.
internal/config/config.go Add package-level documentation comment.
.golangci.yml Introduce golangci-lint configuration (enabled linters + runtime settings).
.github/workflows/ci.yml Update golangci-lint action invocation to use repo config and timeout args.
go.mod / go.sum Replace websocket dependency and remove unused modules.
embed.go Add package docs and remove redundant blank import.
cmd/BasculaServicio/main.go Add package-level documentation comment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +5 to +6
_ "image/jpeg" // Register JPEG decoder
_ "image/png" // Register PNG decoder

Copilot AI Feb 12, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

secureFilepath includes blank imports for image/jpeg and image/png, but this file only does path validation and never decodes images. These imports add unnecessary dependencies and init-time work; remove them unless they’re needed elsewhere in the logging package (in which case they should live next to the image-decoding code).

Suggested change
_ "image/jpeg" // Register JPEG decoder
_ "image/png" // Register PNG decoder

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +37
// Ensure target is inside base directory
if targetAbs != baseAbs && !strings.HasPrefix(targetAbs, baseAbs+string(os.PathSeparator)) {
return "", fmt.Errorf("file %s is outside allowed directory", relPath)
}

Copilot AI Feb 12, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The directory-traversal check uses strings.HasPrefix(targetAbs, baseAbs+string(os.PathSeparator)), which is fragile on Windows/macOS due to case-insensitive paths and path normalization (and is a common footgun for path containment checks). Consider using filepath.Rel(baseAbs, targetAbs) and rejecting any relative path that starts with .. (and also ensure both paths are on the same volume on Windows) to make the containment check robust.

Suggested change
// Ensure target is inside base directory
if targetAbs != baseAbs && !strings.HasPrefix(targetAbs, baseAbs+string(os.PathSeparator)) {
return "", fmt.Errorf("file %s is outside allowed directory", relPath)
}
// Ensure target is inside base directory using a robust relative-path check
rel, err := filepath.Rel(baseAbs, targetAbs)
if err != nil {
return "", fmt.Errorf("file %s is outside allowed directory", relPath)
}
if rel != "." && (rel == ".." || strings.HasPrefix(rel, ".."+string(os.PathSeparator))) {
return "", fmt.Errorf("file %s is outside allowed directory", relPath)
}

Copilot uses AI. Check for mistakes.
Comment thread internal/scale/scale.go
Comment on lines +209 to 216
switch {
case errors.Is(err, io.EOF):
log.Printf("[!] %s: %s", ErrorDescriptions[ErrEOF], conf.Puerto)
r.sendError(ErrEOF)
} else if strings.Contains(err.Error(), "timeout") {
case strings.Contains(err.Error(), "timeout"):
log.Printf("[~] %s: %s. Reintentando...", ErrorDescriptions[ErrTimeout], conf.Puerto)
r.sendError(ErrTimeout)
continue

Copilot AI Feb 12, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On io.EOF the code sends ErrEOF but keeps the serial port open and immediately continues the read loop. If EOF indicates a disconnected/closed device (as the error description suggests), this can result in repeated EOF errors without triggering a reconnect. Consider closing the port and breaking out of the read loop on EOF (similar to the write-error path) so the outer cycle can reconnect after RetryDelay.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size/M

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants