import { readFileSync } from 'fs';
import { execSync } from 'child_process';
import jwt from 'jsonwebtoken';
import readlineSync from 'readline-sync';
const getUserInput = () => {
  const tenantId = readlineSync.question('Please enter your tenant ID: ');
  const clientId = readlineSync.question('Please enter your client ID: ');
  return { tenantId, clientId };
};
const readPrivateKey = (path) => {
  try {
    return readFileSync(path, 'utf8');
  } catch (error) {
    console.error(`Error reading private key from ${path}:`, error);
    throw error;
  }
};
const getX5tThumbprint = (certPath) => {
  const command = `echo $(openssl x509 -in ${certPath} -fingerprint -noout) | sed 's/SHA1 Fingerprint=//g' | sed 's/://g' | xxd -r -ps | base64`;
  
  try {
    const thumbprint = execSync(command).toString().trim();
    return thumbprint;
  } catch (error) {
    console.error(`Error calculating x5t thumbprint for certificate ${certPath}:`, error);
    throw error;
  }
};
const TEN_YEARS_MS = 10 * 365 * 24 * 60 * 60 * 1000;
// Microsoft Entra ID doesn't place restrictions on the exp time currently.
const createJwtClaims = (tenantId, clientId, expirationInSeconds = TEN_YEARS_MS) => ({
  aud: `https://login.microsoftonline.com/${tenantId}/oauth2/token`,
  iss: clientId,
  sub: clientId,
  nbf: Math.floor(Date.now() / 1000),
  exp: Math.floor(Date.now() / 1000) + expirationInSeconds,
  jti: generateUniqueJti(),
});
const generateUniqueJti = () => `jti-${Math.random().toString(36).substr(2, 9)}`;
const createJwt = (claims, privateKey, x5tThumbprint) => {
  const header = {
    alg: "PS256",
    typ: "JWT",
    x5t: x5tThumbprint,
  };
  try {
    return jwt.sign(claims, privateKey, {
      algorithm: 'RS256',
      header: header,
    });
  } catch (error) {
    console.error('Error signing JWT:', error);
    throw error;
  }
};
const generateJwtAssertion = () => {
  const { tenantId, clientId } = getUserInput();
  const certPath = 'certificate.pem';
  const privateKeyPath = 'private.key';
  const privateKey = readPrivateKey(privateKeyPath);
  const x5tThumbprint = getX5tThumbprint(certPath);
  console.log('Calculated x5t Thumbprint:', x5tThumbprint);
  const claims = createJwtClaims(tenantId, clientId);
  const token = createJwt(claims, privateKey, x5tThumbprint);
  console.log('JWT Assertion:', token);
};
generateJwtAssertion();