forked from fr/deguapp
Added: tests, signin api, not working docker
This commit is contained in:
parent
dc1b955a8a
commit
bd8a5d607f
23
api/Dockerfile
Normal file
23
api/Dockerfile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
FROM node:18-alpine
|
||||||
|
|
||||||
|
WORKDIR /nork
|
||||||
|
|
||||||
|
COPY ../../nork .
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
RUN npm link
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD ["npm", "start"]
|
19
api/docker-compose.yaml
Normal file
19
api/docker-compose.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
services:
|
||||||
|
mongo:
|
||||||
|
image: mongo
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
MONGO_INITDB_ROOT_USERNAME: root
|
||||||
|
MONGO_INITDB_ROOT_PASSWORD: root
|
||||||
|
ports:
|
||||||
|
- 27017:27017
|
||||||
|
mongo-express:
|
||||||
|
image: mongo-express
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 8081:8081
|
||||||
|
environment:
|
||||||
|
ME_CONFIG_MONGODB_ADMINUSERNAME: root
|
||||||
|
ME_CONFIG_MONGODB_ADMINPASSWORD: root
|
||||||
|
ME_CONFIG_MONGODB_URL: mongodb://root:root@mongo:27017/
|
||||||
|
ME_CONFIG_BASICAUTH: false
|
@ -19,22 +19,29 @@
|
|||||||
"author": "Filip Rojek",
|
"author": "Filip Rojek",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bcrypt": "^5.1.1",
|
||||||
"colors": "1.4.0",
|
"colors": "1.4.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"inquirer": "^8.1.2",
|
"inquirer": "^8.1.2",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"mongoose": "^8.3.3",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"pad": "^3.2.0",
|
"pad": "^3.2.0",
|
||||||
"path": "^0.12.7"
|
"path": "^0.12.7",
|
||||||
|
"yup": "^1.4.0",
|
||||||
|
"yup-password": "^0.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.7.1",
|
"@biomejs/biome": "1.7.1",
|
||||||
|
"@types/bcrypt": "^5.0.2",
|
||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/fs-extra": "^9.0.13",
|
"@types/fs-extra": "^9.0.13",
|
||||||
"@types/inquirer": "^8.1.3",
|
"@types/inquirer": "^8.1.3",
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
|
"@types/jsonwebtoken": "^9.0.6",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/morgan": "^1.9.9",
|
"@types/morgan": "^1.9.9",
|
||||||
"@types/shelljs": "^0.8.11",
|
"@types/shelljs": "^0.8.11",
|
||||||
@ -46,6 +53,7 @@
|
|||||||
"http": "^0.0.1-security",
|
"http": "^0.0.1-security",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"mocha": "^9.1.3",
|
"mocha": "^9.1.3",
|
||||||
|
"mongodb-memory-server": "^9.2.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
|
@ -1,5 +1,81 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from 'express';
|
||||||
|
import bcrypt from 'bcrypt';
|
||||||
|
import jwt from 'jsonwebtoken';
|
||||||
|
import env from '../config/environment';
|
||||||
|
import Docs from '../services/docsService';
|
||||||
|
import User from '../models/User';
|
||||||
|
import {Log} from 'nork'
|
||||||
|
import { IUser, signupExam, ISignin, signinExam } from '../validators/authValidator';
|
||||||
|
|
||||||
export function signup_post(req: Request, res: Response) {
|
new Docs('user', 'signup', '/api/v1/auth/signup', 'POST', 'user signup api', undefined, signupExam, 'status object');
|
||||||
res.send("logged in");
|
export async function signup_post(req: Request, res: Response) {
|
||||||
|
try {
|
||||||
|
const payload: IUser = req.body;
|
||||||
|
|
||||||
|
payload.password = await bcrypt.hash(payload.password, 12);
|
||||||
|
const user = new User(payload);
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
res.status(201).json(Log.info(201, 'user was successfully signed up'));
|
||||||
|
} catch (err: any) {
|
||||||
|
if (err.code == 11000) {
|
||||||
|
res.status(400).json(Log.error(400, 'this user already exists'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.error(500, err);
|
||||||
|
res.status(500).json(Log.error(500, 'something went wrong'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new Docs('user', 'signin', '/api/v1/auth/signin', 'POST', 'user signin api', undefined, signinExam, 'status object');
|
||||||
|
export async function signin_post(req: Request, res: Response) {
|
||||||
|
try {
|
||||||
|
const payload: ISignin = req.body;
|
||||||
|
|
||||||
|
const user = await User.findOne({ email: payload.email });
|
||||||
|
if (!user) {
|
||||||
|
res.cookie('jwt', '', { httpOnly: true, maxAge: 0 });
|
||||||
|
res.cookie('auth', false, { httpOnly: false, maxAge: 0 });
|
||||||
|
res.status(401).json(Log.error(401, 'email or password is wrong'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await bcrypt.compare(payload.password, user.password)) {
|
||||||
|
const maxAge = 3 * 24 * 60 * 60; // 3 days in seconds
|
||||||
|
const createToken = (id: any) => {
|
||||||
|
return jwt.sign({ id }, env.JWT_SECRET, {
|
||||||
|
expiresIn: maxAge
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const token = createToken(user._id);
|
||||||
|
res.cookie('jwt', token, { httpOnly: true, maxAge: maxAge * 1000 });
|
||||||
|
res.cookie('auth', true, { httpOnly: false, maxAge: maxAge * 1000 });
|
||||||
|
|
||||||
|
res.json(Log.info(200, 'user is logged in'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.cookie('jwt', '', { httpOnly: true, maxAge: 0 });
|
||||||
|
res.cookie('auth', false, { httpOnly: false, maxAge: 0 });
|
||||||
|
res.status(401).json(Log.error(401, 'email or password is wrong'));
|
||||||
|
} catch (err: any) {
|
||||||
|
Log.error(500, err);
|
||||||
|
res.status(500).json(Log.error(500, 'something went wrong'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new Docs('user', 'logout', '/api/v1/auth/logout', 'POST', 'user logout api', undefined, {}, 'status object');
|
||||||
|
export function logout_post(req: Request, res: Response) {
|
||||||
|
res.cookie('jwt', '', { httpOnly: true, maxAge: 0 });
|
||||||
|
res.cookie('auth', false, { httpOnly: false, maxAge: 0 });
|
||||||
|
res.json(Log.info(200, 'user was logged out'));
|
||||||
|
}
|
||||||
|
|
||||||
|
new Docs('user', 'status', '/api/v1/auth/status', 'GET', 'user login status api', undefined, undefined, 'status code | user object');
|
||||||
|
export function status_get(req: Request, res: Response) {
|
||||||
|
let userObject = res.locals.user;
|
||||||
|
userObject.password = undefined;
|
||||||
|
userObject.__v = undefined;
|
||||||
|
res.status(200).json(Log.info(200, 'user is logged in', userObject));
|
||||||
|
}
|
15
api/src/middlewares/validateRequest.ts
Normal file
15
api/src/middlewares/validateRequest.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
import { object, AnySchema } from 'yup';
|
||||||
|
import { Log } from 'nork';
|
||||||
|
|
||||||
|
const validate = (schema: AnySchema) => async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
await schema.validate(req.body);
|
||||||
|
|
||||||
|
next();
|
||||||
|
} catch (err: any) {
|
||||||
|
return res.status(400).json(Log.error(400, 'validation error', err));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default validate;
|
26
api/src/models/User.ts
Normal file
26
api/src/models/User.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { Schema, model } from 'mongoose';
|
||||||
|
import { IUser } from '../validators/authValidator';
|
||||||
|
|
||||||
|
const schema = new Schema<IUser>(
|
||||||
|
{
|
||||||
|
username: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default model(path.basename(__filename).split('.')[0], schema);
|
@ -1,6 +1,7 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import * as authController from "../controllers/authController";
|
import * as authController from "../controllers/authController";
|
||||||
//import authValidator from "../validators/authValidator";
|
import validate from '../middlewares/validateRequest'
|
||||||
|
import * as AuthVal from '../validators/authValidator'
|
||||||
//import handleValidation from "../middlewares/handleValidation";
|
//import handleValidation from "../middlewares/handleValidation";
|
||||||
//import { requireAuth } from "../middlewares/authMiddleware";
|
//import { requireAuth } from "../middlewares/authMiddleware";
|
||||||
|
|
||||||
@ -8,7 +9,7 @@ const router = Router();
|
|||||||
|
|
||||||
//const mws = [requireAuth, handleValidation.handleValidationError];
|
//const mws = [requireAuth, handleValidation.handleValidationError];
|
||||||
|
|
||||||
router.post("/signup", authController.signup_post);
|
router.post("/auth/signup",validate(AuthVal.signup) , authController.signup_post);
|
||||||
|
|
||||||
//router.post(
|
//router.post(
|
||||||
// "/login",
|
// "/login",
|
@ -1,9 +1,9 @@
|
|||||||
import { Request, Response, Router } from "express";
|
import { Request, Response, Router } from "express";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import authRoutes from "./authRoutes";
|
import api_v1 from "./api_v1";
|
||||||
export const router = Router();
|
export const router = Router();
|
||||||
|
|
||||||
router.use("/api/auth", authRoutes);
|
router.use("/api/v1", api_v1);
|
||||||
|
|
||||||
//router.get("*", (req: Request, res: Response) => {
|
//router.get("*", (req: Request, res: Response) => {
|
||||||
// res.sendFile(path.join(__dirname, "../views/index.html"));
|
// res.sendFile(path.join(__dirname, "../views/index.html"));
|
||||||
|
@ -1,26 +1,40 @@
|
|||||||
import http from "http";
|
import http from "http";
|
||||||
import { app } from "./app";
|
import { app } from "./app";
|
||||||
import env from "./config/environment";
|
import env from "./config/environment";
|
||||||
//const env = {
|
import mongoose from 'mongoose' // TODO: dopsat nork module pro db
|
||||||
// APP_PORT: 8080,
|
|
||||||
// APP_HOSTNAME: "127.0.0.1",
|
|
||||||
//};
|
|
||||||
import { Log } from "nork";
|
import { Log } from "nork";
|
||||||
//import database from './config/database'
|
|
||||||
const port: number = env.APP_PORT || 8080;
|
const port: number = env.APP_PORT || 8080;
|
||||||
const hostname: string = env.APP_HOSTNAME || "localhost";
|
const hostname: string = env.APP_HOSTNAME || "localhost";
|
||||||
|
|
||||||
export const server = http.createServer(app);
|
export const server = http.createServer(app);
|
||||||
|
|
||||||
// Server
|
// Server
|
||||||
export function runServer(): void {
|
//export function runServer(): void {
|
||||||
server.listen(port, hostname, () => {
|
// server.listen(port, hostname, () => {
|
||||||
Log.info(200, `Server is listening on http://${hostname}:${port}`);
|
// Log.info(200, `Server is listening on http://${hostname}:${port}`);
|
||||||
});
|
// });
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
//if (!env.NORK.database) {
|
////if (!env.NORK.database) {
|
||||||
runServer();
|
//runServer();
|
||||||
//} else {
|
//} else {
|
||||||
// const db_connection = database()
|
// const db_connection = database()
|
||||||
// runServer()
|
// runServer()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
if (!process.env.DOCS_GEN) {
|
||||||
|
try {
|
||||||
|
await mongoose.connect(env.DB_URI);
|
||||||
|
Log.info(200, 'connected to db');
|
||||||
|
server.listen(port, () => {
|
||||||
|
Log.info(200, `Server is listening on http://localhost:${port}`);
|
||||||
|
});
|
||||||
|
} catch (err: any) {
|
||||||
|
Log.error(500, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
62
api/src/services/docsService.ts
Normal file
62
api/src/services/docsService.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE';
|
||||||
|
export type ApiResponse = 'status object' | Object | string;
|
||||||
|
|
||||||
|
export class Docs {
|
||||||
|
private name: string;
|
||||||
|
private operation: string;
|
||||||
|
private route: string;
|
||||||
|
private method: HttpMethods;
|
||||||
|
private parameters?: Object[];
|
||||||
|
private description?: string;
|
||||||
|
private body?: Object;
|
||||||
|
private response?: ApiResponse;
|
||||||
|
|
||||||
|
public constructor(name: string, operation: string, route: string, method: HttpMethods, description?: string, parameters?: Object[], body?: Object, response?: ApiResponse) {
|
||||||
|
this.name = name;
|
||||||
|
this.operation = operation;
|
||||||
|
this.route = route;
|
||||||
|
this.method = method;
|
||||||
|
description ? (this.description = description) : null;
|
||||||
|
parameters ? (this.parameters = parameters) : null;
|
||||||
|
body ? (this.body = body) : null;
|
||||||
|
response ? (this.response = response) : null;
|
||||||
|
|
||||||
|
this.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private generate(): boolean {
|
||||||
|
if (!process.env.DOCS_GEN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsonPath = path.join(__dirname, '../public/api.json');
|
||||||
|
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json')).toString());
|
||||||
|
|
||||||
|
const jsonAPI = () => JSON.parse(fs.readFileSync(jsonPath).toString());
|
||||||
|
const genJsonAPI = () => fs.writeFileSync(jsonPath, JSON.stringify({ version: pkg.version, endpoints: {} }));
|
||||||
|
|
||||||
|
if (!fs.existsSync(path.join(__dirname, '../public'))) {
|
||||||
|
fs.mkdirSync(path.join(__dirname, '../public'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(jsonPath)) {
|
||||||
|
genJsonAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonAPI().version != pkg.version) {
|
||||||
|
genJsonAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = jsonAPI();
|
||||||
|
data.endpoints[this.name] ? undefined : (data.endpoints[this.name] = {});
|
||||||
|
data.endpoints[this.name][this.operation] = this;
|
||||||
|
fs.writeFileSync(jsonPath, JSON.stringify(data));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Docs;
|
@ -1,48 +0,0 @@
|
|||||||
import { Sequelize } from 'sequelize';
|
|
||||||
|
|
||||||
let sequelize: Sequelize | null = null;
|
|
||||||
|
|
||||||
const connectDB = async () => {
|
|
||||||
sequelize = new Sequelize({
|
|
||||||
dialect: 'mariadb',
|
|
||||||
host: 'localhost',
|
|
||||||
username: 'your_username',
|
|
||||||
password: 'your_password',
|
|
||||||
database: 'your_database',
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await sequelize.authenticate();
|
|
||||||
console.log('Connection to the database has been established successfully.');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Unable to connect to the database:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const dropDB = async () => {
|
|
||||||
if (sequelize) {
|
|
||||||
try {
|
|
||||||
await sequelize.drop();
|
|
||||||
console.log('Database dropped successfully.');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error dropping database:', error);
|
|
||||||
} finally {
|
|
||||||
await sequelize.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const dropTables = async () => {
|
|
||||||
if (sequelize) {
|
|
||||||
try {
|
|
||||||
await sequelize.sync({ force: true });
|
|
||||||
console.log('All tables dropped successfully.');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error dropping tables:', error);
|
|
||||||
} finally {
|
|
||||||
await sequelize.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export { connectDB, dropDB, dropTables };
|
|
30
api/src/utils/test_mongodb.ts
Normal file
30
api/src/utils/test_mongodb.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
|
|
||||||
|
let mongo: any = null;
|
||||||
|
|
||||||
|
const connectDB = async () => {
|
||||||
|
mongo = await MongoMemoryServer.create({ binary: { os: { os: 'linux', dist: 'ubuntu', release: '18.04' } } }); // TODO: check that host OS is Void Linux, else remove the argument
|
||||||
|
const uri = mongo.getUri();
|
||||||
|
|
||||||
|
await mongoose.connect(uri);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dropDB = async () => {
|
||||||
|
if (mongo) {
|
||||||
|
await mongoose.connection.dropDatabase();
|
||||||
|
await mongoose.connection.close();
|
||||||
|
await mongo.stop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const dropCollections = async () => {
|
||||||
|
if (mongo) {
|
||||||
|
const collections = await mongoose.connection.db.collections();
|
||||||
|
for (let collection of collections) {
|
||||||
|
await collection.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { connectDB, dropDB, dropCollections };
|
34
api/src/validators/authValidator.ts
Normal file
34
api/src/validators/authValidator.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import * as yup from 'yup';
|
||||||
|
import YupPassword from 'yup-password';
|
||||||
|
YupPassword(yup);
|
||||||
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
|
interface mongooseAddition {
|
||||||
|
_id?: Schema.Types.ObjectId;
|
||||||
|
createdAt?: Schema.Types.Date;
|
||||||
|
updatedAt?: Schema.Types.Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignUp
|
||||||
|
export const signup = yup.object({
|
||||||
|
username: yup.string().required(),
|
||||||
|
email: yup.string().email().required(),
|
||||||
|
password: yup.string().min(8).minLowercase(1).minUppercase(1).minNumbers(1).required()
|
||||||
|
});
|
||||||
|
export interface IUser extends yup.InferType<typeof signup>, mongooseAddition {}
|
||||||
|
export const signupExam: IUser = {
|
||||||
|
username: 'testuser',
|
||||||
|
email: 'text@example.com',
|
||||||
|
password: 'Test1234'
|
||||||
|
};
|
||||||
|
|
||||||
|
// SignIn
|
||||||
|
export const signin = yup.object({
|
||||||
|
email: yup.string().email().required(),
|
||||||
|
password: yup.string().min(8).minLowercase(1).minUppercase(1).minNumbers(1).required()
|
||||||
|
});
|
||||||
|
export interface ISignin extends yup.InferType<typeof signin>, mongooseAddition {}
|
||||||
|
export const signinExam: ISignin = {
|
||||||
|
email: 'text@example.com',
|
||||||
|
password: 'Test1234'
|
||||||
|
};
|
@ -1,17 +1,227 @@
|
|||||||
import request from "supertest"
|
import supertest from 'supertest';
|
||||||
import {server as app} from "../server"
|
import { app } from '../src/app';
|
||||||
|
import { connectDB, dropDB, dropCollections } from '../src/utils/test_mongodb';
|
||||||
|
|
||||||
describe('Auth API Endpoints', () => {
|
const request = supertest(app);
|
||||||
afterAll((done) => {
|
|
||||||
app.close(done);
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should signup new user', async () => {
|
export const getJWT = async () => {
|
||||||
const res = await request(app)
|
try {
|
||||||
.post('/api/auth/signup')
|
const resReg: any = await request.post('/api/v1/auth/signup').send({
|
||||||
.send({});
|
email: 'test@example.local',
|
||||||
|
password: 'admin1234',
|
||||||
|
username: 'Test Test'
|
||||||
|
});
|
||||||
|
|
||||||
expect(res.statusCode).toEqual(200)
|
const resLog: any = await request.post('/api/auth/login').send({
|
||||||
|
email: 'test@example.local',
|
||||||
})
|
password: 'admin1234'
|
||||||
})
|
});
|
||||||
|
if (resLog.statusCode != 200) throw 'error while logging in';
|
||||||
|
|
||||||
|
const body = JSON.parse(resLog.text);
|
||||||
|
return Promise.resolve(body.data.jwt);
|
||||||
|
} catch (err: any) {
|
||||||
|
console.log(err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns JWT cookie
|
||||||
|
*/
|
||||||
|
export async function login(): Promise<string> {
|
||||||
|
const res = await request.post('/api/v1/auth/signin').send({
|
||||||
|
email: 'thisistest@host.local',
|
||||||
|
password: 'Admin1234'
|
||||||
|
});
|
||||||
|
return res.headers['set-cookie'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function signup(): Promise<boolean> {
|
||||||
|
const res = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: 'thisistest@host.local',
|
||||||
|
password: 'Admin1234',
|
||||||
|
username: 'Test Test'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.statusCode == 201) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('POST /api/v1/auth/signup', () => {
|
||||||
|
describe('should drop validation error', () => {
|
||||||
|
it('should drop 400 (empty request))', async () => {
|
||||||
|
const res: any = await request.post('/api/v1/auth/signup').send({});
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should drop 400 (email))', async () => {
|
||||||
|
const res: any = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: '',
|
||||||
|
username: 'User Admin',
|
||||||
|
password: 'Admin1234'
|
||||||
|
});
|
||||||
|
console.log(res)
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('email');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should drop 400 (username))', async () => {
|
||||||
|
const res: any = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: 'admin@localhost.local',
|
||||||
|
username: '',
|
||||||
|
password: 'Admin1234'
|
||||||
|
});
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('username');
|
||||||
|
});
|
||||||
|
it('should drop 400 (password))', async () => {
|
||||||
|
const res: any = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: 'admin@localhost.local',
|
||||||
|
username: 'User Admin',
|
||||||
|
password: ''
|
||||||
|
});
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('password');
|
||||||
|
});
|
||||||
|
it('should drop 400 (password - min 8 chars', async () => {
|
||||||
|
const res = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: 'admin@localhost.local',
|
||||||
|
username: 'User Admin',
|
||||||
|
password: 'Admin12'
|
||||||
|
});
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('password');
|
||||||
|
});
|
||||||
|
it('should drop 400 (password - min 1 number', async () => {
|
||||||
|
const res = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: 'admin@localhost.local',
|
||||||
|
username: 'User Admin',
|
||||||
|
password: 'Adminadmin'
|
||||||
|
});
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('password');
|
||||||
|
});
|
||||||
|
it('should drop 400 (password - min 1 uppercase', async () => {
|
||||||
|
const res = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: 'admin@localhost.local',
|
||||||
|
username: 'User Admin',
|
||||||
|
password: 'admin1234'
|
||||||
|
});
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('password');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should register an user', async () => {
|
||||||
|
const res: any = await request.post('/api/v1/auth/signup').send({
|
||||||
|
email: 'thisistest@host.local',
|
||||||
|
password: 'Admin1234',
|
||||||
|
username: 'Test Test'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(201);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
describe('POST /api/v1/auth/signin', () => {
|
||||||
|
const url = '/api/v1/auth/signin';
|
||||||
|
|
||||||
|
describe('should drop an validation error', () => {
|
||||||
|
it('should drop 400 (empty)', async () => {
|
||||||
|
const res = await request.post(url).send();
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should drop 400 (email)', async () => {
|
||||||
|
const res = await request.post(url).send({
|
||||||
|
password: 'Admin1234'
|
||||||
|
});
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('email');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should drop 400 (password)', async () => {
|
||||||
|
const res = await request.post(url).send({
|
||||||
|
email: 'thisistest@host.local'
|
||||||
|
});
|
||||||
|
const body = JSON.parse(res.text);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(body.data.path).toBe('password');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should drop 401', async () => {
|
||||||
|
const res = await request.post(url).send({
|
||||||
|
email: 'thisistest@host.local',
|
||||||
|
password: 'Test12365465132'
|
||||||
|
});
|
||||||
|
expect(res.statusCode).toBe(401);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should login an user', async () => {
|
||||||
|
const res: any = await request.post(url).send({
|
||||||
|
email: 'thisistest@host.local',
|
||||||
|
password: 'Admin1234'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws errors idk
|
||||||
|
|
||||||
|
describe('POST /api/v1/auth/logout', () => {
|
||||||
|
const url = '/api/v1/auth/logout';
|
||||||
|
test('should drop 401 error', async () => {
|
||||||
|
const res = await request.post(url).send({});
|
||||||
|
expect(res.statusCode).toBe(401);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should logout an user', async () => {
|
||||||
|
const jwt = await login();
|
||||||
|
const res = await request.post(url).set('Cookie', jwt).send({});
|
||||||
|
|
||||||
|
res.headers['set-cookie'].forEach((el: any) => {
|
||||||
|
if (el.split('=')[0] == 'jwt') {
|
||||||
|
expect(Number(el.split('=')[2][0])).toBe(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
describe('GET /api/v1/auth/status', () => {
|
||||||
|
const url = '/api/v1/auth/status';
|
||||||
|
test('should return login status 401', async () => {
|
||||||
|
const res = await request.get(url).send();
|
||||||
|
expect(res.statusCode).toBe(401);
|
||||||
|
});
|
||||||
|
test('should return login status 200', async () => {
|
||||||
|
const jwt = await login();
|
||||||
|
const res = await request.get(url).set('Cookie', jwt).send();
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user