Skip to content

Commit

Permalink
[FUNK-1648] Custom Params support for Extensible Webhook Destination (#…
Browse files Browse the repository at this point in the history
…2745)

* custom param support for webhook-extensible

* custom params changes
  • Loading branch information
vaibhav-nanda authored Mar 4, 2025
1 parent e817a1a commit 1b9735f
Show file tree
Hide file tree
Showing 3 changed files with 397 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,53 @@ import {
} from '@segment/actions-core'
import Webhook from '../index'

const settings = {
oauth: {},
dynamicAuthSettings: {
oauth: {
type: 'authCode',
clientId: 'clientID',
clientSecret: 'clientSecret',
scopes: 'scope',
authorizationServerUrl: 'https://www.webhook-extensible/authorize',
accessTokenServerUrl: 'https://www.webhook-extensible/access_token',
refreshTokenServerUrl: 'https://www.webhook-extensible/refresh_token',
access: {
access_token: 'accessToken1',
token_type: 'bearer',
expires_in: 86400,
refresh_token: 'refreshToken1',
scope: 'scope'
},
customParams: {}
}
}
}

const auth = {
refreshToken: 'refreshToken1',
accessToken: 'accessToken1',
clientId: 'clientID',
clientSecret: 'clientSecret'
}

const expectedRequest = {
grant_type: 'refresh_token',
refresh_token: 'refreshToken1',
scope: 'scope',
client_id: 'clientID',
client_secret: 'clientSecret'
}

const customParams = [
{ key: 'param1', value: 'val1', sendIn: 'header' },
{ key: 'param2', value: 'val2', sendIn: 'header' },
{ key: 'param3', value: 'val3', sendIn: 'body' },
{ key: 'param4', value: 'val4', sendIn: 'body' },
{ key: 'param5', value: 'val5', sendIn: 'query' },
{ key: 'param6', value: 'val6', sendIn: 'query' }
]

// Exported so we can re-use to test webhook-audiences
export const baseWebhookTests = (def: DestinationDefinition<any>) => {
const testDestination = createTestIntegration(def)
Expand Down Expand Up @@ -80,6 +127,266 @@ export const baseWebhookTests = (def: DestinationDefinition<any>) => {
).rejects.toThrow(PayloadValidationError)
})
})

describe('refreshAccessToken', () => {
it('should return access token for authCode type', async () => {
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post('', new URLSearchParams(expectedRequest).toString())
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(settings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token, refreshToken: mockResponse.refresh_token })
})

it('should return access token for authCode type with custom params', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: customParams
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
...expectedRequest,
param3: 'val3',
param4: 'val4'
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.matchHeader('param1', 'val1')
.matchHeader('param2', 'val2')
.query({ param5: 'val5', param6: 'val6' })
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token, refreshToken: mockResponse.refresh_token })
})

it('should return access token for authCode type with only custom header', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: [customParams[0], customParams[1]]
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
...expectedRequest
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.matchHeader('param1', 'val1')
.matchHeader('param2', 'val2')
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token, refreshToken: mockResponse.refresh_token })
})

it('should return access token for authCode type with only custom body', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: [customParams[2], customParams[3]]
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
...expectedRequest,
param3: 'val3',
param4: 'val4'
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token, refreshToken: mockResponse.refresh_token })
})

it('should return access token for authCode type with only custom query params', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: [customParams[4], customParams[5]]
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
...expectedRequest
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.query({ param5: 'val5', param6: 'val6' })
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token, refreshToken: mockResponse.refresh_token })
})

it('should return access token for clientCredentials type', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.type = 'clientCredentials'
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
grant_type: 'client_credentials',
scope: 'scope'
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token })
})

it('should return access token for clientCredentials type with custom params', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.type = 'clientCredentials'
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: customParams
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
grant_type: 'client_credentials',
scope: 'scope',
param3: 'val3',
param4: 'val4'
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.query({ param5: 'val5', param6: 'val6' })
.matchHeader('param1', 'val1')
.matchHeader('param2', 'val2')
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token })
})

it('should return access token for clientCredentials type with custom header', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.type = 'clientCredentials'
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: [customParams[0], customParams[1]]
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
grant_type: 'client_credentials',
scope: 'scope'
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.matchHeader('param1', 'val1')
.matchHeader('param2', 'val2')
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token })
})

it('should return access token for clientCredentials type with custom body', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.type = 'clientCredentials'
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: [customParams[2], customParams[3]]
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
grant_type: 'client_credentials',
scope: 'scope',
param3: 'val3',
param4: 'val4'
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token })
})

it('should return access token for clientCredentials type with custom query params', async () => {
const newSettings = JSON.parse(JSON.stringify(settings))
newSettings.dynamicAuthSettings.oauth.type = 'clientCredentials'
newSettings.dynamicAuthSettings.oauth.customParams = {
refreshRequest: [customParams[4], customParams[5]]
}
const mockResponse = {
access_token: 'accessToken123',
refresh_token: 'refreshToken123'
}
nock(`https://www.webhook-extensible/refresh_token`)
.post(
'',
new URLSearchParams({
grant_type: 'client_credentials',
scope: 'scope'
}).toString()
)
.matchHeader('Authorization', `Basic ${Buffer.from('clientID:clientSecret').toString('base64')}`)
.query({ param5: 'val5', param6: 'val6' })
.reply(200, mockResponse)

const token = await testDestination.refreshAccessToken(newSettings, auth)

expect(token).toEqual({ accessToken: mockResponse.access_token })
})
})
})
}

Expand Down
Loading

0 comments on commit 1b9735f

Please sign in to comment.