From b09d4e4845fd59400c51c74c6d6448b633ebc277 Mon Sep 17 00:00:00 2001 From: Ankit Tiwari Date: Tue, 5 Dec 2023 19:33:56 +0530 Subject: [PATCH] fix: LinkedIn OAuth --- CHANGELOG.md | 4 +++ setup.py | 2 +- supertokens_python/constants.py | 2 +- .../recipe/thirdparty/providers/linkedin.py | 25 +++++-------------- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e81cb0dcf..70ef7bb25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +## [0.18.2] - 2023-12-05 + +- Updates LinkedIn OAuth implementation as per the latest [changes](https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2?context=linkedin%2Fconsumer%2Fcontext#authenticating-members). + ## [0.18.1] - 2023-12-01 - Fixes bug in dashboard recipe where we did not expose `USER_EMAIL_VERIFY_TOKEN_API` API. diff --git a/setup.py b/setup.py index 38d5b497c..5001707ef 100644 --- a/setup.py +++ b/setup.py @@ -70,7 +70,7 @@ setup( name="supertokens_python", - version="0.18.1", + version="0.18.2", author="SuperTokens", license="Apache 2.0", author_email="team@supertokens.com", diff --git a/supertokens_python/constants.py b/supertokens_python/constants.py index 033d01503..27c4ecdd7 100644 --- a/supertokens_python/constants.py +++ b/supertokens_python/constants.py @@ -14,7 +14,7 @@ from __future__ import annotations SUPPORTED_CDI_VERSIONS = ["3.0"] -VERSION = "0.18.1" +VERSION = "0.18.2" TELEMETRY = "/telemetry" USER_COUNT = "/users/count" USER_DELETE = "/user/remove" diff --git a/supertokens_python/recipe/thirdparty/providers/linkedin.py b/supertokens_python/recipe/thirdparty/providers/linkedin.py index 54708c139..2da9319d8 100644 --- a/supertokens_python/recipe/thirdparty/providers/linkedin.py +++ b/supertokens_python/recipe/thirdparty/providers/linkedin.py @@ -42,7 +42,8 @@ async def get_config_for_client_type( config = await super().get_config_for_client_type(client_type, user_context) if config.scope is None: - config.scope = ["r_emailaddress", "r_liteprofile"] + # https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2?context=linkedin%2Fconsumer%2Fcontext#authenticating-members + config.scope = ["openid", "profile", "email"] return config @@ -59,31 +60,17 @@ async def get_user_info( } raw_user_info_from_provider = RawUserInfoFromProvider({}, {}) + # https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2?context=linkedin%2Fconsumer%2Fcontext#sample-api-response user_info = await do_get_request( - "https://api.linkedin.com/v2/me", headers=headers + "https://api.linkedin.com/v2/userinfo", headers=headers ) raw_user_info_from_provider.from_user_info_api = user_info - email_api_url = "https://api.linkedin.com/v2/emailAddress" - email_info: Dict[str, Any] = await do_get_request( - email_api_url, - query_params={"q": "members", "projection": "(elements*(handle~))"}, - headers=headers, - ) - - if email_info.get("elements") is not None and len(email_info.get("elements")) > 0: # type: ignore - raw_user_info_from_provider.from_user_info_api["email"] = email_info.get("elements")[0].get("handle~").get("emailAddress") # type: ignore - - raw_user_info_from_provider.from_user_info_api = { - **raw_user_info_from_provider.from_user_info_api, - **email_info, - } - return UserInfo( - third_party_user_id=raw_user_info_from_provider.from_user_info_api.get("id"), # type: ignore + third_party_user_id=raw_user_info_from_provider.from_user_info_api.get("sub"), # type: ignore email=UserInfoEmail( email=raw_user_info_from_provider.from_user_info_api.get("email"), # type: ignore - is_verified=False, + is_verified=raw_user_info_from_provider.from_user_info_api.get("email_verified"), # type: ignore ), )