Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve labels #3793

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions cmd/clidoc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func init() {
"NewErrorValidationPasswordTooManyBreaches": text.NewErrorValidationPasswordTooManyBreaches(101),
"NewErrorValidationInvalidCredentials": text.NewErrorValidationInvalidCredentials(),
"NewErrorValidationDuplicateCredentials": text.NewErrorValidationDuplicateCredentials(),
"NewErrorValidationDuplicateCredentialsWithHints": text.NewErrorValidationDuplicateCredentialsWithHints([]string{"{available_credential_types_list}"}, []string{"{available_oidc_providers_list}"}, "{credential_identifier_hint}"),
"NewErrorValidationDuplicateCredentialsWithHints": text.NewErrorValidationDuplicateCredentialsWithHints([]string{"{available_credential_types_list}"}, []string{"{available_oidc_providers_list}"}, "{credential_identifier_hint}", "{flow}"),
"NewErrorValidationDuplicateCredentialsOnOIDCLink": text.NewErrorValidationDuplicateCredentialsOnOIDCLink(),
"NewErrorValidationTOTPVerifierWrong": text.NewErrorValidationTOTPVerifierWrong(),
"NewErrorValidationLookupAlreadyUsed": text.NewErrorValidationLookupAlreadyUsed(),
Expand Down Expand Up @@ -147,7 +147,6 @@ func init() {
"NewErrorValidationRecoveryStateFailure": text.NewErrorValidationRecoveryStateFailure(),
"NewInfoNodeInputEmail": text.NewInfoNodeInputEmail(),
"NewInfoNodeResendOTP": text.NewInfoNodeResendOTP(),
"NewInfoNodeLoginAndLinkCredential": text.NewInfoNodeLoginAndLinkCredential(),
"NewInfoNodeLabelContinue": text.NewInfoNodeLabelContinue(),
"NewInfoSelfServiceSettingsRegisterWebAuthn": text.NewInfoSelfServiceSettingsRegisterWebAuthn(),
"NewInfoLoginWebAuthnPasswordless": text.NewInfoLoginWebAuthnPasswordless(),
Expand Down
1 change: 1 addition & 0 deletions internal/client-go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
76 changes: 0 additions & 76 deletions internal/testhelpers/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ import (
"net/http/httptest"
"net/url"

"github.com/ory/kratos/text"
"github.com/ory/kratos/ui/node"

"github.com/ory/kratos/x"
"github.com/ory/x/pointerx"

kratos "github.com/ory/kratos/internal/httpclient"
)

Expand Down Expand Up @@ -61,73 +55,3 @@ func SDKFormFieldsToURLValues(ff []kratos.UiNode) url.Values {
}
return values
}

func NewFakeCSRFNode() *kratos.UiNode {
return &kratos.UiNode{
Group: node.DefaultGroup.String(),
Type: "input",
Attributes: kratos.UiNodeInputAttributesAsUiNodeAttributes(&kratos.UiNodeInputAttributes{
Name: "csrf_token",
Required: pointerx.Bool(true),
Type: "hidden",
Value: x.FakeCSRFToken,
}),
}
}

func NewSDKEmailNode(group string) *kratos.UiNode {
return &kratos.UiNode{
Type: "input",
Group: group,
Attributes: kratos.UiNodeInputAttributesAsUiNodeAttributes(&kratos.UiNodeInputAttributes{
Name: "email",
Type: "email",
Required: pointerx.Bool(true),
Value: "email",
}),
}
}

func NewSDKOIDCNode(name, provider string) *kratos.UiNode {
t := text.NewInfoRegistrationWith(provider)
return &kratos.UiNode{
Group: node.OpenIDConnectGroup.String(),
Type: "input",
Attributes: kratos.UiNodeInputAttributesAsUiNodeAttributes(&kratos.UiNodeInputAttributes{
Name: name,
Type: "submit",
Value: provider,
}),
Meta: kratos.UiNodeMeta{
Label: &kratos.UiText{
Id: int64(t.ID),
Text: t.Text,
Type: string(t.Type),
},
},
}
}

func NewMethodSubmit(group, value string) *kratos.UiNode {
return &kratos.UiNode{
Type: "input",
Group: group,
Attributes: kratos.UiNodeInputAttributesAsUiNodeAttributes(&kratos.UiNodeInputAttributes{
Name: "method",
Type: "submit",
Value: value,
}),
}
}

func NewPasswordNode() *kratos.UiNode {
return &kratos.UiNode{
Type: "input",
Group: node.PasswordGroup.String(),
Attributes: kratos.UiNodeInputAttributesAsUiNodeAttributes(&kratos.UiNodeInputAttributes{
Name: "password",
Type: "password",
Required: pointerx.Bool(true),
}),
}
}
4 changes: 2 additions & 2 deletions schema/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ type DuplicateCredentialsHinter interface {
HasHints() bool
}

func NewDuplicateCredentialsError(err error) error {
func NewDuplicateCredentialsError(err error, flow text.DuplicateCredentialsFlow) error {
if hinter := DuplicateCredentialsHinter(nil); errors.As(err, &hinter) && hinter.HasHints() {
return errors.WithStack(&ValidationError{
ValidationError: &jsonschema.ValidationError{
Expand All @@ -152,7 +152,7 @@ func NewDuplicateCredentialsError(err error) error {
IdentifierHint: hinter.IdentifierHint(),
},
},
Messages: new(text.Messages).Add(text.NewErrorValidationDuplicateCredentialsWithHints(hinter.AvailableCredentials(), hinter.AvailableOIDCProviders(), hinter.IdentifierHint())),
Messages: new(text.Messages).Add(text.NewErrorValidationDuplicateCredentialsWithHints(hinter.AvailableCredentials(), hinter.AvailableOIDCProviders(), hinter.IdentifierHint(), flow)),
})
}

Expand Down
2 changes: 1 addition & 1 deletion selfservice/flow/registration/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (s *ErrorHandler) WriteFlowError(
) {

if dup := new(identity.ErrDuplicateCredentials); errors.As(err, &dup) {
err = schema.NewDuplicateCredentialsError(dup)
err = schema.NewDuplicateCredentialsError(dup, text.DuplicateCredentialsSignInFlow)
}

s.d.Audit().
Expand Down
2 changes: 1 addition & 1 deletion selfservice/flow/settings/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func (e *HookExecutor) PostSettingsHook(w http.ResponseWriter, r *http.Request,
return errors.WithStack(NewFlowNeedsReAuth())
}
if errors.Is(err, sqlcon.ErrUniqueViolation) {
return schema.NewDuplicateCredentialsError(err)
return schema.NewDuplicateCredentialsError(err, text.DuplicateCredentialsSettingsFlow)
}
return err
}
Expand Down
2 changes: 1 addition & 1 deletion selfservice/strategy/oidc/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ func (s *Strategy) handleError(w http.ResponseWriter, r *http.Request, f flow.Fl
// This is kinda hacky and will probably need to be updated at some point.

if dup := new(identity.ErrDuplicateCredentials); errors.As(err, &dup) {
err = schema.NewDuplicateCredentialsError(dup)
err = schema.NewDuplicateCredentialsError(dup, text.DuplicateCredentialsSignUpFlow)

if validationErr := new(schema.ValidationError); errors.As(err, &validationErr) {
for _, m := range validationErr.Messages {
Expand Down
6 changes: 4 additions & 2 deletions selfservice/strategy/oidc/strategy_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"net/http"
"time"

"github.com/ory/x/stringsx"

"github.com/ory/x/sqlxx"

"github.com/tidwall/sjson"
Expand Down Expand Up @@ -173,7 +175,7 @@ func (s *Strategy) PopulateSettingsMethod(r *http.Request, id *identity.Identity
if l.Config().OrganizationID != "" {
continue
}
sr.UI.GetNodes().Append(NewLinkNode(l.Config().ID))
sr.UI.GetNodes().Append(NewLinkNode(stringsx.Coalesce(l.Config().Label, l.Config().ID)))
}

count, err := s.d.IdentityManager().CountActiveFirstFactorCredentials(r.Context(), confidential)
Expand All @@ -185,7 +187,7 @@ func (s *Strategy) PopulateSettingsMethod(r *http.Request, id *identity.Identity
// This means that we're able to remove a connection because it is the last configured credential. If it is
// removed, the identity is no longer able to sign in.
for _, l := range linked {
sr.UI.GetNodes().Append(NewUnlinkNode(l.Config().ID))
sr.UI.GetNodes().Append(NewUnlinkNode(stringsx.Coalesce(l.Config().Label, l.Config().ID)))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ describe("Registration failures with email profile", () => {
cy.submitPasswordForm()
cy.get('[data-testid="ui/message/4000028"]').should(
"contain.text",
"You tried signing in with " +
"You tried signing up with " +
email +
" which is already in use by another account. You can sign in using your password.",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ context("Social Sign In Successes", () => {
cy.visit(settings)
cy.get('[value="hydra"]')
.should("have.attr", "name", "unlink")
.should("contain.text", "Unlink hydra")
.should("contain.text", "Unlink Ory")
})

it("should be able to sign up with redirects", () => {
Expand Down
6 changes: 3 additions & 3 deletions text/message_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func NewInfoLoginLinkMessage(dupIdentifier, provider, newLoginURL string) *Messa
ID: InfoSelfServiceLoginLink,
Type: Info,
Text: fmt.Sprintf(
"Signing in will link your account to %q at provider %q. If you do not wish to link that account, please start a new login flow.",
"Once signed in, your account will be linked to %s at %s. If you do not wish to link that account, please abort the flow.",
dupIdentifier,
provider,
),
Expand All @@ -76,7 +76,7 @@ func NewInfoLoginLinkMessage(dupIdentifier, provider, newLoginURL string) *Messa
func NewInfoLoginAndLink() *Message {
return &Message{
ID: InfoSelfServiceLoginAndLink,
Text: "Sign in and link",
Text: "Continue",
Type: Info,
}
}
Expand Down Expand Up @@ -119,7 +119,7 @@ func NewInfoLoginWith(provider string) *Message {
func NewInfoLoginWithAndLink(provider string) *Message {
return &Message{
ID: InfoSelfServiceLoginWithAndLink,
Text: fmt.Sprintf("Sign in with %s and link credential", provider),
Text: fmt.Sprintf("Continue with %s", provider),
Type: Info,
Context: context(map[string]any{
"provider": provider,
Expand Down
8 changes: 0 additions & 8 deletions text/message_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,3 @@ func NewInfoNodeResendOTP() *Message {
Type: Info,
}
}

func NewInfoNodeLoginAndLinkCredential() *Message {
return &Message{
ID: InfoNodeLabelLoginAndLinkCredential,
Text: "Login and link credential",
Type: Info,
}
}
13 changes: 10 additions & 3 deletions text/message_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,13 @@ func NewErrorValidationDuplicateCredentials() *Message {
}
}

func NewErrorValidationDuplicateCredentialsWithHints(availableCredentialTypes []string, availableOIDCProviders []string, credentialIdentifierHint string) *Message {
type DuplicateCredentialsFlow string

const DuplicateCredentialsSignInFlow DuplicateCredentialsFlow = "signing in"
const DuplicateCredentialsSignUpFlow DuplicateCredentialsFlow = "signing up"
const DuplicateCredentialsSettingsFlow DuplicateCredentialsFlow = "linking"

func NewErrorValidationDuplicateCredentialsWithHints(availableCredentialTypes []string, availableOIDCProviders []string, credentialIdentifierHint string, flow DuplicateCredentialsFlow) *Message {
identifier := credentialIdentifierHint
if identifier == "" {
identifier = "an email, phone, or username"
Expand All @@ -277,7 +283,7 @@ func NewErrorValidationDuplicateCredentialsWithHints(availableCredentialTypes []
oidcProviders = append(oidcProviders, cases.Title(language.English).String(provider))
}

reason := fmt.Sprintf("You tried signing in with %s which is already in use by another account.", identifier)
reason := fmt.Sprintf("You tried %s with %s which is already in use by another account.", flow, identifier)
if len(availableCredentialTypes) > 0 {
humanReadable := make(map[string]struct{}, len(availableCredentialTypes))
for _, cred := range availableCredentialTypes {
Expand All @@ -299,8 +305,9 @@ func NewErrorValidationDuplicateCredentialsWithHints(availableCredentialTypes []
}
reason += fmt.Sprintf(" You can sign in using %s.", strings.Join(maps.Keys(humanReadable), ", "))
}

if len(oidcProviders) > 0 {
reason += fmt.Sprintf(" You can sign in using one of the following social sign in providers: %s.", strings.Join(oidcProviders, ", "))
reason += fmt.Sprintf(" Your social sign in providers are: %s.", strings.Join(oidcProviders, ", "))
}

return &Message{
Expand Down
Loading