chore: updated every file to match biome rules

This commit is contained in:
Hackntosh 2024-01-24 15:22:01 +00:00
parent b6b978c017
commit 7087050fc0
89 changed files with 1071 additions and 1130 deletions

View file

@ -1,12 +1,11 @@
/* eslint-disable */ import * as express from "express";
import * as express from 'express'
declare global { declare global {
namespace Express { namespace Express {
namespace Multer { namespace Multer {
interface File { interface File {
location: string location: string;
key: string key: string;
} }
} }
} }

View file

@ -1,30 +1,29 @@
import app from '../../app' import app from "../../app";
import { expect, describe, beforeAll, afterAll, it } from 'vitest' import { expect, describe, beforeAll, afterAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import deleteUser from '../utils/delete-user' import deleteUser from "../utils/delete-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let user: User let user: User;
describe('POST /post/create', () => { describe("POST /post/create", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
}) });
afterAll(async () => { afterAll(async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion await deleteUser(user.username as string); // TODO: need to take a look at this
await deleteUser(user.username!) });
})
it('should respond with 200 status code if the user send the token and the content', async () => { it("should respond with 200 status code if the user send the token and the content", async () => {
const response = await request(app) const response = await request(app)
.post('/post/create') .post("/post/create")
.send({ .send({
content: 'Hello world', content: "Hello world",
}) })
.set('Authorization', `Bearer ${user.token ?? ''}`) .set("Authorization", `Bearer ${user.token ?? ""}`)
.expect(200) .expect(200);
expect(response.body).toEqual( expect(response.body).toEqual(
expect.objectContaining({ expect.objectContaining({
@ -33,13 +32,13 @@ describe('POST /post/create', () => {
authorId: expect.any(String), authorId: expect.any(String),
createdAt: expect.any(String), createdAt: expect.any(String),
updatedAt: expect.any(String), updatedAt: expect.any(String),
}),
)
}) })
);
});
it('should respond with 400 status code if the user send no token', async () => { it("should respond with 400 status code if the user send no token", async () => {
const response = await request(app).post('/post/create').expect(401) const response = await request(app).post("/post/create").expect(401);
expect(response.body).toHaveProperty('error') expect(response.body).toHaveProperty("error");
}) });
}) });

View file

@ -1,37 +1,36 @@
import app from '../../app' import app from "../../app";
import { describe, beforeAll, afterAll, it } from 'vitest' import { describe, beforeAll, afterAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import deleteUser from '../utils/delete-user' import deleteUser from "../utils/delete-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let user: User let user: User;
describe('DELETE /post/delete', () => { describe("DELETE /post/delete", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
}) });
afterAll(async () => { afterAll(async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion await deleteUser(user.username as string); // TODO: here too
await deleteUser(user.username!) });
})
it('should delete the post successfully', async () => { it("should delete the post successfully", async () => {
const response = await request(app) const response = await request(app)
.post('/post/create') .post("/post/create")
.send({ .send({
content: 'lorem ipsum', content: "lorem ipsum",
}) })
.set('Authorization', `Bearer ${user.token ?? ''}`) .set("Authorization", `Bearer ${user.token ?? ""}`)
.expect(200) .expect(200);
await request(app) await request(app)
.post('/post/delete') .post("/post/delete")
.send({ .send({
postId: response.body.id, postId: response.body.id,
}) })
.set('Authorization', `Bearer ${user.token ?? ''}`) .set("Authorization", `Bearer ${user.token ?? ""}`)
.expect(200) .expect(200);
}) });
}) });

View file

@ -1,40 +1,39 @@
import app from '../../app' import app from "../../app";
import { expect, describe, beforeAll, afterAll, it } from 'vitest' import { expect, describe, beforeAll, afterAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import deleteUser from '../utils/delete-user' import deleteUser from "../utils/delete-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let postId: string let postId: string;
let user: User let user: User;
describe('POST /post/info', () => { describe("POST /post/info", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
const token = user.token ?? '' const token = user.token ?? "";
const post = await request(app) const post = await request(app)
.post('/post/create') .post("/post/create")
.send({ .send({
content: 'Hello world', content: "Hello world",
}) })
.set('Authorization', `Bearer ${token}`) .set("Authorization", `Bearer ${token}`)
.expect(200) .expect(200);
postId = post.body.id postId = post.body.id;
}) });
afterAll(async () => { afterAll(async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion await deleteUser(user.username as string); // TODO: here too btw
await deleteUser(user.username!) });
})
it('should respond with 200 status code and return some info about the post', async () => { it("should respond with 200 status code and return some info about the post", async () => {
const response = await request(app) const response = await request(app)
.get(`/post/info?id=${postId}`) .get(`/post/info?id=${postId}`)
.expect(200) .expect(200);
expect(response.body).toEqual( expect(response.body).toEqual(
expect.objectContaining({ expect.objectContaining({
@ -43,13 +42,13 @@ describe('POST /post/info', () => {
createdAt: expect.any(String), createdAt: expect.any(String),
updatedAt: expect.any(String), updatedAt: expect.any(String),
author: expect.any(Object), author: expect.any(Object),
}),
)
}) })
);
});
it('should respond with 400 status code if the post does not exists', async () => { it("should respond with 400 status code if the post does not exists", async () => {
const response = await request(app).get('/post/info?id=abc').expect(400) const response = await request(app).get("/post/info?id=abc").expect(400);
expect(response.body).toHaveProperty('error') expect(response.body).toHaveProperty("error");
}) });
}) });

View file

@ -1,47 +1,46 @@
import app from '../../app' import app from "../../app";
import { expect, describe, beforeAll, afterAll, it } from 'vitest' import { expect, describe, beforeAll, afterAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import deleteUser from '../utils/delete-user' import deleteUser from "../utils/delete-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let user: User let user: User;
describe('PUT /post/update', () => { describe("PUT /post/update", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
}) });
afterAll(async () => { afterAll(async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion await deleteUser(user.username as string); // TODO: well, here too
await deleteUser(user.username!) });
})
it('should create a new post and update the content of it', async () => { it("should create a new post and update the content of it", async () => {
const post = await request(app) const post = await request(app)
.post('/post/create') .post("/post/create")
.send({ .send({
content: 'Lorem', content: "Lorem",
}) })
.set('Authorization', `Bearer ${user.token ?? ''}`) .set("Authorization", `Bearer ${user.token ?? ""}`)
.expect(200) .expect(200);
expect(post.body).toHaveProperty('id') expect(post.body).toHaveProperty("id");
const fieldsToUpdate = { const fieldsToUpdate = {
postId: post.body.id, postId: post.body.id,
content: 'Lorem ipsum', content: "Lorem ipsum",
} };
const response = await request(app) const response = await request(app)
.put('/post/update') .put("/post/update")
.send(fieldsToUpdate) .send(fieldsToUpdate)
.set('Authorization', `Bearer ${user.token ?? ''}`) .set("Authorization", `Bearer ${user.token ?? ""}`)
.expect(200) .expect(200);
// Post content should be Lorem Ipsum // Post content should be Lorem Ipsum
if (post.body.content === response.body.content) { if (post.body.content === response.body.content) {
throw new Error("Post didn't update") throw new Error("Post didn't update");
} }
expect(response.body).toEqual( expect(response.body).toEqual(
@ -51,7 +50,7 @@ describe('PUT /post/update', () => {
createdAt: expect.any(String), createdAt: expect.any(String),
updatedAt: expect.any(String), updatedAt: expect.any(String),
author: expect.any(Object), author: expect.any(Object),
}),
)
}) })
}) );
});
});

View file

@ -1,46 +1,45 @@
import app from '../../app' import app from "../../app";
import deleteUser from '../utils/delete-user' import deleteUser from "../utils/delete-user";
import { expect, describe, beforeAll, afterAll, it } from 'vitest' import { expect, describe, beforeAll, afterAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let user: User let user: User;
describe('POST /user/auth', () => { describe("POST /user/auth", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
}) });
afterAll(async () => { afterAll(async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion await deleteUser(user.username as string);
await deleteUser(user.username!) });
})
it('should respond with a error if the user does not exists', async () => { it("should respond with a error if the user does not exists", async () => {
const response = await request(app) const response = await request(app)
.post('/user/auth') .post("/user/auth")
.send({ email: 'mm@mm.com', password: 'aa' }) .send({ email: "mm@mm.com", password: "aa" })
.expect(400) .expect(400);
expect(response.body).toHaveProperty('error') expect(response.body).toHaveProperty("error");
expect(response.body.error).toBe('Invalid email or password') expect(response.body.error).toBe("Invalid email or password");
}) });
it('should respond with a error if receive an invalid email or password', async () => { it("should respond with a error if receive an invalid email or password", async () => {
const response = await request(app) const response = await request(app)
.post('/user/auth') .post("/user/auth")
.send({ email: user.email, password: 'fake_pass' }) .send({ email: user.email, password: "fake_pass" })
.expect(400) .expect(400);
expect(response.body).toHaveProperty('error') expect(response.body).toHaveProperty("error");
expect(response.body.error).toBe('Invalid email or password') expect(response.body.error).toBe("Invalid email or password");
}) });
it('should respond with a error if receive an empty body', async () => { it("should respond with a error if receive an empty body", async () => {
const response = await request(app).post('/user/auth').send({}).expect(400) const response = await request(app).post("/user/auth").send({}).expect(400);
expect(response.body).toHaveProperty('error') expect(response.body).toHaveProperty("error");
expect(response.body.error).toBe('Missing fields') expect(response.body.error).toBe("Missing fields");
}) });
}) });

View file

@ -1,20 +1,20 @@
import app from '../../app' import app from "../../app";
import { describe, beforeAll, it } from 'vitest' import { describe, beforeAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let user: User let user: User;
describe('DELETE /user/delete', () => { describe("DELETE /user/delete", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
}) });
it('should delete the user successfully', async () => { it("should delete the user successfully", async () => {
await request(app) await request(app)
.post('/user/delete') .post("/user/delete")
.set('Authorization', `Bearer ${user.token ?? ''}`) .set("Authorization", `Bearer ${user.token ?? ""}`)
.expect(200) .expect(200);
}) });
}) });

View file

