Skip to content

Commit f500110

Browse files
authored
Merge pull request #2 from markrai/fix/error-sentinel-unification
fix(errors): unify sentinel errors to preserve identity across packages
2 parents 84c6549 + 8be0a35 commit f500110

7 files changed

Lines changed: 48 additions & 18 deletions

File tree

.github/workflows/dco.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@ name: DCO Check
22

33
on:
44
pull_request:
5+
branches: [main, master]
56

67
jobs:
78
dco:
89
runs-on: ubuntu-latest
910
steps:
10-
- name: DCO Check
11-
uses: tim-actions/dco@v1
11+
- name: Get PR commits
12+
id: get-pr-commits
13+
uses: tim-actions/get-pr-commits@v1.3.1
14+
with:
15+
token: ${{ secrets.GITHUB_TOKEN }}
16+
- name: DCO check
17+
uses: tim-actions/dco@v1.1.0
18+
with:
19+
commits: ${{ steps.get-pr-commits.outputs.commits }}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ Thumbs.db
3737
coverage.out
3838
*.cover
3939
*.test
40+
41+
# Development related
42+
f.bat
43+
a.bat
44+
*.pem
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
package auth
22

33
import (
4-
"errors"
54
"fmt"
65
"strings"
7-
)
86

9-
// ErrValidation is returned when password validation fails.
10-
var ErrValidation = errors.New("validation")
7+
"scrumboy/internal/errs"
8+
)
119

1210
const minPasswordLength = 8
1311

1412
// ValidatePassword validates a password for signup or reset.
1513
// Rules: min length 8, trim whitespace, reject empty.
16-
// Returns ErrValidation on failure.
14+
// Returns errs.ErrValidation on failure.
1715
func ValidatePassword(password string) error {
1816
p := strings.TrimSpace(password)
1917
if p == "" {
20-
return fmt.Errorf("%w: password required", ErrValidation)
18+
return fmt.Errorf("%w: password required", errs.ErrValidation)
2119
}
2220
if len(p) < minPasswordLength {
23-
return fmt.Errorf("%w: password too short", ErrValidation)
21+
return fmt.Errorf("%w: password too short", errs.ErrValidation)
2422
}
2523
return nil
2624
}

internal/config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66
"path/filepath"
77
"strconv"
8+
"strings"
89
)
910

1011
type Config struct {
@@ -51,8 +52,9 @@ func FromEnv() Config {
5152
SQLiteJournalMode: getenv("SQLITE_JOURNAL_MODE", "WAL"),
5253
SQLiteSynchronous: getenv("SQLITE_SYNCHRONOUS", "FULL"),
5354

54-
ScrumboyMode: mode,
55-
TwoFactorEncryptionKey: getenv("SCRUMBOY_ENCRYPTION_KEY", ""),
55+
ScrumboyMode: mode,
56+
// Trim whitespace so keys from .env / copy-paste decode (base64 is sensitive to newlines).
57+
TwoFactorEncryptionKey: strings.TrimSpace(os.Getenv("SCRUMBOY_ENCRYPTION_KEY")),
5658

5759
TLSCertFile: getenv("SCRUMBOY_TLS_CERT", "./cert.pem"),
5860
TLSKeyFile: getenv("SCRUMBOY_TLS_KEY", "./key.pem"),

internal/crypto/totpenc.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ func DecryptTOTPSecret(key []byte, encrypted string) ([]byte, error) {
8181

8282
// DecodeKey decodes a base64-encoded 32-byte key. Returns error if wrong length.
8383
func DecodeKey(b64 string) ([]byte, error) {
84+
b64 = strings.TrimSpace(b64)
8485
key, err := base64.StdEncoding.DecodeString(b64)
8586
if err != nil {
8687
key, err = base64.RawURLEncoding.DecodeString(b64)

internal/errs/errs.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package errs
2+
3+
import "errors"
4+
5+
// NOTE: All shared sentinel errors MUST be defined here.
6+
// Do not redefine errors.New(...) for these concepts elsewhere.
7+
// Use errs.ErrX (or store re-exports that alias errs.ErrX) to preserve identity across packages.
8+
var (
9+
ErrValidation = errors.New("validation")
10+
ErrUnauthorized = errors.New("unauthorized")
11+
ErrNotFound = errors.New("not found")
12+
ErrConflict = errors.New("conflict")
13+
ErrTooManyAttempts = errors.New("too many attempts")
14+
Err2FAEncryptionNotConfigured = errors.New("2FA encryption not configured")
15+
)

internal/store/types.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package store
22

33
import (
4-
"errors"
54
"time"
5+
6+
"scrumboy/internal/errs"
67
)
78

89
var (
9-
ErrNotFound = errors.New("not found")
10-
ErrConflict = errors.New("conflict")
11-
ErrValidation = errors.New("validation")
12-
ErrUnauthorized = errors.New("unauthorized")
13-
ErrTooManyAttempts = errors.New("too many attempts")
14-
Err2FAEncryptionNotConfigured = errors.New("2FA encryption not configured")
10+
ErrNotFound = errs.ErrNotFound
11+
ErrConflict = errs.ErrConflict
12+
ErrValidation = errs.ErrValidation
13+
ErrUnauthorized = errs.ErrUnauthorized
14+
ErrTooManyAttempts = errs.ErrTooManyAttempts
15+
Err2FAEncryptionNotConfigured = errs.Err2FAEncryptionNotConfigured
1516
)
1617

1718
const (

0 commit comments

Comments
 (0)