mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
# Which Problems Are Solved This PR adds the OTP SMS Challenge needed for CreateSession API https://github.com/zitadel/zitadel/issues/11035 # How the Problems Are Solved - Introduce `OTPSMSChallengeCommand` (validate/execute/events) for session creation checks - Introduce `GetOTPCryptoGeneratorConfigWithDefault` to fetch per-instance secret generator settings - Add unit tests # Additional Changes Refactor tests in `session_check_recovery_code_test.go` to make the helper functions reusable in `session_challenge_otp_sms_test.go` # Additional Context Related to https://github.com/zitadel/zitadel/issues/11035
77 lines
2.3 KiB
Go
77 lines
2.3 KiB
Go
package domain
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
|
"github.com/zitadel/zitadel/internal/crypto"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
)
|
|
|
|
type newOTPCodeFunc func(g crypto.Generator) (*crypto.CryptoValue, string, error)
|
|
|
|
type OTPType int64
|
|
|
|
const (
|
|
OTPTypeSMS OTPType = iota
|
|
OTPTypeEmail
|
|
)
|
|
|
|
func GetOTPCryptoGeneratorConfigWithDefault(ctx context.Context, instanceID string, opts *InvokeOpts, defaultConfig *crypto.GeneratorConfig, otpType OTPType) (*crypto.GeneratorConfig, error) {
|
|
if defaultConfig == nil {
|
|
return nil, zerrors.ThrowInternal(nil, "DOM-3AcM0U", "missing default config")
|
|
}
|
|
|
|
if opts == nil || opts.secretGeneratorSettingsRepo == nil {
|
|
return defaultConfig, nil
|
|
}
|
|
|
|
settingsRepo := opts.secretGeneratorSettingsRepo
|
|
cfg, err := settingsRepo.Get(
|
|
ctx,
|
|
opts.DB(),
|
|
database.WithCondition(
|
|
settingsRepo.UniqueCondition(instanceID, nil, SettingTypeSecretGenerator, SettingStateActive),
|
|
),
|
|
)
|
|
if err := handleGetError(err, "DOM-x7Yd3E", "SecretGeneratorSettings"); err != nil {
|
|
return nil, err // todo: or return defaultConfig?
|
|
}
|
|
|
|
if cfg.State != SettingStateActive {
|
|
return defaultConfig, nil
|
|
}
|
|
|
|
var attrs SecretGeneratorAttrsWithExpiry
|
|
switch otpType {
|
|
case OTPTypeSMS:
|
|
if cfg.OTPSMS == nil {
|
|
return defaultConfig, nil
|
|
}
|
|
attrs = cfg.OTPSMS.SecretGeneratorAttrsWithExpiry
|
|
case OTPTypeEmail:
|
|
if cfg.OTPEmail == nil {
|
|
return defaultConfig, nil
|
|
}
|
|
attrs = cfg.OTPEmail.SecretGeneratorAttrsWithExpiry
|
|
default:
|
|
return nil, zerrors.ThrowInternal(nil, "DOM-3AcM0U", "invalid otp type")
|
|
}
|
|
return &crypto.GeneratorConfig{
|
|
Length: getValueOrDefault(attrs.Length, defaultConfig.Length),
|
|
Expiry: getValueOrDefault(attrs.Expiry, defaultConfig.Expiry),
|
|
IncludeLowerLetters: getValueOrDefault(attrs.IncludeLowerLetters, defaultConfig.IncludeLowerLetters),
|
|
IncludeUpperLetters: getValueOrDefault(attrs.IncludeUpperLetters, defaultConfig.IncludeUpperLetters),
|
|
IncludeDigits: getValueOrDefault(attrs.IncludeDigits, defaultConfig.IncludeDigits),
|
|
IncludeSymbols: getValueOrDefault(attrs.IncludeSymbols, defaultConfig.IncludeSymbols),
|
|
}, nil
|
|
}
|
|
|
|
// getValueOrDefault safely dereferences a pointer or returns a default value
|
|
func getValueOrDefault[T any](ptr *T, defaultVal T) T {
|
|
if ptr != nil {
|
|
return *ptr
|
|
}
|
|
return defaultVal
|
|
}
|