@ -1,38 +1,38 @@
import app from '../../app' import app from "../../app";
import { expect, describe, beforeAll, afterAll, it } from 'vitest' import { expect, describe, beforeAll, afterAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import deleteUser from '../utils/delete-user' import deleteUser from "../utils/delete-user";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let user: User let user: User;
describe('POST /user/info', () => { describe("POST /user/info", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
}) });
afterAll(async () => { afterAll(async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await deleteUser(user.username!) await deleteUser(user.username as string);
}) });
it('should respond with 200 status code and return the user data', async () => { it("should respond with 200 status code and return the user data", async () => {
const response = await request(app) const response = await request(app)
.get(`/user/info?u=${user.username ?? ''}`) .get(`/user/info?u=${user.username ?? ""}`)
.expect(200) .expect(200);
expect(response.body).toHaveProperty('profileImage') expect(response.body).toHaveProperty("profileImage");
expect(response.body).toHaveProperty('displayName') expect(response.body).toHaveProperty("displayName");
expect(response.body).toHaveProperty('username') expect(response.body).toHaveProperty("username");
expect(response.body).toHaveProperty('createdAt') expect(response.body).toHaveProperty("createdAt");
expect(response.body).toHaveProperty('posts') expect(response.body).toHaveProperty("posts");
expect(response.body).toHaveProperty('likedPosts') expect(response.body).toHaveProperty("likedPosts");
}) });
it('should respond with 400 status code if the user send no username', async () => { it("should respond with 400 status code if the user send no username", async () => {
const response = await request(app).get('/user/info?u=').expect(400) const response = await request(app).get("/user/info?u=").expect(400);
expect(response.body).toHaveProperty('error') expect(response.body).toHaveProperty("error");
}) });
}) });

View file

@ -1,46 +1,46 @@
import app from '../../app' import app from "../../app";
import { describe, beforeAll, afterAll, it } from 'vitest' import { describe, beforeAll, afterAll, it } from "vitest";
import request from 'supertest' import request from "supertest";
import deleteUser from '../utils/delete-user' import deleteUser from "../utils/delete-user";
import signUpNewUser from '../utils/create-user' import signUpNewUser from "../utils/create-user";
import type User from 'interfaces/user' import type User from "interfaces/user";
let user: User let user: User;
describe('POST /user/signup', () => { describe("POST /user/signup", () => {
beforeAll(async () => { beforeAll(async () => {
user = await signUpNewUser() user = await signUpNewUser();
delete user.token user.token = undefined;
}) });
afterAll(async () => { afterAll(async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await deleteUser(user.username!) await deleteUser(user.username as string);
}) });
it('should respond with a 400 status code if sent any invalid data', async () => { it("should respond with a 400 status code if sent any invalid data", async () => {
await request(app) await request(app)
.post('/user/signup') .post("/user/signup")
.send({ .send({
username: 'username12@', username: "username12@",
email: user.email, email: user.email,
password: user.password, password: user.password,
}) })
.expect(400) .expect(400);
}) });
it('should respond with a 400 status code for an existing username or email', async () => { it("should respond with a 400 status code for an existing username or email", async () => {
await request(app) await request(app)
.post('/user/signup') .post("/user/signup")
.send({ .send({
username: user.username, username: user.username,
email: user.email, email: user.email,
password: user.password, password: user.password,
}) })
.expect(400) .expect(400);
}) });
it('should respond with a 400 status code if receive an empty body', async () => { it("should respond with a 400 status code if receive an empty body", async () => {
await request(app).post('/user/signup').send({}).expect(400) await request(app).post("/user/signup").send({}).expect(400);
}) });
}) });

View file

@ -1,37 +1,37 @@
import app from '../../app' import app from "../../app";
import request from 'supertest' import request from "supertest";
import { faker } from '@faker-js/faker' import { faker } from "@faker-js/faker";
import type userPayload from '../../interfaces/user' import type userPayload from "../../interfaces/user";
async function signUpNewUser(): Promise<userPayload> { async function signUpNewUser(): Promise<userPayload> {
// To avoid conflicts with existing usernames or emails // To avoid conflicts with existing usernames or emails
const username = faker.internet.userName({ lastName: 'doe' }).toLowerCase() const username = faker.internet.userName({ lastName: "doe" }).toLowerCase();
const email = faker.internet.email() const email = faker.internet.email();
const password = faker.internet.password() + '@1' const password = `${faker.internet.password()}@1`;
await request(app) await request(app)
.post('/user/signup') .post("/user/signup")
.send({ .send({
username, username,
email, email,
password, password,
}) })
.expect(200) .expect(200);
const response = await request(app) const response = await request(app)
.post('/user/auth') .post("/user/auth")
.send({ .send({
email, email,
password, password,
}) })
.expect(200) .expect(200);
return { return {
username, username,
email, email,
password, password,
token: response.body.token, token: response.body.token,
} };
} }
export default signUpNewUser export default signUpNewUser;

View file

@ -1,4 +1,4 @@
import prisma from '../../clients/prisma-client' import prisma from "../../clients/prisma-client";
export default async function deleteUser(username: string) { export default async function deleteUser(username: string) {
await prisma.post.deleteMany({ await prisma.post.deleteMany({
@ -7,11 +7,11 @@ export default async function deleteUser(username: string) {
username, username,
}, },
}, },
}) });
await prisma.user.deleteMany({ await prisma.user.deleteMany({
where: { where: {
username, username,
}, },
}) });
} }

View file

@ -1,49 +1,49 @@
import 'dotenv/config' import "dotenv/config";
import compression from 'compression' import compression from "compression";
import cors from 'cors' import cors from "cors";
import express from 'express' import express from "express";
import limiter from 'middlewares/rate-limit' import limiter from "middlewares/rate-limit";
import morganMiddleware from 'middlewares/morgan' import morganMiddleware from "middlewares/morgan";
import router from './routes' import router from "./routes";
import swaggerUI from 'swagger-ui-express' import swaggerUI from "swagger-ui-express";
import swaggerDocument from 'helpers/parse-swagger' import swaggerDocument from "helpers/parse-swagger";
import swaggerConfig from 'config/swagger' import swaggerConfig from "config/swagger";
const app = express() const app = express();
// TODO: test socket io, emit notifications when create one. // TODO: test socket io, emit notifications when create one.
app.use(express.json()) app.use(express.json());
app.use(express.urlencoded({ extended: true })) app.use(express.urlencoded({ extended: true }));
app.use(morganMiddleware) app.use(morganMiddleware);
app.options('*', cors()) app.options("*", cors());
app.use( app.use(
cors({ cors({
credentials: true, credentials: true,
origin: process.env.CLIENT_URL, origin: process.env.CLIENT_URL,
methods: ['GET', 'POST', 'PUT'], methods: ["GET", "POST", "PUT"],
optionsSuccessStatus: 200, optionsSuccessStatus: 200,
}), })
) );
app.use(express.static('public')) app.use(express.static("public"));
app.use(limiter) app.use(limiter);
app.use(router) app.use(router);
app.use( app.use(
'/docs', "/docs",
swaggerUI.serve, swaggerUI.serve,
swaggerUI.setup(swaggerDocument, swaggerConfig), swaggerUI.setup(swaggerDocument, swaggerConfig)
) );
app.use(compression({ level: 9 })) app.use(compression({ level: 9 }));
app.get('/', function (_req, res) { app.get("/", (_req, res) => {
res.redirect('/docs') res.redirect("/docs");
}) });
app.use((_req, res) => { app.use((_req, res) => {
res.status(404).json({ res.status(404).json({
error: 'Endpoint not found', error: "Endpoint not found",
}) });
}) });
export default app export default app;

View file

@ -1,5 +1,5 @@
import { PrismaClient } from '@prisma/client' import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient() const prisma = new PrismaClient();
export default prisma export default prisma;

View file

@ -1,27 +1,27 @@
import logger from 'helpers/logger' import logger from "helpers/logger";
import { createClient, type RedisClientOptions } from 'redis' import { createClient, type RedisClientOptions } from "redis";
const redisPort = parseInt(process.env.REDIS_PORT ?? '6379', 10) const redisPort = parseInt(process.env.REDIS_PORT ?? "6379", 10);
const redisHost = process.env.REDIS_HOST ?? '127.0.0.1' const redisHost = process.env.REDIS_HOST ?? "127.0.0.1";
const redisPassword = process.env.REDIS_PASSWORD ?? '' const redisPassword = process.env.REDIS_PASSWORD ?? "";
const redisConfig: RedisClientOptions = { const redisConfig: RedisClientOptions = {
url: `redis://:${redisPassword}@${redisHost}:${redisPort}/0`, url: `redis://:${redisPassword}@${redisHost}:${redisPort}/0`,
} };
const redis = createClient(redisConfig) const redis = createClient(redisConfig);
redis redis
.connect() .connect()
.then(() => { .then(() => {
logger.info('Successfully connected to Redis') logger.info("Successfully connected to Redis");
}) })
.catch((e: Error) => { .catch((e: Error) => {
logger.error(`Error while connecting to Redis: ${e.message}`) logger.error(`Error while connecting to Redis: ${e.message}`);
}) });
redis.on('error', async (e: Error) => { redis.on("error", async (e: Error) => {
logger.error(`Error in Redis client: ${e.message}`) logger.error(`Error in Redis client: ${e.message}`);
}) });
export default redis export default redis;

View file

@ -1,24 +1,24 @@
import { S3Client } from '@aws-sdk/client-s3' import { S3Client } from "@aws-sdk/client-s3";
import logger from 'helpers/logger' import logger from "helpers/logger";
let s3: S3Client let s3: S3Client;
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === "development") {
logger.info('Using Localstack services instead of AWS.') logger.info("Using Localstack services instead of AWS.");
s3 = new S3Client({ s3 = new S3Client({
credentials: { credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID ?? '', accessKeyId: process.env.AWS_ACCESS_KEY_ID ?? "",
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY ?? '', secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY ?? "",
}, },
endpoint: 'http://127.0.0.1:4566', // Uses localstack instead of aws, make sure to create the bucket first with public-read acl endpoint: "http://127.0.0.1:4566", // Uses localstack instead of aws, make sure to create the bucket first with public-read acl
}) });
} else { } else {
s3 = new S3Client({ s3 = new S3Client({
credentials: { credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID ?? '', accessKeyId: process.env.AWS_ACCESS_KEY_ID ?? "",
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY ?? '', secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY ?? "",
}, },
}) });
} }
export default s3 export default s3;

View file

