Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Stop using pages router INTER-911 #167

Merged
merged 9 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
Loading