ADP's REST API requires that a SSL certificate and private key be sent with every request.
When I use the 'standard, Node.js HTTP(S) module:
require('dotenv').config()
const fs = require('fs')
const path = require('path')
const certificate_path = path.resolve('../credentials/certificate.pem')
const private_key_path = path.resolve('../credentials/private.key')
const options = {
hostname: 'api.adp.com',
path: '/hr/v2/workers/ABCDEFGHIJKLMNOP',
method: 'GET',
headers: {
'Accept': 'application/json;masked=false',
'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`
},
cert: fs.readFileSync(certificate_path, "utf8"),
key: fs.readFileSync(private_key_path, "utf8"),
};
require('https').get(options, res => {
let data = [];
res.on('data', chunk => {
data.push(chunk);
});
res.on('end', () => {
const workers = JSON.parse(Buffer.concat(data).toString());
for(worker of workers.workers) {
console.log(`Got worker with id: ${worker.associateOID}, name: ${worker.person.legalName.formattedName}`);
}
});
}).on('error', err => {
console.log('Error: ', err.message);
});
The request works as expected:
$ node ./standard.js
Got worker with id: ABCDEFGHIJKLMNOP, name: Last, First
However, when I use node-fetch:
require('dotenv').config()
const fs = require('fs')
const path = require('path')
const certificate_path = path.resolve('../credentials/certificate.pem')
const private_key_path = path.resolve('../credentials/private.key')
const url = 'https://accounts.adp.com/hr/v2/workers/ABCDEFGHIJKLMNOP'
const options = {
headers: {
'Accept': 'application/json;masked=false',
'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`
},
agent: new require('https').Agent({
cert: fs.readFileSync(certificate_path, "utf8"),
key: fs.readFileSync(private_key_path, "utf8")
})
}
fetch(url,options)
.then((response) => response.json())
.then((body) => {
console.log(body);
});
I get an error:
$ node ./fetch.js
{
response: {
responseCode: 401,
methodCode: 'GET',
resourceUri: { href: '/hr/v2/workers/ABCDEFGHIJKLMNOP' },
serverRequestDateTime: '2023-03-30T14:25:23.351Z',
applicationCode: {
code: 401,
typeCode: 'error',
message: 'Request did not provide the required two-way TLS certificate'
},
client_ip_adddress: 'a.b.c.d',
'adp-correlationID': '61f76d29-04e1-48b8-be9d-acf459408b2b'
}
}
What am I missing in the second approach?