Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .env
Empty file.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules
5 changes: 5 additions & 0 deletions nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"watch":["src"],
"ext":".ts, .js",
"exec" : "ts-node ./src/app.ts"
}
1,743 changes: 1,743 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "backenddevelopmentapplications",
"version": "1.0.0",
"description": "this assignment by zigy",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon"
},
"author": "Sahil Sayyad",
"license": "ISC",
"devDependencies": {
"@types/body-parser": "^1.19.3",
"@types/compression": "^1.7.3",
"@types/cookie-parser": "^1.4.4",
"@types/cors": "^2.8.14",
"@types/express": "^4.17.18",
"@types/mongoose": "^5.11.97",
"nodemon": "^3.0.1",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
},
"dependencies": {
"body-parser": "^1.20.2",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"crypto": "^1.0.1",
"express": "^4.18.2",
"mongoose": "^7.5.3"
}
}
25 changes: 25 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import express from "express";
import http from "http";
import bodyParser from "body-parser";
import cookieParser from "cookie-parser";
import compression from "compression";
import cors from "cors";
import connectDb from "./config/mongoose";
import routes from "./routes";
connectDb();

const app = express();
const port = process.env.PORT || 8080;
app.use(cors({
credentials:true,
}));

app.use(compression());
app.use(cookieParser());
app.use(bodyParser.json());
app.use('/', routes());

const server = http.createServer(app);
server.listen(port, ()=>{
console.log(`Server is running on port ${port}`);
});
12 changes: 12 additions & 0 deletions src/config/mongoose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import mongoose from "mongoose";
const connectDb = async () => {
try {
const MOGNO_URL = "";
await mongoose.connect(MOGNO_URL);
console.log(`MongoDb connected`);
} catch (error) {
console.log(error);
process.exit(1);
}
};
export default connectDb;
62 changes: 62 additions & 0 deletions src/controllers/authentication.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import express from "express";
import { getUserByEmail, createUser } from "../models/user";
import { random, authentication } from "../helpers";

export const login = async (req: express.Request, res: express.Response) => {
try {
const { email, password } = req.body;

if (!email || !password) {
return res.sendStatus(400);
}

const user = await getUserByEmail(email).select('+authentication.salt +authentication.password');

if (!user) {
return res.sendStatus(400);
}

const expectedHash = authentication(user.authentication.salt, password);

if (user.authentication.password != expectedHash) {
return res.sendStatus(403);
}

const salt = random();
user.authentication.sessionToken = authentication(salt, user._id.toString());

await user.save();

res.cookie('SAHIL-AUTH', user.authentication.sessionToken, { domain: 'localhost', path: '/' });

return res.status(200).json(user).end();
} catch (error) {
console.log(error);
return res.sendStatus(400);
}
};
export const register = async (req: express.Request, res: express.Response) => {
try {
const { email, password, username } = req.body;
if (!email || !password || !username) {
return res.sendStatus(400);
}
const existingUser = await getUserByEmail(email);
if (existingUser) {
return res.sendStatus(400);
}
const salt = random();
const user = await createUser({
email,
username,
authentication: {
salt,
password: authentication(salt, password),
},
});
return res.status(200).json(user).end();
} catch (error) {
console.log(error);
return res.sendStatus(400);
}
}
7 changes: 7 additions & 0 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import crypto from 'crypto';

const SECRET = 'sahil';
export const random = () => crypto.randomBytes(128).toString('base64');
export const authentication = (salt: string, password: string) => {
return crypto.createHmac('sha256', [salt, password].join('/')).update(SECRET).digest('hex');
}
24 changes: 24 additions & 0 deletions src/models/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import mongoose from "mongoose";

const userSchema = new mongoose.Schema({
username:{type:String, required:true},
email:{type:String, required:true, unique:true},
authentication:{
password:{type:String, required:true, select:false},
salt:{type:String, select:false},
sessionToken:{type:String , select:false},
}
});

export const UserModel = mongoose.model("User", userSchema);

export const getUsers = ()=> UserModel.find();
export const getUserByEmail = (email:string)=> UserModel.findOne({email});
export const getUserBySessionToken = (sessionToken:string) => UserModel.findOne({
"authentication.sessionToken": sessionToken,
});
export const getUserById = (id:string)=> UserModel.findById(id);
export const createUser = (values:Record<string,any>) => new UserModel(values)
.save().then((user)=> user.toObject());
export const deleteUserById = (id:string)=> UserModel.findOneAndDelete({_id:id});
// export const updateUserById = (values:Record<string,any>) => UserModel.findByIdAndUpdate(id,values);
8 changes: 8 additions & 0 deletions src/routes/authentication.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from "express";

import { login, register } from "../controllers/authentication";

export default (router:express.Router)=>{
router.post('/auth/register', register);
router.post('/auth/login', login);
};
9 changes: 9 additions & 0 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import express from 'express';
import authentication from './authentication';

const router = express.Router();

export default (): express.Router =>{
authentication(router);
return router;
}
11 changes: 11 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "node",
"baseUrl": "src",
"outDir": "dist",
"sourceMap": true,
"noImplicitAny": true,
},
"include": ["src/**/*"],
}