Domain in cookie not being set properly after deploying but works in localhost

I am creating a full stack application using the MERN stack and I’m deploying it to render but when I try to send a cookie with the headers sameSite: “None”, secure: true, and domain: “.onrender.com” it does not set the cookie in the applications at all.

When I get rid of the domain header, the cookie is set but the domain is set to my backend url “backend-api.onrender.com” so my frontend “frontend.onrender.com” cannot read it. When I test it out using localhost everything works because the domain is localhost and both my frontend and backend are using that domain. Is there any way I can fix this issue?

How can I mute/unmute a microphone using WebRTC and PeerJs?

I’m trying to get the user to mute their microphone so that the other user on the call can’t hear them, but I’ve failed in every attempt.

I just wish the caller or callee could mute themselves so that one can’t hear the other.

This is my code:

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia({ audio: true }).then(function(stream) {
        let currentCall = null;
        let remoteAudioElement = null;
        var localStream = stream;

        // Atender a chamada e fornecer a MediaStream
        peer.on('call', function(call) {
            currentCall = call;
            
            incommingCallToast.show();
            document.getElementById('callerUsername').innerText = call.metadata.callerUsername;

            document.getElementById('acceptCallButton').onclick = function() {
                incommingCallToast.hide();
                call.answer(localStream);  // Use apenas localStream aqui
                call.on('stream', function(remoteStream) {
                    remoteAudioElement = new Audio();
                    remoteAudioElement.srcObject = remoteStream;
                    remoteAudioElement.play();
                    document.getElementById('endCallButton').style.display = 'flex';
                });

                call.on('close', function() {
                    incommingCallToast.hide();
                    showErrorToast('Chamada encerrada.');
                    document.getElementById('endCallButton').style.display = 'none';
                });
            };

            document.getElementById('rejectCallButton').onclick = function() {
                incommingCallToast.hide();
                call.close();
            };
        });

        // Realizar a chamada ao clicar no botão
        document.getElementById('audioCallButton').addEventListener('click', function() {
            $.ajax({
                url: `/friends/${currentFriendId}`,
                method: 'GET',
                success: function (data) {
                    if (data.friend) {
                        const friend = data.friend;

                        if(!friend.online)
                            return showErrorToast("O seu amigo está offline, portanto não pode receber chamadas.");

                        document.getElementById('calleeUsername').innerText = friend.username;
                        callingToast.show();

                        console.log('Calling peer ID: ' + friend.peerid);

                        var call = peer.call(friend.peerid, localStream, {
                            metadata: { callerUsername: currentUsername }
                        });

                        currentCall = call;

                        call.on('stream', function(remoteStream) {
                            remoteAudioElement = new Audio();
                            remoteAudioElement.srcObject = remoteStream;
                            remoteAudioElement.play();
                            document.getElementById('endCallButton').style.display = 'flex';
                            callingToast.hide();
                        });

                        document.getElementById('rejectCallButton').onclick = function() {
                            callingToast.hide();
                            call.close();
                        };

                        call.on('close', function() {
                            callingToast.hide();
                            showErrorToast('Chamada encerrada.');
                            document.getElementById('endCallButton').style.display = 'none';
                        });

                    } else {
                        showErrorToast('Dados do amigo não encontrado.');
                    }
                },
                error: function (jqXHR) {
                    const errorMessage = jqXHR.responseJSON ? jqXHR.responseJSON.error : 'Dados do amigo não encontrados.';
                    showErrorToast(errorMessage);
                }
            });
        });

        document.getElementById('endCallButton').onclick = function() {
            callingToast.hide();

            if (currentCall) {
                currentCall.close();
                currentCall = null;
                document.getElementById('endCallButton').style.display = 'none';
                showErrorToast('Chamada encerrada.');
            } else {
                document.getElementById('endCallButton').style.display = 'none';
                showErrorToast('Nenhuma chamada ativa para encerrar.');
            }
        };

        // Controlar volume e mute
        var muteButton = document.getElementById('muteButton');
        var isMuted = false;

        muteButton.addEventListener('click', function() {
            const icon = muteButton.querySelector('i');
            if (remoteAudioElement) {
                isMuted = !isMuted;
                remoteAudioElement.muted = isMuted;

                if (isMuted) {
                    icon.classList.remove('fa-microphone');
                    icon.classList.add('fa-microphone-slash');
                    icon.style.color = '#FF6347'; // Define a cor para '#FF6347' quando o microfone está mutado
                } else {
                    icon.classList.remove('fa-microphone-slash');
                    icon.classList.add('fa-microphone');
                    icon.style.color = 'white'; // Define a cor para 'white' quando o microfone está desmutado
                }
            }
        });
    }).catch(function(err) {
        showErrorToast('Failed to get local stream', err);
    });
} else {
    showErrorToast('Seu navegador não suporta a API getUserMedia.');
}

