Get your own Node server
const crypto = require('crypto');
const fs = require('fs');

// Function to create HMAC for a file
function createHmacForFile(filePath, algorithm, key) {
  return new Promise((resolve, reject) => {
    const hmac = crypto.createHmac(algorithm, key);
    const stream = fs.createReadStream(filePath);
    
    stream.on('data', (data) => {
      hmac.update(data);
    });
    
    stream.on('end', () => {
      const digest = hmac.digest('hex');
      resolve(digest);
    });
    
    stream.on('error', (error) => {
      reject(error);
    });
  });
}

// Function to verify file integrity
async function verifyFileIntegrity(filePath, storedHmacPath, algorithm, key) {
  try {
    // Read the stored HMAC
    const storedHmac = fs.readFileSync(storedHmacPath, 'utf8').trim();
    
    // Calculate the current HMAC
    const currentHmac = await createHmacForFile(filePath, algorithm, key);
    
    // Compare the HMACs
    const isValid = currentHmac === storedHmac;
    
    return {
      isValid,
      storedHmac,
      currentHmac
    };
  } catch (error) {
    throw new Error(`Verification failed: ${error.message}`);
  }
}

// Secret key (must be the same as used to create the original HMAC)
const secretKey = 'file-authentication-key';

// Example usage
const filePath = 'example.txt';
const hmacPath = `${filePath}.hmac`;

// Verify the file integrity
verifyFileIntegrity(filePath, hmacPath, 'sha256', secretKey)
  .then(result => {
    console.log(`File: ${filePath}`);
    console.log(`HMAC file: ${hmacPath}`);
    console.log(`Integrity verified: ${result.isValid}`);
    
    if (!result.isValid) {
      console.log('Stored HMAC:', result.storedHmac);
      console.log('Current HMAC:', result.currentHmac);
      console.log('The file has been modified!');
    } else {
      console.log('The file is intact and has not been tampered with.');
    }
  })
  .catch(error => {
    console.error('Error:', error.message);
  });

              
File: example.txt
HMAC file: example.txt.hmac
Integrity verified: true
The file is intact and has not been tampered with.