const { connect } = require('getstream');
const bcrypt = require('bcrypt');
const StreamChat = require('stream-chat').StreamChat;
const crypto = require('crypto');
require('dotenv').config();
const api_key = process.env.STREAM_API_KEY;
const api_secret = process.env.STREAM_API_SECRET;
const app_id = process.env.STREAM_APP_ID;
const login = async (req, res) => {
try {
const { fullName, username, password, phoneNumber } = req.body;
const userId = crypto.randomBytes(16).toString('hex');
const serverClient = connect(api_key, api_secret, app_id);
const hashedPassword = await bcrypt.hash(password, 10);
const token = serverClient.createUserToken(userId);
res.status(200).json({ token, fullName, username, userId, hashedPassword, phoneNumber });
} catch (error) {
console.log(error);
res.status(500).json({ message: error});
const signup = async (req, res) => {
try {
const { username, password } = req.body;
const serverClient = connect(api_key, api_secret, app_id);
const client = StreamChat.getInstance(api_key, api_secret);
const { users } = await client.queryUsers({ name: username });
if(!users.length) return res.status(400).json({ message: 'User not found' });
const success = await bcrypt.compare(password, users[0].hashedPassword);
const token = serverClient.createUserToken(users[0].id);
if(success) {
res.status(200).json({ token, fullName: users[0].fullName, username, userId: users[0].id });
} else {
res.status(500).json({ message: 'Incorrect Password' });
} catch (error) {
console.log(error);
res.status(500).json({ message: error});
module.exports = { signup, login }
This is the auth.jsx file in my client side:
import React, { useState } from 'react';
import Cookies from 'universal-cookie';
import axios from 'axios';
import signinImage from '../assets/signup.jpg';
const cookies = new Cookies();
const initialState = {
fullName: '',
username: '',
password: '',
confirmPassword: '',
phoneNumber: '',
avatarURL: '',
const Auth = () => {
const [form, setForm] = useState(initialState);
const [isSignup, setIsSignup] = useState(true);
const handleChange = async (e) => {
setForm({ ...form, [e.target.name]: e.target.value });
const handleSubmit = async (e) => {
e.preventDefault();
const { fullName, username, password, phoneNumber, avatarURL } = form;
const URL = 'https://localhost:5000/auth';
const { data: { token, userId, hashedPassword } } = await axios.post(`${URL}/${isSignup ? 'signup' : 'login'}`, {
username, password, fullName, phoneNumber, avatarURL
cookies.set('token', token);
cookies.set('username', username);
cookies.set('fullName', fullName);
cookies.set('userId', userId);
if(isSignup) {
cookies.set('phoneNumber', phoneNumber);
cookies.set('avatarURL', avatarURL);
cookies.set('hashedPassword', hashedPassword);
window.location.reload();
const switchMode = () => {
setIsSignup((prevIsSignup) => !prevIsSignup)
return (
<div className='auth__form-container'>
<div className='auth__form-container_fields'>
<div className='auth__form-container_fields-content'>
<p>{isSignup ? 'Sign Up' : 'Sign In'}</p>
<form onSubmit={handleSubmit}>
{isSignup && (
<div className='auth__form-container_fields-content_input'>
<label htmlFor='fullName'>Full Name</label>
<input
name='fullName'
type='text'
placeholder='Full Name'
onChange={handleChange}
required
<div className='auth__form-container_fields-content_input'>
<label htmlFor='username'>Username</label>
<input
name='username'
type='text'
placeholder='Username'
onChange={handleChange}
required
{isSignup && (
<div className='auth__form-container_fields-content_input'>
<label htmlFor='phoneNumber'>Phone Number</label>
<input
name='phoneNumber'
type='text'
placeholder='Phone Number'
onChange={handleChange}
required
{isSignup && (
<div className='auth__form-container_fields-content_input'>
<label htmlFor='avatarURL'>Avatar URL</label>
<input
name='avatarURL'
type='text'
placeholder='Avatar URL'
onChange={handleChange}
required
<div className='auth__form-container_fields-content_input'>
<label htmlFor='password'>Password</label>
<input
name='password'
type='password'
placeholder='Password'
onChange={handleChange}
required
{isSignup && (
<div className='auth__form-container_fields-content_input'>
<label htmlFor='confirmPassword'>Confirm Password</label>
<input
name='confirmPassword'
type='password'
placeholder='Confirm Password'
onChange={handleChange}
required
<div className='auth__form-container_fields-content_button'>
<button>{isSignup ? 'Sign Up' : 'Sign In'}</button>
</form>
<div className='auth__form-container_fields-account'>
{isSignup
? "Already have an account? "
: "Don't have an account? "
<span onClick={switchMode}>
{isSignup ? 'Sign In' : 'Sign Up'}
</span>
<div className='auth__form-container_image'>
<img src={signinImage} alt='sign in'/>
export default Auth
And this is the index.js code in my server folder:
const express = require('express');
const cors = require('cors');
const authRoutes = require("./routes/auth.js");
const app = express();
const PORT = process.env.PORT || 5000;
require('dotenv').config();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded());
app.get('/', (req, res) => {
res.send('Hello, World!');
app.use('/auth', authRoutes);
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
I followed everything the tutorial says, but he didn't encounter such problem like mine. I'm not very knowledgeable in debugging, so... any help?
Convert the password to a string before passing it as a parameter to the bcrypt.hash function
const hashedPassword = await bcrypt.hash(password.toString(), 10)
@akere-code thanks for reaching out. I suggest you following the solution from the tutorial's repo
It's been a while, therefore I'll be closing this issue for now.
Please don't hesitate to contact us in the future if this issue or any questions arise.