feat: authsession service

This commit is contained in:
Ilia Denisov
2026-04-08 16:23:07 +02:00
committed by GitHub
parent 28f04916af
commit 86a68ed9d0
174 changed files with 31732 additions and 112 deletions
@@ -0,0 +1,43 @@
package ports
import (
"context"
"fmt"
"galaxy/authsession/internal/domain/challenge"
"galaxy/authsession/internal/domain/common"
)
// ChallengeStore provides source-of-truth persistence for auth confirmation
// challenges without exposing storage-specific primitives.
type ChallengeStore interface {
// Get returns the stored challenge for challengeID. Implementations must
// wrap ErrNotFound when challengeID does not exist.
Get(ctx context.Context, challengeID common.ChallengeID) (challenge.Challenge, error)
// Create persists record as a new challenge. Implementations must wrap
// ErrConflict when record.ID already exists.
Create(ctx context.Context, record challenge.Challenge) error
// CompareAndSwap replaces previous with next when the currently stored
// challenge matches previous exactly. Implementations must wrap ErrConflict
// when the stored challenge differs from previous and wrap ErrNotFound when
// previous.ID does not exist.
CompareAndSwap(ctx context.Context, previous challenge.Challenge, next challenge.Challenge) error
}
// ValidateComparableChallenges reports whether previous and next are suitable
// for one ChallengeStore compare-and-swap call.
func ValidateComparableChallenges(previous challenge.Challenge, next challenge.Challenge) error {
if err := previous.Validate(); err != nil {
return fmt.Errorf("previous challenge: %w", err)
}
if err := next.Validate(); err != nil {
return fmt.Errorf("next challenge: %w", err)
}
if previous.ID != next.ID {
return fmt.Errorf("challenge compare-and-swap ids must match: %q != %q", previous.ID, next.ID)
}
return nil
}