Skip to content

Commit e04bad7

Browse files
fix(slack): add an alternate path for access_token if undefined (#4025)
## Describe the problem and your solution - Add an alternate path for `access_token` interpolation if not found at top-level, Nango's default for Oauth2. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR addresses an issue with Slack's OAuth2 authentication flow where access tokens are sometimes returned in a nested path ('authed_user.access_token') rather than at the top level. The changes add support for retrieving tokens from alternate paths when the default path returns undefined, ensuring connections can be established successfully with Slack's API. **Key Changes:** • Added alternate_access_token_response_path property to ProviderOAuth2 interface • Modified parseRawCredentials to check alternate paths when access_token is not found • Updated Slack provider configuration to use the new alternate path **Affected Areas:** • OAuth2 authentication flow • Slack provider integration • Connection credential parsing logic *This summary was automatically generated by @propel-code-bot*
1 parent 74867a9 commit e04bad7

File tree

7 files changed

+20
-8
lines changed

7 files changed

+20
-8
lines changed

packages/providers/providers.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9046,6 +9046,7 @@ slack:
90469046
auth_mode: OAUTH2
90479047
authorization_url: https://slack.com/oauth/v2/authorize
90489048
scope_separator: ','
9049+
alternate_access_token_response_path: authed_user.access_token
90499050
token_url: https://slack.com/api/oauth.v2.access
90509051
token_response_metadata:
90519052
- incoming_webhook.url

packages/server/lib/controllers/connection.controller.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import type {
2121
OAuth1Credentials,
2222
OAuth2ClientCredentials,
2323
ProviderGithubApp,
24-
TbaCredentials
24+
TbaCredentials,
25+
ProviderOAuth2
2526
} from '@nangohq/types';
2627
import type { NextFunction, Request, Response } from 'express';
2728

@@ -205,7 +206,8 @@ class ConnectionController {
205206

206207
const { expires_at: parsedExpiresAt } = connectionService.parseRawCredentials(
207208
{ access_token, refresh_token, expires_at, expires_in },
208-
provider.auth_mode
209+
provider.auth_mode,
210+
provider as ProviderOAuth2
209211
) as OAuth2Credentials;
210212

211213
if (!access_token) {

packages/server/lib/controllers/oauth.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ class OAuthController {
10171017
let parsedRawCredentials: OAuth2Credentials;
10181018

10191019
try {
1020-
parsedRawCredentials = connectionService.parseRawCredentials(rawCredentials, 'OAUTH2') as OAuth2Credentials;
1020+
parsedRawCredentials = connectionService.parseRawCredentials(rawCredentials, 'OAUTH2', provider as ProviderOAuth2) as OAuth2Credentials;
10211021
} catch (err) {
10221022
void logCtx.error('The OAuth token response from the server could not be parsed - OAuth flow failed.', { error: err, rawCredentials });
10231023
await logCtx.failed();

packages/shared/lib/clients/oauth2.client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ export async function getFreshOAuth2Credentials({
172172

173173
let newCredentials: OAuth2Credentials;
174174
try {
175-
newCredentials = connectionsManager.parseRawCredentials(rawNewAccessToken.token, 'OAUTH2') as OAuth2Credentials;
175+
newCredentials = connectionsManager.parseRawCredentials(rawNewAccessToken.token, 'OAUTH2', provider) as OAuth2Credentials;
176176

177177
if (!newCredentials.refresh_token && credentials.refresh_token != null) {
178178
newCredentials.refresh_token = credentials.refresh_token;

packages/shared/lib/services/connection.service.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -840,10 +840,15 @@ class ConnectionService {
840840

841841
switch (authMode) {
842842
case 'OAUTH2': {
843-
if (!rawCreds['access_token']) {
844-
throw new NangoError(`incomplete_raw_credentials`);
843+
let accessToken: string | undefined = rawCreds['access_token'];
844+
845+
if (!accessToken && template && 'alternate_access_token_response_path' in template && template.alternate_access_token_response_path) {
846+
accessToken = extractValueByPath(rawCreds, template.alternate_access_token_response_path);
845847
}
846848

849+
if (!accessToken) {
850+
throw new NangoError(`incomplete_raw_credentials`);
851+
}
847852
let expiresAt: Date | undefined;
848853

849854
if (rawCreds['expires_at']) {
@@ -854,7 +859,7 @@ class ConnectionService {
854859

855860
const oauth2Creds: OAuth2Credentials = {
856861
type: 'OAUTH2',
857-
access_token: rawCreds['access_token'],
862+
access_token: accessToken,
858863
refresh_token: rawCreds['refresh_token'],
859864
expires_at: expiresAt,
860865
raw: rawCreds
@@ -1289,7 +1294,7 @@ class ConnectionService {
12891294
> {
12901295
if (providerClient.shouldUseProviderClient(providerConfig.provider)) {
12911296
const rawCreds = await providerClient.refreshToken(provider as ProviderOAuth2, providerConfig, connection);
1292-
const parsedCreds = this.parseRawCredentials(rawCreds, 'OAUTH2') as OAuth2Credentials;
1297+
const parsedCreds = this.parseRawCredentials(rawCreds, 'OAUTH2', provider as ProviderOAuth2) as OAuth2Credentials;
12931298

12941299
return { success: true, error: null, response: parsedCreds };
12951300
} else if (provider.auth_mode === 'OAUTH2_CC') {

packages/types/lib/providers/provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export interface ProviderOAuth2 extends BaseProvider {
101101
grant_type: 'refresh_token';
102102
};
103103
authorization_method?: OAuthAuthorizationMethodType;
104+
alternate_access_token_response_path?: string;
104105

105106
refresh_url?: string;
106107
expires_in_unit?: 'milliseconds';

scripts/validation/providers/schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
"display_name": {
1515
"type": "string"
1616
},
17+
"alternate_access_token_response_path": {
18+
"type": "string"
19+
},
1720
"auth": {
1821
"type": "object",
1922
"additionalProperties": true,

0 commit comments

Comments
 (0)