Files
zitadel/internal/notification/channels/smtp/generic_auth.go
T
3fc0ef2506 feat: added xoauth for smtp (#11239)
# Which Problems Are Solved

- Some mail providers (e.g.: MS Exchange) have deprecated plain auth

# How the Problems Are Solved

Adds XOauth2 auth option to SMPT
- SMTP config now can contain XOAuth2 auth config
- Proto files are updated to have a oneof for configuration selection.
Old fields for configuring plain auth are still available not to create
a breaking change. These can be removed in the future.
- Columns are added to the database to persist the config

# Additional Changes

none

# Additional Context

Replace this example with links to related issues, discussions, discord
threads, or other sources with more context.
Use the Closing #issue syntax for issues that are resolved with this PR.
- Closes #8042

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Tim Möhlmann <[email protected]>
2026-01-27 15:11:56 +01:00

42 lines
1.1 KiB
Go

package smtp
import (
"net/smtp"
"slices"
"github.com/zitadel/zitadel/internal/zerrors"
)
type GenericAuth struct {
Host string
PlainOrLogin *plainOrLoginAuth
XOAuth2 *xoauth2Auth
selectedMethod smtp.Auth
}
func (a *GenericAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
if server.Name != a.Host {
return "", nil, zerrors.ThrowInternal(nil, "SMTP-BtXgkX", "wrong host name")
}
switch {
case slices.Contains(server.Auth, "XOAUTH2") && a.XOAuth2 != nil:
a.selectedMethod = a.XOAuth2
case slices.Contains(server.Auth, "PLAIN") && a.PlainOrLogin != nil:
a.selectedMethod = a.PlainOrLogin
case slices.Contains(server.Auth, "LOGIN") && a.PlainOrLogin != nil:
a.selectedMethod = a.PlainOrLogin
default:
return "", nil, zerrors.ThrowInternalf(nil, "SMTP-3mBHTz", "no supported auth method found (server supports: %v)", server.Auth)
}
return a.selectedMethod.Start(server)
}
func (a *GenericAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if a.selectedMethod == nil {
return nil, zerrors.ThrowInternal(nil, "SMTP-G99DUr", "no auth method selected")
}
return a.selectedMethod.Next(fromServer, more)
}