Skip to content

Commit

Permalink
Work in progress: authentication APIs ⚒
Browse files Browse the repository at this point in the history
  • Loading branch information
DineshRout779 committed Jun 27, 2023
1 parent 090e9a6 commit 9189bb6
Show file tree
Hide file tree
Showing 9 changed files with 2,166 additions and 0 deletions.
130 changes: 130 additions & 0 deletions server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
33 changes: 33 additions & 0 deletions server/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Import packages
const dotenv = require('dotenv');
const express = require('express');
const cors = require('cors');
const connectDB = require('./config/db');
const authRoutes = require('./routes/auth');

// configure environment variables
dotenv.config();

// Express Instance
const app = express();
const port = process.env.PORT || 5000;

// Set up middlewares
app.use(express.json());
app.use(cors());

// Database connection
connectDB();

// routes
app.get('/api/v1', (req, res) => {
return res.status(200).json({
status: true,
message: 'Welcome to the API',
});
});
app.use('/api/v1/auth', authRoutes);

app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
15 changes: 15 additions & 0 deletions server/config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const mongoose = require('mongoose');

const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
if (conn) console.log('MongoDB Connected');
} catch (err) {
console.log(err);
}
};

module.exports = connectDB;
77 changes: 77 additions & 0 deletions server/controllers/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const bcrypt = require('bcrypt');
const generateToken = require('../helpers/generateToken');
const User = require('../models/User');

exports.signup = async (req, res) => {
try {
const { username, email, password } = req.body;

// Check if the email already exists
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(400).json({
status: false,
message: 'Username already exists',
});
}

// Hash the password
const hashedPassword = await bcrypt.hash(password, 10);

// Create a new user
const newUser = new User({ username, email, password: hashedPassword });
await newUser.save();

// Generate and send JWT token
const token = generateToken(newUser);
return res.status(201).json({
token,
status: true,
message: 'Successfully signed up!',
});
} catch (error) {
console.log(error);
res.status(500).json({
status: false,
error: error.message,
message: 'Internal server error',
});
}
};

exports.login = async (req, res) => {
try {
const { email, password } = req.body;

// find the user
const user = await User.findOne({ email });

// if no user exists
if (!user) {
return res.status(401).json({
status: false,
message: `User doesn't exists!`,
});
}

// Compare passwords
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
return res.status(401).json({
status: false,
message: 'Invalid credentials',
});
}

// Generate and send JWT token
const token = generateToken(user);
res.json({ token });
} catch (error) {
console.log(error);
return res.status(500).json({
status: false,
message: `Internal server error`,
error,
});
}
};
13 changes: 13 additions & 0 deletions server/helpers/generateToken.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const jwt = require('jsonwebtoken');

// Generate JWT token
function generateToken(user) {
const payload = {
id: user._id,
username: user.username,
};

return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1d' });
}

module.exports = generateToken;
24 changes: 24 additions & 0 deletions server/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const mongoose = require('mongoose');

const userSchema = new mongoose.Schema(
{
username: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
},
{ timestamps: true }
);

// Create a user model
const User = mongoose.model('User', userSchema);

module.exports = User;
Loading

0 comments on commit 9189bb6

Please sign in to comment.