@ -1,45 +1,44 @@
import multer from 'multer' import multer from "multer";
import { type Request } from 'express' import { type Request } from "express";
import path from 'path' import path from "path";
import s3 from 'clients/s3-client' import s3 from "clients/s3-client";
import multerS3 from 'multer-s3' import multerS3 from "multer-s3";
const tempFolder = path.resolve(__dirname, '..', '..', 'temp', 'uploads') const tempFolder = path.resolve(__dirname, "..", "..", "temp", "uploads");
const storageTypes = { const storageTypes = {
local: multer.diskStorage({ local: multer.diskStorage({
destination: (req: Request, file: Express.Multer.File, callback) => { destination: (req: Request, file: Express.Multer.File, callback) => {
callback(null, tempFolder) callback(null, tempFolder);
}, },
filename: (req: Request, file: Express.Multer.File, callback) => { filename: (req: Request, file: Express.Multer.File, callback) => {
/* eslint-disable */ const folder = req.body.isProfilePicture ? "profile_images" : "media";
const folder = req.body.isProfilePicture ? 'profile_images' : 'media' const fileName: string = `${folder}/${req.res?.locals.user.id}.webp`;
const fileName: string = `${folder}/${req.res?.locals.user.id}.webp`
callback(null, fileName) callback(null, fileName);
}, },
}), }),
s3: multerS3({ s3: multerS3({
s3, s3,
bucket: process.env.AWS_BUCKET ?? '', bucket: process.env.AWS_BUCKET ?? "",
contentType: multerS3.AUTO_CONTENT_TYPE, contentType: multerS3.AUTO_CONTENT_TYPE,
acl: 'public-read', acl: "public-read",
key: (req: Request, file: Express.Multer.File, callback) => { key: (req: Request, file: Express.Multer.File, callback) => {
let folder let folder: string;
if (req.body.isProfilePicture === 'true') { if (req.body.isProfilePicture === "true") {
folder = 'profile_images' folder = "profile_images";
} else { } else {
folder = 'media' folder = "media";
} }
const fileName: string = `${folder}/${req.res?.locals.user.id}.jpg` const fileName: string = `${folder}/${req.res?.locals.user.id}.jpg`;
callback(null, fileName) callback(null, fileName);
}, },
}), }),
} };
const multerConfig = { const multerConfig = {
dest: tempFolder, dest: tempFolder,
@ -50,16 +49,16 @@ const multerConfig = {
fileFilter: ( fileFilter: (
req: Request, req: Request,
file: Express.Multer.File, file: Express.Multer.File,
callback: multer.FileFilterCallback, callback: multer.FileFilterCallback
) => { ) => {
const allowedMimes = ['image/jpeg', 'image/png'] const allowedMimes = ["image/jpeg", "image/png"];
if (allowedMimes.includes(file.mimetype)) { if (allowedMimes.includes(file.mimetype)) {
callback(null, true) callback(null, true);
} else { } else {
callback(new Error('Filetype not allowed')) callback(new Error("Filetype not allowed"));
} }
}, },
} };
export default multerConfig export default multerConfig;

View file

@ -1,9 +1,9 @@
import type { SwaggerUiOptions } from 'swagger-ui-express' import type { SwaggerUiOptions } from "swagger-ui-express";
const swaggerConfig: SwaggerUiOptions = { const swaggerConfig: SwaggerUiOptions = {
customCssUrl: '/swagger-ui.css', customCssUrl: "/swagger-ui.css",
customSiteTitle: 'Project Knedita Docs', customSiteTitle: "Project Knedita Docs",
customfavIcon: '/favicon.png', customfavIcon: "/favicon.png",
} };
export default swaggerConfig export default swaggerConfig;

View file

@ -1,22 +1,22 @@
import { Router } from 'express' import { Router } from "express";
// Controllers // Controllers
import comments from './comments' import comments from "./comments";
// Middlewares // Middlewares
import authenticated from 'middlewares/authenticated' import authenticated from "middlewares/authenticated";
const commentsRouter = Router() const commentsRouter = Router();
// GET // GET
commentsRouter.get('/fetch-likes', comments.fetchLikes) commentsRouter.get("/fetch-likes", comments.fetchLikes);
commentsRouter.get('/info', comments.fetch) commentsRouter.get("/info", comments.fetch);
// POST // POST
commentsRouter.post('/create', authenticated, comments.create) commentsRouter.post("/create", authenticated, comments.create);
commentsRouter.post('/delete', authenticated, comments.delete) commentsRouter.post("/delete", authenticated, comments.delete);
// PUT // PUT
commentsRouter.put('/update', authenticated, comments.update) commentsRouter.put("/update", authenticated, comments.update);
export default commentsRouter export default commentsRouter;

View file

@ -1,28 +1,28 @@
import comment from 'services/comments' import comment from "services/comments";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function commentCreateController( async function commentCreateController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { content, postId } = req.body const { content, postId } = req.body;
const id = res.locals.user.id const id = res.locals.user.id;
if (postId === undefined) { if (postId === undefined) {
badRequest(res, 'Expected post id') badRequest(res, "Expected post id");
return return;
} }
if (content === undefined) { if (content === undefined) {
badRequest(res, 'Expected comment content') badRequest(res, "Expected comment content");
return return;
} }
const result = await comment.create(postId, content, id) const result = await comment.create(postId, content, id);
handleResponse(res, result) handleResponse(res, result);
} }
export default commentCreateController export default commentCreateController;

View file

@ -1,23 +1,23 @@
import comment from 'services/comments' import comment from "services/comments";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function commentDeleteController( async function commentDeleteController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { commentId } = req.body const { commentId } = req.body;
const id = res.locals.user.id const id = res.locals.user.id;
if (commentId === undefined) { if (commentId === undefined) {
badRequest(res, 'Expected comment id') badRequest(res, "Expected comment id");
return return;
} }
const result = await comment.delete(commentId, id) const result = await comment.delete(commentId, id);
handleResponse(res, result) handleResponse(res, result);
} }
export default commentDeleteController export default commentDeleteController;

View file

@ -1,22 +1,22 @@
import comment from 'services/comments' import comment from "services/comments";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function commentFetchController( async function commentFetchController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const commentId = req.query.id as string const commentId = req.query.id as string;
if (commentId === undefined) { if (commentId === undefined) {
badRequest(res, 'Expected comment id') badRequest(res, "Expected comment id");
return return;
} }
const result = await comment.fetch(commentId) const result = await comment.fetch(commentId);
handleResponse(res, result) handleResponse(res, result);
} }
export default commentFetchController export default commentFetchController;

View file

@ -1,22 +1,22 @@
import comment from 'services/comments' import comment from "services/comments";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function commentFetchLikesController( async function commentFetchLikesController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const commentId = req.query.id as string const commentId = req.query.id as string;
if (commentId === undefined) { if (commentId === undefined) {
badRequest(res, 'Expected comment id') badRequest(res, "Expected comment id");
return return;
} }
const result = await comment.fetchLikes(commentId) const result = await comment.fetchLikes(commentId);
handleResponse(res, result) handleResponse(res, result);
} }
export default commentFetchLikesController export default commentFetchLikesController;

View file

@ -1,8 +1,8 @@
import commentCreateController from './create' import commentCreateController from "./create";
import commentDeleteController from './delete' import commentDeleteController from "./delete";
import commentFetchController from './fetch-info' import commentFetchController from "./fetch-info";
import commentFetchLikesController from './fetch-likes' import commentFetchLikesController from "./fetch-likes";
import commentUpdateController from './update' import commentUpdateController from "./update";
const comments = { const comments = {
create: commentCreateController, create: commentCreateController,
@ -10,6 +10,6 @@ const comments = {
fetch: commentFetchController, fetch: commentFetchController,
fetchLikes: commentFetchLikesController, fetchLikes: commentFetchLikesController,
update: commentUpdateController, update: commentUpdateController,
} as const } as const;
export default comments export default comments;

View file

@ -1,28 +1,28 @@
import comment from 'services/comments' import comment from "services/comments";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function commentUpdateController( async function commentUpdateController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { commentId, content } = req.body const { commentId, content } = req.body;
const id = res.locals.user.id const id = res.locals.user.id;
if (commentId === undefined) { if (commentId === undefined) {
badRequest(res, 'Expected comment content') badRequest(res, "Expected comment content");
return return;
} }
if (content === undefined) { if (content === undefined) {
badRequest(res, 'Expected content to update') badRequest(res, "Expected content to update");
return return;
} }
const result = await comment.update(content, id, commentId) const result = await comment.update(content, id, commentId);
handleResponse(res, result) handleResponse(res, result);
} }
export default commentUpdateController export default commentUpdateController;

View file

@ -1,22 +1,22 @@
import { Router } from 'express' import { Router } from "express";
// Controllers // Controllers
import post from './posts' import post from "./posts";
// Middlewares // Middlewares
import authenticated from 'middlewares/authenticated' import authenticated from "middlewares/authenticated";
const postsRouter = Router() const postsRouter = Router();
// GET // GET
postsRouter.get('/fetch-likes', post.fetchLikes) postsRouter.get("/fetch-likes", post.fetchLikes);
postsRouter.get('/info', post.fetch) postsRouter.get("/info", post.fetch);
// POST // POST
postsRouter.post('/create', authenticated, post.create) postsRouter.post("/create", authenticated, post.create);
postsRouter.post('/delete', authenticated, post.delete) postsRouter.post("/delete", authenticated, post.delete);
// PUT // PUT
postsRouter.put('/update', authenticated, post.update) postsRouter.put("/update", authenticated, post.update);
export default postsRouter export default postsRouter;

View file

@ -1,23 +1,23 @@
import post from 'services/posts' import post from "services/posts";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function postCreateController( async function postCreateController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { content } = req.body const { content } = req.body;
const id = res.locals.user.id const id = res.locals.user.id;
if (content === undefined) { if (content === undefined) {
badRequest(res, 'Expected post content') badRequest(res, "Expected post content");
return return;
} }
const result = await post.create(content, id) const result = await post.create(content, id);
handleResponse(res, result) handleResponse(res, result);
} }
export default postCreateController export default postCreateController;

View file

@ -1,23 +1,23 @@
import post from 'services/posts' import post from "services/posts";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function postDeleteController( async function postDeleteController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const userId = res.locals.user.id const userId = res.locals.user.id;
const postId = req.body.postId const postId = req.body.postId;
if (postId === undefined) { if (postId === undefined) {
badRequest(res, 'Missing post id') badRequest(res, "Missing post id");
return return;
} }
const result = await post.delete(postId, userId) const result = await post.delete(postId, userId);
handleResponse(res, result) handleResponse(res, result);
} }
export default postDeleteController export default postDeleteController;

View file

@ -1,22 +1,22 @@
import post from 'services/posts' import post from "services/posts";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function postFetchInfoController( async function postFetchInfoController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const id = req.query.id as string const id = req.query.id as string;
if (id === undefined) { if (id === undefined) {
badRequest(res, 'Missing post id') badRequest(res, "Missing post id");
return return;
} }
const result = await post.fetch(id) const result = await post.fetch(id);
handleResponse(res, result) handleResponse(res, result);
} }
export default postFetchInfoController export default postFetchInfoController;

View file

@ -1,22 +1,22 @@
import post from 'services/posts' import post from "services/posts";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function postFetchLikesController( async function postFetchLikesController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const id = req.query.id as string const id = req.query.id as string;
if (id === undefined) { if (id === undefined) {
badRequest(res, 'Missing post id') badRequest(res, "Missing post id");
return return;
} }
const result = await post.fetchLikes(id) const result = await post.fetchLikes(id);
handleResponse(res, result) handleResponse(res, result);
} }
export default postFetchLikesController export default postFetchLikesController;

View file

