@sap/cds
Version:
SAP Cloud Application Programming Model - CDS for Node.js
76 lines (68 loc) • 2.56 kB
JavaScript
const https = require('https')
const _errorObj = result => {
const errorObj = new Error('Authorization failed')
errorObj.target = { kind: 'TOKEN' }
errorObj.response = result
return errorObj
}
const requestToken = ({ client, secret, endpoint, mTLS }, tenant, tokenStore) => {
const promise = new Promise((resolve, reject) => {
const options = {
host: endpoint.replace('/oauth/token', '').replace('https://', ''),
headers: {}
}
if (mTLS) {
options.method = 'POST'
options.path = '/oauth/token'
options.headers['content-type'] = 'application/x-www-form-urlencoded'
options.cert = mTLS.cert
options.key = mTLS.key
} else {
options.method = 'GET'
options.path = '/oauth/token?grant_type=client_credentials&response_type=token'
options.headers.Authorization = 'Basic ' + Buffer.from(client + ':' + secret).toString('base64')
}
if (tenant) options.headers['x-zid'] = tenant
const req = https.request(options, res => {
res.setEncoding('utf8')
let chunks = ''
res.on('data', chunk => {
chunks += chunk
})
res.on('end', () => {
const result = { body: chunks, headers: res.headers, statusCode: res.statusCode }
if (res.statusCode < 200 || res.statusCode >= 300) {
return reject(_errorObj(result))
}
try {
const json = JSON.parse(result.body)
if (!json.access_token) {
reject(_errorObj(result))
return
}
// set timeout to delete token from cache 5 minutes (300 seconds) before it expires
const expiresIn = json.expires_in || 3600
const timeout = Math.max(0, (expiresIn - 300) * 1000)
if (tokenStore.expirationTimeout) clearTimeout(tokenStore.expirationTimeout)
tokenStore.expires_in = json.expires_in
tokenStore.expirationTimeout = setTimeout(() => {
delete tokenStore.token
delete tokenStore.expires_in
delete tokenStore.expirationTimeout
}, timeout)
tokenStore.expirationTimeout.unref()
// store token value on tokenStore
tokenStore.token = json.access_token
resolve(json.access_token)
} catch {
reject(_errorObj(result))
}
})
})
if (options.method === 'POST') req.write(`client_id=${client}&grant_type=client_credentials&response_type=token`)
req.end()
})
tokenStore.token = promise
return promise
}
module.exports = requestToken