diff --git a/Makefile b/Makefile index 04c46bc890ba..33a95356b0f9 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ export PATH := .bin:${PATH} export PWD := $(shell pwd) export BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") export VCS_REF := $(shell git rev-parse HEAD) -export QUICKSTART_OPTIONS ?= +export QUICKSTART_OPTIONS ?= "" GO_DEPENDENCIES = github.com/ory/go-acc \ github.com/golang/mock/mockgen \ diff --git a/identity/credentials.go b/identity/credentials.go index 7b1c485579b6..10ff849a66c5 100644 --- a/identity/credentials.go +++ b/identity/credentials.go @@ -4,10 +4,14 @@ package identity import ( + "bytes" "context" + "encoding/json" "reflect" "time" + "github.com/pkg/errors" + "github.com/gobuffalo/pop/v6" "github.com/ory/kratos/ui/node" @@ -117,6 +121,10 @@ func (c *Credentials) AfterEagerFind(tx *pop.Connection) error { return c.setCredentials() } +func (c *Credentials) UnmarshalConfig(target interface{}) error { + return errors.WithStack(json.NewDecoder(bytes.NewBuffer(c.Config)).Decode(&target)) +} + func (c *Credentials) setCredentials() error { c.Type = c.IdentityCredentialType.Name c.Identifiers = make([]string, 0, len(c.CredentialIdentifiers)) diff --git a/identity/credentials_oidc.go b/identity/credentials_oidc.go index 1ad0ada209c1..3709d6878384 100644 --- a/identity/credentials_oidc.go +++ b/identity/credentials_oidc.go @@ -29,6 +29,9 @@ type CredentialsOIDCProvider struct { InitialIDToken string `json:"initial_id_token"` InitialAccessToken string `json:"initial_access_token"` InitialRefreshToken string `json:"initial_refresh_token"` + CurrentIDToken string `json:"current_id_token"` + CurrentAccessToken string `json:"current_access_token"` + CurrentRefreshToken string `json:"current_refresh_token"` } // NewCredentialsOIDC creates a new OIDC credential. @@ -50,6 +53,9 @@ func NewCredentialsOIDC(idToken, accessToken, refreshToken, provider, subject st InitialIDToken: idToken, InitialAccessToken: accessToken, InitialRefreshToken: refreshToken, + CurrentIDToken: idToken, + CurrentAccessToken: accessToken, + CurrentRefreshToken: refreshToken, }}, }); err != nil { return nil, errors.WithStack(x.PseudoPanic. @@ -66,3 +72,12 @@ func NewCredentialsOIDC(idToken, accessToken, refreshToken, provider, subject st func OIDCUniqueID(provider, subject string) string { return fmt.Sprintf("%s:%s", provider, subject) } + +func (c *CredentialsOIDC) GetProvider(provider, subject string) (k int, found bool) { + for k, p := range c.Providers { + if p.Subject == subject && p.Provider == provider { + return k, true + } + } + return -1, false +} diff --git a/identity/credentials_oidc_test.go b/identity/credentials_oidc_test.go index b916220f1b9b..8f0a6bbc273c 100644 --- a/identity/credentials_oidc_test.go +++ b/identity/credentials_oidc_test.go @@ -17,3 +17,26 @@ func TestNewCredentialsOIDC(t *testing.T) { _, err = NewCredentialsOIDC("", "", "", "not-empty", "not-empty") require.NoError(t, err) } + +func TestGetProvider(t *testing.T) { + c := CredentialsOIDC{ + Providers: []CredentialsOIDCProvider{ + { + Subject: "user-a", + Provider: "google", + }, + { + Subject: "user-a", + Provider: "github", + }, + }, + } + + k, found := c.GetProvider("github", "user-a") + require.True(t, found) + require.Equal(t, 1, k) + + k, found = c.GetProvider("not-found", "user-a") + require.False(t, found) + require.Equal(t, -1, k) +} diff --git a/identity/handler_test.go b/identity/handler_test.go index e8d1107f181e..73835aa2ade2 100644 --- a/identity/handler_test.go +++ b/identity/handler_test.go @@ -315,6 +315,9 @@ func TestHandler(t *testing.T) { InitialAccessToken: transform(accessToken + "0"), InitialRefreshToken: transform(refreshToken + "0"), InitialIDToken: transform(idToken + "0"), + CurrentAccessToken: transform(accessToken + "current-0"), + CurrentRefreshToken: transform(refreshToken + "current-0"), + CurrentIDToken: transform(idToken + "current-0"), }, { Subject: "baz", @@ -322,6 +325,9 @@ func TestHandler(t *testing.T) { InitialAccessToken: transform(accessToken + "1"), InitialRefreshToken: transform(refreshToken + "1"), InitialIDToken: transform(idToken + "1"), + CurrentAccessToken: transform(accessToken + "current-1"), + CurrentRefreshToken: transform(refreshToken + "current-1"), + CurrentIDToken: transform(idToken + "current-1"), }, }}), }, diff --git a/identity/identity.go b/identity/identity.go index 520d824cf867..44885204a156 100644 --- a/identity/identity.go +++ b/identity/identity.go @@ -417,7 +417,7 @@ func (i *Identity) WithDeclassifiedCredentialsOIDC(ctx context.Context, c cipher toPublish := original toPublish.Config = []byte{} - for _, token := range []string{"initial_id_token", "initial_access_token", "initial_refresh_token"} { + for _, token := range []string{"initial_id_token", "initial_access_token", "initial_refresh_token", "current_id_token", "current_access_token", "current_refresh_token"} { var i int var err error gjson.GetBytes(original.Config, "providers").ForEach(func(_, v gjson.Result) bool { diff --git a/identity/manager.go b/identity/manager.go index e2f83189e831..419d4857472f 100644 --- a/identity/manager.go +++ b/identity/manager.go @@ -131,6 +131,33 @@ func (m *Manager) Update(ctx context.Context, updated *Identity, opts ...Manager return m.r.PrivilegedIdentityPool().UpdateIdentity(ctx, updated) } +func (m *Manager) UpdateCredentials(ctx context.Context, id uuid.UUID, ct CredentialsType, cb func(*Credentials) error, opts ...ManagerOption) (err error) { + ctx, span := m.r.Tracer(ctx).Tracer().Start(ctx, "identity.Manager.Update") + defer otelx.End(span, &err) + + updated, err := m.r.PrivilegedIdentityPool().GetIdentityConfidential(ctx, id) + if err != nil { + return err + } + + c, ok := updated.GetCredentials(ct) + if !ok { + return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Expected credentials of type %s to exist but they did not.", ct)) + } + + if err := cb(c); err != nil { + return err + } + + updated.SetCredentials(ct, *c) + o := newManagerOptions(opts) + if err := m.ValidateIdentity(ctx, updated, o); err != nil { + return err + } + + return m.r.PrivilegedIdentityPool().UpdateIdentity(ctx, updated) +} + func (m *Manager) UpdateSchemaID(ctx context.Context, id uuid.UUID, schemaID string, opts ...ManagerOption) (err error) { ctx, span := m.r.Tracer(ctx).Tracer().Start(ctx, "identity.Manager.UpdateSchemaID") defer otelx.End(span, &err) diff --git a/identity/manager_test.go b/identity/manager_test.go index 6764f33ab95c..1c5cc32f49fc 100644 --- a/identity/manager_test.go +++ b/identity/manager_test.go @@ -9,6 +9,11 @@ import ( "testing" "time" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" + + "github.com/ory/x/assertx" + "github.com/ory/x/sqlxx" "github.com/ory/kratos/internal/testhelpers" @@ -203,6 +208,54 @@ func TestManager(t *testing.T) { assert.Equal(t, 1, count) }) + t.Run("method=UpdateCredentials", func(t *testing.T) { + original := identity.NewIdentity(config.DefaultIdentityTraitsSchemaID) + original.Traits = newTraits("update_creds@ory.sh", "") + original.Credentials[identity.CredentialsTypePassword] = identity.Credentials{ + Type: identity.CredentialsTypePassword, + Identifiers: []string{"update_creds@ory.sh"}, + Config: []byte(`{"hashed_password":"$argon2id$v=19$m=32,t=2,p=4$cm94YnRVOW5jZzFzcVE4bQ$MNzk5BtR2vUhrp6qQEjRNw"}`), + } + original.Credentials[identity.CredentialsTypeWebAuthn] = identity.Credentials{ + Type: identity.CredentialsTypeWebAuthn, + Identifiers: []string{"foo"}, + Config: []byte(`{"credentials":[{"is_passwordless":false}]}`), + Version: 1, + } + require.NoError(t, reg.IdentityManager().Create(context.Background(), original)) + + t.Run("case=can not update non-existing credentials", func(t *testing.T) { + require.Error(t, reg.IdentityManager().UpdateCredentials(context.Background(), original.ID, identity.CredentialsTypeOIDC, func(c *identity.Credentials) error { + return nil + })) + }) + + t.Run("case=propagates error", func(t *testing.T) { + err := errors.New("foo") + require.ErrorIs(t, reg.IdentityManager().UpdateCredentials(context.Background(), original.ID, identity.CredentialsTypePassword, func(c *identity.Credentials) error { + return err + }), err) + }) + + t.Run("case=updates credentials", func(t *testing.T) { + require.NoError(t, reg.IdentityManager().UpdateCredentials(context.Background(), original.ID, identity.CredentialsTypePassword, func(c *identity.Credentials) (err error) { + c.Config, err = sjson.SetBytes(c.Config, "new_key", "new_value") + return nil + })) + + fromStore, err := reg.PrivilegedIdentityPool().GetIdentityConfidential(context.Background(), original.ID) + require.NoError(t, err) + + actual, ok := fromStore.GetCredentials(identity.CredentialsTypePassword) + require.True(t, ok) + assert.Equal(t, "new_value", gjson.GetBytes(actual.Config, "new_key").String()) + + actual, ok = fromStore.GetCredentials(identity.CredentialsTypeWebAuthn) + require.True(t, ok) + assertx.EqualAsJSONExcept(t, actual, original.Credentials[identity.CredentialsTypeWebAuthn], []string{"updated_at"}, "other credentials should not be changed") + }) + }) + t.Run("method=UpdateTraits", func(t *testing.T) { t.Run("case=should update protected traits with option", func(t *testing.T) { original := identity.NewIdentity(config.DefaultIdentityTraitsSchemaID) diff --git a/selfservice/flow/login/handler.go b/selfservice/flow/login/handler.go index 0b277d6e8538..90fd2bed2231 100644 --- a/selfservice/flow/login/handler.go +++ b/selfservice/flow/login/handler.go @@ -716,7 +716,6 @@ continueLogin: var i *identity.Identity var group node.UiNodeGroup - var s Strategy for _, ss := range h.d.AllLoginStrategies() { interim, err := ss.Login(w, r, f, sess.IdentityID) group = ss.NodeGroup() @@ -738,16 +737,15 @@ continueLogin: method := ss.CompletedAuthenticationMethod(r.Context()) sess.CompletedLoginFor(method.Method, method.AAL) i = interim - s = ss break } - if i == nil || s == nil { + if i == nil { h.d.LoginFlowErrorHandler().WriteFlowError(w, r, f, node.DefaultGroup, errors.WithStack(schema.NewNoLoginStrategyResponsible())) return } - if err := h.d.LoginHookExecutor().PostLoginHook(w, r, s.ID(), group, f, i, sess); err != nil { + if err := h.d.LoginHookExecutor().PostLoginHook(w, r, group, f, i, sess); err != nil { if errors.Is(err, ErrAddressNotVerified) { h.d.LoginFlowErrorHandler().WriteFlowError(w, r, f, node.DefaultGroup, errors.WithStack(schema.NewAddressNotVerifiedError())) return diff --git a/selfservice/flow/login/handler_test.go b/selfservice/flow/login/handler_test.go index 21f51853805d..53f534dd5feb 100644 --- a/selfservice/flow/login/handler_test.go +++ b/selfservice/flow/login/handler_test.go @@ -237,7 +237,7 @@ func TestFlowLifecycle(t *testing.T) { assert.NotEqual(t, gjson.Get(a, "session_token").String(), gjson.Get(b, "session_token").String()) assert.NotEmpty(t, gjson.Get(b, "session.id").String()) - assert.NotEqual(t, gjson.Get(b, "session.id").String(), gjson.Get(a, "session.id").String()) + assert.NotEqual(t, gjson.Get(b, "session.id").String(), gjson.Get(a, "id").String()) }) }) diff --git a/selfservice/flow/login/hook.go b/selfservice/flow/login/hook.go index 5233c246dbf1..7517a0107f64 100644 --- a/selfservice/flow/login/hook.go +++ b/selfservice/flow/login/hook.go @@ -44,9 +44,7 @@ type ( type ( executorDependencies interface { config.Provider - identity.ManagementProvider hydra.HydraProvider - identity.ManagementProvider session.ManagementProvider session.PersistenceProvider x.CSRFTokenGeneratorProvider @@ -114,11 +112,12 @@ func (e *HookExecutor) handleLoginError(_ http.ResponseWriter, r *http.Request, return flowError } -func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, ct identity.CredentialsType, g node.UiNodeGroup, a *Flow, i *identity.Identity, s *session.Session) (err error) { +func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, g node.UiNodeGroup, a *Flow, i *identity.Identity, s *session.Session) (err error) { ctx := r.Context() ctx, span := e.d.Tracer(ctx).Tracer().Start(ctx, "HookExecutor.PostLoginHook") r = r.WithContext(ctx) defer otelx.End(span, &err) + if err := s.Activate(r, i, e.d.Config(), time.Now().UTC()); err != nil { return err } @@ -199,15 +198,6 @@ func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, ct return nil } - if ct == identity.CredentialsTypeOIDC { - options := []identity.ManagerOption{ - identity.ManagerExposeValidationErrorsForInternalTypeAssertion, - identity.ManagerAllowWriteProtectedTraits, - } - if err := e.d.IdentityManager().Update(r.Context(), i, options...); err != nil { - return errors.WithStack(err) - } - } if err := e.d.SessionManager().UpsertAndIssueCookie(r.Context(), w, r, s); err != nil { return errors.WithStack(err) } diff --git a/selfservice/flow/login/hook_test.go b/selfservice/flow/login/hook_test.go index bfd0768c3c98..adfa477c2df0 100644 --- a/selfservice/flow/login/hook_test.go +++ b/selfservice/flow/login/hook_test.go @@ -65,7 +65,7 @@ func TestLoginExecutor(t *testing.T) { } testhelpers.SelfServiceHookLoginErrorHandler(t, w, r, - reg.LoginHookExecutor().PostLoginHook(w, r, identity.CredentialsType(strategy), strategy.ToUiNodeGroup(), a, useIdentity, sess)) + reg.LoginHookExecutor().PostLoginHook(w, r, strategy.ToUiNodeGroup(), a, useIdentity, sess)) }) ts := httptest.NewServer(router) diff --git a/selfservice/strategy/oidc/strategy_login.go b/selfservice/strategy/oidc/strategy_login.go index 0d36fad137c9..2faf652af46e 100644 --- a/selfservice/strategy/oidc/strategy_login.go +++ b/selfservice/strategy/oidc/strategy_login.go @@ -131,55 +131,64 @@ func (s *Strategy) processLogin(w http.ResponseWriter, r *http.Request, a *login var o identity.CredentialsOIDC if err := json.NewDecoder(bytes.NewBuffer(c.Config)).Decode(&o); err != nil { - return nil, s.handleError(w, r, a, provider.Config().ID, nil, errors.WithStack(herodot.ErrInternalServerError.WithReason("The password credentials could not be decoded properly").WithDebug(err.Error()))) - } - - // UPDATE TOKEN - var it string - if idToken, ok := token.Extra("id_token").(string); ok { - if it, err = s.d.Cipher(r.Context()).Encrypt(r.Context(), []byte(idToken)); err != nil { - return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) - } - } - - cat, err := s.d.Cipher(r.Context()).Encrypt(r.Context(), []byte(token.AccessToken)) - if err != nil { - return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) - } - - crt, err := s.d.Cipher(r.Context()).Encrypt(r.Context(), []byte(token.RefreshToken)) - if err != nil { - return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) + return nil, s.handleError(w, r, a, provider.Config().ID, nil, errors.WithStack(herodot.ErrInternalServerError.WithReason("The OpenID connect credentials could not be decoded properly.").WithDebug(err.Error()))) } sess := session.NewInactiveSession() sess.CompletedLoginFor(s.ID(), identity.AuthenticatorAssuranceLevel1) + + found := -1 for k := range o.Providers { p := &o.Providers[k] if p.Subject == claims.Subject && p.Provider == provider.Config().ID { - i, err := s.d.PrivilegedIdentityPool().GetIdentityConfidential(r.Context(), i.ID) - if err != nil { - return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) - } + found = k + break + } + } - p.InitialIDToken = it - p.InitialAccessToken = cat - p.InitialRefreshToken = crt + if found == -1 { + return nil, s.handleError(w, r, a, provider.Config().ID, nil, errors.WithStack(herodot.ErrInternalServerError.WithReason("Unable to find matching OpenID Connect Credentials.").WithDebugf(`Unable to find credentials that match the given provider "%s" and subject "%s".`, provider.Config().ID, claims.Subject))) + } - c.Config, err = json.Marshal(o) - if err != nil { - return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) - } + if err := s.d.IdentityManager().UpdateCredentials(r.Context(), i.ID, identity.CredentialsTypeOIDC, func(toUpdate *identity.Credentials) error { + var toUpdateConfig identity.CredentialsOIDC + if err := toUpdate.UnmarshalConfig(toUpdate); err != nil { + return err + } - i.Credentials[s.ID()] = *c - if err = s.d.LoginHookExecutor().PostLoginHook(w, r, identity.CredentialsTypeOIDC, node.OpenIDConnectGroup, a, i, sess); err != nil { - return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) + k, found := toUpdateConfig.GetProvider(provider.Config().ID, claims.Subject) + if !found { + // Credentials are not found, we can ignore this. + return nil + } + + if idToken, ok := token.Extra("id_token").(string); ok { + if toUpdateConfig.Providers[k].CurrentIDToken, err = s.d.Cipher(r.Context()).Encrypt(r.Context(), []byte(idToken)); err != nil { + return err } - return nil, nil } + + toUpdateConfig.Providers[k].CurrentAccessToken, err = s.d.Cipher(r.Context()).Encrypt(r.Context(), []byte(token.AccessToken)) + if err != nil { + return err + } + + toUpdateConfig.Providers[k].CurrentRefreshToken, err = s.d.Cipher(r.Context()).Encrypt(r.Context(), []byte(token.RefreshToken)) + if err != nil { + return err + } + + toUpdate.Config, err = json.Marshal(toUpdateConfig) + return errors.WithStack(err) + }); err != nil { + return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) + } + + if err = s.d.LoginHookExecutor().PostLoginHook(w, r, node.OpenIDConnectGroup, a, toUpdate, sess); err != nil { + return nil, s.handleError(w, r, a, provider.Config().ID, nil, err) } - return nil, s.handleError(w, r, a, provider.Config().ID, nil, errors.WithStack(herodot.ErrInternalServerError.WithReason("Unable to find matching OpenID Connect Credentials.").WithDebugf(`Unable to find credentials that match the given provider "%s" and subject "%s".`, provider.Config().ID, claims.Subject))) + return nil, nil } func (s *Strategy) Login(w http.ResponseWriter, r *http.Request, f *login.Flow, identityID uuid.UUID) (i *identity.Identity, err error) { diff --git a/selfservice/strategy/oidc/strategy_settings.go b/selfservice/strategy/oidc/strategy_settings.go index 3cb3a6cfdcf3..339d1262ea23 100644 --- a/selfservice/strategy/oidc/strategy_settings.go +++ b/selfservice/strategy/oidc/strategy_settings.go @@ -425,6 +425,9 @@ func (s *Strategy) linkProvider(w http.ResponseWriter, r *http.Request, ctxUpdat InitialAccessToken: cat, InitialRefreshToken: crt, InitialIDToken: it, + CurrentAccessToken: cat, + CurrentRefreshToken: crt, + CurrentIDToken: it, }) creds.Config, err = json.Marshal(conf) diff --git a/selfservice/strategy/oidc/strategy_settings_test.go b/selfservice/strategy/oidc/strategy_settings_test.go index 4ce80da5b200..341728e88546 100644 --- a/selfservice/strategy/oidc/strategy_settings_test.go +++ b/selfservice/strategy/oidc/strategy_settings_test.go @@ -234,6 +234,9 @@ func TestSettingsStrategy(t *testing.T) { assert.NotEmpty(t, p.InitialIDToken) assert.NotEmpty(t, p.InitialAccessToken) assert.NotEmpty(t, p.InitialRefreshToken) + assert.NotEmpty(t, p.CurrentIDToken) + assert.NotEmpty(t, p.CurrentAccessToken) + assert.NotEmpty(t, p.CurrentRefreshToken) } break } diff --git a/test/e2e/cypress/integration/profiles/oidc-provider/update.spec.ts b/test/e2e/cypress/integration/profiles/oidc-provider/update.spec.ts index 5904aeed99c4..0d4517cef82f 100644 --- a/test/e2e/cypress/integration/profiles/oidc-provider/update.spec.ts +++ b/test/e2e/cypress/integration/profiles/oidc-provider/update.spec.ts @@ -1,13 +1,11 @@ // Copyright © 2022 Ory Corp // SPDX-License-Identifier: Apache-2.0 -import {appPrefix, gen, website} from "../../../helpers" +import { appPrefix, gen, website } from "../../../helpers" import { routes as express } from "../../../helpers/express" -import * as httpbin from "../../../helpers/httpbin" -import {routes as react} from "../../../helpers/react"; -import * as oauth2 from "../../../helpers/oauth2"; +import { routes as react } from "../../../helpers/react" -context( "OpenID Provider Update", () => { +context("OpenID Provider Update", () => { ;[ { login: react.login, @@ -21,10 +19,9 @@ context( "OpenID Provider Update", () => { app: "express" as "express", profile: "oidc", }, - - ].forEach(({login, registration, profile, app}) => { + ].forEach(({ login, registration, profile, app }) => { describe(`for app ${app}`, () => { - before( () => { + before(() => { cy.useConfigProfile(profile) cy.proxy(app) }) @@ -99,12 +96,56 @@ context( "OpenID Provider Update", () => { }) cy.getSession().then((session) => { shouldSession(email)(session) - cy.getFullIdentityById({id: session.identity.id}).then ( (identity) => { - expect(identity.credentials.oidc.config.providers[0].initial_access_token).to.not.be.empty - expect(identity.credentials.oidc.config.providers[0].initial_id_token).to.not.be.empty - expect(identity.credentials.oidc.config.providers[0].initial_refresh_token).to.not.be.empty - expect(identity.credentials.oidc.config.providers[0].provider).to.eq("hydra") - }) + cy.getFullIdentityById({ id: session.identity.id }).then( + (identity) => { + expect( + identity.credentials.oidc.config.providers[0] + .initial_access_token, + ).to.not.be.empty + expect( + identity.credentials.oidc.config.providers[0].initial_id_token, + ).to.not.be.empty + expect( + identity.credentials.oidc.config.providers[0] + .initial_refresh_token, + ).to.not.be.empty + expect( + identity.credentials.oidc.config.providers[0] + .current_access_token, + ).to.not.be.empty + expect( + identity.credentials.oidc.config.providers[0].current_id_token, + ).to.not.be.empty + expect( + identity.credentials.oidc.config.providers[0] + .current_refresh_token, + ).to.not.be.empty + + expect( + identity.credentials.oidc.config.providers[0] + .initial_access_token, + ).to.not.eq( + identity.credentials.oidc.config.providers[0] + .current_access_token, + ) + expect( + identity.credentials.oidc.config.providers[0].initial_id_token, + ).to.not.eq( + identity.credentials.oidc.config.providers[0].current_id_token, + ) + expect( + identity.credentials.oidc.config.providers[0] + .initial_refresh_token, + ).to.not.eq( + identity.credentials.oidc.config.providers[0] + .current_refresh_token, + ) + + expect( + identity.credentials.oidc.config.providers[0].provider, + ).to.eq("hydra") + }, + ) }) }) }) diff --git a/test/e2e/cypress/support/commands.ts b/test/e2e/cypress/support/commands.ts index c72c7616e0e7..2e432446c8c9 100644 --- a/test/e2e/cypress/support/commands.ts +++ b/test/e2e/cypress/support/commands.ts @@ -1016,14 +1016,14 @@ Cypress.Commands.add("getIdentityByEmail", ({ email }) => }), ) -Cypress.Commands.add( "getFullIdentityById", ({ id }) => +Cypress.Commands.add("getFullIdentityById", ({ id }) => cy .request({ method: "GET", url: `${KRATOS_ADMIN}/admin/identities/${id}?include_credential=oidc`, failOnStatusCode: false, }) - .then( (response) => { + .then((response) => { expect(response.status).to.eq(200) return response.body }), diff --git a/test/e2e/package.json b/test/e2e/package.json index b82f60a5fa42..3dca8afef148 100644 --- a/test/e2e/package.json +++ b/test/e2e/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@ory/kratos-client": "0.0.0-next.8d3b018594f7", - "@types/node": "^16.9.6", + "@types/node": "^16.9.6", "@types/yamljs": "^0.2.31", "chrome-remote-interface": "0.31.2", "cypress": "^11.2.0",