below code works fine when running locally, but "getAccessToken ()" does not work as expected when running inside an aws lambda function, when doing "POST" to /webhook endpoint. I am using node 8.10, "aws-serverless-express": "^3.3.6", "express": "^4.16.4" and "node-fetch": "^2.5.0", basically it print the correct jwt token but node-fetch does not return anything, sample log.
START RequestId: c8efba59-1869-4eaa-b9d8-aa15a7507d52 Version: $LATEST 2019-05-27T19:55:32.328Z c8efba59-1869-4eaa-b9d8-aa15a7507d52 start getExecution 2019-05-27T19:55:32.328Z c8efba59-1869-4eaa-b9d8-aa15a7507d52 exectution_url: 2019-05-27T19:55:32.328Z c8efba59-1869-4eaa-b9d8-aa15a7507d52 https://cloudmanager.adobe.io/somevalidurl 2019-05-27T19:55:32.328Z c8efba59-1869-4eaa-b9d8-aa15a7507d52 start getAccessToken END RequestId: c8efba59-1869-4eaa-b9d8-aa15a7507d52 REPORT RequestId: c8efba59-1869-4eaa-b9d8-aa15a7507d52 Duration: 6657.00 ms Billed Duration: 6700 ms Memory Size: 128 MB Max Memory Used: 37 MB
I made sure lambda timeout is 30 seconds, tried to disable "node-fetch" timeout by setting it to 0 and , used a middleware for all the routes "app.use(timeout("30000"))" also for that specific webhook request timeout. (I receive the 200 pong response immediately but getexectuion async function does not work properly)
const express = require('express')
const bodyParser = require('body-parser')
const crypto = require('crypto')
const jsrsasign = require('jsrsasign')
const fetch = require('node-fetch')
const timeout = require('connect-timeout')
const URL = require('url').URL
const URLSearchParams = require('url').URLSearchParams
//require('dotenv').config()
const app = express()
async function getAccessToken () {
console.log("start getAccessToken")
const EXPIRATION = 60 * 60 // 1 hour
const header = {
'alg': 'RS256',
'typ': 'JWT'
}
const payload = {
'exp': Math.round(new Date().getTime() / 1000) + EXPIRATION,
'iss': process.env.ORGANIZATION_ID,
'sub': process.env.TECHNICAL_ACCOUNT_ID,
'aud': `https://ims-na1.adobelogin.com/c/${process.env.API_KEY}`,
'https://ims-na1.adobelogin.com/s/ent_cloudmgr_sdk': true
}
const jwtToken = jsrsasign.jws.JWS.sign('RS256', JSON.stringify(header), JSON.stringify(payload), process.env.PRIVATE_KEY)
//console.log("jwt token:")
//console.log(jwtToken)
const body = new URLSearchParams({
client_id: process.env.API_KEY,
client_secret: process.env.CLIENT_SECRET,
jwt_token: jwtToken
})
const response = await fetch('https://ims-na1.adobelogin.com/ims/exchange/jwt', {
method: 'POST',
options: { timeout: 0},
timeout: 0,
size: 0,
body: body
})//.catch(error => {
// console.log("an error happend in fetchg")
// console.log(error)
//})
const json = await response.json()
if ((response.status !== 200) && (response.status !== 201)) {
console.error(`Invalid response status ${ response.status }.`);
throw json;
}
console.log("access_token:")
console.log(json['access_token'])
return json['access_token']
}
async function makeApiCall (accessToken, url, method) {
console.log("start make api call")
const response = await fetch(url, {
'method': method,
'headers': {
'x-gw-ims-org-id': process.env.ORGANIZATION_ID,
'x-api-key': process.env.API_KEY,
'Authorization': `Bearer ${accessToken}`
}
})
console.log("finish make api call")
const json = await response.json()
return json
}
function getLink (obj, linkType) {
return obj['_links'][linkType].href
}
async function getExecution (executionUrl) {
console.log("start getExecution")
console.log("exectution_url:")
console.log(executionUrl)
const accessToken = await getAccessToken()
console.log("access-token:")
console.log(accessToken)
const execution = await makeApiCall(accessToken, executionUrl, 'GET')
console.log(execution)
console.log("aaaa")
const program = await makeApiCall(accessToken, new URL(getLink(execution, 'http://ns.adobe.com/adobecloud/rel/program'), executionUrl))
console.log(execution)
console.log("here")
execution.program = program
return execution
}
//app.use(bodyParser.json())
app.use(bodyParser.json({
verify: (req, res, buf, encoding) => {
const signature = req.header('x-adobe-signature')
if (signature) {
const hmac = crypto.createHmac('sha256', process.env.CLIENT_SECRET)
hmac.update(buf)
const digest = hmac.digest('base64')
if (signature !== digest) {
throw new Error('x-adobe-signature HMAC check failed')
}
} else if (!process.env.DEBUG && req.method === 'POST') {
throw new Error('x-adobe-signature required')
}
}
}))
app.use(timeout("30000"))
app.post('/webhook', (req, res) => {
req.setTimeout(120000, function(){
console.log('Request has timed out.');
res.send(408);
});
res.writeHead(200, { 'Content-Type': 'application/text' })
res.end('pong')
getExecution("https://cloudmanager.adobe.io/<somevalidurl>").then(execution => {
console.log(`Execution for ${execution.program.name} started`)
})
})
module.exports = app;
//const port = process.env.PORT || 3000
//app.listen(port, () =>
// console.log(`App is listening on port ${port}.`)
//)