Skip to content

Commit 6301fb0

Browse files
feat(microsoft-teams): microsoft: Obtain tenantId by decoding the access token instead of calling the /organizations endpoint (#4024)
This PR updates the Microsoft Teams post-connection logic to decode the access token using JWT. It introduces a new interface for the decoded token structure and retrieves the tenant ID directly from the decoded token instead of making an API call. This change improves efficiency by reducing unnecessary network requests and streamlining the connection configuration process. - Ticket: [EXT-699](https://linear.app/nango/issue/EXT-699/microsoft-obtain-tenantid-by-decoding-the-access-token-instead-of) <!-- Summary by @propel-code-bot --> --- **Microsoft Teams Authentication Optimization: JWT Token Decoding for TenantID** This PR optimizes the Microsoft Teams authentication flow by replacing an API call with direct JWT token decoding. Instead of making a network request to the '/v1.0/organization' endpoint, the code now extracts the tenant ID directly from the access token. This approach reduces latency, eliminates a potential failure point, and improves overall connection efficiency by removing an unnecessary network dependency. **Key Changes:** • Replaced ``API`` call to /v1.0/organization with ``JWT`` token decoding • Created comprehensive `MicrosoftDecodedToken` interface for token structure • Extracted tenant ``ID`` (tid) directly from the decoded token • Removed dependency on axios for this operation **Affected Areas:** • Microsoft Teams post-connection handler • Authentication flow for Microsoft Teams integration **Potential Impact:** **Functionality**: More reliable tenant ID retrieval with fewer dependencies on external API calls **Performance**: Reduced latency by eliminating an HTTP request during connection setup **Security**: Potential security concern due to using jwt.decode() without proper token verification **Scalability**: Improved scalability by reducing external API dependencies and network traffic **Review Focus:** • Security concern: Using jwt.decode() without verification • Completeness of the `MicrosoftDecodedToken` interface • Error handling when token is not decodable • Type assertion safety when handling the decoded ``JWT`` <details> <summary><strong>Testing Needed</strong></summary> • Verify tenant ``ID`` extraction works for tokens from different Microsoft tenants • Test with various token structures to ensure the interface is complete • Verify error handling when token cannot be decoded properly • Test with expired/invalid tokens to ensure graceful failure </details> <details> <summary><strong>Code Quality Assessment</strong></summary> **packages/server/lib/hooks/connection/providers/microsoft-teams/post-connection.ts**: Well-structured with clear type definitions. The interface is comprehensive but could potentially be simplified if not all properties are needed. </details> <details> <summary><strong>Best Practices</strong></summary> **Code Organization**: • Well-defined interfaces • Type safety **Error Handling**: • Defensive coding with type and existence checks **Performance**: • Reducing ``API`` calls • Local processing instead of network requests </details> <details> <summary><strong>Possible Issues</strong></summary> • Security vulnerability from using jwt.decode() without verification • Token structure might change in Microsoft API updates • Interface may need updates if Microsoft adds/removes fields from their tokens </details> --- *This summary was automatically generated by @propel-code-bot*
1 parent e04bad7 commit 6301fb0

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed
Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,57 @@
11
import type { InternalNango as Nango } from '../../post-connection.js';
2-
import axios from 'axios';
2+
import type { OAuth2Credentials } from '@nangohq/types';
3+
import jwt from 'jsonwebtoken';
4+
5+
interface MicrosoftDecodedToken {
6+
aud: string;
7+
iss: string;
8+
iat: number;
9+
nbf: number;
10+
exp: number;
11+
acct: number;
12+
acr: string;
13+
aio: string;
14+
amr: string[];
15+
app_displayname: string;
16+
appid: string;
17+
appidacr: string;
18+
family_name: string;
19+
given_name: string;
20+
idtyp: string;
21+
ipaddr: string;
22+
name: string;
23+
oid: string;
24+
platf: string;
25+
puid: string;
26+
rh: string;
27+
scp: string;
28+
signin_state: string[];
29+
sub: string;
30+
tenant_region_scope: string;
31+
tid: string;
32+
unique_name: string;
33+
upn: string;
34+
uti: string;
35+
ver: string;
36+
wids: string[];
37+
xms_ftd: string;
38+
xms_idrel: string;
39+
xms_st: {
40+
sub: string;
41+
};
42+
xms_tcdt: number;
43+
}
344

445
export default async function execute(nango: Nango) {
546
const connection = await nango.getConnection();
6-
const response = await nango.proxy({
7-
endpoint: '/v1.0/organization',
8-
method: 'GET',
9-
providerConfigKey: connection.provider_config_key
10-
});
47+
const accessToken = (connection.credentials as OAuth2Credentials).access_token;
48+
const decoded = jwt.decode(accessToken) as MicrosoftDecodedToken;
1149

12-
if (axios.isAxiosError(response) || !response || !response.data) {
50+
if (!decoded || typeof decoded !== 'object') {
1351
return;
1452
}
1553

16-
const [{ id }] = response.data.value;
54+
const id = decoded.tid;
1755

1856
await nango.updateConnectionConfig({ tenantId: id });
1957
}

0 commit comments

Comments
 (0)