1.1.0 • Published 5 months ago
@microfox/linkedin-oauth v1.1.0
@microfox/linkedin-oauth
A robust TypeScript SDK for LinkedIn OAuth 2.0 authentication.
Features
- 📘 Full TypeScript support with type definitions
- 🔐 OAuth 2.0 authentication flow
- 🔑 Comprehensive LinkedIn API scopes
- 🛡️ Built-in CSRF protection with state parameter
- ⚠️ Error handling with descriptive messages
- 🔍 Zod schema validation for responses
- 🔄 Refresh token support
- 🔍 Token validation and introspection
Installation
npm install @microfox/linkedin-oauth
# or
yarn add @microfox/linkedin-oauth
# or
pnpm add @microfox/linkedin-oauthUsage
Basic Setup
import { LinkedInOAuthSdk, LinkedInScope } from '@microfox/linkedin-oauth';
const sdk = new LinkedInOAuthSdk({
clientId: 'your_client_id',
clientSecret: 'your_client_secret',
redirectUri: 'https://your-app.com/callback',
scopes: [LinkedInScope.OPENID, LinkedInScope.PROFILE],
});OAuth Flow
- Generate authorization URL:
const authUrl = sdk.getAuthUrl();
// Redirect user to authUrl- Handle callback and get access token:
const code = 'authorization_code_from_callback';
const { accessToken, refreshToken } = await sdk.exchangeCodeForTokens(code);
// Note: refreshToken will be null if OFFLINE_ACCESS scope was not requestedRefresh Tokens
To enable refresh tokens, include the OFFLINE_ACCESS scope when initializing the SDK:
const sdk = new LinkedInOAuthSdk({
clientId: 'your_client_id',
clientSecret: 'your_client_secret',
redirectUri: 'your_redirect_uri',
scopes: [LinkedInScope.OFFLINE_ACCESS],
});
// When the access token expires, use the refresh token to get a new one:
const { accessToken: newAccessToken, refreshToken: newRefreshToken } =
await sdk.refreshAccessToken(refreshToken);Validate Access Tokens
You can validate access tokens to check if they're still valid:
try {
const result = await sdk.validateAccessToken(accessToken);
if (result.isValid) {
console.log('Token is valid');
console.log('Expires at:', new Date(result.expiresAt!).toISOString());
console.log('Scopes:', result.scopes);
} else {
console.error('Token validation failed:', result.error);
}
} catch (error) {
console.error('Validation error:', error);
}State Parameter
The SDK automatically generates and manages a state parameter for CSRF protection. You can access it if needed:
const state = await sdk.getState();Error Handling
The SDK uses Zod for validation and throws descriptive errors:
try {
const { accessToken } = await sdk.exchangeCodeForTokens(code);
} catch (error) {
if (error instanceof z.ZodError) {
console.error('Invalid response format:', error.errors);
} else {
console.error('Failed to exchange code:', error.message);
}
}Types
import type {
LinkedInScope,
LinkedInAuthConfig,
} from '@microfox/linkedin-oauth';
// Zod-inferred types
import type { TokenResponse, ErrorResponse } from '@microfox/linkedin-oauth';Available Scopes
The SDK provides a comprehensive set of LinkedIn API scopes:
OpenID Connect Scopes
LinkedInScope.OPENID(openid) - OpenID Connect authenticationLinkedInScope.PROFILE(profile) - Basic profile informationLinkedInScope.EMAIL(email) - Access email address
Basic Profile Scopes
LinkedInScope.BASIC_PROFILE(r_basicprofile) - Read basic profile informationLinkedInScope.FULL_PROFILE(r_fullprofile) - Read full profile information
Contact Scopes
LinkedInScope.CONTACTS(r_contacts) - Access to contactsLinkedInScope.CONTACTS_READONLY(r_contacts_readonly) - Read-only access to contacts
Email Scopes
LinkedInScope.EMAIL_ADDRESS(r_emailaddress) - Access to email address
Organization Scopes
LinkedInScope.ORGANIZATION(r_organization_social) - Access to organization dataLinkedInScope.ORGANIZATION_ADMIN(w_organization_social) - Admin access to organization data
Content Sharing Scopes
LinkedInScope.SHARE(w_member_social) - Share and interact with contentLinkedInScope.SHARE_READONLY(r_member_social) - Read-only access to shared content
Job Posting Scopes
LinkedInScope.JOBS(w_job_posting) - Post and manage job listingsLinkedInScope.JOBS_READONLY(r_job_posting) - Read-only access to job listings
Company Scopes
LinkedInScope.COMPANY(r_company_admin) - Admin access to company dataLinkedInScope.COMPANY_READONLY(r_company_admin_readonly) - Read-only access to company data
Groups Scopes
LinkedInScope.GROUPS(r_groups) - Access to groupsLinkedInScope.GROUPS_READONLY(r_groups_readonly) - Read-only access to groups
Ads Scopes
LinkedInScope.ADS(r_ads) - Access to adsLinkedInScope.ADS_READONLY(r_ads_readonly) - Read-only access to adsLinkedInScope.ADS_REPORTING(r_ads_reporting) - Access to ads reporting
Marketing Developer Platform Scopes
LinkedInScope.MARKETING(r_marketing) - Access to marketing dataLinkedInScope.MARKETING_READONLY(r_marketing_readonly) - Read-only access to marketing data
Offline Access
LinkedInScope.OFFLINE_ACCESS(r_liteprofile r_emailaddress w_member_social offline_access) - Enable refresh tokens (includes r_liteprofile, r_emailaddress, w_member_social, and offline_access)
Configuration
interface LinkedInAuthConfig {
clientId: string;
clientSecret: string;
redirectUri: string;
scopes?: LinkedInScope[];
state?: string;
}Security Best Practices
This SDK implements several security features:
- CSRF protection using state parameter (auto-generated if not provided)
- Input validation using Zod schemas
- Type-safe token handling
- Token validation and introspection
Best practices for implementation:
- Store client credentials securely (use environment variables)
- Keep access and refresh tokens secure
- Use HTTPS for all OAuth endpoints
- Always verify the state parameter on callbacks
- Implement proper session management
- Never expose tokens in client-side code or URLs
- Regularly validate access tokens before use
License
MIT