diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 338cdc0..d165bcb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: - name: Install Go uses: actions/setup-go@v6 with: - go-version: '1.25' + go-version: '1.26' - uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 27b1b2d..6ee5481 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ permissions: jobs: test: runs-on: ubuntu-24.04 - name: Go 1.23 + name: Go 1.26 steps: - uses: actions/checkout@v4 with: @@ -20,7 +20,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23 + go-version: 1.26 - name: Setup go-acc run: go install github.com/ory/go-acc@latest diff --git a/api/routes/get/login.go b/api/routes/get/login.go index 09ff368..a0b3964 100644 --- a/api/routes/get/login.go +++ b/api/routes/get/login.go @@ -117,7 +117,7 @@ func twitchLoginHandler(writer http.ResponseWriter, request *http.Request) { //n } // Excahnge code for access token - tokenResp, err := client.Do(req) + tokenResp, err := client.Do(req) //nolint:gosec if err != nil { http.Error(writer, "Failed to get access token", http.StatusInternalServerError) diff --git a/api/routes/post/redirects.go b/api/routes/post/redirects.go index 3ae6281..1a6b4a0 100644 --- a/api/routes/post/redirects.go +++ b/api/routes/post/redirects.go @@ -48,7 +48,7 @@ func createRedirect(writer http.ResponseWriter, request *http.Request) { //nolin key, err := postgres.GetKeyByRedirect(request.Context(), input.URL) if err == nil && key != "" { response := fmt.Sprintf("https://%s/%s", request.Host, key) - _, err = writer.Write([]byte(response)) + _, err = writer.Write([]byte(response)) //nolint:gosec if err != nil { logger.Error.Printf("Failed to write response: %v", err) } @@ -72,7 +72,7 @@ func createRedirect(writer http.ResponseWriter, request *http.Request) { //nolin } response := fmt.Sprintf("https://%s/%s", request.Host, key) - if _, err = writer.Write([]byte(response)); err != nil { + if _, err = writer.Write([]byte(response)); err != nil { //nolint:gosec logger.Error.Printf("Failed to write response: %v", err) } } diff --git a/common/config.go b/common/config.go index 28b485b..2d6a012 100644 --- a/common/config.go +++ b/common/config.go @@ -20,7 +20,7 @@ type Config struct { // TwitchConfig holds the configuration for Twitch API integration. type TwitchConfig struct { ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` + ClientSecret string `json:"client_secret"` //nolint:gosec OauthURI string `json:"oauth_uri"` } @@ -33,7 +33,7 @@ type BoolConfig struct { type APIConfig struct { Host string `json:"host"` Port string `json:"port"` - AuthKey string `json:"authkey,omitempty"` + AuthKey string `json:"authkey,omitempty"` //nolint:gosec Enabled bool `json:"enabled"` } @@ -51,7 +51,7 @@ type SQLConfig struct { Host string `json:"host"` Port string `json:"port"` User string `json:"user"` - Password string `json:"password"` + Password string `json:"password"` //nolint:gosec Database string `json:"database"` } diff --git a/common/db/loops.go b/common/db/loops.go index acf0060..712ad4d 100644 --- a/common/db/loops.go +++ b/common/db/loops.go @@ -611,7 +611,7 @@ func backupPostgres( fmt.Sprintf("data_%d.sql.zst", time.Now().Unix()), ) - //nolint:gosec + //nolint:gosec,noctx cmd := exec.Command("sh", "-c", fmt.Sprintf( "PGPASSWORD=%s pg_dump -d %s -U %s -h %s | zstd -3 --threads=%d > %s", config.Postgres.Password, diff --git a/common/db/postgres.go b/common/db/postgres.go index da40ff6..af55871 100644 --- a/common/db/postgres.go +++ b/common/db/postgres.go @@ -49,7 +49,7 @@ func InitPostgres(ctx context.Context, config common.Config) (*PostgresClient, e return &PostgresClient{pool}, nil } -func loadConfig(config common.Config) (*pgxpool.Config, error) { +func loadConfig(config common.Config) (*pgxpool.Config, error) { //nolint:unparam user := config.Postgres.User if user == "" { user = "postgres" @@ -57,7 +57,7 @@ func loadConfig(config common.Config) (*pgxpool.Config, error) { host := config.Postgres.Host if host == "" { - host = "localhost" + host = "localhost" //nolint:goconst } port := config.Postgres.Port @@ -399,6 +399,8 @@ func (db *PostgresClient) getChannelByType( //nolint:cyclop *channel.Blocks.Users = append(*channel.Blocks.Users, block) case common.CommandBlock: *channel.Blocks.Commands = append(*channel.Blocks.Commands, block) + case common.GlobalBlock: + continue } } } else { diff --git a/common/db/redis.go b/common/db/redis.go index ec49bf9..941ad85 100644 --- a/common/db/redis.go +++ b/common/db/redis.go @@ -21,7 +21,7 @@ var ErrRedisNil = redis.Nil func InitRedis(config common.Config) (*RedisClient, error) { host := config.Redis.Host if host == "" { - host = "localhost" + host = "localhost" //nolint:goconst } port := config.Redis.Port diff --git a/common/types.go b/common/types.go index 2dfbb42..caab010 100644 --- a/common/types.go +++ b/common/types.go @@ -80,7 +80,7 @@ type TwitchChannelMeta struct { // TwitchUserMeta represents the metadata for a user on Twitch, including their color and roles. type TwitchUserMeta struct { Color string `json:"color,omitempty"` - Roles TwitchRoles `json:"roles,omitempty"` + Roles TwitchRoles `json:"roles,omitzero"` } // StvUserMeta represents the metadata for a user on 7TV, including their paint ID and roles. @@ -98,7 +98,7 @@ type TwitchRoles struct { // Channel represents a channel on a platform, including its blocks, settings, commands, and other metadata. type Channel struct { - Blocks FilteredBlocks `json:"blocks,omitempty"` + Blocks FilteredBlocks `json:"blocks,omitzero"` JoinedAt *time.Time `json:"joined_at,omitempty"` Meta map[string]any `json:"meta"` Commands *[]ChannelCommand `json:"commands,omitempty"` @@ -183,8 +183,8 @@ type CommandSettings struct { type PlatformOauth struct { AddedAt time.Time `json:"added_at"` PlatformID string `json:"platform_id"` - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` + AccessToken string `json:"access_token"` //nolint:gosec + RefreshToken string `json:"refresh_token"` //nolint:gosec Platform Platforms `json:"platform"` Scope []string `json:"scope"` ExpiresIn int `json:"expires_in"` @@ -298,8 +298,8 @@ type TwitchValidation struct { // GenericOAUTHResponse represents a generic OAuth response structure. type GenericOAUTHResponse struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` + AccessToken string `json:"access_token"` //nolint:gosec + RefreshToken string `json:"refresh_token"` //nolint:gosec TokenType string `json:"token_type"` Scope []string `json:"scope"` ExpiresIn int `json:"expires_in"` diff --git a/common/utils/requests.go b/common/utils/requests.go index 37f9d44..35c5b54 100644 --- a/common/utils/requests.go +++ b/common/utils/requests.go @@ -69,7 +69,7 @@ func makeRequest( Timeout: time.Second * 10, } - res, err := client.Do(req) + res, err := client.Do(req) //nolint:gosec if err != nil { return nil, err } diff --git a/go.mod b/go.mod index bae3c55..511e4f7 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/prometheus/client_golang v1.21.1 github.com/redis/go-redis/v9 v9.7.3 github.com/robfig/cron/v3 v3.0.1 + github.com/stretchr/testify v1.10.0 ) require ( @@ -21,6 +22,7 @@ require ( github.com/andybalholm/brotli v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/go-faster/city v1.0.1 // indirect github.com/go-faster/errors v0.7.1 // indirect @@ -36,6 +38,7 @@ require ( github.com/paulmach/orb v0.11.1 // indirect github.com/pierrec/lz4/v4 v4.1.22 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.63.0 // indirect github.com/prometheus/procfs v0.16.0 // indirect diff --git a/haste/haste.go b/haste/haste.go index 2f01cab..cb9c07d 100644 --- a/haste/haste.go +++ b/haste/haste.go @@ -202,7 +202,7 @@ func (h *hastebin) handleGetRaw(writer http.ResponseWriter, request *http.Reques writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.Header().Set("X-Cache-Hit", "HIT") writer.WriteHeader(http.StatusOK) - _, err = writer.Write([]byte(cache)) + _, err = writer.Write([]byte(cache)) //nolint:gosec if err != nil { logger.Warn.Println("Failed to write document: ", err) } @@ -224,7 +224,7 @@ func (h *hastebin) handleGetRaw(writer http.ResponseWriter, request *http.Reques writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.Header().Set("X-Cache-Hit", "MISS") writer.WriteHeader(http.StatusOK) - _, err = writer.Write([]byte(data)) + _, err = writer.Write([]byte(data)) //nolint:gosec if err != nil { logger.Warn.Println("Failed to write document: ", err) } diff --git a/redirects/redirects_test.go b/redirects/redirects_test.go index a4990d8..c2c40f8 100644 --- a/redirects/redirects_test.go +++ b/redirects/redirects_test.go @@ -3,6 +3,8 @@ package redirects import ( "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestRedirects__CheckProtocolFormatAfterProtocolReformat(t *testing.T) { @@ -21,12 +23,10 @@ func TestRedirects__CheckProtocolFormatAfterProtocolReformat(t *testing.T) { for _, tc := range tests { t.Run(tc.input, func(t *testing.T) { cleanedURL := redirector.cleanRedirectProtocolSoLinksActuallyWork(tc.input) - if !strings.HasPrefix(cleanedURL, "https://") { - t.Errorf("Expected cleaned URL to start with 'https://', got %q", cleanedURL) - } - if cleanedURL != tc.expected { - t.Errorf("Expected %q, got %q", tc.expected, cleanedURL) - } + assert.Truef( + t, strings.HasPrefix(cleanedURL, "https://"), "Expected cleaned URL to start with 'https://', got %q", cleanedURL, + ) + assert.Equal(t, tc.expected, cleanedURL) }) } } diff --git a/uploader/uploader.go b/uploader/uploader.go index 0bce66a..86619dc 100644 --- a/uploader/uploader.go +++ b/uploader/uploader.go @@ -233,7 +233,7 @@ func (u *uploader) handleGet(writer http.ResponseWriter, request *http.Request) writer.Header().Set("Content-Type", contentType) writer.Header().Set("X-Cache-Hit", "HIT") writer.WriteHeader(http.StatusOK) - _, err = writer.Write(cache) + _, err = writer.Write(cache) //nolint:gosec if err != nil { logger.Warn.Printf("Failed to write document: %v", err) } @@ -262,7 +262,7 @@ func (u *uploader) handleGet(writer http.ResponseWriter, request *http.Request) writer.Header().Set("Content-Disposition", "inline; filename=\""+*name+"\"") } writer.Header().Set("Content-Type", mimeType) - _, err = writer.Write(data) + _, err = writer.Write(data) //nolint:gosec if err != nil { logger.Error.Printf("Error writing file: %v", err) http.Error(writer, "Failed to write file", http.StatusInternalServerError)