feat: authsession service
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package ports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"galaxy/authsession/internal/domain/common"
|
||||
)
|
||||
|
||||
// MailSender delivers the public login code or intentionally suppresses
|
||||
// outward delivery while keeping the auth flow success-shaped.
|
||||
type MailSender interface {
|
||||
// SendLoginCode attempts delivery for one generated login code. Explicit
|
||||
// delivery failure is reported through error, while sent vs suppressed is
|
||||
// returned in the result.
|
||||
SendLoginCode(ctx context.Context, input SendLoginCodeInput) (SendLoginCodeResult, error)
|
||||
}
|
||||
|
||||
// SendLoginCodeInput describes one mail-delivery request generated by the auth
|
||||
// flow.
|
||||
type SendLoginCodeInput struct {
|
||||
// Email identifies the normalized target e-mail address.
|
||||
Email common.Email
|
||||
|
||||
// Code stores the cleartext login code that should be delivered to Email.
|
||||
Code string
|
||||
}
|
||||
|
||||
// Validate reports whether SendLoginCodeInput contains a complete delivery
|
||||
// request.
|
||||
func (i SendLoginCodeInput) Validate() error {
|
||||
if err := i.Email.Validate(); err != nil {
|
||||
return fmt.Errorf("send login code input email: %w", err)
|
||||
}
|
||||
switch {
|
||||
case strings.TrimSpace(i.Code) == "":
|
||||
return errors.New("send login code input code must not be empty")
|
||||
case strings.TrimSpace(i.Code) != i.Code:
|
||||
return errors.New("send login code input code must not contain surrounding whitespace")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// SendLoginCodeOutcome identifies the coarse mail-delivery outcome reported
|
||||
// back to the auth flow.
|
||||
type SendLoginCodeOutcome string
|
||||
|
||||
const (
|
||||
// SendLoginCodeOutcomeSent reports that delivery was attempted and accepted.
|
||||
SendLoginCodeOutcomeSent SendLoginCodeOutcome = "sent"
|
||||
|
||||
// SendLoginCodeOutcomeSuppressed reports that outward behavior remains
|
||||
// success-shaped while actual delivery is intentionally skipped.
|
||||
SendLoginCodeOutcomeSuppressed SendLoginCodeOutcome = "suppressed"
|
||||
)
|
||||
|
||||
// IsKnown reports whether SendLoginCodeOutcome is supported by the current
|
||||
// mail-sender contract.
|
||||
func (o SendLoginCodeOutcome) IsKnown() bool {
|
||||
switch o {
|
||||
case SendLoginCodeOutcomeSent, SendLoginCodeOutcomeSuppressed:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// SendLoginCodeResult describes the stable outcome returned by MailSender for
|
||||
// one delivery request.
|
||||
type SendLoginCodeResult struct {
|
||||
// Outcome reports whether delivery was sent or intentionally suppressed.
|
||||
Outcome SendLoginCodeOutcome
|
||||
}
|
||||
|
||||
// Validate reports whether SendLoginCodeResult satisfies the mail-sender
|
||||
// contract invariants.
|
||||
func (r SendLoginCodeResult) Validate() error {
|
||||
if !r.Outcome.IsKnown() {
|
||||
return fmt.Errorf("send login code result outcome %q is unsupported", r.Outcome)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user