login and sign up
parent
0789dcdf1c
commit
be88a7ff28
4
index.ts
4
index.ts
|
@ -30,12 +30,12 @@ const options = {
|
||||||
|
|
||||||
servers: [
|
servers: [
|
||||||
{
|
{
|
||||||
url: "http://localhost:3000",
|
url: "http://localhost:3000/api/v1",
|
||||||
//description: "PartyApp API Documentation",
|
//description: "PartyApp API Documentation",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
apis: ["./src/routes/api/v1/router/*.ts"],
|
apis: ["./src/routes/*.ts"],
|
||||||
};
|
};
|
||||||
|
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
|
|
|
@ -1,33 +1,92 @@
|
||||||
import { Request } from "express";
|
import { Request, Response } from "express";
|
||||||
import bcrypt from "bcrypt";
|
import bcrypt from "bcrypt";
|
||||||
import { User } from "../models/user";
|
import { User } from "../models/user";
|
||||||
|
import crypto from "crypto";
|
||||||
|
import { Session } from "../models/session";
|
||||||
|
|
||||||
export async function SignUp(req: Request, res: any) {
|
export async function SignUp(req: Request, res: Response) {
|
||||||
if (!req.body.accountName || !req.body.username || !req.body.password) {
|
if (!req.body.accountName || !req.body.username || !req.body.password) {
|
||||||
res.status(400).json({ error: "invalid body" });
|
return res.status(400).json({ status: "err" });
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const decodedPassword = Buffer.from(req.body.password, "base64").toString(
|
const { accountName, username, password } = req.body;
|
||||||
"utf-8"
|
|
||||||
);
|
const existingUser = await User.findOne({ accountName });
|
||||||
|
|
||||||
|
if (existingUser) {
|
||||||
|
return res.status(400).json({ status: "err" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const isBase64Password =
|
||||||
|
/^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$/.test(
|
||||||
|
password
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isBase64Password) {
|
||||||
|
return res.status(400).json({ status: "err" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const decodedPassword = Buffer.from(password, "base64").toString("utf-8");
|
||||||
|
|
||||||
const hashedPassword = await bcrypt.hash(decodedPassword, 10);
|
const hashedPassword = await bcrypt.hash(decodedPassword, 10);
|
||||||
|
|
||||||
const user = new User({
|
const user = new User({
|
||||||
accountName: req.body.accountName,
|
accountName: accountName,
|
||||||
username: req.body.username,
|
username: username,
|
||||||
password: hashedPassword,
|
password: hashedPassword,
|
||||||
});
|
});
|
||||||
|
|
||||||
user
|
user
|
||||||
.save()
|
.save()
|
||||||
.then(() => {
|
.then(() => res.status(200).json({ status: "ok" }))
|
||||||
console.log("test");
|
|
||||||
res.status(200).json({ status: "ok" });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
res.status(500).json({ status: "err" });
|
res.status(500).json({ status: "err" });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function Login(req: Request, res: Response) {
|
||||||
|
try {
|
||||||
|
if (!req.body.accountName || !req.body.password) {
|
||||||
|
return res.status(400).json({ status: "err" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { accountName, password } = req.body;
|
||||||
|
|
||||||
|
const user = await User.findOne({ accountName });
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return res.status(401).json({ status: "err" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.password === undefined || user.password === null) {
|
||||||
|
return res.status(401).json({ status: "err" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const decodedPassword = Buffer.from(password, "base64").toString("utf-8");
|
||||||
|
|
||||||
|
const isPasswordValid = await bcrypt.compare(
|
||||||
|
decodedPassword,
|
||||||
|
user.password
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isPasswordValid) {
|
||||||
|
return res.status(401).json({ status: "err" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionId = crypto.randomBytes(32).toString("hex");
|
||||||
|
|
||||||
|
const session = new Session({
|
||||||
|
sessionId: sessionId,
|
||||||
|
accountName: user.accountName,
|
||||||
|
});
|
||||||
|
|
||||||
|
session
|
||||||
|
.save()
|
||||||
|
.then(() => res.status(200).json({ sessionId }))
|
||||||
|
.catch(() => res.status(500).json({ status: "err" }));
|
||||||
|
} catch (error) {
|
||||||
|
console.error("error on login:", error);
|
||||||
|
res.status(500).json({ status: "err" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import mongoose, { InferSchemaType, Schema } from "mongoose";
|
||||||
|
|
||||||
|
export const sessionSchema = new Schema({
|
||||||
|
sessionId: String,
|
||||||
|
accountName: String,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Session = InferSchemaType<typeof sessionSchema>;
|
||||||
|
|
||||||
|
export const Session = mongoose.model<Session>("Session", sessionSchema);
|
|
@ -4,58 +4,126 @@ import * as userController from "../controllers/userController";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* components:
|
* tags:
|
||||||
* schemas:
|
* name: users
|
||||||
* Post:
|
* description: User-related operations
|
||||||
* type: object
|
|
||||||
* required:
|
|
||||||
* - userId
|
|
||||||
* - title
|
|
||||||
* - body
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* description: The Auto-generated id of a post
|
|
||||||
* userId:
|
|
||||||
* type: integer
|
|
||||||
* description: id of author
|
|
||||||
* title:
|
|
||||||
* type: string
|
|
||||||
* description: title of post
|
|
||||||
* body:
|
|
||||||
* type: string
|
|
||||||
* descripton: content of post *
|
|
||||||
* example:
|
|
||||||
* id: 1
|
|
||||||
* userId: 1
|
|
||||||
* title: my title
|
|
||||||
* body: my article
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* tags:
|
* /signup:
|
||||||
* name: Posts
|
* post:
|
||||||
* description: posts of users
|
* summary: Sign up a new user
|
||||||
*/
|
* description: Create a new user account with accountName, username, and password
|
||||||
|
* tags:
|
||||||
/**
|
* - users
|
||||||
* @swagger
|
* requestBody:
|
||||||
* /posts:
|
* required: true
|
||||||
* get:
|
* content:
|
||||||
* summary: Returns all posts
|
* application/json:
|
||||||
* tags: [Posts]
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* accountName:
|
||||||
|
* type: string
|
||||||
|
* username:
|
||||||
|
* type: string
|
||||||
|
* password:
|
||||||
|
* type: string
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: the list of the posts
|
* description: Successful user registration
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* type: array
|
* type: object
|
||||||
* items:
|
* properties:
|
||||||
* $ref: '#/components/schemas/Post'
|
* status:
|
||||||
|
* type: string
|
||||||
|
* example: 'ok'
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body or account already exists
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* example: 'err'
|
||||||
|
* 500:
|
||||||
|
* description: Internal server error
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* example: 'err'
|
||||||
*/
|
*/
|
||||||
router.post("/user/signup", userController.SignUp);
|
router.post("/user/signup", userController.SignUp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /user/login:
|
||||||
|
* post:
|
||||||
|
* summary: Log in a user
|
||||||
|
* description: Log in a user by checking accountName and password
|
||||||
|
* tags:
|
||||||
|
* - users
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* accountName:
|
||||||
|
* type: string
|
||||||
|
* password:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Successful login
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* sessionId:
|
||||||
|
* type: string
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* example: 'err'
|
||||||
|
* 401:
|
||||||
|
* description: Authentication failed
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* example: 'err'
|
||||||
|
* 500:
|
||||||
|
* description: Internal server error
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* example: 'err'
|
||||||
|
*/
|
||||||
|
router.post("/user/login", userController.Login);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
Reference in New Issue