Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 9 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
name: build
on: [push, pull_request]

permissions:
contents: read

jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: set up go 1.25
uses: actions/setup-go@v6
- name: set up go 1.26
uses: actions/setup-go@v7
with:
go-version: "1.25"
go-version: "1.26"
id: go

- name: test
Expand All @@ -26,7 +29,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.7.2
version: v2.12.2

- name: install goveralls
run: go install github.com/mattn/goveralls@latest
Expand Down Expand Up @@ -55,7 +58,7 @@ jobs:
artifact: linux-arm64
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
Expand Down
20 changes: 13 additions & 7 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,33 @@ jobs:

steps:
- name: checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: setup go
uses: actions/setup-go@v6
uses: actions/setup-go@v7
with:
go-version: "1.25"
go-version: "1.26"

- name: cache playwright browsers
uses: actions/cache@v5
uses: actions/cache@v6
id: playwright-cache
with:
path: ~/.cache/ms-playwright
path: |
~/.cache/ms-playwright
~/.cache/ms-playwright-go
key: playwright-${{ runner.os }}-${{ hashFiles('go.sum') }}

- name: install playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: go run github.com/playwright-community/playwright-go/cmd/playwright@latest install --with-deps chromium
run: |
version=$(go list -m -f '{{.Version}}' github.com/mxschmitt/playwright-go)
go run github.com/mxschmitt/playwright-go/cmd/playwright@${version} install --with-deps chromium

- name: install playwright deps only
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: go run github.com/playwright-community/playwright-go/cmd/playwright@latest install-deps chromium
run: |
version=$(go list -m -f '{{.Version}}' github.com/mxschmitt/playwright-go)
go run github.com/mxschmitt/playwright-go/cmd/playwright@${version} install-deps chromium

- name: run e2e tests
run: go test -v -count=1 -timeout=5m -tags=e2e ./e2e/...
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: check out code
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0

- name: set up go
uses: actions/setup-go@v6
uses: actions/setup-go@v7
with:
go-version: "1.25"
go-version: "1.26"

- name: run goreleaser
uses: goreleaser/goreleaser-action@v7
Expand Down
5 changes: 5 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ linters:
goconst:
min-len: 2
min-occurrences: 7
ignore-tests: true
gocritic:
disabled-checks:
- wrapperFunc
Expand Down Expand Up @@ -136,6 +137,10 @@ linters:
- gosec
path: e2e/
text: "G101: Potential hardcoded credentials"
- linters:
- gosec
path: _test\.go$
text: "G124:"
- linters:
- goconst
text: "string `text` has"
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ info:
@echo "revision: $(REV)"

e2e-setup:
go run github.com/playwright-community/playwright-go/cmd/playwright@latest install --with-deps chromium
go run github.com/mxschmitt/playwright-go/cmd/playwright@$$(go list -m -f '{{.Version}}' github.com/mxschmitt/playwright-go) install --with-deps chromium

