mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:17:32 +00:00
feat(api): add otp (sms and email) checks in session api (#6422)
* feat: add otp (sms and email) checks in session api * implement sending * fix tests * add tests * add integration tests * fix merge main and add tests * put default OTP Email url into config --------- Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
This commit is contained in:
@@ -10,6 +10,12 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
||||
RegisterFilterEventMapper(AggregateType, WebAuthNChallengedType, eventstore.GenericEventMapper[WebAuthNChallengedEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, WebAuthNCheckedType, eventstore.GenericEventMapper[WebAuthNCheckedEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, TOTPCheckedType, eventstore.GenericEventMapper[TOTPCheckedEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, OTPSMSChallengedType, eventstore.GenericEventMapper[OTPSMSChallengedEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, OTPSMSSentType, eventstore.GenericEventMapper[OTPSMSSentEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, OTPSMSCheckedType, eventstore.GenericEventMapper[OTPSMSCheckedEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, OTPEmailChallengedType, eventstore.GenericEventMapper[OTPEmailChallengedEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, OTPEmailSentType, eventstore.GenericEventMapper[OTPEmailSentEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, OTPEmailCheckedType, eventstore.GenericEventMapper[OTPEmailCheckedEvent]).
|
||||
RegisterFilterEventMapper(AggregateType, TokenSetType, TokenSetEventMapper).
|
||||
RegisterFilterEventMapper(AggregateType, MetadataSetType, MetadataSetEventMapper).
|
||||
RegisterFilterEventMapper(AggregateType, TerminateType, TerminateEventMapper)
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
@@ -20,6 +21,12 @@ const (
|
||||
WebAuthNChallengedType = sessionEventPrefix + "webAuthN.challenged"
|
||||
WebAuthNCheckedType = sessionEventPrefix + "webAuthN.checked"
|
||||
TOTPCheckedType = sessionEventPrefix + "totp.checked"
|
||||
OTPSMSChallengedType = sessionEventPrefix + "otp.sms.challenged"
|
||||
OTPSMSSentType = sessionEventPrefix + "otp.sms.sent"
|
||||
OTPSMSCheckedType = sessionEventPrefix + "otp.sms.checked"
|
||||
OTPEmailChallengedType = sessionEventPrefix + "otp.email.challenged"
|
||||
OTPEmailSentType = sessionEventPrefix + "otp.email.sent"
|
||||
OTPEmailCheckedType = sessionEventPrefix + "otp.email.checked"
|
||||
TokenSetType = sessionEventPrefix + "token.set"
|
||||
MetadataSetType = sessionEventPrefix + "metadata.set"
|
||||
TerminateType = sessionEventPrefix + "terminated"
|
||||
@@ -298,6 +305,211 @@ func NewTOTPCheckedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
type OTPSMSChallengedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
Code *crypto.CryptoValue `json:"code"`
|
||||
Expiry time.Duration `json:"expiry"`
|
||||
CodeReturned bool `json:"codeReturned,omitempty"`
|
||||
}
|
||||
|
||||
func (e *OTPSMSChallengedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *OTPSMSChallengedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OTPSMSChallengedEvent) SetBaseEvent(base *eventstore.BaseEvent) {
|
||||
e.BaseEvent = *base
|
||||
}
|
||||
|
||||
func NewOTPSMSChallengedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
code *crypto.CryptoValue,
|
||||
expiry time.Duration,
|
||||
codeReturned bool,
|
||||
) *OTPSMSChallengedEvent {
|
||||
return &OTPSMSChallengedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
OTPSMSChallengedType,
|
||||
),
|
||||
Code: code,
|
||||
Expiry: expiry,
|
||||
CodeReturned: codeReturned,
|
||||
}
|
||||
}
|
||||
|
||||
type OTPSMSSentEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *OTPSMSSentEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *OTPSMSSentEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OTPSMSSentEvent) SetBaseEvent(base *eventstore.BaseEvent) {
|
||||
e.BaseEvent = *base
|
||||
}
|
||||
|
||||
func NewOTPSMSSentEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *OTPSMSSentEvent {
|
||||
return &OTPSMSSentEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
OTPSMSSentType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type OTPSMSCheckedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
CheckedAt time.Time `json:"checkedAt"`
|
||||
}
|
||||
|
||||
func (e *OTPSMSCheckedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *OTPSMSCheckedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OTPSMSCheckedEvent) SetBaseEvent(base *eventstore.BaseEvent) {
|
||||
e.BaseEvent = *base
|
||||
}
|
||||
|
||||
func NewOTPSMSCheckedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
checkedAt time.Time,
|
||||
) *OTPSMSCheckedEvent {
|
||||
return &OTPSMSCheckedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
OTPSMSCheckedType,
|
||||
),
|
||||
CheckedAt: checkedAt,
|
||||
}
|
||||
}
|
||||
|
||||
type OTPEmailChallengedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
Code *crypto.CryptoValue `json:"code"`
|
||||
Expiry time.Duration `json:"expiry"`
|
||||
ReturnCode bool `json:"returnCode,omitempty"`
|
||||
URLTmpl string `json:"urlTmpl,omitempty"`
|
||||
}
|
||||
|
||||
func (e *OTPEmailChallengedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *OTPEmailChallengedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OTPEmailChallengedEvent) SetBaseEvent(base *eventstore.BaseEvent) {
|
||||
e.BaseEvent = *base
|
||||
}
|
||||
|
||||
func NewOTPEmailChallengedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
code *crypto.CryptoValue,
|
||||
expiry time.Duration,
|
||||
returnCode bool,
|
||||
urlTmpl string,
|
||||
) *OTPEmailChallengedEvent {
|
||||
return &OTPEmailChallengedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
OTPEmailChallengedType,
|
||||
),
|
||||
Code: code,
|
||||
Expiry: expiry,
|
||||
ReturnCode: returnCode,
|
||||
URLTmpl: urlTmpl,
|
||||
}
|
||||
}
|
||||
|
||||
type OTPEmailSentEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *OTPEmailSentEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *OTPEmailSentEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OTPEmailSentEvent) SetBaseEvent(base *eventstore.BaseEvent) {
|
||||
e.BaseEvent = *base
|
||||
}
|
||||
|
||||
func NewOTPEmailSentEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *OTPEmailSentEvent {
|
||||
return &OTPEmailSentEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
OTPEmailSentType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type OTPEmailCheckedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
CheckedAt time.Time `json:"checkedAt"`
|
||||
}
|
||||
|
||||
func (e *OTPEmailCheckedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *OTPEmailCheckedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OTPEmailCheckedEvent) SetBaseEvent(base *eventstore.BaseEvent) {
|
||||
e.BaseEvent = *base
|
||||
}
|
||||
|
||||
func NewOTPEmailCheckedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
checkedAt time.Time,
|
||||
) *OTPEmailCheckedEvent {
|
||||
return &OTPEmailCheckedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
OTPEmailCheckedType,
|
||||
),
|
||||
CheckedAt: checkedAt,
|
||||
}
|
||||
}
|
||||
|
||||
type TokenSetEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
|
Reference in New Issue
Block a user