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: two-step login and improved UI APIs for Ory Elements v1 #3934

Merged
merged 34 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4df7b86
feat: identifier first auth
aeneasr May 7, 2024
7d8625b
feat: add additional messages
aeneasr Mar 26, 2024
55e361d
feat: add redirect to continue_with for SPA flows
aeneasr Apr 22, 2024
83f284b
feat: add browser return_to continue_with action
aeneasr Apr 22, 2024
09a6f8a
feat(sdk): add missing profile discriminator to update registration
aeneasr Apr 23, 2024
0a6d591
feat(sdk): avoid eval with javascript triggers
aeneasr Apr 23, 2024
0e5bf01
fix: replace submit with continue button for recovery and verificatio…
aeneasr Apr 25, 2024
892b032
feat: set maxlength for totp input
aeneasr Apr 26, 2024
a18a85c
fix: add missing JS triggers
aeneasr May 24, 2024
03ef0a3
feat: add if method to sdk
aeneasr May 24, 2024
6487282
chore: regenerate SDK
aeneasr May 24, 2024
b29954b
feat: identifier first login for all first factor login methods
aeneasr May 24, 2024
9ef1c4f
test: add form hydration tests for password login
aeneasr Jun 13, 2024
efd70bc
test: add form hydration tests for code login
aeneasr Jun 14, 2024
91570cd
test: add form hydration tests for oidc login
aeneasr Jun 14, 2024
f817e28
test: add form hydration tests for idfirst login
aeneasr Jun 14, 2024
0fa0081
feat: add social providers to credential discovery as well
aeneasr Jun 14, 2024
8d83cbe
test: add form hydration tests for passkey login
aeneasr Jun 14, 2024
d3dd13d
test: add form hydration tests for webauthn login
aeneasr Jun 14, 2024
9222eb3
test: add tests for idfirst
aeneasr Jun 17, 2024
2f6bc07
chore: updated snapshots and clean up
aeneasr Jun 17, 2024
00603db
test: verify redirect continue_with in hook executor for browser clients
aeneasr Jun 17, 2024
86589e8
test: resolve issues and update snapshots for all selfservice strategies
aeneasr Jun 18, 2024
a26548a
feat: separate 2fa refresh from 1st factor refresh (#3961)
aeneasr Jun 20, 2024
8e96451
feat: better detection if credentials exist on identifier first login…
aeneasr Jun 21, 2024
1afdc53
feat: add tests for two step login (#3959)
jonas-jonas Jul 5, 2024
0da3ef2
chore: regenerate SDK and format code
aeneasr Jul 8, 2024
e806cc6
fix: timestamp precision on mysql
jonas-jonas Jul 8, 2024
2ff6bdc
chore: rename one_step to unified
aeneasr Jul 8, 2024
86a057f
chore: regenerate config types
jonas-jonas Jul 9, 2024
e6cae4c
Update .github/workflows/ci.yaml
jonas-jonas Jul 9, 2024
e070b27
chore: use correct import
aeneasr Jul 9, 2024
0da0c9b
chore: re-add WithIdentifier (#3992)
jonas-jonas Jul 10, 2024
5160bfc
chore: remove max length
jonas-jonas Jul 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ test/e2e/kratos.*.yml
# VSCode debug artifact
__debug_bin
.debug.sqlite.db
.last-run.json
2 changes: 2 additions & 0 deletions .schema/openapi/patches/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
set_ory_session_token: "#/components/schemas/continueWithSetOrySessionToken"
show_settings_ui: "#/components/schemas/continueWithSettingsUi"
show_recovery_ui: "#/components/schemas/continueWithRecoveryUi"
redirect_browser_to: "#/components/schemas/continueWithRedirectBrowserTo"

- op: add
path: /components/schemas/continueWith/oneOf
Expand All @@ -51,3 +52,4 @@
- "$ref": "#/components/schemas/continueWithSetOrySessionToken"
- "$ref": "#/components/schemas/continueWithSettingsUi"
- "$ref": "#/components/schemas/continueWithRecoveryUi"
- "$ref": "#/components/schemas/continueWithRedirectBrowserTo"
6 changes: 5 additions & 1 deletion .schema/openapi/patches/selfservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- "$ref": "#/components/schemas/updateRegistrationFlowWithWebAuthnMethod"
- "$ref": "#/components/schemas/updateRegistrationFlowWithCodeMethod"
- "$ref": "#/components/schemas/updateRegistrationFlowWithPasskeyMethod"
- "$ref": "#/components/schemas/updateRegistrationFlowWithProfileMethod"
- op: add
path: /components/schemas/updateRegistrationFlowBody/discriminator
value:
Expand All @@ -28,7 +29,8 @@
oidc: "#/components/schemas/updateRegistrationFlowWithOidcMethod"
webauthn: "#/components/schemas/updateRegistrationFlowWithWebAuthnMethod"
code: "#/components/schemas/updateRegistrationFlowWithCodeMethod"
passKey: "#/components/schemas/updateRegistrationFlowWithPasskeyMethod"
passkey: "#/components/schemas/updateRegistrationFlowWithPasskeyMethod"
profile: "#/components/schemas/updateRegistrationFlowWithProfileMethod"
- op: add
path: /components/schemas/registrationFlowState/enum
value:
Expand All @@ -50,6 +52,7 @@
- "$ref": "#/components/schemas/updateLoginFlowWithLookupSecretMethod"
- "$ref": "#/components/schemas/updateLoginFlowWithCodeMethod"
- "$ref": "#/components/schemas/updateLoginFlowWithPasskeyMethod"
- "$ref": "#/components/schemas/updateLoginFlowWithIdentifierFirstMethod"
- op: add
path: /components/schemas/updateLoginFlowBody/discriminator
value:
Expand All @@ -62,6 +65,7 @@
lookup_secret: "#/components/schemas/updateLoginFlowWithLookupSecretMethod"
code: "#/components/schemas/updateLoginFlowWithCodeMethod"
passkey: "#/components/schemas/updateLoginFlowWithPasskeyMethod"
identifier_first: "#/components/schemas/updateLoginFlowWithIdentifierFirstMethod"
- op: add
path: /components/schemas/loginFlowState/enum
value:
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ migrations-sync: .bin/ory
ory dev pop migration sync persistence/sql/migrations/templates persistence/sql/migratest/testdata
script/add-down-migrations.sh

.PHONY: test-update-snapshots
test-update-snapshots:
.PHONY: test-refresh
test-refresh:
UPDATE_SNAPSHOTS=true go test -tags sqlite,json1,refresh -short ./...

.PHONY: post-release
Expand Down
2 changes: 2 additions & 0 deletions cmd/clidoc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func init() {
"NewErrorValidationAddressUnknown": text.NewErrorValidationAddressUnknown(),
"NewInfoSelfServiceLoginCodeMFA": text.NewInfoSelfServiceLoginCodeMFA(),
"NewInfoSelfServiceLoginCodeMFAHint": text.NewInfoSelfServiceLoginCodeMFAHint("{maskedIdentifier}"),
"NewInfoLoginPassword": text.NewInfoLoginPassword(),
"NewErrorValidationAccountNotFound": text.NewErrorValidationAccountNotFound(),
}
}

Expand Down
3 changes: 1 addition & 2 deletions courier/sms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func TestQueueSMS(t *testing.T) {
Body: body.Body,
})
}))
t.Cleanup(srv.Close)