e2e:
go test -v -count=1 -timeout=5m -tags=e2e ./e2e/...
Expand Down
2 changes: 2 additions & 0 deletions app/server/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (s Server) loginCtrl(w http.ResponseWriter, r *http.Request) {

log.Printf("[INFO] login success, ip=%s", GetHashedIP(r))
// authentication successful, set session cookie
//nolint:gosec // G124: Secure is set from the configured protocol, plain http is allowed for local runs
http.SetCookie(w, &http.Cookie{
Name: authCookieName,
Value: s.generateSessionToken(),
Expand All @@ -89,6 +90,7 @@ func (s Server) loginCtrl(w http.ResponseWriter, r *http.Request) {
// GET /logout
func (s Server) logoutCtrl(w http.ResponseWriter, r *http.Request) {
// clear the auth cookie
//nolint:gosec // G124: Secure is set from the configured protocol, plain http is allowed for local runs
http.SetCookie(w, &http.Cookie{
Name: authCookieName,
Value: "",
Expand Down
1 change: 1 addition & 0 deletions app/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ func (s Server) Run(ctx context.Context) error {
IdleTimeout: 30 * time.Second,
}

//nolint:gosec // G118: the shutdown deadline can't derive from ctx, it is already done at this point
go func() {
<-ctx.Done()
if httpServer != nil {
Expand Down
3 changes: 3 additions & 0 deletions app/server/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ func (s Server) loadMessageCtrl(w http.ResponseWriter, r *http.Request) {
// non-HTMX request (from client-side JS with fetch) - return blob for decryption
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(http.StatusOK)
//nolint:gosec // G705: base64url ciphertext served as text/plain, nosniff set by security headers
_, _ = w.Write(msg.Data)
log.Printf("[INFO] accessed message %s, type=client-enc, status=200 (success), ip=%s", form.Key, GetHashedIP(r))
return
Expand Down Expand Up @@ -406,6 +407,7 @@ func (s Server) loadMessageCtrl(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Length", strconv.Itoa(len(msg.Data)-dataStart))
w.Header().Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(http.StatusOK)
//nolint:gosec // G705: served as octet-stream attachment with nosniff, never rendered by the browser
_, _ = w.Write(msg.Data[dataStart:])
log.Printf("[INFO] accessed message %s, type=file, status=200 (success), ip=%s", form.Key, GetHashedIP(r))
return
Expand Down Expand Up @@ -526,6 +528,7 @@ func (s Server) themeToggleCtrl(w http.ResponseWriter, r *http.Request) {
}

// set cookie (client-side storage)
//nolint:gosec // G124: theme preference carries no secret and HttpOnly is off on purpose, see below
http.SetCookie(w, &http.Cookie{
Name: "theme",
Value: nextTheme,
Expand Down
2 changes: 1 addition & 1 deletion app/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func GenerateID() string {
}
// reject values >= 248 to avoid modulo bias (248 = 62*4, evenly divisible)
if b[0] < 248 {
result[i] = alphabet[b[0]%62] //nolint:gosec // index always 0-61, safe
result[i] = alphabet[b[0]%62]
i++
}
}
Expand Down
2 changes: 1 addition & 1 deletion e2e/crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package e2e
import (
"testing"

"github.com/playwright-community/playwright-go"
"github.com/mxschmitt/playwright-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down
20 changes: 12 additions & 8 deletions e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"testing"
"time"

"github.com/playwright-community/playwright-go"
"github.com/mxschmitt/playwright-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -390,15 +390,19 @@ func TestTheme_Toggle(t *testing.T) {
require.True(t, visible, "theme toggle button should be visible")

require.NoError(t, themeBtn.Click())
// wait for page to fully reload by checking for message form
messageTextarea := page.Locator("#message")
waitVisible(t, messageTextarea)

// check theme changed
newTheme, err := page.Locator("html").GetAttribute("data-theme")
require.NoError(t, err)
// the toggle answers with HX-Refresh, and #message is present both before and after the
// reload, so the attribute has to be polled until the reloaded document arrives
var newTheme string
require.Eventually(t, func() bool {
v, attrErr := page.Locator("html").GetAttribute("data-theme")
if attrErr != nil {
return false
}
newTheme = v
return v != initialTheme
}, 5*time.Second, 50*time.Millisecond, "theme should change after toggle")
assert.NotEmpty(t, newTheme, "theme attribute should be set after toggle")
assert.NotEqual(t, initialTheme, newTheme, "theme should change after toggle")
}

// --- about page tests ---
Expand Down
2 changes: 1 addition & 1 deletion e2e/hybrid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"testing"
"time"

"github.com/playwright-community/playwright-go"
"github.com/mxschmitt/playwright-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down
2 changes: 1 addition & 1 deletion e2e/no_pin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"testing"
"time"

"github.com/playwright-community/playwright-go"
"github.com/mxschmitt/playwright-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down
42 changes: 19 additions & 23 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,45 +1,41 @@
module github.com/umputun/secrets/v2

go 1.25.0
go 1.26.0

require (
github.com/didip/tollbooth/v8 v8.0.1
github.com/go-pkgz/lgr v0.12.3
github.com/go-pkgz/notify v1.3.0
github.com/go-pkgz/rest v1.21.0
github.com/go-pkgz/routegroup v1.6.0
github.com/go-pkgz/lgr v0.12.4
github.com/go-pkgz/notify v1.4.0
github.com/go-pkgz/rest v1.24.0
github.com/go-pkgz/routegroup v1.6.1
github.com/google/uuid v1.6.0
github.com/playwright-community/playwright-go v0.5200.1
github.com/stretchr/testify v1.11.1
github.com/mxschmitt/playwright-go v0.6201.1
github.com/stretchr/testify v1.12.0
github.com/umputun/go-flags v1.5.1
golang.org/x/crypto v0.49.0
modernc.org/sqlite v1.48.0
golang.org/x/crypto v0.55.0
modernc.org/sqlite v1.57.0
)

require (
github.com/aymerick/douceur v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set/v2 v2.7.0 // indirect
github.com/deckarep/golang-set/v2 v2.8.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/go-jose/go-jose/v3 v3.0.5 // indirect
github.com/go-pkgz/email v0.6.0 // indirect
github.com/go-pkgz/expirable-cache/v3 v3.1.0 // indirect
github.com/go-pkgz/repeater v1.2.0 // indirect
github.com/go-pkgz/email v0.8.0 // indirect
github.com/go-pkgz/expirable-cache/v3 v3.1.1 // indirect
github.com/go-pkgz/repeater/v2 v2.2.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/gorilla/css v1.0.1 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/slack-go/slack v0.20.0 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/tools v0.43.0 // indirect
github.com/slack-go/slack v0.29.0 // indirect
golang.org/x/net v0.58.0 // indirect
golang.org/x/sys v0.47.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.70.0 // indirect
modernc.org/libc v1.75.3 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/memory v1.12.0 // indirect
)
Loading