Files
OpenFlare/backend/openflare/plugins/server/kernel/credential/sensitive.go
T

72 lines
1.7 KiB
Go

// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
// Package credential seals and opens OpenFlare integration credentials.
package credential
import (
"crypto/sha256"
"encoding/hex"
"errors"
"strings"
"Wavelet/openflare/plugins/server/kernel/runtimeconfig"
"Wavelet/pkg/util"
)
// Prefix identifies values encrypted with the current credential format.
const Prefix = "enc:v1:"
var sessionSecret string
// SetSessionSecret binds the host session secret used to seal credentials.
func SetSessionSecret(secret string) {
sessionSecret = strings.TrimSpace(secret)
}
func encryptionKey() string {
secret := strings.TrimSpace(sessionSecret)
if secret == "" {
secret = strings.TrimSpace(runtimeconfig.SessionSecret())
}
if secret == "" {
return ""
}
sum := sha256.Sum256([]byte(secret))
return hex.EncodeToString(sum[:])
}
// Seal trims and encrypts plaintext when a session secret is configured.
// Plaintext storage is preserved for installations without a session secret.
func Seal(plaintext string) (string, error) {
plaintext = strings.TrimSpace(plaintext)
if plaintext == "" {
return "", nil
}
key := encryptionKey()
if key == "" {
return plaintext, nil
}
encrypted, err := util.Encrypt(key, plaintext)
if err != nil {
return "", err
}
return Prefix + encrypted, nil
}
// Open decrypts a sealed value and accepts legacy plaintext values.
func Open(stored string) (string, error) {
stored = strings.TrimSpace(stored)
if stored == "" {
return "", nil
}
if !strings.HasPrefix(stored, Prefix) {
return stored, nil
}
key := encryptionKey()
if key == "" {
return "", errors.New("cannot decrypt sensitive field without session secret")
}
return util.Decrypt(key, strings.TrimPrefix(stored, Prefix))
}