By the way, the user can establish a connection, I can hear and be heard, I can end the call, etc., the only problem is the mute/unmute, besides, am I using good practices in this code?

How could I close this navbar by clicking out of it?

`import './SideNavBar.scss';
import { useState } from 'react';
import { Cancel01Icon, Menu01Icon } from '../assets/icons';
import { Link } from 'react-router-dom';

const SideNavBar = () => {

const [isOpen, setIsOpen] = useState(false);

const toggleMenu = () => setIsOpen(!isOpen);

   return (
  <>
    <button className="menu-button" onClick={toggleMenu}>

     {isOpen ? <Cancel01Icon className='sideicon' /> : <Menu01Icon className='sideicon' />}

    </button>

  <nav className={`side-navbar ${isOpen ? 'open' : ''}`}>
    <ul className='side-navbar-ul'>
      <li className='side-navbar-li'><Link to={'/'}>Home</Link></li>
        <div className='line'></div>
      <li className='side-navbar-li'><Link to={'/loja'}>Loja</Link></li>
        <div className='line'></div>
      <li className='side-navbar-li'><Link to={'/galeria'}>Galeria</Link></li>
        <div className='line'></div>
      <li className='side-navbar-li'><Link to={'/contato'}>Contato</Link></li>
        <div className='line'></div>
      <li className='side-navbar-li'><a>Restrito</a></li>
        <div className='line'></div>
        
      

         </ul>
       </nav>
     </>

     )};

     export default SideNavBar;`

#How could I make this navbar close when I click in out of it, considering that this is a React app? I’ve seen somethings but it’s more like vanila js, I need to know how to do this in a React component, jsx

GraphJS mouse hover timezone

I’m working on building a status page for all of my microservices using graphjs (page available here), and when hovering over points of data the timezone is UTC, but I was hoping there’s a way to set it automatically based on the user’s timezone.

My config for the graphs is

          <script>
              new Chart(document.getElementById('chart-${index}'), {
                  type: 'line',
                  data: {
                      labels: ${JSON.stringify(labels)},
                      datasets: [{
                          label: 'Response Time',
                          data: ${JSON.stringify(datapoints)},
                          fill: true,
                          borderColor: '#43b581',
                          cubicInterpolationMode: 'monotone',
                          tension: 0.2,
                          pointBorderWidth: 0
                      }]
                  },
                  options: {
                      responsive: true,
                      maintainAspectRatio: false,
                      scales: {
                          x: {
                              display: false
                          },
                          y: {
                              beginAtZero: true
                          }
                      },
                      plugins: {
                          legend: {
                              display: false
                          }
                      }
                  }
              });
          </script>

InvalidKeySpecException In Java

I have a client (an Android app with Java) and a Node.js server. I want to generate a shared secret using the client’s and server’s Diffie-Hellman public keys.

The server and the client send their Diffie-Hellman public keys to each other over TCP (Transmission Control Protocol) so that they may generate a shared secret. When the server sends its public key to the client as a base64 string, I can successfully convert this string to bytes on the client-side.

The problem is that, when converting the bytes to a PublicKey instance on the marked Line 8, I get the error:

java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: DER length more than 4 bytes: 33

Here’s my Java code:

public boolean generateSharedSecret() throws Exception {
        byte[] serverDiffieHellmanPublicKey = receiveDiffieHellmanPublicKey();

        Log.e("String Length", String.valueOf(Base64.encodeToString(serverDiffieHellmanPublicKey, Base64.DEFAULT).length())); // Outputs 90.
        Log.e("Bytes Length", String.valueOf(serverDiffieHellmanPublicKey.length)); // Outputs 64.

        KeyFactory keyFactory = KeyFactory.getInstance("DH");
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(serverDiffieHellmanPublicKey); // Line 8
        PublicKey dhPublicKeyFromServer = keyFactory.generatePublic(x509EncodedKeySpec);

        // ...
}

