mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-09-20 04:23:43 +00:00
Phase 6 of the 2026-05-09 review remediation plan. Bundle of small
hygiene fixes — none individually urgent but better folded together
than scattered across follow-ups.
- .golangci.yml: enable errcheck/govet/gosec/staticcheck/unused/
ineffassign/gocyclo/misspell/revive. Tuned to the codebase style
(no universal exported-doc requirement, gocyclo cap at 20 to
accommodate handler dispatch). 0 issues across the tree.
- ci.yml: add golangci-lint job + govulncheck (informational).
- Defensive guards:
- registry.go: Module.Name mismatch now errors at Build instead of
silently overwriting (TestBuild_RejectsFactoryNameMismatch).
- cmd/server/main.go: PORT env validated numerically + 0..65535.
- firestore_provider.go: For() re-validates module name; invalid
names return an invalidStore whose every op errors with
ErrInvalidModuleName.
- Dead code removal:
- wordle: gameTTLSeconds const + pickDaily/hashDJB2/todayUTC
helpers + their tests deleted (pickDaily was unused;
daily.go renamed pick_random.go).
- Dependency: golang.org/x/net v0.52.0 -> v0.54.0 (resolves
GO-2026-4918 HTTP/2 infinite-loop CVE).
- Deferred from the original phase plan: Docker digest pinning
(Dependabot handles), per-handler file splits (largest file 279 LOC;
splits would churn for marginal gain).
go test -race -count=1 ./... clean (15 packages); golangci-lint run
clean (0 issues).
39 lines
1.5 KiB
Go
39 lines
1.5 KiB
Go
package storage
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
"cloud.google.com/go/firestore"
|
|
)
|
|
|
|
// collectionNameRe mirrors modules.moduleNameRe. Defense-in-depth: callers
|
|
// should validate first (modules.Build does), but a junk collection name
|
|
// that escapes validation could let any caller drop docs into someone
|
|
// else's namespace. Match the canonical alphabet here too.
|
|
var collectionNameRe = regexp.MustCompile(`^[a-z0-9_-]{1,32}$`)
|
|
|
|
// FirestoreProvider is a KVProvider that creates one collection per module.
|
|
// No key prefix wrapping is needed — collection-per-module IS the isolation.
|
|
type FirestoreProvider struct {
|
|
client *firestore.Client
|
|
}
|
|
|
|
// NewFirestoreProvider returns a provider over the given client. The client
|
|
// must outlive every KVStore the provider hands out; callers own its Close.
|
|
func NewFirestoreProvider(client *firestore.Client) *FirestoreProvider {
|
|
return &FirestoreProvider{client: client}
|
|
}
|
|
|
|
// For returns a FirestoreKVStore writing to a collection named after the
|
|
// module. moduleName is re-validated against collectionNameRe — defense in
|
|
// depth against caller bugs that bypass modules.Build. An invalid name
|
|
// returns a store whose every operation errors with ErrInvalidModuleName,
|
|
// so the bug surfaces at first use rather than silently writing to a
|
|
// junk-named collection.
|
|
func (p *FirestoreProvider) For(moduleName string) KVStore {
|
|
if !collectionNameRe.MatchString(moduleName) {
|
|
return invalidStore{name: moduleName}
|
|
}
|
|
return NewFirestoreKVStore(p.client, moduleName)
|
|
}
|