@ -1,8 +1,8 @@
import postCreateController from './create' import postCreateController from "./create";
import postDeleteController from './delete' import postDeleteController from "./delete";
import postFetchInfoController from './fetch-info' import postFetchInfoController from "./fetch-info";
import postUpdateController from './update' import postUpdateController from "./update";
import postFetchLikesController from './fetch-likes' import postFetchLikesController from "./fetch-likes";
const post = { const post = {
create: postCreateController, create: postCreateController,
@ -10,6 +10,6 @@ const post = {
fetch: postFetchInfoController, fetch: postFetchInfoController,
fetchLikes: postFetchLikesController, fetchLikes: postFetchLikesController,
update: postUpdateController, update: postUpdateController,
} as const } as const;
export default post export default post;

View file

@ -1,17 +1,17 @@
import post from 'services/posts' import post from "services/posts";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function postUpdateController( async function postUpdateController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { postId, content } = req.body const { postId, content } = req.body;
const userId = res.locals.user.id const userId = res.locals.user.id;
const result = await post.update(postId, content, userId) const result = await post.update(postId, content, userId);
handleResponse(res, result) handleResponse(res, result);
} }
export default postUpdateController export default postUpdateController;

View file

@ -1,37 +1,37 @@
import { Router } from 'express' import { Router } from "express";
// Controllers // Controllers
import user from './users' import user from "./users";
// Middlewares // Middlewares
import authenticated from 'middlewares/authenticated' import authenticated from "middlewares/authenticated";
import uploadFile from 'middlewares/upload-image' import uploadFile from "middlewares/upload-image";
const usersRouter = Router() const usersRouter = Router();
// GET // GET
usersRouter.get('/fetch-posts', user.fetchPosts) usersRouter.get("/fetch-posts", user.fetchPosts);
usersRouter.get('/info', user.fetchInfo) usersRouter.get("/info", user.fetchInfo);
usersRouter.get('/search', user.searchUser) usersRouter.get("/search", user.searchUser);
// POST // POST
usersRouter.post('/auth', user.auth) usersRouter.post("/auth", user.auth);
usersRouter.post('/delete', authenticated, user.delete) usersRouter.post("/delete", authenticated, user.delete);
usersRouter.post('/me', authenticated, user.fetchUser) usersRouter.post("/me", authenticated, user.fetchUser);
usersRouter.post('/follow-user', authenticated, user.follow) usersRouter.post("/follow-user", authenticated, user.follow);
usersRouter.post('/like-comment', authenticated, user.likeComment) usersRouter.post("/like-comment", authenticated, user.likeComment);
usersRouter.post('/like-post', authenticated, user.likePost) usersRouter.post("/like-post", authenticated, user.likePost);
usersRouter.post('/signup', user.signup) usersRouter.post("/signup", user.signup);
// PUT // PUT
usersRouter.put( usersRouter.put(
'/profile-picture/upload', "/profile-picture/upload",
authenticated, authenticated,
uploadFile, uploadFile,
user.uploadPicture, user.uploadPicture
) );
usersRouter.put('/update-email', authenticated, user.updateEmail) usersRouter.put("/update-email", authenticated, user.updateEmail);
usersRouter.put('/update-name', authenticated, user.updateName) usersRouter.put("/update-name", authenticated, user.updateName);
usersRouter.put('/update-password', authenticated, user.updatePassword) usersRouter.put("/update-password", authenticated, user.updatePassword);
export default usersRouter export default usersRouter;

View file

@ -1,13 +1,13 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userAuthController(req: Request, res: Response): Promise<void> { async function userAuthController(req: Request, res: Response): Promise<void> {
const { email, password } = req.body const { email, password } = req.body;
const result = await user.auth({ email, password }) const result = await user.auth({ email, password });
handleResponse(res, result) handleResponse(res, result);
} }
export default userAuthController export default userAuthController;

View file

@ -1,15 +1,15 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userDeleteController( async function userDeleteController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const userId = res.locals.user.id const userId = res.locals.user.id;
const result = await user.delete(userId) const result = await user.delete(userId);
handleResponse(res, result) handleResponse(res, result);
} }
export default userDeleteController export default userDeleteController;

View file

@ -1,22 +1,22 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userFetchInfoController( async function userFetchInfoController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const username = req.query.u as string const username = req.query.u as string;
if (username === undefined) { if (username === undefined) {
badRequest(res, 'Missing username') badRequest(res, "Missing username");
return return;
} }
const result = await user.fetchInfo(username.toLowerCase()) const result = await user.fetchInfo(username.toLowerCase());
handleResponse(res, result) handleResponse(res, result);
} }
export default userFetchInfoController export default userFetchInfoController;

View file

@ -1,22 +1,22 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userFetchPostsController( async function userFetchPostsController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const username = req.query.u as string const username = req.query.u as string;
if (username === undefined) { if (username === undefined) {
badRequest(res, 'Missing username') badRequest(res, "Missing username");
return return;
} }
const result = await user.fetchPosts(username) const result = await user.fetchPosts(username);
handleResponse(res, result) handleResponse(res, result);
} }
export default userFetchPostsController export default userFetchPostsController;

View file

@ -1,22 +1,22 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userFetchUserController( async function userFetchUserController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const id = res.locals.user.id const id = res.locals.user.id;
if (id === undefined) { if (id === undefined) {
badRequest(res, 'Missing id') badRequest(res, "Missing id");
return return;
} }
const result = await user.fetchUser(id) const result = await user.fetchUser(id);
handleResponse(res, result) handleResponse(res, result);
} }
export default userFetchUserController export default userFetchUserController;

View file

@ -1,17 +1,17 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userFollowController( async function userFollowController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const userId = res.locals.user.id const userId = res.locals.user.id;
const { userToFollow } = req.body const { userToFollow } = req.body;
const result = await user.follow(userId, userToFollow) const result = await user.follow(userId, userToFollow);
handleResponse(res, result) handleResponse(res, result);
} }
export default userFollowController export default userFollowController;

View file

@ -1,17 +1,17 @@
import userAuthController from './auth' import userAuthController from "./auth";
import userDeleteController from './delete' import userDeleteController from "./delete";
import userFollowController from './follow-user' import userFollowController from "./follow-user";
import userFetchInfoController from './fetch-info' import userFetchInfoController from "./fetch-info";
import userFetchPostsController from './fetch-posts' import userFetchPostsController from "./fetch-posts";
import userFetchUserController from './fetch-user' import userFetchUserController from "./fetch-user";
import userLikeCommentController from './like-comment' import userLikeCommentController from "./like-comment";
import userLikePostController from './like-post' import userLikePostController from "./like-post";
import userSearchController from './search-user' import userSearchController from "./search-user";
import userSignupController from './signup' import userSignupController from "./signup";
import userUpdateEmailController from './update-email' import userUpdateEmailController from "./update-email";
import userUpdateNameController from './update-name' import userUpdateNameController from "./update-name";
import userUpdatePasswordController from './update-password' import userUpdatePasswordController from "./update-password";
import userUploadPictureController from './upload-picture' import userUploadPictureController from "./upload-picture";
const user = { const user = {
auth: userAuthController, auth: userAuthController,
@ -28,6 +28,6 @@ const user = {
updateName: userUpdateNameController, updateName: userUpdateNameController,
updatePassword: userUpdatePasswordController, updatePassword: userUpdatePasswordController,
uploadPicture: userUploadPictureController, uploadPicture: userUploadPictureController,
} as const } as const;
export default user export default user;

View file

@ -1,17 +1,17 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userLikeCommentController( async function userLikeCommentController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const userId = res.locals.user.id const userId = res.locals.user.id;
const { commentId } = req.body const { commentId } = req.body;
const result = await user.likeComment(commentId, userId) const result = await user.likeComment(commentId, userId);
handleResponse(res, result) handleResponse(res, result);
} }
export default userLikeCommentController export default userLikeCommentController;

View file

@ -1,17 +1,17 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userLikePostController( async function userLikePostController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const userId = res.locals.user.id const userId = res.locals.user.id;
const { postId } = req.body const { postId } = req.body;
const result = await user.likePost(postId, userId) const result = await user.likePost(postId, userId);
handleResponse(res, result) handleResponse(res, result);
} }
export default userLikePostController export default userLikePostController;

View file

@ -1,21 +1,21 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
async function userSearchController( async function userSearchController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const username = req.query.u as string const username = req.query.u as string;
if (username === undefined) { if (username === undefined) {
badRequest(res, 'Missing username') badRequest(res, "Missing username");
return return;
} }
const result = await user.searchUser(username) const result = await user.searchUser(username);
res.json(result) res.json(result);
} }
export default userSearchController export default userSearchController;

View file

@ -1,16 +1,16 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userSignupController( async function userSignupController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { username, email, password } = req.body const { username, email, password } = req.body;
const result = await user.signup({ username, email, password }) const result = await user.signup({ username, email, password });
handleResponse(res, result) handleResponse(res, result);
} }
export default userSignupController export default userSignupController;

View file

@ -1,17 +1,17 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userUpdateEmailController( async function userUpdateEmailController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { email } = req.body const { email } = req.body;
const id = res.locals.user.id const id = res.locals.user.id;
const result = await user.updateEmail({ id, email }) const result = await user.updateEmail({ id, email });
handleResponse(res, result) handleResponse(res, result);
} }
export default userUpdateEmailController export default userUpdateEmailController;

View file

@ -1,17 +1,17 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userUpdateNameController( async function userUpdateNameController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { displayName, username } = req.body const { displayName, username } = req.body;
const id = res.locals.user.id const id = res.locals.user.id;
const result = await user.updateName({ id, displayName, username }) const result = await user.updateName({ id, displayName, username });
handleResponse(res, result) handleResponse(res, result);
} }
export default userUpdateNameController export default userUpdateNameController;

View file

@ -1,17 +1,17 @@
import user from 'services/users' import user from "services/users";
import type { Request, Response } from 'express' import type { Request, Response } from "express";
import handleResponse from 'helpers/handle-response' import handleResponse from "helpers/handle-response";
async function userUpdatePasswordController( async function userUpdatePasswordController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
const { currentPassword, newPassword } = req.body const { currentPassword, newPassword } = req.body;
const id = res.locals.user.id const id = res.locals.user.id;
const result = await user.updatePassword(id, currentPassword, newPassword) const result = await user.updatePassword(id, currentPassword, newPassword);
handleResponse(res, result) handleResponse(res, result);
} }
export default userUpdatePasswordController export default userUpdatePasswordController;

View file