public byte[] receiveDiffieHellmanPublicKey() {
    try {
        Socket socket = new Socket("185.255.95.248", 1211);
        InputStream inputStream = socket.getInputStream();

        byte[] buffer = new byte[1024];
        int bytesRead = inputStream.read(buffer);
        String keyString = new String(buffer, 0, bytesRead);
        return Base64.decode(keyString, Base64.DEFAULT);
    } catch (Exception ignore) {}

}

Here’s my Node.js code:

const net = require("net");
const crypto = require("crypto");
const dh = crypto.createDiffieHellman(512);
const serverDiffieHellman = crypto.generateDiffieHellman(dh.getPrime());

net.createServer((socket) => {
    socket.on("connect", () => socket.write(serverDiffieHellman.getPublicKey().toString("base64")));
}).listen(1211, "185.255.95.248", () => console.log("TCP server is running..."));

Any help will be pleasantly appreciated. Thanks, regards…

Firebase permission denied even when authenticated

I have a basic database with these rules

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid",
        ".read": "$uid === auth.uid"
      }
    }
  }
}

I try reading from the database path /users/+storageuid

const storageuid = localStorage.getItem("uid");
export const testCall = ()=>{
    
    const dbRef = ref(getDatabase());
    const path = "/users/"+storageuid;
    
    get(child(dbRef, path)).then((snaphot) => {
        if (snapshot.exists()) {
            console.log(snapshot);
        } else {

        }
    }).catch((error) => {
        console.log(error);
    });
}

Where storageuid is my authentication uid after google signin. I place it in localstorage.setItem(“uid”);
And I still get a permission denied..

EXIF.getData() function always returns an empty string and “undefined”

I’m developing a simple Chromium extension that reads EXIF data and shows to the user but in the library I’m using (which is Exif.js), I feel like there are things I’m not doing correctly because the output is always an empty string and undefined. Here’s the code:

const img = document.getElementById("someImage");

window.onload = getExif(img);

function getExif(file) {
    try {
        EXIF.getData(file, function () {
            if (file) {
                var make = EXIF.getTag(this, "Make");
                var model = EXIF.getTag(this, "Model");
                var allMetaData = EXIF.pretty(this);

                console.log(JSON.stringify(allMetaData, null, 2));
                console.log(make, model);
            } else {
                console.error("EXIF data has not been found or incomplete.");
            }
        });
    } catch (error) {
        console.error("Error reading EXIF data", error);
    }
}

“make” and “model” always returns an “undefined” from an image I’m using through classical const img = document.getElementById(someImage) in popup.html as well as allMetaData returning and empty string.

I’ve followed the “Usage” section in the documentation but nothing appears to be fixing this.

How to disable the automatic scroll of browser on back navigation

I have a Product Listing Page and Product Detail Page. The products in PLP are listed dynamically through graphql. The scenario is when a product is clicked on the PLP it takes me to PDP and when browser’s back button is clicked, it takes me back to PLP. Now, as we know browsers have default scroll set for back navigation to that part of the page till where it was last scrolled to. So, same is happening here, when I click on back button from PDP and it lands on PLP,the page is landed on the part where it was last scrolled to but in some cases where internet is slow and there is no html as data is dynamic, it slides to the bottom, i.e., footer and then it has to be manually scrolled to the product DOM. I tried to disable the automatic scroll for the PDP click scenario using the below code:

if ('scrollRestoration' in history) {
    history.scrollRestoration = 'auto';
}

This works if I run this directly without any condition. But for my case, I have added the Product Id of the product which is clicked on the page in Session Storage. So, I need to check that variable if it exists in session storage, if yes then only the above code will run. So, the getting of session storage takes time and browser already initiates the auto scroll. Below is the code:

if(!sessionStorage.getItem("productId")){
  if ('scrollRestoration' in history) {
      history.scrollRestoration = 'auto';
  }
}

