mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
Update next-connect, begin work on cloud img upload
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -38,3 +38,6 @@ next-env.d.ts
|
|||||||
|
|
||||||
# http requests
|
# http requests
|
||||||
*.http
|
*.http
|
||||||
|
|
||||||
|
# uploaded images
|
||||||
|
public/uploads
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
/* eslint-disable jsx-a11y/label-has-associated-control */
|
/* eslint-disable jsx-a11y/label-has-associated-control */
|
||||||
/* eslint-disable jsx-a11y/label-has-for */
|
/* eslint-disable jsx-a11y/label-has-for */
|
||||||
|
|
||||||
|
import UserContext from '@/contexts/userContext';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useEffect, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
|
||||||
interface Page {
|
interface Page {
|
||||||
slug: string;
|
slug: string;
|
||||||
@@ -14,19 +15,36 @@ const Navbar = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [currentURL, setCurrentURL] = useState('/');
|
const [currentURL, setCurrentURL] = useState('/');
|
||||||
|
|
||||||
|
const { user } = useContext(UserContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrentURL(router.asPath);
|
setCurrentURL(router.asPath);
|
||||||
}, [router.asPath]);
|
}, [router.asPath]);
|
||||||
|
|
||||||
const pages: Page[] = [
|
const authenticatedPages: readonly Page[] = [
|
||||||
|
{ slug: '/account', name: 'Account' },
|
||||||
|
{ slug: '/logout', name: 'Logout' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const unauthenticatedPages: readonly Page[] = [
|
||||||
|
{ slug: '/login', name: 'Login' },
|
||||||
|
{ slug: '/register', name: 'Register' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const otherPages: readonly Page[] = [
|
||||||
{ slug: '/beers', name: 'Beers' },
|
{ slug: '/beers', name: 'Beers' },
|
||||||
{ slug: '/breweries', name: 'Breweries' },
|
{ slug: '/breweries', name: 'Breweries' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const pages: readonly Page[] = [
|
||||||
|
...otherPages,
|
||||||
|
...(user ? authenticatedPages : unauthenticatedPages),
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="navbar bg-primary">
|
<nav className="navbar bg-primary">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<Link className="btn btn-ghost text-3xl normal-case" href="/">
|
<Link className="btn-ghost btn text-3xl normal-case" href="/">
|
||||||
<span className="cursor-pointer text-xl font-bold">The Biergarten App</span>
|
<span className="cursor-pointer text-xl font-bold">The Biergarten App</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -51,7 +69,7 @@ const Navbar = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex-none lg:hidden">
|
<div className="flex-none lg:hidden">
|
||||||
<div className="dropdown-end dropdown">
|
<div className="dropdown-end dropdown">
|
||||||
<label tabIndex={0} className="btn btn-ghost btn-circle">
|
<label tabIndex={0} className="btn-ghost btn-circle btn">
|
||||||
<span className="w-10 rounded-full">
|
<span className="w-10 rounded-full">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
27
config/cloudinary/index.ts
Normal file
27
config/cloudinary/index.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
import { v2 as cloudinary } from 'cloudinary';
|
||||||
|
import { CloudinaryStorage } from 'multer-storage-cloudinary';
|
||||||
|
import ServerError from '../util/ServerError';
|
||||||
|
|
||||||
|
const { CLOUDINARY_CLOUD_NAME, CLOUDINARY_KEY, CLOUDINARY_SECRET } = process.env;
|
||||||
|
|
||||||
|
if (!(CLOUDINARY_CLOUD_NAME && CLOUDINARY_KEY && CLOUDINARY_SECRET)) {
|
||||||
|
throw new ServerError(
|
||||||
|
'The cloudinary credentials were not found in the environment variables.',
|
||||||
|
500,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
cloudinary.config({
|
||||||
|
cloud_name: CLOUDINARY_CLOUD_NAME,
|
||||||
|
api_key: CLOUDINARY_KEY,
|
||||||
|
api_secret: CLOUDINARY_SECRET,
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
|
const storage = new CloudinaryStorage({ cloudinary, params: { folder: 'BeerApp' } });
|
||||||
|
|
||||||
|
/** Configuration object for Cloudinary image upload. */
|
||||||
|
const cloudinaryConfig = { cloudinary, storage };
|
||||||
|
|
||||||
|
export default cloudinaryConfig;
|
||||||
@@ -1,22 +1,15 @@
|
|||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
|
||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { Options } from 'next-connect';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import ServerError from '../util/ServerError';
|
import ServerError from '../util/ServerError';
|
||||||
|
|
||||||
const NextConnectConfig: Options<
|
const NextConnectOptions = {
|
||||||
NextApiRequest,
|
onNoMatch(req: NextApiRequest, res: NextApiResponse) {
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
|
||||||
> = {
|
|
||||||
onNoMatch(req, res) {
|
|
||||||
res.status(405).json({
|
res.status(405).json({
|
||||||
message: 'Method not allowed.',
|
message: 'Method not allowed.',
|
||||||
statusCode: 405,
|
statusCode: 405,
|
||||||
success: false,
|
success: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError(error, req, res) {
|
onError(error: unknown, req: NextApiRequest, res: NextApiResponse) {
|
||||||
const message = error instanceof Error ? error.message : 'Internal server error.';
|
const message = error instanceof Error ? error.message : 'Internal server error.';
|
||||||
const statusCode = error instanceof ServerError ? error.statusCode : 500;
|
const statusCode = error instanceof ServerError ? error.statusCode : 500;
|
||||||
res.status(statusCode).json({
|
res.status(statusCode).json({
|
||||||
@@ -27,4 +20,4 @@ const NextConnectConfig: Options<
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NextConnectConfig;
|
export default NextConnectOptions;
|
||||||
@@ -2,8 +2,8 @@ import { NextApiResponse } from 'next';
|
|||||||
import { NextHandler } from 'next-connect';
|
import { NextHandler } from 'next-connect';
|
||||||
import findUserById from '@/services/User/findUserById';
|
import findUserById from '@/services/User/findUserById';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import ServerError from '@/config/util/ServerError';
|
||||||
import { getLoginSession } from '../session';
|
import { getLoginSession } from '../../auth/session';
|
||||||
import { UserExtendedNextApiRequest } from '../types';
|
import { UserExtendedNextApiRequest } from '../../auth/types';
|
||||||
|
|
||||||
/** Get the current user from the session. Adds the user to the request object. */
|
/** Get the current user from the session. Adds the user to the request object. */
|
||||||
const getCurrentUser = async (
|
const getCurrentUser = async (
|
||||||
@@ -19,7 +19,7 @@ const getCurrentUser = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
req.user = user;
|
req.user = user;
|
||||||
next();
|
return next();
|
||||||
};
|
};
|
||||||
|
|
||||||
export default getCurrentUser;
|
export default getCurrentUser;
|
||||||
@@ -42,7 +42,7 @@ const validateRequest =
|
|||||||
req.query = parsed.data;
|
req.query = parsed.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
return next();
|
||||||
};
|
};
|
||||||
|
|
||||||
export default validateRequest;
|
export default validateRequest;
|
||||||
1420
package-lock.json
generated
1420
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -18,10 +18,13 @@
|
|||||||
"@next/font": "13.1.6",
|
"@next/font": "13.1.6",
|
||||||
"@prisma/client": "^4.9.0",
|
"@prisma/client": "^4.9.0",
|
||||||
"argon2": "^0.30.3",
|
"argon2": "^0.30.3",
|
||||||
|
"cloudinary": "^1.33.0",
|
||||||
"cookie": "0.5.0",
|
"cookie": "0.5.0",
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.29.3",
|
||||||
|
"multer": "^1.4.5-lts.1",
|
||||||
|
"multer-storage-cloudinary": "^4.0.0",
|
||||||
"next": "13.1.6",
|
"next": "13.1.6",
|
||||||
"next-connect": "^0.13.0",
|
"next-connect": "^1.0.0-next.3",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"pino": "^8.8.0",
|
"pino": "^8.8.0",
|
||||||
@@ -37,6 +40,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@faker-js/faker": "^7.6.0",
|
"@faker-js/faker": "^7.6.0",
|
||||||
"@types/cookie": "^0.5.1",
|
"@types/cookie": "^0.5.1",
|
||||||
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^18.13.0",
|
"@types/node": "^18.13.0",
|
||||||
"@types/passport-local": "^1.0.35",
|
"@types/passport-local": "^1.0.35",
|
||||||
"@types/react": "18.0.27",
|
"@types/react": "18.0.27",
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import validateRequest from '@/config/zod/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import createNewBeerComment from '@/services/BeerComment/createNewBeerComment';
|
import createNewBeerComment from '@/services/BeerComment/createNewBeerComment';
|
||||||
import { BeerCommentQueryResultT } from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
import { BeerCommentQueryResultT } from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
||||||
import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBeerCommentValidationSchema';
|
import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBeerCommentValidationSchema';
|
||||||
|
|
||||||
import nextConnect from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
|
|
||||||
interface CreateCommentRequest extends UserExtendedNextApiRequest {
|
interface CreateCommentRequest extends UserExtendedNextApiRequest {
|
||||||
@@ -36,10 +36,16 @@ const createComment = async (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect(NextConnectConfig).post(
|
const router = createRouter<
|
||||||
|
CreateCommentRequest,
|
||||||
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
>();
|
||||||
|
|
||||||
|
router.post(
|
||||||
validateRequest({ bodySchema: BeerCommentValidationSchema }),
|
validateRequest({ bodySchema: BeerCommentValidationSchema }),
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
createComment,
|
createComment,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
77
pages/api/beers/[id]/images/index.ts
Normal file
77
pages/api/beers/[id]/images/index.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
|
import { NextHandler, createRouter, expressWrapper } from 'next-connect';
|
||||||
|
|
||||||
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
|
import getBeerPostById from '@/services/BeerPost/getBeerPostById';
|
||||||
|
|
||||||
|
import multer from 'multer';
|
||||||
|
|
||||||
|
import cloudinaryConfig from '@/config/cloudinary';
|
||||||
|
import { NextApiResponse } from 'next';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import ServerError from '@/config/util/ServerError';
|
||||||
|
|
||||||
|
const { storage } = cloudinaryConfig;
|
||||||
|
|
||||||
|
const fileFilter: multer.Options['fileFilter'] = (req, file, cb) => {
|
||||||
|
if (
|
||||||
|
file.mimetype === 'image/png' ||
|
||||||
|
file.mimetype === 'image/jpg' ||
|
||||||
|
file.mimetype === 'image/jpeg'
|
||||||
|
) {
|
||||||
|
cb(null, true);
|
||||||
|
} else {
|
||||||
|
cb(null, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadMiddleware = multer({ storage, fileFilter }).array('images');
|
||||||
|
|
||||||
|
interface UploadBeerPostImagesRequest extends UserExtendedNextApiRequest {
|
||||||
|
files?:
|
||||||
|
| Express.Multer.File[]
|
||||||
|
| {
|
||||||
|
[fieldname: string]: Express.Multer.File[];
|
||||||
|
};
|
||||||
|
|
||||||
|
query: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// beerPost?: BeerPostQueryResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkIfBeerPostOwner = async (
|
||||||
|
req: UploadBeerPostImagesRequest,
|
||||||
|
res: NextApiResponse,
|
||||||
|
next: NextHandler,
|
||||||
|
) => {
|
||||||
|
const { id } = req.query;
|
||||||
|
const user = req.user!;
|
||||||
|
const beerPost = await getBeerPostById(id);
|
||||||
|
|
||||||
|
if (!beerPost) {
|
||||||
|
throw new ServerError('Beer post not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beerPost.postedBy.id !== user.id) {
|
||||||
|
throw new ServerError('You are not authorized to edit this beer post', 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
};
|
||||||
|
|
||||||
|
const router = createRouter<
|
||||||
|
UploadBeerPostImagesRequest,
|
||||||
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
>();
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
|
router.post(getCurrentUser, expressWrapper(uploadMiddleware), checkIfBeerPostOwner);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
|
export default handler;
|
||||||
|
|
||||||
|
export const config = { api: { bodyParser: false } };
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import getBeerPostById from '@/services/BeerPost/getBeerPostById';
|
import getBeerPostById from '@/services/BeerPost/getBeerPostById';
|
||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import validateRequest from '@/config/zod/middleware/validateRequest';
|
import { createRouter } from 'next-connect';
|
||||||
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
|
||||||
import nextConnect from 'next-connect';
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import ServerError from '@/config/util/ServerError';
|
||||||
import createBeerPostLike from '@/services/BeerPostLike/createBeerPostLike';
|
import createBeerPostLike from '@/services/BeerPostLike/createBeerPostLike';
|
||||||
import removeBeerPostLikeById from '@/services/BeerPostLike/removeBeerPostLikeById';
|
import removeBeerPostLikeById from '@/services/BeerPostLike/removeBeerPostLikeById';
|
||||||
import findBeerPostLikeById from '@/services/BeerPostLike/findBeerPostLikeById';
|
import findBeerPostLikeById from '@/services/BeerPostLike/findBeerPostLikeById';
|
||||||
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
|
|
||||||
const sendLikeRequest = async (
|
const sendLikeRequest = async (
|
||||||
req: UserExtendedNextApiRequest,
|
req: UserExtendedNextApiRequest,
|
||||||
@@ -43,7 +43,12 @@ const sendLikeRequest = async (
|
|||||||
res.status(200).json(jsonResponse);
|
res.status(200).json(jsonResponse);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect(NextConnectConfig).post(
|
const router = createRouter<
|
||||||
|
UserExtendedNextApiRequest,
|
||||||
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
>();
|
||||||
|
|
||||||
|
router.post(
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
validateRequest({
|
validateRequest({
|
||||||
querySchema: z.object({
|
querySchema: z.object({
|
||||||
@@ -53,4 +58,5 @@ const handler = nextConnect(NextConnectConfig).post(
|
|||||||
sendLikeRequest,
|
sendLikeRequest,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import validateRequest from '@/config/zod/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import DBClient from '@/prisma/DBClient';
|
import DBClient from '@/prisma/DBClient';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import nextConnect from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
const checkIfLiked = async (
|
const checkIfLiked = async (
|
||||||
@@ -30,10 +30,20 @@ const checkIfLiked = async (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect(NextConnectConfig).get(
|
const router = createRouter<
|
||||||
|
UserExtendedNextApiRequest,
|
||||||
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
>();
|
||||||
|
|
||||||
|
router.get(
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
validateRequest({ querySchema: z.object({ id: z.string().uuid() }) }),
|
validateRequest({
|
||||||
|
querySchema: z.object({
|
||||||
|
id: z.string().uuid(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
checkIfLiked,
|
checkIfLiked,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import validateRequest from '@/config/zod/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
import nextConnect from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import createNewBeerPost from '@/services/BeerPost/createNewBeerPost';
|
import createNewBeerPost from '@/services/BeerPost/createNewBeerPost';
|
||||||
import BeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
|
import BeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
|
|
||||||
interface CreateBeerPostRequest extends UserExtendedNextApiRequest {
|
interface CreateBeerPostRequest extends UserExtendedNextApiRequest {
|
||||||
body: z.infer<typeof BeerPostValidationSchema>;
|
body: z.infer<typeof BeerPostValidationSchema>;
|
||||||
@@ -37,10 +37,16 @@ const createBeerPost = async (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect(NextConnectConfig).post(
|
const router = createRouter<
|
||||||
|
CreateBeerPostRequest,
|
||||||
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
|
>();
|
||||||
|
|
||||||
|
router.post(
|
||||||
validateRequest({ bodySchema: BeerPostValidationSchema }),
|
validateRequest({ bodySchema: BeerPostValidationSchema }),
|
||||||
getCurrentUser,
|
getCurrentUser,
|
||||||
createBeerPost,
|
createBeerPost,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import getCurrentUser from '@/config/auth/middleware/getCurrentUser';
|
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||||
import nextConnect from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
const sendCurrentUser = async (req: UserExtendedNextApiRequest, res: NextApiResponse) => {
|
const sendCurrentUser = async (req: UserExtendedNextApiRequest, res: NextApiResponse) => {
|
||||||
@@ -16,9 +16,12 @@ const sendCurrentUser = async (req: UserExtendedNextApiRequest, res: NextApiResp
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nextConnect<
|
const router = createRouter<
|
||||||
UserExtendedNextApiRequest,
|
UserExtendedNextApiRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>(NextConnectConfig).get(getCurrentUser, sendCurrentUser);
|
>();
|
||||||
|
|
||||||
|
router.get(getCurrentUser, sendCurrentUser);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,36 +1,35 @@
|
|||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import passport from 'passport';
|
import passport from 'passport';
|
||||||
import nextConnect from 'next-connect';
|
import { createRouter, expressWrapper } from 'next-connect';
|
||||||
import localStrat from '@/config/auth/localStrat';
|
import localStrat from '@/config/auth/localStrat';
|
||||||
import { setLoginSession } from '@/config/auth/session';
|
import { setLoginSession } from '@/config/auth/session';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import ServerError from '@/config/util/ServerError';
|
|
||||||
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';
|
||||||
|
|
||||||
export default nextConnect<
|
const router = createRouter<
|
||||||
UserExtendedNextApiRequest,
|
UserExtendedNextApiRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>(NextConnectConfig)
|
>();
|
||||||
.use(passport.initialize())
|
|
||||||
.use(async (req, res, next) => {
|
router.post(
|
||||||
const parsed = LoginValidationSchema.safeParse(req.body);
|
validateRequest({ bodySchema: LoginValidationSchema }),
|
||||||
if (!parsed.success) {
|
expressWrapper(async (req, res, next) => {
|
||||||
throw new ServerError('Username and password are required.', 400);
|
passport.initialize();
|
||||||
}
|
|
||||||
passport.use(localStrat);
|
passport.use(localStrat);
|
||||||
passport.authenticate('local', { session: false }, (error, token) => {
|
passport.authenticate('local', { session: false }, (error, token) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
next(error);
|
next(error);
|
||||||
} else {
|
return;
|
||||||
req.user = token;
|
|
||||||
next();
|
|
||||||
}
|
}
|
||||||
|
req.user = token;
|
||||||
|
next();
|
||||||
})(req, res, next);
|
})(req, res, next);
|
||||||
})
|
}),
|
||||||
.post(async (req, res) => {
|
async (req, res) => {
|
||||||
const user = req.user!;
|
const user = req.user!;
|
||||||
await setLoginSession(res, user);
|
await setLoginSession(res, user);
|
||||||
|
|
||||||
@@ -40,4 +39,8 @@ export default nextConnect<
|
|||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
success: true,
|
success: true,
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
|
export default handler;
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import { getLoginSession } from '@/config/auth/session';
|
import { getLoginSession } from '@/config/auth/session';
|
||||||
import { removeTokenCookie } from '@/config/auth/cookie';
|
import { removeTokenCookie } from '@/config/auth/cookie';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import nextConnect from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import ServerError from '@/config/util/ServerError';
|
||||||
|
|
||||||
const handler = nextConnect<
|
const router = createRouter<
|
||||||
NextApiRequest,
|
NextApiRequest,
|
||||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
>(NextConnectConfig).all(async (req, res) => {
|
>();
|
||||||
|
|
||||||
|
router.all(async (req, res) => {
|
||||||
const session = await getLoginSession(req);
|
const session = await getLoginSession(req);
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
@@ -18,10 +20,13 @@ const handler = nextConnect<
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeTokenCookie(res);
|
removeTokenCookie(res);
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
message: 'Logged out.',
|
message: 'Logged out.',
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
success: true,
|
success: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import ServerError from '@/config/util/ServerError';
|
import ServerError from '@/config/util/ServerError';
|
||||||
import nc from 'next-connect';
|
import { createRouter } from 'next-connect';
|
||||||
import createNewUser from '@/services/User/createNewUser';
|
import createNewUser from '@/services/User/createNewUser';
|
||||||
import CreateUserValidationSchema from '@/services/User/schema/CreateUserValidationSchema';
|
import CreateUserValidationSchema from '@/services/User/schema/CreateUserValidationSchema';
|
||||||
import NextConnectConfig from '@/config/nextConnect/NextConnectConfig';
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||||
import findUserByUsername from '@/services/User/findUserByUsername';
|
import findUserByUsername from '@/services/User/findUserByUsername';
|
||||||
import findUserByEmail from '@/services/User/findUserByEmail';
|
import findUserByEmail from '@/services/User/findUserByEmail';
|
||||||
import validateRequest from '@/config/zod/middleware/validateRequest';
|
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||||
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||||
|
|
||||||
interface RegisterUserRequest extends NextApiRequest {
|
interface RegisterUserRequest extends NextApiRequest {
|
||||||
body: z.infer<typeof CreateUserValidationSchema>;
|
body: z.infer<typeof CreateUserValidationSchema>;
|
||||||
@@ -42,9 +43,12 @@ const registerUser = async (req: RegisterUserRequest, res: NextApiResponse) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handler = nc(NextConnectConfig).post(
|
const router = createRouter<
|
||||||
validateRequest({ bodySchema: CreateUserValidationSchema }),
|
RegisterUserRequest,
|
||||||
registerUser,
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||||
);
|
>();
|
||||||
|
|
||||||
|
router.post(validateRequest({ bodySchema: CreateUserValidationSchema }), registerUser);
|
||||||
|
|
||||||
|
const handler = router.handler(NextConnectOptions);
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
Reference in New Issue
Block a user