mirror of
https://gh-proxy.org/https://github.com/klinsmaya/new-api.git
synced 2026-11-08 01:17:09 +08:00
Require scoped, single-use verification for account bindings and password operations. Bind OAuth authorization and email confirmations to the initiating session; preserve the last usable login method and audit operation outcomes. Apply Unicode-aware password length limits, Argon2id writes with bcrypt compatibility, and long-password encryption. Return has_password with the existing profile SELECT without extra queries. Reuse the existing security dialogs and add all seven locale translations. Validation: - Go: go test ./common ./model ./service ./middleware ./controller ./router -count=1 - DB: SQLite 3.50.4, MySQL 8.4.11, PostgreSQL 16.15; separate main/log databases - MySQL/PostgreSQL: TEST_SECURITY_DIALECT=<dialect> with TEST_<DIALECT>_DSN, go test ./controller -run '^(TestSecurityAccount|TestSecurityEnrollment|TestGenerateOAuthCode|TestOAuthBind|TestTelegramOAuth)' -count=1 -v - Web: relevant Vitest suites, bun run typecheck, targeted oxlint/format, bun run i18n:sync, and bun run build Roll out dual-format readers to every instance with ACCOUNT_PASSWORD_HASH_ALGORITHM=bcrypt before enabling Argon2id writes and the new UI. Rollbacks must retain Argon2id and v2 envelope readers. Relevant controls: ASVS 5.0.0 6.2.1-6.2.3, 6.2.5-6.2.9, 6.3.7, 7.4.3, 7.5.1; this change does not assert application-wide ASVS certification.
37 lines
902 B
Go
37 lines
902 B
Go
package common
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"strings"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func GenerateHMACWithKey(key []byte, data string) string {
|
|
h := hmac.New(sha256.New, key)
|
|
h.Write([]byte(data))
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|
|
|
|
func GenerateHMAC(data string) string {
|
|
h := hmac.New(sha256.New, []byte(CryptoSecret))
|
|
h.Write([]byte(data))
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|
|
|
|
func Password2Hash(password string) (string, error) {
|
|
passwordBytes := []byte(password)
|
|
hashedPassword, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
|
|
return string(hashedPassword), err
|
|
}
|
|
|
|
func ValidatePasswordAndHash(password string, hash string) bool {
|
|
if strings.HasPrefix(hash, "$argon2id$") {
|
|
return validateArgon2AccountPassword(password, hash)
|
|
}
|
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
|
return err == nil
|
|
}
|