Changeset 0.30.2 (#201)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit is contained in:
@@ -365,18 +365,28 @@ func DestroyVaultDB(ctx context.Context, stores store.Stores, userID string) (pr
|
||||
// wrapped with a different password), the vault and personal providers are
|
||||
// destroyed so initVault fires cleanly on next login.
|
||||
//
|
||||
// Used by BootstrapAdmin and SeedUsers where the password is known at
|
||||
// startup but the UEK cache is not available.
|
||||
// When uekCache is non-nil and the vault unlocks successfully, the UEK is
|
||||
// cached so that BYOK operations work immediately without requiring a fresh
|
||||
// login. This is important for bootstrapped/seeded users whose browser
|
||||
// sessions survive server restarts.
|
||||
//
|
||||
// Used by BootstrapAdmin and SeedUsers where the password is known at startup.
|
||||
// v0.29.0: accepts stores instead of using database.DB directly.
|
||||
func ProbeAndRepairVault(ctx context.Context, stores store.Stores, userID, password string) {
|
||||
// v0.30.2: accepts optional uekCache to pre-warm vault on restart.
|
||||
func ProbeAndRepairVault(ctx context.Context, stores store.Stores, userID, password string, uekCache ...*crypto.UEKCache) {
|
||||
vaultSet, encryptedUEK, salt, nonce, err := stores.Users.GetVaultKeys(ctx, userID)
|
||||
if err != nil || !vaultSet {
|
||||
return // no vault to probe
|
||||
}
|
||||
|
||||
pdk := crypto.DeriveKeyFromPassword(password, salt)
|
||||
if _, err := crypto.UnwrapUEK(encryptedUEK, nonce, pdk); err == nil {
|
||||
return // vault seal matches current password — all good
|
||||
uek, err := crypto.UnwrapUEK(encryptedUEK, nonce, pdk)
|
||||
if err == nil {
|
||||
// Vault seal matches current password — cache UEK if cache provided
|
||||
if len(uekCache) > 0 && uekCache[0] != nil {
|
||||
uekCache[0].Store(userID, uek)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Stale seal: password has actually changed since the vault was sealed
|
||||
@@ -465,7 +475,9 @@ func (h *AuthHandler) unlockVault(ctx context.Context, user *models.User, passwo
|
||||
}
|
||||
|
||||
// BootstrapAdmin creates/updates the admin user from env vars (K8s secret).
|
||||
func BootstrapAdmin(cfg *config.Config, s store.Stores) {
|
||||
// When uekCache is provided, the admin's vault is pre-warmed so BYOK
|
||||
// operations work immediately without requiring a fresh login.
|
||||
func BootstrapAdmin(cfg *config.Config, s store.Stores, uekCache ...*crypto.UEKCache) {
|
||||
if cfg.AdminUsername == "" || cfg.AdminPassword == "" {
|
||||
return
|
||||
}
|
||||
@@ -492,7 +504,11 @@ func BootstrapAdmin(cfg *config.Config, s store.Stores) {
|
||||
handle := auth.UniqueHandle(ctx, s.Users, models.HandleFromName(cfg.AdminUsername))
|
||||
s.Users.Update(ctx, existing.ID, map[string]interface{}{"handle": handle})
|
||||
}
|
||||
ProbeAndRepairVault(ctx, s, existing.ID, cfg.AdminPassword)
|
||||
var cache *crypto.UEKCache
|
||||
if len(uekCache) > 0 {
|
||||
cache = uekCache[0]
|
||||
}
|
||||
ProbeAndRepairVault(ctx, s, existing.ID, cfg.AdminPassword, cache)
|
||||
log.Printf(" ✅ Admin user '%s' updated", cfg.AdminUsername)
|
||||
return
|
||||
}
|
||||
@@ -524,7 +540,7 @@ func BootstrapAdmin(cfg *config.Config, s store.Stores) {
|
||||
// Format: "user:pass:role,user2:pass2:role2" where role is "admin" or "user".
|
||||
// Upsert: existing users get their password and role refreshed on every restart.
|
||||
// Gated to non-production environments.
|
||||
func SeedUsers(cfg *config.Config, s store.Stores) {
|
||||
func SeedUsers(cfg *config.Config, s store.Stores, uekCache ...*crypto.UEKCache) {
|
||||
if cfg.SeedUsers == "" {
|
||||
log.Printf(" ℹ SEED_USERS not set, skipping")
|
||||
return
|
||||
@@ -582,7 +598,11 @@ func SeedUsers(cfg *config.Config, s store.Stores) {
|
||||
handle := auth.UniqueHandle(ctx, s.Users, models.HandleFromName(username))
|
||||
s.Users.Update(ctx, existing.ID, map[string]interface{}{"handle": handle})
|
||||
}
|
||||
ProbeAndRepairVault(ctx, s, existing.ID, password)
|
||||
var cache *crypto.UEKCache
|
||||
if len(uekCache) > 0 {
|
||||
cache = uekCache[0]
|
||||
}
|
||||
ProbeAndRepairVault(ctx, s, existing.ID, password, cache)
|
||||
log.Printf(" 🌱 Seed user '%s' updated (role=%s)", username, role)
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user