diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a421a686..dc5ee6fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,9 @@ jobs: - name: Lint run: yarn lint + + - name: Spellcheck + run: yarn spellcheck unit-tests: name: Unit tests runs-on: ubuntu-latest diff --git a/contributing.md b/contributing.md index d0e0dca4..3bd7cccc 100644 --- a/contributing.md +++ b/contributing.md @@ -1,27 +1,39 @@ # Contributing to Fingerprint Pro use cases +The `main` branch is locked for the push action. For proposing changes, use the standard [pull request approach](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). It's recommended to discuss fixes or new functionality in the Issues, first. + ## Working with code We prefer using [yarn](https://yarnpkg.com/) for installing dependencies and running scripts. -The `main` branch is locked for the push action. For proposing changes, use the standard [pull request approach](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). It's recommended to discuss fixes or new functionality in the Issues, first. +* Run `yarn install` to install dependencies. +* Run `yarn dev` to start the local development server. +* Run `yarn build` to build a production build of the project. +* Run `yarn start` to start the production build of the project. +* Run `yarn lint` to check the code style using [ESLint](https://eslint.org/). + +See the [package.json](./package.json) -> `scripts` section for more useful commands. -### How to build +## Testing -Just run: +* Run `yarn test` to run unit tests using [Vitest](https://vitest.dev/). +* To run end-to-end tests using [Playwright](https://playwright.dev/): + * First run `yarn dev` or `yarn start` to start the development or production server. + * Then run `yarn test:e2e:chrome` to run the tests in Chrome. -```shell -yarn build -``` +### Deployment -### Code style +- Merging a PR into `main` automatically triggers a new deployment accessible on [demo.fingerprint.com](https://demo.fingerprint.com). +- The app is deployed as a Digital Ocean App. +- The app is deployed behind a CloudFront distribution in the Fingerprint DEV AWS environment (search for `demo.fingerprint.com` in the distribution description). + - If you ever encounter caching issues, for example, a cached index.html pointing to no longer existing resources, you can fix it by [creating a cache invalidation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation_Requests.html#invalidating-objects-console) (`/*` is fine) in the CloudFront distribution. -The code style is controlled by [ESLint](https://eslint.org/). Run to check that the code style is ok: +### Rollbacks and incident response -```shell -yarn lint -``` +If an incident occurs, any member of the Fingerprint team on Digital Ocean can rollback the app to the previous version. In case of any problems, please contact @JuroUhlar and the Integrations team. -### How to publish +1. Go to the [Digital Ocean control panel](https://cloud.digitalocean.com/apps/69a24f2e-6d8e-4e9d-bcf3-024a653ae7b2/deployments). +2. Find the `fingerprint-use-cases` app. +3. Click on the `Activity` tab. +4. Find a previous working version and click `Rollback`. -- Project is deployed to [demo.fingerprint.com](https://demo.fingerprint.com) with each merge into the `main` branch. diff --git a/cspell.json b/cspell.json new file mode 100644 index 00000000..99cb5cd5 --- /dev/null +++ b/cspell.json @@ -0,0 +1,36 @@ +{ + "version": "0.2", + "words": [ + "AIRMAX", + "ALLSTAR", + "botd", + "chargeback", + "chargebacks", + "fingerprinthub", + "fingerprintjs", + "fpjs", + "Frida", + "Headout", + "inkeep", + "Jailbroken", + "Jumia", + "Korsit", + "mapbox", + "notistack", + "omnichannel", + "pastable", + "subheadline", + "unshredded", + "usequerystate", + "Webstore", + "ruleset", + "rulesets", + "srcset", + "urlset", + "Juro", + "Uhlar" + ], + "flagWords": ["Cloudfront"], + "files": ["**/*.md", "src/**/*.ts", "src/**/*.tsx"], + "ignorePaths": ["node_modules", "dist", "src/env.ts"] +} diff --git a/package.json b/package.json index 0a1337ee..04495a78 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "prettier": "prettier src --check", "prettier:fix": "yarn prettier --write", "format": "yarn prettier:fix && yarn lint:fix", + "spellcheck": "cspell --config cspell.json", "test": "vitest", "test:start": "yarn build && yarn start", "test:e2e": "playwright test", @@ -69,6 +70,7 @@ "@types/react": "^18.2.61", "@types/react-syntax-highlighter": "^15.5.11", "@vitejs/plugin-react": "^4.2.1", + "cspell": "^8.16.0", "dotenv": "^16.4.5", "eslint-config-next": "^14.1.1", "eslint-plugin-jsx-a11y": "^6.8.0", diff --git a/src/app/coupon-fraud/page.tsx b/src/app/coupon-fraud/page.tsx index e78bf0c0..b2751a8b 100644 --- a/src/app/coupon-fraud/page.tsx +++ b/src/app/coupon-fraud/page.tsx @@ -4,6 +4,6 @@ import { CouponFraudUseCase } from './CouponFraud'; export const metadata = generateUseCaseMetadata(USE_CASES.couponFraud); -export default function CoupounFraudPage() { +export default function CouponFraudPage() { return ; } diff --git a/src/app/credential-stuffing/api/authenticate/route.ts b/src/app/credential-stuffing/api/authenticate/route.ts index 1726b748..c621e91f 100644 --- a/src/app/credential-stuffing/api/authenticate/route.ts +++ b/src/app/credential-stuffing/api/authenticate/route.ts @@ -26,6 +26,7 @@ const mockedUser = { }; function getKnownVisitorIds() { + // cspell:disable-next-line const defaultVisitorIds = ['bXbwuhCBRB9lLTK692vw', 'ABvLgKyH3fAr6uAjn0vq', 'BNvLgKyHefAr9iOjn0ul']; const visitorIdsFromEnv = env.KNOWN_VISITOR_IDS?.split(','); console.info(`Extracted ${visitorIdsFromEnv?.length ?? 0} visitorIds from env.`); diff --git a/src/app/paywall/api/articles.ts b/src/app/paywall/api/articles.ts index bc94508e..8471d680 100644 --- a/src/app/paywall/api/articles.ts +++ b/src/app/paywall/api/articles.ts @@ -24,15 +24,17 @@ export const ARTICLES: ArticleData[] = [ date: '1 hour ago', title: 'How to defend your site from common cyber attacks', description: - "Websites are an integral part of our lives, but that also makes them a prime target for cyberattacks — malicious attempts to exploit vulnerabilities in your website's security to steal sensitive information.", + "Websites are an integral part of our lives, but that also makes them a prime target for cyber attacks — malicious attempts to exploit vulnerabilities in your website's security to steal sensitive information.", content: [ - "Websites are an integral part of our lives, but that also makes them a prime target for cyberattacks — malicious attempts to exploit vulnerabilities in your website's security to steal sensitive information, disrupt services, or cause other types of damage.", - 'Depending on the nature of your website and services, successful cyberattacks can have severe consequences such as financial loss, reputational damage, and legal liabilities.', - "According to cybersecurity statistics compiled by Zippia, the cost of cybercrime is increasing significantly and is expected to grow by as much as 15% over the next five years. It's estimated that by 2025, cybercrime will cost the world roughly $10.5 trillion every year. Zippia estimates that 30,000 websites are hacked each day globally, with one happening every 39 seconds.", - 'The good news is that 95% of cyberattacks are due to human error, which means that something can be done to prevent them. To help track and prevent common cyberattacks, the Open Web Application Security Project (OWASP), a nonprofit organization, maintains a list of the most prevalent security risks affecting websites, including injection attacks, security misconfigurations, and broken authentication. The project is a community-driven initiative that aims to improve the security of software and web applications.', - 'By understanding these attacks and implementing appropriate security measures, you can better protect your websites from potential threats. In this article, you will learn about some of the common cyberattacks and how to implement defenses to ensure that your site is secure.', + "Websites are an integral part of our lives, but that also makes them a prime target for cyber attacks — malicious attempts to exploit vulnerabilities in your website's security to steal sensitive information, disrupt services, or cause other types of damage.", + 'Depending on the nature of your website and services, successful cyber attacks can have severe consequences such as financial loss, reputation damage, and legal liabilities.', + /* cspell:disable-next-line */ + "According to cybersecurity statistics compiled by Zippia, the cost of cyber crime is increasing significantly and is expected to grow by as much as 15% over the next five years. It's estimated that by 2025, cyber crime will cost the world roughly $10.5 trillion every year. Zippia estimates that 30,000 websites are hacked each day globally, with one happening every 39 seconds.", + 'The good news is that 95% of cyber attacks are due to human error, which means that something can be done to prevent them. To help track and prevent common cyber attacks, the Open Web Application Security Project (OWASP), a nonprofit organization, maintains a list of the most prevalent security risks affecting websites, including injection attacks, security misconfigurations, and broken authentication. The project is a community-driven initiative that aims to improve the security of software and web applications.', + 'By understanding these attacks and implementing appropriate security measures, you can better protect your websites from potential threats. In this article, you will learn about some of the common cyber attacks and how to implement defenses to ensure that your site is secure.', ], image: ArticleHeroSvg, + // cspell:disable-next-line author: { name: 'Daniel Olaogun', avatar: GenericAvatarImage }, tags: ['Fingerprinting', 'Fraud'], }, diff --git a/src/app/personalization/api/seed.ts b/src/app/personalization/api/seed.ts index dbac9ef2..e1daf12c 100644 --- a/src/app/personalization/api/seed.ts +++ b/src/app/personalization/api/seed.ts @@ -6,7 +6,7 @@ export async function seedProducts() { ProductDbModel.create({ price: 9, name: `Extra strong coffee`, - image: '/personalization/img/extrastrong.svg', + image: '/personalization/img/extraStrong.svg', tags: ['Big'], timestamp: new Date().getTime().toString(), }), diff --git a/src/app/playground/components/Map.tsx b/src/app/playground/components/Map.tsx index 33eee423..544a175e 100644 --- a/src/app/playground/components/Map.tsx +++ b/src/app/playground/components/Map.tsx @@ -31,7 +31,7 @@ type MapProps = { const MAPBOX_ACCESS_TOKEN = env.NEXT_PUBLIC_MAPBOX_API_TOKEN; export const Map: FunctionComponent = (props) => { - const defaultZoom = 9; // Shows you rougly inside a specific city + const defaultZoom = 9; // Shows you roughly inside a specific city return ( { {activateResponse.message} )} -
+