diff --git a/app/services/identity_reconciler.go b/app/services/identity_reconciler.go index f022b321a..e38684933 100644 --- a/app/services/identity_reconciler.go +++ b/app/services/identity_reconciler.go @@ -30,9 +30,14 @@ func IdentityReconciler(accountStore data.AccountStore, cfg *app.Config, provide return nil, errors.Wrap(err, "FindByOauthAccount") } if linkedAccount != nil { + if linkedAccount.ID != linkableAccountID && linkableAccountID != 0 { + return nil, errors.New("account already linked") + } + if linkedAccount.Locked { return nil, errors.New("account locked") } + return linkedAccount, nil } diff --git a/server/handlers/get_oauth_return_test.go b/server/handlers/get_oauth_return_test.go index 9309a472a..f24b63fa0 100644 --- a/server/handlers/get_oauth_return_test.go +++ b/server/handlers/get_oauth_return_test.go @@ -84,6 +84,23 @@ func TestGetOauthReturn(t *testing.T) { test.AssertRedirect(t, res, "https://localhost:9999/return?status=failed") }) + t.Run("not connect provider account already linked", func(t *testing.T) { + linkedAccount, err := app.AccountStore.Create("linked.account@keratin.tech", []byte("password")) + require.NoError(t, err) + + err = app.AccountStore.AddOauthAccount(linkedAccount.ID, "test", "LINKEDID", "TOKEN") + require.NoError(t, err) + + account, err := app.AccountStore.Create("registered.account@keratin.tech", []byte("password")) + require.NoError(t, err) + + session := test.CreateSession(app.RefreshTokenStore, app.Config, account.ID) + + res, err := client.WithCookie(session).Get("/oauth/test/return?code=LINKEDID&state=" + state) + require.NoError(t, err) + test.AssertRedirect(t, res, "https://localhost:9999/return?status=failed") + }) + t.Run("log in to existing identity", func(t *testing.T) { account, err := app.AccountStore.Create("registered@keratin.tech", []byte("password")) require.NoError(t, err)