mirror of
https://github.com/zitadel/zitadel.git
synced 2025-10-26 23:51:42 +00:00
feat: passwordless registration (#2103)
* begin pw less registration * create pwless one time codes * send pwless link * separate send and add passwordless link * separate send and add passwordless link events * custom message text for passwordless registration * begin custom login texts for passwordless * i18n * i18n message * i18n message * custom message text * custom login text * org design and texts * create link in human import process * fix import human tests * begin passwordless init required step * passwordless init * passwordless init * do not return link in mgmt api * prompt * passwordless init only (no additional prompt) * cleanup * cleanup * add passwordless prompt to custom login text * increase init code complexity * fix grpc * cleanup * fix and add some cases for nextStep tests * fix tests * Update internal/notification/static/i18n/en.yaml * Update internal/notification/static/i18n/de.yaml * Update proto/zitadel/management.proto * Update internal/ui/login/static/i18n/de.yaml * Update internal/ui/login/static/i18n/de.yaml * Update internal/ui/login/static/i18n/de.yaml Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/notification/types"
|
||||
user_repo "github.com/caos/zitadel/internal/repository/user"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@@ -124,6 +125,8 @@ func (n *Notification) Reduce(event *models.Event) (err error) {
|
||||
err = n.handlePasswordCode(event)
|
||||
case es_model.DomainClaimed:
|
||||
err = n.handleDomainClaimed(event)
|
||||
case models.EventType(user_repo.HumanPasswordlessInitCodeRequestedType):
|
||||
err = n.handlePasswordlessRegistrationLink(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -312,6 +315,52 @@ func (n *Notification) handleDomainClaimed(event *models.Event) (err error) {
|
||||
return n.command.UserDomainClaimedSent(ctx, event.ResourceOwner, event.AggregateID)
|
||||
}
|
||||
|
||||
func (n *Notification) handlePasswordlessRegistrationLink(event *models.Event) (err error) {
|
||||
addedEvent := new(user_repo.HumanPasswordlessInitCodeRequestedEvent)
|
||||
if err := json.Unmarshal(event.Data, addedEvent); err != nil {
|
||||
return err
|
||||
}
|
||||
events, err := n.getUserEvents(event.AggregateID, event.Sequence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, e := range events {
|
||||
if e.Type == models.EventType(user_repo.HumanPasswordlessInitCodeSentType) {
|
||||
sentEvent := new(user_repo.HumanPasswordlessInitCodeSentEvent)
|
||||
if err := json.Unmarshal(e.Data, sentEvent); err != nil {
|
||||
return err
|
||||
}
|
||||
if sentEvent.ID == addedEvent.ID {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
user, err := n.getUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := getSetNotifyContextData(event.ResourceOwner)
|
||||
colors, err := n.getLabelPolicy(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template, err := n.getMailTemplate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
translator, err := n.getTranslatorWithOrgTexts(user.ResourceOwner, domain.PasswordlessRegistrationMessageType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = types.SendPasswordlessRegistrationLink(string(template.Template), translator, user, addedEvent, n.systemDefaults, n.AesCrypto, colors, n.apiDomain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n.command.HumanPasswordlessInitCodeSent(ctx, event.AggregateID, event.ResourceOwner, addedEvent.ID)
|
||||
}
|
||||
|
||||
func (n *Notification) checkIfCodeAlreadyHandledOrExpired(event *models.Event, expiry time.Duration, eventTypes ...models.EventType) (bool, error) {
|
||||
if event.CreationDate.Add(expiry).Before(time.Now().UTC()) {
|
||||
return true, nil
|
||||
|
||||
Reference in New Issue
Block a user