diff --git a/internal/api/external_kakao_test.go b/internal/api/external_kakao_test.go index ecd7d58d5..01e694d5f 100644 --- a/internal/api/external_kakao_test.go +++ b/internal/api/external_kakao_test.go @@ -100,6 +100,34 @@ func (ts *ExternalTestSuite) TestSignupExternalKakao_AuthorizationCode() { assertAuthorizationSuccess(ts, u, tokenCount, userCount, "kakao@example.com", "Kakao Test", "123", "http://example.com/avatar") } +func (ts *ExternalTestSuite) TestSignupExternalKakao_AuthorizationCode_NoEmailWithEmailOptional() { + ts.Config.DisableSignup = false + ts.Config.External.Kakao.EmailOptional = true + tokenCount, userCount := 0, 0 + code := "authcode" + emails := `[{"primary": true, "verified": true}]` + server := KakaoTestSignupSetup(ts, &tokenCount, &userCount, code, emails) + defer server.Close() + + u := performAuthorization(ts, "kakao", code, "") + + assertAuthorizationSuccess(ts, u, tokenCount, userCount, "", "Kakao Test", "123", "http://example.com/avatar") +} + +func (ts *ExternalTestSuite) TestSignupExternalKakao_AuthorizationCode_NoEmailWithoutEmailOptional() { + ts.Config.DisableSignup = false + ts.Config.External.Kakao.EmailOptional = false + tokenCount, userCount := 0, 0 + code := "authcode" + emails := `[{"primary": true, "verified": true}]` + server := KakaoTestSignupSetup(ts, &tokenCount, &userCount, code, emails) + defer server.Close() + + u := performAuthorization(ts, "kakao", code, "") + + assertAuthorizationFailure(ts, u, "Error getting user email from external provider", "server_error", "") +} + func (ts *ExternalTestSuite) TestSignupExternalKakaoDisableSignupErrorWhenNoUser() { ts.Config.DisableSignup = true tokenCount, userCount := 0, 0 diff --git a/internal/api/provider/kakao.go b/internal/api/provider/kakao.go index a5588d1f8..5c0b20de9 100644 --- a/internal/api/provider/kakao.go +++ b/internal/api/provider/kakao.go @@ -85,10 +85,12 @@ func NewKakaoProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuth apiHost := chooseHost(ext.URL, defaultKakaoAPIBase) oauthScopes := []string{ - "account_email", "profile_image", "profile_nickname", } + if !ext.EmailOptional { + oauthScopes = append([]string{"account_email"}, oauthScopes...) + } if scopes != "" { oauthScopes = append(oauthScopes, strings.Split(scopes, ",")...) diff --git a/internal/api/provider/kakao_test.go b/internal/api/provider/kakao_test.go new file mode 100644 index 000000000..a0c578c70 --- /dev/null +++ b/internal/api/provider/kakao_test.go @@ -0,0 +1,61 @@ +package provider + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/supabase/auth/internal/conf" +) + +func TestNewKakaoProviderScopes(t *testing.T) { + config := conf.OAuthProviderConfiguration{ + Enabled: true, + ClientID: []string{"client-id"}, + Secret: "secret", + RedirectURI: "https://project.supabase.co/auth/v1/callback", + } + + t.Run("requests email by default", func(t *testing.T) { + p, err := NewKakaoProvider(config, "") + require.NoError(t, err) + + kakao, ok := p.(*kakaoProvider) + require.True(t, ok) + require.Equal(t, []string{ + "account_email", + "profile_image", + "profile_nickname", + }, kakao.Scopes) + }) + + t.Run("omits email when email is optional", func(t *testing.T) { + config := config + config.EmailOptional = true + + p, err := NewKakaoProvider(config, "") + require.NoError(t, err) + + kakao, ok := p.(*kakaoProvider) + require.True(t, ok) + require.Equal(t, []string{ + "profile_image", + "profile_nickname", + }, kakao.Scopes) + }) + + t.Run("allows custom scopes to opt back into email", func(t *testing.T) { + config := config + config.EmailOptional = true + + p, err := NewKakaoProvider(config, "account_email") + require.NoError(t, err) + + kakao, ok := p.(*kakaoProvider) + require.True(t, ok) + require.Equal(t, []string{ + "profile_image", + "profile_nickname", + "account_email", + }, kakao.Scopes) + }) +}