diff --git a/README.md b/README.md index 5a19165..f613e81 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,7 @@ The following providers have pre-defined OAuth configurations: 1. [GitHub](https://jsr.io/@deno/kv-oauth/doc/~/createGitHubOAuthConfig) 1. [GitLab](https://jsr.io/@deno/kv-oauth/doc/~/createGitLabOAuthConfig) 1. [Google](https://jsr.io/@deno/kv-oauth/doc/~/createGoogleOAuthConfig) +1. [LinkedIn](https://deno.land/x/deno_kv_oauth/mod.ts?s=createLinkedInOAuthConfig) 1. [Logto](https://jsr.io/@deno/kv-oauth/doc/~/createLogtoOAuthConfig) 1. [Notion](https://jsr.io/@deno/kv-oauth/doc/~/createNotionOAuthConfig) 1. [Okta](https://jsr.io/@deno/kv-oauth/doc/~/createOktaOAuthConfig) diff --git a/lib/create_helpers.ts b/lib/create_helpers.ts index 8d412da..c94403a 100644 --- a/lib/create_helpers.ts +++ b/lib/create_helpers.ts @@ -220,7 +220,13 @@ export function createHelpers( const oauthSession = await getAndDeleteOAuthSession(oauthSessionId); const tokens = await new OAuth2Client(oauthConfig) - .code.getToken(request.url, oauthSession); + .code.getToken(request.url, { + ...oauthSession, + // Workaround ensuring the default code verifier is used, if defined. + codeVerifier: + oauthConfig.defaults?.requestOptions?.body?.code_verifier ?? + oauthSession.codeVerifier, + }); const sessionId = crypto.randomUUID(); const response = redirect(oauthSession.successUrl); diff --git a/lib/create_linkedin_oauth_config.ts b/lib/create_linkedin_oauth_config.ts new file mode 100644 index 0000000..b2db7b7 --- /dev/null +++ b/lib/create_linkedin_oauth_config.ts @@ -0,0 +1,50 @@ +// Copyright 2023-2024 the Deno authors. All rights reserved. MIT license. +import type { OAuth2ClientConfig } from "https://deno.land/x/oauth2_client@v1.0.2/mod.ts"; +import { getRequiredEnv } from "./get_required_env.ts"; + +/** + * Returns the OAuth configuration for LinkedIn. + * + * Requires `--allow-env[=LINKEDIN_CLIENT_ID,LINKEDIN_CLIENT_SECRET]` permissions + * and environment variables: + * 1. `LINKEDIN_CLIENT_ID` + * 2. `LINKEDIN_CLIENT_SECRET` + * + * @example + * ```ts + * import { createLinkedInOAuthConfig } from "jsr:@deno/kv-oauth"; + * + * const oauthConfig = createLinkedInOAuthConfig({ + * redirectUri: "http://localhost:8000/callback", + * scope: ["profile", "email"], + * }); + * ``` + * + * @see {@link https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin%2Fcontext&tabs=HTTPS1} + */ +export function createLinkedInOAuthConfig(config: { + /** @see {@linkcode OAuth2ClientConfig.redirectUri} */ + redirectUri: string; + /** @see {@linkcode OAuth2ClientConfig.defaults}*/ + scope: string | string[]; +}): OAuth2ClientConfig { + const clientId = getRequiredEnv("LINKEDIN_CLIENT_ID"); + const clientSecret = getRequiredEnv("LINKEDIN_CLIENT_SECRET"); + return { + clientId, + clientSecret, + authorizationEndpointUri: "https://www.linkedin.com/oauth/v2/authorization", + tokenUri: "https://www.linkedin.com/oauth/v2/accessToken", + redirectUri: config.redirectUri, + defaults: { + requestOptions: { + body: { + client_id: clientId, + client_secret: clientSecret, + code_verifier: "", + }, + }, + scope: config.scope, + }, + }; +} diff --git a/lib/create_oauth_config_test.ts b/lib/create_oauth_config_test.ts index babcc84..e58d7d5 100644 --- a/lib/create_oauth_config_test.ts +++ b/lib/create_oauth_config_test.ts @@ -10,6 +10,7 @@ import { createFacebookOAuthConfig } from "./create_facebook_oauth_config.ts"; import { createGitHubOAuthConfig } from "./create_github_oauth_config.ts"; import { createGitLabOAuthConfig } from "./create_gitlab_oauth_config.ts"; import { createGoogleOAuthConfig } from "./create_google_oauth_config.ts"; +import { createLinkedInOAuthConfig } from "./create_linkedin_oauth_config.ts"; import { createLogtoOAuthConfig } from "./create_logto_oauth_config.ts"; import { createNotionOAuthConfig } from "./create_notion_oauth_config.ts"; import { createOktaOAuthConfig } from "./create_okta_oauth_config.ts"; @@ -59,6 +60,10 @@ import { createTwitterOAuthConfig } from "./create_twitter_oauth_config.ts"; envPrefix: "GOOGLE", createOAuthConfigFn: createGoogleOAuthConfig, }, + { + envPrefix: "LINKEDIN", + createOAuthConfigFn: createLinkedInOAuthConfig, + }, { envPrefix: "LOGTO", createOAuthConfigFn: createLogtoOAuthConfig, diff --git a/mod.ts b/mod.ts index 2cc8e42..52cec65 100644 --- a/mod.ts +++ b/mod.ts @@ -10,6 +10,7 @@ export * from "./lib/create_facebook_oauth_config.ts"; export * from "./lib/create_github_oauth_config.ts"; export * from "./lib/create_gitlab_oauth_config.ts"; export * from "./lib/create_google_oauth_config.ts"; +export * from "./lib/create_linkedin_oauth_config.ts"; export * from "./lib/create_logto_oauth_config.ts"; export * from "./lib/create_notion_oauth_config.ts"; export * from "./lib/create_okta_oauth_config.ts";