mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
continue extracting user controllers out of routes
This commit is contained in:
@@ -10,6 +10,7 @@ import getBeerRecommendations from '@/services/BeerPost/getBeerRecommendations';
|
|||||||
import getAllBeerPosts from '@/services/BeerPost/getAllBeerPosts';
|
import getAllBeerPosts from '@/services/BeerPost/getAllBeerPosts';
|
||||||
import DBClient from '@/prisma/DBClient';
|
import DBClient from '@/prisma/DBClient';
|
||||||
import createNewBeerPost from '@/services/BeerPost/createNewBeerPost';
|
import createNewBeerPost from '@/services/BeerPost/createNewBeerPost';
|
||||||
|
import getBeerPostsByPostedById from '@/services/BeerPost/getBeerPostsByPostedById';
|
||||||
import {
|
import {
|
||||||
BeerPostRequest,
|
BeerPostRequest,
|
||||||
CreateBeerPostRequest,
|
CreateBeerPostRequest,
|
||||||
@@ -17,6 +18,7 @@ import {
|
|||||||
GetAllBeerPostsRequest,
|
GetAllBeerPostsRequest,
|
||||||
GetBeerRecommendationsRequest,
|
GetBeerRecommendationsRequest,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
import { GetPostsByUserIdRequest } from '../types';
|
||||||
|
|
||||||
export const checkIfBeerPostOwner = async <BeerPostRequestType extends BeerPostRequest>(
|
export const checkIfBeerPostOwner = async <BeerPostRequestType extends BeerPostRequest>(
|
||||||
req: BeerPostRequestType,
|
req: BeerPostRequestType,
|
||||||
@@ -141,3 +143,32 @@ export const createBeerPost = async (
|
|||||||
success: true,
|
success: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getBeerPostsByUserId = async (
|
||||||
|
req: GetPostsByUserIdRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const pageNum = parseInt(req.query.page_num, 10);
|
||||||
|
const pageSize = parseInt(req.query.page_size, 10);
|
||||||
|
|
||||||
|
const { id } = req.query;
|
||||||
|
|
||||||
|
const beerPosts = await getBeerPostsByPostedById({
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
postedById: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const beerPostCount = await DBClient.instance.beerPost.count({
|
||||||
|
where: { postedBy: { id } },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.setHeader('X-Total-Count', beerPostCount);
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
message: `Beer posts by user ${id} fetched successfully`,
|
||||||
|
statusCode: 200,
|
||||||
|
payload: beerPosts,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
36
src/controllers/posts/breweries/index.ts
Normal file
36
src/controllers/posts/breweries/index.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import DBClient from '@/prisma/DBClient';
|
||||||
|
import getAllBreweryPostsByPostedById from '@/services/BreweryPost/getAllBreweryPostsByPostedById';
|
||||||
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
import { NextApiResponse } from 'next';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { GetPostsByUserIdRequest } from '../types';
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export const getBreweryPostsByUserId = async (
|
||||||
|
req: GetPostsByUserIdRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const pageNum = parseInt(req.query.page_num, 10);
|
||||||
|
const pageSize = parseInt(req.query.page_size, 10);
|
||||||
|
|
||||||
|
const { id } = req.query;
|
||||||
|
|
||||||
|
const breweryPosts = await getAllBreweryPostsByPostedById({
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
postedById: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const breweryPostCount = await DBClient.instance.breweryPost.count({
|
||||||
|
where: { postedBy: { id } },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.setHeader('X-Total-Count', breweryPostCount);
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
message: `Brewery posts by user ${id} fetched successfully`,
|
||||||
|
statusCode: 200,
|
||||||
|
payload: breweryPosts,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -3,3 +3,7 @@ import { NextApiRequest } from 'next';
|
|||||||
export interface GetAllPostsRequest extends NextApiRequest {
|
export interface GetAllPostsRequest extends NextApiRequest {
|
||||||
query: { page_size: string; page_num: string };
|
query: { page_size: string; page_num: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GetPostsByUserIdRequest extends NextApiRequest {
|
||||||
|
query: { id: string; page_size: string; page_num: string };
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,11 +19,17 @@ import { verifyConfirmationToken } from '@/config/jwt';
|
|||||||
import updateUserToBeConfirmedById from '@/services/User/updateUserToBeConfirmedById';
|
import updateUserToBeConfirmedById from '@/services/User/updateUserToBeConfirmedById';
|
||||||
import DBClient from '@/prisma/DBClient';
|
import DBClient from '@/prisma/DBClient';
|
||||||
import sendResetPasswordEmail from '@/services/User/sendResetPasswordEmail';
|
import sendResetPasswordEmail from '@/services/User/sendResetPasswordEmail';
|
||||||
|
import { hashPassword } from '@/config/auth/passwordFns';
|
||||||
|
import deleteUserById from '@/services/User/deleteUserById';
|
||||||
import {
|
import {
|
||||||
|
CheckEmailRequest,
|
||||||
|
CheckUsernameRequest,
|
||||||
RegisterUserRequest,
|
RegisterUserRequest,
|
||||||
ResetPasswordRequest,
|
ResetPasswordRequest,
|
||||||
TokenValidationRequest,
|
TokenValidationRequest,
|
||||||
|
UpdatePasswordRequest,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
import { EditUserRequest, UserRouteRequest } from '../profile/types';
|
||||||
|
|
||||||
export const authenticateUser = expressWrapper(
|
export const authenticateUser = expressWrapper(
|
||||||
async (
|
async (
|
||||||
@@ -165,3 +171,135 @@ export const resetPassword = async (
|
|||||||
'If an account with that email exists, we have sent you an email to reset your password.',
|
'If an account with that email exists, we have sent you an email to reset your password.',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const sendCurrentUser = async (
|
||||||
|
req: UserExtendedNextApiRequest,
|
||||||
|
res: NextApiResponse,
|
||||||
|
) => {
|
||||||
|
const { user } = req;
|
||||||
|
res.status(200).json({
|
||||||
|
message: `Currently logged in as ${user!.username}`,
|
||||||
|
statusCode: 200,
|
||||||
|
success: true,
|
||||||
|
payload: user,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkEmail = async (req: CheckEmailRequest, res: NextApiResponse) => {
|
||||||
|
const { email: emailToCheck } = req.query;
|
||||||
|
|
||||||
|
const email = await findUserByEmail(emailToCheck);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
payload: { emailIsTaken: !!email },
|
||||||
|
statusCode: 200,
|
||||||
|
message: 'Getting email availability.',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkUsername = async (req: CheckUsernameRequest, res: NextApiResponse) => {
|
||||||
|
const { username: usernameToCheck } = req.query;
|
||||||
|
|
||||||
|
const username = await findUserByUsername(usernameToCheck);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
payload: { usernameIsTaken: !!username },
|
||||||
|
statusCode: 200,
|
||||||
|
message: username ? 'Username is taken.' : 'Username is available.',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updatePassword = async (
|
||||||
|
req: UpdatePasswordRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const { password } = req.body;
|
||||||
|
const hash = await hashPassword(password);
|
||||||
|
|
||||||
|
const user = req.user!;
|
||||||
|
await DBClient.instance.user.update({
|
||||||
|
data: { hash },
|
||||||
|
where: { id: user.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: 'Updated user password.',
|
||||||
|
statusCode: 200,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const resendConfirmation = async (
|
||||||
|
req: UserExtendedNextApiRequest,
|
||||||
|
res: NextApiResponse,
|
||||||
|
) => {
|
||||||
|
const user = req.user!;
|
||||||
|
|
||||||
|
await sendConfirmationEmail(user);
|
||||||
|
res.status(200).json({
|
||||||
|
message: `Resent the confirmation email for ${user.username}.`,
|
||||||
|
statusCode: 200,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const editUserInfo = async (
|
||||||
|
req: EditUserRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const { email, firstName, lastName, username } = req.body;
|
||||||
|
|
||||||
|
const [usernameIsTaken, emailIsTaken] = await Promise.all([
|
||||||
|
findUserByUsername(username),
|
||||||
|
findUserByEmail(email),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const emailChanged = req.user!.email !== email;
|
||||||
|
const usernameChanged = req.user!.username !== username;
|
||||||
|
|
||||||
|
if (emailIsTaken && emailChanged) {
|
||||||
|
throw new ServerError('Email is already taken', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usernameIsTaken && usernameChanged) {
|
||||||
|
throw new ServerError('Username is already taken', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedUser = await DBClient.instance.user.update({
|
||||||
|
where: { id: req.user!.id },
|
||||||
|
data: {
|
||||||
|
email,
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
username,
|
||||||
|
accountIsVerified: emailChanged ? false : undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: 'User edited successfully',
|
||||||
|
payload: updatedUser,
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAccount = async (
|
||||||
|
req: UserRouteRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const { id } = req.query;
|
||||||
|
const deletedUser = await deleteUserById(id);
|
||||||
|
|
||||||
|
if (!deletedUser) {
|
||||||
|
throw new ServerError('Could not find a user with that id.', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
message: 'Successfully deleted user.',
|
||||||
|
statusCode: 200,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import { CreateUserValidationSchema } from '@/services/User/schema/CreateUserValidationSchemas';
|
import {
|
||||||
|
CreateUserValidationSchema,
|
||||||
|
UpdatePasswordSchema,
|
||||||
|
} from '@/services/User/schema/CreateUserValidationSchemas';
|
||||||
import TokenValidationSchema from '@/services/User/schema/TokenValidationSchema';
|
import TokenValidationSchema from '@/services/User/schema/TokenValidationSchema';
|
||||||
import { NextApiRequest } from 'next';
|
import { NextApiRequest } from 'next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@@ -15,3 +18,14 @@ export interface TokenValidationRequest extends UserExtendedNextApiRequest {
|
|||||||
export interface ResetPasswordRequest extends NextApiRequest {
|
export interface ResetPasswordRequest extends NextApiRequest {
|
||||||
body: { email: string };
|
body: { email: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdatePasswordRequest extends UserExtendedNextApiRequest {
|
||||||
|
body: z.infer<typeof UpdatePasswordSchema>;
|
||||||
|
}
|
||||||
|
export interface CheckEmailRequest extends NextApiRequest {
|
||||||
|
query: { email: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CheckUsernameRequest extends NextApiRequest {
|
||||||
|
query: { username: string };
|
||||||
|
}
|
||||||
237
src/controllers/users/profile/index.ts
Normal file
237
src/controllers/users/profile/index.ts
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
import ServerError from '@/config/util/ServerError';
|
||||||
|
import DBClient from '@/prisma/DBClient';
|
||||||
|
import findUserById from '@/services/User/findUserById';
|
||||||
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
import { NextApiResponse } from 'next';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import getUsersFollowingUser from '@/services/UserFollows/getUsersFollowingUser';
|
||||||
|
import getUsersFollowedByUser from '@/services/UserFollows/getUsersFollowedByUser';
|
||||||
|
import { NextHandler } from 'next-connect';
|
||||||
|
import updateUserAvatarById, {
|
||||||
|
UpdateUserAvatarByIdParams,
|
||||||
|
} from '@/services/UserAccount/UpdateUserAvatarByIdParams';
|
||||||
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
|
import updateUserProfileById from '@/services/User/updateUserProfileById';
|
||||||
|
import {
|
||||||
|
UserRouteRequest,
|
||||||
|
GetUserFollowInfoRequest,
|
||||||
|
EditUserRequest,
|
||||||
|
UpdateAvatarRequest,
|
||||||
|
UpdateProfileRequest,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
export const followUser = async (
|
||||||
|
req: UserRouteRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const { id } = req.query;
|
||||||
|
|
||||||
|
const user = await findUserById(id);
|
||||||
|
if (!user) {
|
||||||
|
throw new ServerError('User not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentUser = req.user!;
|
||||||
|
const userIsFollowedBySessionUser = await DBClient.instance.userFollow.findFirst({
|
||||||
|
where: {
|
||||||
|
followerId: currentUser.id,
|
||||||
|
followingId: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userIsFollowedBySessionUser) {
|
||||||
|
await DBClient.instance.userFollow.create({
|
||||||
|
data: { followerId: currentUser.id, followingId: id },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
message: 'Now following user.',
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await DBClient.instance.userFollow.delete({
|
||||||
|
where: {
|
||||||
|
followerId_followingId: {
|
||||||
|
followerId: currentUser.id,
|
||||||
|
followingId: id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
message: 'No longer following user.',
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getUserFollowers = async (
|
||||||
|
req: GetUserFollowInfoRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
const { id, page_num, page_size } = req.query;
|
||||||
|
|
||||||
|
const user = await findUserById(id);
|
||||||
|
if (!user) {
|
||||||
|
throw new ServerError('User not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageNum = parseInt(page_num, 10);
|
||||||
|
const pageSize = parseInt(page_size, 10);
|
||||||
|
|
||||||
|
const following = await getUsersFollowingUser({
|
||||||
|
userId: id,
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
});
|
||||||
|
const followingCount = await DBClient.instance.userFollow.count({
|
||||||
|
where: { following: { id } },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.setHeader('X-Total-Count', followingCount);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: 'Retrieved users that are followed by queried user',
|
||||||
|
payload: following,
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getUsersFollowed = async (
|
||||||
|
req: GetUserFollowInfoRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
const { id, page_num, page_size } = req.query;
|
||||||
|
|
||||||
|
const user = await findUserById(id);
|
||||||
|
if (!user) {
|
||||||
|
throw new ServerError('User not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageNum = parseInt(page_num, 10);
|
||||||
|
const pageSize = parseInt(page_size, 10);
|
||||||
|
|
||||||
|
const following = await getUsersFollowedByUser({
|
||||||
|
userId: id,
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
});
|
||||||
|
const followingCount = await DBClient.instance.userFollow.count({
|
||||||
|
where: { follower: { id } },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.setHeader('X-Total-Count', followingCount);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: 'Retrieved users that are followed by queried user',
|
||||||
|
payload: following,
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkIfUserIsFollowedBySessionUser = async (
|
||||||
|
req: GetUserFollowInfoRequest,
|
||||||
|
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||||
|
) => {
|
||||||
|
const { id } = req.query;
|
||||||
|
|
||||||
|
const user = await findUserById(id);
|
||||||
|
if (!user) {
|
||||||
|
throw new ServerError('User not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentUser = req.user!;
|
||||||
|
|
||||||
|
const userIsFollowedBySessionUser = await DBClient.instance.userFollow.findFirst({
|
||||||
|
where: { followerId: currentUser.id, followingId: id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userIsFollowedBySessionUser) {
|
||||||
|
res.status(200).json({
|
||||||
|
message: 'User is not followed by the current user.',
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
payload: { isFollowed: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
message: 'User is followed by the current user.',
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
payload: { isFollowed: true },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkIfUserCanEditUser = async (
|
||||||
|
req: EditUserRequest,
|
||||||
|
res: NextApiResponse,
|
||||||
|
next: NextHandler,
|
||||||
|
) => {
|
||||||
|
const authenticatedUser = req.user!;
|
||||||
|
|
||||||
|
const userToUpdate = await findUserById(req.query.id);
|
||||||
|
if (!userToUpdate) {
|
||||||
|
throw new ServerError('User not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authenticatedUser.id !== userToUpdate.id) {
|
||||||
|
throw new ServerError('You are not permitted to modify this user', 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkIfUserCanUpdateProfile = async <T extends UserExtendedNextApiRequest>(
|
||||||
|
req: T,
|
||||||
|
res: NextApiResponse,
|
||||||
|
next: NextHandler,
|
||||||
|
) => {
|
||||||
|
const user = req.user!;
|
||||||
|
|
||||||
|
if (user.id !== req.query.id) {
|
||||||
|
throw new ServerError('You can only update your own profile.', 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
await next();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateAvatar = async (req: UpdateAvatarRequest, res: NextApiResponse) => {
|
||||||
|
const { file, user } = req;
|
||||||
|
|
||||||
|
const avatar: UpdateUserAvatarByIdParams['data']['avatar'] = {
|
||||||
|
alt: file.originalname,
|
||||||
|
path: file.path,
|
||||||
|
caption: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateUserAvatarById({ id: user!.id, data: { avatar } });
|
||||||
|
res.status(200).json({
|
||||||
|
message: 'User avatar updated successfully.',
|
||||||
|
statusCode: 200,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateProfile = async (req: UpdateProfileRequest, res: NextApiResponse) => {
|
||||||
|
const user = req.user!;
|
||||||
|
const { body } = req;
|
||||||
|
|
||||||
|
await updateUserProfileById({ id: user!.id, data: { bio: body.bio } });
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
message: 'Profile updated successfully.',
|
||||||
|
statusCode: 200,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
23
src/controllers/users/profile/types/index.ts
Normal file
23
src/controllers/users/profile/types/index.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
|
import EditUserSchema from '@/services/User/schema/EditUserSchema';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export interface UserRouteRequest extends UserExtendedNextApiRequest {
|
||||||
|
query: { id: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetUserFollowInfoRequest extends UserExtendedNextApiRequest {
|
||||||
|
query: { id: string; page_size: string; page_num: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditUserRequest extends UserRouteRequest {
|
||||||
|
body: z.infer<typeof EditUserSchema>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateAvatarRequest extends UserExtendedNextApiRequest {
|
||||||
|
file: Express.Multer.File;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateProfileRequest extends UserExtendedNextApiRequest {
|
||||||
|
body: { bio: string };
|
||||||
|
}
|
||||||
@@ -2,9 +2,7 @@ import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
|||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import { followUser } from '@/controllers/users/profile';
|
||||||
import DBClient from '@/prisma/DBClient';
|
|
||||||
import findUserById from '@/services/User/findUserById';
|
|
||||||
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
|
||||||
@@ -21,55 +19,6 @@ const router = createRouter<
|
|||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const followUser = async (
|
|
||||||
req: GetUserFollowInfoRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
const { id } = req.query;
|
|
||||||
|
|
||||||
const user = await findUserById(id);
|
|
||||||
if (!user) {
|
|
||||||
throw new ServerError('User not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentUser = req.user!;
|
|
||||||
const userIsFollowedBySessionUser = await DBClient.instance.userFollow.findFirst({
|
|
||||||
where: {
|
|
||||||
followerId: currentUser.id,
|
|
||||||
followingId: id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!userIsFollowedBySessionUser) {
|
|
||||||
await DBClient.instance.userFollow.create({
|
|
||||||
data: { followerId: currentUser.id, followingId: id },
|
|
||||||
});
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
message: 'Now following user.',
|
|
||||||
success: true,
|
|
||||||
statusCode: 200,
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await DBClient.instance.userFollow.delete({
|
|
||||||
where: {
|
|
||||||
followerId_followingId: {
|
|
||||||
followerId: currentUser.id,
|
|
||||||
followingId: id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
message: 'No longer following user.',
|
|
||||||
success: true,
|
|
||||||
statusCode: 200,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
|
|||||||
@@ -1,59 +1,18 @@
|
|||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
|
||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import { getUserFollowers } from '@/controllers/users/profile';
|
||||||
import DBClient from '@/prisma/DBClient';
|
import { GetUserFollowInfoRequest } from '@/controllers/users/profile/types';
|
||||||
import findUserById from '@/services/User/findUserById';
|
|
||||||
import getUsersFollowingUser from '@/services/UserFollows/getUsersFollowingUser';
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
interface GetUserFollowInfoRequest extends UserExtendedNextApiRequest {
|
|
||||||
query: { id: string; page_size: string; page_num: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
GetUserFollowInfoRequest,
|
GetUserFollowInfoRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const getFollowingInfo = async (
|
|
||||||
req: GetUserFollowInfoRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
const { id, page_num, page_size } = req.query;
|
|
||||||
|
|
||||||
const user = await findUserById(id);
|
|
||||||
if (!user) {
|
|
||||||
throw new ServerError('User not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const pageNum = parseInt(page_num, 10);
|
|
||||||
const pageSize = parseInt(page_size, 10);
|
|
||||||
|
|
||||||
const following = await getUsersFollowingUser({
|
|
||||||
userId: id,
|
|
||||||
pageNum,
|
|
||||||
pageSize,
|
|
||||||
});
|
|
||||||
const followingCount = await DBClient.instance.userFollow.count({
|
|
||||||
where: { following: { id } },
|
|
||||||
});
|
|
||||||
|
|
||||||
res.setHeader('X-Total-Count', followingCount);
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
message: 'Retrieved users that are followed by queried user',
|
|
||||||
payload: following,
|
|
||||||
success: true,
|
|
||||||
statusCode: 200,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
validateRequest({
|
validateRequest({
|
||||||
querySchema: z.object({
|
querySchema: z.object({
|
||||||
@@ -62,7 +21,7 @@ router.get(
|
|||||||
page_num: z.string().regex(/^\d+$/),
|
page_num: z.string().regex(/^\d+$/),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
getFollowingInfo,
|
getUserFollowers,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handler = router.handler(NextConnectOptions);
|
const handler = router.handler(NextConnectOptions);
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import { getUsersFollowed } from '@/controllers/users/profile';
|
||||||
import DBClient from '@/prisma/DBClient';
|
|
||||||
import findUserById from '@/services/User/findUserById';
|
|
||||||
import getUsersFollowedByUser from '@/services/UserFollows/getUsersFollowedByUser';
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
@@ -20,40 +17,6 @@ const router = createRouter<
|
|||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const getFollowingInfo = async (
|
|
||||||
req: GetUserFollowInfoRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
const { id, page_num, page_size } = req.query;
|
|
||||||
|
|
||||||
const user = await findUserById(id);
|
|
||||||
if (!user) {
|
|
||||||
throw new ServerError('User not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const pageNum = parseInt(page_num, 10);
|
|
||||||
const pageSize = parseInt(page_size, 10);
|
|
||||||
|
|
||||||
const following = await getUsersFollowedByUser({
|
|
||||||
userId: id,
|
|
||||||
pageNum,
|
|
||||||
pageSize,
|
|
||||||
});
|
|
||||||
const followingCount = await DBClient.instance.userFollow.count({
|
|
||||||
where: { follower: { id } },
|
|
||||||
});
|
|
||||||
|
|
||||||
res.setHeader('X-Total-Count', followingCount);
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
message: 'Retrieved users that are followed by queried user',
|
|
||||||
payload: following,
|
|
||||||
success: true,
|
|
||||||
statusCode: 200,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
validateRequest({
|
validateRequest({
|
||||||
querySchema: z.object({
|
querySchema: z.object({
|
||||||
@@ -62,7 +25,7 @@ router.get(
|
|||||||
page_num: z.string().regex(/^\d+$/),
|
page_num: z.string().regex(/^\d+$/),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
getFollowingInfo,
|
getUsersFollowed,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handler = router.handler(NextConnectOptions);
|
const handler = router.handler(NextConnectOptions);
|
||||||
|
|||||||
@@ -1,113 +1,16 @@
|
|||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
|
||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import { editUserInfo, deleteAccount } from '@/controllers/users/auth';
|
||||||
import DBClient from '@/prisma/DBClient';
|
import { checkIfUserCanEditUser } from '@/controllers/users/profile';
|
||||||
import deleteUserById from '@/services/User/deleteUserById';
|
import { EditUserRequest } from '@/controllers/users/profile/types';
|
||||||
import findUserByEmail from '@/services/User/findUserByEmail';
|
import EditUserSchema from '@/services/User/schema/EditUserSchema';
|
||||||
import findUserById from '@/services/User/findUserById';
|
|
||||||
import findUserByUsername from '@/services/User/findUserByUsername';
|
|
||||||
import { BaseCreateUserSchema } from '@/services/User/schema/CreateUserValidationSchemas';
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { NextHandler, createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
const EditUserSchema = BaseCreateUserSchema.pick({
|
|
||||||
username: true,
|
|
||||||
email: true,
|
|
||||||
firstName: true,
|
|
||||||
lastName: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
interface UserRouteRequest extends UserExtendedNextApiRequest {
|
|
||||||
query: { id: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EditUserRequest extends UserRouteRequest {
|
|
||||||
body: z.infer<typeof EditUserSchema>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkIfUserCanEditUser = async (
|
|
||||||
req: EditUserRequest,
|
|
||||||
res: NextApiResponse,
|
|
||||||
next: NextHandler,
|
|
||||||
) => {
|
|
||||||
const authenticatedUser = req.user!;
|
|
||||||
|
|
||||||
const userToUpdate = await findUserById(req.query.id);
|
|
||||||
if (!userToUpdate) {
|
|
||||||
throw new ServerError('User not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (authenticatedUser.id !== userToUpdate.id) {
|
|
||||||
throw new ServerError('You are not permitted to modify this user', 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
|
||||||
};
|
|
||||||
|
|
||||||
const editUser = async (
|
|
||||||
req: EditUserRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
const { email, firstName, lastName, username } = req.body;
|
|
||||||
|
|
||||||
const [usernameIsTaken, emailIsTaken] = await Promise.all([
|
|
||||||
findUserByUsername(username),
|
|
||||||
findUserByEmail(email),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const emailChanged = req.user!.email !== email;
|
|
||||||
const usernameChanged = req.user!.username !== username;
|
|
||||||
|
|
||||||
if (emailIsTaken && emailChanged) {
|
|
||||||
throw new ServerError('Email is already taken', 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usernameIsTaken && usernameChanged) {
|
|
||||||
throw new ServerError('Username is already taken', 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedUser = await DBClient.instance.user.update({
|
|
||||||
where: { id: req.user!.id },
|
|
||||||
data: {
|
|
||||||
email,
|
|
||||||
firstName,
|
|
||||||
lastName,
|
|
||||||
username,
|
|
||||||
accountIsVerified: emailChanged ? false : undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
message: 'User edited successfully',
|
|
||||||
payload: updatedUser,
|
|
||||||
success: true,
|
|
||||||
statusCode: 200,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const deleteUser = async (
|
|
||||||
req: UserRouteRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
const { id } = req.query;
|
|
||||||
const deletedUser = await deleteUserById(id);
|
|
||||||
|
|
||||||
if (!deletedUser) {
|
|
||||||
throw new ServerError('Could not find a user with that id.', 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.send({
|
|
||||||
message: 'Successfully deleted user.',
|
|
||||||
statusCode: 200,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
EditUserRequest,
|
EditUserRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
@@ -120,7 +23,7 @@ router.put(
|
|||||||
querySchema: z.object({ id: z.string().cuid() }),
|
querySchema: z.object({ id: z.string().cuid() }),
|
||||||
}),
|
}),
|
||||||
checkIfUserCanEditUser,
|
checkIfUserCanEditUser,
|
||||||
editUser,
|
editUserInfo,
|
||||||
);
|
);
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
@@ -129,7 +32,7 @@ router.delete(
|
|||||||
querySchema: z.object({ id: z.string().cuid() }),
|
querySchema: z.object({ id: z.string().cuid() }),
|
||||||
}),
|
}),
|
||||||
checkIfUserCanEditUser,
|
checkIfUserCanEditUser,
|
||||||
deleteUser,
|
deleteAccount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handler = router.handler(NextConnectOptions);
|
const handler = router.handler(NextConnectOptions);
|
||||||
|
|||||||
@@ -1,62 +1,21 @@
|
|||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
|
||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
|
||||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
|
||||||
import ServerError from '@/config/util/ServerError';
|
|
||||||
import DBClient from '@/prisma/DBClient';
|
|
||||||
import findUserById from '@/services/User/findUserById';
|
|
||||||
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
|
||||||
|
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
interface GetUserFollowInfoRequest extends UserExtendedNextApiRequest {
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
query: { id: string };
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
}
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
|
|
||||||
|
import { checkIfUserIsFollowedBySessionUser } from '@/controllers/users/profile';
|
||||||
|
import { GetUserFollowInfoRequest } from '@/controllers/users/profile/types';
|
||||||
|
|
||||||
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
GetUserFollowInfoRequest,
|
GetUserFollowInfoRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const checkIfUserIsFollowedBySessionUser = async (
|
|
||||||
req: GetUserFollowInfoRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
const { id } = req.query;
|
|
||||||
|
|
||||||
const user = await findUserById(id);
|
|
||||||
if (!user) {
|
|
||||||
throw new ServerError('User not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentUser = req.user!;
|
|
||||||
|
|
||||||
const userIsFollowedBySessionUser = await DBClient.instance.userFollow.findFirst({
|
|
||||||
where: { followerId: currentUser.id, followingId: id },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!userIsFollowedBySessionUser) {
|
|
||||||
res.status(200).json({
|
|
||||||
message: 'User is not followed by the current user.',
|
|
||||||
success: true,
|
|
||||||
statusCode: 200,
|
|
||||||
payload: { isFollowed: false },
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
message: 'User is followed by the current user.',
|
|
||||||
success: true,
|
|
||||||
statusCode: 200,
|
|
||||||
payload: { isFollowed: true },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
|
|||||||
@@ -1,48 +1,15 @@
|
|||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import DBClient from '@/prisma/DBClient';
|
|
||||||
import getBeerPostsByPostedById from '@/services/BeerPost/getBeerPostsByPostedById';
|
|
||||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
import { GetPostsByUserIdRequest } from '@/controllers/posts/types';
|
||||||
interface GetBeerPostsRequest extends NextApiRequest {
|
import { getBeerPostsByUserId } from '@/controllers/posts/beerPosts';
|
||||||
query: {
|
|
||||||
page_num: string;
|
|
||||||
page_size: string;
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const getBeerPostsByUserId = async (
|
|
||||||
req: GetBeerPostsRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
const pageNum = parseInt(req.query.page_num, 10);
|
|
||||||
const pageSize = parseInt(req.query.page_size, 10);
|
|
||||||
|
|
||||||
const { id } = req.query;
|
|
||||||
|
|
||||||
const beerPosts = await getBeerPostsByPostedById({ pageNum, pageSize, postedById: id });
|
|
||||||
|
|
||||||
const beerPostCount = await DBClient.instance.beerPost.count({
|
|
||||||
where: { postedBy: { id } },
|
|
||||||
});
|
|
||||||
|
|
||||||
res.setHeader('X-Total-Count', beerPostCount);
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
message: `Beer posts by user ${id} fetched successfully`,
|
|
||||||
statusCode: 200,
|
|
||||||
payload: beerPosts,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
GetBeerPostsRequest,
|
GetPostsByUserIdRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +1,15 @@
|
|||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import DBClient from '@/prisma/DBClient';
|
|
||||||
import getAllBreweryPostsByPostedById from '@/services/BreweryPost/getAllBreweryPostsByPostedById';
|
|
||||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
import { getBreweryPostsByUserId } from '@/controllers/posts/breweries';
|
||||||
interface GetBreweryPostsRequest extends NextApiRequest {
|
import { GetPostsByUserIdRequest } from '@/controllers/posts/types';
|
||||||
query: {
|
|
||||||
page_num: string;
|
|
||||||
page_size: string;
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const getBreweryPostsByUserId = async (
|
|
||||||
req: GetBreweryPostsRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
const pageNum = parseInt(req.query.page_num, 10);
|
|
||||||
const pageSize = parseInt(req.query.page_size, 10);
|
|
||||||
|
|
||||||
const { id } = req.query;
|
|
||||||
|
|
||||||
const breweryPosts = await getAllBreweryPostsByPostedById({
|
|
||||||
pageNum,
|
|
||||||
pageSize,
|
|
||||||
postedById: id,
|
|
||||||
});
|
|
||||||
|
|
||||||
const breweryPostCount = await DBClient.instance.breweryPost.count({
|
|
||||||
where: { postedBy: { id } },
|
|
||||||
});
|
|
||||||
|
|
||||||
res.setHeader('X-Total-Count', breweryPostCount);
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
message: `Brewery posts by user ${id} fetched successfully`,
|
|
||||||
statusCode: 200,
|
|
||||||
payload: breweryPosts,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
GetBreweryPostsRequest,
|
GetPostsByUserIdRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const checkIfUserCanUpdateProfile = async (
|
|||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateProfile = async (req: UpdateProfileRequest, res: NextApiResponse) => {
|
const updateAvatar = async (req: UpdateProfileRequest, res: NextApiResponse) => {
|
||||||
const { file, user } = req;
|
const { file, user } = req;
|
||||||
|
|
||||||
const avatar: UpdateUserAvatarByIdParams['data']['avatar'] = {
|
const avatar: UpdateUserAvatarByIdParams['data']['avatar'] = {
|
||||||
@@ -60,7 +60,7 @@ router.put(
|
|||||||
checkIfUserCanUpdateProfile,
|
checkIfUserCanUpdateProfile,
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
singleUploadMiddleware,
|
singleUploadMiddleware,
|
||||||
updateProfile,
|
updateAvatar,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handler = router.handler();
|
const handler = router.handler();
|
||||||
|
|||||||
@@ -1,75 +1,13 @@
|
|||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
|
||||||
|
|
||||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import { checkIfUserCanUpdateProfile, updateProfile } from '@/controllers/users/profile';
|
||||||
import DBClient from '@/prisma/DBClient';
|
import { UpdateProfileRequest } from '@/controllers/users/profile/types';
|
||||||
import GetUserSchema from '@/services/User/schema/GetUserSchema';
|
|
||||||
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { NextHandler, createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
interface UpdateProfileRequest extends UserExtendedNextApiRequest {
|
|
||||||
body: { bio: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
interface UpdateUserProfileByIdParams {
|
|
||||||
id: string;
|
|
||||||
data: { bio: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateUserProfileById = async ({ id, data }: UpdateUserProfileByIdParams) => {
|
|
||||||
const user: z.infer<typeof GetUserSchema> = await DBClient.instance.user.update({
|
|
||||||
where: { id },
|
|
||||||
data: { bio: data.bio },
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
username: true,
|
|
||||||
email: true,
|
|
||||||
bio: true,
|
|
||||||
userAvatar: true,
|
|
||||||
accountIsVerified: true,
|
|
||||||
createdAt: true,
|
|
||||||
firstName: true,
|
|
||||||
lastName: true,
|
|
||||||
updatedAt: true,
|
|
||||||
dateOfBirth: true,
|
|
||||||
role: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return user;
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateProfile = async (req: UpdateProfileRequest, res: NextApiResponse) => {
|
|
||||||
const user = req.user!;
|
|
||||||
const { body } = req;
|
|
||||||
|
|
||||||
await updateUserProfileById({ id: user!.id, data: { bio: body.bio } });
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
message: 'Profile updated successfully.',
|
|
||||||
statusCode: 200,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkIfUserCanUpdateProfile = async (
|
|
||||||
req: UpdateProfileRequest,
|
|
||||||
res: NextApiResponse,
|
|
||||||
next: NextHandler,
|
|
||||||
) => {
|
|
||||||
const user = req.user!;
|
|
||||||
|
|
||||||
if (user.id !== req.query.id) {
|
|
||||||
throw new ServerError('You can only update your own profile.', 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
await next();
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
UpdateProfileRequest,
|
UpdateProfileRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
|||||||
@@ -1,38 +1,18 @@
|
|||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import findUserByEmail from '@/services/User/findUserByEmail';
|
import { CheckEmailRequest } from '@/controllers/users/auth/types';
|
||||||
|
import { checkEmail } from '@/controllers/users/auth';
|
||||||
const CheckEmailRequestQuerySchema = z.object({
|
|
||||||
email: z.string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
interface CheckEmailRequestSchema extends NextApiRequest {
|
|
||||||
query: z.infer<typeof CheckEmailRequestQuerySchema>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
CheckEmailRequestSchema,
|
CheckEmailRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const checkEmail = async (req: NextApiRequest, res: NextApiResponse) => {
|
|
||||||
const { email: emailToCheck } = req.query;
|
|
||||||
|
|
||||||
const email = await findUserByEmail(emailToCheck as string);
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
payload: { emailIsTaken: !!email },
|
|
||||||
statusCode: 200,
|
|
||||||
message: 'Getting email availability.',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
validateRequest({ querySchema: z.object({ email: z.string().email() }) }),
|
validateRequest({ querySchema: z.object({ email: z.string().email() }) }),
|
||||||
checkEmail,
|
checkEmail,
|
||||||
|
|||||||
@@ -1,38 +1,19 @@
|
|||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
|
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import findUserByUsername from '@/services/User/findUserByUsername';
|
|
||||||
|
|
||||||
const CheckUsernameRequestQuerySchema = z.object({
|
import { CheckUsernameRequest } from '@/controllers/users/auth/types';
|
||||||
username: z.string(),
|
import { checkUsername } from '@/controllers/users/auth';
|
||||||
});
|
|
||||||
|
|
||||||
interface CheckUsernameRequestSchema extends NextApiRequest {
|
|
||||||
query: z.infer<typeof CheckUsernameRequestQuerySchema>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
CheckUsernameRequestSchema,
|
CheckUsernameRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const checkUsername = async (req: NextApiRequest, res: NextApiResponse) => {
|
|
||||||
const { username: usernameToCheck } = req.query;
|
|
||||||
|
|
||||||
const user = await findUserByUsername(usernameToCheck as string);
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
payload: { usernameIsTaken: !!user },
|
|
||||||
statusCode: 200,
|
|
||||||
message: 'Getting username availability.',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
validateRequest({ querySchema: z.object({ username: z.string() }) }),
|
validateRequest({ querySchema: z.object({ username: z.string() }) }),
|
||||||
checkUsername,
|
checkUsername,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { createRouter } from 'next-connect';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
|
|
||||||
import { TokenValidationRequest } from '@/controllers/auth/types';
|
import { TokenValidationRequest } from '@/controllers/users/auth/types';
|
||||||
import { confirmUser } from '@/controllers/auth';
|
import { confirmUser } from '@/controllers/users/auth';
|
||||||
import TokenValidationSchema from '@/services/User/schema/TokenValidationSchema';
|
import TokenValidationSchema from '@/services/User/schema/TokenValidationSchema';
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
|
|||||||
@@ -5,16 +5,7 @@ import { NextApiResponse } from 'next';
|
|||||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import { sendCurrentUser } from '@/controllers/users/auth';
|
||||||
const sendCurrentUser = async (req: UserExtendedNextApiRequest, res: NextApiResponse) => {
|
|
||||||
const { user } = req;
|
|
||||||
res.status(200).json({
|
|
||||||
message: `Currently logged in as ${user!.username}`,
|
|
||||||
statusCode: 200,
|
|
||||||
success: true,
|
|
||||||
payload: user,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
UserExtendedNextApiRequest,
|
UserExtendedNextApiRequest,
|
||||||
|
|||||||
@@ -1,38 +1,14 @@
|
|||||||
import { hashPassword } from '@/config/auth/passwordFns';
|
|
||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
|
||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import DBClient from '@/prisma/DBClient';
|
import { updatePassword } from '@/controllers/users/auth';
|
||||||
|
import { UpdatePasswordRequest } from '@/controllers/users/auth/types';
|
||||||
import { UpdatePasswordSchema } from '@/services/User/schema/CreateUserValidationSchemas';
|
import { UpdatePasswordSchema } from '@/services/User/schema/CreateUserValidationSchemas';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
interface UpdatePasswordRequest extends UserExtendedNextApiRequest {
|
|
||||||
body: z.infer<typeof UpdatePasswordSchema>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatePassword = async (
|
|
||||||
req: UpdatePasswordRequest,
|
|
||||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
|
||||||
) => {
|
|
||||||
const { password } = req.body;
|
|
||||||
const hash = await hashPassword(password);
|
|
||||||
|
|
||||||
const user = req.user!;
|
|
||||||
await DBClient.instance.user.update({
|
|
||||||
data: { hash },
|
|
||||||
where: { id: user.id },
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
message: 'Updated user password.',
|
|
||||||
statusCode: 200,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
UpdatePasswordRequest,
|
UpdatePasswordRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { createRouter } from 'next-connect';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import { resetPassword } from '@/controllers/auth';
|
import { resetPassword } from '@/controllers/users/auth';
|
||||||
import { ResetPasswordRequest } from '@/controllers/auth/types';
|
import { ResetPasswordRequest } from '@/controllers/users/auth/types';
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
ResetPasswordRequest,
|
ResetPasswordRequest,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { z } from 'zod';
|
|||||||
import LoginValidationSchema from '@/services/User/schema/LoginValidationSchema';
|
import LoginValidationSchema from '@/services/User/schema/LoginValidationSchema';
|
||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import { authenticateUser, loginUser } from '@/controllers/auth';
|
import { authenticateUser, loginUser } from '@/controllers/users/auth';
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
UserExtendedNextApiRequest,
|
UserExtendedNextApiRequest,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import APIResponseValidationSchema from '@/validation/APIResponseValidationSchem
|
|||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { logoutUser } from '@/controllers/auth';
|
import { logoutUser } from '@/controllers/users/auth';
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
NextApiRequest,
|
NextApiRequest,
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { CreateUserValidationSchema } from '@/services/User/schema/CreateUserVal
|
|||||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { registerUser } from '@/controllers/auth';
|
import { registerUser } from '@/controllers/users/auth';
|
||||||
import { RegisterUserRequest } from '@/controllers/auth/types';
|
import { RegisterUserRequest } from '@/controllers/users/auth/types';
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
RegisterUserRequest,
|
RegisterUserRequest,
|
||||||
|
|||||||
@@ -5,21 +5,7 @@ import { NextApiResponse } from 'next';
|
|||||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import { createRouter } from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import sendConfirmationEmail from '@/services/User/sendConfirmationEmail';
|
import { resendConfirmation } from '@/controllers/users/auth';
|
||||||
|
|
||||||
const resendConfirmation = async (
|
|
||||||
req: UserExtendedNextApiRequest,
|
|
||||||
res: NextApiResponse,
|
|
||||||
) => {
|
|
||||||
const user = req.user!;
|
|
||||||
|
|
||||||
await sendConfirmationEmail(user);
|
|
||||||
res.status(200).json({
|
|
||||||
message: `Resent the confirmation email for ${user.username}.`,
|
|
||||||
statusCode: 200,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = createRouter<
|
const router = createRouter<
|
||||||
UserExtendedNextApiRequest,
|
UserExtendedNextApiRequest,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const getBeerPostsByBeerStyleId = async ({
|
|||||||
const beers = await DBClient.instance.beerPost.findMany({
|
const beers = await DBClient.instance.beerPost.findMany({
|
||||||
where: { styleId },
|
where: { styleId },
|
||||||
take: pageSize,
|
take: pageSize,
|
||||||
skip: pageNum * pageSize,
|
skip: (pageNum - 1) * pageSize,
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const getAllBeerPostsByBreweryId = async ({
|
|||||||
const beers = await DBClient.instance.beerPost.findMany({
|
const beers = await DBClient.instance.beerPost.findMany({
|
||||||
where: { breweryId },
|
where: { breweryId },
|
||||||
take: pageSize,
|
take: pageSize,
|
||||||
skip: pageNum * pageSize,
|
skip: (pageNum - 1) * pageSize,
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const getBeerPostsByPostedById = async ({
|
|||||||
const beers = await DBClient.instance.beerPost.findMany({
|
const beers = await DBClient.instance.beerPost.findMany({
|
||||||
where: { postedBy: { id: postedById } },
|
where: { postedBy: { id: postedById } },
|
||||||
take: pageSize,
|
take: pageSize,
|
||||||
skip: pageNum * pageSize,
|
skip: (pageNum - 1) * pageSize,
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
|
|||||||
10
src/services/User/schema/EditUserSchema.ts
Normal file
10
src/services/User/schema/EditUserSchema.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { BaseCreateUserSchema } from './CreateUserValidationSchemas';
|
||||||
|
|
||||||
|
const EditUserSchema = BaseCreateUserSchema.pick({
|
||||||
|
username: true,
|
||||||
|
email: true,
|
||||||
|
firstName: true,
|
||||||
|
lastName: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default EditUserSchema;
|
||||||
33
src/services/User/updateUserProfileById.ts
Normal file
33
src/services/User/updateUserProfileById.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import DBClient from '@/prisma/DBClient';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import GetUserSchema from './schema/GetUserSchema';
|
||||||
|
|
||||||
|
interface UpdateUserProfileByIdParams {
|
||||||
|
id: string;
|
||||||
|
data: { bio: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateUserProfileById = async ({ id, data }: UpdateUserProfileByIdParams) => {
|
||||||
|
const user: z.infer<typeof GetUserSchema> = await DBClient.instance.user.update({
|
||||||
|
where: { id },
|
||||||
|
data: { bio: data.bio },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
email: true,
|
||||||
|
bio: true,
|
||||||
|
userAvatar: true,
|
||||||
|
accountIsVerified: true,
|
||||||
|
createdAt: true,
|
||||||
|
firstName: true,
|
||||||
|
lastName: true,
|
||||||
|
updatedAt: true,
|
||||||
|
dateOfBirth: true,
|
||||||
|
role: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return user;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default updateUserProfileById;
|
||||||
Reference in New Issue
Block a user