Skip to content

Commit

Permalink
Chore: Stop using pages router INTER-911 (#167)
Browse files Browse the repository at this point in the history
* chore: move remaining page and handler to `app`

* chore: clean up files

* chore: consolidate layour

* chore: more file clean up

* chore: fix cors

* chore: clean up cors

* chore: clean up cors

* chore: fix seo

* chore: move files around
  • Loading branch information
JuroUhlar authored Oct 11, 2024
1 parent d5e9f34 commit 92b21dd
Show file tree
Hide file tree
Showing 180 changed files with 419 additions and 488 deletions.
2 changes: 1 addition & 1 deletion cron-jobs/delete_expired_ip_rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Op } from 'sequelize';
import { syncFirewallRuleset } from '../src/app/bot-firewall/api/block-ip/cloudflareApiHelper';
import { schedule } from 'node-cron';
import 'dotenv/config';
import { ONE_HOUR_MS } from '../src/shared/timeUtils';
import { ONE_HOUR_MS } from '../src/utils/timeUtils';
import { BlockedIpDbModel } from '../src/app/bot-firewall/api/get-blocked-ips/blockedIpsDatabase';

/**
Expand Down
2 changes: 1 addition & 1 deletion e2e/sms-pumping/bot-unprotected.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test';
import { TEST_IDS } from '../../src/client/testIDs';

import { assertAlert, assertSnackbar, blockGoogleTagManager, resetScenarios } from '../e2eTestUtils';
import { ONE_MINUTE_MS } from '../../src/shared/timeUtils';
import { ONE_MINUTE_MS } from '../../src/utils/timeUtils';
import { TEST_BUILD } from '../../src/envShared';
import {
SMS_FRAUD_COPY,
Expand Down
1 change: 0 additions & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = {
formats: ['image/webp'],
},
sassOptions: {
includePaths: [path.join(__dirname, 'src/styles')],
includePaths: [path.join(__dirname, 'src/client/styles')],
prependData: `@import "common.scss";`,
},
experimental: {
Expand Down
18 changes: 0 additions & 18 deletions src/Layout.tsx

This file was deleted.

File renamed without changes.
22 changes: 22 additions & 0 deletions src/app/LayoutUI.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use client';

import '../client/styles/global-styles.scss';
import { useSelectedLayoutSegments } from 'next/navigation';
import { IS_PRODUCTION } from '../envShared';
import Header from '../client/components/Header/Header';
import { Analytics } from '../client/analytics/Analytics';
import Footer from '../client/components/Footer/Footer';
import styles from './LayoutUI.module.scss';

export function LayoutUI({ children }: { children: React.ReactNode }) {
const segments = useSelectedLayoutSegments();
const embed = Boolean(segments?.includes('embed'));
return (
<div className={styles.layout}>
{embed ? null : <Header />}
{IS_PRODUCTION ? <Analytics /> : null}
<div>{children}</div>
{embed ? null : <Footer />}
</div>
);
}
4 changes: 2 additions & 2 deletions src/Providers.tsx → src/app/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import { QueryClient, QueryClientProvider } from 'react-query';
import { SnackbarProvider } from 'notistack';
import { PropsWithChildren } from 'react';
import { CloseSnackbarButton, CustomSnackbar } from './client/components/common/Alert/Alert';
import { FingerprintJSPro, FpjsProvider } from '@fingerprintjs/fingerprintjs-pro-react';
import { env } from './env';
import { env } from '../env';
import { CloseSnackbarButton, CustomSnackbar } from '../client/components/Alert/Alert';

const queryClient = new QueryClient({
defaultOptions: {
Expand Down
101 changes: 101 additions & 0 deletions src/app/api/event/[requestId]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { NextRequest, NextResponse } from 'next/server';
import { EventResponse, isEventError } from '@fingerprintjs/fingerprintjs-pro-server-api';
import { OUR_ORIGINS } from '../../../../server/checks';
import { IS_PRODUCTION } from '../../../../envShared';
import { fingerprintServerApiClient } from '../../../../server/fingerprint-server-api';

// Also allow our documentation to use the endpoint
const allowedOrigins = [...OUR_ORIGINS, 'https://dev.fingerprint.com'];

// Handle CORS
const getCorsHeaders = (origin: string | null) => ({
'Access-Control-Allow-Origin': String(origin),
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
});

type CorsHeaders = ReturnType<typeof getCorsHeaders>;

export async function OPTIONS(request: NextRequest) {
const origin = request.headers.get('origin');

// CORS preflight
if (origin && allowedOrigins.includes(origin)) {
return new NextResponse(null, {
status: 200,
headers: getCorsHeaders(origin),
});
}

return new NextResponse(null, { status: 204 });
}

// Main handler
export async function POST(request: NextRequest, { params }: { params: { requestId: string } }) {
const origin = request.headers.get('origin');
const requestId = params.requestId;

// In production, validate the origin
if (IS_PRODUCTION && (!origin || !allowedOrigins.includes(origin))) {
return new NextResponse(null, {
status: 403,
statusText: `Origin "${origin}" is not allowed to call this endpoint`,
headers: getCorsHeaders(origin),
});
}

if (!requestId) {
return new NextResponse(null, {
status: 400,
statusText: 'Missing requestId parameter',
headers: getCorsHeaders(origin),
});
}

const result = await tryGetFingerprintEvent(requestId);

if (!result.okay) {
return sendErrorResponse(result.error, getCorsHeaders(origin));
}

return NextResponse.json(result.data, { headers: getCorsHeaders(origin) });
}

async function tryGetFingerprintEvent(
requestId: string,
retryCount = 5,
retryDelay: number = 3000,
): Promise<{ okay: true; data: EventResponse } | { okay: false; error: unknown }> {
try {
const eventResponse = await fingerprintServerApiClient.getEvent(requestId);
return { okay: true, data: eventResponse };
} catch (error) {
// Retry only Not Found (404) requests.
if (isEventError(error) && error.statusCode === 404 && retryCount > 1) {
await new Promise((resolve) => setTimeout(resolve, retryDelay));
return tryGetFingerprintEvent(requestId, retryCount - 1, retryDelay);
} else {
console.error(error);
return { okay: false, error };
}
}
}

function sendErrorResponse(error: unknown, corsHeaders: CorsHeaders): NextResponse {
if (isEventError(error)) {
return NextResponse.json(
{ message: error.message, code: error.errorCode },
{
status: error.statusCode,
statusText: `${error.errorCode} - ${error.message}`,
headers: corsHeaders,
},
);
} else {
return new NextResponse(null, {
status: 500,
statusText: `Something went wrong ${error}`,
headers: corsHeaders,
});
}
}
9 changes: 0 additions & 9 deletions src/app/appLayout.tsx

This file was deleted.

12 changes: 6 additions & 6 deletions src/app/bot-firewall/BotFirewall.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client';

import { INSTRUCTION_ANCHOR_ID, UseCaseWrapper } from '../../client/components/common/UseCaseWrapper/UseCaseWrapper';
import { USE_CASES } from '../../client/components/common/content';
import { INSTRUCTION_ANCHOR_ID, UseCaseWrapper } from '../../client/components/UseCaseWrapper/UseCaseWrapper';
import { USE_CASES } from '../../client/content';
import { useMutation, useQuery } from 'react-query';
import Button from '../../client/components/common/Button/Button';
import Button from '../../client/components/Button/Button';
import { BlockIpPayload, BlockIpResponse } from './api/block-ip/route';
import styles from './components/botFirewallComponents.module.scss';
import { VisitorQueryContext, useVisitorData } from '@fingerprintjs/fingerprintjs-pro-react';
Expand All @@ -12,9 +12,9 @@ import ChevronIcon from '../../client/img/chevronBlack.svg';
import Image from 'next/image';
import Link from 'next/link';
import { FunctionComponent, useState } from 'react';
import { wait } from '../../shared/timeUtils';
import { Spinner } from '../../client/components/common/Spinner/Spinner';
import { Alert } from '../../client/components/common/Alert/Alert';
import { wait } from '../../utils/timeUtils';
import { Spinner } from '../../client/components/Spinner/Spinner';
import { Alert } from '../../client/components/Alert/Alert';
import { BotVisit } from './api/get-bot-visits/botVisitDatabase';
import { BotTypeInfo, BotVisitAction, InstructionPrompt } from './components/botFirewallComponents';

Expand Down
2 changes: 1 addition & 1 deletion src/app/bot-firewall/api/block-ip/buildFirewallRules.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { chunk } from '../../../../shared/utils';
import { chunk } from '../../../../utils/utils';

/**
* Cloudflare rule expressions are limited to [4096 characters](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/#maximum-rule-expression-length).
Expand Down
2 changes: 1 addition & 1 deletion src/app/bot-firewall/api/block-ip/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { syncFirewallRuleset } from './cloudflareApiHelper';
import { Severity, getAndValidateFingerprintResult } from '../../../../server/checks';
import { isIP } from 'is-ip';
import { ValidationResult } from '../../../../shared/types';
import { ValidationResult } from '../../../../utils/types';
import { NextRequest, NextResponse } from 'next/server';
import { deleteBlockedIp, saveBlockedIp } from '../get-blocked-ips/blockedIpsDatabase';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Attributes, DataTypes, FindOptions, InferAttributes, InferCreationAttributes, Model } from 'sequelize';
import { sequelize } from '../../../../server/sequelize';
import { EventResponseBotData } from '../../../../shared/types';
import { EventResponseBotData } from '../../../../utils/types';

interface BotVisitAttributes
extends Model<InferAttributes<BotVisitAttributes>, InferCreationAttributes<BotVisitAttributes>> {
Expand Down
4 changes: 2 additions & 2 deletions src/app/bot-firewall/components/botFirewallComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { BOT_FIREWALL_COPY } from './botFirewallCopy';
import { Tooltip } from '@mui/material';
import Image from 'next/image';
import WaveIcon from '../../../client/img/wave.svg';
import InfoIcon from '../../../client/img/InfoIcon.svg';
import InfoIcon from '../../../client/img/InfoIconSvg.svg';
import styles from './botFirewallComponents.module.scss';
import { BlockIpPayload } from '../api/block-ip/route';
import Button from '../../../client/components/common/Button/Button';
import Button from '../../../client/components/Button/Button';

type BotVisitActionProps = {
ip: string;
Expand Down
4 changes: 2 additions & 2 deletions src/app/bot-firewall/embed/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { USE_CASES } from '../../../client/components/common/content';
import { generateUseCaseMetadata } from '../../../client/components/common/seo';
import { USE_CASES } from '../../../client/content';
import { generateUseCaseMetadata } from '../../../client/seo';
import BotFirewall from '../BotFirewall';

export const metadata = generateUseCaseMetadata(USE_CASES.botFirewall);
Expand Down
4 changes: 2 additions & 2 deletions src/app/bot-firewall/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { USE_CASES } from '../../client/components/common/content';
import { generateUseCaseMetadata } from '../../client/components/common/seo';
import { USE_CASES } from '../../client/content';
import { generateUseCaseMetadata } from '../../client/seo';
import BotFirewall from './BotFirewall';

export const metadata = generateUseCaseMetadata(USE_CASES.botFirewall);
Expand Down
12 changes: 6 additions & 6 deletions src/app/coupon-fraud/CouponFraud.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
'use client';

import { UseCaseWrapper } from '../../client/components/common/UseCaseWrapper/UseCaseWrapper';
import { UseCaseWrapper } from '../../client/components/UseCaseWrapper/UseCaseWrapper';
import { useState } from 'react';
import React from 'react';
import { USE_CASES } from '../../client/components/common/content';
import { USE_CASES } from '../../client/content';
import styles from './couponFraud.module.scss';
import formStyles from '../../styles/forms.module.scss';
import formStyles from '../../client/styles/forms.module.scss';
import classNames from 'classnames';
import AirMax from './shoeAirMax.svg';
import AllStar from './shoeAllStar.svg';
import { Alert } from '../../client/components/common/Alert/Alert';
import Button from '../../client/components/common/Button/Button';
import { Cart } from '../../client/components/common/Cart/Cart';
import { Alert } from '../../client/components/Alert/Alert';
import Button from '../../client/components/Button/Button';
import { Cart } from '../../client/components/Cart/Cart';
import { useVisitorData } from '@fingerprintjs/fingerprintjs-pro-react';
import { TEST_IDS } from '../../client/testIDs';
import { useMutation } from 'react-query';
Expand Down
4 changes: 2 additions & 2 deletions src/app/coupon-fraud/embed/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { USE_CASES } from '../../../client/components/common/content';
import { generateUseCaseMetadata } from '../../../client/components/common/seo';
import { USE_CASES } from '../../../client/content';
import { generateUseCaseMetadata } from '../../../client/seo';
import { CouponFraudUseCase } from '../CouponFraud';

export const metadata = generateUseCaseMetadata(USE_CASES.couponFraud);
Expand Down
4 changes: 2 additions & 2 deletions src/app/coupon-fraud/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { USE_CASES } from '../../client/components/common/content';
import { generateUseCaseMetadata } from '../../client/components/common/seo';
import { USE_CASES } from '../../client/content';
import { generateUseCaseMetadata } from '../../client/seo';
import { CouponFraudUseCase } from './CouponFraud';

export const metadata = generateUseCaseMetadata(USE_CASES.couponFraud);
Expand Down
10 changes: 5 additions & 5 deletions src/app/credential-stuffing/CredentialStuffing.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
'use client';

import { useState } from 'react';
import { UseCaseWrapper } from '../../client/components/common/UseCaseWrapper/UseCaseWrapper';
import { UseCaseWrapper } from '../../client/components/UseCaseWrapper/UseCaseWrapper';
import React from 'react';
import { USE_CASES } from '../../client/components/common/content';
import { Alert } from '../../client/components/common/Alert/Alert';
import Button from '../../client/components/common/Button/Button';
import { USE_CASES } from '../../client/content';
import { Alert } from '../../client/components/Alert/Alert';
import Button from '../../client/components/Button/Button';
import styles from './credentialStuffing.module.scss';
import formStyles from '../../styles/forms.module.scss';
import formStyles from '../../client/styles/forms.module.scss';
import classNames from 'classnames';
import hiddenIcon from './iconHidden.svg';
import shownIcon from './iconShown.svg';
Expand Down
4 changes: 2 additions & 2 deletions src/app/credential-stuffing/embed/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { USE_CASES } from '../../../client/components/common/content';
import { generateUseCaseMetadata } from '../../../client/components/common/seo';
import { USE_CASES } from '../../../client/content';
import { generateUseCaseMetadata } from '../../../client/seo';
import { CredentialStuffing } from '.././CredentialStuffing';

export const metadata = generateUseCaseMetadata(USE_CASES.credentialStuffing);
Expand Down
4 changes: 2 additions & 2 deletions src/app/credential-stuffing/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { USE_CASES } from '../../client/components/common/content';
import { generateUseCaseMetadata } from '../../client/components/common/seo';
import { USE_CASES } from '../../client/content';
import { generateUseCaseMetadata } from '../../client/seo';
import { CredentialStuffing } from './CredentialStuffing';

export const metadata = generateUseCaseMetadata(USE_CASES.credentialStuffing);
Expand Down
6 changes: 3 additions & 3 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Providers from '../Providers';
import LayoutUiInsideApp from './appLayout';
import { LayoutUI } from './LayoutUI';
import Providers from './Providers';

export const metadata = {
title: 'Fingerprint Pro Use Cases',
Expand All @@ -12,7 +12,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<html lang='en'>
<body>
<Providers>
<LayoutUiInsideApp>{children}</LayoutUiInsideApp>
<LayoutUI>{children}</LayoutUI>
</Providers>
</body>
</html>
Expand Down
16 changes: 8 additions & 8 deletions src/app/loan-risk/LoanRisk.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
'use client';

import { UseCaseWrapper } from '../../client/components/common/UseCaseWrapper/UseCaseWrapper';
import { UseCaseWrapper } from '../../client/components/UseCaseWrapper/UseCaseWrapper';
import { FunctionComponent, useMemo, useState } from 'react';
import { calculateMonthInstallment } from '../../shared/loan-risk/calculate-month-installment';
import { calculateMonthInstallment } from './api/request-loan/calculate-month-installment';
import React from 'react';
import { USE_CASES } from '../../client/components/common/content';
import Button from '../../client/components/common/Button/Button';
import { Alert } from '../../client/components/common/Alert/Alert';
import formStyles from '../../styles/forms.module.scss';
import { Slider } from '../../client/components/common/Slider/Slider';
import { NumberInputWithUnits } from '../../client/components/common/InputNumberWithUnits/InputNumberWithUnits';
import { USE_CASES } from '../../client/content';
import Button from '../../client/components/Button/Button';
import { Alert } from '../../client/components/Alert/Alert';
import formStyles from '../../client/styles/forms.module.scss';
import { Slider } from '../../client/components/Slider/Slider';
import { NumberInputWithUnits } from '../../client/components/InputNumberWithUnits/InputNumberWithUnits';
import styles from './loanRisk.module.scss';
import classNames from 'classnames';
import { TEST_IDS } from '../../client/testIDs';
Expand Down
2 changes: 1 addition & 1 deletion src/app/loan-risk/api/request-loan/evaluateLoanRequest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { calculateMonthInstallment } from '../../../../shared/loan-risk/calculate-month-installment';
import { calculateMonthInstallment } from './calculate-month-installment';

/**
* Required minimal income.
Expand Down
Loading

0 comments on commit 92b21dd

Please sign in to comment.