Is there any way I can run this code first when the page is loading. I have tried document ready but also not working. Anything which can work just when page is landed, even before html is rendered?

Local storage doesn’t work on reload. Why?

I have a list of items that should be saved if they are open also an ‘active’ item that is currently previewed. Everything disappears on reload.


const Projects = () => {
    const [allProjectsOpen, setAllProjectsOpen] = useState(false);
    const [reactProjectsOpen, setReactProjectsOpen] = useState(false);
    const [angularProjectsOpen, setAngularProjectsOpen] = useState(false);
    const [openItems, setOpenItems] = useState([]);
    const [activeItem, setActiveItem] = useState(null);


    const projectItemsRef = useRef([
        {
            name: '_photo_portfolio',
            icon: <RiJavascriptFill className="w-6 h-6 text-custom-blue" />,
            type: 'react',
            component: PhotoPortfolio,
        },
        {
            name: '_angul_it',
            icon: <FaAngular className="w-6 h-6 text-custom-purple" />,
            type: 'angular',
            component: AngulIt,
        },
        {
            name: '_unknown_project',
            icon: <RiJavascriptFill className="w-6 h-6 text-custom-blue" />,
            type: 'react',
            component: UnknownProject,
        },
    ]);



    // Load state from localStorage
    useEffect(() => {
        const storedOpenItemNames = JSON.parse(localStorage.getItem('openItemNames')) || [];
        const storedActiveItemName = localStorage.getItem('activeItemName');

        const storedOpenItems = projectItemsRef.current.filter(item => storedOpenItemNames.includes(item.name));
        setOpenItems(storedOpenItems);
        setActiveItem(storedActiveItemName || null);
    }, []);


    // Save state to localStorage
    useEffect(() => {
        // Save state to localStorage when openItems or activeItem changes
        const openItemNames = openItems.map(item => item.name);
        localStorage.setItem('openItemNames', JSON.stringify(openItemNames));
        localStorage.setItem('activeItemName', activeItem);
    }, [openItems, activeItem]);



    // Add item to openItems
    const addItem = (item) => {
        setOpenItems((prevItems) => {
            // Prevent adding duplicates
            if (prevItems.some(prevItem => prevItem.name === item.name)) {
                return prevItems;
            }
            return [...prevItems, item]; // Add item to the openItems array
        });
        setActiveItem(item.name); // Set the newly added item as active
    };


    // Remove item from openItems
    const removeItem = (itemName) => {
        setOpenItems((prevItems) => prevItems.filter((prevItem) => prevItem.name !== itemName));
        if (activeItem === itemName) {
            setActiveItem(null); // Reset active item if it's removed
        }
    };

    return (
        <div>
            <div>
                <ItemList
                    items={openItems}
                    activeItem={activeItem}
                    setActiveItem={setActiveItem}
                    removeItem={removeItem} />
                <div>
                    {ActiveComponent && <ActiveComponent />}
                </div>
            </div>
        </div>
    );
};


I’m trying to save this to local storage so on reload it would have the list and the active item open. I can see it saves the items and active item to local storage but on reload everything disappears.

How to re-render only child component if parent child share same state variable in React

I have parent with multiple children, I want to only re-render selected children, not parent component over and over.

const ParentComp = () =>
{
    const [state1, setState1] = useState(0);
    const [state2, setState2] = useState(0);
    const [state3, setState3] = useState(0);
    // ... more children if needed

    // example: do something complex based on events
    //          and update states for desired component

    return(
        // ... parent stuff
        <ChildComp1 state=state1/>
        <ChildComp1 state=state2/>
        <ChildComp1 state=state3/>
        // ... parent stuff
    )
}

I can wrap children in memo and it will render selected child component but it will still re-render parent.

WordPress Elementor Content Protect PHP JS HTML

How can I add protected content to my page? I want to protect content to only one WordPress account role – for example Subscriber. I have my own HTML CSS and JS on WordPress. So I asked Claude.ai and it told me to use this in the functions.php file in Elementor Theme files:

