@@ -119,6 +119,81 @@ try {
119119| ` apiUrl ` | ` string ` | ` https://api.us.nylas.com ` | API base URL |
120120| ` persistTokens ` | ` boolean ` | ` true ` | Store tokens in localStorage |
121121| ` debug ` | ` boolean ` | ` true ` on localhost | Enable debug logging |
122+ | ` codeExchange ` | (param: CodeExchangeParams) => Promise<ConnectResult >` | - | Custom code exchange method |
123+
124+ ## Custom Code Exchange
125+
126+ For enhanced security, you can handle the OAuth code exchange on your backend instead of in the browser. This approach keeps your API keys secure and gives you full control over the token exchange process.
127+
128+ ### Backend Code Exchange
129+
130+ ``` typescript
131+ const nylasConnect = new NylasConnect ({
132+ clientId: ' your-nylas-client-id' ,
133+ redirectUri: ' http://localhost:3000/auth/callback' ,
134+ codeExchange : async (params ) => {
135+ // Send the authorization code to your backend
136+ const response = await fetch (' /api/auth/exchange' , {
137+ method: ' POST' ,
138+ headers: { ' Content-Type' : ' application/json' },
139+ body: JSON .stringify ({
140+ code: params .code ,
141+ state: params .state ,
142+ clientId: params .clientId ,
143+ redirectUri: params .redirectUri ,
144+ scopes: params .scopes ,
145+ provider: params .provider ,
146+ }),
147+ });
148+
149+ if (! response .ok ) {
150+ throw new Error (` Token exchange failed: ${response .statusText } ` );
151+ }
152+
153+ const tokenData = await response .json ();
154+
155+ // Return the expected ConnectResult format
156+ return {
157+ accessToken: tokenData .access_token ,
158+ idToken: tokenData .id_token ,
159+ grantId: tokenData .grant_id ,
160+ expiresAt: Date .now () + tokenData .expires_in * 1000 ,
161+ scope: tokenData .scope ,
162+ grantInfo: tokenData .grant_info ,
163+ };
164+ }
165+ });
166+
167+ // Use normally - the custom exchange will be called automatically
168+ const result = await nylasConnect .connect ({ method: ' popup' });
169+ ```
170+
171+ ### Backend Implementation Example
172+
173+ ``` typescript
174+ // Example backend endpoint (/api/auth/exchange)
175+ export async function POST(request : Request ) {
176+ const { code, clientId, redirectUri } = await request .json ();
177+
178+ // Exchange code for tokens using your API key
179+ const response = await fetch (' https://api.us.nylas.com/connect/token' , {
180+ method: ' POST' ,
181+ headers: {
182+ ' Content-Type' : ' application/x-www-form-urlencoded' ,
183+ ' Authorization' : ` Bearer ${process .env .NYLAS_API_KEY } ` ,
184+ },
185+ body: new URLSearchParams ({
186+ client_id: clientId ,
187+ redirect_uri: redirectUri ,
188+ code ,
189+ grant_type: ' authorization_code' ,
190+ }),
191+ });
192+
193+ const tokenData = await response .json ();
194+ return Response .json (tokenData );
195+ }
196+ ```
122197
123198## API
124199
0 commit comments