104 lines
3.8 KiB
JavaScript
104 lines
3.8 KiB
JavaScript
|
|
import crypto from 'crypto';
|
||
|
|
import https from 'https';
|
||
|
|
import fs from 'fs';
|
||
|
|
|
||
|
|
const header = Buffer.from(JSON.stringify({ alg: 'RS256' })).toString('base64url');
|
||
|
|
const now = Math.floor(Date.now() / 1000);
|
||
|
|
const claims = {
|
||
|
|
iss: '3MVG9RGDcVlytYtcgAeR2ANSn3O2OMs6MBQgA.tpHlObl8_eArqCzm0u0E73PfcBZxkCvs5DAiDb8yFYtcL5Q',
|
||
|
|
sub: 'portal.integration@asolutions.co.jp.playground',
|
||
|
|
aud: 'https://asolutions--playground.sandbox.my.salesforce.com',
|
||
|
|
exp: now + 300
|
||
|
|
};
|
||
|
|
const payload = Buffer.from(JSON.stringify(claims)).toString('base64url');
|
||
|
|
const unsigned = header + '.' + payload;
|
||
|
|
const keyPem = fs.readFileSync('apps/bff/secrets/sf-sandbox-private.pem', 'utf8');
|
||
|
|
const sign = crypto.createSign('RSA-SHA256');
|
||
|
|
sign.update(unsigned);
|
||
|
|
const sig = sign.sign(keyPem, 'base64url');
|
||
|
|
const jwt = unsigned + '.' + sig;
|
||
|
|
|
||
|
|
function sfRequest(accessToken, instanceUrl, soql) {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const url = new URL(instanceUrl + '/services/data/v59.0/query?q=' + encodeURIComponent(soql));
|
||
|
|
https.get({
|
||
|
|
hostname: url.hostname,
|
||
|
|
path: url.pathname + url.search,
|
||
|
|
headers: { 'Authorization': 'Bearer ' + accessToken }
|
||
|
|
}, (res) => {
|
||
|
|
let body = '';
|
||
|
|
res.on('data', d => body += d);
|
||
|
|
res.on('end', () => resolve(JSON.parse(body)));
|
||
|
|
}).on('error', reject);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function sfPatch(accessToken, instanceUrl, sobjectPath, data) {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const url = new URL(instanceUrl + '/services/data/v59.0/sobjects/' + sobjectPath);
|
||
|
|
const jsonData = JSON.stringify(data);
|
||
|
|
const req = https.request({
|
||
|
|
hostname: url.hostname,
|
||
|
|
path: url.pathname,
|
||
|
|
method: 'PATCH',
|
||
|
|
headers: {
|
||
|
|
'Authorization': 'Bearer ' + accessToken,
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
'Content-Length': Buffer.byteLength(jsonData)
|
||
|
|
}
|
||
|
|
}, (res) => {
|
||
|
|
let body = '';
|
||
|
|
res.on('data', d => body += d);
|
||
|
|
res.on('end', () => resolve({ status: res.statusCode, body }));
|
||
|
|
});
|
||
|
|
req.on('error', reject);
|
||
|
|
req.write(jsonData);
|
||
|
|
req.end();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function getToken() {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const postData = 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=' + jwt;
|
||
|
|
const url = new URL('https://asolutions--playground.sandbox.my.salesforce.com/services/oauth2/token');
|
||
|
|
const req = https.request({
|
||
|
|
hostname: url.hostname, path: url.pathname, method: 'POST',
|
||
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) }
|
||
|
|
}, (res) => {
|
||
|
|
let body = '';
|
||
|
|
res.on('data', d => body += d);
|
||
|
|
res.on('end', () => resolve(JSON.parse(body)));
|
||
|
|
});
|
||
|
|
req.on('error', reject);
|
||
|
|
req.write(postData);
|
||
|
|
req.end();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
const token = await getToken();
|
||
|
|
if (!token.access_token) {
|
||
|
|
console.error('Auth failed:', token);
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get all inactive SIM products
|
||
|
|
const result = await sfRequest(token.access_token, token.instance_url,
|
||
|
|
"SELECT Id, Name, IsActive FROM Product2 WHERE Product2Categories1__c = 'Sim' AND IsActive = false"
|
||
|
|
);
|
||
|
|
|
||
|
|
console.log(`Found ${result.totalSize} inactive SIM products. Activating...`);
|
||
|
|
|
||
|
|
for (const record of (result.records || [])) {
|
||
|
|
const res = await sfPatch(token.access_token, token.instance_url, `Product2/${record.Id}`, { IsActive: true });
|
||
|
|
const status = res.status === 204 ? 'OK' : `FAILED (${res.status}: ${res.body})`;
|
||
|
|
console.log(` ${record.Name} → ${status}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('\nDone. Verifying...');
|
||
|
|
const verify = await sfRequest(token.access_token, token.instance_url,
|
||
|
|
"SELECT Id, Name, IsActive FROM Product2 WHERE Product2Categories1__c = 'Sim'"
|
||
|
|
);
|
||
|
|
const active = verify.records.filter(r => r.IsActive).length;
|
||
|
|
const inactive = verify.records.filter(r => !r.IsActive).length;
|
||
|
|
console.log(`Active: ${active}, Inactive: ${inactive}`);
|