Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: rename phone channel to sms
Browse files Browse the repository at this point in the history
jonas-jonas committed Jan 5, 2024
1 parent d8b42f0 commit 9808796
Showing 20 changed files with 197 additions and 97 deletions.
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
}
},
"verification": {
"via": "phone"
"via": "sms"
}
}
}
4 changes: 2 additions & 2 deletions contrib/quickstart/kratos/phone-password/kratos.yml
Original file line number Diff line number Diff line change
@@ -96,12 +96,12 @@ identity:

courier:
channels:
- id: phone
- id: sms
type: http
request_config:
url: https://api.twilio.com/2010-04-01/Accounts/AXXXXXXXXXXXXXX/Messages.json
method: POST
body: base64://ZnVuY3Rpb24oY3R4KSB7CkJvZHk6IGN0eC5ib2R5LApUbzogY3R4LnRvLEZyb206IGN0eC5mcm9tCn0=
body: base64://ZnVuY3Rpb24oY3R4KSB7ClRvOiBjdHguUmVjaXBpZW50LApCb2R5OiBjdHguQm9keSwKfQ==
headers:
Content-Type: application/x-www-form-urlencoded
auth:
10 changes: 5 additions & 5 deletions courier/http_channel.go
Original file line number Diff line number Diff line change
@@ -61,12 +61,12 @@ func (c *httpChannel) Dispatch(ctx context.Context, msg Message) (err error) {

builder, err := request.NewBuilder(ctx, c.requestConfig, c.d)
if err != nil {
return err
return errors.WithStack(err)

Check warning on line 64 in courier/http_channel.go

Codecov / codecov/patch

courier/http_channel.go#L64

Added line #L64 was not covered by tests
}

tmpl, err := newTemplate(c.d, msg)
if err != nil {
return err
return errors.WithStack(err)

Check warning on line 69 in courier/http_channel.go

Codecov / codecov/patch

courier/http_channel.go#L69

Added line #L69 was not covered by tests
}

td := httpDataModel{
@@ -80,12 +80,12 @@ func (c *httpChannel) Dispatch(ctx context.Context, msg Message) (err error) {

req, err := builder.BuildRequest(ctx, td)
if err != nil {
return err
return errors.WithStack(err)

Check warning on line 83 in courier/http_channel.go

Codecov / codecov/patch

courier/http_channel.go#L83

Added line #L83 was not covered by tests
}

res, err := c.d.HTTPClient(ctx).Do(req)
if err != nil {
return err
return errors.WithStack(err)
}

if res.StatusCode >= 200 && res.StatusCode < 300 {
@@ -109,7 +109,7 @@ func (c *httpChannel) Dispatch(ctx context.Context, msg Message) (err error) {
WithField("message_subject", msg.Subject).
WithError(err).
Error("sending mail via HTTP failed.")
return err
return errors.WithStack(err)

Check warning on line 112 in courier/http_channel.go

Codecov / codecov/patch

courier/http_channel.go#L112

Added line #L112 was not covered by tests
}

func newTemplate(d template.Dependencies, msg Message) (Template, error) {
2 changes: 1 addition & 1 deletion courier/sms.go
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ func (c *courier) QueueSMS(ctx context.Context, t SMSTemplate) (uuid.UUID, error
message := &Message{
Status: MessageStatusQueued,
Type: MessageTypeSMS,
Channel: "phone",
Channel: "sms",
Recipient: recipient,
TemplateType: t.TemplateType(),
TemplateData: templateData,
4 changes: 2 additions & 2 deletions courier/sms_test.go
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ func TestQueueSMS(t *testing.T) {
conf, reg := internal.NewFastRegistryWithMocks(t)
conf.MustSet(ctx, config.ViperKeyCourierChannels, fmt.Sprintf(`[
{
"id": "phone",
"id": "sms",
"type": "http",
"request_config": %s
}
@@ -122,7 +122,7 @@ func TestDisallowedInternalNetwork(t *testing.T) {
conf, reg := internal.NewFastRegistryWithMocks(t)
conf.MustSet(ctx, config.ViperKeyCourierChannels, `[
{
"id": "phone",
"id": "sms",
"type": "http",
"request_config": {
"url": "http://127.0.0.1/",
2 changes: 1 addition & 1 deletion embedx/config.schema.json
Original file line number Diff line number Diff line change
@@ -1999,7 +1999,7 @@
"title": "Channel id",
"description": "The channel id. Corresponds to the .via property of the identity schema for recovery, verification, etc. Currently only phone is supported.",
"maxLength": 32,
"enum": ["phone"]
"enum": ["sms"]
},
"type": {
"type": "string",
2 changes: 1 addition & 1 deletion embedx/identity_extension.schema.json
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@
"properties": {
"via": {
"type": "string",
"enum": ["email", "phone"]
"enum": ["email", "sms"]
}
}
},
20 changes: 14 additions & 6 deletions embedx/identity_meta.schema.json
Original file line number Diff line number Diff line change
@@ -10,9 +10,7 @@
"properties": {
"properties": {
"type": "object",
"required": [
"traits"
],
"required": ["traits"],
"properties": {
"traits": {
"type": "object",
@@ -27,6 +25,18 @@
"patternProperties": {
".*": {
"type": "object",
"properties": {
"format": {
"enum": [
"email",
"tel",
"date",
"time",
"date-time",
"noformat"
]
}
},
"allOf": [
{
"$ref": "ory://identity-extension"
@@ -40,9 +50,7 @@
}
}
},
"required": [
"properties"
]
"required": ["properties"]
}
]
}
72 changes: 49 additions & 23 deletions identity/extension_verification.go
Original file line number Diff line number Diff line change
@@ -9,10 +9,18 @@ import (
"sync"
"time"

"golang.org/x/exp/maps"

"github.com/ory/jsonschema/v3"
"github.com/ory/kratos/schema"
)

func init() {
jsonschema.Formats["noformat"] = func(v interface{}) bool {
return true
}
}

type SchemaExtensionVerification struct {
lifespan time.Duration
l sync.Mutex
@@ -24,40 +32,58 @@ func NewSchemaExtensionVerification(i *Identity, lifespan time.Duration) *Schema
return &SchemaExtensionVerification{i: i, lifespan: lifespan}
}

const (
ChannelTypeEmail = "email"
ChannelTypeSMS = "sms"
ChannelTypePhone = "phone"
)

func (r *SchemaExtensionVerification) Run(ctx jsonschema.ValidationContext, s schema.ExtensionConfig, value interface{}) error {
r.l.Lock()
defer r.l.Unlock()

switch s.Verification.Via {
case AddressTypeEmail:
if !jsonschema.Formats["email"](value) {
return ctx.Error("format", "%q is not valid %q", value, "email")
}

address := NewVerifiableEmailAddress(
strings.ToLower(strings.TrimSpace(
fmt.Sprintf("%s", value))), r.i.ID)

r.appendAddress(address)
if s.Verification.Via == "" {
return nil
}

format, ok := s.RawSchema["format"]
if !ok {
format = ""
}
formatString, ok := format.(string)
if !ok {
return nil
}

case AddressTypePhone:
if !jsonschema.Formats["tel"](value) {
return ctx.Error("format", "%q is not valid %q", value, "phone")
if formatString == "" {
switch s.Verification.Via {
case ChannelTypeEmail:
formatString = "email"
formatter, ok := jsonschema.Formats[formatString]
if !ok {
supportedKeys := maps.Keys(jsonschema.Formats)
return ctx.Error("format", "format %q is not supported. Supported formats are [%s]", formatString, strings.Join(supportedKeys, ", "))

Check warning on line 65 in identity/extension_verification.go

Codecov / codecov/patch

identity/extension_verification.go#L64-L65

Added lines #L64 - L65 were not covered by tests
}

if !formatter(value) {
return ctx.Error("format", "%q is not valid %q", value, formatString)
}
default:
return ctx.Error("format", "no format specified. A format is required if verification is enabled. If this was intentional, please set \"format\" to \"noformat\"")
}
}

address := NewVerifiablePhoneAddress(fmt.Sprintf("%s", value), r.i.ID)

r.appendAddress(address)

return nil

case "":
return nil
var normalized string
switch formatString {
case "email":
normalized = strings.ToLower(strings.TrimSpace(fmt.Sprintf("%s", value)))
default:
normalized = strings.TrimSpace(fmt.Sprintf("%s", value))
}

return ctx.Error("", "verification.via has unknown value %q", s.Verification.Via)
address := NewVerifiableAddress(normalized, r.i.ID, s.Verification.Via)
r.appendAddress(address)
return nil
}

func (r *SchemaExtensionVerification) Finish() error {
76 changes: 57 additions & 19 deletions identity/extension_verification_test.go
Original file line number Diff line number Diff line change
@@ -6,12 +6,13 @@ package identity
import (
"bytes"
"context"
"errors"
"fmt"
"net"
"reflect"
"testing"
"time"

"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

@@ -22,13 +23,17 @@ import (
)

const (
emailSchemaPath = "file://./stub/extension/verify/email.schema.json"
phoneSchemaPath = "file://./stub/extension/verify/phone.schema.json"
emailSchemaPath = "file://./stub/extension/verify/email.schema.json"
phoneSchemaPath = "file://./stub/extension/verify/phone.schema.json"
missingFormatSchemaPath = "file://./stub/extension/verify/missing-format.schema.json"
legacyEmailMissingFormatSchemaPath = "file://./stub/extension/verify/legacy-email-missing-format.schema.json"
noFormatSchemaPath = "file://./stub/extension/verify/no-format.schema.json"
)

var ctx = context.Background()

func TestSchemaExtensionVerification(t *testing.T) {
net.IP{}.IsPrivate()
t.Run("address verification", func(t *testing.T) {
iid := x.NewUUID()

@@ -194,7 +199,7 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+18004444444",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -208,7 +213,7 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+442087599036",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -217,7 +222,7 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+18004444444",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -231,14 +236,14 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+442087599036",
Verified: true,
Status: VerifiableAddressStatusCompleted,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
{
Value: "+380634872774",
Verified: true,
Status: VerifiableAddressStatusCompleted,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -247,14 +252,14 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+442087599036",
Verified: true,
Status: VerifiableAddressStatusCompleted,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
{
Value: "+18004444444",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -268,14 +273,14 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+18004444444",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
{
Value: "+380634872774",
Verified: true,
Status: VerifiableAddressStatusCompleted,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -284,14 +289,14 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+18004444444",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
{
Value: "+442087599036",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -305,21 +310,21 @@ func TestSchemaExtensionVerification(t *testing.T) {
Value: "+18004444444",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
{
Value: "+442087599036",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
{
Value: "+380634872774",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
@@ -328,7 +333,41 @@ func TestSchemaExtensionVerification(t *testing.T) {
name: "phone:must return error for malformed input",
schema: phoneSchemaPath,
doc: `{"phones":["+18004444444","+18004444444","12112112"], "username": "+380634872774"}`,
expectErr: errors.New("I[#/phones/2] S[#/properties/phones/items/format] \"12112112\" is not valid \"phone\""),
expectErr: errors.New("I[#/phones/2] S[#/properties/phones/items/format] \"12112112\" is not valid \"tel\""),
},
{
name: "missing format returns an error",
schema: missingFormatSchemaPath,
doc: `{"phone": "+380634872774"}`,
expectErr: errors.New("I[#/phone] S[#/properties/phone/format] no format specified. A format is required if verification is enabled. If this was intentional, please set \"format\" to \"noformat\""),
},
{
name: "missing format works for email if format is missing",
schema: legacyEmailMissingFormatSchemaPath,
doc: `{"email": "user@ory.sh"}`,
expect: []VerifiableAddress{
{
Value: "user@ory.sh",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: ChannelTypeEmail,
IdentityID: iid,
},
},
},
{
name: "format: noformat works",
schema: noFormatSchemaPath,
doc: `{"phone": "not a phone number"}`,
expect: []VerifiableAddress{
{
Value: "not a phone number",
Verified: false,
Status: VerifiableAddressStatusPending,
Via: ChannelTypeSMS,
IdentityID: iid,
},
},
},
} {
t.Run(fmt.Sprintf("case=%v", tc.name), func(t *testing.T) {
@@ -357,7 +396,6 @@ func TestSchemaExtensionVerification(t *testing.T) {
})
}
})

}

func mustContainAddress(t *testing.T, expected, actual []VerifiableAddress) {
26 changes: 5 additions & 21 deletions identity/identity_verification.go
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ const (
// VerifiableAddressType must not exceed 16 characters as that is the limitation in the SQL Schema
//
// swagger:model identityVerifiableAddressType
type VerifiableAddressType string
type VerifiableAddressType = string

// VerifiableAddressStatus must not exceed 16 characters as that is the limitation in the SQL Schema
//
@@ -57,7 +57,7 @@ type VerifiableAddress struct {
// enum: ["email"]
// example: email
// required: true
Via VerifiableAddressType `json:"via" db:"via"`
Via string `json:"via" db:"via"`

// The verified address status
//
@@ -87,36 +87,20 @@ type VerifiableAddress struct {
NID uuid.UUID `json:"-" faker:"-" db:"nid"`
}

func (v VerifiableAddressType) HTMLFormInputType() string {
switch v {
case VerifiableAddressTypeEmail:
return "email"
case VerifiableAddressTypePhone:
return "phone"
}
return ""
}

func (a VerifiableAddress) TableName(ctx context.Context) string {
return "identity_verifiable_addresses"
}

func NewVerifiableEmailAddress(value string, identity uuid.UUID) *VerifiableAddress {
return &VerifiableAddress{
Value: value,
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypeEmail,
IdentityID: identity,
}
return NewVerifiableAddress(value, identity, VerifiableAddressTypeEmail)
}

func NewVerifiablePhoneAddress(value string, identity uuid.UUID) *VerifiableAddress {
func NewVerifiableAddress(value string, identity uuid.UUID, channel string) *VerifiableAddress {
return &VerifiableAddress{
Value: value,
Verified: false,
Status: VerifiableAddressStatusPending,
Via: VerifiableAddressTypePhone,
Via: channel,
IdentityID: identity,
}
}
2 changes: 1 addition & 1 deletion identity/pool.go
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ type (
GetIdentity(context.Context, uuid.UUID, sqlxx.Expandables) (*Identity, error)

// FindVerifiableAddressByValue returns a matching address or sql.ErrNoRows if no address could be found.
FindVerifiableAddressByValue(ctx context.Context, via VerifiableAddressType, address string) (*VerifiableAddress, error)
FindVerifiableAddressByValue(ctx context.Context, via string, address string) (*VerifiableAddress, error)

// FindRecoveryAddressByValue returns a matching address or sql.ErrNoRows if no address could be found.
FindRecoveryAddressByValue(ctx context.Context, via RecoveryAddressType, address string) (*RecoveryAddress, error)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"type": "object",
"properties": {
"email": {
"type": "string",
"ory.sh/kratos": {
"verification": {
"via": "email"
}
}
}
}
}
13 changes: 13 additions & 0 deletions identity/stub/extension/verify/missing-format.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"type": "object",
"properties": {
"phone": {
"type": "string",
"ory.sh/kratos": {
"verification": {
"via": "sms"
}
}
}
}
}
14 changes: 14 additions & 0 deletions identity/stub/extension/verify/no-format.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"type": "object",
"properties": {
"phone": {
"type": "string",
"format": "noformat",
"ory.sh/kratos": {
"verification": {
"via": "sms"
}
}
}
}
}
6 changes: 4 additions & 2 deletions identity/stub/extension/verify/phone.schema.json
Original file line number Diff line number Diff line change
@@ -5,18 +5,20 @@
"type": "array",
"items": {
"type": "string",
"format": "tel",
"ory.sh/kratos": {
"verification": {
"via": "phone"
"via": "sms"
}
}
}
},
"username": {
"type": "string",
"format": "tel",
"ory.sh/kratos": {
"verification": {
"via": "phone"
"via": "sms"
}
}
}
2 changes: 1 addition & 1 deletion persistence/sql/identity/persister_identity.go
Original file line number Diff line number Diff line change
@@ -957,7 +957,7 @@ func (p *IdentityPersister) GetIdentityConfidential(ctx context.Context, id uuid
return p.GetIdentity(ctx, id, identity.ExpandEverything)
}

func (p *IdentityPersister) FindVerifiableAddressByValue(ctx context.Context, via identity.VerifiableAddressType, value string) (_ *identity.VerifiableAddress, err error) {
func (p *IdentityPersister) FindVerifiableAddressByValue(ctx context.Context, via string, value string) (_ *identity.VerifiableAddress, err error) {
ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.FindVerifiableAddressByValue")
otelx.End(span, &err)

8 changes: 4 additions & 4 deletions request/builder.go
Original file line number Diff line number Diff line change
@@ -163,23 +163,23 @@
enc.SetIndent("", "")

if err := enc.Encode(body); err != nil {
return err
return errors.WithStack(err)

Check warning on line 166 in request/builder.go

Codecov / codecov/patch

request/builder.go#L166

Added line #L166 was not covered by tests
}

vm, err := b.deps.JsonnetVM(ctx)
if err != nil {
return err
return errors.WithStack(err)

Check warning on line 171 in request/builder.go

Codecov / codecov/patch

request/builder.go#L171

Added line #L171 was not covered by tests
}
vm.TLACode("ctx", buf.String())

res, err := vm.EvaluateAnonymousSnippet(b.Config.TemplateURI, template.String())
if err != nil {
return err
return errors.WithStack(err)

Check warning on line 177 in request/builder.go

Codecov / codecov/patch

request/builder.go#L177

Added line #L177 was not covered by tests
}

values := map[string]string{}
if err := json.Unmarshal([]byte(res), &values); err != nil {
return err
return errors.WithStack(err)

Check warning on line 182 in request/builder.go

Codecov / codecov/patch

request/builder.go#L182

Added line #L182 was not covered by tests
}

u := url.Values{}
4 changes: 3 additions & 1 deletion schema/extension.go
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ type (
Recovery struct {
Via string `json:"via"`
} `json:"recovery"`
RawSchema map[string]interface{} `json:"-"`
}

ValidateExtension interface {
@@ -53,7 +54,7 @@ type (

ExtensionRunner struct {
meta *jsonschema.Schema
compile func(ctx jsonschema.CompilerContext, m map[string]interface{}) (interface{}, error)
compile func(ctx jsonschema.CompilerContext, rawSchema map[string]interface{}) (interface{}, error)
validate func(ctx jsonschema.ValidationContext, s interface{}, v interface{}) error

validateRunners []ValidateExtension
@@ -106,6 +107,7 @@ func NewExtensionRunner(ctx context.Context, opts ...ExtensionRunnerOption) (*Ex
return nil, err
}
}
e.RawSchema = m

return &e, nil
}
12 changes: 6 additions & 6 deletions selfservice/strategy/code/code_sender.go
Original file line number Diff line number Diff line change
@@ -241,7 +241,7 @@
// If the address does not exist in the store and dispatching invalid emails is enabled (CourierEnableInvalidDispatch is
// true), an email is still being sent to prevent account enumeration attacks. In that case, this function returns the
// ErrUnknownAddress error.
func (s *Sender) SendVerificationCode(ctx context.Context, f *verification.Flow, via identity.VerifiableAddressType, to string) error {
func (s *Sender) SendVerificationCode(ctx context.Context, f *verification.Flow, via string, to string) error {
s.deps.Logger().
WithField("via", via).
WithSensitiveField("address", to).
@@ -317,21 +317,21 @@

// TODO: this can likely be abstracted by making templates not specific to the channel they're using
switch code.VerifiableAddress.Via {
case identity.AddressTypeEmail:
case identity.ChannelTypeEmail:
t = email.NewVerificationCodeValid(s.deps, &email.VerificationCodeValidModel{
To: code.VerifiableAddress.Value,
VerificationURL: s.constructVerificationLink(ctx, f.ID, codeString),
Identity: model,
VerificationCode: codeString,
})
case identity.AddressTypePhone:
case identity.ChannelTypeSMS:

Check warning on line 327 in selfservice/strategy/code/code_sender.go

Codecov / codecov/patch

selfservice/strategy/code/code_sender.go#L327

Added line #L327 was not covered by tests
t = sms.NewVerificationCodeValid(s.deps, &sms.VerificationCodeValidModel{
To: code.VerifiableAddress.Value,
VerificationCode: codeString,
Identity: model,
})
default:
return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Expected email or phone but got %s", code.VerifiableAddress.Via))
return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Expected email or sms but got %s", code.VerifiableAddress.Via))

Check warning on line 334 in selfservice/strategy/code/code_sender.go

Codecov / codecov/patch

selfservice/strategy/code/code_sender.go#L334

Added line #L334 was not covered by tests
}

if err := s.send(ctx, string(code.VerifiableAddress.Via), t); err != nil {
@@ -343,7 +343,7 @@

func (s *Sender) send(ctx context.Context, via string, t courier.Template) error {
switch f := stringsx.SwitchExact(via); {
case f.AddCase(identity.AddressTypeEmail):
case f.AddCase(identity.ChannelTypeEmail):
c, err := s.deps.Courier(ctx)
if err != nil {
return err
@@ -356,7 +356,7 @@

_, err = c.QueueEmail(ctx, t)
return err
case f.AddCase(identity.AddressTypePhone):
case f.AddCase(identity.ChannelTypeSMS):

Check warning on line 359 in selfservice/strategy/code/code_sender.go

Codecov / codecov/patch

selfservice/strategy/code/code_sender.go#L359

Added line #L359 was not covered by tests
c, err := s.deps.Courier(ctx)
if err != nil {
return err

0 comments on commit 9808796

Please sign in to comment.