Merge pull request #211 from CarterPerez-dev/fix/lints

fix: resolve CI lint failures across frontend and Go projects
This commit is contained in:
Carter Perez 2026-05-08 06:45:00 -04:00 committed by GitHub
commit d6c4fb7b4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 829 additions and 787 deletions

View File

@ -123,13 +123,13 @@ jobs:
if: matrix.type == 'biome' if: matrix.type == 'biome'
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20' node-version: '22'
- name: Setup pnpm - name: Setup pnpm
if: matrix.type == 'biome' if: matrix.type == 'biome'
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: latest version: 10
- name: Cache pnpm store - name: Cache pnpm store
if: matrix.type == 'biome' if: matrix.type == 'biome'

View File

@ -0,0 +1,2 @@
strict-dep-builds=false
auto-install-peers=true

View File

@ -0,0 +1,2 @@
strict-dep-builds=false
auto-install-peers=true

View File

@ -3,7 +3,7 @@
FROM node:24-alpine FROM node:24-alpine
RUN corepack enable && corepack prepare pnpm@latest --activate RUN corepack enable && corepack prepare pnpm@10.29.1 --activate
WORKDIR /app WORKDIR /app

View File

@ -3,11 +3,11 @@
FROM node:24-alpine AS build FROM node:24-alpine AS build
RUN corepack enable && corepack prepare pnpm@latest --activate RUN corepack enable && corepack prepare pnpm@10.29.1 --activate
WORKDIR /app WORKDIR /app
COPY frontend/package.json frontend/pnpm-lock.yaml* ./ COPY frontend/package.json frontend/pnpm-lock.yaml* frontend/.npmrc* ./
RUN pnpm install --frozen-lockfile || pnpm install RUN pnpm install --frozen-lockfile || pnpm install

View File

@ -0,0 +1 @@
strict-dep-builds=false

View File

@ -59,6 +59,10 @@
"pnpm": { "pnpm": {
"overrides": { "overrides": {
"vite": "npm:rolldown-vite@7.2.5" "vite": "npm:rolldown-vite@7.2.5"
} },
"onlyBuiltDependencies": [
"@parcel/watcher",
"esbuild"
]
} }
} }

View File

@ -0,0 +1,2 @@
strict-dep-builds=false
auto-install-peers=true

View File

@ -25,6 +25,19 @@ linters:
- testifylint - testifylint
- fatcontext - fatcontext
exclusions:
rules:
- path: _test\.go
linters:
- funlen
- dupl
- goconst
- gosec
paths:
- vendor
- testdata
max-same-issues: 50
settings: settings:
errcheck: errcheck:
check-type-assertions: true check-type-assertions: true
@ -78,24 +91,11 @@ linters:
kv-only: true kv-only: true
context: all context: all
issues:
max-same-issues: 50
exclude-dirs:
- vendor
- testdata
exclude-rules:
- path: _test\.go
linters:
- funlen
- dupl
- goconst
formatters: formatters:
enable: enable:
- gci # Groups imports - gci
- gofumpt # Whitespace - gofumpt
- golines # Vertical wrap - golines
settings: settings:
golines: golines:
max-len: 80 max-len: 80

View File

