@logto/connector-linkedin 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -49,10 +49,10 @@ var defaultMetadata = {
49
49
  },
50
50
  {
51
51
  key: "scope",
52
- type: ConnectorConfigFormItemType.Text,
52
+ type: ConnectorConfigFormItemType.MultilineText,
53
53
  label: "Scope",
54
54
  required: false,
55
- description: "The `scope` determines permissions granted by the user's authorization. If you are not sure what to enter, do not worry, just leave it blank."
55
+ description: "The `scope` determines permissions granted by the user's authorization. "
56
56
  }
57
57
  ]
58
58
  };
@@ -79,7 +79,7 @@ var accessTokenResponseGuard = z.object({
79
79
  });
80
80
 
81
81
  // src/index.ts
82
- var getAuthorizationUri = (getConfig) => async ({ state, redirectUri }, setSession) => {
82
+ var getAuthorizationUri = (getConfig) => async ({ state, redirectUri, scope }, setSession) => {
83
83
  const config = await getConfig(defaultMetadata.id);
84
84
  validateConfig(config, linkedInConfigGuard);
85
85
  await setSession({ redirectUri });
@@ -87,7 +87,7 @@ var getAuthorizationUri = (getConfig) => async ({ state, redirectUri }, setSessi
87
87
  response_type: "code",
88
88
  client_id: config.clientId,
89
89
  redirect_uri: redirectUri,
90
- scope: config.scope ?? defaultScope,
90
+ scope: scope ?? config.scope ?? defaultScope,
91
91
  state
92
92
  });
93
93
  return `${authorizationEndpoint}?${queryParams.toString()}`;
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts"],"sourcesContent":["import { conditional } from '@silverhand/essentials';\n\nimport {\n ConnectorError,\n ConnectorErrorCodes,\n validateConfig,\n ConnectorType,\n jsonGuard,\n} from '@logto/connector-kit';\nimport type {\n GetAuthorizationUri,\n GetUserInfo,\n SocialConnector,\n CreateConnector,\n GetConnectorConfig,\n} from '@logto/connector-kit';\nimport ky, { HTTPError } from 'ky';\n\nimport {\n authorizationEndpoint,\n accessTokenEndpoint,\n defaultMetadata,\n defaultTimeout,\n defaultScope,\n userInfoEndpoint,\n} from './constant.js';\nimport type { LinkedInConfig } from './types.js';\nimport {\n linkedInConfigGuard,\n userInfoResponseGuard,\n authResponseGuard,\n accessTokenResponseGuard,\n} from './types.js';\n\nconst getAuthorizationUri =\n (getConfig: GetConnectorConfig): GetAuthorizationUri =>\n async ({ state, redirectUri }, setSession) => {\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, linkedInConfigGuard);\n\n await setSession({ redirectUri });\n\n const queryParams = new URLSearchParams({\n response_type: 'code',\n client_id: config.clientId,\n redirect_uri: redirectUri,\n scope: config.scope ?? defaultScope,\n state,\n });\n\n return `${authorizationEndpoint}?${queryParams.toString()}`;\n };\n\nexport const getAccessToken = async (config: LinkedInConfig, code: string, redirectUri: string) => {\n const response = await ky\n .post(accessTokenEndpoint, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n client_id: config.clientId,\n client_secret: config.clientSecret,\n }).toString(),\n timeout: defaultTimeout,\n })\n .json();\n\n return accessTokenResponseGuard.parse(response);\n};\n\nconst getUserInfo =\n (getConfig: GetConnectorConfig): GetUserInfo =>\n async (data, getSession) => {\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, linkedInConfigGuard);\n\n const authResponseResult = authResponseGuard.safeParse(data);\n\n if (!authResponseResult.success) {\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(data));\n }\n\n const { code } = authResponseResult.data;\n const { redirectUri } = await getSession();\n\n if (!redirectUri) {\n throw new ConnectorError(ConnectorErrorCodes.General, {\n message: 'Cannot find `redirectUri` from connector session.',\n });\n }\n\n try {\n const { access_token } = await getAccessToken(config, code, redirectUri);\n\n const userInfo = await ky\n .get(userInfoEndpoint, {\n headers: {\n Authorization: `Bearer ${access_token}`,\n },\n timeout: defaultTimeout,\n })\n .json();\n const userInfoResult = userInfoResponseGuard.safeParse(userInfo);\n\n if (!userInfoResult.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userInfoResult.error);\n }\n\n const { sub, name, email, picture } = userInfoResult.data;\n\n return {\n id: sub,\n name: conditional(name),\n email: conditional(email),\n picture: conditional(picture),\n rawData: jsonGuard.parse(userInfo),\n };\n } catch (error: unknown) {\n if (error instanceof HTTPError) {\n const { status, body: rawBody } = error.response;\n\n if (status === 401) {\n throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid);\n }\n\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(rawBody));\n }\n\n throw error;\n }\n };\n\nconst createLinkedInConnector: CreateConnector<SocialConnector> = async ({ getConfig }) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Social,\n configGuard: linkedInConfigGuard,\n getAuthorizationUri: getAuthorizationUri(getConfig),\n getUserInfo: getUserInfo(getConfig),\n };\n};\n\nexport default createLinkedInConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorPlatform, ConnectorConfigFormItemType } from '@logto/connector-kit';\n\n// See https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin\nexport const authorizationEndpoint = 'https://www.linkedin.com/oauth/v2/authorization';\nexport const defaultScope = 'openid profile email';\nexport const accessTokenEndpoint = 'https://www.linkedin.com/oauth/v2/accessToken';\nexport const userInfoEndpoint = 'https://api.linkedin.com/v2/userinfo';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'linkedin-universal',\n target: 'linkedin',\n platform: ConnectorPlatform.Universal,\n name: {\n en: 'LinkedIn',\n 'zh-CN': 'LinkedIn',\n 'tr-TR': 'LinkedIn',\n ko: 'LinkedIn',\n },\n logo: './logo.svg',\n logoDark: null,\n description: {\n en: 'LinkedIn is a social media platform for professional networking and information sharing.',\n 'zh-CN': 'LinkedIn是一个职业社交和信息分享的社交媒体平台。',\n 'tr-TR':\n 'LinkedIn, profesyonel ağ oluşturma ve bilgi paylaşma için bir sosyal medya platformudur.',\n ko: 'LinkedIn은 전문 네트워킹과 정보 공유를 위한 소셜 미디어 플랫폼입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'clientId',\n type: ConnectorConfigFormItemType.Text,\n label: 'Client ID',\n required: true,\n },\n {\n key: 'clientSecret',\n type: ConnectorConfigFormItemType.Text,\n label: 'Client Secret',\n required: true,\n },\n {\n key: 'scope',\n type: ConnectorConfigFormItemType.Text,\n label: 'Scope',\n required: false,\n description:\n \"The `scope` determines permissions granted by the user's authorization. If you are not sure what to enter, do not worry, just leave it blank.\",\n },\n ],\n};\n\nexport const defaultTimeout = 5000;\n","import { z } from 'zod';\n\nexport const linkedInConfigGuard = z.object({\n clientId: z.string(),\n clientSecret: z.string(),\n scope: z.string().optional(),\n});\n\nexport type LinkedInConfig = z.infer<typeof linkedInConfigGuard>;\n\nexport const userInfoResponseGuard = z.object({\n sub: z.string(),\n name: z.string().nullish(),\n email: z.string().nullish(),\n picture: z.string().nullish(),\n});\n\nexport type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;\n\nexport const authResponseGuard = z.object({\n code: z.string(),\n});\n\nexport const accessTokenResponseGuard = z.object({\n access_token: z.string(),\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts"],"sourcesContent":["import { conditional } from '@silverhand/essentials';\n\nimport {\n ConnectorError,\n ConnectorErrorCodes,\n validateConfig,\n ConnectorType,\n jsonGuard,\n} from '@logto/connector-kit';\nimport type {\n GetAuthorizationUri,\n GetUserInfo,\n SocialConnector,\n CreateConnector,\n GetConnectorConfig,\n} from '@logto/connector-kit';\nimport ky, { HTTPError } from 'ky';\n\nimport {\n authorizationEndpoint,\n accessTokenEndpoint,\n defaultMetadata,\n defaultTimeout,\n defaultScope,\n userInfoEndpoint,\n} from './constant.js';\nimport type { LinkedInConfig } from './types.js';\nimport {\n linkedInConfigGuard,\n userInfoResponseGuard,\n authResponseGuard,\n accessTokenResponseGuard,\n} from './types.js';\n\nconst getAuthorizationUri =\n (getConfig: GetConnectorConfig): GetAuthorizationUri =>\n async ({ state, redirectUri, scope }, setSession) => {\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, linkedInConfigGuard);\n\n await setSession({ redirectUri });\n\n const queryParams = new URLSearchParams({\n response_type: 'code',\n client_id: config.clientId,\n redirect_uri: redirectUri,\n scope: scope ?? config.scope ?? defaultScope,\n state,\n });\n\n return `${authorizationEndpoint}?${queryParams.toString()}`;\n };\n\nexport const getAccessToken = async (config: LinkedInConfig, code: string, redirectUri: string) => {\n const response = await ky\n .post(accessTokenEndpoint, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n client_id: config.clientId,\n client_secret: config.clientSecret,\n }).toString(),\n timeout: defaultTimeout,\n })\n .json();\n\n return accessTokenResponseGuard.parse(response);\n};\n\nconst getUserInfo =\n (getConfig: GetConnectorConfig): GetUserInfo =>\n async (data, getSession) => {\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, linkedInConfigGuard);\n\n const authResponseResult = authResponseGuard.safeParse(data);\n\n if (!authResponseResult.success) {\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(data));\n }\n\n const { code } = authResponseResult.data;\n const { redirectUri } = await getSession();\n\n if (!redirectUri) {\n throw new ConnectorError(ConnectorErrorCodes.General, {\n message: 'Cannot find `redirectUri` from connector session.',\n });\n }\n\n try {\n const { access_token } = await getAccessToken(config, code, redirectUri);\n\n const userInfo = await ky\n .get(userInfoEndpoint, {\n headers: {\n Authorization: `Bearer ${access_token}`,\n },\n timeout: defaultTimeout,\n })\n .json();\n const userInfoResult = userInfoResponseGuard.safeParse(userInfo);\n\n if (!userInfoResult.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userInfoResult.error);\n }\n\n const { sub, name, email, picture } = userInfoResult.data;\n\n return {\n id: sub,\n name: conditional(name),\n email: conditional(email),\n picture: conditional(picture),\n rawData: jsonGuard.parse(userInfo),\n };\n } catch (error: unknown) {\n if (error instanceof HTTPError) {\n const { status, body: rawBody } = error.response;\n\n if (status === 401) {\n throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid);\n }\n\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(rawBody));\n }\n\n throw error;\n }\n };\n\nconst createLinkedInConnector: CreateConnector<SocialConnector> = async ({ getConfig }) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Social,\n configGuard: linkedInConfigGuard,\n getAuthorizationUri: getAuthorizationUri(getConfig),\n getUserInfo: getUserInfo(getConfig),\n };\n};\n\nexport default createLinkedInConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorPlatform, ConnectorConfigFormItemType } from '@logto/connector-kit';\n\n// See https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin\nexport const authorizationEndpoint = 'https://www.linkedin.com/oauth/v2/authorization';\nexport const defaultScope = 'openid profile email';\nexport const accessTokenEndpoint = 'https://www.linkedin.com/oauth/v2/accessToken';\nexport const userInfoEndpoint = 'https://api.linkedin.com/v2/userinfo';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'linkedin-universal',\n target: 'linkedin',\n platform: ConnectorPlatform.Universal,\n name: {\n en: 'LinkedIn',\n 'zh-CN': 'LinkedIn',\n 'tr-TR': 'LinkedIn',\n ko: 'LinkedIn',\n },\n logo: './logo.svg',\n logoDark: null,\n description: {\n en: 'LinkedIn is a social media platform for professional networking and information sharing.',\n 'zh-CN': 'LinkedIn是一个职业社交和信息分享的社交媒体平台。',\n 'tr-TR':\n 'LinkedIn, profesyonel ağ oluşturma ve bilgi paylaşma için bir sosyal medya platformudur.',\n ko: 'LinkedIn은 전문 네트워킹과 정보 공유를 위한 소셜 미디어 플랫폼입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'clientId',\n type: ConnectorConfigFormItemType.Text,\n label: 'Client ID',\n required: true,\n },\n {\n key: 'clientSecret',\n type: ConnectorConfigFormItemType.Text,\n label: 'Client Secret',\n required: true,\n },\n {\n key: 'scope',\n type: ConnectorConfigFormItemType.MultilineText,\n label: 'Scope',\n required: false,\n description: \"The `scope` determines permissions granted by the user's authorization. \",\n },\n ],\n};\n\nexport const defaultTimeout = 5000;\n","import { z } from 'zod';\n\nexport const linkedInConfigGuard = z.object({\n clientId: z.string(),\n clientSecret: z.string(),\n scope: z.string().optional(),\n});\n\nexport type LinkedInConfig = z.infer<typeof linkedInConfigGuard>;\n\nexport const userInfoResponseGuard = z.object({\n sub: z.string(),\n name: z.string().nullish(),\n email: z.string().nullish(),\n picture: z.string().nullish(),\n});\n\nexport type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;\n\nexport const authResponseGuard = z.object({\n code: z.string(),\n});\n\nexport const accessTokenResponseGuard = z.object({\n access_token: z.string(),\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@logto/connector-linkedin",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "LinkedIn web connector implementation.",
5
5
  "author": "Silverhand Inc. <contact@silverhand.io>",
