mirror of
https://github.com/hknsh/project-knedita.git
synced 2024-11-28 17:41:15 +00:00
chore: updated every file to match biome rules
This commit is contained in:
parent
b6b978c017
commit
7087050fc0
89 changed files with 1071 additions and 1130 deletions
7
src/@types/express.d.ts
vendored
7
src/@types/express.d.ts
vendored
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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),
|
||||||
}),
|
})
|
||||||
)
|
);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
64
src/app.ts
64
src/app.ts
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
})
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
Loading…
Reference in a new issue