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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
"ghcr.io/devcontainers/features/common-utils:1": {
"installZsh": false,
"installOhMyZsh": false,
"upgradePackages": true
"upgradePackages": true
},
"ghcr.io/devcontainers/features/go:1": {},
"ghcr.io/devcontainers/features/node:1": {}
},

"customizations": {
"vscode": {
"extensions": [
Expand All @@ -27,6 +26,5 @@
]
}
},

"postStartCommand": ".devcontainer/post-start-command.sh"
}
}
25 changes: 25 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Lint

on:
# Test on checkin.
push:
# Pull requests
pull_request:
# Manual trigger.
workflow_dispatch:

jobs:
go-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: 'stable'
- uses: golangci/golangci-lint-action@v3
env:
GOOS: js
GOARCH: wasm
with:
version: 'latest'
only-new-issues: true
3 changes: 3 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
linters:
presets:
- bugs
13 changes: 13 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"go.lintTool": "golangci-lint",
"go.toolsEnvVars": {
"GOOS": "js",
"GOARCH": "wasm"
},
"gopls": {
"build.env": {
"GOOS": "js",
"GOARCH": "wasm"
}
}
}
3 changes: 3 additions & 0 deletions go.work
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
go 1.21.0

use .
2 changes: 1 addition & 1 deletion go/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (a *AppContext) Run() {

init.Wait()
if initErr != nil {
panic(fmt.Errorf("%s init failed: %v; terminating", a.app.Name(), initErr))
panic(fmt.Errorf("%s init failed: %w; terminating", a.app.Name(), initErr))
}

done.Wait()
Expand Down
13 changes: 8 additions & 5 deletions go/jsutil/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package jsutil

import (
"errors"
"syscall/js"
)

Expand All @@ -36,17 +37,17 @@ func (e JSError) AsJSValue() js.Value {

// Name returns the Error's name.
func (e JSError) Name() string {
return e.Get("name").String()
return e.Value.Get("name").String()
}

// Message returns the Error's message.
func (e JSError) Message() string {
return e.Get("message").String()
return e.Value.Get("message").String()
}

// Error implements Go's error interface.
func (e JSError) Error() string {
return e.Call("toString").String()
return e.Value.Call("toString").String()
}

const (
Expand All @@ -58,8 +59,10 @@ func NewError(err error) JSError {
if err == nil {
panic("Cannot construct nil JSError")
}
if e, ok := err.(JSError); ok {
return e

var je JSError
if errors.As(err, &je) {
return je
}

e := jsError.New(err.Error())
Expand Down
34 changes: 17 additions & 17 deletions go/keys/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (s *Server) makeErrorResponse(err error) js.Value {
func (s *Server) OnMessage(ctx jsutil.AsyncContext, headerObj js.Value, sender js.Value) js.Value {
var header msgHeader
if err := vert.ValueOf(headerObj).AssignTo(&header); err != nil {
return s.makeErrorResponse(fmt.Errorf("failed to parse message header: %v", err))
return s.makeErrorResponse(fmt.Errorf("failed to parse message header: %w", err))
}

jsutil.LogDebug("Server.OnMessage(type = %d)", header.Type)
Expand Down Expand Up @@ -195,7 +195,7 @@ func (s *Server) OnMessage(ctx jsutil.AsyncContext, headerObj js.Value, sender j
case msgTypeAdd:
var m msgAdd
if err := vert.ValueOf(headerObj).AssignTo(&m); err != nil {
return s.makeErrorResponse(fmt.Errorf("failed to parse Add message: %v", err))
return s.makeErrorResponse(fmt.Errorf("failed to parse Add message: %w", err))
}
jsutil.LogDebug("Server.OnMessage(Add req): name=%s", m.Name)
err := s.mgr.Add(ctx, m.Name, m.PEMPrivateKey)
Expand All @@ -208,7 +208,7 @@ func (s *Server) OnMessage(ctx jsutil.AsyncContext, headerObj js.Value, sender j
case msgTypeRemove:
var m msgRemove
if err := vert.ValueOf(headerObj).AssignTo(&m); err != nil {
return s.makeErrorResponse(fmt.Errorf("failed to parse Remove message: %v", err))
return s.makeErrorResponse(fmt.Errorf("failed to parse Remove message: %w", err))
}
jsutil.LogDebug("Server.OnMessage(Remove req): id=%s", m.ID)
err := s.mgr.Remove(ctx, ID(m.ID))
Expand All @@ -221,7 +221,7 @@ func (s *Server) OnMessage(ctx jsutil.AsyncContext, headerObj js.Value, sender j
case msgTypeLoad:
var m msgLoad
if err := vert.ValueOf(headerObj).AssignTo(&m); err != nil {
return s.makeErrorResponse(fmt.Errorf("failed to parse Load message: %v", err))
return s.makeErrorResponse(fmt.Errorf("failed to parse Load message: %w", err))
}
jsutil.LogDebug("Server.OnMessage(Load req): id=%s", m.ID)
err := s.mgr.Load(ctx, ID(m.ID), m.Passphrase)
Expand All @@ -234,7 +234,7 @@ func (s *Server) OnMessage(ctx jsutil.AsyncContext, headerObj js.Value, sender j
case msgTypeUnload:
var m msgUnload
if err := vert.ValueOf(headerObj).AssignTo(&m); err != nil {
return s.makeErrorResponse(fmt.Errorf("failed to parse Unload message: %v", err))
return s.makeErrorResponse(fmt.Errorf("failed to parse Unload message: %w", err))
}
jsutil.LogDebug("Server.OnMessage(Unload req): id=%s", m.ID)
err := s.mgr.Unload(ctx, ID(m.ID))
Expand Down Expand Up @@ -267,11 +267,11 @@ func (c *client) Configured(ctx jsutil.AsyncContext) ([]*ConfiguredKey, error) {
rspObj, err := c.msg.Send(ctx, vert.ValueOf(msg).JSValue())
jsutil.LogDebug("Client.Configured(rsp)")
if err != nil {
return nil, fmt.Errorf("failed to send message: %v", err)
return nil, fmt.Errorf("failed to send message: %w", err)
}
var rsp rspConfigured
if err := vert.ValueOf(rspObj).AssignTo(&rsp); err != nil {
return nil, fmt.Errorf("failed to parse response: %v", err)
return nil, fmt.Errorf("failed to parse response: %w", err)
}
return rsp.Keys, makeErr(rsp.Err)
}
Expand All @@ -284,11 +284,11 @@ func (c *client) Loaded(ctx jsutil.AsyncContext) ([]*LoadedKey, error) {
rspObj, err := c.msg.Send(ctx, vert.ValueOf(msg).JSValue())
jsutil.LogDebug("Client.Loaded(rsp)")
if err != nil {
return nil, fmt.Errorf("failed to send message: %v", err)
return nil, fmt.Errorf("failed to send message: %w", err)
}
var rsp rspLoaded
if err := vert.ValueOf(rspObj).AssignTo(&rsp); err != nil {
return nil, fmt.Errorf("failed to parse response: %v", err)
return nil, fmt.Errorf("failed to parse response: %w", err)
}
return rsp.Keys, makeErr(rsp.Err)
}
Expand All @@ -303,11 +303,11 @@ func (c *client) Add(ctx jsutil.AsyncContext, name string, pemPrivateKey string)
rspObj, err := c.msg.Send(ctx, vert.ValueOf(msg).JSValue())
jsutil.LogDebug("Client.Add(rsp)")
if err != nil {
return fmt.Errorf("failed to send message: %v", err)
return fmt.Errorf("failed to send message: %w", err)
}
var rsp rspAdd
if err := vert.ValueOf(rspObj).AssignTo(&rsp); err != nil {
return fmt.Errorf("failed to parse response: %v", err)
return fmt.Errorf("failed to parse response: %w", err)
}
return makeErr(rsp.Err)
}
Expand All @@ -321,11 +321,11 @@ func (c *client) Remove(ctx jsutil.AsyncContext, id ID) error {
rspObj, err := c.msg.Send(ctx, vert.ValueOf(msg).JSValue())
jsutil.LogDebug("Client.Remove(rsp)")
if err != nil {
return fmt.Errorf("failed to send message: %v", err)
return fmt.Errorf("failed to send message: %w", err)
}
var rsp rspRemove
if err := vert.ValueOf(rspObj).AssignTo(&rsp); err != nil {
return fmt.Errorf("failed to parse response: %v", err)
return fmt.Errorf("failed to parse response: %w", err)
}
return makeErr(rsp.Err)
}
Expand All @@ -340,11 +340,11 @@ func (c *client) Load(ctx jsutil.AsyncContext, id ID, passphrase string) error {
rspObj, err := c.msg.Send(ctx, vert.ValueOf(msg).JSValue())
jsutil.LogDebug("Client.Load(rsp)")
if err != nil {
return fmt.Errorf("failed to send message: %v", err)
return fmt.Errorf("failed to send message: %w", err)
}
var rsp rspLoad
if err := vert.ValueOf(rspObj).AssignTo(&rsp); err != nil {
return fmt.Errorf("failed to parse response: %v", err)
return fmt.Errorf("failed to parse response: %w", err)
}
return makeErr(rsp.Err)
}
Expand All @@ -358,11 +358,11 @@ func (c *client) Unload(ctx jsutil.AsyncContext, id ID) error {
rspObj, err := c.msg.Send(ctx, vert.ValueOf(msg).JSValue())
jsutil.LogDebug("Client.Unload(rsp)")
if err != nil {
return fmt.Errorf("failed to send message: %v", err)
return fmt.Errorf("failed to send message: %w", err)
}
var rsp rspUnload
if err := vert.ValueOf(rspObj).AssignTo(&rsp); err != nil {
return fmt.Errorf("failed to parse response: %v", err)
return fmt.Errorf("failed to parse response: %w", err)
}
return makeErr(rsp.Err)
}
8 changes: 4 additions & 4 deletions go/keys/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ func decryptKey(key *storedKey, passphrase string) (decryptedKey, error) {
}
// Wrap all other non-specific errors.
if err != nil {
return "", fmt.Errorf("%w: %v", errParseFailed, err)
return "", fmt.Errorf("%w: %w", errParseFailed, err)
}

// Workaround for https://github.com/google/chrome-ssh-agent/issues/28.
Expand All @@ -427,7 +427,7 @@ func decryptKey(key *storedKey, passphrase string) (decryptedKey, error) {
// Marshal to PKCS#8 format.
buf, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
return "", fmt.Errorf("%w: %v", errMarshalFailed, err)
return "", fmt.Errorf("%w: %w", errMarshalFailed, err)
}

return decryptedKey(pem.EncodeToMemory(&pem.Block{
Expand Down Expand Up @@ -518,11 +518,11 @@ func (m *DefaultManager) Unload(ctx jsutil.AsyncContext, id ID) error {
Blob: lk.Blob(),
}
if err := m.agent.Remove(pub); err != nil {
return fmt.Errorf("%w: %v", errAgentUnloadFailed, err)
return fmt.Errorf("%w: %w", errAgentUnloadFailed, err)
}

if err := m.sessionKeys.Delete(ctx, func(sk *sessionKey) bool { return ID(sk.ID) == id }); err != nil {
return fmt.Errorf("%w: %v", errStorageUnloadFailed, err)
return fmt.Errorf("%w: %w", errStorageUnloadFailed, err)
}

return nil
Expand Down
4 changes: 3 additions & 1 deletion go/lock/lock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ func TestExclusive(t *testing.T) {

// Wait for all routines to complete.
for _, p := range promises {
p.Await(ctx)
if _, err := p.Await(ctx); err != nil {
t.Errorf("promise returned error: %v", err)
}
}

// Validate that all workers completed.
Expand Down
16 changes: 8 additions & 8 deletions go/optionsui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (u *UI) add(ctx jsutil.AsyncContext, evt dom.Event) {
}

if err := u.mgr.Add(ctx, name, privateKey); err != nil {
u.setError(fmt.Errorf("failed to add key: %v", err))
u.setError(fmt.Errorf("failed to add key: %w", err))
return
}

Expand Down Expand Up @@ -185,7 +185,7 @@ func (u *UI) load(ctx jsutil.AsyncContext, id keys.ID) {
}

if err := u.mgr.Load(ctx, id, passphrase); err != nil {
u.setError(fmt.Errorf("failed to load key: %v", err))
u.setError(fmt.Errorf("failed to load key: %w", err))
return
}
u.setError(nil)
Expand Down Expand Up @@ -224,7 +224,7 @@ func (u *UI) promptPassphrase(ctx jsutil.AsyncContext) (ok bool, passphrase stri
// unload unloads the specified key.
func (u *UI) unload(ctx jsutil.AsyncContext, id keys.ID) {
if err := u.mgr.Unload(ctx, id); err != nil {
u.setError(fmt.Errorf("failed to unload key ID %s: %v", id, err))
u.setError(fmt.Errorf("failed to unload key ID %s: %w", id, err))
return
}
u.setError(nil)
Expand Down Expand Up @@ -275,7 +275,7 @@ func (u *UI) remove(ctx jsutil.AsyncContext, id keys.ID) {
}

if err := u.mgr.Remove(ctx, id); err != nil {
u.setError(fmt.Errorf("failed to remove key ID %s: %v", id, err))
u.setError(fmt.Errorf("failed to remove key ID %s: %w", id, err))
return
}
u.setError(nil)
Expand Down Expand Up @@ -309,7 +309,7 @@ type displayedKey struct {
func (d *displayedKey) LoadedKey() (*keys.LoadedKey, error) {
blob, err := base64.StdEncoding.DecodeString(d.Blob)
if err != nil {
return nil, fmt.Errorf("failed to decode blob: %v", err)
return nil, fmt.Errorf("failed to decode blob: %w", err)
}

l := &keys.LoadedKey{
Expand Down Expand Up @@ -539,13 +539,13 @@ func mergeKeys(configured []*keys.ConfiguredKey, loaded []*keys.LoadedKey) []*di
func (u *UI) updateKeys(ctx jsutil.AsyncContext) {
configured, err := u.mgr.Configured(ctx)
if err != nil {
u.setError(fmt.Errorf("failed to get configured keys: %v", err))
u.setError(fmt.Errorf("failed to get configured keys: %w", err))
return
}

loaded, err := u.mgr.Loaded(ctx)
if err != nil {
u.setError(fmt.Errorf("failed to get loaded keys: %v", err))
u.setError(fmt.Errorf("failed to get loaded keys: %w", err))
return
}
u.setError(nil)
Expand Down Expand Up @@ -605,7 +605,7 @@ func (u *UI) EndToEndTest(ctx jsutil.AsyncContext) []error {
jsutil.Log("Generate random name to use for key")
i, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
errs = append(errs, fmt.Errorf("failed to generate random number: %v", err))
errs = append(errs, fmt.Errorf("failed to generate random number: %w", err))
return errs
}
keyName := fmt.Sprintf("e2e-test-key-%s", i.String())
Expand Down
Loading