- JWT revocation with JTI (UUID v4): in-memory tracking, POST /api/logout, refresh handler revokes old JTI, RequireAuth rejects revoked tokens - Fix extractKey for S3 portfolio deletion: extracts full key path from URLs instead of just filename, preventing orphaned storage files - Notes validation: max=1000000 on all 13 Notes fields across 4 booking structs - CharCounter: grapheme-aware counter (Intl.Segmenter), threshold 750K, color-coded, integrated into 6 booking/admin components - loginInProgress: timestamp-based tracking, 30s staleness, 20-entry cap (429), ticker cleanup for stuck entries - Profile picture 15MB client-side limit, portfolio 20MB backend limit - Exceptional scheduling: expand query start to Monday of week - TodayCalendar: week-range fetching, closing time indicator, short-day lunch skip - NavBar: link reorder, mobile burger badge, slide transition, backdrop - ImageUpload: 20MB limit with visual feedback - formatDateISO: shared YYYY-MM-DD utility, shouldApplyLunchProtection helper - Update README.md and all Obsidian docs (Overview, Technical, Admin, Future Work) - Add 28 new tests: JWT (11), auth handlers (7), portfolio extractKey (5), notes validation (5). go build + go vet clean with test,dev tags
70 lines
1.1 KiB
Go
70 lines
1.1 KiB
Go
//go:build test
|
|
// +build test
|
|
|
|
package jwt
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"crussell/auth"
|
|
)
|
|
|
|
const testSecret = "test-secret-key-for-testing-only"
|
|
|
|
var (
|
|
once sync.Once
|
|
initialized bool
|
|
)
|
|
|
|
func init() {
|
|
Init()
|
|
}
|
|
|
|
func Init() {
|
|
once.Do(func() {
|
|
if auth.TokenAuth == nil {
|
|
auth.InitJWT(testSecret)
|
|
}
|
|
initialized = true
|
|
})
|
|
}
|
|
|
|
func EnsureInitialized() {
|
|
if !initialized {
|
|
Init()
|
|
}
|
|
}
|
|
|
|
func GenerateTestToken(userID, role string) string {
|
|
EnsureInitialized()
|
|
token, _, err := auth.GenerateToken(userID, role)
|
|
if err != nil {
|
|
panic("failed to generate test token: " + err.Error())
|
|
}
|
|
return token
|
|
}
|
|
|
|
func GenerateAdminToken() string {
|
|
return GenerateTestToken("admintest001", "admin")
|
|
}
|
|
|
|
func GenerateVerifiedUserToken(userID string) string {
|
|
return GenerateTestToken(userID, "verified_email")
|
|
}
|
|
|
|
func GenerateUnverifiedUserToken(userID string) string {
|
|
return GenerateTestToken(userID, "unverified_email")
|
|
}
|
|
|
|
func GenerateUserToken(userID string) string {
|
|
return GenerateVerifiedUserToken(userID)
|
|
}
|
|
|
|
func GetTestSecret() string {
|
|
return testSecret
|
|
}
|
|
|
|
func SetTestSecret(secret string) {
|
|
auth.InitJWT(secret)
|
|
}
|