function check_user_status() {
    $response = array(
        'loggedIn' => is_user_logged_in(),
        'username' => '',
        'isSubscriber' => false
    );
    if ($response['loggedIn']) {
        $current_user = wp_get_current_user();
        $response['username'] = $current_user->user_login;
        $response['isSubscriber'] = in_array('subscriber', $current_user->roles);
    }
    wp_send_json($response);
}
add_action('wp_ajax_check_user_status', 'check_user_status');
add_action('wp_ajax_nopriv_check_user_status', 'check_user_status');

And this Javascript:


    let currentUser = null;
    let isSubscriber = false;

    function checkUserStatus() {
        $.ajax({
            url: wpApiSettings.ajaxUrl,
            type: "POST",
            data: {
                action: "check_user_status",
                nonce: wpApiSettings.nonce,
            },
            success: function (response) {
                console.log("User status response:", response);
                if (response.loggedIn) {
                    currentUser = response.username;
                    isSubscriber = response.isSubscriber;
                } else {
                    currentUser = null;
                    isSubscriber = false;
                }
                updateAuthUI();
            },
            error: function (xhr, status, error) {
                console.error("Error checking user status:", error);
            },
        });
    }

    function updateAuthUI() {
        const authSection = $("#auth-section");
        const userInfo = $("#user-info");
        const usernameSpan = $("#username");
        const subscriberContent = $("#subscriber-content");

        if (currentUser) {
            authSection.find("#login-button, #register-button").hide();
            userInfo.show();
            usernameSpan.text(currentUser);

            if (isSubscriber) {
                subscriberContent.show();
            } else {
                subscriberContent.hide();
            }
        } else {
            authSection.find("#login-button, #register-button").show();
            userInfo.hide();
            subscriberContent.hide();
        }
    }

    $(document).on("click", "#logout-button", function (e) {
        e.preventDefault();
        window.location.href = wpApiSettings.logoutUrl;
    });


    checkUserStatus();


    setInterval(checkUserStatus, 60000);


    document.addEventListener("DOMContentLoaded", () => {
        setMealType("breakfast");
        populatePopularDishes();
        checkUserStatus();
    });

And this HTML:

<div id="auth-section">
    <button id="login-button">Zaloguj się</button>
    <button id="register-button">Zarejestruj się</button>
    <div id="user-info" style="display: none;">
        Witaj, <span id="username"></span>!
        <button id="logout-button">Wyloguj się</button>
    </div>
</div>

<div id="subscriber-content" style="display: none;">
    <h3>Zawartość dla subskrybentów</h3>
    <p>Ta treść jest widoczna tylko dla zalogowanych subskrybentów.</p>
</div>

But it didnt worked.
Actually I want to have specific DIV restrcited to role in WordPress Accounts.

I tried like every set up ai told me and no one worked.

How can const work at the end of the code? [duplicate]

How come the const styles can be declared and initialized after being used in the code (in the App function) since in javascript hoisting doesn’t exist for variables/constants ?

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.tsx to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Sinon sandboxes not stubbing functions in a controller in a express js app

I tried stubbing functions that were in a controller in an express app and when I called the controller function, assertions I wrote throws an error that the stubbed functions are not called or not called with the required arguments. Below is the test file. When I console.log(createUserStub) I get [Function: createUser]. Also, when I tried console.logging the newUser generated in the controller function, the result printed out shows that the actual internal function, createUser was called and not the stubbed function.

const sinon = require("sinon");
const sinonChai = require("sinon-chai");
const chai = require("chai");

chai.use(sinonChai);
const expect = chai.expect;

const authController = require("./../../src/controllers/auth");
const tokenService = require("./../../src/services/token.js");
const authService = require("./../../src/services/auth.js");

const { generatePassword } = require("./../../src/utils/auth.js");
const sendEmailModule = require("./../../src/utils/sendEmail.js");