@ -1,33 +1,32 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */ import user from "services/users";
import user from 'services/users' import type { Request, Response } from "express";
import type { Request, Response } from 'express' import { badRequest } from "helpers/http-errors";
import { badRequest } from 'helpers/http-errors' import handleResponse from "helpers/handle-response";
import handleResponse from 'helpers/handle-response'
async function userUploadPictureController( async function userUploadPictureController(
req: Request, req: Request,
res: Response, res: Response
): Promise<void> { ): Promise<void> {
if (req.file === undefined) { if (req.file === undefined) {
badRequest(res, 'Expected a JPG or PNG file') badRequest(res, "Expected a JPG or PNG file");
return return;
} }
const userId = res.locals.user.id const userId = res.locals.user.id;
let url: string let url: string;
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === "development") {
url = `http://${ url = `http://${
process.env.AWS_BUCKET ?? '' process.env.AWS_BUCKET ?? ""
}.s3.localhost.localstack.cloud:4566/${req.file.key}` }.s3.localhost.localstack.cloud:4566/${req.file.key}`;
} else { } else {
url = req.file.location url = req.file.location;
} }
const result = await user.uploadPicture(userId, url) const result = await user.uploadPicture(userId, url);
handleResponse(res, result) handleResponse(res, result);
} }
export default userUploadPictureController export default userUploadPictureController;

View file

@ -1,43 +1,42 @@
import sharp from 'sharp' import sharp from "sharp";
import s3 from 'clients/s3-client' import s3 from "clients/s3-client";
import { GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3' import { GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
export default async function compressImage( export default async function compressImage(
imageName: string, imageName: string,
isProfilePicture: string, isProfilePicture: string
): Promise<Error | Record<never, never>> { ): Promise<Error | Record<never, never>> {
// Get file from s3 // Get file from s3
const { Body } = await s3.send( const { Body } = await s3.send(
new GetObjectCommand({ new GetObjectCommand({
Bucket: process.env.AWS_BUCKET ?? '', Bucket: process.env.AWS_BUCKET ?? "",
Key: imageName, Key: imageName,
}), })
) );
const imageBuffer = await Body?.transformToByteArray() const imageBuffer = await Body?.transformToByteArray();
const compressedImageBuffer = await sharp(imageBuffer) const compressedImageBuffer = await sharp(imageBuffer)
.resize( .resize(
isProfilePicture === 'true' ? 200 : undefined, isProfilePicture === "true" ? 200 : undefined,
isProfilePicture === 'true' ? 200 : undefined, isProfilePicture === "true" ? 200 : undefined
) )
.jpeg({ quality: 65 }) .jpeg({ quality: 65 })
.toBuffer() .toBuffer();
// Send file back // Send file back
const params = { const params = {
Bucket: process.env.AWS_BUCKET ?? '', Bucket: process.env.AWS_BUCKET ?? "",
Key: imageName, Key: imageName,
Body: compressedImageBuffer, Body: compressedImageBuffer,
ContentType: 'image/jpeg', ContentType: "image/jpeg",
ContentDisposition: 'inline', ContentDisposition: "inline",
} };
const { ETag } = await s3.send(new PutObjectCommand(params)) const { ETag } = await s3.send(new PutObjectCommand(params));
if (ETag !== null) { if (ETag !== null) {
return {} return {};
} else {
return new Error('Error while compressing image')
} }
return new Error("Error while compressing image");
} }

View file

@ -1,10 +1,11 @@
import { type Response } from 'express' import { type Response } from "express";
import { badRequest } from './http-errors' import { badRequest } from "./http-errors";
// biome-ignore lint/suspicious/noExplicitAny: don't question it.
export default function handleResponse(res: Response, result: any): void { export default function handleResponse(res: Response, result: any): void {
if (result instanceof Error) { if (result instanceof Error) {
badRequest(res, result.message) badRequest(res, result.message);
} else { } else {
res.json(result) res.json(result);
} }
} }

View file

@ -1,28 +1,28 @@
import { type Response } from 'express' import { type Response } from "express";
const sendErrorResponse = ( const sendErrorResponse = (
res: Response, res: Response,
status: number, status: number,
message: string, message: string
): void => { ): void => {
res.status(status).json({ error: message }) res.status(status).json({ error: message });
} };
export const badRequest = (res: Response, message = 'Bad Request'): void => { export const badRequest = (res: Response, message = "Bad Request"): void => {
sendErrorResponse(res, 400, message) sendErrorResponse(res, 400, message);
} };
export const unauthorized = (res: Response, message = 'Unauthorized'): void => { export const unauthorized = (res: Response, message = "Unauthorized"): void => {
sendErrorResponse(res, 401, message) sendErrorResponse(res, 401, message);
} };
export const forbidden = (res: Response, message = 'Forbidden'): void => { export const forbidden = (res: Response, message = "Forbidden"): void => {
sendErrorResponse(res, 403, message) sendErrorResponse(res, 403, message);
} };
export const internalServerError = ( export const internalServerError = (
res: Response, res: Response,
message = 'Internal Server Error', message = "Internal Server Error"
): void => { ): void => {
sendErrorResponse(res, 500, message) sendErrorResponse(res, 500, message);
} };

View file

@ -1,4 +1,4 @@
import winston from 'winston' import winston from "winston";
const levels = { const levels = {
error: 0, error: 0,
@ -6,47 +6,45 @@ const levels = {
info: 2, info: 2,
http: 3, http: 3,
debug: 4, debug: 4,
} };
const level = (): string => { const level = (): string => {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing const env = process.env.NODE_ENV || "development";
const env = process.env.NODE_ENV || 'development' const isDevelopment = env === "development";
const isDevelopment = env === 'development' return isDevelopment ? "debug" : "warn";
return isDevelopment ? 'debug' : 'warn' };
}
const colors = { const colors = {
error: 'red', error: "red",
warn: 'yellow', warn: "yellow",
info: 'green', info: "green",
http: 'magenta', http: "magenta",
debug: 'white', debug: "white",
} };
winston.addColors(colors) winston.addColors(colors);
const format = winston.format.combine( const format = winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:ms' }), winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss:ms" }),
winston.format.colorize({ all: true }), winston.format.colorize({ all: true }),
winston.format.printf( winston.format.printf(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions (info) => `${info.timestamp} ${info.level}: ${info.message}`
info => `${info.timestamp} ${info.level}: ${info.message}`, )
), );
)
const transports = [ const transports = [
new winston.transports.Console(), new winston.transports.Console(),
new winston.transports.File({ new winston.transports.File({
filename: 'logs/error.log', filename: "logs/error.log",
level: 'error', level: "error",
}), }),
] ];
const logger = winston.createLogger({ const logger = winston.createLogger({
level: level(), level: level(),
levels, levels,
format, format,
transports, transports,
}) });
export default logger export default logger;

View file

@ -1,11 +1,11 @@
import { type NotificationType } from '@prisma/client' import { type NotificationType } from "@prisma/client";
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
export async function createNotification( export async function createNotification(
fromUserId: string, fromUserId: string,
toUserId: string, toUserId: string,
content: string, content: string,
type: NotificationType, type: NotificationType
): Promise<Record<never, never> | Error> { ): Promise<Record<never, never> | Error> {
try { try {
await prisma.notifications.create({ await prisma.notifications.create({
@ -25,25 +25,25 @@ export async function createNotification(
}, },
}, },
}, },
}) });
return {} return {};
} catch (_) { } catch (_) {
return new Error('Error while creating notification') return new Error("Error while creating notification");
} }
} }
export async function countNotifications( export async function countNotifications(
toUserId: string, toUserId: string
): Promise<number | Error> { ): Promise<number | Error> {
try { try {
const count = await prisma.notifications.count({ const count = await prisma.notifications.count({
where: { where: {
toUserId, toUserId,
}, },
}) });
return count return count;
} catch (_) { } catch (_) {
return new Error('Error while counting user notifications') return new Error("Error while counting user notifications");
} }
} }

View file

@ -1,7 +1,7 @@
import { parse } from 'yaml' import { parse } from "yaml";
import { readFileSync } from 'fs' import { readFileSync } from "fs";
const swaggerConfigFile = readFileSync('./swagger.yaml', 'utf-8') const swaggerConfigFile = readFileSync("./swagger.yaml", "utf-8");
const swaggerDocument = parse(swaggerConfigFile) const swaggerDocument = parse(swaggerConfigFile);
export default swaggerDocument export default swaggerDocument;

View file

@ -1,7 +1,7 @@
interface jwtPayload { interface jwtPayload {
id: string id: string;
iat: number iat: number;
exp: number exp: number;
} }
export default jwtPayload export default jwtPayload;

View file

@ -1,13 +1,13 @@
interface User { interface User {
id?: string id?: string;
displayName?: string | null displayName?: string | null;
username?: string username?: string;
email?: string email?: string;
password?: string password?: string;
profileImage?: string | null profileImage?: string | null;
createdAt?: Date createdAt?: Date;
token?: string token?: string;
socketId?: string socketId?: string;
} }
export default User export default User;

View file

@ -1,56 +1,56 @@
import { verify } from 'jsonwebtoken' import { verify } from "jsonwebtoken";
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
import type { Response, Request, NextFunction } from 'express' import type { Response, Request, NextFunction } from "express";
import { unauthorized } from 'helpers/http-errors' import { unauthorized } from "helpers/http-errors";
import type jwtPayload from 'interfaces/jwt' import type jwtPayload from "interfaces/jwt";
async function authenticated( async function authenticated(
req: Request, req: Request,
res: Response, res: Response,
next: NextFunction, next: NextFunction
): Promise<void> { ): Promise<void> {
try { try {
if ( if (
req.headers.authorization === undefined || req.headers.authorization === undefined ||
req.headers.authorization.length === 0 req.headers.authorization.length === 0
) { ) {
unauthorized(res, 'Missing token') unauthorized(res, "Missing token");
return return;
} }
const token = req.headers.authorization.split(' ')[1] const token = req.headers.authorization.split(" ")[1];
if (token === undefined) { if (token === undefined) {
unauthorized(res, 'Missing token') unauthorized(res, "Missing token");
return return;
} }
const { id } = verify( const { id } = verify(
token, token,
process.env.JWT_ACCESS_SECRET ?? '', process.env.JWT_ACCESS_SECRET ?? ""
) as jwtPayload ) as jwtPayload;
if (id === undefined) { if (id === undefined) {
unauthorized(res, 'Invalid token') unauthorized(res, "Invalid token");
return return;
} }
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
id, id,
}, },
}) });
if (user === undefined) { if (user === undefined) {
unauthorized(res, 'User does not exists') unauthorized(res, "User does not exists");
return return;
} }
res.locals.user = user res.locals.user = user;
next() next();
} catch (e) { } catch (e) {
unauthorized(res, `JWT Error: ${(e as Error).message}`) unauthorized(res, `JWT Error: ${(e as Error).message}`);
} }
} }
export default authenticated export default authenticated;

View file

@ -1,12 +1,12 @@
import morgan, { type StreamOptions } from 'morgan' import morgan, { type StreamOptions } from "morgan";
import logger from 'helpers/logger' import logger from "helpers/logger";
const stream: StreamOptions = { const stream: StreamOptions = {
write: message => logger.http(message), write: (message) => logger.http(message),
} };
const morganMiddleware = morgan(':method :url :status - :response-time ms', { const morganMiddleware = morgan(":method :url :status - :response-time ms", {
stream, stream,
}) });
export default morganMiddleware export default morganMiddleware;