@ -35,6 +35,13 @@ import (
"github.com/CarterPerez-dev/angela/pkg/types" "github.com/CarterPerez-dev/angela/pkg/types"
) )
const (
severityCritical = "CRITICAL"
severityHigh = "HIGH"
severityModerate = "MODERATE"
severityLow = "LOW"
)
func printDivider() { func printDivider() {
fmt.Printf("\n %s\n", ui.HiBlack(ui.HRule(44))) fmt.Printf("\n %s\n", ui.HiBlack(ui.HRule(44)))
} }
@ -314,13 +321,13 @@ func sortVulnsBySeverity(
func severityRank(sev string) int { func severityRank(sev string) int {
switch strings.ToUpper(sev) { switch strings.ToUpper(sev) {
case "CRITICAL": case severityCritical:
return 0 return 0
case "HIGH": case severityHigh:
return 1 return 1
case "MODERATE": case severityModerate:
return 2 return 2
case "LOW": case severityLow:
return 3 return 3
default: default:
return 4 return 4
@ -336,7 +343,11 @@ func severityBreakdown(
} }
order := []string{ order := []string{
"CRITICAL", "HIGH", "MODERATE", "LOW", "UNKNOWN", severityCritical,
severityHigh,
severityModerate,
severityLow,
"UNKNOWN",
} }
var parts []string var parts []string
@ -520,13 +531,13 @@ func severityColorFn(
sev string, sev string,
) func(a ...any) string { ) func(a ...any) string {
switch strings.ToUpper(sev) { switch strings.ToUpper(sev) {
case "CRITICAL": case severityCritical:
return ui.Red return ui.Red
case "HIGH": case severityHigh:
return ui.RedBold return ui.RedBold
case "MODERATE": case severityModerate:
return ui.HiYellow return ui.HiYellow
case "LOW": case severityLow:
return ui.Cyan return ui.Cyan
default: default:
return ui.HiBlack return ui.HiBlack

View File

@ -43,6 +43,16 @@ const (
vulnEndpoint = "https://api.osv.dev/v1/vulns/" vulnEndpoint = "https://api.osv.dev/v1/vulns/"
userAgent = "angela/0.1.0 (https://github.com/CarterPerez-dev/angela)" userAgent = "angela/0.1.0 (https://github.com/CarterPerez-dev/angela)"
maxHydrate = 15 maxHydrate = 15
ecosystemPyPI = "PyPI"
cvssTypeV3 = "CVSS_V3"
cvssTypeV4 = "CVSS_V4"
sevCritical = "CRITICAL"
sevHigh = "HIGH"
sevModerate = "MODERATE"
sevLow = "LOW"
refTypeWeb = "WEB"
refTypeReport = "REPORT"
) )
// Client queries the OSV.dev API for known vulnerabilities // Client queries the OSV.dev API for known vulnerabilities
@ -161,7 +171,7 @@ func (c *Client) queryBatch(
queries := make([]query, len(packages)) queries := make([]query, len(packages))
for i, p := range packages { for i, p := range packages {
queries[i] = query{ queries[i] = query{
Package: pkg{Name: p.Name, Ecosystem: "PyPI"}, Package: pkg{Name: p.Name, Ecosystem: ecosystemPyPI},
Version: p.Version, Version: p.Version,
} }
} }
@ -346,7 +356,7 @@ func toVulnerability(v *osvVuln) types.Vulnerability {
func extractSeverity(v *osvVuln) string { func extractSeverity(v *osvVuln) string {
for _, s := range v.Severity { for _, s := range v.Severity {
if s.Type != "CVSS_V3" && s.Type != "CVSS_V4" { if s.Type != cvssTypeV3 && s.Type != cvssTypeV4 {
continue continue
} }
@ -374,13 +384,13 @@ func extractSeverity(v *osvVuln) string {
func classifyScore(score float64) string { func classifyScore(score float64) string {
switch { switch {
case score >= 9.0: case score >= 9.0:
return "CRITICAL" return sevCritical
case score >= 7.0: case score >= 7.0:
return "HIGH" return sevHigh
case score >= 4.0: case score >= 4.0:
return "MODERATE" return sevModerate
case score > 0: case score > 0:
return "LOW" return sevLow
default: default:
return "NONE" return "NONE"
} }
@ -388,7 +398,7 @@ func classifyScore(score float64) string {
func extractFixed(affected []affected) string { func extractFixed(affected []affected) string {
for _, a := range affected { for _, a := range affected {
if !strings.EqualFold(a.Package.Ecosystem, "PyPI") { if !strings.EqualFold(a.Package.Ecosystem, ecosystemPyPI) {
continue continue
} }
for _, r := range a.Ranges { for _, r := range a.Ranges {
@ -409,7 +419,7 @@ func extractLink(refs []reference) string {
} }
} }
for _, r := range refs { for _, r := range refs {
if r.Type == "WEB" || r.Type == "REPORT" { if r.Type == refTypeWeb || r.Type == refTypeReport {
return r.URL return r.URL
} }
} }

View File

@ -24,11 +24,11 @@ func TestExtractSeverityCVSSV3(t *testing.T) {
v := &osvVuln{ v := &osvVuln{
Severity: []severity{ Severity: []severity{
{Type: "CVSS_V3", Score: "9.8"}, {Type: cvssTypeV3, Score: "9.8"},
}, },
} }
got := extractSeverity(v) got := extractSeverity(v)
if got != "CRITICAL" { //nolint:goconst if got != sevCritical {
t.Errorf("extractSeverity = %q, want CRITICAL", got) t.Errorf("extractSeverity = %q, want CRITICAL", got)
} }
} }
@ -38,11 +38,11 @@ func TestExtractSeverityCVSSV4(t *testing.T) {
v := &osvVuln{ v := &osvVuln{
Severity: []severity{ Severity: []severity{
{Type: "CVSS_V4", Score: "7.5"}, {Type: cvssTypeV4, Score: "7.5"},
}, },
} }
got := extractSeverity(v) got := extractSeverity(v)
if got != "HIGH" { if got != sevHigh {
t.Errorf("extractSeverity = %q, want HIGH", got) t.Errorf("extractSeverity = %q, want HIGH", got)
} }
} }
@ -53,13 +53,13 @@ func TestExtractSeverityCVSSVector(t *testing.T) {
v := &osvVuln{ v := &osvVuln{
Severity: []severity{ Severity: []severity{
{ {
Type: "CVSS_V3", Type: cvssTypeV3,
Score: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/9.8", Score: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/9.8",
}, },
}, },
} }
got := extractSeverity(v) got := extractSeverity(v)
if got != "CRITICAL" { if got != sevCritical {
t.Errorf("extractSeverity = %q, want CRITICAL", got) t.Errorf("extractSeverity = %q, want CRITICAL", got)
} }
} }
@ -69,11 +69,11 @@ func TestExtractSeverityDatabaseSpecific(t *testing.T) {
v := &osvVuln{ v := &osvVuln{
DatabaseSpecific: map[string]any{ DatabaseSpecific: map[string]any{
"severity": "MODERATE", "severity": sevModerate,
}, },
} }
got := extractSeverity(v) got := extractSeverity(v)
if got != "MODERATE" { if got != sevModerate {
t.Errorf("extractSeverity = %q, want MODERATE", got) t.Errorf("extractSeverity = %q, want MODERATE", got)
} }
} }
@ -95,14 +95,14 @@ func TestClassifyScore(t *testing.T) {
score float64 score float64
want string want string
}{ }{
{9.8, "CRITICAL"}, {9.8, sevCritical},
{9.0, "CRITICAL"}, {9.0, sevCritical},
{8.5, "HIGH"}, {8.5, sevHigh},
{7.0, "HIGH"}, {7.0, sevHigh},
{6.9, "MODERATE"}, {6.9, sevModerate},
{4.0, "MODERATE"}, {4.0, sevModerate},
{3.9, "LOW"}, {3.9, sevLow},
{0.1, "LOW"}, {0.1, sevLow},
{0.0, "NONE"}, {0.0, "NONE"},
} }
@ -154,7 +154,7 @@ func TestExtractFixed(t *testing.T) {
aff := []affected{ aff := []affected{
{ {
Package: pkg{Name: "django", Ecosystem: "PyPI"}, Package: pkg{Name: "django", Ecosystem: ecosystemPyPI},
Ranges: []rng{ Ranges: []rng{
{ {
Type: "ECOSYSTEM", Type: "ECOSYSTEM",
@ -178,7 +178,7 @@ func TestExtractFixedNoFix(t *testing.T) {
aff := []affected{ aff := []affected{
{ {
Package: pkg{Name: "django", Ecosystem: "PyPI"}, Package: pkg{Name: "django", Ecosystem: ecosystemPyPI},
Ranges: []rng{ Ranges: []rng{
{ {
Type: "ECOSYSTEM", Type: "ECOSYSTEM",
@ -198,7 +198,7 @@ func TestExtractLink(t *testing.T) {
t.Parallel() t.Parallel()
refs := []reference{ refs := []reference{
{Type: "WEB", URL: "https://example.com"}, {Type: refTypeWeb, URL: "https://example.com"},
{ {
Type: "ADVISORY", Type: "ADVISORY",
URL: "https://nvd.nist.gov/vuln/detail/CVE-2023-1234", URL: "https://nvd.nist.gov/vuln/detail/CVE-2023-1234",
@ -216,7 +216,7 @@ func TestExtractLinkFallback(t *testing.T) {
refs := []reference{ refs := []reference{
{Type: "PACKAGE", URL: "https://pypi.org/project/django"}, {Type: "PACKAGE", URL: "https://pypi.org/project/django"},
{Type: "WEB", URL: "https://example.com/info"}, {Type: refTypeWeb, URL: "https://example.com/info"},
} }
got := extractLink(refs) got := extractLink(refs)

View File

@ -0,0 +1,2 @@
strict-dep-builds=false
auto-install-peers=true

View File

@ -78,9 +78,9 @@ func (d *Detector) Detect(chunk types.Chunk) []types.Finding { //nolint:gocognit
charset := rules.DetectCharset(secret) charset := rules.DetectCharset(secret)
var charsetStr string var charsetStr string
switch charset { switch charset {
case "hex": case rules.CharsetNameHex:
charsetStr = rules.HexCharset charsetStr = rules.HexCharset
case "base64": case rules.CharsetNameBase64:
charsetStr = rules.Base64Charset charsetStr = rules.Base64Charset
default: default:
charsetStr = rules.AlphanumericCharset charsetStr = rules.AlphanumericCharset

File diff suppressed because it is too large Load Diff

View File

@ -84,8 +84,8 @@ func TestIsPlaceholder(t *testing.T) { //nolint:dupl
secret: "your-api-key", secret: "your-api-key",
want: true, want: true,
}, },
"placeholder": { stopwordPlaceholder: {
secret: "placeholder", secret: stopwordPlaceholder,
want: true, want: true,
}, },
"xxxx pattern": { "xxxx pattern": {

View File

@ -32,6 +32,10 @@ const (
Base64Charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-_" Base64Charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-_"
HexCharset = "0123456789abcdefABCDEF" HexCharset = "0123456789abcdefABCDEF"
AlphanumericCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" AlphanumericCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
CharsetNameHex = "hex"
CharsetNameBase64 = "base64"
CharsetNameAlphanumeric = "alphanumeric"
) )
var ( var (
@ -98,19 +102,19 @@ func DetectCharset(s string) string {
} }
if total == 0 { if total == 0 {
return "alphanumeric" return CharsetNameAlphanumeric
} }
hexRatio := float64(hexCount) / float64(total) hexRatio := float64(hexCount) / float64(total)
b64Ratio := float64(b64Count) / float64(total) b64Ratio := float64(b64Count) / float64(total)
if hexRatio == 1.0 && isAllHexChars(s) { if hexRatio == 1.0 && isAllHexChars(s) {
return "hex" return CharsetNameHex
} }
if b64Ratio >= 0.95 { if b64Ratio >= 0.95 {
return "base64" return CharsetNameBase64
} }
return "alphanumeric" return CharsetNameAlphanumeric
} }
func ExtractHighEntropyTokens( func ExtractHighEntropyTokens(

View File

@ -128,27 +128,27 @@ func TestDetectCharset(t *testing.T) {
}{ }{
"hex string": { "hex string": {
input: "a1b2c3d4e5f6", input: "a1b2c3d4e5f6",
want: "hex", want: CharsetNameHex,
}, },
"base64 with special chars": { "base64 with special chars": {
input: "kR9mPx2vBnQ8jL5w+/YzTf==", input: "kR9mPx2vBnQ8jL5w+/YzTf==",
want: "base64", want: CharsetNameBase64,
}, },
"pure alphanumeric": { "pure alphanumeric": {
input: "HelloWorld123XYZ", input: "HelloWorld123XYZ",
want: "base64", want: CharsetNameBase64,
}, },
"mixed with symbols": { "mixed with symbols": {
input: "hello@world#foo$bar", input: "hello@world#foo$bar",
want: "alphanumeric", want: CharsetNameAlphanumeric,
}, },
"empty string": { "empty string": {
input: "", input: "",
want: "alphanumeric", want: CharsetNameAlphanumeric,
}, },
"only hex digits": { "only hex digits": {
input: "deadbeef0123456789", input: "deadbeef0123456789",
want: "hex", want: CharsetNameHex,
}, },
} }

View File

@ -0,0 +1,2 @@
strict-dep-builds=false
auto-install-peers=true