describe("Signup Controller", () => {
  let res, req, createUserStub, generateTokenStub, sendEmailStub;
  let sandbox;

  const fakeHashedPassword = "fhfhgjkggklgj";
  const fakeId = "hjklkjhghjkjhghjkjh";
  const fakePictureUrl = "www.picture.com";
  const fakeToken = "rhjkljhghjkjhghj";

  const userInput = {
    name: "Emmanuel Ibekwe",
    email: "[email protected]",
    password: generatePassword(),
    picture: fakePictureUrl
  };

  const newUser = {
    _id: fakeId,
    name: "Emmanuel Ibekwe",
    email: "[email protected]",
    picture: fakePictureUrl
  };

  const fakeCreatedUser = {
    ...userInput,
    password: fakeHashedPassword,
    _id: fakeId
  };

  beforeEach(() => {
    sandbox = sinon.createSandbox();
    console.log("inside beforeEach");
    createUserStub = sandbox.stub(authService, "createUser");

    createUserStub.resolves(fakeCreatedUser);

    generateTokenStub = sandbox.stub(tokenService, "generateToken");
    generateTokenStub.resolves(fakeToken);

    sendEmailStub = sandbox.stub(sendEmailModule, "sendEmail").resolves();
  });

  afterEach(() => {
    console.log("inside afterEach");
    sandbox.restore();
  });

  it("should sign up user successfully", async done => {
    const statusJsonSpy = sandbox.spy();

    res = {
      json: sandbox.spy(),
      status: sandbox.stub().returns({ json: statusJsonSpy })
    };
    req = { body: userInput };

    const next = err => {
      console.log("err", err);
    };

    try {
      await authController.signup(req, res, next);

      // createUserStub();
      expect(createUserStub).to.have.been.calledOnce;
      expect(createUserStub).to.have.been.calledOnceWith(userInput);
      expect(generateTokenStub).to.have.been.calledTwice;
      expect(sendEmailStub).to.have.been.calledOnce;
      expect(res.status).to.have.been.calledOnceWith(201);
      expect(res.json).to.have.been.calledWith({
        message: "sign up successful",
        accessToken: fakeToken,
        refreshToken: fakeToken,
        user: newUser
      });

      done();
    } catch (error) {
      done(error);
    }
  }); //
});

This is the controller

const { createUser, signInUser } = require("./../services/auth.js");
const { generateToken, verifyToken } = require("./../services/token.js");
const createHttpError = require("http-errors");
const User = require("./../models/user.js");
const { sendEmail } = require("./../utils/sendEmail.js");
const PasswordResetCode = require("./../models/PasswordResetCode.js");
const bcryptjs = require("bcryptjs");
const { isPasswordFalse } = require("../utils/validation.js");
const { getRandomSixDigit, generatePassword } = require("./../utils/auth.js");
const dotenv = require("dotenv");
const { OAuth2Client } = require("google-auth-library");

dotenv.config();

const {
  ADMIN_EMAIL,
  FRONT_END_TESTING_DOMAIN,
  FRONT_END_PRODUCTION_DOMAIN
} = process.env;

const signup = async (req, res, next) => {
  try {
    const { name, email, password, picture } = req.body;
    console.log("req.body", { name, email, password, picture });
    const newUser = await createUser({
      name,
      email,
      password,
      picture
    });
    console.log("newUser", newUser);

    const accessToken = await generateToken(
      {
        userId: newUser._id.toString(),
        email: newUser.email
      },
      "1d",
      process.env.ACCESS_TOKEN_SECRET
    );
    console.log("accessToken", accessToken);

    const refreshToken = await generateToken(
      {
        userId: newUser._id.toString(),
        email: newUser.email
      },
      "30d",
      process.env.REFRESH_TOKEN_SECRET
    );

    await sendEmail({
      code: null,
      to: newUser.email,
      subject: "Trackr Sign up",
      name: newUser.name.split(" ")[0],
      type: "sign up"
    });

    console.log(201);

    res.status(201).json({
      message: "sign up successful",
      accessToken,
      refreshToken,
      user: {
        _id: newUser._id,
        name: newUser.name,
        email: newUser.email,
        picture: newUser.picture
      }
    });
  } catch (error) {
    if (!error.status) {
      error.status = 500;
    }
    next(error);
  }
};

Here are the codes of the internal functions.

const createHttpError = require("http-errors");
const validator = require("validator");
const bcryptjs = require("bcryptjs");
const User = require("../models/user.js");
const validation = require("./../utils/validation.js");
const { isPasswordFalse } = validation;

