Getting error: execution time limit exceeded with module

After experimenting with this I came up with some examples that can serve as starting points.

To generate a hash using scrypt:

exports = ({input}) => {
  
  const crypto = require('crypto');

  try {
    
/*
Note that the size argument in the randomBytes method doesn't 
necessarily need to match the key length argument in the scryptSync 
method. It just creates a longer salt. You might get by with just 16 
instead of 32. I'm not an expert on best practices so DYOR.
*/
    const salt = crypto.randomBytes(32).toString('hex');
    
    const hash = crypto.scryptSync(input, salt, 32).toString('hex');

/*
Here I'm concatenating the salt and hash but alternatively you could
you could just store the salt and hash separately in your database;
*/
    const concatenatedString = salt.concat("", hash);
   
    return concatenatedString;
    
  } catch(err){
    
    throw(err);
    
  }
  
};

To compare a hashed input to a stored hash value using scrypt:

exports = ({
  input,
  storedValue
}) => {
  
  const crypto = require('crypto');
    
  try {
    
/*
The length of the substring will depend on the length of the salt;
As already mentioned you could instead store the salts and hashes 
separately in your database;
*/
    const salt = storedValue.substring(0, 64);
    
    const hash = crypto.scryptSync(input, salt, 32).toString('hex');
    
    const concatenatedString = salt.concat("", hash);
    
    if(concatenatedString === storedValue){
      
      return true;
      
    } else {
      
      return false;
  
    }
    
  } catch (err) {
    
    throw(err);  
    
  }
  
};

I’ve also confirmed that regular old bcrypt works just fine in Google Cloud. Here is an example of how you could stick with bcrypt and still use it with Atlas by calling a Google Cloud Function. In Google Cloud use the following code to generate a hash using bcrypt:

const functions = require('@google-cloud/functions-framework');

const bcrypt = require('bcrypt');

const getHash = async({ input }) => {

  const hash = bcrypt.hashSync(input, 10);
  
  return hash;

};

functions.http('generateBcryptHash', async(req, res) => {
  
    try {
      
      const input = req.body.input;

      const hash = await getHash({ input });

      res.json(hash);
      
    } catch (err){

      res.json({err:{message:err.message}});

    }

  }

});

To call the Google Cloud Function in Atlas you could use:

exports = async({
 input
}) => {
      
    try {
      
      const response = await context.http.post({
        url: "https://us-central1-yourgoogleprojectname.net/generateBcryptHash",
        body:{
          input
        },
        encodeBodyAsJSON: true
      });
      
      const hash = JSON.parse(response.body.text());
       
      if(hash.err){
        
        throw new Error(hash.err.message);
        
      } else {
        
        return hash;
        
      }
      
    } catch(err){
      
      throw(err);
      
    }
  
};

Then in Google Cloud for the compare function:

const functions = require('@google-cloud/functions-framework');

const bcrypt = require('bcrypt');

const compare = ({ input, storedValue }) => {
  
  const result = bcrypt.compareSync(input, storedValue);
  
  return result;

};

functions.http('compareBcryptHash', async(req, res) => {

    try {
      
      const input = req.body.input;

      const storedValue = req.body.storedValue;

      const isMatch = await compare({ input, storedValue });

      res.json(isMatch);

    } catch (err){

      res.json({err:{message:err.message}});

    }

  }

});

Finally in Atlas call the Google Cloud Function to make a comparison:

exports = async function({
  input,
  storedValue
}){

  try {
    
    const response = await context.http.post({
      url: "https://us-central1-yourgoogleprojectname.cloudfunctions.net/compareBcryptHash",
      body:{
        input,
        storedValue
      },
      encodeBodyAsJSON: true
    });
  
    const isMatch = JSON.parse(response.body.text());
    
    if(isMatch.err){
      
      throw new Error(isMatch.err.message);
      
    } else {
      
      return isMatch;
      
    }
      
  } catch(err) {
    
    throw(err);
    
  }

};