View file

@ -1,26 +1,26 @@
import rateLimit from 'express-rate-limit' import rateLimit from "express-rate-limit";
import RedisStore from 'rate-limit-redis' import RedisStore from "rate-limit-redis";
import redis from 'clients/redis-client' import redis from "clients/redis-client";
import logger from 'helpers/logger' import logger from "helpers/logger";
let skip: boolean let skip: boolean;
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') { if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
logger.info('Development environment detected. Rate limit is now disabled.') logger.info("Development environment detected. Rate limit is now disabled.");
skip = true skip = true;
} else { } else {
skip = false skip = false;
} }
const limiter = rateLimit({ const limiter = rateLimit({
windowMs: 1 * 60 * 1000, // 60 seconds windowMs: 1 * 60 * 1000, // 60 seconds
max: 5, max: 5,
message: { error: 'Too many requests' }, message: { error: "Too many requests" },
legacyHeaders: false, legacyHeaders: false,
skip: (_req, _res) => skip, skip: (_req, _res) => skip,
store: new RedisStore({ store: new RedisStore({
sendCommand: async (...args: string[]) => await redis.sendCommand(args), sendCommand: async (...args: string[]) => await redis.sendCommand(args),
}), }),
}) });
export default limiter export default limiter;

View file

@ -1,32 +1,33 @@
import type { Response, Request, NextFunction } from 'express' import type { Response, Request, NextFunction } from "express";
import multer from 'multer' import multer from "multer";
import multerConfig from 'config/multer' import multerConfig from "config/multer";
import compressImage from 'helpers/compress-image' import compressImage from "helpers/compress-image";
import { badRequest } from 'helpers/http-errors' import { badRequest } from "helpers/http-errors";
function uploadImage(req: Request, res: Response, next: NextFunction): void { function uploadImage(req: Request, res: Response, next: NextFunction): void {
const upload = multer(multerConfig).single('image') const upload = multer(multerConfig).single("image");
// biome-ignore lint/suspicious/noExplicitAny: i don't know, it's working, no need to change anything here.
upload(req, res, async (cb: multer.MulterError | Error | any) => { upload(req, res, async (cb: multer.MulterError | Error | any) => {
if (req.res?.locals.user == null) { if (req.res?.locals.user == null) {
badRequest(res, 'You must be logged in to upload a profile picture') badRequest(res, "You must be logged in to upload a profile picture");
return return;
} }
if (cb instanceof multer.MulterError || cb instanceof Error) { if (cb instanceof multer.MulterError || cb instanceof Error) {
badRequest(res, cb.message) badRequest(res, cb.message);
return return;
} }
if (req.file === undefined) { if (req.file === undefined) {
badRequest(res, 'Expected file') badRequest(res, "Expected file");
return return;
} }
await compressImage(req.file?.key, req.body.isProfilePicture) await compressImage(req.file?.key, req.body.isProfilePicture);
next() next();
}) });
} }
export default uploadImage export default uploadImage;

View file

@ -1,14 +1,14 @@
import { Router } from 'express' import { Router } from "express";
// Routers // Routers
import usersRouter from 'controllers/users-router' import usersRouter from "controllers/users-router";
import postsRouter from 'controllers/posts-router' import postsRouter from "controllers/posts-router";
import commentsRouter from 'controllers/comments-router' import commentsRouter from "controllers/comments-router";
const router = Router() const router = Router();
router.use('/user', usersRouter) router.use("/user", usersRouter);
router.use('/post', postsRouter) router.use("/post", postsRouter);
router.use('/comment', commentsRouter) router.use("/comment", commentsRouter);
export default router export default router;

View file

@ -1,26 +1,19 @@
import app from './app' import app from "./app";
import { createServer } from 'http' import { createServer } from "http";
import logger from 'helpers/logger' import logger from "helpers/logger";
import createSocketIOInstance from './socket'
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
import redis from 'clients/redis-client' import redis from "clients/redis-client";
const server = createServer(app) const server = createServer(app);
const io = createSocketIOInstance(server)
app.use((req, res, next) => {
res.locals.io = io
next()
})
server.listen(process.env.SERVER_PORT, () => { server.listen(process.env.SERVER_PORT, () => {
logger.info(`Server is running @ ${process.env.SERVER_PORT ?? ''}`) logger.info(`Server is running @ ${process.env.SERVER_PORT ?? ""}`);
}) });
process.on('SIGINT', async () => { process.on("SIGINT", async () => {
logger.warn('Closing server...') logger.warn("Closing server...");
await prisma.$disconnect() await prisma.$disconnect();
await redis.disconnect() await redis.disconnect();
server.close() server.close();
}) });

View file

@ -1,28 +1,28 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function commentCreateService( async function commentCreateService(
postId: string, postId: string,
content: string, content: string,
authorId: string, authorId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const post = await prisma.post.findFirst({ const post = await prisma.post.findFirst({
where: { where: {
id: postId, id: postId,
}, },
}) });
if (post === null) { if (post === null) {
return new Error('Post not found') return new Error("Post not found");
} }
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
id: authorId, id: authorId,
}, },
}) });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
const comment = await prisma.comments.create({ const comment = await prisma.comments.create({
@ -31,9 +31,9 @@ async function commentCreateService(
postId, postId,
userId: authorId, userId: authorId,
}, },
}) });
return comment return comment;
} }
export default commentCreateService export default commentCreateService;

View file

@ -1,17 +1,17 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function commentDeleteService( async function commentDeleteService(
commentId: string, commentId: string,
authorId: string, authorId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
id: authorId, id: authorId,
}, },
}) });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
const comment = await prisma.comments.findFirst({ const comment = await prisma.comments.findFirst({
@ -19,10 +19,10 @@ async function commentDeleteService(
id: commentId, id: commentId,
userId: user.id, userId: user.id,
}, },
}) });
if (comment === null) { if (comment === null) {
return new Error('Comment not found') return new Error("Comment not found");
} }
await prisma.comments.deleteMany({ await prisma.comments.deleteMany({
@ -30,9 +30,9 @@ async function commentDeleteService(
id: comment.id, id: comment.id,
userId: user.id, userId: user.id,
}, },
}) });
return {} return {};
} }
export default commentDeleteService export default commentDeleteService;

View file

@ -1,7 +1,7 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function commentFetchService( async function commentFetchService(
commentId: string, commentId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const comment = await prisma.comments.findFirst({ const comment = await prisma.comments.findFirst({
where: { where: {
@ -21,13 +21,13 @@ async function commentFetchService(
}, },
}, },
}, },
}) });
if (comment === null) { if (comment === null) {
return new Error('Comment not found') return new Error("Comment not found");
} }
return comment return comment;
} }
export default commentFetchService export default commentFetchService;

View file

@ -1,4 +1,4 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function commentFetchLikesService(id: string): Promise<unknown | Error> { async function commentFetchLikesService(id: string): Promise<unknown | Error> {
const post = await prisma.commentLike.findMany({ const post = await prisma.commentLike.findMany({
@ -14,13 +14,13 @@ async function commentFetchLikesService(id: string): Promise<unknown | Error> {
}, },
}, },
}, },
}) });
if (post === null) { if (post === null) {
return new Error('Comment not found') return new Error("Comment not found");
} }
return post return post;
} }
export default commentFetchLikesService export default commentFetchLikesService;

View file

@ -1,8 +1,8 @@
import commentCreateService from './create' import commentCreateService from "./create";
import commentDeleteService from './delete' import commentDeleteService from "./delete";
import commentFetchService from './fetch-info' import commentFetchService from "./fetch-info";
import commentFetchLikesService from './fetch-likes' import commentFetchLikesService from "./fetch-likes";
import commentUpdateService from './update' import commentUpdateService from "./update";
const comment = { const comment = {
create: commentCreateService, create: commentCreateService,
@ -10,6 +10,6 @@ const comment = {
fetch: commentFetchService, fetch: commentFetchService,
fetchLikes: commentFetchLikesService, fetchLikes: commentFetchLikesService,
update: commentUpdateService, update: commentUpdateService,
} as const } as const;
export default comment export default comment;

View file

@ -1,19 +1,19 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function commentUpdateService( async function commentUpdateService(
content: string, content: string,
authorId: string, authorId: string,
commentId: string, commentId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const comment = await prisma.comments.findFirst({ const comment = await prisma.comments.findFirst({
where: { where: {
id: commentId, id: commentId,
userId: authorId, userId: authorId,
}, },
}) });
if (comment === null) { if (comment === null) {
return new Error('Comment does not exists') return new Error("Comment does not exists");
} }
const updatedComment = await prisma.comments.update({ const updatedComment = await prisma.comments.update({
@ -37,8 +37,8 @@ async function commentUpdateService(
}, },
}, },
}, },
}) });
return updatedComment return updatedComment;
} }
export default commentUpdateService export default commentUpdateService;

View file

@ -1,13 +1,13 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function postCreateService( async function postCreateService(
content: string, content: string,
authorId: string, authorId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ where: { id: authorId } }) const user = await prisma.user.findFirst({ where: { id: authorId } });
if (user === null) { if (user === null) {
return new Error("This user doesn't exists") return new Error("This user doesn't exists");
} }
const post = await prisma.post.create({ const post = await prisma.post.create({
@ -15,9 +15,9 @@ async function postCreateService(
content, content,
authorId, authorId,
}, },
}) });
return post return post;
} }
export default postCreateService export default postCreateService;

View file

@ -1,30 +1,30 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function postDeleteService( async function postDeleteService(
postId: string, postId: string,
userId: string, userId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const post = await prisma.post.findFirst({ where: { id: postId } }) const post = await prisma.post.findFirst({ where: { id: postId } });
if (post === null) { if (post === null) {
return new Error('Post not found') return new Error("Post not found");
} }
if ((await prisma.user.findFirst({ where: { id: userId } })) === null) { if ((await prisma.user.findFirst({ where: { id: userId } })) === null) {
return new Error('User not found') return new Error("User not found");
} }
if (post.authorId !== userId) { if (post.authorId !== userId) {
return new Error('Forbidden') return new Error("Forbidden");
} }
await prisma.post.deleteMany({ await prisma.post.deleteMany({
where: { where: {
id: postId, id: postId,
}, },
}) });
return {} return {};
} }
export default postDeleteService export default postDeleteService;

View file

@ -1,7 +1,7 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function postFetchInfoService( async function postFetchInfoService(
id: string, id: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const post = await prisma.post.findFirst({ const post = await prisma.post.findFirst({
where: { where: {
@ -21,13 +21,13 @@ async function postFetchInfoService(
}, },
}, },
}, },
}) });
if (post === null) { if (post === null) {
return new Error('Post not found') return new Error("Post not found");
} }
return post return post;
} }
export default postFetchInfoService export default postFetchInfoService;

View file

