diff --git a/docs/v3.x/plugins/users-permissions.md b/docs/v3.x/plugins/users-permissions.md index 6f6924959e..2bf13f0eaf 100644 --- a/docs/v3.x/plugins/users-permissions.md +++ b/docs/v3.x/plugins/users-permissions.md @@ -493,6 +493,40 @@ The use of `ngrok` is not needed. ::: +::: tab LinkedIn + +#### Using ngrok + +LinkedIn accepts the `localhost` urls.
+The use of `ngrok` is not needed. + +#### LinkedIn configuration + +- Visit the Apps list page
[https://www.linkedin.com/developers/apps](https://www.linkedin.com/developers/apps) +- Click on **Create app** button +- Fill the information: + - **App name**: Strapi auth + - **LinkedIn Page**: Enter a LinkedIn page name to associate with the app or click **Create a new LinkedIn Page** to create a new one + - **App Logo**: Upload a square image that is at least 100x100 pixels. +- Click on the **Create app** to create the app +- On the app page click on **Auth** tab +- Fill the information: + - **Authorized redirect URL**: `http://localhost:1337/connect/linkedin/callback` +- On the app page click on **Products** tab. +- Select `Sign In with LinkedIn` from the product list to enable it. + +#### Strapi configuration + +- Visit the User Permissions provider settings page
[http://localhost:1337/admin/plugins/users-permissions/providers](http://localhost:1337/admin/plugins/users-permissions/providers) +- Click on the **LinkedIn** provider +- Fill the information: + - **Enable**: `ON` + - **Client ID**: 84witsxk641rlv + - **Client Secret**: HdXO7a7mkrU5a6WN + - **The redirect URL to your front-end app**: `http://localhost:3000/connect/linkedin/redirect` + +::: + :::: Your configuration is done. diff --git a/packages/strapi-plugin-users-permissions/config/functions/bootstrap.js b/packages/strapi-plugin-users-permissions/config/functions/bootstrap.js index be16ee70bd..41dedb3aa8 100644 --- a/packages/strapi-plugin-users-permissions/config/functions/bootstrap.js +++ b/packages/strapi-plugin-users-permissions/config/functions/bootstrap.js @@ -94,6 +94,14 @@ module.exports = async () => { callback: `${strapi.config.server.url}/auth/twitch/callback`, scope: ['user:read:email'], }, + linkedin: { + enabled: false, + icon: 'linkedin', + key: '', + secret: '', + callback: `${strapi.config.server.url}/auth/linkedin/callback`, + scope: ['r_liteprofile', 'r_emailaddress'], + }, }; const prevGrantConfig = (await pluginStore.get({ key: 'grant' })) || {}; // store grant auth config to db diff --git a/packages/strapi-plugin-users-permissions/services/Providers.js b/packages/strapi-plugin-users-permissions/services/Providers.js index ab7504be6a..867c0efd9c 100644 --- a/packages/strapi-plugin-users-permissions/services/Providers.js +++ b/packages/strapi-plugin-users-permissions/services/Providers.js @@ -386,6 +386,69 @@ const getProfile = async (provider, query, callback) => { }); break; } + case 'linkedin': { + const linkedIn = purest({ + provider: 'linkedin', + config: { + linkedin: { + 'https://api.linkedin.com': { + __domain: { + auth: [{ auth: { bearer: '[0]' } }], + }, + '[version]/{endpoint}': { + __path: { + alias: '__default', + version: 'v2', + }, + }, + }, + }, + }, + }); + try { + const getDetailsRequest = () => { + return new Promise((resolve, reject) => { + linkedIn + .query() + .get('me') + .auth(access_token) + .request((err, res, body) => { + if (err) { + return reject(err); + } + resolve(body); + }); + }); + }; + + const getEmailRequest = () => { + return new Promise((resolve, reject) => { + linkedIn + .query() + .get('emailAddress?q=members&projection=(elements*(handle~))') + .auth(access_token) + .request((err, res, body) => { + if (err) { + return reject(err); + } + resolve(body); + }); + }); + }; + + const { localizedFirstName } = await getDetailsRequest(); + const { elements } = await getEmailRequest(); + const email = elements[0]['handle~']; + + callback(null, { + username: localizedFirstName, + email: email.emailAddress, + }); + } catch (err) { + callback(err); + } + break; + } default: callback({ message: 'Unknown provider.',