Skip to content

Commit

Permalink
finished authentication throughout project
Browse files Browse the repository at this point in the history
  • Loading branch information
TomPadmanathan committed Oct 28, 2023
1 parent 69c107e commit 94106a3
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 150 deletions.
12 changes: 7 additions & 5 deletions components/checkout/CheckoutGuest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export default function CheckoutGuest(): JSX.Element {
orderNote: '',
forename: '',
surname: '',
userType: 'guest',
});
const [showGuest, setShowGuest] = useState<boolean>(true);

Expand All @@ -66,7 +65,7 @@ export default function CheckoutGuest(): JSX.Element {
router.push({
pathname: '/auth/login',
query: {
url: 'http://localhost:3000/checkout',
url: `${process.env.NEXT_PUBLIC_URL}/checkout`,
},
})
}
Expand All @@ -84,9 +83,12 @@ export default function CheckoutGuest(): JSX.Element {
<SecondaryButton
content="Login"
onClick={(): Promise<boolean> =>
router.push(
'/auth/login?url=http://localhost:3000/checkout'
)
router.push({
pathname: 'auth/login',
query: {
url: `${process.env.NEXT_PUBLIC_URL}/checkout`,
},
})
}
addClass="mx-5 mb-5 mt-2 px-20"
/>
Expand Down
4 changes: 0 additions & 4 deletions components/checkout/CheckoutUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ function checkoutUserInfomationToQueryParams(
return {
orderNote: checkoutInfo.orderNote,
includeCutlery: checkoutInfo.includeCutlery.toString(),
userId: checkoutInfo.userId,
userType: checkoutInfo.userType,
};
}

Expand All @@ -37,8 +35,6 @@ export default function CheckoutUser({ user }: props): JSX.Element {
const [checkoutInfo, setCheckoutInfo] = useState<checkoutInfoUser>({
orderNote: '',
includeCutlery: false,
userId: user.userId,
userType: 'user',
});

return (
Expand Down
7 changes: 4 additions & 3 deletions interfaces/checkoutInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export interface checkoutInfoGuest {
orderNote: string;
forename: string;
surname: string;
userType: 'guest';
userType?: 'guest';
userId?: string;
}
export interface checkoutInfoUser {
orderNote: string;
includeCutlery: boolean;
userId: string;
userType: 'user';
userType?: 'user';
userId?: string;
}
72 changes: 46 additions & 26 deletions pages/api/create-payment-intent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Packages
import Stripe from 'stripe';
import Jwt, { JwtPayload } from 'jsonwebtoken';

// Utils
import calculateCheckoutPricesFromServerSide from '@/utils/calculateCheckoutPricesFromServerSide';
Expand Down Expand Up @@ -28,37 +29,55 @@ export default async function handler(
response: NextApiResponse
): Promise<void> {
const cart: cart = request.body.cart;
let userData: checkoutInfoUser | checkoutInfoGuest = JSON.parse(
request.body.userData

const checkoutData: checkoutInfoGuest | checkoutInfoUser = JSON.parse(
request.body.checkoutData
);

if (request.method !== 'POST') {
response.status(405).json({ error: 'Method not allowed' });
console.error('Method not allowed');
return;
}
const authorizationHeader = request.headers.authorization;
if (!authorizationHeader) {
checkoutData.userType = 'guest';
} else {
const token = authorizationHeader.replace('Bearer ', '');
const decodedToken: JwtPayload | null | string = Jwt.decode(token);
if (!decodedToken || typeof decodedToken != 'object') return;
checkoutData.userType = 'user';
checkoutData.userId = decodedToken.userId;
}

let customer;
switch (userData.userType) {
switch (checkoutData.userType) {
case 'guest':
customer = await stripe.customers.create({
email: userData.email,
name: userData.forename + ' ' + userData.surname,
phone: userData.phoneNumber.toString(),
email: checkoutData.email,
name: checkoutData.forename + ' ' + checkoutData.surname,
phone: checkoutData.phoneNumber.toString(),
address: {
city: userData.cityTown,
line1: userData.addressLine1,
line2: userData.addressLine2,
postal_code: userData.postcode,
city: checkoutData.cityTown,
line1: checkoutData.addressLine1,
line2: checkoutData.addressLine2,
postal_code: checkoutData.postcode,
},
metadata: {
orderNote: userData.orderNote,
includeCutlery: userData.includeCutlery ? 1 : 0,
userType: userData.userType,
orderNote: checkoutData.orderNote,
includeCutlery: checkoutData.includeCutlery ? 1 : 0,
userType: checkoutData.userType,
},
});
break;

case 'user':
customer = await stripe.customers.create({
metadata: {
orderNote: userData.orderNote,
includeCutlery: userData.includeCutlery ? 1 : 0,
userId: userData.userId,
userType: userData.userType,
orderNote: checkoutData.orderNote,
includeCutlery: checkoutData.includeCutlery ? 1 : 0,
userType: checkoutData.userType,
userId: checkoutData.userId ? checkoutData.userId : null,
},
});
break;
Expand All @@ -68,15 +87,16 @@ export default async function handler(
return;
}

const paymentIntent = await stripe.paymentIntents.create({
amount: await calculateOrderAmount(cart),
currency: 'gbp',
payment_method_types: ['card'],
metadata: {
customerId: customer.id,
cart: JSON.stringify(getIdsAndOptionsInCart(cart)),
},
});
const paymentIntent: Stripe.Response<Stripe.PaymentIntent> =
await stripe.paymentIntents.create({
amount: await calculateOrderAmount(cart),
currency: 'gbp',
payment_method_types: ['card'],
metadata: {
customerId: customer.id,
cart: JSON.stringify(getIdsAndOptionsInCart(cart)),
},
});

response.send({
clientSecret: paymentIntent.client_secret,
Expand Down
34 changes: 29 additions & 5 deletions pages/api/getOrderFromId.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Packages
import sequelize from '@/database/sequelize';
import Jwt, { JwtPayload } from 'jsonwebtoken';

// Database Models
import Order from '@/database/models/Order';
Expand All @@ -19,19 +20,42 @@ export default async function handler(
response: NextApiResponse
): Promise<void> {
response.status(200);

await sequelize.sync();
if (request.method !== 'POST') {
response.status(405).json({ error: 'Method not allowed' });
console.error('Method not allowed');
return;
}
const authorizationHeader = request.headers.authorization;
if (!authorizationHeader) {
response
.status(404)
.json({ error: 'No token provided in the request' });
console.error('No token provided in the request.');
return;
}
const token: string = authorizationHeader.replace('Bearer ', '');
const decodedToken: JwtPayload | null | string = Jwt.decode(token);
if (!decodedToken || typeof decodedToken != 'object') return;
const userId: string = decodedToken.userId;

try {
await sequelize.sync();
const order: Order | null = await Order.findOne({
where: {
orderId: request.body.orderId,
},
include: User
include: User,
});

if (order) response.send(order);
else console.error('Order not found');
if (!order) {
response.status(404).json({ error: 'order not found' });
return;
}
if (userId !== order.userId) {
response.status(404).json({ error: 'Invalid permissions' });
return;
}
response.json({ order: order });
} catch (error) {
console.error('Sequlize error:', error);
}
Expand Down
22 changes: 14 additions & 8 deletions pages/checkout/new-checkout-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { Elements } from '@stripe/react-stripe-js';
// Context
import { AppContext } from '@/context/AppContext';

// Utils
import fetchWithToken from '@/utils/JWT/fetchWithToken';

// Components
import CheckoutForm from '@/components/CheckoutForm';

Expand All @@ -24,14 +27,17 @@ export default function App(): JSX.Element {
const router: NextRouter = useRouter();

const fetchData = useCallback(async (): Promise<void> => {
const response: Response = await fetch('/api/create-payment-intent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
cart: cart,
userData: JSON.stringify(router.query),
}),
});
const response: Response = await fetchWithToken(
'/api/create-payment-intent',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
cart: cart,
checkoutData: JSON.stringify(router.query),
}),
}
);
const data = await response.json();
setClientSecret(data.clientSecret);
}, [cart, router.query]);
Expand Down
Loading

0 comments on commit 94106a3

Please sign in to comment.