75 lines
2.9 KiB
Go
75 lines
2.9 KiB
Go
package flow
|
|
|
|
import (
|
|
"context"
|
|
customer "git.sendico.io/tech/sxchnge/product/customers/model"
|
|
"git.sendico.io/tech/sxchnge/product/notifications"
|
|
model "git.sendico.io/tech/sxchnge/product/verification/model"
|
|
verification "git.sendico.io/tech/sxchnge/product/verification/store"
|
|
merrors "git.sendico.io/tech/sxchnge/shared/errors"
|
|
"github.com/stretchr/testify/require"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type tokenStub struct {
|
|
verification.DB
|
|
request *verification.Request
|
|
result verification.CreateResult
|
|
err error
|
|
}
|
|
|
|
func (s *tokenStub) CreateWithResult(_ context.Context, r *verification.Request) (verification.CreateResult, error) {
|
|
s.request = r
|
|
return s.result, s.err
|
|
}
|
|
|
|
type senderStub struct {
|
|
messages []notifications.Message
|
|
err error
|
|
}
|
|
|
|
func (s *senderStub) Send(_ context.Context, m notifications.Message) error {
|
|
s.messages = append(s.messages, m)
|
|
return s.err
|
|
}
|
|
func TestIssueRetriesSamePayloadAndBindsServerSecret(t *testing.T) {
|
|
expiry := time.Now().UTC().Add(time.Minute)
|
|
tokens := &tokenStub{result: verification.CreateResult{VerificationToken: "123456", ExpiresAt: expiry}}
|
|
sender := &senderStub{err: merrors.ServiceUnavailable("queue")}
|
|
service := &Service{Tokens: tokens, Sender: sender, Secret: []byte(strings.Repeat("s", 32))}
|
|
a := &customer.Account{}
|
|
a.ID = bson.NewObjectID()
|
|
a.Login = "user@example.com"
|
|
a.Locale = "ru-RU"
|
|
_, err := service.Issue(context.Background(), a, model.PurposeLogin, "pending-scope", "client-key", expiry)
|
|
require.Error(t, err)
|
|
key := *tokens.request.IdempotencyKey
|
|
require.NotEqual(t, "client-key", key)
|
|
require.Equal(t, "pending-scope", tokens.request.ContextRef)
|
|
require.LessOrEqual(t, tokens.request.Ttl, time.Minute)
|
|
sender.err = nil
|
|
_, err = service.Issue(context.Background(), a, model.PurposeLogin, "pending-scope", "client-key", expiry)
|
|
require.NoError(t, err)
|
|
require.Equal(t, sender.messages[0], sender.messages[1])
|
|
require.Equal(t, "ru", sender.messages[0].Locale)
|
|
service.Secret = []byte(strings.Repeat("b", 32))
|
|
require.NotEqual(t, key, service.key(a.ID.Hex(), string(model.PurposeLogin), "pending-scope", "client-key"))
|
|
tokens.result.ExpiresAt = time.Now().Add(-time.Minute)
|
|
_, err = service.Issue(context.Background(), a, model.PurposeLogin, "pending-scope", "expired")
|
|
require.ErrorIs(t, err, verification.ErrTokenExpired)
|
|
require.Len(t, sender.messages, 2)
|
|
}
|
|
func TestValidateActivationDestination(t *testing.T) {
|
|
for _, destination := range []string{"https://app.example/verify-email", "http://localhost:5126/verify-email"} {
|
|
s := &Service{Secret: []byte(strings.Repeat("s", 32)), ActivationURL: destination}
|
|
require.NoError(t, s.Validate())
|
|
}
|
|
for _, destination := range []string{"http://app.example/verify-email", "//app.example", "https://user:pass@app.example/verify-email", "https://app.example/#/verify"} {
|
|
s := &Service{Secret: []byte(strings.Repeat("s", 32)), ActivationURL: destination}
|
|
require.Error(t, s.Validate())
|
|
}
|
|
}
|