@ -1,4 +1,4 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function postFetchLikesService(id: string): Promise<unknown | Error> { async function postFetchLikesService(id: string): Promise<unknown | Error> {
const post = await prisma.postLike.findMany({ const post = await prisma.postLike.findMany({
@ -14,13 +14,13 @@ async function postFetchLikesService(id: string): Promise<unknown | Error> {
}, },
}, },
}, },
}) });
if (post === null) { if (post === null) {
return new Error('Post not found') return new Error("Post not found");
} }
return post return post;
} }
export default postFetchLikesService export default postFetchLikesService;

View file

@ -1,8 +1,8 @@
import postCreateService from './create' import postCreateService from "./create";
import postDeleteService from './delete' import postDeleteService from "./delete";
import postFetchInfoService from './fetch-info' import postFetchInfoService from "./fetch-info";
import postFetchLikesService from './fetch-likes' import postFetchLikesService from "./fetch-likes";
import postUpdateService from './update' import postUpdateService from "./update";
const post = { const post = {
create: postCreateService, create: postCreateService,
@ -10,6 +10,6 @@ const post = {
fetch: postFetchInfoService, fetch: postFetchInfoService,
fetchLikes: postFetchLikesService, fetchLikes: postFetchLikesService,
update: postUpdateService, update: postUpdateService,
} as const } as const;
export default post export default post;

View file

@ -1,26 +1,27 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function postUpdateService( async function postUpdateService(
postId: string, postId: string,
content: string, content: string,
userId: string, userId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const post = await prisma.post.findFirst({ where: { id: postId } }) const post = await prisma.post.findFirst({ where: { id: postId } });
if (post === null) { if (post === null) {
return new Error('Post not found') return new Error("Post not found");
} }
if ((await prisma.user.findFirst({ where: { id: userId } })) === null) { if ((await prisma.user.findFirst({ where: { id: userId } })) === null) {
return new Error('User not found') return new Error("User not found");
} }
if (post.authorId !== userId) { if (post.authorId !== userId) {
return new Error('Forbidden') return new Error("Forbidden");
} }
if (post.content === content.trim()) { if (post.content === content.trim()) {
content = post.content let postContent: string = content;
postContent = post.content;
} }
const updatedPost = await prisma.post.update({ const updatedPost = await prisma.post.update({
@ -42,8 +43,8 @@ async function postUpdateService(
}, },
}, },
}, },
}) });
return updatedPost return updatedPost;
} }
export default postUpdateService export default postUpdateService;

View file

@ -1,7 +1,7 @@
import * as bcrypt from 'bcrypt' import * as bcrypt from "bcrypt";
import jsonwebtoken from 'jsonwebtoken' import jsonwebtoken from "jsonwebtoken";
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
import type User from 'interfaces/user' import type User from "interfaces/user";
async function userAuthService({ async function userAuthService({
email, email,
@ -11,37 +11,37 @@ async function userAuthService({
where: { where: {
email, email,
}, },
}) });
if (user == null) { if (user == null) {
return new Error('Invalid email or password') return new Error("Invalid email or password");
} }
if (email === undefined || password === undefined) { if (email === undefined || password === undefined) {
return new Error('Missing fields') return new Error("Missing fields");
} }
const validPassword = await bcrypt.compare( const validPassword = await bcrypt.compare(
password.replace(/ /g, ''), password.replace(/ /g, ""),
user.password, user.password
) );
if (!validPassword) { if (!validPassword) {
return new Error('Invalid email or password') return new Error("Invalid email or password");
} }
const { id } = user const { id } = user;
const bearer = jsonwebtoken.sign( const bearer = jsonwebtoken.sign(
{ id }, { id },
process.env.JWT_ACCESS_SECRET ?? '', process.env.JWT_ACCESS_SECRET ?? "",
{ expiresIn: '1d' }, { expiresIn: "1d" }
) );
return { return {
token: bearer, token: bearer,
user: user.username, user: user.username,
} };
} }
export default userAuthService export default userAuthService;

View file

@ -1,25 +1,25 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userDeleteService( async function userDeleteService(
userId: string, userId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ where: { id: userId } }) const user = await prisma.user.findFirst({ where: { id: userId } });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
if (user.id !== userId) { if (user.id !== userId) {
return new Error('Forbidden') return new Error("Forbidden");
} }
await prisma.user.deleteMany({ await prisma.user.deleteMany({
where: { where: {
id: userId, id: userId,
}, },
}) });
return {} return {};
} }
export default userDeleteService export default userDeleteService;

View file

@ -1,7 +1,7 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userFetchInfoService( async function userFetchInfoService(
username: string, username: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
@ -29,22 +29,22 @@ async function userFetchInfoService(
}, },
}, },
}, },
}) });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
const followers = user.followers.length const followers = user.followers.length;
const following = user.following.length const following = user.following.length;
const info = { const info = {
...user, ...user,
followers, followers,
following, following,
} };
return info return info;
} }
export default userFetchInfoService export default userFetchInfoService;

View file

@ -1,7 +1,7 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userFetchPostsService( async function userFetchPostsService(
username: string, username: string
): Promise<unknown | Error> { ): Promise<unknown | Error> {
const posts = await prisma.post.findMany({ const posts = await prisma.post.findMany({
where: { where: {
@ -23,8 +23,8 @@ async function userFetchPostsService(
}, },
}, },
}, },
}) });
return posts return posts;
} }
export default userFetchPostsService export default userFetchPostsService;

View file

@ -1,7 +1,7 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userFetchUserService( async function userFetchUserService(
id: string, id: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
@ -29,22 +29,22 @@ async function userFetchUserService(
}, },
}, },
}, },
}) });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
const followers = user.followers.length const followers = user.followers.length;
const following = user.following.length const following = user.following.length;
const info = { const info = {
...user, ...user,
followers, followers,
following, following,
} };
return info return info;
} }
export default userFetchUserService export default userFetchUserService;

View file

@ -1,31 +1,31 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userFollowService( async function userFollowService(
userId: string, userId: string,
followingUsername: string, followingUsername: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
if (userId === undefined || followingUsername === undefined) { if (userId === undefined || followingUsername === undefined) {
return new Error('Missing fields') return new Error("Missing fields");
} }
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
username: followingUsername, username: followingUsername,
}, },
}) });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
const userToFollow = await prisma.user.findFirst({ const userToFollow = await prisma.user.findFirst({
where: { where: {
id: userId, id: userId,
}, },
}) });
if (userToFollow === null) { if (userToFollow === null) {
return new Error('User to follow not found') return new Error("User to follow not found");
} }
const alreadyFollow = await prisma.follows.findFirst({ const alreadyFollow = await prisma.follows.findFirst({
@ -33,7 +33,7 @@ async function userFollowService(
followerId: user.id, followerId: user.id,
followingId: userToFollow.id, followingId: userToFollow.id,
}, },
}) });
if (alreadyFollow !== null) { if (alreadyFollow !== null) {
await prisma.follows.deleteMany({ await prisma.follows.deleteMany({
@ -41,8 +41,8 @@ async function userFollowService(
followerId: user.id, followerId: user.id,
followingId: userToFollow.id, followingId: userToFollow.id,
}, },
}) });
return {} return {};
} }
const follow = await prisma.follows.create({ const follow = await prisma.follows.create({
@ -50,9 +50,9 @@ async function userFollowService(
followerId: user.id, followerId: user.id,
followingId: userToFollow.id, followingId: userToFollow.id,
}, },
}) });
return follow return follow;
} }
export default userFollowService export default userFollowService;

View file

@ -1,17 +1,17 @@
import userAuthService from './auth' import userAuthService from "./auth";
import userDeleteService from './delete' import userDeleteService from "./delete";
import userFollowService from './follow-user' import userFollowService from "./follow-user";
import userFetchPostsService from './fetch-posts' import userFetchPostsService from "./fetch-posts";
import userFetchInfoService from './fetch-info' import userFetchInfoService from "./fetch-info";
import userFetchUserService from './fetch-user' import userFetchUserService from "./fetch-user";
import userLikeCommentService from './like-comment' import userLikeCommentService from "./like-comment";
import userLikePostService from './like-post' import userLikePostService from "./like-post";
import userSearchService from './search-user' import userSearchService from "./search-user";
import userSignupService from './signup' import userSignupService from "./signup";
import userUpdateEmailService from './update-email' import userUpdateEmailService from "./update-email";
import userUpdateNameService from './update-name' import userUpdateNameService from "./update-name";
import userUpdatePasswordService from './update-password' import userUpdatePasswordService from "./update-password";
import userUploadPictureService from './upload-picture' import userUploadPictureService from "./upload-picture";
const user = { const user = {
auth: userAuthService, auth: userAuthService,
@ -28,6 +28,6 @@ const user = {
updateName: userUpdateNameService, updateName: userUpdateNameService,
updatePassword: userUpdatePasswordService, updatePassword: userUpdatePasswordService,
uploadPicture: userUploadPictureService, uploadPicture: userUploadPictureService,
} as const } as const;
export default user export default user;

View file

@ -1,31 +1,31 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userLikeCommentService( async function userLikeCommentService(
commentId: string, commentId: string,
userId: string, userId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
if (commentId === undefined || userId === undefined) { if (commentId === undefined || userId === undefined) {
return new Error('Missing fields') return new Error("Missing fields");
} }
const comment = await prisma.comments.findFirst({ const comment = await prisma.comments.findFirst({
where: { where: {
id: commentId, id: commentId,
}, },
}) });
if (comment === null) { if (comment === null) {
return new Error('Comment not found') return new Error("Comment not found");
} }
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
id: userId, id: userId,
}, },
}) });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
const alreadyLiked = await prisma.commentLike.findFirst({ const alreadyLiked = await prisma.commentLike.findFirst({
@ -33,7 +33,7 @@ async function userLikeCommentService(
commentId: comment.id, commentId: comment.id,
userId: user.id, userId: user.id,
}, },
}) });
if (alreadyLiked !== null) { if (alreadyLiked !== null) {
await prisma.commentLike.deleteMany({ await prisma.commentLike.deleteMany({
@ -41,8 +41,8 @@ async function userLikeCommentService(
commentId: comment.id, commentId: comment.id,
userId: user.id, userId: user.id,
}, },
}) });
return {} return {};
} }
const like = await prisma.commentLike.create({ const like = await prisma.commentLike.create({
@ -50,9 +50,9 @@ async function userLikeCommentService(
commentId: comment.id, commentId: comment.id,
userId: user.id, userId: user.id,
}, },
}) });
return like return like;
} }
export default userLikeCommentService export default userLikeCommentService;

View file

