@mantlejs/auth-linkedin
LinkedIn Sign-In (OpenID Connect) strategy for Mantle JS. Implements the authorization code flow — no Passport.js dependency. Registers GET /auth/linkedin and GET /auth/linkedin/callback on the HTTP transport, then finds or creates a user record and returns a Mantle JWT pair.
Installation
Section titled “Installation”npm install @mantlejs/auth-linkedinConcepts
Section titled “Concepts”OpenID Connect
Section titled “OpenID Connect”This strategy uses LinkedIn’s “Sign In with LinkedIn using OpenID Connect” product — the legacy r_liteprofile/v2 profile API is not touched. Enable this product on your LinkedIn developer app before using this package.
No PKCE
Section titled “No PKCE”Unlike the Google and Microsoft strategies, LinkedIn’s authorization code flow authenticates the token exchange with the client secret only. CSRF protection comes from the state round-trip through the configured OAuthStateStore — the same posture as the GitHub and Facebook strategies.
Find-or-create
Section titled “Find-or-create”On callback the plugin searches the configured user service for a record where linkedinId (configurable) matches the sub claim from LinkedIn’s OIDC userinfo endpoint. If no record is found, it creates one with { linkedinId, email, name } from the profile. The same user is returned on every subsequent sign-in.
Quick start
Section titled “Quick start”import { mantle } from "@mantlejs/mantle";import { express } from "@mantlejs/express";import { auth } from "@mantlejs/auth";import { linkedinStrategy } from "@mantlejs/auth-linkedin";
const app = mantle() .configure(express()) .configure(auth({ secret: process.env.JWT_SECRET! })) .configure( linkedinStrategy({ clientId: process.env.LINKEDIN_CLIENT_ID!, clientSecret: process.env.LINKEDIN_CLIENT_SECRET!, }), );
app.listen(3030);Sign-in flow:
- Redirect the browser to
GET /auth/linkedin - User authenticates on LinkedIn and consents
- LinkedIn redirects to
GET /auth/linkedin/callback?code=...&state=... - The plugin exchanges the code, fetches the profile, finds or creates the user, and responds:
{ "accessToken": "eyJhbGciOiJIUzI1NiJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiJ9...", "user": { "id": "1", "linkedinId": "AAAA...", "email": "alice@example.com", "name": "Alice" }}linkedinStrategy(config)
Section titled “linkedinStrategy(config)”function linkedinStrategy(config: LinkedInStrategyConfig): MantlePlugin;
type LinkedInStrategyConfig = OAuthPluginConfig; // no provider-specific fields| Field | Type | Default | Description |
|---|---|---|---|
clientId |
string |
— | LinkedIn app client ID (required) |
clientSecret |
string |
— | LinkedIn app client secret (required) |
callbackUrl |
string |
'/auth/linkedin/callback' |
Callback path — must match the redirect URI registered on the LinkedIn app |
scope |
string[] |
['openid', 'profile', 'email'] |
LinkedIn OAuth scopes |
entity |
string |
'users' |
Mantle service used to find or create users |
entityIdField |
string |
'linkedinId' |
Field on the user record matched against LinkedIn’s sub claim |
redirectUrl |
string |
none — returns JSON | Frontend URL to redirect to on completion, with tokens (or an error) in the URL fragment — see @mantlejs/auth-oauth |
Routes registered:
| Method | Path | Description |
|---|---|---|
GET |
/auth/linkedin |
Redirect to LinkedIn sign-in |
GET |
/auth/linkedin/callback |
Handle callback, issue Mantle JWT pair |
Must be configured after the transport (e.g. express()) and auth().
import type { LinkedInStrategyConfig } from "@mantlejs/auth-linkedin";LinkedInStrategyConfig is OAuthPluginConfig from @mantlejs/auth-oauth — LinkedIn has no provider-specific config.
LinkedIn developer app setup
Section titled “LinkedIn developer app setup”- Create an app at linkedin.com/developers/apps
- Under Products, request access to “Sign In with LinkedIn using OpenID Connect”
- Under Auth, add an Authorized redirect URL:
https://your-domain.com/auth/linkedin/callback - Copy the Client ID and Client Secret into your environment
Development
Section titled “Development”npx nx build auth-linkedin # compilenpx nx test auth-linkedin # run testsnpx nx lint auth-linkedin # lintPublishing
Section titled “Publishing”npx nx build auth-linkedincd packages/auth-linkedinnpm publish --access public