import { readFileSync } from 'fs';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import { Saml20 } from 'saml';
import crypto from 'crypto';
import readlineSync from 'readline-sync';
const __dirname = dirname(fileURLToPath(import.meta.url));
const getUserInput = () => {
const clientId = readlineSync.question('Enter your SuccessFactors client ID: ');
const hostname = readlineSync.question('Enter your SuccessFactors hostname (e.g., hcm68sales.successfactors.com): ');
const companyId = readlineSync.question('Enter your company ID (e.g., SFCPART001523): ');
const username = readlineSync.question('Enter your SuccessFactors username (leave blank to use userId): ');
let userId = '';
if (!username) {
userId = readlineSync.question('Enter your SuccessFactors userId: ');
}
return {
clientId,
hostname,
companyId,
username,
userId
};
};
const readCertificateFiles = () => {
try {
return {
cert: readFileSync(`cert.pem`, 'utf8'),
privateKey: readFileSync(`private.pem`, 'utf8')
};
} catch (error) {
console.error('Error reading certificate files:', error.message);
console.log('Please ensure both public.pem and private.pem exist');
process.exit(1);
}
};
const createSamlOptions = (config, certData) => {
const isUsingUsername = !!config.username;
return {
cert: certData.cert,
key: certData.privateKey,
issuer: 'www.successfactors.com',
lifetimeInSeconds: 315360000,
audiences: 'www.successfactors.com',
attributes: {
api_key: config.clientId,
use_username: isUsingUsername ? 'true' : 'false',
use_email: 'false',
external_user: 'false',
...(isUsingUsername ? {} : { user_id: config.userId })
},
nameIdentifier: config.username,
sessionIndex: crypto.randomUUID(),
recipient: `https://${config.hostname}/oauth/token`
};
};
const generateSamlAssertion = () => {
const config = getUserInput();
const certData = readCertificateFiles();
const options = createSamlOptions(config, certData);
const rawAssertion = Saml20.create(options);
const assertion = Buffer.from(rawAssertion).toString('base64');
console.log('\n✅ SAML client assertion');
console.log(assertion);
};
generateSamlAssertion();