@ -1,31 +1,31 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userLikePostService( async function userLikePostService(
postId: string, postId: string,
userId: string, userId: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
if (postId === undefined || userId === undefined) { if (postId === undefined || userId === undefined) {
return new Error('Missing fields') return new Error("Missing fields");
} }
const post = await prisma.post.findFirst({ const post = await prisma.post.findFirst({
where: { where: {
id: postId, id: postId,
}, },
}) });
if (post === null) { if (post === null) {
return new Error('Post not found') return new Error("Post not found");
} }
const user = await prisma.user.findFirst({ const user = await prisma.user.findFirst({
where: { where: {
id: userId, id: userId,
}, },
}) });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
const alreadyLiked = await prisma.postLike.findFirst({ const alreadyLiked = await prisma.postLike.findFirst({
@ -33,7 +33,7 @@ async function userLikePostService(
postId: post.id, postId: post.id,
userId: user.id, userId: user.id,
}, },
}) });
if (alreadyLiked !== null) { if (alreadyLiked !== null) {
await prisma.postLike.deleteMany({ await prisma.postLike.deleteMany({
@ -41,8 +41,8 @@ async function userLikePostService(
postId: post.id, postId: post.id,
userId: user.id, userId: user.id,
}, },
}) });
return {} return {};
} }
const like = await prisma.postLike.create({ const like = await prisma.postLike.create({
@ -50,9 +50,9 @@ async function userLikePostService(
postId: post.id, postId: post.id,
userId: user.id, userId: user.id,
}, },
}) });
return like return like;
} }
export default userLikePostService export default userLikePostService;

View file

@ -1,4 +1,4 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userSearchService(username: string): Promise<unknown | Error> { async function userSearchService(username: string): Promise<unknown | Error> {
const users = await prisma.user.findMany({ const users = await prisma.user.findMany({
@ -13,8 +13,8 @@ async function userSearchService(username: string): Promise<unknown | Error> {
profileImage: true, profileImage: true,
}, },
take: 10, take: 10,
}) });
return users return users;
} }
export default userSearchService export default userSearchService;

View file

@ -1,10 +1,10 @@
import * as bcrypt from 'bcrypt' import * as bcrypt from "bcrypt";
import validator from 'validator' import validator from "validator";
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
import type User from 'interfaces/user' import type User from "interfaces/user";
const passwordRegex = /^(?=.*[0-9])(?=.*[!@#$%^&*_])[a-zA-Z0-9!@#$%^&*_]{8,}$/ const passwordRegex = /^(?=.*[0-9])(?=.*[!@#$%^&*_])[a-zA-Z0-9!@#$%^&*_]{8,}$/;
const usernameRegex = /^[a-zA-Z0-9_.]{5,15}$/ const usernameRegex = /^[a-zA-Z0-9_.]{5,15}$/;
async function userSignupService({ async function userSignupService({
username, username,
@ -12,35 +12,35 @@ async function userSignupService({
password, password,
}: User): Promise<Record<string, unknown> | Error> { }: User): Promise<Record<string, unknown> | Error> {
if (username === undefined || email === undefined || password === undefined) { if (username === undefined || email === undefined || password === undefined) {
return new Error('Missing fields') return new Error("Missing fields");
} }
if (!passwordRegex.test(password)) { if (!passwordRegex.test(password)) {
return new Error( return new Error(
'Password must have at least 8 characters, one number and one special character.', "Password must have at least 8 characters, one number and one special character."
) );
} }
if (!usernameRegex.test(username)) { if (!usernameRegex.test(username)) {
return new Error( return new Error(
'Username not allowed. Only alphanumerics characters (uppercase and lowercase words), underscore, dots and it must be between 5 and 15 characters', "Username not allowed. Only alphanumerics characters (uppercase and lowercase words), underscore, dots and it must be between 5 and 15 characters"
) );
} }
if (!validator.isEmail(email)) { if (!validator.isEmail(email)) {
return new Error('Invalid email format') return new Error("Invalid email format");
} }
if ((await prisma.user.findFirst({ where: { username } })) != null) { if ((await prisma.user.findFirst({ where: { username } })) != null) {
return new Error('Username already in use') return new Error("Username already in use");
} }
if ((await prisma.user.findFirst({ where: { email } })) != null) { if ((await prisma.user.findFirst({ where: { email } })) != null) {
return new Error('Email already in use') return new Error("Email already in use");
} }
const salt = await bcrypt.genSalt(15) const salt = await bcrypt.genSalt(15);
const hashedPassword = await bcrypt.hash(password.replace(/ /g, ''), salt) // Removes every space in the string const hashedPassword = await bcrypt.hash(password.replace(/ /g, ""), salt); // Removes every space in the string
const user = await prisma.user.create({ const user = await prisma.user.create({
data: { data: {
@ -53,9 +53,9 @@ async function userSignupService({
username: true, username: true,
createdAt: true, createdAt: true,
}, },
}) });
return user return user;
} }
export default userSignupService export default userSignupService;

View file

@ -1,24 +1,24 @@
import type User from 'interfaces/user' import type User from "interfaces/user";
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userUpdateEmailService({ async function userUpdateEmailService({
id, id,
email, email,
}: User): Promise<Record<string, unknown> | Error> { }: User): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ where: { id } }) const user = await prisma.user.findFirst({ where: { id } });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
if (user.id !== id) { if (user.id !== id) {
return new Error('Forbidden') return new Error("Forbidden");
} }
if (email !== undefined && email.trim() !== user.email) { if (email !== undefined && email.trim() !== user.email) {
const existingUser = await prisma.user.findFirst({ where: { email } }) const existingUser = await prisma.user.findFirst({ where: { email } });
if (existingUser != null && existingUser.email !== user.email) { if (existingUser != null && existingUser.email !== user.email) {
return new Error('Email already in use') return new Error("Email already in use");
} }
} }
@ -34,9 +34,9 @@ async function userUpdateEmailService({
username: true, username: true,
createdAt: true, createdAt: true,
}, },
}) });
return { message: 'Successfully updated user email' } return { message: "Successfully updated user email" };
} }
export default userUpdateEmailService export default userUpdateEmailService;

View file

@ -1,29 +1,29 @@
import type User from 'interfaces/user' import type User from "interfaces/user";
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userUpdateNameService({ async function userUpdateNameService({
id, id,
displayName, displayName,
username, username,
}: User): Promise<Record<string, unknown> | Error> { }: User): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ where: { id } }) const user = await prisma.user.findFirst({ where: { id } });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
// Check if the provided username is different from the current user's data // Check if the provided username is different from the current user's data
// if different, queries are made to check if the new username is already in use. // if different, queries are made to check if the new username is already in use.
if (username !== undefined && username.trim() !== user.username) { if (username !== undefined && username.trim() !== user.username) {
const existingUser = await prisma.user.findFirst({ where: { username } }) const existingUser = await prisma.user.findFirst({ where: { username } });
if (existingUser != null && existingUser.username !== user.username) { if (existingUser != null && existingUser.username !== user.username) {
return new Error('Username already in use') return new Error("Username already in use");
} }
} }
if (user.id !== id) { if (user.id !== id) {
return new Error('Forbidden') return new Error("Forbidden");
} }
const updatedUser = await prisma.user.update({ const updatedUser = await prisma.user.update({
@ -39,9 +39,9 @@ async function userUpdateNameService({
username: true, username: true,
createdAt: true, createdAt: true,
}, },
}) });
return updatedUser return updatedUser;
} }
export default userUpdateNameService export default userUpdateNameService;

View file

@ -1,40 +1,40 @@
import * as bcrypt from 'bcrypt' import * as bcrypt from "bcrypt";
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
const passwordRegex = /^(?=.*[0-9])(?=.*[!@#$%^&*_])[a-zA-Z0-9!@#$%^&*_]{8,}$/ const passwordRegex = /^(?=.*[0-9])(?=.*[!@#$%^&*_])[a-zA-Z0-9!@#$%^&*_]{8,}$/;
async function userUpdatePasswordService( async function userUpdatePasswordService(
id: string, id: string,
currentPassword: string, currentPassword: string,
newPassword: string, newPassword: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
if (!passwordRegex.test(newPassword)) { if (!passwordRegex.test(newPassword)) {
return new Error( return new Error(
'New password must have at least 8 characters, one number and one special character.', "New password must have at least 8 characters, one number and one special character."
) );
} }
const user = await prisma.user.findFirst({ where: { id } }) const user = await prisma.user.findFirst({ where: { id } });
if (user === null) { if (user === null) {
return new Error('User not found') return new Error("User not found");
} }
if (user.id !== id) { if (user.id !== id) {
return new Error('Forbidden') return new Error("Forbidden");
} }
const validPassword = await bcrypt.compare( const validPassword = await bcrypt.compare(
currentPassword.replace(/ /g, ''), currentPassword.replace(/ /g, ""),
user.password, user.password
) );
if (!validPassword) { if (!validPassword) {
return new Error('Invalid password') return new Error("Invalid password");
} }
const salt = await bcrypt.genSalt(15) const salt = await bcrypt.genSalt(15);
const hashedPassword = await bcrypt.hash(newPassword.replace(/ /g, ''), salt) const hashedPassword = await bcrypt.hash(newPassword.replace(/ /g, ""), salt);
await prisma.user.update({ await prisma.user.update({
where: { where: {
@ -48,9 +48,9 @@ async function userUpdatePasswordService(
username: true, username: true,
createdAt: true, createdAt: true,
}, },
}) });
return { message: 'Successfully updated user password' } return { message: "Successfully updated user password" };
} }
export default userUpdatePasswordService export default userUpdatePasswordService;

View file

@ -1,13 +1,13 @@
import prisma from 'clients/prisma-client' import prisma from "clients/prisma-client";
async function userUploadPictureService( async function userUploadPictureService(
authorId: string, authorId: string,
url: string, url: string
): Promise<Record<string, unknown> | Error> { ): Promise<Record<string, unknown> | Error> {
const user = await prisma.user.findFirst({ where: { id: authorId } }) const user = await prisma.user.findFirst({ where: { id: authorId } });
if (user == null) { if (user == null) {
return new Error('User does not exists') return new Error("User does not exists");
} }
const updatedUser = await prisma.user.update({ const updatedUser = await prisma.user.update({
@ -20,9 +20,9 @@ async function userUploadPictureService(
select: { select: {
profileImage: true, profileImage: true,
}, },
}) });
return updatedUser return updatedUser;
} }
export default userUploadPictureService export default userUploadPictureService;

View file

@ -1,44 +0,0 @@
import prisma from 'clients/prisma-client'
import logger from 'helpers/logger'
import { Server } from 'socket.io'
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export default function createSocketIOInstance(httpServer: any) {
const io = new Server(httpServer, {
cors: {
origin: process.env.CORS_ORIGIN ?? '*',
},
})
io.use(async (socket, next) => {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (!socket.handshake.auth?.id) {
const error = new Error()
error.message = 'Unauthorized'
next(error)
}
await prisma.user.update({
where: {
id: socket.handshake.auth.id,
},
data: {
socketId: socket.id,
},
})
next()
})
/*
const handleConnection = (socket) => {
// TODO
}
*/
io.on('connection', _ => {
logger.info('Placeholder')
})
return io
}