### Install @frejun/oauth Source: https://github.com/frejun-tech/frejun-oauth-sdk/blob/main/README.md Install the package via npm. ```bash npm install @frejun/oauth ``` -------------------------------- ### Initialize and Configure FreJun OAuth Source: https://github.com/frejun-tech/frejun-oauth-sdk/blob/main/examples/browser.html Setup the FreJunOAuth client using environment variables and define event listeners for authentication lifecycle events. ```javascript import { FrejunOAuth } from '../dist/esm/index.js'; import { FREJUN_CLIENT_ID, FREJUN_CLIENT_SECRET } from './env.js'; // Set these via your bundler's env plugin (e.g. Vite, Webpack DefinePlugin) const oauth = new FrejunOAuth({ clientId: FREJUN_CLIENT_ID, clientSecret: FREJUN_CLIENT_SECRET, }); let tokens = {}; const out = document.getElementById('output'); const log = (msg) => (out.textContent += msg + '\n'); oauth.on('authCode', (data) => { log(`Auth code: ${data.code} - received for ${data.email}`); }); oauth.on('tokens', (data) => { log(`Access token: ${data.access_token}`); log(`Refresh token: ${data.refresh_token}`); log(`Expires in: ${data.expires_in}s`); tokens = data; // Store tokens for later use (e.g. refresh or disconnect) }); oauth.on('tokensRefreshed', (data) => { log(`Refreshed access token: ${data.access_token}`); }); oauth.on('error', (err) => { log(`Error: ${err.message}`); }); document.getElementById('login').addEventListener('click', () => { oauth.openAuthPopup(); }); document.getElementById('logout').addEventListener('click', () => { oauth.disconnect(tokens.refresh_token); log('Disconnected from FreJun'); }); ``` -------------------------------- ### Initialize and Use FrejunOAuth Source: https://github.com/frejun-tech/frejun-oauth-sdk/blob/main/README.md Configure the OAuth client and set up event listeners for token management and error handling. ```ts import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', redirectUri: 'https://yourapp.com/callback', // optional extraParams: { state: 'random-csrf-token' }, // optional }); // Listen for new tokens oauth.on('tokens', (data) => { console.log('Access token:', data.access_token); console.log('Refresh token:', data.refresh_token); console.log('Expires in:', data.expires_in); }); // Listen for refreshed tokens oauth.on('tokensRefreshed', (data) => { console.log('New access token:', data.access_token); console.log('New refresh token:', data.refresh_token); }); // Listen for errors oauth.on('error', (err) => { console.error('OAuth error:', err.message); }); // Open the FreJun consent popup (browser only) oauth.openAuthPopup(); ``` -------------------------------- ### FreJunOAuth Initialization Source: https://github.com/frejun-tech/frejun-oauth-sdk/blob/main/README.md Initializes the FreJunOAuth client with required credentials and optional configuration. ```APIDOC ## new FrejunOAuth(config) ### Description Initializes a new instance of the FreJun OAuth client. ### Parameters #### Request Body - **clientId** (string) - Required - Your FreJun OAuth app client ID - **clientSecret** (string) - Required - Your FreJun OAuth app client secret - **redirectUri** (string) - Optional - Override the registered redirect URI - **extraParams** (Record) - Optional - Extra query params (state, username, etc.) ``` -------------------------------- ### Initialize FreJunOAuth Client Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Instantiate the client with credentials and optional configuration parameters like redirect URIs or extra query parameters. ```typescript import { FrejunOAuth } from '@frejun/oauth'; // Basic initialization const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Full configuration with all options const oauthFull = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', redirectUri: 'https://yourapp.com/callback', // Override registered redirect URI extraParams: { state: 'random-csrf-token', // CSRF protection username: 'user@example.com', // Pre-fill user email }, }); ``` -------------------------------- ### FreJunOAuth Constructor Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Initializes a new FreJun OAuth client with the required credentials and optional configuration. It validates clientId and clientSecret and stores the configuration. ```APIDOC ## FrejunOAuth Constructor Initializes a new FreJun OAuth client with the required credentials and optional configuration. The constructor validates that both `clientId` and `clientSecret` are provided and stores the configuration for subsequent API calls. ### Parameters #### Request Body - **clientId** (string) - Required - The client ID obtained from FreJun. - **clientSecret** (string) - Required - The client secret obtained from FreJun. - **redirectUri** (string) - Optional - Overrides the registered redirect URI. - **extraParams** (object) - Optional - Additional parameters to include in the authorization request, such as `state` for CSRF protection. ### Request Example ```typescript import { FrejunOAuth } from '@frejun/oauth'; // Basic initialization const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Full configuration with all options const oauthFull = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', redirectUri: 'https://yourapp.com/callback', extraParams: { state: 'random-csrf-token', username: 'user@example.com', }, }); ``` ``` -------------------------------- ### openAuthPopup() Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Opens the FreJun consent page in a centered browser popup and listens for the authorization code via `window.postMessage`. It can automatically exchange the code for tokens. ```APIDOC ## openAuthPopup() Opens the FreJun consent page in a centered browser popup and automatically listens for the authorization code via `window.postMessage`. By default, it exchanges the code for tokens automatically. This method is browser-only and throws an error in Node.js environments. ### Method GET ### Endpoint /oauth/authorize/ ### Parameters #### Request Body - **generateTokens** (boolean) - Optional - If true (default), automatically exchanges the authorization code for tokens. If false, the code must be exchanged manually using `createTokens()`. ### Request Example ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Set up event listeners before opening popup oauth.on('tokens', (data) => { console.log('Access token:', data.access_token); console.log('Refresh token:', data.refresh_token); console.log('Expires in:', data.expires_in, 'seconds'); console.log('Organization:', data.org_identifier); // Store tokens securely for API calls localStorage.setItem('frejun_tokens', JSON.stringify(data)); }); oauth.on('error', (err) => { console.error('OAuth failed:', err.message); }); // Open popup with automatic token generation (default) document.getElementById('login-btn').addEventListener('click', () => { oauth.openAuthPopup(); }); // Or disable automatic token generation for backend token exchange oauth.openAuthPopup({ generateTokens: false }); ``` ### Response #### Success Response (200) - **tokens** (object) - Emitted when tokens are successfully generated. Contains `access_token`, `refresh_token`, `expires_in`, `token_type`, and `org_identifier`. - **error** (object) - Emitted when an error occurs during the OAuth flow. ``` -------------------------------- ### Event System (on, once, off) Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Subscribe to OAuth lifecycle events using the built-in event emitter. The SDK emits `authCode`, `tokens`, `tokensRefreshed`, and `error` events. Use `on()` for persistent listeners, `once()` for one-time listeners, and `off()` to unsubscribe. ```APIDOC ## Event Emitter Methods ### `on(eventName, listener)` #### Description Registers a persistent listener for a specific event. #### Parameters - **eventName** (string) - The name of the event to listen for (e.g., 'tokens', 'error'). - **listener** (function) - The callback function to execute when the event is emitted. ### `once(eventName, listener)` #### Description Registers a one-time listener for a specific event. The listener is automatically removed after it has been called once. #### Parameters - **eventName** (string) - The name of the event to listen for. - **listener** (function) - The callback function to execute. ### `off(eventName, listener)` #### Description Removes a specific listener for a given event. #### Parameters - **eventName** (string) - The name of the event. - **listener** (function) - The specific listener function to remove. ### Supported Events - **authCode**: Emitted when an authorization code is received. - **tokens**: Emitted when new access and refresh tokens are obtained. - **tokensRefreshed**: Emitted when access and refresh tokens are successfully refreshed. - **error**: Emitted when an OAuth-related error occurs. ``` -------------------------------- ### Backend Token Generation Pattern Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt This pattern demonstrates how to generate tokens on the server for enhanced security. It involves disabling automatic token exchange in the popup and listening for the `authCode` event to send the authorization code to your backend for token generation. ```APIDOC ## POST /api/auth/frejun/callback ### Description This endpoint receives an authorization code from the client-side SDK and exchanges it for session tokens with the FreJun authentication server. It is designed to be called from your backend after receiving the `authCode` event. ### Method POST ### Endpoint /api/auth/frejun/callback ### Parameters #### Request Body - **code** (string) - Required - The authorization code received from the `authCode` event. - **email** (string) - Required - The email associated with the authentication. - **state** (string) - Required - The CSRF token provided by the client for verification. ### Request Example ```json { "code": "AUTHORIZATION_CODE", "email": "user@example.com", "state": "CSRF_TOKEN" } ``` ### Response #### Success Response (200) - **sessionToken** (string) - The session token generated by the backend, to be used for subsequent authenticated requests or stored in cookies. #### Response Example ```json { "sessionToken": "YOUR_SESSION_TOKEN" } ``` ``` -------------------------------- ### Open Authentication Popup Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Launch a browser popup for user consent and handle token events. This method is restricted to browser environments. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Set up event listeners before opening popup oauth.on('tokens', (data) => { console.log('Access token:', data.access_token); console.log('Refresh token:', data.refresh_token); console.log('Expires in:', data.expires_in, 'seconds'); console.log('Organization:', data.org_identifier); // Store tokens securely for API calls localStorage.setItem('frejun_tokens', JSON.stringify(data)); }); oauth.on('error', (err) => { console.error('OAuth failed:', err.message); }); // Open popup with automatic token generation (default) document.getElementById('login-btn').addEventListener('click', () => { oauth.openAuthPopup(); }); // Or disable automatic token generation for backend token exchange oauth.openAuthPopup({ generateTokens: false }); ``` -------------------------------- ### createTokens() Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Exchanges an authorization code for access and refresh tokens by calling the FreJun API. Emits a `tokens` event upon success. Use this method on the server side or when `generateTokens: false` was passed to `openAuthPopup()`. ```APIDOC ## createTokens() Exchanges an authorization code for access and refresh tokens by calling the FreJun API. Emits a `tokens` event upon success. Use this method on the server side or when `generateTokens: false` was passed to `openAuthPopup()`. ### Method POST ### Endpoint /oauth/token/ ### Parameters #### Request Body - **code** (string) - Required - The authorization code received from the OAuth provider. - **grant_type** (string) - Required - Should be 'authorization_code'. - **redirect_uri** (string) - Optional - The redirect URI used in the initial authorization request. ### Request Example ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Server-side token exchange async function handleOAuthCallback(authCode: string) { try { const tokens = await oauth.createTokens(authCode); console.log('Token exchange successful:'); console.log(' Access token:', tokens.access_token); console.log(' Refresh token:', tokens.refresh_token); console.log(' Expires in:', tokens.expires_in, 'seconds'); console.log(' Token type:', tokens.token_type); console.log(' Organization:', tokens.org_identifier); // Store tokens in database await saveTokensToDatabase(tokens); return tokens; } catch (error) { if (error.name === 'FrejunApiError') { console.error('API Error:', error.statusCode, error.responseBody); } throw error; } } // Example: Express.js callback endpoint // app.get('/callback', async (req, res) => { // const tokens = await handleOAuthCallback(req.query.code); // res.redirect('/dashboard'); // }); ``` ### Response #### Success Response (200) - **access_token** (string) - The access token. - **refresh_token** (string) - The refresh token. - **expires_in** (number) - The lifetime in seconds of the access token. - **token_type** (string) - The type of token, usually 'Bearer'. - **org_identifier** (string) - The identifier of the organization associated with the token. #### Error Response - **FrejunApiError** - Thrown when the API returns an error. Contains `statusCode` and `responseBody`. ``` -------------------------------- ### getAuthorizationUrl() Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Builds and returns the FreJun authorization URL as a string with all configured query parameters. Useful for manual redirects. ```APIDOC ## getAuthorizationUrl() Builds and returns the FreJun authorization URL as a string with all configured query parameters. Useful when you need to construct the authorization URL manually, for example when redirecting instead of using a popup. ### Method GET ### Endpoint /oauth/authorize/ ### Parameters #### Query Parameters - **client_id** (string) - Required - The client ID. - **redirect_uri** (string) - Optional - The redirect URI. - **response_type** (string) - Required - Should be 'code'. - **scope** (string) - Optional - The requested scopes. - **state** (string) - Optional - A value used to maintain state between the request and callback. - **extraParams** (object) - Optional - Any other parameters to be included in the URL. ### Response Example ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', extraParams: { state: 'abc123' }, }); const authUrl = oauth.getAuthorizationUrl(); console.log(authUrl); // Output: https://product.frejun.com/oauth/authorize/?client_id=your-client-id&state=abc123 // Use for manual redirect window.location.href = authUrl; ``` ``` -------------------------------- ### Authentication Methods Source: https://github.com/frejun-tech/frejun-oauth-sdk/blob/main/README.md Methods for managing the OAuth flow, including URL generation, popup handling, and token operations. ```APIDOC ## Methods ### getAuthorizationUrl() Returns the FreJun authorization URL as a string. ### openAuthPopup(options?) Opens the consent page in a popup. By default, automatically exchanges the code for tokens. Pass `{ generateTokens: false }` to skip token generation. ### createTokens(code) Exchange an auth code for tokens. Emits 'tokens'. ### refreshTokens(refreshToken) Refresh an expired access token. Emits 'tokensRefreshed'. ### verifyToken(token) Check whether an access or refresh token is valid. ### disconnect(refreshToken) Disconnect the OAuth app from the organization. Revokes all tokens for this organization. ### destroy() Clean up all listeners and close any open popup. ``` -------------------------------- ### Subscribe to Events Source: https://github.com/frejun-tech/frejun-oauth-sdk/blob/main/README.md Manage event listeners for token updates and lifecycle events. ```ts // Called on every token refresh oauth.on('tokensRefreshed', (data) => { saveTokens(data.access_token, data.refresh_token); }); ``` ```ts // Only capture the first set of tokens oauth.once('tokens', (data) => { console.log('Initial tokens received:', data.access_token); }); ``` ```ts const handler = (data) => { /* ... */ }; oauth.on('tokens', handler); // Later, unsubscribe oauth.off('tokens', handler); ``` -------------------------------- ### destroy() Method Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt The `destroy()` method is crucial for cleaning up resources. It removes all event listeners and closes any open popup windows associated with the FreJunOAuth client instance. This should be called when the client is no longer needed, typically during component unmounting in frontend frameworks, to prevent memory leaks. ```APIDOC ## destroy() ### Description Cleans up all event listeners and closes any open popup window associated with the FreJunOAuth client instance. This method should be called when the OAuth client is no longer needed to prevent memory leaks. ### Method `destroy()` ### Parameters None ### Usage Example (React) ```javascript import { useEffect } from 'react'; import { FrejunOAuth } from '@frejun/oauth'; function MyComponent() { const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); useEffect(() => { // Setup listeners or other initializations oauth.on('tokens', handleTokens); oauth.on('error', handleError); // Cleanup function to destroy the client instance return () => { oauth.destroy(); console.log('OAuth client destroyed, all listeners removed'); }; }, []); // Empty dependency array ensures this runs only on mount and unmount // ... rest of your component } ``` ### Usage Example (Manual Cleanup) ```javascript function cleanupOAuth() { // Assuming 'oauth' is your FrejunOAuth instance oauth.destroy(); console.log('OAuth client destroyed, all listeners removed'); } ``` ``` -------------------------------- ### Manage OAuth lifecycle events Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Subscribe to events like authCode, tokens, and errors using the built-in event emitter. Use on, once, and off to manage listener lifecycles. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Persistent listener - fires every time oauth.on('tokens', (data) => { console.log('Tokens received:', data.access_token); saveTokens(data); }); oauth.on('tokensRefreshed', (data) => { console.log('Tokens refreshed:', data.access_token); updateStoredTokens(data); }); oauth.on('error', (error) => { console.error('OAuth error:', error.message); showErrorNotification(error.message); }); // One-time listener - automatically removed after firing oauth.once('authCode', (data) => { console.log('Auth code received for:', data.email); console.log('Code:', data.code); // This listener only fires once }); // Remove a specific listener const tokenHandler = (data) => { console.log('Token handler:', data.access_token); }; oauth.on('tokens', tokenHandler); // Later, unsubscribe oauth.off('tokens', tokenHandler); ``` -------------------------------- ### Generate Authorization URL Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Construct the authorization URL manually for custom redirect flows. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', extraParams: { state: 'abc123' }, }); const authUrl = oauth.getAuthorizationUrl(); console.log(authUrl); // Output: https://product.frejun.com/oauth/authorize/?client_id=your-client-id&state=abc123 // Use for manual redirect window.location.href = authUrl; ``` -------------------------------- ### Handle Backend Token Generation Source: https://github.com/frejun-tech/frejun-oauth-sdk/blob/main/README.md Disable automatic token exchange to handle authorization codes on your server. ```ts oauth.on('authCode', async ({ code, email, ...params }) => { // Send the code to your backend for token generation await fetch('/api/auth/frejun', { // your backend endpoint method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code, email, ...params }), }); }); oauth.openAuthPopup({ generateTokens: false }); ``` -------------------------------- ### Verify token validity with FrejunOAuth Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Checks if a token is valid by calling the verification endpoint. No authorization header is required for this call. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Verify token validity async function checkTokenValidity(token: string) { try { const result = await oauth.verifyToken(token); console.log('Token is valid:', result); return true; } catch (error) { console.log('Token is invalid or expired'); return false; } } // Usage in authentication middleware async function authMiddleware(req, res, next) { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'No token provided' }); } const isValid = await checkTokenValidity(token); if (!isValid) { return res.status(401).json({ error: 'Invalid token' }); } next(); } ``` -------------------------------- ### Token Verification API Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Checks whether an access or refresh token is still valid by calling the FreJun verification endpoint. No authorization header is required for this endpoint. Returns token metadata if valid. ```APIDOC ## POST /oauth/verify ### Description Verifies the validity of an access or refresh token. ### Method POST ### Endpoint /oauth/verify ### Parameters #### Request Body - **token** (string) - Required - The access or refresh token to verify. ### Request Example ```json { "token": "your_token_to_verify" } ``` ### Response #### Success Response (200) - **valid** (boolean) - Indicates if the token is valid. - **metadata** (object) - Token metadata if valid (e.g., expiration time, scopes). #### Response Example ```json { "valid": true, "metadata": { "exp": 1678886400, "iat": 1678882800, "jti": "some_jwt_id", "scopes": ["read", "write"] } } ``` ``` -------------------------------- ### Implement Backend Token Generation Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Disable automatic token generation to handle the auth code exchange on your backend for enhanced security. Ensure CSRF tokens are verified before sending the code to your server. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', extraParams: { state: generateCSRFToken() }, }); // Listen for auth code to send to backend oauth.on('authCode', async ({ code, email, state }) => { // Verify CSRF token if (!verifyCSRFToken(state)) { console.error('CSRF token mismatch'); return; } // Send code to backend for token exchange const response = await fetch('/api/auth/frejun/callback', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code, email }), }); if (response.ok) { const { sessionToken } = await response.json(); // Backend handles token storage, returns session document.cookie = `session=${sessionToken}; Secure; HttpOnly`; window.location.href = '/dashboard'; } }); oauth.on('error', (err) => { console.error('OAuth error:', err.message); }); // Open popup WITHOUT automatic token generation document.getElementById('login').addEventListener('click', () => { oauth.openAuthPopup({ generateTokens: false }); }); ``` -------------------------------- ### Refresh tokens with FrejunOAuth Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Use this method to refresh expired access tokens proactively or reactively. Emits a tokensRefreshed event upon success. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Listen for refresh events oauth.on('tokensRefreshed', (data) => { console.log('Tokens refreshed successfully'); console.log(' New access token:', data.access_token); console.log(' New refresh token:', data.refresh_token); // Update stored tokens localStorage.setItem('frejun_tokens', JSON.stringify(data)); }); // Proactive token refresh async function refreshBeforeExpiry(currentRefreshToken: string) { try { const newTokens = await oauth.refreshTokens(currentRefreshToken); return newTokens; } catch (error) { console.error('Token refresh failed:', error.message); // Redirect to login if refresh fails oauth.openAuthPopup(); } } // Auto-refresh implementation function scheduleTokenRefresh(expiresIn: number, refreshToken: string) { // Refresh 5 minutes before expiry const refreshTime = (expiresIn - 300) * 1000; setTimeout(() => { refreshBeforeExpiry(refreshToken); }, refreshTime); } ``` -------------------------------- ### Exchange Authorization Code for Tokens Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Perform a server-side token exchange using an authorization code. This method is suitable for backend implementations or when automatic popup token generation is disabled. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Server-side token exchange async function handleOAuthCallback(authCode: string) { try { const tokens = await oauth.createTokens(authCode); console.log('Token exchange successful:'); console.log(' Access token:', tokens.access_token); console.log(' Refresh token:', tokens.refresh_token); console.log(' Expires in:', tokens.expires_in, 'seconds'); console.log(' Token type:', tokens.token_type); console.log(' Organization:', tokens.org_identifier); // Store tokens in database await saveTokensToDatabase(tokens); return tokens; } catch (error) { if (error.name === 'FrejunApiError') { console.error('API Error:', error.statusCode, error.responseBody); } throw error; } } // Example: Express.js callback endpoint // app.get('/callback', async (req, res) => { // const tokens = await handleOAuthCallback(req.query.code); // res.redirect('/dashboard'); // }); ``` -------------------------------- ### Destroy OAuth Client Instance Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Use the destroy method to remove event listeners and close popups, preventing memory leaks during component unmounting. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Setup listeners oauth.on('tokens', handleTokens); oauth.on('error', handleError); // React component cleanup example // useEffect(() => { // return () => { // oauth.destroy(); // Clean up on unmount // }; // }, []); // Manual cleanup function cleanup() { oauth.destroy(); console.log('OAuth client destroyed, all listeners removed'); } ``` -------------------------------- ### Disconnect OAuth integration Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Revokes all refresh tokens for the client-organization pair and removes the app-org link. Useful for logout or account unlinking. ```typescript import { FrejunOAuth } from '@frejun/oauth'; const oauth = new FrejunOAuth({ clientId: 'your-client-id', clientSecret: 'your-client-secret', }); // Disconnect FreJun integration async function disconnectFreJun(refreshToken: string) { try { const result = await oauth.disconnect(refreshToken); if (result.success) { console.log('Successfully disconnected:', result.message); // Clear local token storage localStorage.removeItem('frejun_tokens'); // Update UI to show disconnected state updateUIDisconnected(); } return result; } catch (error) { console.error('Disconnect failed:', error.message); throw error; } } // Usage with logout button document.getElementById('disconnect-btn').addEventListener('click', async () => { const tokens = JSON.parse(localStorage.getItem('frejun_tokens')); if (tokens?.refresh_token) { await disconnectFreJun(tokens.refresh_token); } }); ``` -------------------------------- ### Token Refresh API Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Refreshes an expired access token using a valid refresh token. This method should be called proactively before the access token expires or reactively when API calls return 401 errors. It emits a `tokensRefreshed` event upon success. ```APIDOC ## POST /oauth/refresh ### Description Refreshes an expired access token using a valid refresh token. ### Method POST ### Endpoint /oauth/refresh ### Parameters #### Request Body - **refresh_token** (string) - Required - The valid refresh token to use for obtaining a new access token. ### Request Example ```json { "refresh_token": "your_refresh_token" } ``` ### Response #### Success Response (200) - **access_token** (string) - The new access token. - **refresh_token** (string) - The new refresh token. - **expires_in** (integer) - The time in seconds until the access token expires. #### Response Example ```json { "access_token": "new_access_token", "refresh_token": "new_refresh_token", "expires_in": 3600 } ``` ``` -------------------------------- ### Disconnect API Source: https://context7.com/frejun-tech/frejun-oauth-sdk/llms.txt Disconnects the OAuth app from the organization associated with the refresh token. This revokes all refresh tokens for the client-organization pair and removes the app-org link. Use this for logout or account unlinking functionality. ```APIDOC ## POST /oauth/disconnect ### Description Disconnects the OAuth application from the organization. ### Method POST ### Endpoint /oauth/disconnect ### Parameters #### Request Body - **refresh_token** (string) - Required - The refresh token associated with the organization to disconnect. ### Request Example ```json { "refresh_token": "your_refresh_token_to_revoke" } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the disconnection was successful. - **message** (string) - A message confirming the disconnection. #### Response Example ```json { "success": true, "message": "OAuth application disconnected successfully." } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.