6
6
  "dependencies": {
7
- "@logto/connector-kit": "^4.1.1",
8
7
  "@silverhand/essentials": "^2.9.1",
9
8
  "ky": "^1.2.3",
10
9
  "query-string": "^9.0.0",
11
10
  "snakecase-keys": "^8.0.1",
12
- "zod": "^3.23.8"
11
+ "zod": "3.24.3",
12
+ "@logto/connector-kit": "^4.4.0"
13
13
  },
14
14
  "main": "./lib/index.js",
15
15
  "module": "./lib/index.js",
@@ -23,7 +23,7 @@
23
23
  "logo-dark.svg"
24
24
  ],
25
25
  "engines": {
26
- "node": "^20.9.0"
26
+ "node": "^22.14.0"
27
27
  },
28
28
  "eslintConfig": {
29
29
  "extends": "@silverhand",
@@ -44,17 +44,17 @@
44
44
  "devDependencies": {
45
45
  "@silverhand/eslint-config": "6.0.1",
46
46
  "@silverhand/ts-config": "6.0.0",
47
- "@types/node": "^20.11.20",
47
+ "@types/node": "^22.14.0",
48
48
  "@types/supertest": "^6.0.2",
49
- "@vitest/coverage-v8": "^2.1.8",
49
+ "@vitest/coverage-v8": "^3.1.1",
50
50
  "eslint": "^8.56.0",
51
51
  "lint-staged": "^15.0.2",
52
- "nock": "14.0.0-beta.15",
53
- "prettier": "^3.0.0",
52
+ "nock": "^14.0.3",
53
+ "prettier": "^3.5.3",
54
54
  "supertest": "^7.0.0",
55
- "tsup": "^8.3.0",
55
+ "tsup": "^8.5.0",
56
56
  "typescript": "^5.5.3",
57
- "vitest": "^2.1.8"
57
+ "vitest": "^3.1.1"
58
58
  },
59
59
  "scripts": {
60
60
  "precommit": "lint-staged",