requestConfig := fmt.Sprintf(`{
"url": "%s",
Expand Down Expand Up @@ -112,8 +113,6 @@ func TestQueueSMS(t *testing.T) {
assert.Equal(t, expected.To, message.To)
assert.Equal(t, fmt.Sprintf("stub sms body %s\n", expected.Body), message.Body)
}

srv.Close()
}

func TestDisallowedInternalNetwork(t *testing.T) {
Expand Down
19 changes: 18 additions & 1 deletion driver/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ const (
ViperKeySelfServiceRegistrationAfter = "selfservice.flows.registration.after"
ViperKeySelfServiceRegistrationBeforeHooks = "selfservice.flows.registration.before.hooks"
ViperKeySelfServiceLoginUI = "selfservice.flows.login.ui_url"
ViperKeySelfServiceLoginFlowStyle = "selfservice.flows.login.style"
ViperKeySecurityAccountEnumerationMitigate = "security.account_enumeration.mitigate"
ViperKeySelfServiceLoginRequestLifespan = "selfservice.flows.login.lifespan"
ViperKeySelfServiceLoginAfter = "selfservice.flows.login.after"
ViperKeySelfServiceLoginBeforeHooks = "selfservice.flows.login.before.hooks"
Expand Down Expand Up @@ -774,14 +776,16 @@ func (p *Config) SelfServiceStrategy(ctx context.Context, strategy string) *Self
var err error
config, err = json.Marshal(pp.GetF(basePath+".config", config))
if err != nil {
p.l.WithError(err).Warn("Unable to marshal self service strategy configuration.")
p.l.WithError(err).Warn("Unable to marshal self-service strategy configuration.")
config = json.RawMessage("{}")
}

// The default value can easily be overwritten by setting e.g. `{"selfservice": "null"}` which means that
// we need to forcibly set these values here:
defaultEnabled := false
switch strategy {
case "identifier_first":
defaultEnabled = p.SelfServiceLoginFlowIdentifierFirstEnabled(ctx)
case "code", "password", "profile":
defaultEnabled = true
}
Expand Down Expand Up @@ -1612,3 +1616,16 @@ func (p *Config) PasswordMigrationHook(ctx context.Context) (hook *PasswordMigra

return hook
}

func (p *Config) SelfServiceLoginFlowIdentifierFirstEnabled(ctx context.Context) bool {
switch p.GetProvider(ctx).String(ViperKeySelfServiceLoginFlowStyle) {
case "identifier_first":
return true
default:
return false
}
}

func (p *Config) SecurityAccountEnumerationMitigate(ctx context.Context) bool {
return p.GetProvider(ctx).Bool(ViperKeySecurityAccountEnumerationMitigate)
}
4 changes: 4 additions & 0 deletions driver/registry_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"testing"
"time"

"github.com/ory/kratos/selfservice/strategy/idfirst"

"github.com/cenkalti/backoff"
"github.com/dgraph-io/ristretto"
"github.com/gobuffalo/pop/v6"
Expand Down Expand Up @@ -324,6 +326,7 @@ func (m *RegistryDefault) selfServiceStrategies() []any {
passkey.NewStrategy(m),
webauthn.NewStrategy(m),
lookup.NewStrategy(m),
idfirst.NewStrategy(m),
}
}
}
Expand Down Expand Up @@ -379,6 +382,7 @@ nextStrategy:
continue nextStrategy
}
}

if m.strategyLoginEnabled(ctx, s.ID().String()) {
loginStrategies = append(loginStrategies, s)
}
Expand Down
2 changes: 1 addition & 1 deletion driver/registry_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ func TestDefaultRegistry_AllStrategies(t *testing.T) {
_, reg := internal.NewVeryFastRegistryWithoutDB(t)

t.Run("case=all login strategies", func(t *testing.T) {
expects := []string{"password", "oidc", "code", "totp", "passkey", "webauthn", "lookup_secret"}
expects := []string{"password", "oidc", "code", "totp", "passkey", "webauthn", "lookup_secret", "identifier_first"}
s := reg.AllLoginStrategies()
require.Len(t, s, len(expects))
for k, e := range expects {
Expand Down
27 changes: 18 additions & 9 deletions embedx/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1298,10 +1298,10 @@
},
"style": {
"title": "Login Flow Style",
"description": "The style of the login flow. If set to `one_step` the login flow will be a one-step process. If set to `identifier_first` (experimental!) the login flow will first ask for the identifier and then the credentials.",
"description": "The style of the login flow. If set to `unified` the login flow will be a one-step process. If set to `identifier_first` (experimental!) the login flow will first ask for the identifier and then the credentials.",
"type": "string",
"enum": ["one_step", "identifier_first"],
"default": "one_step"
"enum": ["unified", "identifier_first"],
"default": "unified"
},
"before": {
"$ref": "#/definitions/selfServiceBeforeLogin"
Expand Down Expand Up @@ -1557,12 +1557,6 @@
"title": "Enables login flows code method to fulfil MFA requests",
"default": false
},
"passwordless_login_fallback_enabled": {
"type": "boolean",
"title": "Passwordless Login Fallback Enabled",
"description": "This setting allows the code method to always login a user with code if they have registered with another authentication method such as password or social sign in.",
"default": false
},
"enabled": {
"type": "boolean",
"title": "Enables Code Method",
Expand Down Expand Up @@ -2879,6 +2873,21 @@
}
}
},
"security": {
"type": "object",
"properties": {
"account_enumeration": {
jonas-jonas marked this conversation as resolved.
Show resolved Hide resolved
"type": "object",
"properties": {
"mitigate": {
"type": "boolean",
"default": false,
"description": "Mitigate account enumeration by making it harder to figure out if an identifier (email, phone number) exists or not. Enabling this setting degrades user experience. This setting does not mitigate all possible attack vectors yet."
}
}
}
}
},
"version": {
"title": "The kratos version this config is written for.",
"description": "SemVer according to https://semver.org/ prefixed with `v` as in our releases.",
Expand Down
6 changes: 2 additions & 4 deletions examples/go/pkg/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ import (
"os"
"testing"

"github.com/ory/kratos/x"

"github.com/ory/kratos/internal/testhelpers"

ory "github.com/ory/client-go"
"github.com/ory/kratos/internal/testhelpers"
"github.com/ory/kratos/x"
)

func PrintJSONPretty(v interface{}) {
Expand Down
4 changes: 4 additions & 0 deletions internal/client-go/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ docs/ConsistencyRequestParameters.md
docs/ContinueWith.md
docs/ContinueWithRecoveryUi.md
docs/ContinueWithRecoveryUiFlow.md
docs/ContinueWithRedirectBrowserTo.md
docs/ContinueWithSetOrySessionToken.md
docs/ContinueWithSettingsUi.md
docs/ContinueWithSettingsUiFlow.md
Expand Down Expand Up @@ -99,6 +100,7 @@ docs/UiText.md
docs/UpdateIdentityBody.md
docs/UpdateLoginFlowBody.md
docs/UpdateLoginFlowWithCodeMethod.md
docs/UpdateLoginFlowWithIdentifierFirstMethod.md
docs/UpdateLoginFlowWithLookupSecretMethod.md
docs/UpdateLoginFlowWithOidcMethod.md
docs/UpdateLoginFlowWithPasskeyMethod.md
Expand Down Expand Up @@ -139,6 +141,7 @@ model_consistency_request_parameters.go
model_continue_with.go
model_continue_with_recovery_ui.go
model_continue_with_recovery_ui_flow.go
model_continue_with_redirect_browser_to.go
model_continue_with_set_ory_session_token.go
model_continue_with_settings_ui.go
model_continue_with_settings_ui_flow.go
Expand Down Expand Up @@ -219,6 +222,7 @@ model_ui_text.go
model_update_identity_body.go
model_update_login_flow_body.go
model_update_login_flow_with_code_method.go
model_update_login_flow_with_identifier_first_method.go
model_update_login_flow_with_lookup_secret_method.go
model_update_login_flow_with_oidc_method.go
model_update_login_flow_with_passkey_method.go
Expand Down
2 changes: 2 additions & 0 deletions internal/client-go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Class | Method | HTTP request | Description
- [ContinueWith](docs/ContinueWith.md)
- [ContinueWithRecoveryUi](docs/ContinueWithRecoveryUi.md)
- [ContinueWithRecoveryUiFlow](docs/ContinueWithRecoveryUiFlow.md)
- [ContinueWithRedirectBrowserTo](docs/ContinueWithRedirectBrowserTo.md)
- [ContinueWithSetOrySessionToken](docs/ContinueWithSetOrySessionToken.md)
- [ContinueWithSettingsUi](docs/ContinueWithSettingsUi.md)
- [ContinueWithSettingsUiFlow](docs/ContinueWithSettingsUiFlow.md)
Expand Down Expand Up @@ -222,6 +223,7 @@ Class | Method | HTTP request | Description
- [UpdateIdentityBody](docs/UpdateIdentityBody.md)
- [UpdateLoginFlowBody](docs/UpdateLoginFlowBody.md)
- [UpdateLoginFlowWithCodeMethod](docs/UpdateLoginFlowWithCodeMethod.md)
- [UpdateLoginFlowWithIdentifierFirstMethod](docs/UpdateLoginFlowWithIdentifierFirstMethod.md)
- [UpdateLoginFlowWithLookupSecretMethod](docs/UpdateLoginFlowWithLookupSecretMethod.md)
- [UpdateLoginFlowWithOidcMethod](docs/UpdateLoginFlowWithOidcMethod.md)
- [UpdateLoginFlowWithPasskeyMethod](docs/UpdateLoginFlowWithPasskeyMethod.md)
Expand Down
40 changes: 40 additions & 0 deletions internal/client-go/model_continue_with.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading