UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

76 lines (68 loc) 2.56 kB
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