UNPKG

@remcostoeten/fync

Version:

Unified TypeScript library for 9 popular APIs with consistent functional architecture

284 lines (283 loc) 12 kB
"use strict"; var _fync = require("@remcostoeten/fync"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /** * Simple OAuth2 Usage Examples * * Quick examples showing how to use fync OAuth2 authentication * without complex integrations. */ // ============================================================================== // Basic GitHub OAuth Example // ============================================================================== async function githubOAuthExample() { // Initialize GitHub OAuth const githubAuth = (0, _fync.GitHubOAuth)({ clientId: 'your-github-client-id', clientSecret: 'your-github-client-secret', redirectUri: 'http://localhost:3000/auth/github/callback' }); // Step 1: Generate authorization URL const { url, codeVerifier } = githubAuth.getAuthorizationUrl({ scope: ['user:email', 'repo'], state: 'random-state-for-csrf-protection' }); console.log('Visit this URL to authorize:', url); // Step 2: After user authorizes, you'll receive a code in your callback // Exchange the code for tokens const code = 'authorization-code-from-callback'; const tokens = await githubAuth.exchangeCodeForToken(code); console.log('Access Token:', tokens.access_token); console.log('Token Type:', tokens.token_type); console.log('Scope:', tokens.scope); // Step 3: Use the token to get user info const user = await githubAuth.withToken(tokens.access_token).getUser(); console.log('User:', user.login, user.email); // Get user's email addresses const emails = await githubAuth.withToken(tokens.access_token).getUserEmails(); console.log('Emails:', emails); // Get primary email const primaryEmail = await githubAuth.withToken(tokens.access_token).getPrimaryEmail(); console.log('Primary Email:', primaryEmail); // Check token validity const isValid = await githubAuth.withToken(tokens.access_token).validateToken(); console.log('Token is valid:', isValid); // Get token scopes const scopes = await githubAuth.withToken(tokens.access_token).getTokenScopes(); console.log('Token scopes:', scopes); // Get complete profile const profile = await githubAuth.withToken(tokens.access_token).getCompleteProfile(); console.log('Complete profile:', profile); // Refresh token (if available) if (tokens.refresh_token) { const newTokens = await githubAuth.refreshToken(tokens.refresh_token); console.log('New access token:', newTokens.access_token); } // Revoke token await githubAuth.revokeToken(tokens.access_token); console.log('Token revoked'); } // ============================================================================== // Basic Google OAuth Example // ============================================================================== async function googleOAuthExample() { // Initialize Google OAuth const googleAuth = (0, _fync.GoogleOAuth)({ clientId: 'your-google-client-id.apps.googleusercontent.com', clientSecret: 'your-google-client-secret', redirectUri: 'http://localhost:3000/auth/google/callback' }); // Step 1: Generate authorization URL const { url, codeVerifier } = googleAuth.getAuthorizationUrl({ scope: ['openid', 'email', 'profile', 'https://www.googleapis.com/auth/calendar'], state: 'random-state-for-csrf-protection', accessType: 'offline', // Required for refresh tokens pkce: true // Use PKCE for better security }); console.log('Visit this URL to authorize:', url); console.log('Store this code verifier:', codeVerifier); // Step 2: After user authorizes, you'll receive a code in your callback // Exchange the code for tokens const code = 'authorization-code-from-callback'; const tokens = await googleAuth.exchangeCodeForToken(code, codeVerifier); console.log('Access Token:', tokens.access_token); console.log('Refresh Token:', tokens.refresh_token); console.log('Expires In:', tokens.expires_in); console.log('Scope:', tokens.scope); // Step 3: Use the token to get user info const user = await googleAuth.withToken(tokens.access_token).getUser(); console.log('User:', user.name, user.email); // Get token information const tokenInfo = await googleAuth.withToken(tokens.access_token).getTokenInfo(); console.log('Token expires at:', new Date(tokenInfo.exp * 1000)); // Check token validity const isValid = await googleAuth.withToken(tokens.access_token).validateToken(); console.log('Token is valid:', isValid); // Get token scopes const scopes = await googleAuth.withToken(tokens.access_token).getTokenScopes(); console.log('Token scopes:', scopes); // Check if token has specific scope const hasCalendarScope = await googleAuth.withToken(tokens.access_token).hasScope('https://www.googleapis.com/auth/calendar'); console.log('Has calendar scope:', hasCalendarScope); // Get complete profile const profile = await googleAuth.withToken(tokens.access_token).getCompleteProfile(); console.log('Complete profile:', profile); // Check token expiration const expirationTime = await googleAuth.withToken(tokens.access_token).getTokenExpirationTime(); console.log('Token expires in:', expirationTime, 'seconds'); const isExpired = await googleAuth.withToken(tokens.access_token).isTokenExpired(300); // 5 minutes buffer console.log('Token is expired (with 5min buffer):', isExpired); // Refresh token if (tokens.refresh_token) { const newTokens = await googleAuth.refreshToken(tokens.refresh_token); console.log('New access token:', newTokens.access_token); } // Revoke token await googleAuth.revokeToken(tokens.access_token); console.log('Token revoked'); } // ============================================================================== // Using OAuth tokens with other fync APIs // ============================================================================== async function usingOAuthWithAPIs() { // After getting tokens from OAuth flow... const githubAccessToken = 'github-access-token'; const googleAccessToken = 'google-access-token'; // Use GitHub token with GitHub API const { GitHub } = await Promise.resolve().then(() => _interopRequireWildcard(require('@remcostoeten/fync/github'))); const github = GitHub({ token: githubAccessToken }); const user = await github.me.getAuthenticatedUser(); const repos = await github.me.getMyRepos(); console.log('GitHub user:', user.login); console.log('Repositories count:', repos.length); // Use Google token with Google Calendar API const { GoogleCalendar } = await Promise.resolve().then(() => _interopRequireWildcard(require('@remcostoeten/fync/google-calendar'))); const calendar = GoogleCalendar({ token: googleAccessToken }); const calendars = await calendar.getCalendars(); const events = await calendar.getUpcomingEvents('primary', 10); console.log('Calendars count:', calendars.items?.length || 0); console.log('Upcoming events count:', events.length); } // ============================================================================== // Express.js Integration Example // ============================================================================== async function expressIntegrationExample() { // This would be in your Express.js routes const express = require('express'); const app = express(); // GitHub OAuth routes app.get('/auth/github', (req, res) => { const githubAuth = (0, _fync.GitHubOAuth)({ clientId: process.env.GITHUB_CLIENT_ID, clientSecret: process.env.GITHUB_CLIENT_SECRET, redirectUri: 'http://localhost:3000/auth/github/callback' }); const { url } = githubAuth.getAuthorizationUrl({ scope: ['user:email'], state: req.session?.id || 'random-state' }); res.redirect(url); }); app.get('/auth/github/callback', async (req, res) => { const { code, state } = req.query; try { const githubAuth = (0, _fync.GitHubOAuth)({ clientId: process.env.GITHUB_CLIENT_ID, clientSecret: process.env.GITHUB_CLIENT_SECRET, redirectUri: 'http://localhost:3000/auth/github/callback' }); const tokens = await githubAuth.exchangeCodeForToken(code, state); const user = await githubAuth.withToken(tokens.access_token).getUser(); // Store user and tokens in session/database req.session.user = user; req.session.tokens = tokens; res.redirect('/dashboard'); } catch (error) { res.redirect('/auth/error'); } }); // Google OAuth routes app.get('/auth/google', (req, res) => { const googleAuth = (0, _fync.GoogleOAuth)({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, redirectUri: 'http://localhost:3000/auth/google/callback' }); const { url, codeVerifier } = googleAuth.getAuthorizationUrl({ scope: ['openid', 'email', 'profile'], state: req.session?.id || 'random-state', accessType: 'offline', pkce: true }); // Store code verifier in session req.session.codeVerifier = codeVerifier; res.redirect(url); }); app.get('/auth/google/callback', async (req, res) => { const { code } = req.query; const codeVerifier = req.session?.codeVerifier; try { const googleAuth = (0, _fync.GoogleOAuth)({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, redirectUri: 'http://localhost:3000/auth/google/callback' }); const tokens = await googleAuth.exchangeCodeForToken(code, codeVerifier); const user = await googleAuth.withToken(tokens.access_token).getUser(); // Store user and tokens in session/database req.session.user = user; req.session.tokens = tokens; res.redirect('/dashboard'); } catch (error) { res.redirect('/auth/error'); } }); app.listen(3000, () => { console.log('Server running on http://localhost:3000'); }); } // ============================================================================== // Error Handling Examples // ============================================================================== async function errorHandlingExample() { const githubAuth = (0, _fync.GitHubOAuth)({ clientId: 'invalid-client-id', clientSecret: 'invalid-client-secret', redirectUri: 'http://localhost:3000/callback' }); try { const tokens = await githubAuth.exchangeCodeForToken('invalid-code'); } catch (error) { if (error instanceof Error) { console.error('OAuth error:', error.message); // Handle specific error cases if (error.message.includes('invalid_client')) { console.log('Invalid client credentials'); } else if (error.message.includes('invalid_grant')) { console.log('Invalid authorization code'); } else if (error.message.includes('expired')) { console.log('Authorization code has expired'); } } } // Token validation with error handling try { const isValid = await githubAuth.withToken('invalid-token').validateToken(); console.log('Token is valid:', isValid); // Will be false } catch (error) { console.log('Token validation failed'); } } // Run examples if (require.main === module) { console.log('Running OAuth examples...'); // Uncomment the examples you want to run // githubOAuthExample(); // googleOAuthExample(); // usingOAuthWithAPIs(); // errorHandlingExample(); }