UNPKG

apigee-edge-js

Version:

nodejs library for the administration API for Apigee (Edge and X and hybrid).

168 lines (154 loc) 4.79 kB
// common.js // ------------------------------------------------------------------ // Copyright 2018-2021 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // /* jshint esversion:9, node:true, strict:implied */ /* global Buffer */ const tokenMgmt = require('./tokenMgmt.js'), utility = require('./utility.js'), jsonRe = new RegExp('application/json'); function generateRandomString(L) { function c() { return (Math.floor(Math.random() * 5)<1) ? (Math.floor(Math.random() * 10) + 48) : // number String.fromCharCode(65 + Math.floor(Math.random() * 26) + (Math.floor(Math.random() * 2) * 32)); // alpha } var i, s = ''; L = L || (Math.floor(Math.random() * 7) + 13); for (i=0; i<L; i++) { s += c(); } return s; } /* * convert a simple timespan string, expressed in days, hours, minutes, or * seconds, such as 30d, 12d, 8h, 45m, 30s, into a numeric quantity in * seconds. */ function resolveExpiry(subject) { let pattern = new RegExp('^([1-9][0-9]*)([smhdw])$','i'), multipliers = {s: 1, m: 60, h : 60*60, d:60*60*24, w: 60*60*24*7, y: 60*60*24*365}, match = pattern.exec(subject); if (match) { return match[1] * multipliers[match[2]] * 1000; } return -1; } function safeJsonParse(response, body) { if ( ! response || !response.headers) return body; let isJson = jsonRe.test(response.headers['content-type']); // this simple approach does not work because the // Apigee API sometimes claims application/json erroneously. //return (isJson) ? (body ? JSON.parse(body): null) : body; if ( ! isJson) { return body; } // no parse if (body){ try { //console.log('jsonparse ' + body); return JSON.parse(body); } catch (e) { response.headers['content-type'] = 'application/octet-stream'; return body; } } return null; } function callback(conn, okstatuses, cb) { return function (error, response, body) { if (conn.verbosity>0) { if (response) { utility.logWrite('status: ' + response.statusCode); } else { utility.logWrite('no response'); } } if ( ! response) { return cb(error || new Error('no response'), null); } if (error) { return cb(error, safeJsonParse(response, body)); } if ( !okstatuses || (okstatuses.length == 0) || (okstatuses.indexOf(response.statusCode) > -1)) { cb(null, safeJsonParse(response, body)); } else { let result = safeJsonParse(response, body); if (conn.verbosity>0) { utility.logWrite('result: ' + JSON.stringify(result) ); } cb(new Error('bad status: ' + response.statusCode), result); } }; } // to handle expiry of the oauth token function insureFreshToken(conn, cb) { let rh = conn.requestHeaders; if (rh && rh.authorization && conn.user && rh.authorization.indexOf('Bearer ') === 0) { var stashedToken = tokenMgmt.currentToken(conn.user, conn.loginBaseUrl, conn.mgmtServer); if (tokenMgmt.isInvalidOrExpired(stashedToken)) { return conn.refreshToken(stashedToken, function(e, result){ if (e) { throw new Error('error refreshing token: ' + e ); } cb({ headers: {...rh}}); }); } else { cb({ headers: {...rh}}); } } else { cb({ headers: {...rh}}); } } function base64Encode(s) { return new Buffer.from(s).toString('base64'); } function arrayOfKeyValuePairsToHash(properties) { if (Array.isArray(properties)) { let hash = {}; properties.forEach(item => hash[item.name] = item.value); return hash; } return properties; } function hashToArrayOfKeyValuePairs(hash) { if (Array.isArray(hash)) { return hash; } return Object.keys(hash).map(key => ( { name : key, value : hash[key]}) ); } function maybeReformAttributes(ary1) { if (Array.isArray(ary1)) { if (typeof ary1[0] == 'string') { let ary2 = []; ary1.forEach(item => { let parts = item.split(':'); ary2[parts[0]] = parts[1]; }); return ary2; } } return ary1; } module.exports = { insureFreshToken, callback, resolveExpiry, generateRandomString, base64Encode, arrayOfKeyValuePairsToHash, hashToArrayOfKeyValuePairs, maybeReformAttributes };