const createUser = async userData => {
  const { name, email, password, picture } = userData;
  // console.log("userData", userData);
  if (!name || !email || !password) {
    throw createHttpError.BadRequest("Please fill all fields");
  }

  // console.log("name", name);
  if (!validator.isEmail(email)) {
    throw createHttpError.BadRequest("email is invalid");
  }

  const checkEmail = await User.findOne({ email: email });

  if (checkEmail) {
    throw createHttpError.Conflict("email already exists. Try a new email.");
  }

  if (isPasswordFalse(password)) {
    throw createHttpError.BadRequest(
      "password must be atleast 8 characters and contain atleast an uppercase, a lowercase, a number or a special character"
    );
  }

  const hashedPassword = await bcryptjs.hash(password, 12);
  // console.log("hashedPassword", hashedPassword);
  const user = await new User({
    name,
    email,
    password: hashedPassword,
    picture: picture || DEFAULT_PICTURE_URL
  });

  return user.save();
};


const tokenUtils = require("./../utils/token.js");
const { sign, verify } = tokenUtils;

const generateToken = async (payload, expiresIn, secret) => {
  const token = await sign(payload, expiresIn, secret);
  return token;
};

I tried testing just the createUser function and all tests were passed. Here is the test file.

const mongoose = require("mongoose");
const sinon = require("sinon");
const sinonChai = require("sinon-chai");
const chai = require("chai");

chai.use(sinonChai);
const expect = chai.expect;

const authService = require("../../src/services/auth.js");
const bcryptjs = require("bcryptjs");
const User = require("../../src/models/user");
const { generatePassword } = require("../../src/utils/auth");

describe("createUser Service", () => {
  let hashStub, findOneStub, saveStub, sandbox;
  const fakeHashedPassword = "fhfhgjkggklgj";
  const fakeId = "hjklkjhghjkjhghjkjh";
  const fakePictureUrl = "www.picture.com";

  const userInput = {
    name: "Emmanuel Ibekwe",
    email: "[email protected]",
    password: generatePassword(),
    picture: fakePictureUrl
  };

  const fakeCreatedUser = {
    ...userInput,
    password: fakeHashedPassword,
    _id: fakeId
  };

  beforeEach(() => {
    sandbox = sinon.createSandbox();
    hashStub = sandbox.stub(bcryptjs, "hash");
    findOneStub = sandbox.stub(mongoose.Model, "findOne");

    saveStub = sandbox.stub(User.prototype, "save");

    hashStub.resolves(fakeHashedPassword);
    findOneStub.resolves(null);

    saveStub.resolves(fakeCreatedUser);
  });
  afterEach(() => {
    sandbox.restore();
  });

  it("should return a newly created user", async () => {
    newUser = await authService.createUser(userInput);

    expect(newUser).to.deep.equal(fakeCreatedUser);
  });

  it("should throw a BadRequest error if name is not provided", async () => {
    try {
      await authService.createUser({ ...userInput, name: undefined });
    } catch (err) {
      //   console.log(err);
      expect(err.status).to.equal(400);
      expect(err.message).to.equal("Please fill all fields");
    }
  });

  it("should throw a BadRequest error if email is invalid", async () => {
    try {
      await authService.createUser({ ...userInput, email: "undefined" });
    } catch (err) {
      //   console.log(err);
      expect(err.status).to.equal(400);
      expect(err.message).to.equal("email is invalid");
    }
  });

  it("should throw a BadRequest error if email is not provided", async () => {
    try {
      await authService.createUser({ ...userInput, email: undefined });
    } catch (err) {
      //   console.log(err);
      expect(err.status).to.equal(400);
      expect(err.message).to.equal("Please fill all fields");
    }
  });

  it("should throw a Conflict error if user already exists", async () => {
    try {
      await authService.createUser({ ...userInput, password: "hhfjdkdlflf" });
    } catch (err) {
      //   console.log(err);
      expect(err.status).to.equal(400);
      expect(err.message).to.equal(
        "password must be atleast 8 characters and contain atleast an uppercase, a lowercase, a number or a special character"
      );
    }
  });

  it("should throw a BadRequest error if password does not meet the required conditions", async () => {
    findOneStub.resolves(fakeCreatedUser);
    try {
      await authService.createUser(userInput);
    } catch (err) {
      expect(err.status).to.equal(409);
      expect(err.message).to.equal("email already exists. Try a new email.");
    }
  });
});