From b576bc98843e5f14b4a879ba22d48a5b8116a0d8 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Tue, 14 May 2024 10:32:37 -0700
Subject: [PATCH 001/137] ci: 1 click deploy
---
.github/workflows/production_deploy.yml | 40 +++++++++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 .github/workflows/production_deploy.yml
diff --git a/.github/workflows/production_deploy.yml b/.github/workflows/production_deploy.yml
new file mode 100644
index 00000000000..ab74e303aa2
--- /dev/null
+++ b/.github/workflows/production_deploy.yml
@@ -0,0 +1,40 @@
+name: Monitor 1-click Deployment
+on:
+ workflow_dispatch:
+ inputs:
+ environment:
+ description: 'Environment to deploy to'
+ required: true
+ default: 'prod'
+ type: choice
+ options:
+ - stage
+ - prod
+ commitSha:
+ description: 'Commit Sha to deploy'
+ required: true
+ type: string
+env:
+ DOCKER_IMAGE_NAME: mozilla/blurts-server
+jobs:
+ pull_retag_push:
+ name: Push Docker image to Docker Hub
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v2
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Pull Docker image
+ run: docker pull ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.commitSha }}
+
+ - name: Retag image
+ run: docker tag ${{ env.DOCKER_IMAGE_NAME }}${{ inputs.commitSha }} ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.environment }}-${{ inputs.commitSha }}
+
+ - name: Redeploy image
+ run: docker push ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.environment }}-${{ inputs.commitSha }}
\ No newline at end of file
From bccbb1e704c05050aeb0cc3c7dade28d03dfd136 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Tue, 28 May 2024 18:21:23 -0700
Subject: [PATCH 002/137] feat: mock HIBP
---
package-lock.json | 61 +++++++++++++++++++
package.json | 1 +
.../range/[hashPrefix]/route.ts | 38 ++++++++++++
3 files changed, 100 insertions(+)
create mode 100644 src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
diff --git a/package-lock.json b/package-lock.json
index c577a425a13..83980f3281d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -93,6 +93,7 @@
"jest-fail-on-console": "^3.3.0",
"lint-staged": "^15.2.2",
"mjml-browser": "^4.15.3",
+ "oauth2-mock-server": "^7.1.2",
"prettier": "3.2.5",
"react-intersection-observer": "^9.10.2",
"sass": "^1.77.2",
@@ -14130,6 +14131,24 @@
}
]
},
+ "node_modules/basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/basic-auth/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
"node_modules/better-opn": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
@@ -15380,6 +15399,19 @@
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"dev": true
},
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dev": true,
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
@@ -24782,6 +24814,35 @@
"resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
"integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="
},
+ "node_modules/oauth2-mock-server": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/oauth2-mock-server/-/oauth2-mock-server-7.1.2.tgz",
+ "integrity": "sha512-xUg/YOTcMRe8W+q2jphecq1fB1BAjlAPbeeA9lvqwGaQSPJKxI2e8JUnDXHrrKGNJAVXQdHgE/9h4RpCtOfYOA==",
+ "dev": true,
+ "dependencies": {
+ "basic-auth": "^2.0.1",
+ "cors": "^2.8.5",
+ "express": "^4.18.2",
+ "is-plain-object": "^5.0.0",
+ "jose": "^5.3.0"
+ },
+ "bin": {
+ "oauth2-mock-server": "dist/oauth2-mock-server.js"
+ },
+ "engines": {
+ "node": "^18.12 || ^20 || ^22",
+ "yarn": "^1.15.2"
+ }
+ },
+ "node_modules/oauth2-mock-server/node_modules/jose": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-5.3.0.tgz",
+ "integrity": "sha512-IChe9AtAE79ru084ow8jzkN2lNrG3Ntfiv65Cvj9uOCE2m5LNsdHG+9EbxWxAoWRF9TgDOqLN5jm08++owDVRg==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
diff --git a/package.json b/package.json
index f0129300603..01289299889 100644
--- a/package.json
+++ b/package.json
@@ -134,6 +134,7 @@
"jest-fail-on-console": "^3.3.0",
"lint-staged": "^15.2.2",
"mjml-browser": "^4.15.3",
+ "oauth2-mock-server": "^7.1.2",
"prettier": "3.2.5",
"react-intersection-observer": "^9.10.2",
"sass": "^1.77.2",
diff --git a/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts b/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
new file mode 100644
index 00000000000..f2c8bae7e9b
--- /dev/null
+++ b/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
@@ -0,0 +1,38 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { NextResponse } from "next/server";
+import { logger } from "../../../../../../functions/server/logging";
+import { getSha1 } from "../../../../../../../utils/fxa";
+import type { BinaryLike } from "crypto";
+type BreachedAccountResponse = {
+ hashSuffix: string;
+ websites: string[];
+}[];
+
+export function GET() {
+ const { APP_ENV } = process.env;
+
+ // Check if APP_ENV is set to production
+ if (APP_ENV === "production") {
+ return NextResponse.json(
+ { error: "Endpoint not available in production environment" },
+ { status: 403 },
+ );
+ }
+
+ // Mock data for test email, can be randomized
+ const userEmail = process.env.E2E_TEST_ACCOUNT_EMAIL;
+ const currentUserSha = getSha1(userEmail as BinaryLike);
+ logger.info("Mock endpoint: /breachedaccount/range/");
+
+ const data: BreachedAccountResponse = [
+ {
+ hashSuffix: currentUserSha.slice(6).toUpperCase(),
+ websites: ["Adobe"],
+ },
+ ];
+
+ return NextResponse.json(data);
+}
From a0d9df7d2d1b17d9b5d7b9e3cd78cf2b9994686c Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Thu, 13 Jun 2024 01:24:38 -0700
Subject: [PATCH 003/137] able to default to mock endpoint on failure locally.
---
.env-dist | 2 +
package.json | 1 -
.../range/[hashPrefix]/route.ts | 14 +++--
src/app/api/mock/hibp/data/fakeBreaches.json | 8 +++
src/app/api/mock/hibp/mockConfigure/route.ts | 56 +++++++++++++++++++
src/utils/hibp.js | 17 +++++-
6 files changed, 89 insertions(+), 9 deletions(-)
create mode 100644 src/app/api/mock/hibp/data/fakeBreaches.json
create mode 100644 src/app/api/mock/hibp/mockConfigure/route.ts
diff --git a/.env-dist b/.env-dist
index 0519ef4f161..5d88112333b 100755
--- a/.env-dist
+++ b/.env-dist
@@ -55,6 +55,8 @@ OAUTH_API_URI="https://api-accounts.stage.mozaws.net/v1"
HIBP_RELOAD_BREACHES_TIMER=600
# HIBP API for range search and subscription
HIBP_KANON_API_ROOT=https://api.haveibeenpwned.com
+HIBP_KANON_API_ROOT_TRUE=https://api.haveibeenpwned.com
+HIBP_KANON_API_ROOT_FAKE=http://localhost:6060/api/mock/hibp
HIBP_KANON_API_TOKEN=
HIBP_API_ROOT=https://haveibeenpwned.com/api/v2
HIBP_API_TOKEN=
diff --git a/package.json b/package.json
index 08b08c6d5da..b03b4839052 100644
--- a/package.json
+++ b/package.json
@@ -135,7 +135,6 @@
"jest-fail-on-console": "^3.3.0",
"lint-staged": "^15.2.5",
"mjml-browser": "^4.15.3",
- "oauth2-mock-server": "^7.1.2",
"prettier": "3.2.5",
"react-intersection-observer": "^9.10.2",
"sass": "^1.77.4",
diff --git a/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts b/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
index f2c8bae7e9b..190fb74c664 100644
--- a/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
+++ b/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
@@ -5,7 +5,9 @@
import { NextResponse } from "next/server";
import { logger } from "../../../../../../functions/server/logging";
import { getSha1 } from "../../../../../../../utils/fxa";
+import fakeBreaches from "../../../data/fakeBreaches.json";
import type { BinaryLike } from "crypto";
+
type BreachedAccountResponse = {
hashSuffix: string;
websites: string[];
@@ -24,15 +26,15 @@ export function GET() {
// Mock data for test email, can be randomized
const userEmail = process.env.E2E_TEST_ACCOUNT_EMAIL;
+ //TODO: getServerSession doesn't work here for some reason
const currentUserSha = getSha1(userEmail as BinaryLike);
logger.info("Mock endpoint: /breachedaccount/range/");
- const data: BreachedAccountResponse = [
- {
- hashSuffix: currentUserSha.slice(6).toUpperCase(),
- websites: ["Adobe"],
- },
- ];
+ let data = fakeBreaches.data as BreachedAccountResponse;
+ data = data.map((elem) => ({
+ ...elem,
+ hashSuffix: currentUserSha.slice(6).toUpperCase(),
+ }));
return NextResponse.json(data);
}
diff --git a/src/app/api/mock/hibp/data/fakeBreaches.json b/src/app/api/mock/hibp/data/fakeBreaches.json
new file mode 100644
index 00000000000..84c48aa96ae
--- /dev/null
+++ b/src/app/api/mock/hibp/data/fakeBreaches.json
@@ -0,0 +1,8 @@
+{
+ "data": [
+ {
+ "hashSuffix": "",
+ "websites": ["Adobe", "AshleyMadison", "BTCE"]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/app/api/mock/hibp/mockConfigure/route.ts b/src/app/api/mock/hibp/mockConfigure/route.ts
new file mode 100644
index 00000000000..6482c26b924
--- /dev/null
+++ b/src/app/api/mock/hibp/mockConfigure/route.ts
@@ -0,0 +1,56 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { NextRequest, NextResponse } from "next/server";
+import { logger } from "../../../../functions/server/logging";
+
+export function GET() {
+ const { APP_ENV, HIBP_KANON_API_ROOT, HIBP_KANON_API_ROOT_TRUE } =
+ process.env;
+ if (APP_ENV === "production") {
+ logger.info("Attempt to access environment variable HIBP_KANON_API_ROOT");
+ return NextResponse.json(
+ { error: "Endpoint not available in production environment" },
+ { status: 403 },
+ );
+ }
+ return NextResponse.json({
+ message: `HIBP endpoint is ${HIBP_KANON_API_ROOT === HIBP_KANON_API_ROOT_TRUE ? "REAL" : "FAKE"}`,
+ });
+}
+
+export async function PUT(req: NextRequest) {
+ //TODO: make new environemnt variable to use for real vs mock endpoint
+
+ const { APP_ENV, HIBP_KANON_API_ROOT_TRUE, SERVER_URL } = process.env;
+ const reqJson = await req.json();
+ const useMock = reqJson.useMock;
+
+ // Check if APP_ENV is set to production
+ if (APP_ENV === "production") {
+ logger.info(
+ "Attempt to change environment variable HIBP_KANON_API_ROOT in production environment",
+ );
+ return NextResponse.json(
+ { error: "Endpoint not available in production environment" },
+ { status: 403 },
+ );
+ }
+ let msg =
+ "Environment variable HIBP_KANON_API_ROOT has been updated to use mock API";
+ // Set the HIBP_KANON_API_ROOT environment variable
+ if (useMock) {
+ process.env.HIBP_KANON_API_ROOT = SERVER_URL + "/api/mock/hibp";
+ } else {
+ process.env.HIBP_KANON_API_ROOT = HIBP_KANON_API_ROOT_TRUE;
+ msg =
+ "Environment variable HIBP_KANON_API_ROOT has been updated to use true API";
+ }
+ logger.info(msg);
+
+ // Return a success response
+ return NextResponse.json({
+ message: msg,
+ });
+}
diff --git a/src/utils/hibp.js b/src/utils/hibp.js
index 60c0b2837c9..3ea51fef134 100644
--- a/src/utils/hibp.js
+++ b/src/utils/hibp.js
@@ -61,8 +61,21 @@ async function _throttledFetch (url, reqOptions, tryCount = 1) {
throw new InternalServerError(`bad response: ${response.status}`)
}
} catch (err) {
- console.error('_throttledFetch', { err })
- throw new InternalServerError(getMessage('error-hibp-connect'))
+ const mockUrl = (String(process.env.HIBP_KANON_API_ROOT_FAKE)) + url.match(/\/breachedaccount.*/);
+
+ console.error('_throttledFetch - attempting to switch to mock endpoint', { err })
+ const fakeEndpoint = process.env.HIBP_KANON_API_ROOT_FAKE + '/mockConfigure';
+ await fetch(fakeEndpoint, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({'useMock': true})
+ })
+ const response = await fetch(mockUrl, reqOptions);
+ const resJson = await response.json();
+ if (response.ok) return resJson;
+ throw new InternalServerError('Both real and mock endpoints FAILED');
}
}
/* c8 ignore stop */
From 695e1fcf5cf66ec4a4e516e642cb80f60f088642 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Thu, 13 Jun 2024 01:40:09 -0700
Subject: [PATCH 004/137] made it host-flexibile for HIBP fallback
---
.env-dist | 2 +-
src/app/api/mock/hibp/mockConfigure/route.ts | 20 ++++++++++++++++++--
src/utils/hibp.js | 10 ++++++++--
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/.env-dist b/.env-dist
index 5d88112333b..cabc1dfd242 100755
--- a/.env-dist
+++ b/.env-dist
@@ -56,7 +56,7 @@ HIBP_RELOAD_BREACHES_TIMER=600
# HIBP API for range search and subscription
HIBP_KANON_API_ROOT=https://api.haveibeenpwned.com
HIBP_KANON_API_ROOT_TRUE=https://api.haveibeenpwned.com
-HIBP_KANON_API_ROOT_FAKE=http://localhost:6060/api/mock/hibp
+HIBP_KANON_API_SUFFIX_FAKE=/api/mock/hibp
HIBP_KANON_API_TOKEN=
HIBP_API_ROOT=https://haveibeenpwned.com/api/v2
HIBP_API_TOKEN=
diff --git a/src/app/api/mock/hibp/mockConfigure/route.ts b/src/app/api/mock/hibp/mockConfigure/route.ts
index 6482c26b924..56e088c2011 100644
--- a/src/app/api/mock/hibp/mockConfigure/route.ts
+++ b/src/app/api/mock/hibp/mockConfigure/route.ts
@@ -23,7 +23,23 @@ export function GET() {
export async function PUT(req: NextRequest) {
//TODO: make new environemnt variable to use for real vs mock endpoint
- const { APP_ENV, HIBP_KANON_API_ROOT_TRUE, SERVER_URL } = process.env;
+ const {
+ APP_ENV,
+ HIBP_KANON_API_ROOT_TRUE,
+ HIBP_KANON_API_SUFFIX_FAKE,
+ SERVER_URL,
+ } = process.env;
+
+ if (HIBP_KANON_API_SUFFIX_FAKE === undefined || SERVER_URL === undefined) {
+ return NextResponse.json(
+ {
+ error:
+ "Server environment not configured correctly: suffix_fake or server_url is undefined",
+ },
+ { status: 500 },
+ );
+ }
+
const reqJson = await req.json();
const useMock = reqJson.useMock;
@@ -41,7 +57,7 @@ export async function PUT(req: NextRequest) {
"Environment variable HIBP_KANON_API_ROOT has been updated to use mock API";
// Set the HIBP_KANON_API_ROOT environment variable
if (useMock) {
- process.env.HIBP_KANON_API_ROOT = SERVER_URL + "/api/mock/hibp";
+ process.env.HIBP_KANON_API_ROOT = SERVER_URL + HIBP_KANON_API_SUFFIX_FAKE;
} else {
process.env.HIBP_KANON_API_ROOT = HIBP_KANON_API_ROOT_TRUE;
msg =
diff --git a/src/utils/hibp.js b/src/utils/hibp.js
index 3ea51fef134..e689fe15ba3 100644
--- a/src/utils/hibp.js
+++ b/src/utils/hibp.js
@@ -61,10 +61,16 @@ async function _throttledFetch (url, reqOptions, tryCount = 1) {
throw new InternalServerError(`bad response: ${response.status}`)
}
} catch (err) {
- const mockUrl = (String(process.env.HIBP_KANON_API_ROOT_FAKE)) + url.match(/\/breachedaccount.*/);
+ const {SERVER_URL, HIBP_KANON_API_SUFFIX_FAKE} = process.env;
+ if (SERVER_URL === undefined || HIBP_KANON_API_SUFFIX_FAKE === undefined) {
+ throw new InternalServerError('Environemnt not configured correctly: Missing server_url or hibp_suffix_fake')
+ }
+
+ const mockHost = String(SERVER_URL) + String(HIBP_KANON_API_SUFFIX_FAKE);
+ const mockUrl = mockHost + url.match(/\/breachedaccount.*/);
console.error('_throttledFetch - attempting to switch to mock endpoint', { err })
- const fakeEndpoint = process.env.HIBP_KANON_API_ROOT_FAKE + '/mockConfigure';
+ const fakeEndpoint = mockHost + '/mockConfigure';
await fetch(fakeEndpoint, {
method: 'PUT',
headers: {
From e07af0e938b8162e72b059dd43bb4dd0e4faf405 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Thu, 13 Jun 2024 07:58:41 -0700
Subject: [PATCH 005/137] npx prettified fakeBraches.json
---
src/app/api/mock/hibp/data/fakeBreaches.json | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/app/api/mock/hibp/data/fakeBreaches.json b/src/app/api/mock/hibp/data/fakeBreaches.json
index 84c48aa96ae..d4d2731dbbb 100644
--- a/src/app/api/mock/hibp/data/fakeBreaches.json
+++ b/src/app/api/mock/hibp/data/fakeBreaches.json
@@ -1,8 +1,8 @@
{
"data": [
- {
- "hashSuffix": "",
- "websites": ["Adobe", "AshleyMadison", "BTCE"]
- }
+ {
+ "hashSuffix": "",
+ "websites": ["Adobe", "AshleyMadison", "BTCE"]
+ }
]
-}
\ No newline at end of file
+}
From c0b253a76cc6c041857e38d81ce2192337fb00e1 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Thu, 13 Jun 2024 08:48:06 -0700
Subject: [PATCH 006/137] made the code cleaner, and switch back to true
endpoint after using falling back to mock
---
src/utils/hibp.js | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/utils/hibp.js b/src/utils/hibp.js
index e689fe15ba3..ecb294931d4 100644
--- a/src/utils/hibp.js
+++ b/src/utils/hibp.js
@@ -29,6 +29,21 @@ function _addStandardOptions (options = {}) {
}
/* c8 ignore stop */
+/**
+ * @param {boolean} doUse
+ */
+async function toggleMockEndpoint(doUse) {
+ const {SERVER_URL, HIBP_KANON_API_SUFFIX_FAKE} = process.env;
+ const fakeEndpoint = String(SERVER_URL) + String(HIBP_KANON_API_SUFFIX_FAKE) + '/mockConfigure';
+ return await fetch(fakeEndpoint, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({'useMock': doUse})
+ })
+}
+
/**
* @param {string} url
* @param {any | undefined} reqOptions
@@ -70,15 +85,9 @@ async function _throttledFetch (url, reqOptions, tryCount = 1) {
const mockUrl = mockHost + url.match(/\/breachedaccount.*/);
console.error('_throttledFetch - attempting to switch to mock endpoint', { err })
- const fakeEndpoint = mockHost + '/mockConfigure';
- await fetch(fakeEndpoint, {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({'useMock': true})
- })
+ await toggleMockEndpoint(true);
const response = await fetch(mockUrl, reqOptions);
+ await toggleMockEndpoint(false);
const resJson = await response.json();
if (response.ok) return resJson;
throw new InternalServerError('Both real and mock endpoints FAILED');
From 25b590b71e83199c3ed899d2e3bf12156da03a83 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Thu, 13 Jun 2024 09:03:16 -0700
Subject: [PATCH 007/137] got rid of second promise wait
---
src/utils/hibp.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/utils/hibp.js b/src/utils/hibp.js
index ecb294931d4..35a569bc24a 100644
--- a/src/utils/hibp.js
+++ b/src/utils/hibp.js
@@ -87,7 +87,7 @@ async function _throttledFetch (url, reqOptions, tryCount = 1) {
console.error('_throttledFetch - attempting to switch to mock endpoint', { err })
await toggleMockEndpoint(true);
const response = await fetch(mockUrl, reqOptions);
- await toggleMockEndpoint(false);
+ toggleMockEndpoint(false);
const resJson = await response.json();
if (response.ok) return resJson;
throw new InternalServerError('Both real and mock endpoints FAILED');
From ab680afadce9e3eb6265e8fc3e1504d5414d7ea7 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Mon, 17 Jun 2024 14:22:35 -0700
Subject: [PATCH 008/137] removed other features, kept only the mock endpoint
---
.env-dist | 2 -
src/app/api/mock/hibp/breaches/route.ts | 45 ++++++++++++
.../api/mock/hibp/data/fakeAllBreaches.json | 52 ++++++++++++++
src/app/api/mock/hibp/mockConfigure/route.ts | 72 -------------------
src/utils/hibp.js | 32 +--------
5 files changed, 99 insertions(+), 104 deletions(-)
create mode 100644 src/app/api/mock/hibp/breaches/route.ts
create mode 100644 src/app/api/mock/hibp/data/fakeAllBreaches.json
delete mode 100644 src/app/api/mock/hibp/mockConfigure/route.ts
diff --git a/.env-dist b/.env-dist
index ca60b0f451c..7757f312ddd 100755
--- a/.env-dist
+++ b/.env-dist
@@ -55,8 +55,6 @@ OAUTH_API_URI="https://api-accounts.stage.mozaws.net/v1"
HIBP_RELOAD_BREACHES_TIMER=600
# HIBP API for range search and subscription
HIBP_KANON_API_ROOT=https://api.haveibeenpwned.com
-HIBP_KANON_API_ROOT_TRUE=https://api.haveibeenpwned.com
-HIBP_KANON_API_SUFFIX_FAKE=/api/mock/hibp
HIBP_KANON_API_TOKEN=
HIBP_API_ROOT=https://haveibeenpwned.com/api/v2
HIBP_API_TOKEN=
diff --git a/src/app/api/mock/hibp/breaches/route.ts b/src/app/api/mock/hibp/breaches/route.ts
new file mode 100644
index 00000000000..5c4230b773f
--- /dev/null
+++ b/src/app/api/mock/hibp/breaches/route.ts
@@ -0,0 +1,45 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { NextResponse } from "next/server";
+import { logger } from "../../../../functions/server/logging";
+import fakeAllBreaches from "../data/fakeAllBreaches.json";
+
+type BreachesListResponse = {
+ Id: number;
+ Name: string;
+ Title: string;
+ Domain: string;
+ BreachDate: string;
+ AddedDate: string;
+ ModifiedDate: string;
+ PwnCount: number;
+ Description: string;
+ LogoPath: string;
+ DataClasses: string[];
+ IsVerified: boolean;
+ IsFabricated: boolean;
+ IsSensitive: boolean;
+ IsRetired: boolean;
+ IsSpamList: boolean;
+ IsMalware: boolean;
+ FaviconUrl: string | null;
+}[];
+
+export function GET() {
+ const { APP_ENV } = process.env;
+
+ // Check if APP_ENV is set to production
+ if (APP_ENV === "production") {
+ return NextResponse.json(
+ { error: "Endpoint not available in production environment" },
+ { status: 403 },
+ );
+ }
+ logger.info("Mock endpoint: /breaches");
+
+ const data = fakeAllBreaches.data as BreachesListResponse;
+
+ return NextResponse.json(data);
+}
diff --git a/src/app/api/mock/hibp/data/fakeAllBreaches.json b/src/app/api/mock/hibp/data/fakeAllBreaches.json
new file mode 100644
index 00000000000..42524b86c5a
--- /dev/null
+++ b/src/app/api/mock/hibp/data/fakeAllBreaches.json
@@ -0,0 +1,52 @@
+{
+ "data": [
+ {
+ "Id": 1,
+ "Name": "000webhost",
+ "Title": "000webhost",
+ "Domain": "000webhost.com",
+ "BreachDate": "2015-03-01T08:00:00.000Z",
+ "AddedDate": "2015-10-26T23:35:45.000Z",
+ "ModifiedDate": "2017-12-10T21:44:27.000Z",
+ "PwnCount": 14936670,
+ "Description": "In approximately March 2015, the free web hosting provider 000webhost suffered a major data breach that exposed almost 15 million customer records. The data was sold and traded before 000webhost was alerted in October. The breach included names, email addresses and plain text passwords.",
+ "LogoPath": "https://haveibeenpwned.com/Content/Images/PwnedLogos/000webhost.png",
+ "DataClasses": ["email-addresses", "ip-addresses", "names", "passwords"],
+ "IsVerified": true,
+ "IsFabricated": false,
+ "IsSensitive": false,
+ "IsRetired": false,
+ "IsSpamList": false,
+ "IsMalware": false,
+ "FaviconUrl": null
+ },
+ {
+ "Id": 2,
+ "Name": "123RF",
+ "Title": "123RF",
+ "Domain": "123rf.com",
+ "BreachDate": "2020-03-22T07:00:00.000Z",
+ "AddedDate": "2020-11-15T00:59:50.000Z",
+ "ModifiedDate": "2020-11-15T01:07:10.000Z",
+ "PwnCount": 8661578,
+ "Description": "In March 2020, the stock photo site 123RF suffered a data breach which impacted over 8 million subscribers and was subsequently sold online. The breach included email, IP and physical addresses, names, phone numbers and passwords stored as MD5 hashes. The data was provided to HIBP by dehashed.com.",
+ "LogoPath": "https://haveibeenpwned.com/Content/Images/PwnedLogos/123RF.png",
+ "DataClasses": [
+ "email-addresses",
+ "ip-addresses",
+ "names",
+ "passwords",
+ "phone-numbers",
+ "physical-addresses",
+ "usernames"
+ ],
+ "IsVerified": true,
+ "IsFabricated": false,
+ "IsSensitive": false,
+ "IsRetired": false,
+ "IsSpamList": false,
+ "IsMalware": false,
+ "FaviconUrl": null
+ }
+ ]
+}
diff --git a/src/app/api/mock/hibp/mockConfigure/route.ts b/src/app/api/mock/hibp/mockConfigure/route.ts
deleted file mode 100644
index 56e088c2011..00000000000
--- a/src/app/api/mock/hibp/mockConfigure/route.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-import { NextRequest, NextResponse } from "next/server";
-import { logger } from "../../../../functions/server/logging";
-
-export function GET() {
- const { APP_ENV, HIBP_KANON_API_ROOT, HIBP_KANON_API_ROOT_TRUE } =
- process.env;
- if (APP_ENV === "production") {
- logger.info("Attempt to access environment variable HIBP_KANON_API_ROOT");
- return NextResponse.json(
- { error: "Endpoint not available in production environment" },
- { status: 403 },
- );
- }
- return NextResponse.json({
- message: `HIBP endpoint is ${HIBP_KANON_API_ROOT === HIBP_KANON_API_ROOT_TRUE ? "REAL" : "FAKE"}`,
- });
-}
-
-export async function PUT(req: NextRequest) {
- //TODO: make new environemnt variable to use for real vs mock endpoint
-
- const {
- APP_ENV,
- HIBP_KANON_API_ROOT_TRUE,
- HIBP_KANON_API_SUFFIX_FAKE,
- SERVER_URL,
- } = process.env;
-
- if (HIBP_KANON_API_SUFFIX_FAKE === undefined || SERVER_URL === undefined) {
- return NextResponse.json(
- {
- error:
- "Server environment not configured correctly: suffix_fake or server_url is undefined",
- },
- { status: 500 },
- );
- }
-
- const reqJson = await req.json();
- const useMock = reqJson.useMock;
-
- // Check if APP_ENV is set to production
- if (APP_ENV === "production") {
- logger.info(
- "Attempt to change environment variable HIBP_KANON_API_ROOT in production environment",
- );
- return NextResponse.json(
- { error: "Endpoint not available in production environment" },
- { status: 403 },
- );
- }
- let msg =
- "Environment variable HIBP_KANON_API_ROOT has been updated to use mock API";
- // Set the HIBP_KANON_API_ROOT environment variable
- if (useMock) {
- process.env.HIBP_KANON_API_ROOT = SERVER_URL + HIBP_KANON_API_SUFFIX_FAKE;
- } else {
- process.env.HIBP_KANON_API_ROOT = HIBP_KANON_API_ROOT_TRUE;
- msg =
- "Environment variable HIBP_KANON_API_ROOT has been updated to use true API";
- }
- logger.info(msg);
-
- // Return a success response
- return NextResponse.json({
- message: msg,
- });
-}
diff --git a/src/utils/hibp.js b/src/utils/hibp.js
index 35a569bc24a..60c0b2837c9 100644
--- a/src/utils/hibp.js
+++ b/src/utils/hibp.js
@@ -29,21 +29,6 @@ function _addStandardOptions (options = {}) {
}
/* c8 ignore stop */
-/**
- * @param {boolean} doUse
- */
-async function toggleMockEndpoint(doUse) {
- const {SERVER_URL, HIBP_KANON_API_SUFFIX_FAKE} = process.env;
- const fakeEndpoint = String(SERVER_URL) + String(HIBP_KANON_API_SUFFIX_FAKE) + '/mockConfigure';
- return await fetch(fakeEndpoint, {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({'useMock': doUse})
- })
-}
-
/**
* @param {string} url
* @param {any | undefined} reqOptions
@@ -76,21 +61,8 @@ async function _throttledFetch (url, reqOptions, tryCount = 1) {
throw new InternalServerError(`bad response: ${response.status}`)
}
} catch (err) {
- const {SERVER_URL, HIBP_KANON_API_SUFFIX_FAKE} = process.env;
- if (SERVER_URL === undefined || HIBP_KANON_API_SUFFIX_FAKE === undefined) {
- throw new InternalServerError('Environemnt not configured correctly: Missing server_url or hibp_suffix_fake')
- }
-
- const mockHost = String(SERVER_URL) + String(HIBP_KANON_API_SUFFIX_FAKE);
- const mockUrl = mockHost + url.match(/\/breachedaccount.*/);
-
- console.error('_throttledFetch - attempting to switch to mock endpoint', { err })
- await toggleMockEndpoint(true);
- const response = await fetch(mockUrl, reqOptions);
- toggleMockEndpoint(false);
- const resJson = await response.json();
- if (response.ok) return resJson;
- throw new InternalServerError('Both real and mock endpoints FAILED');
+ console.error('_throttledFetch', { err })
+ throw new InternalServerError(getMessage('error-hibp-connect'))
}
}
/* c8 ignore stop */
From 184cfcf0295db6b4c3462373b2692a41cbfc59d0 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Mon, 17 Jun 2024 14:27:41 -0700
Subject: [PATCH 009/137] made breaches list match the fake breaches for a user
---
src/app/api/mock/hibp/data/fakeBreaches.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/api/mock/hibp/data/fakeBreaches.json b/src/app/api/mock/hibp/data/fakeBreaches.json
index d4d2731dbbb..70dbadb067c 100644
--- a/src/app/api/mock/hibp/data/fakeBreaches.json
+++ b/src/app/api/mock/hibp/data/fakeBreaches.json
@@ -2,7 +2,7 @@
"data": [
{
"hashSuffix": "",
- "websites": ["Adobe", "AshleyMadison", "BTCE"]
+ "websites": ["000webhost", "123RF"]
}
]
}
From dda9c226daa44910a52fb7cc16e0eb00aa4a734b Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Wed, 19 Jun 2024 17:09:21 -0700
Subject: [PATCH 010/137] file endpoint additions
---
src/app/api/mock/onerep/config/config.ts | 6 ++
src/app/api/mock/onerep/data-brokers/route.ts | 4 +
.../profiles/[profileId]/activate/route.ts | 4 +
.../profiles/[profileId]/deactivate/route.ts | 4 +
.../profiles/[profileId]/optout/route.ts | 4 +
.../mock/onerep/profiles/[profileId]/route.ts | 33 +++++++
.../[profileId]/scans/[scanId]/route.ts | 4 +
.../profiles/[profileId]/scans/route.ts | 4 +
src/app/api/mock/onerep/profiles/route.ts | 86 +++++++++++++++++++
.../api/mock/onerep/stats/profiles/route.ts | 4 +
10 files changed, 153 insertions(+)
create mode 100644 src/app/api/mock/onerep/config/config.ts
create mode 100644 src/app/api/mock/onerep/data-brokers/route.ts
create mode 100644 src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
create mode 100644 src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
create mode 100644 src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
create mode 100644 src/app/api/mock/onerep/profiles/[profileId]/route.ts
create mode 100644 src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
create mode 100644 src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
create mode 100644 src/app/api/mock/onerep/profiles/route.ts
create mode 100644 src/app/api/mock/onerep/stats/profiles/route.ts
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
new file mode 100644
index 00000000000..d8ff54ecdbf
--- /dev/null
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -0,0 +1,6 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+export const MOCK_PROFILE_ID = 777;
+export const MOCK_TIME = "2024-06-19T01:37:02+0000";
diff --git a/src/app/api/mock/onerep/data-brokers/route.ts b/src/app/api/mock/onerep/data-brokers/route.ts
new file mode 100644
index 00000000000..b7e0a1d5ef1
--- /dev/null
+++ b/src/app/api/mock/onerep/data-brokers/route.ts
@@ -0,0 +1,4 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
new file mode 100644
index 00000000000..b7e0a1d5ef1
--- /dev/null
+++ b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
@@ -0,0 +1,4 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
new file mode 100644
index 00000000000..b7e0a1d5ef1
--- /dev/null
+++ b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
@@ -0,0 +1,4 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
new file mode 100644
index 00000000000..b7e0a1d5ef1
--- /dev/null
+++ b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
@@ -0,0 +1,4 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
new file mode 100644
index 00000000000..d3f92e90f31
--- /dev/null
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -0,0 +1,33 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { NextApiRequest, NextApiResponse } from "next";
+import { ShowProfileResponse } from "../../../../../functions/server/onerep";
+
+// Mocked profile data to simulate response
+const mockProfileData: ShowProfileResponse = {
+ id: 0,
+ first_name: "",
+ last_name: "",
+ birth_date: "",
+ addresses: [{ state: "", city: "" }],
+ status: "",
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ url: `https://api.onerep.com/profiles/`,
+};
+
+// Mock endpoint to simulate fetching a profile by ID
+export default function GET(req: NextApiRequest, res: NextApiResponse) {
+ // Extract profileId from query parameters or request body
+ const profileId: number = Number(req.query.profileId || req.body.profileId);
+
+ // Simulate error if profileId is not provided or not valid
+ if (!profileId || isNaN(profileId)) {
+ res.status(400).json({ error: "Invalid profile ID" });
+ return;
+ }
+
+ res.status(200).json(mockProfileData);
+}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
new file mode 100644
index 00000000000..b7e0a1d5ef1
--- /dev/null
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -0,0 +1,4 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
new file mode 100644
index 00000000000..b7e0a1d5ef1
--- /dev/null
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -0,0 +1,4 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
diff --git a/src/app/api/mock/onerep/profiles/route.ts b/src/app/api/mock/onerep/profiles/route.ts
new file mode 100644
index 00000000000..2b2b219d021
--- /dev/null
+++ b/src/app/api/mock/onerep/profiles/route.ts
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import type { NextApiRequest, NextApiResponse } from "next";
+import { MOCK_PROFILE_ID, MOCK_TIME } from "../config/config.ts";
+
+type RequestProfileData = {
+ first_name: string;
+ last_name: string;
+ middle_name: string;
+ birth_date: string;
+ addresses: Array<{ state: string; city: string }>;
+};
+
+type ResponseProfileData = {
+ id: number;
+ first_name: string;
+ last_name: string;
+ middle_name: string | null;
+ birth_date: string;
+ first_names: string[];
+ middle_names: string[];
+ last_names: string[];
+ phone_numbers: string[];
+ emails: string[];
+ addresses: Array<{
+ id: number;
+ profile_id: number;
+ state: string;
+ city: string;
+ address_line: string | null;
+ zip: string | null;
+ created_at: string;
+ updated_at: string;
+ url: string;
+ }>;
+ status: "active" | "inactive";
+ created_at: string;
+ updated_at: string;
+ url: string;
+};
+
+// Mock API endpoint
+export default function POST(req: NextApiRequest, res: NextApiResponse) {
+ //TODO: mock out all URLs
+ try {
+ const requestProfile: RequestProfileData = JSON.parse(req.body);
+
+ // Mock response object
+ const responseProfile: ResponseProfileData = {
+ id: MOCK_PROFILE_ID, //Random Mock id
+ first_name: requestProfile.first_name,
+ last_name: requestProfile.last_name,
+ middle_name: requestProfile.middle_name,
+ birth_date: requestProfile.birth_date,
+ first_names: [],
+ middle_names: [],
+ last_names: [],
+ phone_numbers: [],
+ emails: [],
+ addresses: requestProfile.addresses.map((addr, index) => ({
+ id: MOCK_PROFILE_ID + index, // Mocked IDs for addresses
+ profile_id: MOCK_PROFILE_ID,
+ state: addr.state,
+ city: addr.city,
+ address_line: null,
+ zip: null,
+ created_at: MOCK_TIME,
+ updated_at: MOCK_TIME,
+ url: `https://api.onerep.com/profiles/${MOCK_PROFILE_ID}/addresses/${MOCK_PROFILE_ID + index}`,
+ })),
+ status: "inactive", //assuming status is active
+ created_at: MOCK_TIME,
+ updated_at: MOCK_TIME,
+ url: `https://api.onerep.com/profiles/${MOCK_PROFILE_ID}`,
+ };
+
+ res.status(201).json(responseProfile);
+ } catch (error) {
+ console.error("Failed to process request:", error);
+ res
+ .status(400)
+ .json({ error: "Bad Request: Invalid JSON or incorrect data structure" });
+ }
+}
diff --git a/src/app/api/mock/onerep/stats/profiles/route.ts b/src/app/api/mock/onerep/stats/profiles/route.ts
new file mode 100644
index 00000000000..b7e0a1d5ef1
--- /dev/null
+++ b/src/app/api/mock/onerep/stats/profiles/route.ts
@@ -0,0 +1,4 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
From 988997c80d8069af2a400ba781e4bc7341187861 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Tue, 25 Jun 2024 01:57:28 -0700
Subject: [PATCH 011/137] funtional commit - mocked accessed endpoints
---
src/app/api/mock/onerep/config/config.ts | 10 +++
src/app/api/mock/onerep/config/userObject.ts | 39 ++++++++++
src/app/api/mock/onerep/data-brokers/route.ts | 6 ++
.../profiles/[profileId]/activate/route.ts | 15 ++++
.../profiles/[profileId]/deactivate/route.ts | 15 ++++
.../profiles/[profileId]/optout/route.ts | 15 ++++
.../mock/onerep/profiles/[profileId]/route.ts | 52 ++++++++-----
.../[profileId]/scans/[scanId]/route.ts | 21 +++++
.../profiles/[profileId]/scans/route.ts | 67 ++++++++++++++++
src/app/api/mock/onerep/profiles/route.ts | 76 ++++++-------------
src/app/api/mock/onerep/scan-results/route.ts | 65 ++++++++++++++++
.../api/mock/onerep/stats/profiles/route.ts | 16 ++++
src/app/functions/server/onerep.ts | 44 ++++++++---
src/db/tables/onerep_scans.ts | 1 +
14 files changed, 359 insertions(+), 83 deletions(-)
create mode 100644 src/app/api/mock/onerep/config/userObject.ts
create mode 100644 src/app/api/mock/onerep/scan-results/route.ts
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index d8ff54ecdbf..573ac048713 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -2,5 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { StateAbbr } from "../../../../../utils/states";
+
export const MOCK_PROFILE_ID = 777;
+export const MOCK_SCAN_ID = 6972;
export const MOCK_TIME = "2024-06-19T01:37:02+0000";
+export const MOCK_FIRSTNAME = "John";
+export const MOCK_LASTNAME = "Doe";
+export const MOCK_BIRTHDATE = "2000-01-01";
+
+export const MOCK_ADDRESSES: [{ city: string; state: StateAbbr }] = [
+ { city: "Berkeley", state: "CA" as StateAbbr },
+];
diff --git a/src/app/api/mock/onerep/config/userObject.ts b/src/app/api/mock/onerep/config/userObject.ts
new file mode 100644
index 00000000000..58f284c32ea
--- /dev/null
+++ b/src/app/api/mock/onerep/config/userObject.ts
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+export type RequestProfileData = {
+ first_name: string;
+ last_name: string;
+ middle_name: string;
+ birth_date: string;
+ addresses: Array<{ state: string; city: string }>;
+};
+
+export type ResponseProfileData = {
+ id: number;
+ first_name: string;
+ last_name: string;
+ middle_name: string | null;
+ birth_date: string;
+ first_names: string[];
+ middle_names: string[];
+ last_names: string[];
+ phone_numbers: string[];
+ emails: string[];
+ addresses: Array<{
+ id: number;
+ profile_id: number;
+ state: string;
+ city: string;
+ address_line: string | null;
+ zip: string | null;
+ created_at: string;
+ updated_at: string;
+ url: string;
+ }>;
+ status: "active" | "inactive";
+ created_at: string;
+ updated_at: string;
+ url: string;
+};
diff --git a/src/app/api/mock/onerep/data-brokers/route.ts b/src/app/api/mock/onerep/data-brokers/route.ts
index b7e0a1d5ef1..a047a740545 100644
--- a/src/app/api/mock/onerep/data-brokers/route.ts
+++ b/src/app/api/mock/onerep/data-brokers/route.ts
@@ -2,3 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { NextResponse } from "next/server";
+
+//ONLY PART OF ADMIN - probably shouldn't mock?
+export default function handler() {
+ return NextResponse.json({ error: "You've reached a mock endpoint" });
+}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
index b7e0a1d5ef1..dcae96793f8 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
@@ -2,3 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { NextRequest, NextResponse } from "next/server";
+
+export function PUT(req: NextRequest) {
+ const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+
+ if (!profileId || isNaN(profileId)) {
+ return NextResponse.json({ error: "Invalid profile ID" });
+ }
+
+ //TODO: update the json file corresponding to this user
+
+ return NextResponse.json({
+ message: `Profile ${profileId} successfully activated`,
+ });
+}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
index b7e0a1d5ef1..964652c369d 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
@@ -2,3 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { NextRequest, NextResponse } from "next/server";
+
+export function PUT(req: NextRequest) {
+ const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+
+ if (!profileId || isNaN(profileId)) {
+ return NextResponse.json({ error: "Invalid profile ID" });
+ }
+
+ //TODO: update the json file corresponding to this user
+
+ return NextResponse.json({
+ message: `Profile ${profileId} successfully deactivated`,
+ });
+}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
index b7e0a1d5ef1..8a3bed0ecb6 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
@@ -2,3 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { NextRequest, NextResponse } from "next/server";
+
+export function PUT(req: NextRequest) {
+ const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+
+ if (!profileId || isNaN(profileId)) {
+ return NextResponse.json({ error: "Invalid profile ID" });
+ }
+
+ //TODO: update the json file corresponding to this user
+
+ return NextResponse.json({
+ message: `Profile ${profileId} successfully opted out`,
+ });
+}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
index d3f92e90f31..1eefb2c3b11 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -2,32 +2,46 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import { NextApiRequest, NextApiResponse } from "next";
-import { ShowProfileResponse } from "../../../../../functions/server/onerep";
+import {
+ MOCK_TIME,
+ MOCK_FIRSTNAME,
+ MOCK_LASTNAME,
+ MOCK_BIRTHDATE,
+ MOCK_ADDRESSES,
+} from "../../config/config.ts";
+import { ShowProfileResponse } from "../../../../../functions/server/onerep.ts";
+import { NextRequest, NextResponse } from "next/server";
// Mocked profile data to simulate response
-const mockProfileData: ShowProfileResponse = {
- id: 0,
- first_name: "",
- last_name: "",
- birth_date: "",
- addresses: [{ state: "", city: "" }],
- status: "",
- created_at: new Date().toISOString(),
- updated_at: new Date().toISOString(),
- url: `https://api.onerep.com/profiles/`,
-};
+//TODO: mock out the URL
+
+async function extractProfileId(req: NextRequest) {
+ const idFromBody: number = req.body !== null && (await req.json()).profileId;
+ if (idFromBody) return idFromBody;
+ const idFromUrl: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+ return idFromUrl;
+}
// Mock endpoint to simulate fetching a profile by ID
-export default function GET(req: NextApiRequest, res: NextApiResponse) {
+export async function GET(req: NextRequest) {
// Extract profileId from query parameters or request body
- const profileId: number = Number(req.query.profileId || req.body.profileId);
+ const profileId: number = await extractProfileId(req);
- // Simulate error if profileId is not provided or not valid
if (!profileId || isNaN(profileId)) {
- res.status(400).json({ error: "Invalid profile ID" });
- return;
+ return NextResponse.json({ error: "Invalid profile ID" }, { status: 400 });
}
- res.status(200).json(mockProfileData);
+ const mockProfileData: ShowProfileResponse = {
+ id: profileId,
+ first_name: MOCK_FIRSTNAME,
+ last_name: MOCK_LASTNAME,
+ birth_date: MOCK_BIRTHDATE,
+ addresses: MOCK_ADDRESSES,
+ status: "inactive",
+ created_at: MOCK_TIME,
+ updated_at: MOCK_TIME,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
+ };
+
+ return NextResponse.json(mockProfileData);
}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index b7e0a1d5ef1..7119f8e075d 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -2,3 +2,24 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+// pages/api/profiles/[profileId]/scans/[scanId].ts
+
+import { MOCK_TIME } from "../../../../config/config";
+import { NextRequest, NextResponse } from "next/server";
+
+export function GET(req: NextRequest) {
+ const profileId = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+ const scanId = Number(req.url.match(/scans\/([0-9]+)/)![1]);
+
+ // Check for the availability of the scan
+ const responseData = {
+ id: scanId,
+ profile_id: profileId,
+ status: "finished",
+ reason: "manual",
+ created_at: MOCK_TIME,
+ updated_at: MOCK_TIME,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
+ };
+ return NextResponse.json(responseData);
+}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index b7e0a1d5ef1..17f0d44bb42 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -2,3 +2,70 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { MOCK_SCAN_ID, MOCK_TIME } from "../../../config/config";
+import { NextRequest, NextResponse } from "next/server";
+
+//TODO: mock out the id field and url
+
+function extractProfileId(req: NextRequest) {
+ const idFromUrl = Number(req.url.match(/profiles\/([0-9]+)\/scans/)![1]);
+ return idFromUrl;
+}
+
+export function POST(req: NextRequest) {
+ const profileId: number = extractProfileId(req);
+ if (!profileId || isNaN(profileId)) {
+ return NextResponse.json({ error: "Invalid profile ID" });
+ }
+
+ const mockResponse = {
+ id: MOCK_SCAN_ID,
+ profile_id: profileId,
+ status: "finished",
+ reason: "manual",
+ created_at: MOCK_TIME,
+ updated_at: MOCK_TIME,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_SCAN_ID}`,
+ };
+
+ return NextResponse.json(mockResponse);
+}
+
+export function GET(req: NextRequest) {
+ const profileId: number = extractProfileId(req);
+
+ if (!profileId || isNaN(profileId)) {
+ return NextResponse.json({ error: "Invalid profile ID" });
+ }
+
+ //TODO: mock out ID here and urls
+ const responseData = {
+ data: [
+ {
+ id: MOCK_SCAN_ID,
+ profile_id: profileId,
+ status: "finished",
+ reason: "manual",
+ created_at: MOCK_TIME,
+ updated_at: MOCK_TIME,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_SCAN_ID}`,
+ },
+ ],
+ links: {
+ first: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans?page=1`,
+ last: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans?page=1`,
+ prev: null,
+ next: null,
+ },
+ meta: {
+ current_page: 1,
+ from: 1,
+ last_page: 1,
+ path: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans`,
+ per_page: 20,
+ to: 1,
+ total: 1,
+ },
+ };
+ return NextResponse.json(responseData);
+}
diff --git a/src/app/api/mock/onerep/profiles/route.ts b/src/app/api/mock/onerep/profiles/route.ts
index 2b2b219d021..e60b7746660 100644
--- a/src/app/api/mock/onerep/profiles/route.ts
+++ b/src/app/api/mock/onerep/profiles/route.ts
@@ -2,54 +2,26 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import type { NextApiRequest, NextApiResponse } from "next";
-import { MOCK_PROFILE_ID, MOCK_TIME } from "../config/config.ts";
-
-type RequestProfileData = {
- first_name: string;
- last_name: string;
- middle_name: string;
- birth_date: string;
- addresses: Array<{ state: string; city: string }>;
-};
-
-type ResponseProfileData = {
- id: number;
- first_name: string;
- last_name: string;
- middle_name: string | null;
- birth_date: string;
- first_names: string[];
- middle_names: string[];
- last_names: string[];
- phone_numbers: string[];
- emails: string[];
- addresses: Array<{
- id: number;
- profile_id: number;
- state: string;
- city: string;
- address_line: string | null;
- zip: string | null;
- created_at: string;
- updated_at: string;
- url: string;
- }>;
- status: "active" | "inactive";
- created_at: string;
- updated_at: string;
- url: string;
-};
+import { MOCK_TIME } from "../config/config.ts";
+import {
+ ResponseProfileData,
+ RequestProfileData,
+} from "../config/userObject.ts";
+import { NextRequest, NextResponse } from "next/server";
+import { randomInt } from "crypto";
// Mock API endpoint
-export default function POST(req: NextApiRequest, res: NextApiResponse) {
+export async function POST(req: NextRequest) {
//TODO: mock out all URLs
+ const profileId = randomInt(1000, 10000);
try {
- const requestProfile: RequestProfileData = JSON.parse(req.body);
-
+ if (req.body === null) {
+ return NextResponse.json({ error: "Invalid request - without body" });
+ }
+ const requestProfile: RequestProfileData = await req.json();
// Mock response object
const responseProfile: ResponseProfileData = {
- id: MOCK_PROFILE_ID, //Random Mock id
+ id: profileId,
first_name: requestProfile.first_name,
last_name: requestProfile.last_name,
middle_name: requestProfile.middle_name,
@@ -60,27 +32,27 @@ export default function POST(req: NextApiRequest, res: NextApiResponse) {
phone_numbers: [],
emails: [],
addresses: requestProfile.addresses.map((addr, index) => ({
- id: MOCK_PROFILE_ID + index, // Mocked IDs for addresses
- profile_id: MOCK_PROFILE_ID,
+ id: profileId + index, // Mocked IDs for addresses
+ profile_id: profileId,
state: addr.state,
city: addr.city,
address_line: null,
zip: null,
created_at: MOCK_TIME,
updated_at: MOCK_TIME,
- url: `https://api.onerep.com/profiles/${MOCK_PROFILE_ID}/addresses/${MOCK_PROFILE_ID + index}`,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/addresses/${profileId + index}`,
})),
- status: "inactive", //assuming status is active
+ status: "active", //assuming status is active
created_at: MOCK_TIME,
updated_at: MOCK_TIME,
- url: `https://api.onerep.com/profiles/${MOCK_PROFILE_ID}`,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
};
-
- res.status(201).json(responseProfile);
+ return NextResponse.json(responseProfile, { status: 201 });
} catch (error) {
console.error("Failed to process request:", error);
- res
- .status(400)
- .json({ error: "Bad Request: Invalid JSON or incorrect data structure" });
+ return NextResponse.json(
+ { error: "Bad Request: Invalid JSON or incorrect data structure" },
+ { status: 403 },
+ );
}
}
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
new file mode 100644
index 00000000000..9e2e21cba32
--- /dev/null
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -0,0 +1,65 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import {
+ MOCK_FIRSTNAME,
+ MOCK_LASTNAME,
+ MOCK_TIME,
+ MOCK_PROFILE_ID,
+ MOCK_SCAN_ID,
+} from "../config/config";
+import { NextRequest, NextResponse } from "next/server";
+
+//TODO: mock out all URLS
+export function GET(req: NextRequest) {
+ // const profileId = MOCK_PROFILE_ID
+ const page = req.url.match(/page=([0-9]+)/)![1] || "1";
+ const perPage = req.url.match(/per_page=([0-9]+)/)![1] || "100";
+
+ const magicNum0 = 37680;
+ const magicNum1 = 23;
+ const howMany = 10;
+
+ // TODO: mock put the indecies, id scan_id
+ const responseData = {
+ data: new Array(howMany).fill(null).map((_, index) => ({
+ id: magicNum0 - index,
+ profile_id: MOCK_PROFILE_ID,
+ scan_id: MOCK_SCAN_ID,
+ status: "new",
+ first_name: MOCK_FIRSTNAME,
+ middle_name: null,
+ last_name: MOCK_LASTNAME,
+ age: null,
+ addresses: [],
+ phones: [],
+ emails: [],
+ relatives: [],
+ link: `https://example.com/link-to-databroker${index}`,
+ data_broker: `example${index}.com`,
+ data_broker_id: magicNum1 - index,
+ optout_attempts: 0,
+ created_at: MOCK_TIME,
+ updated_at: MOCK_TIME,
+ url: `${process.env.ONEREP_API_BASE}scan-results/${magicNum0 - index}`,
+ })),
+ links: {
+ first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${MOCK_PROFILE_ID}&per_page=100&page=1`,
+ last: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${MOCK_PROFILE_ID}&per_page=100&page=1`,
+ prev: null,
+ next: null,
+ },
+ meta: {
+ current_page: parseInt(page),
+ from: 1,
+ last_page: 1,
+ path: `${process.env.ONEREP_API_BASE}/scan-results`,
+ per_page: parseInt(perPage),
+ to: 10,
+ total: 10,
+ },
+ };
+
+ return NextResponse.json(responseData);
+}
diff --git a/src/app/api/mock/onerep/stats/profiles/route.ts b/src/app/api/mock/onerep/stats/profiles/route.ts
index b7e0a1d5ef1..ffd8f958068 100644
--- a/src/app/api/mock/onerep/stats/profiles/route.ts
+++ b/src/app/api/mock/onerep/stats/profiles/route.ts
@@ -2,3 +2,19 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { NextResponse } from "next/server";
+
+export function GET() {
+ const profileStats = {
+ created: 0,
+ deleted: 0,
+ activated: 0,
+ reactivated: 0,
+ deactivated: 0,
+ total_active: 0,
+ total_inactive: 0,
+ total: 0,
+ };
+
+ return NextResponse.json(profileStats);
+}
diff --git a/src/app/functions/server/onerep.ts b/src/app/functions/server/onerep.ts
index be35d5379b8..db318d756db 100644
--- a/src/app/functions/server/onerep.ts
+++ b/src/app/functions/server/onerep.ts
@@ -38,7 +38,7 @@ export type ShowProfileResponse = CreateProfileRequest & {
status: "active" | "inactive";
created_at: ISO8601DateString;
updated_at: ISO8601DateString;
- url: `https://api.onerep.com/profiles/${number}`;
+ url: `${string}/profiles/${number}`;
};
export type CreateScanResponse = {
id: number;
@@ -142,7 +142,8 @@ export async function createProfile(
},
],
};
- const response = await onerepFetch("/profiles", {
+ //TODO: add conditional check for '/'
+ const response = await onerepFetch("profiles", {
method: "POST",
body: JSON.stringify(requestBody),
});
@@ -173,7 +174,8 @@ export async function createProfile(
export async function getProfile(
profileId: number,
): Promise {
- const response: Response = await onerepFetch(`/profiles/${profileId}`, {
+ //TODO: add conditional check for '/'
+ const response: Response = await onerepFetch(`profiles/${profileId}`, {
method: "GET",
});
if (!response.ok) {
@@ -190,8 +192,10 @@ export async function getProfile(
}
export async function activateProfile(profileId: number): Promise {
+ //TODO: add conditional check for '/'
+
const response: Response = await onerepFetch(
- `/profiles/${profileId}/activate`,
+ `profiles/${profileId}/activate`,
{
method: "PUT",
},
@@ -207,8 +211,10 @@ export async function activateProfile(profileId: number): Promise {
}
export async function deactivateProfile(profileId: number): Promise {
+ //TODO: add conditional check for '/'
+
const response: Response = await onerepFetch(
- `/profiles/${profileId}/deactivate`,
+ `profiles/${profileId}/deactivate`,
{
method: "PUT",
},
@@ -224,7 +230,9 @@ export async function deactivateProfile(profileId: number): Promise {
}
export async function optoutProfile(profileId: number): Promise {
- const response = await onerepFetch(`/profiles/${profileId}/optout`, {
+ //TODO: add conditional check for '/'
+
+ const response = await onerepFetch(`profiles/${profileId}/optout`, {
method: "POST",
});
if (!response.ok) {
@@ -271,7 +279,9 @@ export async function createScan(
/**
* See https://docs.onerep.com/#operation/createScan
*/
- const response = await onerepFetch(`/profiles/${profileId}/scans`, {
+ //TODO: add conditional check for '/'
+
+ const response = await onerepFetch(`profiles/${profileId}/scans`, {
method: "POST",
});
if (!response.ok) {
@@ -296,8 +306,10 @@ export async function listScans(
if (options.per_page) {
queryParams.set("per_page", options.per_page.toString());
}
+ //TODO: add conditional check for '/'
+
const response: Response = await onerepFetch(
- `/profiles/${profileId}/scans?` + queryParams.toString(),
+ `profiles/${profileId}/scans?` + queryParams.toString(),
{
method: "GET",
},
@@ -338,8 +350,10 @@ export async function listScanResults(
queryParams.append("status[]", status);
});
}
+ //TODO: add conditional check for '/'
+
const response: Response = await onerepFetch(
- "/scan-results/?" + queryParams.toString(),
+ "scan-results/?" + queryParams.toString(),
{
method: "GET",
},
@@ -390,7 +404,9 @@ export async function getScanDetails(
profileId: number,
scanId: number,
): Promise {
- const response = await onerepFetch(`/profiles/${profileId}/scans/${scanId}`, {
+ //TODO: add conditional check for '/'
+
+ const response = await onerepFetch(`profiles/${profileId}/scans/${scanId}`, {
method: "GET",
});
if (!response.ok) {
@@ -413,9 +429,11 @@ export async function getAllScanResults(
}
export async function getAllDataBrokers() {
+ //TODO: add conditional check for '/'
+
return fetchAllPages(async (page: number) => {
const response = await onerepFetch(
- "/data-brokers?per_page=100&page=" + page.toString(),
+ "data-brokers?per_page=100&page=" + page.toString(),
);
const data: OneRepResponse<
Array<{
@@ -467,8 +485,10 @@ export async function getProfilesStats(
if (profileStatsCache.has(queryParamsString))
return profileStatsCache.get(queryParamsString);
+ //TODO: add conditional check for '/'
+
const response: Response = await onerepFetch(
- `/stats/profiles?${queryParamsString}`,
+ `stats/profiles?${queryParamsString}`,
{
method: "GET",
},
diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts
index dd31911fde1..26b66ef3a68 100644
--- a/src/db/tables/onerep_scans.ts
+++ b/src/db/tables/onerep_scans.ts
@@ -195,6 +195,7 @@ async function setOnerepScan(
})
.onConflict("onerep_scan_id")
.merge({
+ onerep_profile_id: onerepProfileId,
onerep_scan_status: onerepScanStatus,
updated_at: knex.fn.now(),
});
From fb2d028883feac7d6b4778bb7001b464ce01654a Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Tue, 25 Jun 2024 13:37:03 -0700
Subject: [PATCH 012/137] fixed the path overwriting issue, added responsive
dynamic configuration of mock data
---
src/app/api/mock/onerep/config/config.ts | 15 +++---
.../mock/onerep/profiles/[profileId]/route.ts | 22 ++++----
.../[profileId]/scans/[scanId]/route.ts | 6 +--
.../profiles/[profileId]/scans/route.ts | 18 +++----
src/app/api/mock/onerep/profiles/route.ts | 11 ++--
src/app/api/mock/onerep/scan-results/route.ts | 38 +++++++-------
src/app/functions/server/onerep.ts | 52 ++++++++-----------
src/db/tables/onerep_scans.ts | 8 +++
8 files changed, 84 insertions(+), 86 deletions(-)
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index 573ac048713..ed4a3cfb041 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -4,13 +4,14 @@
import { StateAbbr } from "../../../../../utils/states";
-export const MOCK_PROFILE_ID = 777;
-export const MOCK_SCAN_ID = 6972;
-export const MOCK_TIME = "2024-06-19T01:37:02+0000";
-export const MOCK_FIRSTNAME = "John";
-export const MOCK_LASTNAME = "Doe";
-export const MOCK_BIRTHDATE = "2000-01-01";
+export const MOCK_ONEREP_PROFILE_ID = 777;
+export const MOCK_ONEREP_SCAN_ID = 129837123;
+export const MOCK_ONEREP_TIME = "2024-06-19T01:37:02+0000";
+export const MOCK_ONEREP_FIRSTNAME = "John";
+export const MOCK_ONEREP_LASTNAME = "Doe";
+export const MOCK_ONEREP_BIRTHDATE = "2000-01-01";
+export const MOCK_ONEREP_EMAIL = "JohnDoe@JohnDoe.com";
-export const MOCK_ADDRESSES: [{ city: string; state: StateAbbr }] = [
+export const MOCK_ONEREP_ADDRESSES: [{ city: string; state: StateAbbr }] = [
{ city: "Berkeley", state: "CA" as StateAbbr },
];
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
index 1eefb2c3b11..aa3641f3a6a 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -3,11 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import {
- MOCK_TIME,
- MOCK_FIRSTNAME,
- MOCK_LASTNAME,
- MOCK_BIRTHDATE,
- MOCK_ADDRESSES,
+ MOCK_ONEREP_TIME,
+ MOCK_ONEREP_FIRSTNAME,
+ MOCK_ONEREP_LASTNAME,
+ MOCK_ONEREP_BIRTHDATE,
+ MOCK_ONEREP_ADDRESSES,
} from "../../config/config.ts";
import { ShowProfileResponse } from "../../../../../functions/server/onerep.ts";
import { NextRequest, NextResponse } from "next/server";
@@ -33,13 +33,13 @@ export async function GET(req: NextRequest) {
const mockProfileData: ShowProfileResponse = {
id: profileId,
- first_name: MOCK_FIRSTNAME,
- last_name: MOCK_LASTNAME,
- birth_date: MOCK_BIRTHDATE,
- addresses: MOCK_ADDRESSES,
+ first_name: MOCK_ONEREP_FIRSTNAME,
+ last_name: MOCK_ONEREP_LASTNAME,
+ birth_date: MOCK_ONEREP_BIRTHDATE,
+ addresses: MOCK_ONEREP_ADDRESSES,
status: "inactive",
- created_at: MOCK_TIME,
- updated_at: MOCK_TIME,
+ created_at: MOCK_ONEREP_TIME,
+ updated_at: MOCK_ONEREP_TIME,
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
};
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index 7119f8e075d..cd122e41556 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -4,7 +4,7 @@
// pages/api/profiles/[profileId]/scans/[scanId].ts
-import { MOCK_TIME } from "../../../../config/config";
+import { MOCK_ONEREP_TIME } from "../../../../config/config";
import { NextRequest, NextResponse } from "next/server";
export function GET(req: NextRequest) {
@@ -17,8 +17,8 @@ export function GET(req: NextRequest) {
profile_id: profileId,
status: "finished",
reason: "manual",
- created_at: MOCK_TIME,
- updated_at: MOCK_TIME,
+ created_at: MOCK_ONEREP_TIME,
+ updated_at: MOCK_ONEREP_TIME,
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
};
return NextResponse.json(responseData);
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index 17f0d44bb42..7c799c3acef 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import { MOCK_SCAN_ID, MOCK_TIME } from "../../../config/config";
+import { MOCK_ONEREP_SCAN_ID, MOCK_ONEREP_TIME } from "../../../config/config";
import { NextRequest, NextResponse } from "next/server";
//TODO: mock out the id field and url
@@ -19,13 +19,13 @@ export function POST(req: NextRequest) {
}
const mockResponse = {
- id: MOCK_SCAN_ID,
+ id: MOCK_ONEREP_SCAN_ID,
profile_id: profileId,
status: "finished",
reason: "manual",
- created_at: MOCK_TIME,
- updated_at: MOCK_TIME,
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_SCAN_ID}`,
+ created_at: MOCK_ONEREP_TIME,
+ updated_at: MOCK_ONEREP_TIME,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID}`,
};
return NextResponse.json(mockResponse);
@@ -42,13 +42,13 @@ export function GET(req: NextRequest) {
const responseData = {
data: [
{
- id: MOCK_SCAN_ID,
+ id: MOCK_ONEREP_SCAN_ID,
profile_id: profileId,
status: "finished",
reason: "manual",
- created_at: MOCK_TIME,
- updated_at: MOCK_TIME,
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_SCAN_ID}`,
+ created_at: MOCK_ONEREP_TIME,
+ updated_at: MOCK_ONEREP_TIME,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID}`,
},
],
links: {
diff --git a/src/app/api/mock/onerep/profiles/route.ts b/src/app/api/mock/onerep/profiles/route.ts
index e60b7746660..2ddc00fd31d 100644
--- a/src/app/api/mock/onerep/profiles/route.ts
+++ b/src/app/api/mock/onerep/profiles/route.ts
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import { MOCK_TIME } from "../config/config.ts";
+import { MOCK_ONEREP_TIME } from "../config/config.ts";
import {
ResponseProfileData,
RequestProfileData,
@@ -12,7 +12,6 @@ import { randomInt } from "crypto";
// Mock API endpoint
export async function POST(req: NextRequest) {
- //TODO: mock out all URLs
const profileId = randomInt(1000, 10000);
try {
if (req.body === null) {
@@ -38,13 +37,13 @@ export async function POST(req: NextRequest) {
city: addr.city,
address_line: null,
zip: null,
- created_at: MOCK_TIME,
- updated_at: MOCK_TIME,
+ created_at: MOCK_ONEREP_TIME,
+ updated_at: MOCK_ONEREP_TIME,
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/addresses/${profileId + index}`,
})),
status: "active", //assuming status is active
- created_at: MOCK_TIME,
- updated_at: MOCK_TIME,
+ created_at: MOCK_ONEREP_TIME,
+ updated_at: MOCK_ONEREP_TIME,
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
};
return NextResponse.json(responseProfile, { status: 201 });
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index 9e2e21cba32..d8c7938fcb8 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -3,50 +3,50 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import {
- MOCK_FIRSTNAME,
- MOCK_LASTNAME,
- MOCK_TIME,
- MOCK_PROFILE_ID,
- MOCK_SCAN_ID,
+ MOCK_ONEREP_FIRSTNAME,
+ MOCK_ONEREP_LASTNAME,
+ MOCK_ONEREP_TIME,
+ MOCK_ONEREP_SCAN_ID,
+ MOCK_ONEREP_EMAIL,
} from "../config/config";
import { NextRequest, NextResponse } from "next/server";
-//TODO: mock out all URLS
export function GET(req: NextRequest) {
- // const profileId = MOCK_PROFILE_ID
const page = req.url.match(/page=([0-9]+)/)![1] || "1";
const perPage = req.url.match(/per_page=([0-9]+)/)![1] || "100";
+ const profileId = req.url.match(/profile_id......=([0-9]+)&/)![1];
+
const magicNum0 = 37680;
const magicNum1 = 23;
- const howMany = 10;
+ const howMany = 5;
// TODO: mock put the indecies, id scan_id
const responseData = {
data: new Array(howMany).fill(null).map((_, index) => ({
id: magicNum0 - index,
- profile_id: MOCK_PROFILE_ID,
- scan_id: MOCK_SCAN_ID,
+ profile_id: profileId,
+ scan_id: MOCK_ONEREP_SCAN_ID,
status: "new",
- first_name: MOCK_FIRSTNAME,
+ first_name: MOCK_ONEREP_FIRSTNAME,
middle_name: null,
- last_name: MOCK_LASTNAME,
+ last_name: MOCK_ONEREP_LASTNAME,
age: null,
addresses: [],
phones: [],
- emails: [],
+ emails: [MOCK_ONEREP_EMAIL],
relatives: [],
- link: `https://example.com/link-to-databroker${index}`,
- data_broker: `example${index}.com`,
+ link: `https://mockexample.com/link-to-databroker${index}`,
+ data_broker: `mockexample${index}.com`,
data_broker_id: magicNum1 - index,
optout_attempts: 0,
- created_at: MOCK_TIME,
- updated_at: MOCK_TIME,
+ created_at: MOCK_ONEREP_TIME,
+ updated_at: MOCK_ONEREP_TIME,
url: `${process.env.ONEREP_API_BASE}scan-results/${magicNum0 - index}`,
})),
links: {
- first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${MOCK_PROFILE_ID}&per_page=100&page=1`,
- last: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${MOCK_PROFILE_ID}&per_page=100&page=1`,
+ first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
+ last: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
prev: null,
next: null,
},
diff --git a/src/app/functions/server/onerep.ts b/src/app/functions/server/onerep.ts
index db318d756db..af7fa53b86a 100644
--- a/src/app/functions/server/onerep.ts
+++ b/src/app/functions/server/onerep.ts
@@ -118,6 +118,16 @@ async function onerepFetch(
if (!onerepApiKey) {
throw new Error("ONEREP_API_KEY env var not set");
}
+
+ //If mock, remove the first slash so that it doesn't overwrite the path
+ if (
+ onerepApiBase.includes("localhost") &&
+ path.length > 1 &&
+ path[0] === "/"
+ ) {
+ path = path.substring(1);
+ }
+
const url = new URL(path, onerepApiBase);
const headers = new Headers(options.headers);
headers.set("Authorization", `Bearer ${onerepApiKey}`);
@@ -142,8 +152,7 @@ export async function createProfile(
},
],
};
- //TODO: add conditional check for '/'
- const response = await onerepFetch("profiles", {
+ const response = await onerepFetch("/profiles", {
method: "POST",
body: JSON.stringify(requestBody),
});
@@ -174,8 +183,7 @@ export async function createProfile(
export async function getProfile(
profileId: number,
): Promise {
- //TODO: add conditional check for '/'
- const response: Response = await onerepFetch(`profiles/${profileId}`, {
+ const response: Response = await onerepFetch(`/profiles/${profileId}`, {
method: "GET",
});
if (!response.ok) {
@@ -192,10 +200,8 @@ export async function getProfile(
}
export async function activateProfile(profileId: number): Promise {
- //TODO: add conditional check for '/'
-
const response: Response = await onerepFetch(
- `profiles/${profileId}/activate`,
+ `/profiles/${profileId}/activate`,
{
method: "PUT",
},
@@ -211,10 +217,8 @@ export async function activateProfile(profileId: number): Promise {
}
export async function deactivateProfile(profileId: number): Promise {
- //TODO: add conditional check for '/'
-
const response: Response = await onerepFetch(
- `profiles/${profileId}/deactivate`,
+ `/profiles/${profileId}/deactivate`,
{
method: "PUT",
},
@@ -230,9 +234,7 @@ export async function deactivateProfile(profileId: number): Promise {
}
export async function optoutProfile(profileId: number): Promise {
- //TODO: add conditional check for '/'
-
- const response = await onerepFetch(`profiles/${profileId}/optout`, {
+ const response = await onerepFetch(`/profiles/${profileId}/optout`, {
method: "POST",
});
if (!response.ok) {
@@ -279,9 +281,7 @@ export async function createScan(
/**
* See https://docs.onerep.com/#operation/createScan
*/
- //TODO: add conditional check for '/'
-
- const response = await onerepFetch(`profiles/${profileId}/scans`, {
+ const response = await onerepFetch(`/profiles/${profileId}/scans`, {
method: "POST",
});
if (!response.ok) {
@@ -306,10 +306,8 @@ export async function listScans(
if (options.per_page) {
queryParams.set("per_page", options.per_page.toString());
}
- //TODO: add conditional check for '/'
-
const response: Response = await onerepFetch(
- `profiles/${profileId}/scans?` + queryParams.toString(),
+ `/profiles/${profileId}/scans?` + queryParams.toString(),
{
method: "GET",
},
@@ -350,10 +348,8 @@ export async function listScanResults(
queryParams.append("status[]", status);
});
}
- //TODO: add conditional check for '/'
-
const response: Response = await onerepFetch(
- "scan-results/?" + queryParams.toString(),
+ "/scan-results/?" + queryParams.toString(),
{
method: "GET",
},
@@ -404,9 +400,7 @@ export async function getScanDetails(
profileId: number,
scanId: number,
): Promise {
- //TODO: add conditional check for '/'
-
- const response = await onerepFetch(`profiles/${profileId}/scans/${scanId}`, {
+ const response = await onerepFetch(`/profiles/${profileId}/scans/${scanId}`, {
method: "GET",
});
if (!response.ok) {
@@ -429,11 +423,9 @@ export async function getAllScanResults(
}
export async function getAllDataBrokers() {
- //TODO: add conditional check for '/'
-
return fetchAllPages(async (page: number) => {
const response = await onerepFetch(
- "data-brokers?per_page=100&page=" + page.toString(),
+ "/data-brokers?per_page=100&page=" + page.toString(),
);
const data: OneRepResponse<
Array<{
@@ -485,10 +477,8 @@ export async function getProfilesStats(
if (profileStatsCache.has(queryParamsString))
return profileStatsCache.get(queryParamsString);
- //TODO: add conditional check for '/'
-
const response: Response = await onerepFetch(
- `stats/profiles?${queryParamsString}`,
+ `/stats/profiles?${queryParamsString}`,
{
method: "GET",
},
diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts
index 26b66ef3a68..d385567bf82 100644
--- a/src/db/tables/onerep_scans.ts
+++ b/src/db/tables/onerep_scans.ts
@@ -4,6 +4,7 @@
import createDbConnection from "../connect.js";
import { logger } from "../../app/functions/server/logging";
+import { MOCK_ONEREP_SCAN_ID } from "../../app/api/mock/onerep/config/config.ts";
import {
ScanResult,
@@ -240,6 +241,13 @@ async function addOnerepScanResults(
});
if (scanResultsMap.length > 0) {
+ //Delete previous records to allow dynamic mock data configuration.
+ if (process.env.ONEREP_API_BASE!.includes("localhost")) {
+ await knex("onerep_scan_results")
+ .where("onerep_scan_id", MOCK_ONEREP_SCAN_ID)
+ .del();
+ }
+
await knex("onerep_scan_results")
.insert(scanResultsMap)
.onConflict("onerep_scan_result_id")
From 2a4e5045901e1c998d35cf8ab771476e550c3070 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Tue, 25 Jun 2024 23:33:33 -0700
Subject: [PATCH 013/137] moved mock user data into a separate file
---
src/app/api/mock/onerep/config/config.ts | 48 +++++++++++++-----
src/app/api/mock/onerep/config/mockUser.json | 12 +++++
src/app/api/mock/onerep/config/userObject.ts | 39 ---------------
src/app/api/mock/onerep/data-brokers/route.ts | 14 +++++-
.../mock/onerep/profiles/[profileId]/route.ts | 12 ++---
src/app/api/mock/onerep/profiles/route.ts | 49 +++++++++++++++----
6 files changed, 108 insertions(+), 66 deletions(-)
create mode 100644 src/app/api/mock/onerep/config/mockUser.json
delete mode 100644 src/app/api/mock/onerep/config/userObject.ts
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index ed4a3cfb041..e0a718efab0 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -3,15 +3,41 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StateAbbr } from "../../../../../utils/states";
+import MockUser from "./mockUser.json";
-export const MOCK_ONEREP_PROFILE_ID = 777;
-export const MOCK_ONEREP_SCAN_ID = 129837123;
-export const MOCK_ONEREP_TIME = "2024-06-19T01:37:02+0000";
-export const MOCK_ONEREP_FIRSTNAME = "John";
-export const MOCK_ONEREP_LASTNAME = "Doe";
-export const MOCK_ONEREP_BIRTHDATE = "2000-01-01";
-export const MOCK_ONEREP_EMAIL = "JohnDoe@JohnDoe.com";
-
-export const MOCK_ONEREP_ADDRESSES: [{ city: string; state: StateAbbr }] = [
- { city: "Berkeley", state: "CA" as StateAbbr },
-];
+export function MOCK_ONEREP_PROFILE_ID() {
+ return MockUser.PROFILE_ID;
+}
+
+export function MOCK_ONEREP_SCAN_ID() {
+ return MockUser.SCAN_ID;
+}
+
+export function MOCK_ONEREP_TIME() {
+ return MockUser.TIME;
+}
+
+export function MOCK_ONEREP_FIRSTNAME() {
+ return MockUser.FIRSTNAME;
+}
+
+export function MOCK_ONEREP_LASTNAME() {
+ return MockUser.LASTNAME;
+}
+
+export function MOCK_ONEREP_BIRTHDATE() {
+ return MockUser.BIRTHDATE;
+}
+
+export function MOCK_ONEREP_EMAIL() {
+ return MockUser.EMAIL;
+}
+
+export function MOCK_ONEREP_ADDRESSES() {
+ type typeOfAddr = [{ city: string; state: StateAbbr }];
+
+ return MockUser.ADDRESSES.map((address) => ({
+ city: address.city,
+ state: address.state as StateAbbr,
+ })) as typeOfAddr;
+}
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
new file mode 100644
index 00000000000..d835457579b
--- /dev/null
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -0,0 +1,12 @@
+{
+ "PROFILE_ID": 777,
+ "SCAN_ID": 129837123,
+ "TIME": "2024-06-19T01:37:02+0000",
+ "FIRSTNAME": "John",
+ "LASTNAME": "Doe",
+ "BIRTHDATE": "2000-01-01",
+ "EMAIL": "JohnDoe@JohnDoe.com",
+ "ADDRESSES": [
+ { "city": "Berkeley", "state": "CA" }
+ ]
+}
diff --git a/src/app/api/mock/onerep/config/userObject.ts b/src/app/api/mock/onerep/config/userObject.ts
deleted file mode 100644
index 58f284c32ea..00000000000
--- a/src/app/api/mock/onerep/config/userObject.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-export type RequestProfileData = {
- first_name: string;
- last_name: string;
- middle_name: string;
- birth_date: string;
- addresses: Array<{ state: string; city: string }>;
-};
-
-export type ResponseProfileData = {
- id: number;
- first_name: string;
- last_name: string;
- middle_name: string | null;
- birth_date: string;
- first_names: string[];
- middle_names: string[];
- last_names: string[];
- phone_numbers: string[];
- emails: string[];
- addresses: Array<{
- id: number;
- profile_id: number;
- state: string;
- city: string;
- address_line: string | null;
- zip: string | null;
- created_at: string;
- updated_at: string;
- url: string;
- }>;
- status: "active" | "inactive";
- created_at: string;
- updated_at: string;
- url: string;
-};
diff --git a/src/app/api/mock/onerep/data-brokers/route.ts b/src/app/api/mock/onerep/data-brokers/route.ts
index a047a740545..7adced07d32 100644
--- a/src/app/api/mock/onerep/data-brokers/route.ts
+++ b/src/app/api/mock/onerep/data-brokers/route.ts
@@ -5,6 +5,18 @@
import { NextResponse } from "next/server";
//ONLY PART OF ADMIN - probably shouldn't mock?
-export default function handler() {
+export function GET() {
+ return NextResponse.json({ error: "You've reached a mock endpoint" });
+}
+
+export function POST() {
+ return NextResponse.json({ error: "You've reached a mock endpoint" });
+}
+
+export function PUT() {
+ return NextResponse.json({ error: "You've reached a mock endpoint" });
+}
+
+export function DELETE() {
return NextResponse.json({ error: "You've reached a mock endpoint" });
}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
index aa3641f3a6a..48a501142b1 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -33,13 +33,13 @@ export async function GET(req: NextRequest) {
const mockProfileData: ShowProfileResponse = {
id: profileId,
- first_name: MOCK_ONEREP_FIRSTNAME,
- last_name: MOCK_ONEREP_LASTNAME,
- birth_date: MOCK_ONEREP_BIRTHDATE,
- addresses: MOCK_ONEREP_ADDRESSES,
+ first_name: MOCK_ONEREP_FIRSTNAME(),
+ last_name: MOCK_ONEREP_LASTNAME(),
+ birth_date: MOCK_ONEREP_BIRTHDATE(),
+ addresses: MOCK_ONEREP_ADDRESSES(),
status: "inactive",
- created_at: MOCK_ONEREP_TIME,
- updated_at: MOCK_ONEREP_TIME,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
};
diff --git a/src/app/api/mock/onerep/profiles/route.ts b/src/app/api/mock/onerep/profiles/route.ts
index 2ddc00fd31d..02d61906c56 100644
--- a/src/app/api/mock/onerep/profiles/route.ts
+++ b/src/app/api/mock/onerep/profiles/route.ts
@@ -3,14 +3,45 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { MOCK_ONEREP_TIME } from "../config/config.ts";
-import {
- ResponseProfileData,
- RequestProfileData,
-} from "../config/userObject.ts";
import { NextRequest, NextResponse } from "next/server";
import { randomInt } from "crypto";
-// Mock API endpoint
+export type RequestProfileData = {
+ first_name: string;
+ last_name: string;
+ middle_name: string;
+ birth_date: string;
+ addresses: Array<{ state: string; city: string }>;
+};
+
+type ResponseProfileData = {
+ id: number;
+ first_name: string;
+ last_name: string;
+ middle_name: string | null;
+ birth_date: string;
+ first_names: string[];
+ middle_names: string[];
+ last_names: string[];
+ phone_numbers: string[];
+ emails: string[];
+ addresses: Array<{
+ id: number;
+ profile_id: number;
+ state: string;
+ city: string;
+ address_line: string | null;
+ zip: string | null;
+ created_at: string;
+ updated_at: string;
+ url: string;
+ }>;
+ status: "active" | "inactive";
+ created_at: string;
+ updated_at: string;
+ url: string;
+};
+
export async function POST(req: NextRequest) {
const profileId = randomInt(1000, 10000);
try {
@@ -37,13 +68,13 @@ export async function POST(req: NextRequest) {
city: addr.city,
address_line: null,
zip: null,
- created_at: MOCK_ONEREP_TIME,
- updated_at: MOCK_ONEREP_TIME,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/addresses/${profileId + index}`,
})),
status: "active", //assuming status is active
- created_at: MOCK_ONEREP_TIME,
- updated_at: MOCK_ONEREP_TIME,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
};
return NextResponse.json(responseProfile, { status: 201 });
From 0b1d9e5971dc523b6ff7c63c59ea69b59c5c4bae Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Tue, 25 Jun 2024 23:48:23 -0700
Subject: [PATCH 014/137] fixed some code quality and substitued constants with
function calls
---
src/app/api/mock/onerep/config/config.ts | 4 ++++
src/app/api/mock/onerep/config/mockUser.json | 5 ++---
.../mock/onerep/profiles/[profileId]/route.ts | 3 ++-
.../profiles/[profileId]/scans/[scanId]/route.ts | 4 ++--
.../onerep/profiles/[profileId]/scans/route.ts | 16 ++++++++--------
src/app/api/mock/onerep/profiles/route.ts | 4 ++--
src/app/api/mock/onerep/scan-results/route.ts | 14 +++++++-------
src/db/tables/onerep_scans.ts | 2 +-
8 files changed, 28 insertions(+), 24 deletions(-)
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index e0a718efab0..987bb110534 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -33,6 +33,10 @@ export function MOCK_ONEREP_EMAIL() {
return MockUser.EMAIL;
}
+export function MOCK_ONEREP_STATUS() {
+ return MockUser.STATUS as "active" | "inactive";
+}
+
export function MOCK_ONEREP_ADDRESSES() {
type typeOfAddr = [{ city: string; state: StateAbbr }];
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index d835457579b..d7705432b5d 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -6,7 +6,6 @@
"LASTNAME": "Doe",
"BIRTHDATE": "2000-01-01",
"EMAIL": "JohnDoe@JohnDoe.com",
- "ADDRESSES": [
- { "city": "Berkeley", "state": "CA" }
- ]
+ "STATUS": "active",
+ "ADDRESSES": [{ "city": "Berkeley", "state": "CA" }]
}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
index 48a501142b1..ea28493e2ba 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -8,6 +8,7 @@ import {
MOCK_ONEREP_LASTNAME,
MOCK_ONEREP_BIRTHDATE,
MOCK_ONEREP_ADDRESSES,
+ MOCK_ONEREP_STATUS,
} from "../../config/config.ts";
import { ShowProfileResponse } from "../../../../../functions/server/onerep.ts";
import { NextRequest, NextResponse } from "next/server";
@@ -37,7 +38,7 @@ export async function GET(req: NextRequest) {
last_name: MOCK_ONEREP_LASTNAME(),
birth_date: MOCK_ONEREP_BIRTHDATE(),
addresses: MOCK_ONEREP_ADDRESSES(),
- status: "inactive",
+ status: MOCK_ONEREP_STATUS(),
created_at: MOCK_ONEREP_TIME(),
updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index cd122e41556..14d56c3b2ae 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -17,8 +17,8 @@ export function GET(req: NextRequest) {
profile_id: profileId,
status: "finished",
reason: "manual",
- created_at: MOCK_ONEREP_TIME,
- updated_at: MOCK_ONEREP_TIME,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
};
return NextResponse.json(responseData);
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index 7c799c3acef..c5c2a934b39 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -19,13 +19,13 @@ export function POST(req: NextRequest) {
}
const mockResponse = {
- id: MOCK_ONEREP_SCAN_ID,
+ id: MOCK_ONEREP_SCAN_ID(),
profile_id: profileId,
status: "finished",
reason: "manual",
- created_at: MOCK_ONEREP_TIME,
- updated_at: MOCK_ONEREP_TIME,
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID}`,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID()}`,
};
return NextResponse.json(mockResponse);
@@ -42,13 +42,13 @@ export function GET(req: NextRequest) {
const responseData = {
data: [
{
- id: MOCK_ONEREP_SCAN_ID,
+ id: MOCK_ONEREP_SCAN_ID(),
profile_id: profileId,
status: "finished",
reason: "manual",
- created_at: MOCK_ONEREP_TIME,
- updated_at: MOCK_ONEREP_TIME,
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID}`,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID()}`,
},
],
links: {
diff --git a/src/app/api/mock/onerep/profiles/route.ts b/src/app/api/mock/onerep/profiles/route.ts
index 02d61906c56..a5180d11320 100644
--- a/src/app/api/mock/onerep/profiles/route.ts
+++ b/src/app/api/mock/onerep/profiles/route.ts
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import { MOCK_ONEREP_TIME } from "../config/config.ts";
+import { MOCK_ONEREP_STATUS, MOCK_ONEREP_TIME } from "../config/config.ts";
import { NextRequest, NextResponse } from "next/server";
import { randomInt } from "crypto";
@@ -72,7 +72,7 @@ export async function POST(req: NextRequest) {
updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/addresses/${profileId + index}`,
})),
- status: "active", //assuming status is active
+ status: MOCK_ONEREP_STATUS(),
created_at: MOCK_ONEREP_TIME(),
updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index d8c7938fcb8..9655b1f32e3 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -19,29 +19,29 @@ export function GET(req: NextRequest) {
const magicNum0 = 37680;
const magicNum1 = 23;
- const howMany = 5;
+ const howMany = 10;
// TODO: mock put the indecies, id scan_id
const responseData = {
data: new Array(howMany).fill(null).map((_, index) => ({
id: magicNum0 - index,
profile_id: profileId,
- scan_id: MOCK_ONEREP_SCAN_ID,
+ scan_id: MOCK_ONEREP_SCAN_ID(),
status: "new",
- first_name: MOCK_ONEREP_FIRSTNAME,
+ first_name: MOCK_ONEREP_FIRSTNAME(),
middle_name: null,
- last_name: MOCK_ONEREP_LASTNAME,
+ last_name: MOCK_ONEREP_LASTNAME(),
age: null,
addresses: [],
phones: [],
- emails: [MOCK_ONEREP_EMAIL],
+ emails: [MOCK_ONEREP_EMAIL()],
relatives: [],
link: `https://mockexample.com/link-to-databroker${index}`,
data_broker: `mockexample${index}.com`,
data_broker_id: magicNum1 - index,
optout_attempts: 0,
- created_at: MOCK_ONEREP_TIME,
- updated_at: MOCK_ONEREP_TIME,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}scan-results/${magicNum0 - index}`,
})),
links: {
diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts
index d385567bf82..0e61241f126 100644
--- a/src/db/tables/onerep_scans.ts
+++ b/src/db/tables/onerep_scans.ts
@@ -244,7 +244,7 @@ async function addOnerepScanResults(
//Delete previous records to allow dynamic mock data configuration.
if (process.env.ONEREP_API_BASE!.includes("localhost")) {
await knex("onerep_scan_results")
- .where("onerep_scan_id", MOCK_ONEREP_SCAN_ID)
+ .where("onerep_scan_id", MOCK_ONEREP_SCAN_ID())
.del();
}
From 29b6f0e5830f8937a8e7186db5c5a2966dff13e4 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Wed, 26 Jun 2024 02:48:09 -0700
Subject: [PATCH 015/137] Allowed for data to be configured dynamically using
an endpoint
---
src/app/api/mock/onerep/config/config.ts | 103 ++++++++++++++++++
src/app/api/mock/onerep/config/mockUser.json | 15 ++-
src/app/api/mock/onerep/config/route.ts | 71 ++++++++++++
src/app/api/mock/onerep/config/test.json | 25 +++++
src/app/api/mock/onerep/scan-results/route.ts | 54 +--------
5 files changed, 214 insertions(+), 54 deletions(-)
create mode 100644 src/app/api/mock/onerep/config/route.ts
create mode 100644 src/app/api/mock/onerep/config/test.json
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index 987bb110534..eae5296af05 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -5,6 +5,28 @@
import { StateAbbr } from "../../../../../utils/states";
import MockUser from "./mockUser.json";
+interface Broker {
+ id: number;
+ profile_id: string;
+ scan_id: number;
+ status: string;
+ first_name: string;
+ middle_name?: string | null;
+ last_name: string;
+ age?: number | null;
+ addresses: object[];
+ phones: object[];
+ emails: object[];
+ relatives: object[];
+ link: string;
+ data_broker: string;
+ data_broker_id: number;
+ optout_attempts: number;
+ created_at: string;
+ updated_at: string;
+ url: string;
+}
+
export function MOCK_ONEREP_PROFILE_ID() {
return MockUser.PROFILE_ID;
}
@@ -45,3 +67,84 @@ export function MOCK_ONEREP_ADDRESSES() {
state: address.state as StateAbbr,
})) as typeOfAddr;
}
+
+const DEFAULT_NUMBER_BREACHES = 10;
+const magicNum0 = 37680;
+const magicNum1 = 23;
+
+export function MOCK_ONEREP_BROKERS(
+ profileId: string,
+ page: string,
+ perPage: string,
+) {
+ const mockResponseData = MockUser.BROKERS_LIST;
+
+ const mockLinks = {
+ first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
+ last: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
+ prev: null,
+ next: null,
+ };
+
+ const mockMeta = {
+ current_page: parseInt(page),
+ from: 1,
+ last_page: 1,
+ path: `${process.env.ONEREP_API_BASE}/scan-results`,
+ per_page: parseInt(perPage),
+ to: 10,
+ total: 10,
+ };
+
+ if (mockResponseData.valid) {
+ const response: {
+ data: Broker[];
+ links: typeof mockLinks;
+ meta: typeof mockMeta;
+ } = {
+ data: [],
+ links: mockLinks,
+ meta: mockMeta,
+ };
+
+ if (mockResponseData.data.length > 0) {
+ response.data = mockResponseData.data.map((broker) => {
+ return {
+ ...(broker as Broker),
+ profile_id: profileId,
+ scan_id: MOCK_ONEREP_SCAN_ID(),
+ };
+ });
+ }
+
+ return mockResponseData;
+ }
+
+ const responseData = {
+ data: new Array(DEFAULT_NUMBER_BREACHES).fill(null).map((_, index) => ({
+ id: magicNum0 - index,
+ profile_id: profileId,
+ scan_id: MOCK_ONEREP_SCAN_ID(),
+ status: "new",
+ first_name: MOCK_ONEREP_FIRSTNAME(),
+ middle_name: null,
+ last_name: MOCK_ONEREP_LASTNAME(),
+ age: null,
+ addresses: [],
+ phones: [],
+ emails: [MOCK_ONEREP_EMAIL()],
+ relatives: [],
+ link: `https://mockexample.com/link-to-databroker${index}`,
+ data_broker: `mockexample${index}.com`,
+ data_broker_id: magicNum1 - index,
+ optout_attempts: 0,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
+ url: `${process.env.ONEREP_API_BASE}scan-results/${magicNum0 - index}`,
+ })),
+ links: mockLinks,
+ meta: mockMeta,
+ };
+
+ return responseData;
+}
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index d7705432b5d..6aba83b3656 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -7,5 +7,16 @@
"BIRTHDATE": "2000-01-01",
"EMAIL": "JohnDoe@JohnDoe.com",
"STATUS": "active",
- "ADDRESSES": [{ "city": "Berkeley", "state": "CA" }]
-}
+ "ADDRESSES": [
+ {
+ "city": "Berkeley",
+ "state": "CA"
+ }
+ ],
+ "BROKERS_LIST": {
+ "data": [],
+ "links": {},
+ "meta": {},
+ "valid": false
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/mock/onerep/config/route.ts b/src/app/api/mock/onerep/config/route.ts
new file mode 100644
index 00000000000..7d933d4725c
--- /dev/null
+++ b/src/app/api/mock/onerep/config/route.ts
@@ -0,0 +1,71 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { NextRequest, NextResponse } from "next/server";
+import fs from "fs";
+import path from "path";
+
+/*
+
+Example fetch, where obj conforms to Broker interface in config.ts
+
+fetch('/api/mock/onerep/config', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ brokers: obj,
+ erase: true
+ })
+})
+.then(response => response.json()).then(data => console.log(data))
+
+
+*/
+
+export async function POST(req: NextRequest) {
+ // Define the path to the JSON file
+ const jsonFilePath = path.join(
+ process.cwd(),
+ "./src/app/api/mock/onerep/config/mockUser.json",
+ );
+
+ // Read the current JSON from the file
+ const fileData = fs.readFileSync(jsonFilePath, "utf8");
+ const jsonData = JSON.parse(fileData);
+
+ try {
+ const newData = await req.json();
+ const erase = newData.erase;
+
+ if (erase) {
+ jsonData.BROKERS_LIST.data = [];
+ jsonData.BROKERS_LIST.valid = false;
+ } else {
+ if (!newData.brokers || !newData.brokers.data) {
+ return NextResponse.json(
+ { error: "Bad Request: Data format is unexpected!" },
+ { status: 400 },
+ );
+ }
+
+ jsonData.BROKERS_LIST.data = newData.brokers.data;
+ jsonData.BROKERS_LIST.valid = true;
+ }
+
+ fs.writeFileSync(jsonFilePath, JSON.stringify(jsonData, null, 2), "utf8");
+
+ return NextResponse.json(
+ { message: "JSON data has been successfully updated." },
+ { status: 200 },
+ );
+ } catch (error) {
+ console.error("Mock endpoint OneRep: Failed to update JSON:", error);
+ return NextResponse.json(
+ { message: "Failed to update JSON data." },
+ { status: 500 },
+ );
+ }
+}
diff --git a/src/app/api/mock/onerep/config/test.json b/src/app/api/mock/onerep/config/test.json
new file mode 100644
index 00000000000..c9306b2f191
--- /dev/null
+++ b/src/app/api/mock/onerep/config/test.json
@@ -0,0 +1,25 @@
+{
+ "data": [
+ {
+ "id": 45000,
+ "profile_id": 0,
+ "scan_id": 0,
+ "status": "new",
+ "first_name": "John",
+ "middle_name": null,
+ "last_name": "Doe",
+ "age": null,
+ "addresses": [],
+ "phones": [],
+ "emails": [],
+ "relatives": [],
+ "link": "https://test.com/link-to-databroker0",
+ "data_broker": "test0.com",
+ "data_broker_id": 23,
+ "optout_attempts": 0,
+ "created_at": "2024-06-19T01:37:02+0000",
+ "updated_at": "2024-06-19T01:37:02+0000",
+ "url": "http://localhost:6060/api/mock/onerep/scan-results/45000"
+ }
+ ]
+}
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index 9655b1f32e3..3f2c76310ed 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -2,13 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import {
- MOCK_ONEREP_FIRSTNAME,
- MOCK_ONEREP_LASTNAME,
- MOCK_ONEREP_TIME,
- MOCK_ONEREP_SCAN_ID,
- MOCK_ONEREP_EMAIL,
-} from "../config/config";
+import { MOCK_ONEREP_BROKERS } from "../config/config";
import { NextRequest, NextResponse } from "next/server";
export function GET(req: NextRequest) {
@@ -17,49 +11,5 @@ export function GET(req: NextRequest) {
const profileId = req.url.match(/profile_id......=([0-9]+)&/)![1];
- const magicNum0 = 37680;
- const magicNum1 = 23;
- const howMany = 10;
-
- // TODO: mock put the indecies, id scan_id
- const responseData = {
- data: new Array(howMany).fill(null).map((_, index) => ({
- id: magicNum0 - index,
- profile_id: profileId,
- scan_id: MOCK_ONEREP_SCAN_ID(),
- status: "new",
- first_name: MOCK_ONEREP_FIRSTNAME(),
- middle_name: null,
- last_name: MOCK_ONEREP_LASTNAME(),
- age: null,
- addresses: [],
- phones: [],
- emails: [MOCK_ONEREP_EMAIL()],
- relatives: [],
- link: `https://mockexample.com/link-to-databroker${index}`,
- data_broker: `mockexample${index}.com`,
- data_broker_id: magicNum1 - index,
- optout_attempts: 0,
- created_at: MOCK_ONEREP_TIME(),
- updated_at: MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}scan-results/${magicNum0 - index}`,
- })),
- links: {
- first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
- last: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
- prev: null,
- next: null,
- },
- meta: {
- current_page: parseInt(page),
- from: 1,
- last_page: 1,
- path: `${process.env.ONEREP_API_BASE}/scan-results`,
- per_page: parseInt(perPage),
- to: 10,
- total: 10,
- },
- };
-
- return NextResponse.json(responseData);
+ return NextResponse.json(MOCK_ONEREP_BROKERS(profileId, page, perPage));
}
From 8ec080df8ca94e60d1cdfed8b7a0da8767df7bb5 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Wed, 26 Jun 2024 02:50:23 -0700
Subject: [PATCH 016/137] lint fail fixed
---
src/app/api/mock/onerep/config/mockUser.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index 6aba83b3656..cbd4dec28e0 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -19,4 +19,4 @@
"meta": {},
"valid": false
}
-}
\ No newline at end of file
+}
From f3e9b37b2daffa4bf72d84846a25718a991dc60c Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Wed, 26 Jun 2024 16:52:29 -0700
Subject: [PATCH 017/137] most tests pass when using mock onerep endpoint
---
src/app/functions/server/getRelevantGuidedSteps.ts | 1 +
src/e2e/pages/purchasePage.ts | 2 +-
src/e2e/utils/helpers.ts | 4 +++-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/app/functions/server/getRelevantGuidedSteps.ts b/src/app/functions/server/getRelevantGuidedSteps.ts
index fb43517a2fa..93ed0ae3f2b 100644
--- a/src/app/functions/server/getRelevantGuidedSteps.ts
+++ b/src/app/functions/server/getRelevantGuidedSteps.ts
@@ -70,6 +70,7 @@ export type StepLinkWithStatus = (typeof stepLinks)[number] & {
};
export function isGuidedResolutionInProgress(stepId: StepLink["id"]) {
+ if (stepId === "Scan" || stepId === "Done") return false; //this fixes a lint check
const inProgressStepIds = stepLinks
.filter((step) => step.id !== "Scan" && step.id !== "Done")
.map(({ id }) => id);
diff --git a/src/e2e/pages/purchasePage.ts b/src/e2e/pages/purchasePage.ts
index e1ead13b02e..4b0c52de122 100644
--- a/src/e2e/pages/purchasePage.ts
+++ b/src/e2e/pages/purchasePage.ts
@@ -121,7 +121,7 @@ export class PurchasePage {
(await this.planDetails.textContent()) as string,
);
expect(planDetails).toContain(
- `${process.env.E2E_TEST_ENV === "prod" ? "yearly" : "every 2 months"}`,
+ `${process.env.E2E_TEST_ENV!.match(/prod|local/) ? "yearly" : "every 2 months"}`,
);
}
diff --git a/src/e2e/utils/helpers.ts b/src/e2e/utils/helpers.ts
index 0d398436dd0..6257d254367 100644
--- a/src/e2e/utils/helpers.ts
+++ b/src/e2e/utils/helpers.ts
@@ -170,7 +170,9 @@ export const clickOnATagCheckDomain = async (
page: Page,
) => {
if (typeof host === "string")
- host = new RegExp(escapeRegExp(host.replace(/^(https?:\/\/)/, "")));
+ host = new RegExp(
+ escapeRegExp(host.replace(/^(https?:\/\/)/, "").replace(/:\d+$/, "")),
+ );
if (typeof path === "string") path = new RegExp(".*" + path + ".*");
const href = await aTag.getAttribute("href");
From 71e5ddf1f29be53761541c0796318daf532f9843 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Fri, 28 Jun 2024 15:57:14 -0700
Subject: [PATCH 018/137] passes all tests except for those in purchase spec
---
.../api/mock/hibp/data/fakeAllBreaches.json | 32 +++++++++++++++-
src/app/api/mock/hibp/data/fakeBreaches.json | 2 +-
.../search}/[hashPrefix]/route.ts | 6 ++-
src/app/api/mock/onerep/config/config.ts | 38 ++++++++++++++-----
src/app/api/mock/onerep/config/mockUser.json | 4 +-
src/app/api/mock/onerep/config/route.ts | 2 +
src/app/api/mock/onerep/config/test.json | 4 +-
.../profiles/[profileId]/optout/route.ts | 2 +-
.../[profileId]/scans/[scanId]/route.ts | 1 -
.../profiles/[profileId]/scans/route.ts | 25 ++++++++----
src/db/tables/onerep_scans.ts | 37 ++++++++++++++----
src/e2e/specs/auth.spec.ts | 5 +--
src/e2e/specs/dashboard.spec.ts | 21 +++++-----
src/e2e/specs/landing.spec.ts | 20 ++--------
14 files changed, 135 insertions(+), 64 deletions(-)
rename src/app/api/mock/hibp/{breachedaccount/range => range/search}/[hashPrefix]/route.ts (90%)
diff --git a/src/app/api/mock/hibp/data/fakeAllBreaches.json b/src/app/api/mock/hibp/data/fakeAllBreaches.json
index 42524b86c5a..44aa91f5f2c 100644
--- a/src/app/api/mock/hibp/data/fakeAllBreaches.json
+++ b/src/app/api/mock/hibp/data/fakeAllBreaches.json
@@ -47,6 +47,36 @@
"IsSpamList": false,
"IsMalware": false,
"FaviconUrl": null
- }
+ },
+ {
+ "Id": 95,
+ "Name": "Bonobos",
+ "Title": "Bonobos",
+ "Domain": "bonobos.com",
+ "BreachDate": "2020-08-14T07:00:00.000Z",
+ "AddedDate": "2021-01-31T00:09:25.000Z",
+ "ModifiedDate": "2021-01-31T00:12:58.000Z",
+ "PwnCount": 2811929,
+ "Description": "In August 2020, the clothing store Bonobos suffered a data breach that exposed almost 70GB of data containing 2.8 million unique email addresses. The breach also exposed names, physical and IP addresses, phone numbers, order histories and passwords stored as salted SHA-512 hashes, including historical passwords. The breach also exposed partial credit card data including card type, the name on the card, expiry date and the last 4 digits of the card. The data was provided to HIBP by dehashed.com.",
+ "LogoPath": "https://haveibeenpwned.com/Content/Images/PwnedLogos/Bonobos.png",
+ "DataClasses": [
+ "email-addresses",
+ "historical-passwords",
+ "ip-addresses",
+ "names",
+ "partial-credit-card-data",
+ "passwords",
+ "phone-numbers",
+ "physical-addresses",
+ "purchases"
+ ],
+ "IsVerified": true,
+ "IsFabricated": false,
+ "IsSensitive": false,
+ "IsRetired": false,
+ "IsSpamList": false,
+ "IsMalware": false,
+ "FaviconUrl": null
+ }
]
}
diff --git a/src/app/api/mock/hibp/data/fakeBreaches.json b/src/app/api/mock/hibp/data/fakeBreaches.json
index 70dbadb067c..65d091e067a 100644
--- a/src/app/api/mock/hibp/data/fakeBreaches.json
+++ b/src/app/api/mock/hibp/data/fakeBreaches.json
@@ -2,7 +2,7 @@
"data": [
{
"hashSuffix": "",
- "websites": ["000webhost", "123RF"]
+ "websites": ["000webhost", "123RF", "Bonobos"]
}
]
}
diff --git a/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts b/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
similarity index 90%
rename from src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
rename to src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
index 190fb74c664..e386a13ed4a 100644
--- a/src/app/api/mock/hibp/breachedaccount/range/[hashPrefix]/route.ts
+++ b/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
@@ -28,7 +28,7 @@ export function GET() {
const userEmail = process.env.E2E_TEST_ACCOUNT_EMAIL;
//TODO: getServerSession doesn't work here for some reason
const currentUserSha = getSha1(userEmail as BinaryLike);
- logger.info("Mock endpoint: /breachedaccount/range/");
+ logger.info("Mock endpoint: /range/search/");
let data = fakeBreaches.data as BreachedAccountResponse;
@@ -36,5 +36,7 @@ export function GET() {
...elem,
hashSuffix: currentUserSha.slice(6).toUpperCase(),
}));
- return NextResponse.json(data);
+ const res = NextResponse.json(data);
+ console.log("opa1", data);
+ return res;
}
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index eae5296af05..228cfb54329 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -2,8 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+// import { randomInt } from "crypto";
import { StateAbbr } from "../../../../../utils/states";
import MockUser from "./mockUser.json";
+// import { getLatestOnerepScanResults } from "../../../../../db/tables/onerep_scans";
interface Broker {
id: number;
@@ -31,8 +33,8 @@ export function MOCK_ONEREP_PROFILE_ID() {
return MockUser.PROFILE_ID;
}
-export function MOCK_ONEREP_SCAN_ID() {
- return MockUser.SCAN_ID;
+export function MOCK_ONEREP_MAGIC_NUM_0() {
+ return MockUser.MAGIC_NUM_0;
}
export function MOCK_ONEREP_TIME() {
@@ -68,9 +70,22 @@ export function MOCK_ONEREP_ADDRESSES() {
})) as typeOfAddr;
}
-const DEFAULT_NUMBER_BREACHES = 10;
-const magicNum0 = 37680;
-const magicNum1 = 23;
+const DEFAULT_NUMBER_BREACHES = 5;
+const MAGIC_NUM_brokerId = 78127;
+const MAGIC_NUM_1 = 24623;
+const MAGIC_NUM_2 = 2161;
+
+export function MOCK_ONEREP_MAGIC_NUM_1() {
+ return MAGIC_NUM_1;
+}
+
+export function MOCK_ONEREP_MAGIC_NUM_2() {
+ return MAGIC_NUM_2;
+}
+
+function getScanId(profileId: string) {
+ return (Number(profileId) * MAGIC_NUM_1) % MAGIC_NUM_2;
+}
export function MOCK_ONEREP_BROKERS(
profileId: string,
@@ -78,6 +93,7 @@ export function MOCK_ONEREP_BROKERS(
perPage: string,
) {
const mockResponseData = MockUser.BROKERS_LIST;
+ const latestScanId = getScanId(profileId);
const mockLinks = {
first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
@@ -112,7 +128,7 @@ export function MOCK_ONEREP_BROKERS(
return {
...(broker as Broker),
profile_id: profileId,
- scan_id: MOCK_ONEREP_SCAN_ID(),
+ scan_id: latestScanId,
};
});
}
@@ -120,11 +136,13 @@ export function MOCK_ONEREP_BROKERS(
return mockResponseData;
}
+ const idStart = latestScanId * MOCK_ONEREP_MAGIC_NUM_0();
+
const responseData = {
data: new Array(DEFAULT_NUMBER_BREACHES).fill(null).map((_, index) => ({
- id: magicNum0 - index,
+ id: idStart - index,
profile_id: profileId,
- scan_id: MOCK_ONEREP_SCAN_ID(),
+ scan_id: latestScanId,
status: "new",
first_name: MOCK_ONEREP_FIRSTNAME(),
middle_name: null,
@@ -136,11 +154,11 @@ export function MOCK_ONEREP_BROKERS(
relatives: [],
link: `https://mockexample.com/link-to-databroker${index}`,
data_broker: `mockexample${index}.com`,
- data_broker_id: magicNum1 - index,
+ data_broker_id: MAGIC_NUM_brokerId - index,
optout_attempts: 0,
created_at: MOCK_ONEREP_TIME(),
updated_at: MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}scan-results/${magicNum0 - index}`,
+ url: `${process.env.ONEREP_API_BASE}scan-results/${idStart - index}`,
})),
links: mockLinks,
meta: mockMeta,
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index cbd4dec28e0..ece3a3a67eb 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -1,6 +1,6 @@
{
"PROFILE_ID": 777,
- "SCAN_ID": 129837123,
+ "MAGIC_NUM_0": 2914,
"TIME": "2024-06-19T01:37:02+0000",
"FIRSTNAME": "John",
"LASTNAME": "Doe",
@@ -19,4 +19,4 @@
"meta": {},
"valid": false
}
-}
+}
\ No newline at end of file
diff --git a/src/app/api/mock/onerep/config/route.ts b/src/app/api/mock/onerep/config/route.ts
index 7d933d4725c..969ed75a812 100644
--- a/src/app/api/mock/onerep/config/route.ts
+++ b/src/app/api/mock/onerep/config/route.ts
@@ -5,6 +5,7 @@
import { NextRequest, NextResponse } from "next/server";
import fs from "fs";
import path from "path";
+import { randomInt } from "crypto";
/*
@@ -43,6 +44,7 @@ export async function POST(req: NextRequest) {
if (erase) {
jsonData.BROKERS_LIST.data = [];
jsonData.BROKERS_LIST.valid = false;
+ jsonData.MAGIC_NUM_0 = randomInt(1000, 100000);
} else {
if (!newData.brokers || !newData.brokers.data) {
return NextResponse.json(
diff --git a/src/app/api/mock/onerep/config/test.json b/src/app/api/mock/onerep/config/test.json
index c9306b2f191..c8d3af447e7 100644
--- a/src/app/api/mock/onerep/config/test.json
+++ b/src/app/api/mock/onerep/config/test.json
@@ -2,8 +2,8 @@
"data": [
{
"id": 45000,
- "profile_id": 0,
- "scan_id": 0,
+ "profile_id": -1,
+ "scan_id": -1,
"status": "new",
"first_name": "John",
"middle_name": null,
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
index 8a3bed0ecb6..611cf44c0bc 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
@@ -4,7 +4,7 @@
import { NextRequest, NextResponse } from "next/server";
-export function PUT(req: NextRequest) {
+export function POST(req: NextRequest) {
const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
if (!profileId || isNaN(profileId)) {
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index 14d56c3b2ae..228088ec1b0 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -11,7 +11,6 @@ export function GET(req: NextRequest) {
const profileId = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
const scanId = Number(req.url.match(/scans\/([0-9]+)/)![1]);
- // Check for the availability of the scan
const responseData = {
id: scanId,
profile_id: profileId,
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index c5c2a934b39..d085e0fc107 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -2,30 +2,38 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import { MOCK_ONEREP_SCAN_ID, MOCK_ONEREP_TIME } from "../../../config/config";
import { NextRequest, NextResponse } from "next/server";
-
-//TODO: mock out the id field and url
+import {
+ MOCK_ONEREP_TIME,
+ MOCK_ONEREP_MAGIC_NUM_1,
+ MOCK_ONEREP_MAGIC_NUM_2,
+} from "../../../config/config";
function extractProfileId(req: NextRequest) {
const idFromUrl = Number(req.url.match(/profiles\/([0-9]+)\/scans/)![1]);
return idFromUrl;
}
+function getScanId(profileId: number) {
+ return (profileId * MOCK_ONEREP_MAGIC_NUM_1()) % MOCK_ONEREP_MAGIC_NUM_2();
+}
+
export function POST(req: NextRequest) {
const profileId: number = extractProfileId(req);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
}
+ const scanId = getScanId(profileId);
+
const mockResponse = {
- id: MOCK_ONEREP_SCAN_ID(),
+ id: scanId,
profile_id: profileId,
status: "finished",
reason: "manual",
created_at: MOCK_ONEREP_TIME(),
updated_at: MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID()}`,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
};
return NextResponse.json(mockResponse);
@@ -38,17 +46,18 @@ export function GET(req: NextRequest) {
return NextResponse.json({ error: "Invalid profile ID" });
}
- //TODO: mock out ID here and urls
+ const scandId = getScanId(profileId);
+
const responseData = {
data: [
{
- id: MOCK_ONEREP_SCAN_ID(),
+ id: scandId,
profile_id: profileId,
status: "finished",
reason: "manual",
created_at: MOCK_ONEREP_TIME(),
updated_at: MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${MOCK_ONEREP_SCAN_ID()}`,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scandId}`,
},
],
links: {
diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts
index 0e61241f126..deee6736e78 100644
--- a/src/db/tables/onerep_scans.ts
+++ b/src/db/tables/onerep_scans.ts
@@ -4,7 +4,6 @@
import createDbConnection from "../connect.js";
import { logger } from "../../app/functions/server/logging";
-import { MOCK_ONEREP_SCAN_ID } from "../../app/api/mock/onerep/config/config.ts";
import {
ScanResult,
@@ -206,7 +205,7 @@ async function addOnerepScanResults(
onerepProfileId: number,
onerepScanResults: Array,
) {
- const scanResultsMap = onerepScanResults.map((scanResult) => ({
+ let scanResultsMap = onerepScanResults.map((scanResult) => ({
onerep_scan_result_id: scanResult.id,
onerep_scan_id: scanResult.scan_id,
link: scanResult.link,
@@ -241,11 +240,35 @@ async function addOnerepScanResults(
});
if (scanResultsMap.length > 0) {
- //Delete previous records to allow dynamic mock data configuration.
- if (process.env.ONEREP_API_BASE!.includes("localhost")) {
- await knex("onerep_scan_results")
- .where("onerep_scan_id", MOCK_ONEREP_SCAN_ID())
- .del();
+ const scan_id = scanResultsMap[0].onerep_scan_id;
+
+ // Delete previous records to allow dynamic mock data configuration, maintaining the 'manually_resolved' field.
+ if (!process.env.ONEREP_API_BASE!.includes("mozilla.api.onerep.com")) {
+ const existingRecords = await knex("onerep_scan_results")
+ .where("onerep_scan_id", scan_id)
+ .select("onerep_scan_result_id", "manually_resolved");
+
+ const resolvedStatusMap = new Map();
+ existingRecords.forEach((record) => {
+ resolvedStatusMap.set(
+ record.onerep_scan_result_id,
+ record.manually_resolved,
+ );
+ });
+
+ await knex("onerep_scan_results").where("onerep_scan_id", scan_id).del();
+
+ scanResultsMap = scanResultsMap.map((item) => {
+ if (resolvedStatusMap.has(item.onerep_scan_result_id)) {
+ return {
+ ...item,
+ manually_resolved: resolvedStatusMap.get(
+ item.onerep_scan_result_id,
+ ),
+ };
+ }
+ return item;
+ });
}
await knex("onerep_scan_results")
diff --git a/src/e2e/specs/auth.spec.ts b/src/e2e/specs/auth.spec.ts
index 92959b012d7..a820b367893 100644
--- a/src/e2e/specs/auth.spec.ts
+++ b/src/e2e/specs/auth.spec.ts
@@ -27,10 +27,7 @@ test.describe(`${process.env.E2E_TEST_ENV} - Authentication flow verification @s
await authPage.signUp(randomEmail, page);
// assert successful login
- const successUrl =
- process.env.E2E_TEST_ENV === "local"
- ? "/user/dashboard"
- : "/user/welcome";
+ const successUrl = "/user/welcome";
expect(page.url()).toBe(`${process.env.E2E_TEST_BASE_URL}${successUrl}`);
await testInfo.attach(
diff --git a/src/e2e/specs/dashboard.spec.ts b/src/e2e/specs/dashboard.spec.ts
index a72dba31d56..d2709338a7f 100644
--- a/src/e2e/specs/dashboard.spec.ts
+++ b/src/e2e/specs/dashboard.spec.ts
@@ -10,7 +10,6 @@ import {
removeUnicodeChars,
clickOnATagCheckDomain,
escapeRegExp,
- forceLoginAs,
} from "../utils/helpers.js";
// bypass login
@@ -426,12 +425,14 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Breaches Scan,
const count = await dashboardPage.allExposures.count();
// Fix first exposure
await dashboardPage.markAsFixed.click();
-
+ // await new Promise(resolve => setTimeout(resolve, 10000));
for (let i = 1; i < count; i++) {
const exposure = dashboardPage.allExposures.nth(i);
await exposure.click();
+ // await new Promise(resolve => setTimeout(resolve, 2000));
if (await dashboardPage.markAsFixed.isVisible()) {
+ // await new Promise(resolve => setTimeout(resolve, 2000));
await dashboardPage.markAsFixed.click();
}
}
@@ -448,6 +449,7 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Breaches Scan,
await dashboardPage.fixedTab.click();
const fixedExposures = await dashboardPage.numFixed.textContent();
expect(fixedExposures as string).toMatch(initialExposuresCount);
+ // expect(false).toBeTruthy();
});
});
@@ -720,13 +722,14 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Navigation`, (
});
test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Data Breaches`, () => {
- test.beforeEach(async ({ landingPage, page, authPage }) => {
- const emailToUse = process.env
- .E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED as string;
- const pwdToUse = process.env.E2E_TEST_ACCOUNT_PASSWORD as string;
- expect(emailToUse).not.toBeUndefined();
- expect(pwdToUse).not.toBeUndefined();
- await forceLoginAs(emailToUse, pwdToUse, page, landingPage, authPage);
+ test.beforeEach(async ({ dashboardPage, page }) => {
+ await dashboardPage.open();
+
+ try {
+ await checkAuthState(page);
+ } catch {
+ console.log("[E2E_LOG] - No fxa auth required, proceeding...");
+ }
});
test("Verify that the High risk data breaches step is displayed correctly", async ({
diff --git a/src/e2e/specs/landing.spec.ts b/src/e2e/specs/landing.spec.ts
index acb202d4656..58d462c36b6 100644
--- a/src/e2e/specs/landing.spec.ts
+++ b/src/e2e/specs/landing.spec.ts
@@ -309,14 +309,8 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page Functionali
await authPage.enterPassword();
// verify dashboard redirect
- const successUrl =
- process.env.E2E_TEST_BASE_URL +
- `${
- process.env.E2E_TEST_ENV === "local"
- ? "/user/welcome"
- : "/user/dashboard"
- }`;
- expect(page.url()).toBe(successUrl);
+ const successUrl = process.env.E2E_TEST_BASE_URL + "/user/dashboard";
+ expect(page.url()).toContain(successUrl);
});
test('Verify the "Start free monitoring" button UI and functionality with existing account', async ({
@@ -336,13 +330,7 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page Functionali
await authPage.enterPassword();
// verify dashboard redirect
- const successUrl =
- process.env.E2E_TEST_BASE_URL +
- `${
- process.env.E2E_TEST_ENV === "local"
- ? "/user/welcome"
- : "/user/dashboard"
- }`;
- expect(page.url()).toBe(successUrl);
+ const successUrl = process.env.E2E_TEST_BASE_URL + "/user/dashboard";
+ expect(page.url()).toContain(successUrl);
});
});
From d6eb4ed150be1d0c9fd73726a167ca52ac2c3257 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Fri, 28 Jun 2024 16:59:41 -0700
Subject: [PATCH 019/137] added production checks
---
src/app/api/mock/hibp/breaches/route.ts | 11 +++--------
.../mock/hibp/range/search/[hashPrefix]/route.ts | 13 +++----------
src/app/api/mock/onerep/config/config.ts | 2 +-
src/app/api/mock/onerep/config/mockUser.json | 2 +-
src/app/api/mock/onerep/config/route.ts | 13 ++++++++++++-
.../profiles/[profileId]/activate/route.ts | 6 ++++--
.../profiles/[profileId]/deactivate/route.ts | 6 ++++--
.../onerep/profiles/[profileId]/optout/route.ts | 6 ++++--
.../mock/onerep/profiles/[profileId]/route.ts | 5 ++++-
.../profiles/[profileId]/scans/[scanId]/route.ts | 6 ++++--
.../onerep/profiles/[profileId]/scans/route.ts | 7 +++++++
src/app/api/mock/onerep/profiles/route.ts | 4 ++++
src/app/api/mock/onerep/scan-results/route.ts | 4 ++++
src/app/api/mock/onerep/stats/profiles/route.ts | 4 ++++
src/app/api/mock/utils/errorThrower.ts | 16 ++++++++++++++++
src/app/functions/server/onerep.ts | 2 +-
src/db/tables/onerep_scans.ts | 2 +-
src/e2e/specs/dashboard.spec.ts | 4 ----
18 files changed, 77 insertions(+), 36 deletions(-)
create mode 100644 src/app/api/mock/utils/errorThrower.ts
diff --git a/src/app/api/mock/hibp/breaches/route.ts b/src/app/api/mock/hibp/breaches/route.ts
index 5c4230b773f..91ed1e2c7ea 100644
--- a/src/app/api/mock/hibp/breaches/route.ts
+++ b/src/app/api/mock/hibp/breaches/route.ts
@@ -5,6 +5,7 @@
import { NextResponse } from "next/server";
import { logger } from "../../../../functions/server/logging";
import fakeAllBreaches from "../data/fakeAllBreaches.json";
+import { errorIfProduction } from "../../utils/errorThrower";
type BreachesListResponse = {
Id: number;
@@ -28,15 +29,9 @@ type BreachesListResponse = {
}[];
export function GET() {
- const { APP_ENV } = process.env;
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
- // Check if APP_ENV is set to production
- if (APP_ENV === "production") {
- return NextResponse.json(
- { error: "Endpoint not available in production environment" },
- { status: 403 },
- );
- }
logger.info("Mock endpoint: /breaches");
const data = fakeAllBreaches.data as BreachesListResponse;
diff --git a/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts b/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
index e386a13ed4a..795a27a381f 100644
--- a/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
+++ b/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
@@ -7,6 +7,7 @@ import { logger } from "../../../../../../functions/server/logging";
import { getSha1 } from "../../../../../../../utils/fxa";
import fakeBreaches from "../../../data/fakeBreaches.json";
import type { BinaryLike } from "crypto";
+import { errorIfProduction } from "../../../../utils/errorThrower";
type BreachedAccountResponse = {
hashSuffix: string;
@@ -14,15 +15,8 @@ type BreachedAccountResponse = {
}[];
export function GET() {
- const { APP_ENV } = process.env;
-
- // Check if APP_ENV is set to production
- if (APP_ENV === "production") {
- return NextResponse.json(
- { error: "Endpoint not available in production environment" },
- { status: 403 },
- );
- }
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
// Mock data for test email, can be randomized
const userEmail = process.env.E2E_TEST_ACCOUNT_EMAIL;
@@ -37,6 +31,5 @@ export function GET() {
hashSuffix: currentUserSha.slice(6).toUpperCase(),
}));
const res = NextResponse.json(data);
- console.log("opa1", data);
return res;
}
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index 228cfb54329..d6a9a152e99 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -70,7 +70,7 @@ export function MOCK_ONEREP_ADDRESSES() {
})) as typeOfAddr;
}
-const DEFAULT_NUMBER_BREACHES = 5;
+const DEFAULT_NUMBER_BREACHES = 10;
const MAGIC_NUM_brokerId = 78127;
const MAGIC_NUM_1 = 24623;
const MAGIC_NUM_2 = 2161;
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index ece3a3a67eb..f39086e0d1b 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -1,6 +1,6 @@
{
"PROFILE_ID": 777,
- "MAGIC_NUM_0": 2914,
+ "MAGIC_NUM_0": 29010,
"TIME": "2024-06-19T01:37:02+0000",
"FIRSTNAME": "John",
"LASTNAME": "Doe",
diff --git a/src/app/api/mock/onerep/config/route.ts b/src/app/api/mock/onerep/config/route.ts
index 969ed75a812..b5cf3a03465 100644
--- a/src/app/api/mock/onerep/config/route.ts
+++ b/src/app/api/mock/onerep/config/route.ts
@@ -6,10 +6,12 @@ import { NextRequest, NextResponse } from "next/server";
import fs from "fs";
import path from "path";
import { randomInt } from "crypto";
+import { logger } from "../../../../functions/server/logging";
/*
Example fetch, where obj conforms to Broker interface in config.ts
+Set erase to true if you want to use default response, or false if obj
fetch('/api/mock/onerep/config', {
method: 'POST',
@@ -26,7 +28,16 @@ fetch('/api/mock/onerep/config', {
*/
-export async function POST(req: NextRequest) {
+export function POST() {
+ logger.info(`Attempted to access ${updateJsonFile.name}`);
+
+ return NextResponse.json(
+ { error: "Endpoint not available yet" },
+ { status: 403 },
+ );
+}
+
+async function updateJsonFile(req: NextRequest) {
// Define the path to the JSON file
const jsonFilePath = path.join(
process.cwd(),
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
index dcae96793f8..d2be762a3ee 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
@@ -3,16 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { NextRequest, NextResponse } from "next/server";
+import { errorIfProduction } from "../../../../utils/errorThrower";
export function PUT(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
}
- //TODO: update the json file corresponding to this user
-
return NextResponse.json({
message: `Profile ${profileId} successfully activated`,
});
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
index 964652c369d..ef8fee39f97 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
@@ -3,16 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { NextRequest, NextResponse } from "next/server";
+import { errorIfProduction } from "../../../../utils/errorThrower";
export function PUT(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
}
- //TODO: update the json file corresponding to this user
-
return NextResponse.json({
message: `Profile ${profileId} successfully deactivated`,
});
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
index 611cf44c0bc..0a74866019c 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
@@ -3,16 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { NextRequest, NextResponse } from "next/server";
+import { errorIfProduction } from "../../../../utils/errorThrower";
export function POST(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
}
- //TODO: update the json file corresponding to this user
-
return NextResponse.json({
message: `Profile ${profileId} successfully opted out`,
});
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
index ea28493e2ba..be0ca13f989 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -12,9 +12,9 @@ import {
} from "../../config/config.ts";
import { ShowProfileResponse } from "../../../../../functions/server/onerep.ts";
import { NextRequest, NextResponse } from "next/server";
+import { errorIfProduction } from "../../../utils/errorThrower.ts";
// Mocked profile data to simulate response
-//TODO: mock out the URL
async function extractProfileId(req: NextRequest) {
const idFromBody: number = req.body !== null && (await req.json()).profileId;
@@ -25,6 +25,9 @@ async function extractProfileId(req: NextRequest) {
// Mock endpoint to simulate fetching a profile by ID
export async function GET(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
// Extract profileId from query parameters or request body
const profileId: number = await extractProfileId(req);
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index 228088ec1b0..d42bd82caa2 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -2,12 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-// pages/api/profiles/[profileId]/scans/[scanId].ts
-
+import { errorIfProduction } from "../../../../../utils/errorThrower";
import { MOCK_ONEREP_TIME } from "../../../../config/config";
import { NextRequest, NextResponse } from "next/server";
export function GET(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileId = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
const scanId = Number(req.url.match(/scans\/([0-9]+)/)![1]);
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index d085e0fc107..fbd32e7244b 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -8,6 +8,7 @@ import {
MOCK_ONEREP_MAGIC_NUM_1,
MOCK_ONEREP_MAGIC_NUM_2,
} from "../../../config/config";
+import { errorIfProduction } from "../../../../utils/errorThrower";
function extractProfileId(req: NextRequest) {
const idFromUrl = Number(req.url.match(/profiles\/([0-9]+)\/scans/)![1]);
@@ -19,6 +20,9 @@ function getScanId(profileId: number) {
}
export function POST(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileId: number = extractProfileId(req);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
@@ -40,6 +44,9 @@ export function POST(req: NextRequest) {
}
export function GET(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileId: number = extractProfileId(req);
if (!profileId || isNaN(profileId)) {
diff --git a/src/app/api/mock/onerep/profiles/route.ts b/src/app/api/mock/onerep/profiles/route.ts
index a5180d11320..98f2b4d8a54 100644
--- a/src/app/api/mock/onerep/profiles/route.ts
+++ b/src/app/api/mock/onerep/profiles/route.ts
@@ -5,6 +5,7 @@
import { MOCK_ONEREP_STATUS, MOCK_ONEREP_TIME } from "../config/config.ts";
import { NextRequest, NextResponse } from "next/server";
import { randomInt } from "crypto";
+import { errorIfProduction } from "../../utils/errorThrower.ts";
export type RequestProfileData = {
first_name: string;
@@ -43,6 +44,9 @@ type ResponseProfileData = {
};
export async function POST(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileId = randomInt(1000, 10000);
try {
if (req.body === null) {
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index 3f2c76310ed..07b4bab3c43 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -2,10 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { errorIfProduction } from "../../utils/errorThrower";
import { MOCK_ONEREP_BROKERS } from "../config/config";
import { NextRequest, NextResponse } from "next/server";
export function GET(req: NextRequest) {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const page = req.url.match(/page=([0-9]+)/)![1] || "1";
const perPage = req.url.match(/per_page=([0-9]+)/)![1] || "100";
diff --git a/src/app/api/mock/onerep/stats/profiles/route.ts b/src/app/api/mock/onerep/stats/profiles/route.ts
index ffd8f958068..fbad9a4e337 100644
--- a/src/app/api/mock/onerep/stats/profiles/route.ts
+++ b/src/app/api/mock/onerep/stats/profiles/route.ts
@@ -3,8 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { NextResponse } from "next/server";
+import { errorIfProduction } from "../../../utils/errorThrower";
export function GET() {
+ const prodError = errorIfProduction();
+ if (prodError) return prodError;
+
const profileStats = {
created: 0,
deleted: 0,
diff --git a/src/app/api/mock/utils/errorThrower.ts b/src/app/api/mock/utils/errorThrower.ts
new file mode 100644
index 00000000000..9471aa108e9
--- /dev/null
+++ b/src/app/api/mock/utils/errorThrower.ts
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { NextResponse } from "next/server";
+
+export function errorIfProduction() {
+ //checks that the environment isnt prod
+ if (process.env.APP_ENV === "production") {
+ return NextResponse.json(
+ { error: "Endpoint not available in production environment" },
+ { status: 403 },
+ );
+ }
+ return null;
+}
diff --git a/src/app/functions/server/onerep.ts b/src/app/functions/server/onerep.ts
index af7fa53b86a..491ad6e3ba7 100644
--- a/src/app/functions/server/onerep.ts
+++ b/src/app/functions/server/onerep.ts
@@ -121,7 +121,7 @@ async function onerepFetch(
//If mock, remove the first slash so that it doesn't overwrite the path
if (
- onerepApiBase.includes("localhost") &&
+ onerepApiBase.includes("/api/mock") &&
path.length > 1 &&
path[0] === "/"
) {
diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts
index deee6736e78..04913d616cd 100644
--- a/src/db/tables/onerep_scans.ts
+++ b/src/db/tables/onerep_scans.ts
@@ -243,7 +243,7 @@ async function addOnerepScanResults(
const scan_id = scanResultsMap[0].onerep_scan_id;
// Delete previous records to allow dynamic mock data configuration, maintaining the 'manually_resolved' field.
- if (!process.env.ONEREP_API_BASE!.includes("mozilla.api.onerep.com")) {
+ if (process.env.ONEREP_API_BASE!.includes("/api/mock")) {
const existingRecords = await knex("onerep_scan_results")
.where("onerep_scan_id", scan_id)
.select("onerep_scan_result_id", "manually_resolved");
diff --git a/src/e2e/specs/dashboard.spec.ts b/src/e2e/specs/dashboard.spec.ts
index d2709338a7f..bc1b0df3eb0 100644
--- a/src/e2e/specs/dashboard.spec.ts
+++ b/src/e2e/specs/dashboard.spec.ts
@@ -425,14 +425,11 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Breaches Scan,
const count = await dashboardPage.allExposures.count();
// Fix first exposure
await dashboardPage.markAsFixed.click();
- // await new Promise(resolve => setTimeout(resolve, 10000));
for (let i = 1; i < count; i++) {
const exposure = dashboardPage.allExposures.nth(i);
await exposure.click();
- // await new Promise(resolve => setTimeout(resolve, 2000));
if (await dashboardPage.markAsFixed.isVisible()) {
- // await new Promise(resolve => setTimeout(resolve, 2000));
await dashboardPage.markAsFixed.click();
}
}
@@ -449,7 +446,6 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Breaches Scan,
await dashboardPage.fixedTab.click();
const fixedExposures = await dashboardPage.numFixed.textContent();
expect(fixedExposures as string).toMatch(initialExposuresCount);
- // expect(false).toBeTruthy();
});
});
From 842b229efe83d474457dc38d138974f2d0a53a42 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Fri, 28 Jun 2024 17:04:01 -0700
Subject: [PATCH 020/137] fixed lint errors
---
src/app/api/mock/hibp/data/fakeAllBreaches.json | 2 +-
src/app/api/mock/onerep/config/mockUser.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/app/api/mock/hibp/data/fakeAllBreaches.json b/src/app/api/mock/hibp/data/fakeAllBreaches.json
index 44aa91f5f2c..ec9063f09f6 100644
--- a/src/app/api/mock/hibp/data/fakeAllBreaches.json
+++ b/src/app/api/mock/hibp/data/fakeAllBreaches.json
@@ -77,6 +77,6 @@
"IsSpamList": false,
"IsMalware": false,
"FaviconUrl": null
- }
+ }
]
}
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index f39086e0d1b..65375f66e67 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -19,4 +19,4 @@
"meta": {},
"valid": false
}
-}
\ No newline at end of file
+}
From 9d368c0fb1c68802f795b40df06a42f0fd11ac5b Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Fri, 28 Jun 2024 17:42:23 -0700
Subject: [PATCH 021/137] reverting smoke test
---
src/e2e/specs/auth.spec.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/e2e/specs/auth.spec.ts b/src/e2e/specs/auth.spec.ts
index a820b367893..92959b012d7 100644
--- a/src/e2e/specs/auth.spec.ts
+++ b/src/e2e/specs/auth.spec.ts
@@ -27,7 +27,10 @@ test.describe(`${process.env.E2E_TEST_ENV} - Authentication flow verification @s
await authPage.signUp(randomEmail, page);
// assert successful login
- const successUrl = "/user/welcome";
+ const successUrl =
+ process.env.E2E_TEST_ENV === "local"
+ ? "/user/dashboard"
+ : "/user/welcome";
expect(page.url()).toBe(`${process.env.E2E_TEST_BASE_URL}${successUrl}`);
await testInfo.attach(
From 29af535c1c357efc39c2f4b20c2cf43d5f120d40 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Sat, 29 Jun 2024 03:18:02 -0700
Subject: [PATCH 022/137] cleaned up query params and dynamic routing
---
src/app/api/mock/onerep/config/mockUser.json | 4 ++--
.../profiles/[profileId]/activate/route.ts | 7 +++++--
.../profiles/[profileId]/deactivate/route.ts | 7 +++++--
.../profiles/[profileId]/optout/route.ts | 7 +++++--
.../mock/onerep/profiles/[profileId]/route.ts | 17 +++++------------
.../[profileId]/scans/[scanId]/route.ts | 10 +++++++---
.../onerep/profiles/[profileId]/scans/route.ts | 18 +++++++++---------
src/app/api/mock/onerep/scan-results/route.ts | 13 ++++++++++---
8 files changed, 48 insertions(+), 35 deletions(-)
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index 65375f66e67..b7e3b3ebbe5 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -1,6 +1,6 @@
{
"PROFILE_ID": 777,
- "MAGIC_NUM_0": 29010,
+ "MAGIC_NUM_0": 83597,
"TIME": "2024-06-19T01:37:02+0000",
"FIRSTNAME": "John",
"LASTNAME": "Doe",
@@ -19,4 +19,4 @@
"meta": {},
"valid": false
}
-}
+}
\ No newline at end of file
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
index d2be762a3ee..74b07b24eef 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
@@ -5,11 +5,14 @@
import { NextRequest, NextResponse } from "next/server";
import { errorIfProduction } from "../../../../utils/errorThrower";
-export function PUT(req: NextRequest) {
+export function PUT(
+ _: NextRequest,
+ { params }: { params: { profileId: string } },
+) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+ const profileId: number = Number(params.profileId);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
index ef8fee39f97..815143010bb 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
@@ -5,11 +5,14 @@
import { NextRequest, NextResponse } from "next/server";
import { errorIfProduction } from "../../../../utils/errorThrower";
-export function PUT(req: NextRequest) {
+export function PUT(
+ _: NextRequest,
+ { params }: { params: { profileId: string } },
+) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+ const profileId: number = Number(params.profileId);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
index 0a74866019c..5ea5e3c37ff 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
@@ -5,11 +5,14 @@
import { NextRequest, NextResponse } from "next/server";
import { errorIfProduction } from "../../../../utils/errorThrower";
-export function POST(req: NextRequest) {
+export function POST(
+ _: NextRequest,
+ { params }: { params: { profileId: string } },
+) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
+ const profileId: number = Number(params.profileId);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
index be0ca13f989..49cb8e3aaad 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -14,22 +14,15 @@ import { ShowProfileResponse } from "../../../../../functions/server/onerep.ts";
import { NextRequest, NextResponse } from "next/server";
import { errorIfProduction } from "../../../utils/errorThrower.ts";
-// Mocked profile data to simulate response
-
-async function extractProfileId(req: NextRequest) {
- const idFromBody: number = req.body !== null && (await req.json()).profileId;
- if (idFromBody) return idFromBody;
- const idFromUrl: number = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
- return idFromUrl;
-}
-
// Mock endpoint to simulate fetching a profile by ID
-export async function GET(req: NextRequest) {
+export function GET(
+ _: NextRequest,
+ { params }: { params: { profileId: string } },
+) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- // Extract profileId from query parameters or request body
- const profileId: number = await extractProfileId(req);
+ const profileId: number = Number(params.profileId);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" }, { status: 400 });
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index d42bd82caa2..7297aabcab4 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -6,12 +6,15 @@ import { errorIfProduction } from "../../../../../utils/errorThrower";
import { MOCK_ONEREP_TIME } from "../../../../config/config";
import { NextRequest, NextResponse } from "next/server";
-export function GET(req: NextRequest) {
+export function GET(
+ _: NextRequest,
+ { params }: { params: { profileId: string; scandId: string } },
+) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId = Number(req.url.match(/profiles\/([0-9]+)/)![1]);
- const scanId = Number(req.url.match(/scans\/([0-9]+)/)![1]);
+ const profileId: number = Number(params.profileId);
+ const scanId: number = Number(params.scandId);
const responseData = {
id: scanId,
@@ -22,5 +25,6 @@ export function GET(req: NextRequest) {
updated_at: MOCK_ONEREP_TIME(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
};
+
return NextResponse.json(responseData);
}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index fbd32e7244b..4bd1265e0a1 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -10,20 +10,15 @@ import {
} from "../../../config/config";
import { errorIfProduction } from "../../../../utils/errorThrower";
-function extractProfileId(req: NextRequest) {
- const idFromUrl = Number(req.url.match(/profiles\/([0-9]+)\/scans/)![1]);
- return idFromUrl;
-}
-
function getScanId(profileId: number) {
return (profileId * MOCK_ONEREP_MAGIC_NUM_1()) % MOCK_ONEREP_MAGIC_NUM_2();
}
-export function POST(req: NextRequest) {
+export function POST({ params }: { params: { profileId: number } }) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = extractProfileId(req);
+ const profileId: number = params.profileId;
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
}
@@ -43,11 +38,16 @@ export function POST(req: NextRequest) {
return NextResponse.json(mockResponse);
}
-export function GET(req: NextRequest) {
+export function GET(
+ _: NextRequest,
+ { params }: { params: { profileId: string } },
+) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = extractProfileId(req);
+ // Extract profileId from query parameters or request body
+ // const profileId: number = await extractProfileId(req)
+ const profileId: number = Number(params.profileId);
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index 07b4bab3c43..f9d9f1eeefe 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -10,10 +10,17 @@ export function GET(req: NextRequest) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const page = req.url.match(/page=([0-9]+)/)![1] || "1";
- const perPage = req.url.match(/per_page=([0-9]+)/)![1] || "100";
+ const page = req.nextUrl.searchParams.get("page") || "1";
+ const perPage = req.nextUrl.searchParams.get("per_page") || "100";
- const profileId = req.url.match(/profile_id......=([0-9]+)&/)![1];
+ const profileId = req.nextUrl.searchParams.get("profile_id[]");
+
+ if (profileId === null) {
+ return NextResponse.json(
+ { error: "No 'profile_id' provided!" },
+ { status: 400 },
+ );
+ }
return NextResponse.json(MOCK_ONEREP_BROKERS(profileId, page, perPage));
}
From fa16c41486cd1715c40bce737167d2f8530453bb Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Sat, 29 Jun 2024 03:23:21 -0700
Subject: [PATCH 023/137] fixed lint errors and corrected a POST endpoint
---
src/app/api/mock/onerep/config/mockUser.json | 2 +-
src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index b7e3b3ebbe5..e757d2af1b1 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -19,4 +19,4 @@
"meta": {},
"valid": false
}
-}
\ No newline at end of file
+}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index 4bd1265e0a1..3a1a2a6e424 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -14,7 +14,10 @@ function getScanId(profileId: number) {
return (profileId * MOCK_ONEREP_MAGIC_NUM_1()) % MOCK_ONEREP_MAGIC_NUM_2();
}
-export function POST({ params }: { params: { profileId: number } }) {
+export function POST(
+ _: NextRequest,
+ { params }: { params: { profileId: number } },
+) {
const prodError = errorIfProduction();
if (prodError) return prodError;
From f3378b0ceeda89f6c318f9b7078ded78219fb18e Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Sat, 29 Jun 2024 18:44:13 -0700
Subject: [PATCH 024/137] added form input
---
.../admin/mock-config/onerep/ConfigPage.tsx | 170 ++++++++++++++++++
.../admin/mock-config/onerep/page.tsx | 23 +++
src/app/api/mock/onerep/config/config.ts | 49 +++--
src/app/api/mock/onerep/config/test.json | 3 +-
.../profiles/[profileId]/scans/route.ts | 14 +-
src/app/api/mock/onerep/scan-results/route.ts | 4 +-
6 files changed, 223 insertions(+), 40 deletions(-)
create mode 100644 src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
create mode 100644 src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/page.tsx
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
new file mode 100644
index 00000000000..39a6d091379
--- /dev/null
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
@@ -0,0 +1,170 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use client";
+
+import React, { useState } from "react";
+import {
+ MOCK_ONEREP_DATABROKER_ID_START,
+ MOCK_ONEREP_ID_START,
+ MOCK_ONEREP_SCAN_ID,
+ MOCK_ONEREP_STATUS,
+ MOCK_ONEREP_TIME,
+} from "../../../../../../api/mock/onerep/config/config";
+
+interface Broker {
+ id: number;
+ profile_id: number;
+ scan_id: number;
+ status: string;
+ first_name: string;
+ middle_name?: string | null;
+ last_name: string;
+ age?: number | null;
+ addresses: object[];
+ phones: object[];
+ emails: object[];
+ relatives: object[];
+ link: string;
+ data_broker: string;
+ data_broker_id: number;
+ optout_attempts: number;
+ created_at: string;
+ updated_at: string;
+}
+
+const ConfigPage = () => {
+ const [brokers, setBrokers] = useState([]);
+
+ // Initialize a base broker template to reset form fields
+ const baseBroker = {
+ id: -1,
+ profile_id: -1,
+ scan_id: -1,
+ status: MOCK_ONEREP_STATUS(),
+ first_name: "",
+ middle_name: null,
+ last_name: "",
+ age: null,
+ addresses: [],
+ phones: [],
+ emails: [],
+ relatives: [],
+ link: "",
+ data_broker: "",
+ data_broker_id: -1,
+ optout_attempts: 0,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
+ };
+
+ // Temporary state to hold form input for a new broker
+ const [newBroker, setNewBroker] = useState(baseBroker);
+
+ const handleChange = (e: React.ChangeEvent) => {
+ setNewBroker({ ...newBroker, [e.target.name]: e.target.value });
+ };
+
+ const handleAddBroker = (event: React.FormEvent) => {
+ event.preventDefault();
+
+ const profileId = Number(newBroker.profile_id);
+ const scandId = MOCK_ONEREP_SCAN_ID(profileId);
+ const brokerIdStart = MOCK_ONEREP_DATABROKER_ID_START(profileId);
+ const idStart = MOCK_ONEREP_ID_START(profileId);
+
+ setBrokers([
+ ...brokers,
+ {
+ ...newBroker,
+ id: idStart - brokers.length,
+ scan_id: scandId,
+ data_broker_id: brokerIdStart - brokers.length,
+ profile_id: profileId,
+ },
+ ]);
+ setNewBroker(baseBroker); // Reset form fields
+ };
+
+ const handleSubmit = (event: React.FormEvent) => {
+ event.preventDefault();
+ try {
+ const response = brokers;
+ console.log("Response:", response);
+ alert("Brokers submitted successfully!");
+ } catch (error) {
+ console.error("Error submitting brokers:", error);
+ alert("Failed to submit brokers.");
+ }
+ };
+
+ return (
+
+
+
+
Brokers List
+
+ {brokers.map((broker) => (
+ -
+ {broker.first_name} {broker.last_name}
+
+ ))}
+
+
+
+
+ );
+};
+
+export default ConfigPage;
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/page.tsx
new file mode 100644
index 00000000000..3062648f0ff
--- /dev/null
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/page.tsx
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { getServerSession } from "../../../../../../functions/server/getServerSession";
+import { notFound } from "next/navigation";
+import { isAdmin } from "../../../../../../api/utils/auth";
+import ConfigPage from "./ConfigPage";
+
+export default async function DevPage() {
+ const session = await getServerSession();
+
+ if (
+ !session?.user?.email ||
+ (!isAdmin(session.user.email) &&
+ session.user.email !== process.env.E2E_TEST_ACCOUNT_EMAIL) ||
+ process.env.APP_ENV !== "local"
+ ) {
+ return notFound();
+ }
+
+ return ;
+}
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index d6a9a152e99..b7373b15507 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -9,7 +9,7 @@ import MockUser from "./mockUser.json";
interface Broker {
id: number;
- profile_id: string;
+ profile_id: number;
scan_id: number;
status: string;
first_name: string;
@@ -26,15 +26,27 @@ interface Broker {
optout_attempts: number;
created_at: string;
updated_at: string;
- url: string;
}
+const DEFAULT_NUMBER_BREACHES = 10;
+const MAGIC_NUM_1 = 24623;
+const MAGIC_NUM_2 = 2161;
+const MAGIC_NUM_3 = 1013;
+
export function MOCK_ONEREP_PROFILE_ID() {
return MockUser.PROFILE_ID;
}
-export function MOCK_ONEREP_MAGIC_NUM_0() {
- return MockUser.MAGIC_NUM_0;
+export function MOCK_ONEREP_SCAN_ID(profileId: number) {
+ return (profileId * MAGIC_NUM_1) % MAGIC_NUM_2;
+}
+
+export function MOCK_ONEREP_DATABROKER_ID_START(profileId: number) {
+ return MockUser.MAGIC_NUM_0 * MOCK_ONEREP_SCAN_ID(profileId);
+}
+
+export function MOCK_ONEREP_ID_START(profileId: number) {
+ return MOCK_ONEREP_DATABROKER_ID_START(profileId) % MAGIC_NUM_3;
}
export function MOCK_ONEREP_TIME() {
@@ -70,30 +82,13 @@ export function MOCK_ONEREP_ADDRESSES() {
})) as typeOfAddr;
}
-const DEFAULT_NUMBER_BREACHES = 10;
-const MAGIC_NUM_brokerId = 78127;
-const MAGIC_NUM_1 = 24623;
-const MAGIC_NUM_2 = 2161;
-
-export function MOCK_ONEREP_MAGIC_NUM_1() {
- return MAGIC_NUM_1;
-}
-
-export function MOCK_ONEREP_MAGIC_NUM_2() {
- return MAGIC_NUM_2;
-}
-
-function getScanId(profileId: string) {
- return (Number(profileId) * MAGIC_NUM_1) % MAGIC_NUM_2;
-}
-
export function MOCK_ONEREP_BROKERS(
- profileId: string,
+ profileId: number,
page: string,
perPage: string,
) {
const mockResponseData = MockUser.BROKERS_LIST;
- const latestScanId = getScanId(profileId);
+ const latestScanId = MOCK_ONEREP_SCAN_ID(profileId);
const mockLinks = {
first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
@@ -136,7 +131,10 @@ export function MOCK_ONEREP_BROKERS(
return mockResponseData;
}
- const idStart = latestScanId * MOCK_ONEREP_MAGIC_NUM_0();
+ const idStart = MOCK_ONEREP_ID_START(profileId);
+ const idStartDataBroker = MOCK_ONEREP_DATABROKER_ID_START(profileId);
+
+ //TODO: update array creation to be of type broker
const responseData = {
data: new Array(DEFAULT_NUMBER_BREACHES).fill(null).map((_, index) => ({
@@ -154,11 +152,10 @@ export function MOCK_ONEREP_BROKERS(
relatives: [],
link: `https://mockexample.com/link-to-databroker${index}`,
data_broker: `mockexample${index}.com`,
- data_broker_id: MAGIC_NUM_brokerId - index,
+ data_broker_id: idStartDataBroker - index,
optout_attempts: 0,
created_at: MOCK_ONEREP_TIME(),
updated_at: MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}scan-results/${idStart - index}`,
})),
links: mockLinks,
meta: mockMeta,
diff --git a/src/app/api/mock/onerep/config/test.json b/src/app/api/mock/onerep/config/test.json
index c8d3af447e7..f808d276593 100644
--- a/src/app/api/mock/onerep/config/test.json
+++ b/src/app/api/mock/onerep/config/test.json
@@ -18,8 +18,7 @@
"data_broker_id": 23,
"optout_attempts": 0,
"created_at": "2024-06-19T01:37:02+0000",
- "updated_at": "2024-06-19T01:37:02+0000",
- "url": "http://localhost:6060/api/mock/onerep/scan-results/45000"
+ "updated_at": "2024-06-19T01:37:02+0000"
}
]
}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index 3a1a2a6e424..cbe6f1d755f 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -3,17 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { NextRequest, NextResponse } from "next/server";
-import {
- MOCK_ONEREP_TIME,
- MOCK_ONEREP_MAGIC_NUM_1,
- MOCK_ONEREP_MAGIC_NUM_2,
-} from "../../../config/config";
+import { MOCK_ONEREP_TIME, MOCK_ONEREP_SCAN_ID } from "../../../config/config";
import { errorIfProduction } from "../../../../utils/errorThrower";
-function getScanId(profileId: number) {
- return (profileId * MOCK_ONEREP_MAGIC_NUM_1()) % MOCK_ONEREP_MAGIC_NUM_2();
-}
-
export function POST(
_: NextRequest,
{ params }: { params: { profileId: number } },
@@ -26,7 +18,7 @@ export function POST(
return NextResponse.json({ error: "Invalid profile ID" });
}
- const scanId = getScanId(profileId);
+ const scanId = MOCK_ONEREP_SCAN_ID(profileId);
const mockResponse = {
id: scanId,
@@ -56,7 +48,7 @@ export function GET(
return NextResponse.json({ error: "Invalid profile ID" });
}
- const scandId = getScanId(profileId);
+ const scandId = MOCK_ONEREP_SCAN_ID(profileId);
const responseData = {
data: [
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index f9d9f1eeefe..de3fc6a03e0 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -22,5 +22,7 @@ export function GET(req: NextRequest) {
);
}
- return NextResponse.json(MOCK_ONEREP_BROKERS(profileId, page, perPage));
+ return NextResponse.json(
+ MOCK_ONEREP_BROKERS(Number(profileId), page, perPage),
+ );
}
From 0a4e15bacae7812c109710dbf9ced3f82f051f76 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Sat, 29 Jun 2024 19:03:45 -0700
Subject: [PATCH 025/137] substituted direct magic numbers access to wrapper
methods
---
src/app/api/mock/onerep/config/config.ts | 49 +++++++++----------
.../profiles/[profileId]/activate/route.ts | 4 +-
.../profiles/[profileId]/deactivate/route.ts | 6 +--
.../profiles/[profileId]/optout/route.ts | 4 +-
.../[profileId]/scans/[scanId]/route.ts | 6 +--
.../profiles/[profileId]/scans/route.ts | 21 +++-----
src/app/api/mock/onerep/scan-results/route.ts | 4 +-
7 files changed, 42 insertions(+), 52 deletions(-)
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index d6a9a152e99..b7373b15507 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -9,7 +9,7 @@ import MockUser from "./mockUser.json";
interface Broker {
id: number;
- profile_id: string;
+ profile_id: number;
scan_id: number;
status: string;
first_name: string;
@@ -26,15 +26,27 @@ interface Broker {
optout_attempts: number;
created_at: string;
updated_at: string;
- url: string;
}
+const DEFAULT_NUMBER_BREACHES = 10;
+const MAGIC_NUM_1 = 24623;
+const MAGIC_NUM_2 = 2161;
+const MAGIC_NUM_3 = 1013;
+
export function MOCK_ONEREP_PROFILE_ID() {
return MockUser.PROFILE_ID;
}
-export function MOCK_ONEREP_MAGIC_NUM_0() {
- return MockUser.MAGIC_NUM_0;
+export function MOCK_ONEREP_SCAN_ID(profileId: number) {
+ return (profileId * MAGIC_NUM_1) % MAGIC_NUM_2;
+}
+
+export function MOCK_ONEREP_DATABROKER_ID_START(profileId: number) {
+ return MockUser.MAGIC_NUM_0 * MOCK_ONEREP_SCAN_ID(profileId);
+}
+
+export function MOCK_ONEREP_ID_START(profileId: number) {
+ return MOCK_ONEREP_DATABROKER_ID_START(profileId) % MAGIC_NUM_3;
}
export function MOCK_ONEREP_TIME() {
@@ -70,30 +82,13 @@ export function MOCK_ONEREP_ADDRESSES() {
})) as typeOfAddr;
}
-const DEFAULT_NUMBER_BREACHES = 10;
-const MAGIC_NUM_brokerId = 78127;
-const MAGIC_NUM_1 = 24623;
-const MAGIC_NUM_2 = 2161;
-
-export function MOCK_ONEREP_MAGIC_NUM_1() {
- return MAGIC_NUM_1;
-}
-
-export function MOCK_ONEREP_MAGIC_NUM_2() {
- return MAGIC_NUM_2;
-}
-
-function getScanId(profileId: string) {
- return (Number(profileId) * MAGIC_NUM_1) % MAGIC_NUM_2;
-}
-
export function MOCK_ONEREP_BROKERS(
- profileId: string,
+ profileId: number,
page: string,
perPage: string,
) {
const mockResponseData = MockUser.BROKERS_LIST;
- const latestScanId = getScanId(profileId);
+ const latestScanId = MOCK_ONEREP_SCAN_ID(profileId);
const mockLinks = {
first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
@@ -136,7 +131,10 @@ export function MOCK_ONEREP_BROKERS(
return mockResponseData;
}
- const idStart = latestScanId * MOCK_ONEREP_MAGIC_NUM_0();
+ const idStart = MOCK_ONEREP_ID_START(profileId);
+ const idStartDataBroker = MOCK_ONEREP_DATABROKER_ID_START(profileId);
+
+ //TODO: update array creation to be of type broker
const responseData = {
data: new Array(DEFAULT_NUMBER_BREACHES).fill(null).map((_, index) => ({
@@ -154,11 +152,10 @@ export function MOCK_ONEREP_BROKERS(
relatives: [],
link: `https://mockexample.com/link-to-databroker${index}`,
data_broker: `mockexample${index}.com`,
- data_broker_id: MAGIC_NUM_brokerId - index,
+ data_broker_id: idStartDataBroker - index,
optout_attempts: 0,
created_at: MOCK_ONEREP_TIME(),
updated_at: MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}scan-results/${idStart - index}`,
})),
links: mockLinks,
meta: mockMeta,
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
index 74b07b24eef..3bedaef54e5 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/activate/route.ts
@@ -7,12 +7,12 @@ import { errorIfProduction } from "../../../../utils/errorThrower";
export function PUT(
_: NextRequest,
- { params }: { params: { profileId: string } },
+ { params }: { params: { profileId: number } },
) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = Number(params.profileId);
+ const profileId: number = params.profileId;
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
index 815143010bb..a4dc0e0def8 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/deactivate/route.ts
@@ -7,15 +7,15 @@ import { errorIfProduction } from "../../../../utils/errorThrower";
export function PUT(
_: NextRequest,
- { params }: { params: { profileId: string } },
+ { params }: { params: { profileId: number } },
) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = Number(params.profileId);
+ const profileId: number = params.profileId;
if (!profileId || isNaN(profileId)) {
- return NextResponse.json({ error: "Invalid profile ID" });
+ return NextResponse.json({ status: 400, error: "Invalid profile ID" });
}
return NextResponse.json({
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
index 5ea5e3c37ff..b28fb2d8885 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/optout/route.ts
@@ -7,12 +7,12 @@ import { errorIfProduction } from "../../../../utils/errorThrower";
export function POST(
_: NextRequest,
- { params }: { params: { profileId: string } },
+ { params }: { params: { profileId: number } },
) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = Number(params.profileId);
+ const profileId: number = params.profileId;
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index 7297aabcab4..7864613bc77 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -8,13 +8,13 @@ import { NextRequest, NextResponse } from "next/server";
export function GET(
_: NextRequest,
- { params }: { params: { profileId: string; scandId: string } },
+ { params }: { params: { profileId: number; scanId: number } },
) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- const profileId: number = Number(params.profileId);
- const scanId: number = Number(params.scandId);
+ const profileId: number = params.profileId;
+ const scanId: number = params.scanId;
const responseData = {
id: scanId,
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index 3a1a2a6e424..1ad2ccc6b22 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -3,17 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { NextRequest, NextResponse } from "next/server";
-import {
- MOCK_ONEREP_TIME,
- MOCK_ONEREP_MAGIC_NUM_1,
- MOCK_ONEREP_MAGIC_NUM_2,
-} from "../../../config/config";
+import { MOCK_ONEREP_SCAN_ID, MOCK_ONEREP_TIME } from "../../../config/config";
import { errorIfProduction } from "../../../../utils/errorThrower";
-function getScanId(profileId: number) {
- return (profileId * MOCK_ONEREP_MAGIC_NUM_1()) % MOCK_ONEREP_MAGIC_NUM_2();
-}
-
export function POST(
_: NextRequest,
{ params }: { params: { profileId: number } },
@@ -22,11 +14,12 @@ export function POST(
if (prodError) return prodError;
const profileId: number = params.profileId;
+
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
}
- const scanId = getScanId(profileId);
+ const scanId = MOCK_ONEREP_SCAN_ID(profileId);
const mockResponse = {
id: scanId,
@@ -43,20 +36,18 @@ export function POST(
export function GET(
_: NextRequest,
- { params }: { params: { profileId: string } },
+ { params }: { params: { profileId: number } },
) {
const prodError = errorIfProduction();
if (prodError) return prodError;
- // Extract profileId from query parameters or request body
- // const profileId: number = await extractProfileId(req)
- const profileId: number = Number(params.profileId);
+ const profileId: number = params.profileId;
if (!profileId || isNaN(profileId)) {
return NextResponse.json({ error: "Invalid profile ID" });
}
- const scandId = getScanId(profileId);
+ const scandId = MOCK_ONEREP_SCAN_ID(profileId);
const responseData = {
data: [
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index f9d9f1eeefe..de3fc6a03e0 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -22,5 +22,7 @@ export function GET(req: NextRequest) {
);
}
- return NextResponse.json(MOCK_ONEREP_BROKERS(profileId, page, perPage));
+ return NextResponse.json(
+ MOCK_ONEREP_BROKERS(Number(profileId), page, perPage),
+ );
}
From 06b25ca8b128355487947410e0d21114c5c5a6b2 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Sat, 29 Jun 2024 21:46:28 -0700
Subject: [PATCH 026/137] mock endpoint config - basic version
---
.../mock-config/onerep/ConfigPage.module.scss | 68 +++++++
.../admin/mock-config/onerep/ConfigPage.tsx | 177 +++++++++---------
src/app/api/mock/onerep/config/config.ts | 12 +-
src/app/api/mock/onerep/config/mockUser.json | 4 +-
src/app/api/mock/onerep/config/route.ts | 45 ++---
src/app/api/mock/onerep/config/test.json | 2 +-
src/db/tables/onerep_scans.ts | 60 +++---
7 files changed, 222 insertions(+), 146 deletions(-)
create mode 100644 src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss
new file mode 100644
index 00000000000..c93a2ed6ef3
--- /dev/null
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss
@@ -0,0 +1,68 @@
+@import "../../../../../../tokens";
+
+.wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: $spacing-2xl;
+ background-color: $color-grey-05;
+ height: 100%;
+ padding: $layout-lg $layout-2xl;
+
+ @media screen and (max-width: $screen-lg) {
+ padding: $spacing-lg;
+ }
+}
+
+.header {
+ font: $text-title-xs;
+ font-weight: normal;
+
+ b {
+ font-weight: bold;
+ }
+}
+
+.form {
+ display: flex;
+ flex-direction: column;
+ gap: $spacing-2xl;
+
+ .userPicker {
+ flex: 1 0 auto;
+ align-items: center;
+ display: flex;
+ flex-wrap: wrap;
+ gap: $spacing-2xl;
+ min-height: $layout-2xl;
+
+ label {
+ display: flex;
+ flex-direction: column;
+ gap: $spacing-sm;
+ min-width: 50%;
+ }
+
+ input {
+ padding: $spacing-sm;
+ font: $text-body-md;
+ }
+ }
+
+ .actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: $spacing-xl;
+
+ button {
+ flex: 1 1 25%;
+ }
+ }
+}
+
+.status {
+ background-color: $color-yellow-05;
+ border: 2px solid $color-yellow-20;
+ border-radius: $border-radius-sm;
+ padding: $spacing-md $spacing-lg;
+ font: $text-body-md;
+}
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
index 39a6d091379..6f7e2902031 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
@@ -9,48 +9,30 @@ import {
MOCK_ONEREP_DATABROKER_ID_START,
MOCK_ONEREP_ID_START,
MOCK_ONEREP_SCAN_ID,
- MOCK_ONEREP_STATUS,
MOCK_ONEREP_TIME,
+ Broker,
} from "../../../../../../api/mock/onerep/config/config";
-
-interface Broker {
- id: number;
- profile_id: number;
- scan_id: number;
- status: string;
- first_name: string;
- middle_name?: string | null;
- last_name: string;
- age?: number | null;
- addresses: object[];
- phones: object[];
- emails: object[];
- relatives: object[];
- link: string;
- data_broker: string;
- data_broker_id: number;
- optout_attempts: number;
- created_at: string;
- updated_at: string;
-}
+import { useSession } from "next-auth/react";
+import styles from "./ConfigPage.module.scss";
const ConfigPage = () => {
const [brokers, setBrokers] = useState([]);
+ const session = useSession();
// Initialize a base broker template to reset form fields
const baseBroker = {
id: -1,
profile_id: -1,
scan_id: -1,
- status: MOCK_ONEREP_STATUS(),
- first_name: "",
+ status: "new",
+ first_name: "Johnny",
middle_name: null,
- last_name: "",
+ last_name: "Doe",
age: null,
- addresses: [],
- phones: [],
- emails: [],
- relatives: [],
+ addresses: ["address0"],
+ phones: ["phone0"],
+ emails: ["email0"],
+ relatives: ["relative0"],
link: "",
data_broker: "",
data_broker_id: -1,
@@ -90,66 +72,88 @@ const ConfigPage = () => {
const handleSubmit = (event: React.FormEvent) => {
event.preventDefault();
try {
- const response = brokers;
- console.log("Response:", response);
- alert("Brokers submitted successfully!");
+ void makeConfigRequest(false);
+ alert("Brokers list update request submitted successfully!");
} catch (error) {
console.error("Error submitting brokers:", error);
alert("Failed to submit brokers.");
}
};
+ const makeConfigRequest = async (erase: boolean) => {
+ return fetch("/api/mock/onerep/config", {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ email: session.data?.user.email,
+ brokers: brokers,
+ erase: erase,
+ }),
+ }).then(async (resp) =>
+ console.log("Response from endpoint config:", await resp.json()),
+ );
+ };
+
return (
-
+
+
+
);
};
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index b7373b15507..216488247d2 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -7,7 +7,7 @@ import { StateAbbr } from "../../../../../utils/states";
import MockUser from "./mockUser.json";
// import { getLatestOnerepScanResults } from "../../../../../db/tables/onerep_scans";
-interface Broker {
+export interface Broker {
id: number;
profile_id: number;
scan_id: number;
@@ -16,10 +16,10 @@ interface Broker {
middle_name?: string | null;
last_name: string;
age?: number | null;
- addresses: object[];
- phones: object[];
- emails: object[];
- relatives: object[];
+ addresses: string[];
+ phones: string[];
+ emails: string[];
+ relatives: string[];
link: string;
data_broker: string;
data_broker_id: number;
@@ -128,7 +128,7 @@ export function MOCK_ONEREP_BROKERS(
});
}
- return mockResponseData;
+ return response;
}
const idStart = MOCK_ONEREP_ID_START(profileId);
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index e757d2af1b1..2fc1db3a690 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -1,6 +1,6 @@
{
"PROFILE_ID": 777,
- "MAGIC_NUM_0": 83597,
+ "MAGIC_NUM_0": 85136,
"TIME": "2024-06-19T01:37:02+0000",
"FIRSTNAME": "John",
"LASTNAME": "Doe",
@@ -19,4 +19,4 @@
"meta": {},
"valid": false
}
-}
+}
\ No newline at end of file
diff --git a/src/app/api/mock/onerep/config/route.ts b/src/app/api/mock/onerep/config/route.ts
index b5cf3a03465..3bb56ebf10b 100644
--- a/src/app/api/mock/onerep/config/route.ts
+++ b/src/app/api/mock/onerep/config/route.ts
@@ -3,10 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { NextRequest, NextResponse } from "next/server";
+import { randomInt } from "crypto";
+// import { logger } from "../../../../functions/server/logging";
+import { isAdmin } from "../../../utils/auth";
import fs from "fs";
import path from "path";
-import { randomInt } from "crypto";
-import { logger } from "../../../../functions/server/logging";
+import { Broker } from "./config";
/*
@@ -14,7 +16,7 @@ Example fetch, where obj conforms to Broker interface in config.ts
Set erase to true if you want to use default response, or false if obj
fetch('/api/mock/onerep/config', {
- method: 'POST',
+ method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
@@ -25,19 +27,28 @@ fetch('/api/mock/onerep/config', {
})
.then(response => response.json()).then(data => console.log(data))
-
*/
-export function POST() {
- logger.info(`Attempted to access ${updateJsonFile.name}`);
+type onerepConfigReq = {
+ email: string;
+ erase?: boolean;
+ brokers: [Broker];
+};
- return NextResponse.json(
- { error: "Endpoint not available yet" },
- { status: 403 },
- );
+export async function PUT(req: NextRequest) {
+ const data = await req.json();
+ const { email, erase = false, brokers } = data as onerepConfigReq;
+
+ if (!isAdmin(email)) {
+ return NextResponse.json(
+ { error: "Unauthorized to access the endpoint" },
+ { status: 401 },
+ );
+ }
+ return updateJsonFile(erase, brokers);
}
-async function updateJsonFile(req: NextRequest) {
+function updateJsonFile(erase: boolean, brokers: [Broker]) {
// Define the path to the JSON file
const jsonFilePath = path.join(
process.cwd(),
@@ -49,22 +60,12 @@ async function updateJsonFile(req: NextRequest) {
const jsonData = JSON.parse(fileData);
try {
- const newData = await req.json();
- const erase = newData.erase;
-
if (erase) {
jsonData.BROKERS_LIST.data = [];
jsonData.BROKERS_LIST.valid = false;
jsonData.MAGIC_NUM_0 = randomInt(1000, 100000);
} else {
- if (!newData.brokers || !newData.brokers.data) {
- return NextResponse.json(
- { error: "Bad Request: Data format is unexpected!" },
- { status: 400 },
- );
- }
-
- jsonData.BROKERS_LIST.data = newData.brokers.data;
+ jsonData.BROKERS_LIST.data = brokers;
jsonData.BROKERS_LIST.valid = true;
}
diff --git a/src/app/api/mock/onerep/config/test.json b/src/app/api/mock/onerep/config/test.json
index f808d276593..31d485d35c4 100644
--- a/src/app/api/mock/onerep/config/test.json
+++ b/src/app/api/mock/onerep/config/test.json
@@ -1,5 +1,5 @@
{
- "data": [
+ "brokers": [
{
"id": 45000,
"profile_id": -1,
diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts
index 04913d616cd..a3490cef99c 100644
--- a/src/db/tables/onerep_scans.ts
+++ b/src/db/tables/onerep_scans.ts
@@ -16,6 +16,7 @@ import {
SubscriberRow,
} from "knex/types/tables";
import { RemovalStatus } from "../../app/functions/universal/scanResult.js";
+import { MOCK_ONEREP_SCAN_ID } from "../../app/api/mock/onerep/config/config.ts";
const knex = createDbConnection();
@@ -239,38 +240,35 @@ async function addOnerepScanResults(
}),
});
- if (scanResultsMap.length > 0) {
- const scan_id = scanResultsMap[0].onerep_scan_id;
-
- // Delete previous records to allow dynamic mock data configuration, maintaining the 'manually_resolved' field.
- if (process.env.ONEREP_API_BASE!.includes("/api/mock")) {
- const existingRecords = await knex("onerep_scan_results")
- .where("onerep_scan_id", scan_id)
- .select("onerep_scan_result_id", "manually_resolved");
-
- const resolvedStatusMap = new Map();
- existingRecords.forEach((record) => {
- resolvedStatusMap.set(
- record.onerep_scan_result_id,
- record.manually_resolved,
- );
- });
-
- await knex("onerep_scan_results").where("onerep_scan_id", scan_id).del();
-
- scanResultsMap = scanResultsMap.map((item) => {
- if (resolvedStatusMap.has(item.onerep_scan_result_id)) {
- return {
- ...item,
- manually_resolved: resolvedStatusMap.get(
- item.onerep_scan_result_id,
- ),
- };
- }
- return item;
- });
- }
+ // Delete previous records to allow dynamic mock data configuration, maintaining the 'manually_resolved' field.
+ if (process.env.ONEREP_API_BASE!.includes("/api/mock")) {
+ const scan_id = MOCK_ONEREP_SCAN_ID(onerepProfileId);
+ const existingRecords = await knex("onerep_scan_results")
+ .where("onerep_scan_id", scan_id)
+ .select("onerep_scan_result_id", "manually_resolved");
+
+ const resolvedStatusMap = new Map();
+ existingRecords.forEach((record) => {
+ resolvedStatusMap.set(
+ record.onerep_scan_result_id,
+ record.manually_resolved,
+ );
+ });
+
+ await knex("onerep_scan_results").where("onerep_scan_id", scan_id).del();
+ scanResultsMap = scanResultsMap.map((item) => {
+ if (resolvedStatusMap.has(item.onerep_scan_result_id)) {
+ return {
+ ...item,
+ manually_resolved: resolvedStatusMap.get(item.onerep_scan_result_id),
+ };
+ }
+ return item;
+ });
+ }
+
+ if (scanResultsMap.length > 0) {
await knex("onerep_scan_results")
.insert(scanResultsMap)
.onConflict("onerep_scan_result_id")
From cf0ebf6980eb3b02e214d982d32d5d552eab6e4a Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Sat, 29 Jun 2024 22:38:10 -0700
Subject: [PATCH 027/137] added more type checks and proper defaults
---
.../admin/mock-config/onerep/ConfigPage.tsx | 18 +++--
src/app/api/mock/onerep/config/config.ts | 67 ++++++++++---------
src/app/api/mock/onerep/config/mockUser.json | 15 +++--
src/app/api/mock/onerep/config/route.ts | 6 +-
src/db/tables/onerep_scans.ts | 5 +-
5 files changed, 66 insertions(+), 45 deletions(-)
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
index 6f7e2902031..1350164f66d 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
@@ -11,6 +11,12 @@ import {
MOCK_ONEREP_SCAN_ID,
MOCK_ONEREP_TIME,
Broker,
+ MOCK_ONEREP_FIRSTNAME,
+ MOCK_ONEREP_LASTNAME,
+ MOCK_ONEREP_ADDRESSES,
+ MOCK_ONEREP_EMAILS,
+ MOCK_ONEREP_RELATIVES,
+ MOCK_ONEREP_PHONES,
} from "../../../../../../api/mock/onerep/config/config";
import { useSession } from "next-auth/react";
import styles from "./ConfigPage.module.scss";
@@ -25,14 +31,14 @@ const ConfigPage = () => {
profile_id: -1,
scan_id: -1,
status: "new",
- first_name: "Johnny",
+ first_name: MOCK_ONEREP_FIRSTNAME(),
middle_name: null,
- last_name: "Doe",
+ last_name: MOCK_ONEREP_LASTNAME(),
age: null,
- addresses: ["address0"],
- phones: ["phone0"],
- emails: ["email0"],
- relatives: ["relative0"],
+ addresses: [MOCK_ONEREP_ADDRESSES()],
+ phones: MOCK_ONEREP_PHONES(),
+ emails: MOCK_ONEREP_EMAILS(),
+ relatives: MOCK_ONEREP_RELATIVES(),
link: "",
data_broker: "",
data_broker_id: -1,
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index 216488247d2..8a9d15956ab 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -16,7 +16,7 @@ export interface Broker {
middle_name?: string | null;
last_name: string;
age?: number | null;
- addresses: string[];
+ addresses: object[];
phones: string[];
emails: string[];
relatives: string[];
@@ -33,10 +33,6 @@ const MAGIC_NUM_1 = 24623;
const MAGIC_NUM_2 = 2161;
const MAGIC_NUM_3 = 1013;
-export function MOCK_ONEREP_PROFILE_ID() {
- return MockUser.PROFILE_ID;
-}
-
export function MOCK_ONEREP_SCAN_ID(profileId: number) {
return (profileId * MAGIC_NUM_1) % MAGIC_NUM_2;
}
@@ -65,8 +61,16 @@ export function MOCK_ONEREP_BIRTHDATE() {
return MockUser.BIRTHDATE;
}
-export function MOCK_ONEREP_EMAIL() {
- return MockUser.EMAIL;
+export function MOCK_ONEREP_EMAILS() {
+ return MockUser.EMAILS;
+}
+
+export function MOCK_ONEREP_PHONES() {
+ return MockUser.PHONES;
+}
+
+export function MOCK_ONEREP_RELATIVES() {
+ return MockUser.RELATIVES;
}
export function MOCK_ONEREP_STATUS() {
@@ -88,7 +92,7 @@ export function MOCK_ONEREP_BROKERS(
perPage: string,
) {
const mockResponseData = MockUser.BROKERS_LIST;
- const latestScanId = MOCK_ONEREP_SCAN_ID(profileId);
+ const scanId = MOCK_ONEREP_SCAN_ID(profileId);
const mockLinks = {
first: `${process.env.ONEREP_API_BASE}/scan-results?profile_id%5B0%5D=${profileId}&per_page=${perPage}&page=${page}`,
@@ -123,7 +127,7 @@ export function MOCK_ONEREP_BROKERS(
return {
...(broker as Broker),
profile_id: profileId,
- scan_id: latestScanId,
+ scan_id: scanId,
};
});
}
@@ -134,29 +138,30 @@ export function MOCK_ONEREP_BROKERS(
const idStart = MOCK_ONEREP_ID_START(profileId);
const idStartDataBroker = MOCK_ONEREP_DATABROKER_ID_START(profileId);
- //TODO: update array creation to be of type broker
-
const responseData = {
- data: new Array(DEFAULT_NUMBER_BREACHES).fill(null).map((_, index) => ({
- id: idStart - index,
- profile_id: profileId,
- scan_id: latestScanId,
- status: "new",
- first_name: MOCK_ONEREP_FIRSTNAME(),
- middle_name: null,
- last_name: MOCK_ONEREP_LASTNAME(),
- age: null,
- addresses: [],
- phones: [],
- emails: [MOCK_ONEREP_EMAIL()],
- relatives: [],
- link: `https://mockexample.com/link-to-databroker${index}`,
- data_broker: `mockexample${index}.com`,
- data_broker_id: idStartDataBroker - index,
- optout_attempts: 0,
- created_at: MOCK_ONEREP_TIME(),
- updated_at: MOCK_ONEREP_TIME(),
- })),
+ data: new Array(DEFAULT_NUMBER_BREACHES).fill(null).map(
+ (_, index) =>
+ ({
+ id: idStart - index,
+ profile_id: profileId,
+ scan_id: scanId,
+ status: "new",
+ first_name: MOCK_ONEREP_FIRSTNAME(),
+ middle_name: null,
+ last_name: MOCK_ONEREP_LASTNAME(),
+ age: null,
+ addresses: [MOCK_ONEREP_ADDRESSES()],
+ phones: MOCK_ONEREP_PHONES(),
+ emails: MOCK_ONEREP_EMAILS(),
+ relatives: MOCK_ONEREP_RELATIVES(),
+ link: `https://mockexample.com/link-to-databroker${index}`,
+ data_broker: `mockexample${index}.com`,
+ data_broker_id: idStartDataBroker - index,
+ optout_attempts: 0,
+ created_at: MOCK_ONEREP_TIME(),
+ updated_at: MOCK_ONEREP_TIME(),
+ }) as Broker,
+ ),
links: mockLinks,
meta: mockMeta,
};
diff --git a/src/app/api/mock/onerep/config/mockUser.json b/src/app/api/mock/onerep/config/mockUser.json
index 2fc1db3a690..7d8345ccdf5 100644
--- a/src/app/api/mock/onerep/config/mockUser.json
+++ b/src/app/api/mock/onerep/config/mockUser.json
@@ -1,11 +1,12 @@
{
- "PROFILE_ID": 777,
- "MAGIC_NUM_0": 85136,
+ "MAGIC_NUM_0": 77013,
"TIME": "2024-06-19T01:37:02+0000",
"FIRSTNAME": "John",
"LASTNAME": "Doe",
"BIRTHDATE": "2000-01-01",
- "EMAIL": "JohnDoe@JohnDoe.com",
+ "EMAILS": [
+ "JohnDoe@JohnDoe.com"
+ ],
"STATUS": "active",
"ADDRESSES": [
{
@@ -13,10 +14,16 @@
"state": "CA"
}
],
+ "PHONES": [
+ "00000000"
+ ],
+ "RELATIVES": [
+ "Bob Doe"
+ ],
"BROKERS_LIST": {
"data": [],
"links": {},
"meta": {},
"valid": false
}
-}
\ No newline at end of file
+}
diff --git a/src/app/api/mock/onerep/config/route.ts b/src/app/api/mock/onerep/config/route.ts
index 3bb56ebf10b..af981ff3116 100644
--- a/src/app/api/mock/onerep/config/route.ts
+++ b/src/app/api/mock/onerep/config/route.ts
@@ -69,7 +69,11 @@ function updateJsonFile(erase: boolean, brokers: [Broker]) {
jsonData.BROKERS_LIST.valid = true;
}
- fs.writeFileSync(jsonFilePath, JSON.stringify(jsonData, null, 2), "utf8");
+ fs.writeFileSync(
+ jsonFilePath,
+ JSON.stringify(jsonData, null, 2) + "\n",
+ "utf8",
+ );
return NextResponse.json(
{ message: "JSON data has been successfully updated." },
diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts
index a3490cef99c..b6988f71481 100644
--- a/src/db/tables/onerep_scans.ts
+++ b/src/db/tables/onerep_scans.ts
@@ -255,8 +255,6 @@ async function addOnerepScanResults(
);
});
- await knex("onerep_scan_results").where("onerep_scan_id", scan_id).del();
-
scanResultsMap = scanResultsMap.map((item) => {
if (resolvedStatusMap.has(item.onerep_scan_result_id)) {
return {
@@ -266,8 +264,9 @@ async function addOnerepScanResults(
}
return item;
});
- }
+ await knex("onerep_scan_results").where("onerep_scan_id", scan_id).del();
+ }
if (scanResultsMap.length > 0) {
await knex("onerep_scan_results")
.insert(scanResultsMap)
From 9fed1645c9d5784ee59fdaf20dfa7c0272634c06 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Sun, 30 Jun 2024 01:08:24 -0700
Subject: [PATCH 028/137] functional OneRep config page, with styling
---
.../mock-config/onerep/ConfigPage.module.scss | 130 ++++++++---
.../admin/mock-config/onerep/ConfigPage.tsx | 208 +++++++++++-------
src/app/api/mock/onerep/config/config.ts | 2 +-
src/app/api/mock/onerep/config/mockUser.json | 2 +-
4 files changed, 237 insertions(+), 105 deletions(-)
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss
index c93a2ed6ef3..674fe11cb8a 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.module.scss
@@ -1,68 +1,140 @@
@import "../../../../../../tokens";
.wrapper {
- display: flex;
- flex-direction: column;
- gap: $spacing-2xl;
- background-color: $color-grey-05;
+ display: grid;
+ grid-template-rows: 120px min-content;
+ gap: $spacing-md;
height: 100%;
- padding: $layout-lg $layout-2xl;
-
- @media screen and (max-width: $screen-lg) {
- padding: $spacing-lg;
- }
+ padding: $layout-sm;
+ background-color: $color-grey-05;
+ align-items: center;
+ justify-content: center;
}
.header {
font: $text-title-xs;
font-weight: normal;
-
+ margin: auto;
+ width: 100%;
b {
font-weight: bold;
}
+ text-align: center;
+}
+
+.formAndListWrapper {
+ margin-top: 40px;
+ display: grid;
+ grid-template-rows: 1fr;
+ grid-template-columns: 3fr 2fr;
+ justify-content: center;
+}
+
+.formWrapper {
+ display: grid;
+ grid-template-rows: 50px 4fr 100px;
+ justify-content: center;
+ h2 {
+ text-align: center;
+ }
+}
+
+.listButtonsWrapper {
+ display: grid;
+ grid-template-rows: auto 100px;
+ justify-content: center;
+}
+
+.listContainer {
+ max-height: 250px;
+ overflow-y: auto;
+}
+
+.buttonsWrapper {
+ height: auto;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+}
+
+.listWrapper {
+ height: min-content;
+ display: grid;
+ grid-template-rows: 50px auto;
+ justify-content: center;
+ align-items: flex-start;
+
+ p {
+ color: #858585;
+ }
+}
+
+.button {
+ display: block;
+ margin: auto;
+ max-height: 100px;
+ max-width: 100px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.buttonUnderList {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+@keyframes shake {
+ 0% {
+ transform: translateX(0);
+ }
+ 25% {
+ transform: translateX(-5px);
+ }
+ 75% {
+ transform: translateX(5px);
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+
+.error {
+ border-color: red; /* Example: Highlight border in red for error */
+ animation: shake 0.5s ease-in-out; /* Example animation */
}
.form {
display: flex;
flex-direction: column;
- gap: $spacing-2xl;
+ gap: $spacing-sm;
+ align-items: center;
+ width: min-content;
.userPicker {
flex: 1 0 auto;
align-items: center;
display: flex;
flex-wrap: wrap;
- gap: $spacing-2xl;
- min-height: $layout-2xl;
+ gap: $spacing-md;
+ min-height: $layout-md;
label {
display: flex;
flex-direction: column;
gap: $spacing-sm;
min-width: 50%;
+ width: 350px;
}
input {
padding: $spacing-sm;
font: $text-body-md;
- }
- }
-
- .actions {
- display: flex;
- flex-wrap: wrap;
- gap: $spacing-xl;
-
- button {
- flex: 1 1 25%;
+ transition: border-color 0.3s ease;
}
}
}
-.status {
- background-color: $color-yellow-05;
- border: 2px solid $color-yellow-20;
- border-radius: $border-radius-sm;
- padding: $spacing-md $spacing-lg;
- font: $text-body-md;
+.listItem:hover {
+ background-color: #f0f0f0; /* Light grey background on hover */
+ cursor: pointer; /* Change cursor to indicate clickable item */
+ text-decoration: line-through;
}
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
index 1350164f66d..f702b6a0248 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/mock-config/onerep/ConfigPage.tsx
@@ -25,6 +25,12 @@ const ConfigPage = () => {
const [brokers, setBrokers] = useState([]);
const session = useSession();
+ const [errors, setErrors] = useState({
+ profile_id: false,
+ data_broker: false,
+ link: false,
+ });
+
// Initialize a base broker template to reset form fields
const baseBroker = {
id: -1,
@@ -35,7 +41,7 @@ const ConfigPage = () => {
middle_name: null,
last_name: MOCK_ONEREP_LASTNAME(),
age: null,
- addresses: [MOCK_ONEREP_ADDRESSES()],
+ addresses: MOCK_ONEREP_ADDRESSES(),
phones: MOCK_ONEREP_PHONES(),
emails: MOCK_ONEREP_EMAILS(),
relatives: MOCK_ONEREP_RELATIVES(),
@@ -57,6 +63,34 @@ const ConfigPage = () => {
const handleAddBroker = (event: React.FormEvent) => {
event.preventDefault();
+ let hasError = false;
+
+ if (newBroker.profile_id < 0) {
+ setErrors({ ...errors, profile_id: true });
+ hasError = true;
+ } else {
+ setErrors({ ...errors, profile_id: false });
+ }
+
+ if (newBroker.data_broker.length === 0) {
+ setErrors({ ...errors, data_broker: true });
+ hasError = true;
+ } else {
+ setErrors({ ...errors, data_broker: false });
+ }
+
+ let linkString = "";
+ try {
+ const urlObj = new URL(newBroker.link);
+ linkString = urlObj.href;
+ setErrors({ ...errors, link: false });
+ } catch {
+ setErrors({ ...errors, link: true });
+ hasError = true;
+ }
+
+ if (hasError) return;
+
const profileId = Number(newBroker.profile_id);
const scandId = MOCK_ONEREP_SCAN_ID(profileId);
const brokerIdStart = MOCK_ONEREP_DATABROKER_ID_START(profileId);
@@ -66,12 +100,14 @@ const ConfigPage = () => {
...brokers,
{
...newBroker,
+ link: linkString,
id: idStart - brokers.length,
scan_id: scandId,
data_broker_id: brokerIdStart - brokers.length,
profile_id: profileId,
},
]);
+
setNewBroker(baseBroker); // Reset form fields
};
@@ -79,15 +115,18 @@ const ConfigPage = () => {
event.preventDefault();
try {
void makeConfigRequest(false);
- alert("Brokers list update request submitted successfully!");
} catch (error) {
console.error("Error submitting brokers:", error);
alert("Failed to submit brokers.");
}
};
- const makeConfigRequest = async (erase: boolean) => {
- return fetch("/api/mock/onerep/config", {
+ const handleDeleteBroker = (id: number) => {
+ setBrokers(brokers.filter((broker) => broker.id !== id));
+ };
+
+ const makeConfigRequest = (erase: boolean) => {
+ void fetch("/api/mock/onerep/config", {
method: "PUT",
headers: {
"Content-Type": "application/json",
@@ -100,84 +139,105 @@ const ConfigPage = () => {
}).then(async (resp) =>
console.log("Response from endpoint config:", await resp.json()),
);
+ alert("Brokers list update request submitted successfully!");
};
return (
-
{props.enableDiscountCoupon &&
!alreadyHasCouponSet &&
- !props.isYearlySubscriber ? (
+ props.isMonthlySubscriber ? (
<>
{
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -272,7 +272,7 @@ it("Add email address button is not shown when email limit of five reached", ()
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -316,7 +316,7 @@ it("Add email address button is shown when fewer than five emails", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -352,7 +352,7 @@ it("preselects 'Send all breach alerts to the primary email address' if that's t
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -396,7 +396,7 @@ it("preselects 'Send breach alerts to the affected email address' if that's the
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -440,7 +440,7 @@ it("disables breach alert notification options if a user opts out of breach aler
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["UpdatedEmailPreferencesOption"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -494,7 +494,7 @@ it("preselects primary email alert option", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["UpdatedEmailPreferencesOption"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -534,7 +534,7 @@ it("unselects the breach alerts checkbox and sends a null value to the API", asy
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["UpdatedEmailPreferencesOption"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -590,7 +590,7 @@ it("preselects the affected email comms option after a user decides to enable br
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["UpdatedEmailPreferencesOption"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -637,7 +637,7 @@ it("sends a call to the API to change the email alert preferences when changing
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["UpdatedEmailPreferencesOption"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -697,7 +697,7 @@ it("checks that monthly monitor report is enabled", () => {
"MonthlyActivityEmail",
]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -744,7 +744,7 @@ it("sends an API call to disable monthly monitor reports", async () => {
"MonthlyActivityEmail",
]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -790,7 +790,7 @@ it("refreshes the session token after changing email alert preferences, to ensur
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -826,7 +826,7 @@ it("marks unverified email addresses as such", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -863,7 +863,7 @@ it("calls the API to resend a verification email if requested to", async () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -910,7 +910,7 @@ it("calls the 'remove' action when clicking the rubbish bin icon", async () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -947,7 +947,7 @@ it("hides the Plus cancellation link if the user doesn't have Plus", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -983,7 +983,7 @@ it("shows the Plus cancellation link if the user has Plus", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1026,7 +1026,7 @@ it("takes you through the cancellation dialog flow all the way to subplat", asyn
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["ConfirmCancellation", "CancellationFlow"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1104,7 +1104,7 @@ it("closes the cancellation survey if the user selects nevermind, take me back",
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["ConfirmCancellation", "CancellationFlow"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1161,7 +1161,7 @@ it("closes the cancellation dialog", async () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={["CancellationFlow"]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1211,7 +1211,7 @@ it("shows the account deletion button if the user does not have Plus", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1252,7 +1252,7 @@ it("warns about the consequences before deleting a free user's account", async (
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1295,7 +1295,7 @@ it("shows a loading state while account deletion is in progress", async () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1339,7 +1339,7 @@ it("shows the account deletion button if the user has Plus", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1380,7 +1380,7 @@ it("warns about the consequences before deleting a Plus user's account", async (
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1432,7 +1432,7 @@ it.skip("calls the 'add' action when adding another email address", async () =>
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1467,7 +1467,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1511,7 +1511,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1555,7 +1555,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1600,7 +1600,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1644,7 +1644,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1693,7 +1693,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1738,7 +1738,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1787,7 +1787,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1831,7 +1831,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1880,7 +1880,7 @@ describe("to learn about usage", () => {
subscriptionBillingAmount={mockedSubscriptionBillingAmount}
enabledFeatureFlags={[]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -1941,7 +1941,7 @@ it("selects the coupon code discount cta and shows the all-set dialog step", asy
"DiscountCouponNextThreeMonths",
]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -2027,7 +2027,7 @@ it("shows error message if the applying the coupon code function was unsuccessfu
"DiscountCouponNextThreeMonths",
]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
@@ -2093,7 +2093,7 @@ it("does not show the coupon code if a user already has a coupon set", async ()
"DiscountCouponNextThreeMonths",
]}
experimentData={defaultExperimentData}
- isYearlySubscriber={false}
+ isMonthlySubscriber={true}
/>
,
);
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/View.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/View.tsx
index 1ed24060d0c..bcec42408bc 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/View.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/View.tsx
@@ -40,7 +40,7 @@ export type Props = {
enabledFeatureFlags: FeatureFlagName[];
experimentData: ExperimentData;
lastScanDate?: Date;
- isYearlySubscriber: boolean;
+ isMonthlySubscriber: boolean;
};
export const SettingsView = (props: Props) => {
@@ -112,7 +112,7 @@ export const SettingsView = (props: Props) => {
)}
fxaSubscriptionsUrl={props.fxaSubscriptionsUrl}
experimentData={props.experimentData}
- isYearlySubscriber={props.isYearlySubscriber}
+ isMonthlySubscriber={props.isMonthlySubscriber}
/>
) : (
);
}
diff --git a/src/app/functions/universal/user.ts b/src/app/functions/universal/user.ts
index 738b3a414df..3a406cbafa7 100644
--- a/src/app/functions/universal/user.ts
+++ b/src/app/functions/universal/user.ts
@@ -43,23 +43,28 @@ export function meetsAgeRequirement(dateOfBirth: ISO8601DateString): boolean {
}
/* c8 ignore start */
-export async function checkUserHasYearlySubscription(user: Session["user"]) {
- if (
- !user.subscriber?.fxa_access_token ||
- !process.env.PREMIUM_PLAN_ID_YEARLY_US
- ) {
+export async function checkUserHasMonthlySubscription(user: Session["user"]) {
+ if (!user.subscriber?.fxa_access_token) {
console.error("FXA token not set");
return false;
}
+ if (!process.env.PREMIUM_PLAN_ID_MONTHLY_US) {
+ console.error("Monthly Plan ID not set");
+ return false;
+ }
+
const billingAndSubscriptionInfo = await getBillingAndSubscriptions(
user.subscriber.fxa_access_token,
);
+
if (billingAndSubscriptionInfo === null) {
return false;
}
- const yearlyPlanId: string = process.env.PREMIUM_PLAN_ID_YEARLY_US;
+ const monthlyPlanId = process.env.PREMIUM_PLAN_ID_MONTHLY_US;
+ const yearlyPlanId = process.env.PREMIUM_PLAN_ID_YEARLY_US ?? "";
+
const subscriptions = billingAndSubscriptionInfo.subscriptions;
const planIds: string[] = [];
@@ -67,6 +72,11 @@ export async function checkUserHasYearlySubscription(user: Session["user"]) {
planIds.push(subscription.plan_id);
});
- return planIds.includes(yearlyPlanId);
+ if (planIds.includes(yearlyPlanId)) {
+ console.error("User has yearly plan set");
+ return false;
+ }
+
+ return planIds.includes(monthlyPlanId);
}
/* c8 ignore stop */
From bb1e38cd08c1945b20b497caeff69a65b8329629 Mon Sep 17 00:00:00 2001
From: Vincent
Date: Mon, 15 Jul 2024 14:19:41 +0200
Subject: [PATCH 096/137] Port breach data fetching cronjob to TS
---
package.json | 3 ++-
src/db/tables/breaches.js | 4 ++--
.../syncBreaches.ts} | 22 +++++++++----------
src/scripts/s3.js | 6 ++++-
4 files changed, 20 insertions(+), 15 deletions(-)
rename src/scripts/{syncBreaches.js => cronjobs/syncBreaches.ts} (86%)
diff --git a/package.json b/package.json
index 5633cbe4892..a2ef69c894c 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"dev:cron:first-data-broker-removal-fixed": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/firstDataBrokerRemovalFixed.tsx",
"dev:cron:monthly-activity": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/monthlyActivity.tsx",
"dev:cron:db-delete-unverified-subscribers": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/deleteUnverifiedSubscribers.ts",
+ "dev:cron:db-pull-breaches": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/syncBreaches.ts",
"dev:cron:onerep-limits-alert": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/onerepStatsAlert.ts",
"dev:nimbus": "node --watch-path config/nimbus.yaml src/scripts/build/nimbusTypes.js",
"build": "npm run get-location-data && npm run build-glean && npm run build-nimbus && next build && npm run build-cronjobs",
@@ -27,7 +28,7 @@
"cron:monthly-activity": "node dist/scripts/cronjobs/monthlyActivity.js",
"cron:breach-alerts": "node src/scripts/emailBreachAlerts.js",
"cron:db-delete-unverified-subscribers": "node dist/scripts/cronjobs/deleteUnverifiedSubscribers.js",
- "cron:db-pull-breaches": "node src/scripts/syncBreaches.js",
+ "cron:db-pull-breaches": "node dist/scripts/cronjobs/syncBreaches.js",
"cron:remote-settings-pull-breaches": "node scripts/updatebreaches.js",
"cron:onerep-limits-alert": "node dist/scripts/cronjobs/onerepStatsAlert.js",
"db:migrate": "node -r dotenv-flow/config node_modules/knex/bin/cli.js migrate:latest --knexfile src/db/knexfile.js",
diff --git a/src/db/tables/breaches.js b/src/db/tables/breaches.js
index 9cbf75cc0cf..9930120015c 100644
--- a/src/db/tables/breaches.js
+++ b/src/db/tables/breaches.js
@@ -88,8 +88,8 @@ async function upsertBreaches(hibpBreaches) {
/**
* Update logo path of a breach by name
*
- * @param {string} name
- * @param {string} faviconUrl
+ * @param {string} name
+ * @param {string | null} faviconUrl
*/
// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
/* c8 ignore start */
diff --git a/src/scripts/syncBreaches.js b/src/scripts/cronjobs/syncBreaches.ts
similarity index 86%
rename from src/scripts/syncBreaches.js
rename to src/scripts/cronjobs/syncBreaches.ts
index d8eafb61068..02d7e4a411e 100644
--- a/src/scripts/syncBreaches.js
+++ b/src/scripts/cronjobs/syncBreaches.ts
@@ -12,13 +12,14 @@
import { readdir } from "node:fs/promises";
import os from "node:os";
import Sentry from "@sentry/nextjs";
-import { req, formatDataClassesArray } from "../utils/hibp.js";
+import { req, formatDataClassesArray } from "../../utils/hibp.js";
import {
getAllBreaches,
upsertBreaches,
updateBreachFaviconUrl,
-} from "../db/tables/breaches.js";
-import { uploadToS3 } from "./s3.js";
+} from "../../db/tables/breaches.js";
+import { uploadToS3 } from "../s3.js";
+import type { Breach } from "../../app/functions/universal/breach.js";
const SENTRY_SLUG = "cron-sync-breaches";
@@ -32,7 +33,7 @@ const checkInId = Sentry.captureCheckIn({
status: "in_progress",
});
-export async function getBreachIcons(breaches) {
+export async function getBreachIcons(breaches: Breach[]) {
// make logofolder if it doesn't exist
const logoFolder = os.tmpdir();
console.log(`Logo folder: ${logoFolder}`);
@@ -82,20 +83,19 @@ export async function getBreachIcons(breaches) {
}
// Get breaches and upserts to DB
-const breachesResponse = await req("/breaches");
-const breaches = [];
+const breachesResponse: Breach[] = await req("/breaches");
+const breaches: Breach[] = [];
const seen = new Set();
for (const breach of breachesResponse) {
breach.DataClasses = formatDataClassesArray(breach.DataClasses);
- breach.LogoPath = /[^/]*$/.exec(breach.LogoPath)[0];
+ breach.LogoPath = /[^/]*$/.exec(breach.LogoPath)![0];
breaches.push(breach);
seen.add(breach.Name + breach.BreachDate);
// sanity check: corrupt data structure
if (!isValidBreach(breach))
throw new Error(
- "Breach data structure is not valid",
- JSON.stringify(breach),
+ "Breach data structure is not valid: " + JSON.stringify(breach),
);
}
@@ -128,10 +128,10 @@ setTimeout(process.exit, 1000);
/**
* Null check for some required field
*
- * @param {object} breach breach object from HIBP
+ * @param breach breach object from HIBP
* @returns Boolean is it a valid breach
*/
-function isValidBreach(breach) {
+function isValidBreach(breach: Breach) {
return (
breach.Name !== undefined &&
breach.BreachDate !== undefined &&
diff --git a/src/scripts/s3.js b/src/scripts/s3.js
index 3a40eda17cb..11f5fcc7874 100644
--- a/src/scripts/s3.js
+++ b/src/scripts/s3.js
@@ -24,6 +24,10 @@ const s3 = new S3({
},
});
+/**
+ * @param {string} fileName
+ * @param {Buffer} fileStream
+ */
export async function uploadToS3(fileName, fileStream) {
console.log("Attempt to upload to s3: ", fileName);
const uploadParams = {
@@ -37,7 +41,7 @@ export async function uploadToS3(fileName, fileStream) {
params: uploadParams,
}).done();
console.log("Successfully uploaded data to " + Bucket + "/" + fileName);
- } catch (err) {
+ } catch (/** @type {any} */ err) {
console.error(err, err.stack);
}
}
From eacb3b7a3f4ed47e5ae0cfff9ef6fbf6116c1439 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Wed, 17 Jul 2024 08:28:56 -0700
Subject: [PATCH 097/137] fix: yearly pricing default var
---
.env.local.example | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.env.local.example b/.env.local.example
index 74190266b0b..0fb8bef968b 100644
--- a/.env.local.example
+++ b/.env.local.example
@@ -58,7 +58,7 @@ NEXT_PUBLIC_SENTRY_DSN=https://573f784b5cc7481ebf8c0c385d2ad776@o1069899.ingest.
# SubPlat product and plan IDs, used for Plus subscriptions:
PREMIUM_PRODUCT_ID=prod_NErZh679W62lai
PREMIUM_PLAN_ID_MONTHLY_US=price_1MUNq0Kb9q6OnNsL4BoJgepf
-PREMIUM_PLAN_ID_YEARLY_US=price_1MUNq0Kb9q6OnNsL4BoJgepf
+PREMIUM_PLAN_ID_YEARLY_US=price_1NvqawKb9q6OnNsLRTnYrtrV
# Mozilla Accounts URLs
FXA_SUBSCRIPTIONS_URL=https://accounts.stage.mozaws.net/subscriptions
From f887e2d66217d112c9748e47facde4aecd975744 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Wed, 17 Jul 2024 09:14:21 -0700
Subject: [PATCH 098/137] fix: account uri
---
.env.local.example | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.env.local.example b/.env.local.example
index 0fb8bef968b..1a82ca694a7 100644
--- a/.env.local.example
+++ b/.env.local.example
@@ -69,7 +69,7 @@ OAUTH_API_URI="https://api-accounts.stage.mozaws.net/v1"
OAUTH_AUTHORIZATION_URI=https://accounts.stage.mozaws.net/authorization
OAUTH_PROFILE_URI=https://profile.stage.mozaws.net/v1/profile
OAUTH_TOKEN_URI=https://oauth.stage.mozaws.net/v1/token
-OAUTH_ACCOUNT_URI = "https://oauth.accounts.firefox.com/v1"
+OAUTH_ACCOUNT_URI=https://oauth.stage.mozaws.net/v1
# Which environment to run end-to-end tests against:
E2E_TEST_ENV=local
From 66d1054a83b40d07714ea1de9b0ea6143c8e3cc3 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Wed, 17 Jul 2024 22:47:27 -0700
Subject: [PATCH 099/137] addressed comments and added safe fallbacks
---
src/app/api/mock/hibp/config/defaults.ts | 2 +-
.../hibp/range/search/[hashPrefix]/route.ts | 3 +-
src/app/api/mock/onerep/config/config.ts | 70 +++++++++---------
.../api/mock/onerep/mockData/mockUser.json | 20 +++++
.../mock/onerep/profiles/[profileId]/route.ts | 26 +++----
.../[profileId]/scans/[scanId]/route.ts | 39 +++++-----
.../profiles/[profileId]/scans/route.ts | 74 ++++++++++---------
src/app/api/mock/onerep/profiles/route.ts | 14 ++--
src/app/api/mock/onerep/scan-results/route.ts | 9 +--
src/app/api/utils/errorThrower.ts | 32 ++++----
src/app/api/utils/mockUtils.ts | 4 +-
src/app/functions/server/onerep.ts | 4 +-
src/app/functions/universal/mock.ts | 2 +-
13 files changed, 159 insertions(+), 140 deletions(-)
diff --git a/src/app/api/mock/hibp/config/defaults.ts b/src/app/api/mock/hibp/config/defaults.ts
index 86ec3073c66..1ccbc0ba12b 100644
--- a/src/app/api/mock/hibp/config/defaults.ts
+++ b/src/app/api/mock/hibp/config/defaults.ts
@@ -11,5 +11,5 @@ export interface BreachMap {
export const getBreachesForHash = (hash: string) => {
const key = hashToEmailKeyMap[hash] || "default";
- return (mockBreaches as BreachMap)[key];
+ return (mockBreaches as BreachMap)[key] || [];
};
diff --git a/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts b/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
index 3956d8a2230..53786210bc7 100644
--- a/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
+++ b/src/app/api/mock/hibp/range/search/[hashPrefix]/route.ts
@@ -30,6 +30,5 @@ export function GET(
websites: breachesList,
},
];
- const res = NextResponse.json(data);
- return res;
+ return NextResponse.json(data);
}
diff --git a/src/app/api/mock/onerep/config/config.ts b/src/app/api/mock/onerep/config/config.ts
index dcd1d219032..1e5bd4417a5 100644
--- a/src/app/api/mock/onerep/config/config.ts
+++ b/src/app/api/mock/onerep/config/config.ts
@@ -5,7 +5,7 @@
import { BinaryLike, createHash } from "crypto";
import { StateAbbr } from "../../../../../utils/states";
import MockUser from "../mockData/mockUser.json";
-import { computeSha1First6, hashToEmailKeyMap } from "../../../utils/mockUtils";
+import { emailHashPrefix, hashToEmailKeyMap } from "../../../utils/mockUtils";
import { getLatestOnerepScan } from "../../../../../db/tables/onerep_scans";
export interface Broker {
@@ -66,51 +66,51 @@ function hasher(plaintext: number | string) {
return parseInt(last4BytesHex, 16);
}
-export function MOCK_ONEREP_SCAN_ID(profileId: number) {
+export function mockOnerepScanId(profileId: number) {
return hasher(profileId);
}
-export function MOCK_ONEREP_DATABROKER_ID_START(profileId: number) {
+export function mockOnerepDatabrokerIdStart(profileId: number) {
return hasher(profileId * MAGIC_NUM_1);
}
-export function MOCK_ONEREP_ID_START(profileId: number) {
+export function mockOnerepIdStart(profileId: number) {
return hasher(profileId * MAGIC_NUM_2);
}
-export function MOCK_ONEREP_TIME() {
+export function mockOnerepTime() {
return MockUser.TIME;
}
-export function MOCK_ONEREP_FIRSTNAME() {
+export function mockOnerepFirstName() {
return MockUser.FIRSTNAME;
}
-export function MOCK_ONEREP_LASTNAME() {
+export function mockOnerepLastName() {
return MockUser.LASTNAME;
}
-export function MOCK_ONEREP_BIRTHDATE() {
+export function mockOnerepBirthdate() {
return MockUser.BIRTHDATE;
}
-export function MOCK_ONEREP_EMAILS() {
+export function mockOnerepEmails() {
return MockUser.EMAILS;
}
-export function MOCK_ONEREP_PHONES() {
+export function mockOnerepPhones() {
return MockUser.PHONES;
}
-export function MOCK_ONEREP_RELATIVES() {
+export function mockOnerepRelatives() {
return MockUser.RELATIVES;
}
-export function MOCK_ONEREP_PROFILE_STATUS() {
+export function mockOnerepProfileStatus() {
return MockUser.STATUS as "active" | "inactive";
}
-export function MOCK_ONEREP_ADDRESSES() {
+export function mockOnerepAddresses() {
type typeOfAddr = [{ city: string; state: StateAbbr }];
return MockUser.ADDRESSES.map((address) => ({
@@ -119,7 +119,7 @@ export function MOCK_ONEREP_ADDRESSES() {
})) as typeOfAddr;
}
-export function MOCK_ONEREP_OBJECT_META(page: number | string = 1) {
+export function mockOnerepObjectMeta(page: number | string = 1) {
if (typeof page === "string") page = parseInt(page);
return {
current_page: page,
@@ -132,7 +132,7 @@ export function MOCK_ONEREP_OBJECT_META(page: number | string = 1) {
};
}
-export function MOCK_ONEREP_OBJECT_LINKS(
+export function mockOnerepObjectLinks(
profileId: number | string,
page: number | string = 1,
perPage: number | string = 100,
@@ -149,46 +149,50 @@ export function MOCK_ONEREP_OBJECT_LINKS(
};
}
-export async function MOCK_ONEREP_BROKERS(
+export async function mockOnerepBrokers(
profileId: number,
page: string,
perPage: string,
email: string,
) {
let scanId = (await getLatestOnerepScan(profileId))?.onerep_scan_id;
- if (!scanId) scanId = MOCK_ONEREP_SCAN_ID(profileId);
- const mockMeta = MOCK_ONEREP_OBJECT_META(page);
- const mockLinks = MOCK_ONEREP_OBJECT_LINKS(profileId, page, perPage);
- const idStart = MOCK_ONEREP_ID_START(profileId);
- const idStartDataBroker = MOCK_ONEREP_DATABROKER_ID_START(profileId);
+ if (!scanId) scanId = mockOnerepScanId(profileId);
+ const mockMeta = mockOnerepObjectMeta(page);
+ const mockLinks = mockOnerepObjectLinks(profileId, page, perPage);
+ const idStart = mockOnerepIdStart(profileId);
+ const idStartDataBroker = mockOnerepDatabrokerIdStart(profileId);
- const emailHash = computeSha1First6(email);
+ const emailHash = emailHashPrefix(email);
const brokersListMap = MockUser.BROKERS_LIST as BrokerMap;
const datasetKey = hashToEmailKeyMap[emailHash] || "default";
- const brokersList = brokersListMap[datasetKey];
+ const brokersListLookup = brokersListMap[datasetKey];
+ const brokersList =
+ brokersListLookup === undefined
+ ? brokersListMap["default"]
+ : brokersListLookup;
const res = brokersList.map(
(elem: BrokerOptionals, index: number) =>
({
id: idStart - index,
profile_id: profileId,
- scan_id: scanId,
+ scan_id: elem["scan_id"] || scanId,
status: elem["status"] || "new",
- first_name: elem["first_name"] || MOCK_ONEREP_FIRSTNAME(),
+ first_name: elem["first_name"] || mockOnerepFirstName(),
middle_name: elem["middle_name"] || null,
- last_name: elem["last_name"] || MOCK_ONEREP_LASTNAME(),
+ last_name: elem["last_name"] || mockOnerepLastName(),
age: elem["age"] || null,
- addresses: elem["addresses"] || MOCK_ONEREP_ADDRESSES(),
- phones: elem["phones"] || MOCK_ONEREP_PHONES(),
- emails: elem["emails"] || MOCK_ONEREP_EMAILS(),
- relatives: elem["relatives"] || MOCK_ONEREP_RELATIVES(),
+ addresses: elem["addresses"] || mockOnerepAddresses(),
+ phones: elem["phones"] || mockOnerepPhones(),
+ emails: elem["emails"] || mockOnerepEmails(),
+ relatives: elem["relatives"] || mockOnerepRelatives(),
link:
elem["link"] || `https://mockexample.com/link-to-databroker${index}`,
data_broker: elem["data_broker"] || `mockexample${index}.com`,
- data_broker_id: idStartDataBroker - index,
+ data_broker_id: elem["data_broker_id"] || idStartDataBroker - index,
optout_attempts: elem["optout_attempts"] || 0,
- created_at: elem["created_at"] || MOCK_ONEREP_TIME(),
- updated_at: elem["updated_at"] || MOCK_ONEREP_TIME(),
+ created_at: elem["created_at"] || mockOnerepTime(),
+ updated_at: elem["updated_at"] || mockOnerepTime(),
}) as Broker,
);
diff --git a/src/app/api/mock/onerep/mockData/mockUser.json b/src/app/api/mock/onerep/mockData/mockUser.json
index 7b4dc487a71..b4fece7e4d5 100644
--- a/src/app/api/mock/onerep/mockData/mockUser.json
+++ b/src/app/api/mock/onerep/mockData/mockUser.json
@@ -49,6 +49,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://arivify.com",
"data_broker": "arivify.com",
+ "data_broker_id": 13,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -83,6 +84,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://beenverified.com",
"data_broker": "beenverified.com",
+ "data_broker_id": 1,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -117,6 +119,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://instantcheckmate.com",
"data_broker": "instantcheckmate.com",
+ "data_broker_id": 11,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -151,6 +154,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://open-public-records.com",
"data_broker": "open-public-records.com",
+ "data_broker_id": 3,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -185,6 +189,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://peoplefinders.com",
"data_broker": "peoplefinders.com",
+ "data_broker_id": 4,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -219,6 +224,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://peoplesmart.com",
"data_broker": "peoplesmart.com",
+ "data_broker_id": 2,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -253,6 +259,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://privateeye.com",
"data_broker": "privateeye.com",
+ "data_broker_id": 5,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -287,6 +294,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://smartbackgroundchecks.com",
"data_broker": "smartbackgroundchecks.com",
+ "data_broker_id": 6,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -321,6 +329,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://truthfinder.com",
"data_broker": "truthfinder.com",
+ "data_broker_id": 10,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -355,6 +364,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://ussearch.com",
"data_broker": "ussearch.com",
+ "data_broker_id": 12,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
@@ -393,6 +403,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://arivify.com",
"data_broker": "arivify.com",
+ "data_broker_id": 13,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -427,6 +438,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://beenverified.com",
"data_broker": "beenverified.com",
+ "data_broker_id": 1,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -461,6 +473,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://instantcheckmate.com",
"data_broker": "instantcheckmate.com",
+ "data_broker_id": 11,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -495,6 +508,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://open-public-records.com",
"data_broker": "open-public-records.com",
+ "data_broker_id": 3,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -529,6 +543,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://peoplefinders.com",
"data_broker": "peoplefinders.com",
+ "data_broker_id": 4,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -563,6 +578,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://peoplesmart.com",
"data_broker": "peoplesmart.com",
+ "data_broker_id": 2,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -597,6 +613,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://privateeye.com",
"data_broker": "privateeye.com",
+ "data_broker_id": 5,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -631,6 +648,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://smartbackgroundchecks.com",
"data_broker": "smartbackgroundchecks.com",
+ "data_broker_id": 6,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -665,6 +683,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://truthfinder.com",
"data_broker": "truthfinder.com",
+ "data_broker_id": 10,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
@@ -699,6 +718,7 @@
"relatives": ["John Smith", "Bob Smith", "Amy Smith"],
"link": "https://ussearch.com",
"data_broker": "ussearch.com",
+ "data_broker_id": 12,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
index 464361a26f0..fbfce58dfb5 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/route.ts
@@ -3,12 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import {
- MOCK_ONEREP_TIME,
- MOCK_ONEREP_FIRSTNAME,
- MOCK_ONEREP_LASTNAME,
- MOCK_ONEREP_BIRTHDATE,
- MOCK_ONEREP_ADDRESSES,
- MOCK_ONEREP_PROFILE_STATUS,
+ mockOnerepTime,
+ mockOnerepFirstName,
+ mockOnerepLastName,
+ mockOnerepBirthdate,
+ mockOnerepAddresses,
+ mockOnerepProfileStatus,
} from "../../config/config.ts";
import { ShowProfileResponse } from "../../../../../functions/server/onerep.ts";
import { NextRequest, NextResponse } from "next/server";
@@ -30,13 +30,13 @@ export function GET(
const mockProfileData: ShowProfileResponse = {
id: profileId,
- first_name: MOCK_ONEREP_FIRSTNAME(),
- last_name: MOCK_ONEREP_LASTNAME(),
- birth_date: MOCK_ONEREP_BIRTHDATE(),
- addresses: MOCK_ONEREP_ADDRESSES(),
- status: MOCK_ONEREP_PROFILE_STATUS(),
- created_at: MOCK_ONEREP_TIME(),
- updated_at: MOCK_ONEREP_TIME(),
+ first_name: mockOnerepFirstName(),
+ last_name: mockOnerepLastName(),
+ birth_date: mockOnerepBirthdate(),
+ addresses: mockOnerepAddresses(),
+ status: mockOnerepProfileStatus(),
+ created_at: mockOnerepTime(),
+ updated_at: mockOnerepTime(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
};
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
index 721df9193ec..86fd39e5e02 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/[scanId]/route.ts
@@ -4,7 +4,7 @@
import { getLatestOnerepScan } from "../../../../../../../../db/tables/onerep_scans";
import { errorIfProduction } from "../../../../../../utils/errorThrower";
-import { MOCK_ONEREP_TIME } from "../../../../config/config";
+import { mockOnerepTime } from "../../../../config/config";
import { NextRequest, NextResponse } from "next/server";
export async function GET(
@@ -19,24 +19,25 @@ export async function GET(
const latestScan = await getLatestOnerepScan(profileId);
- const responseData = latestScan
- ? {
- id: latestScan.id,
- profileId: latestScan.onerep_profile_id,
- status: latestScan.onerep_scan_status,
- created_at: latestScan.created_at,
- updated_at: latestScan.updated_at,
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
- }
- : {
- id: scanId,
- profile_id: profileId,
- status: "finished",
- reason: "manual",
- created_at: MOCK_ONEREP_TIME(),
- updated_at: MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
- };
+ const responseData =
+ latestScan !== null
+ ? {
+ id: latestScan.id,
+ profileId: latestScan.onerep_profile_id,
+ status: latestScan.onerep_scan_status,
+ created_at: latestScan.created_at,
+ updated_at: latestScan.updated_at,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
+ }
+ : {
+ id: scanId,
+ profile_id: profileId,
+ status: "finished",
+ reason: "manual",
+ created_at: mockOnerepTime(),
+ updated_at: mockOnerepTime(),
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
+ };
return NextResponse.json(responseData);
}
diff --git a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
index eb1928e7878..188ab4011c9 100644
--- a/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
+++ b/src/app/api/mock/onerep/profiles/[profileId]/scans/route.ts
@@ -4,10 +4,10 @@
import { NextRequest, NextResponse } from "next/server";
import {
- MOCK_ONEREP_OBJECT_LINKS,
- MOCK_ONEREP_OBJECT_META,
- MOCK_ONEREP_SCAN_ID,
- MOCK_ONEREP_TIME,
+ mockOnerepObjectLinks,
+ mockOnerepObjectMeta,
+ mockOnerepScanId,
+ mockOnerepTime,
} from "../../../config/config";
import { errorIfProduction } from "../../../../../utils/errorThrower";
import {
@@ -15,7 +15,7 @@ import {
getLatestOnerepScan,
} from "../../../../../../../db/tables/onerep_scans";
import {
- computeSha1First6,
+ emailHashPrefix,
hashToEmailKeyMap,
} from "../../../../../utils/mockUtils";
import mockUser from "../../../mockData/mockUser.json";
@@ -59,15 +59,15 @@ export async function POST(
const latestScan = await getLatestOnerepScan(profileId);
if (latestScan) return NextResponse.json([latestScan]);
- const mockScanId = MOCK_ONEREP_SCAN_ID(profileId);
+ const mockScanId = mockOnerepScanId(profileId);
const mockResponse = {
id: mockScanId,
profile_id: profileId,
status: "finished",
reason: "manual",
- created_at: MOCK_ONEREP_TIME(),
- updated_at: MOCK_ONEREP_TIME(),
+ created_at: mockOnerepTime(),
+ updated_at: mockOnerepTime(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${mockScanId}`,
} as MockScan;
@@ -87,43 +87,45 @@ export async function GET(
return NextResponse.json({ error: "Invalid profile ID" });
}
- const scanId = MOCK_ONEREP_SCAN_ID(profileId);
- const links = MOCK_ONEREP_OBJECT_LINKS(profileId);
- const meta = MOCK_ONEREP_OBJECT_META(profileId);
+ const scanId = mockOnerepScanId(profileId);
+ const links = mockOnerepObjectLinks(profileId);
+ const meta = mockOnerepObjectMeta(profileId);
const email = await getEmailForProfile(profileId);
if (!email)
return NextResponse.json({ error: "No email for this ID is found" });
- const emailHash = computeSha1First6(email);
+ const emailHash = emailHashPrefix(email);
const dataKey = hashToEmailKeyMap[emailHash] || "default";
- const data = mockScans[dataKey];
+ const dataLookup = mockScans[dataKey];
+ const data = dataLookup === undefined ? mockScans["default"] : dataLookup;
const latestScan = await getLatestOnerepScan(profileId);
const responseData = {
- data: latestScan
- ? [
- {
- id: latestScan.onerep_scan_id,
- profileId: latestScan.onerep_profile_id,
- status: latestScan.onerep_scan_status,
- created_at: latestScan.created_at,
- updated_at: latestScan.updated_at,
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${latestScan.onerep_scan_id}`,
- },
- ]
- : data.map(
- (scan) =>
- ({
- id: scanId,
- profile_id: profileId,
- status: scan.status || "finished",
- reason: scan.reason || "manual",
- created_at: scan.created_at || MOCK_ONEREP_TIME(),
- updated_at: scan.updated_at || MOCK_ONEREP_TIME(),
- url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
- }) as MockScan,
- ),
+ data:
+ latestScan !== null
+ ? [
+ {
+ id: latestScan.onerep_scan_id,
+ profileId: latestScan.onerep_profile_id,
+ status: latestScan.onerep_scan_status,
+ created_at: latestScan.created_at,
+ updated_at: latestScan.updated_at,
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${latestScan.onerep_scan_id}`,
+ },
+ ]
+ : data.map(
+ (scan) =>
+ ({
+ id: scanId,
+ profile_id: profileId,
+ status: scan.status || "finished",
+ reason: scan.reason || "manual",
+ created_at: scan.created_at || mockOnerepTime(),
+ updated_at: scan.updated_at || mockOnerepTime(),
+ url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/scans/${scanId}`,
+ }) as MockScan,
+ ),
links: links,
meta: meta,
};
diff --git a/src/app/api/mock/onerep/profiles/route.ts b/src/app/api/mock/onerep/profiles/route.ts
index 8a4f0951492..c2016125be6 100644
--- a/src/app/api/mock/onerep/profiles/route.ts
+++ b/src/app/api/mock/onerep/profiles/route.ts
@@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import {
- MOCK_ONEREP_PROFILE_STATUS,
- MOCK_ONEREP_TIME,
+ mockOnerepProfileStatus,
+ mockOnerepTime,
profileIdLeftBound,
profileIdRightBound,
} from "../config/config.ts";
@@ -78,13 +78,13 @@ export async function POST(req: NextRequest) {
city: addr.city,
address_line: null,
zip: null,
- created_at: MOCK_ONEREP_TIME(),
- updated_at: MOCK_ONEREP_TIME(),
+ created_at: mockOnerepTime(),
+ updated_at: mockOnerepTime(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}/addresses/${profileId + index}`,
})),
- status: MOCK_ONEREP_PROFILE_STATUS(),
- created_at: MOCK_ONEREP_TIME(),
- updated_at: MOCK_ONEREP_TIME(),
+ status: mockOnerepProfileStatus(),
+ created_at: mockOnerepTime(),
+ updated_at: mockOnerepTime(),
url: `${process.env.ONEREP_API_BASE}/profiles/${profileId}`,
};
return NextResponse.json(responseProfile, { status: 201 });
diff --git a/src/app/api/mock/onerep/scan-results/route.ts b/src/app/api/mock/onerep/scan-results/route.ts
index 1774819ed98..c372df2bbe1 100644
--- a/src/app/api/mock/onerep/scan-results/route.ts
+++ b/src/app/api/mock/onerep/scan-results/route.ts
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { errorIfProduction } from "../../../utils/errorThrower";
-import { MOCK_ONEREP_BROKERS } from "../config/config";
+import { mockOnerepBrokers } from "../config/config";
import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest) {
@@ -22,12 +22,7 @@ export async function GET(req: NextRequest) {
);
}
- const res = await MOCK_ONEREP_BROKERS(
- Number(profileId),
- page,
- perPage,
- email,
- );
+ const res = await mockOnerepBrokers(Number(profileId), page, perPage, email);
return NextResponse.json(res);
}
diff --git a/src/app/api/utils/errorThrower.ts b/src/app/api/utils/errorThrower.ts
index 1fbcbbc34ea..ba00ecf3bb9 100644
--- a/src/app/api/utils/errorThrower.ts
+++ b/src/app/api/utils/errorThrower.ts
@@ -6,33 +6,31 @@ import { NextResponse } from "next/server";
export function errorIfProduction() {
//checks that the environment isnt production
- return errorIfEnvCond("production", false);
+ if (process.env.APP_ENV === "production") {
+ return error403("Endpoint not available in prod environment");
+ }
+ return null;
}
export function errorIfStage() {
//checks that the environment isnt stage
- return errorIfEnvCond("stage", false);
+ if (process.env.APP_ENV === "stage") {
+ return error403("Endpoint not available in stage environment");
+ }
+ return null;
}
export function errorIfNotLocal() {
- return errorIfEnvCond("local", true);
-}
-
-export function errorIfNotENv(which: string) {
- return errorIfEnvCond(which, true);
-}
-
-export function errorIfEnvCond(which: string, isEqualToWhich: boolean) {
- //checks that the app environment satisfies the 'isEqualToWhich' condition with 'which'
- if (isEqualToWhich !== (process.env.APP_ENV === which)) {
- return NextResponse.json(
- { error: `Endpoint not available in ${which} environment` },
- { status: 403 },
- );
+ if (process.env.APP_ENV !== "local") {
+ return error403("Endpoint not available in non-local environment");
}
return null;
}
+function error403(msg: string) {
+ return NextResponse.json({ error: msg }, { status: 403 });
+}
+
export function unauthError() {
return NextResponse.json(
{ error: "Unauthorized to access the endpoint" },
@@ -45,6 +43,6 @@ export function internalServerError(
) {
return NextResponse.json(
{ error: `Internal server error: ${description}` },
- { status: 401 },
+ { status: 500 },
);
}
diff --git a/src/app/api/utils/mockUtils.ts b/src/app/api/utils/mockUtils.ts
index 69c19b93396..b8842633dfb 100644
--- a/src/app/api/utils/mockUtils.ts
+++ b/src/app/api/utils/mockUtils.ts
@@ -6,7 +6,7 @@ import { BinaryLike } from "crypto";
import { getSha1 } from "../../../utils/fxa";
import { logger } from "../../functions/server/logging";
-export function computeSha1First6(email: string) {
+export function emailHashPrefix(email: string) {
return getSha1(email as BinaryLike)
.slice(0, 6)
.toUpperCase();
@@ -25,7 +25,7 @@ export const allE2ETestEmailKeys = (() => {
export const hashToEmailKeyMap = (() => {
const mapping: { [key: string]: string } = {};
allE2ETestEmailKeys.forEach((key) => {
- mapping[computeSha1First6(process.env[key] as string)] = key;
+ mapping[emailHashPrefix(process.env[key] as string)] = key;
});
return mapping;
})();
diff --git a/src/app/functions/server/onerep.ts b/src/app/functions/server/onerep.ts
index f7cc8f1b80a..ddb8eb9edaf 100644
--- a/src/app/functions/server/onerep.ts
+++ b/src/app/functions/server/onerep.ts
@@ -16,7 +16,7 @@ import {
} from "../../../db/tables/onerep_scans";
import { RemovalStatus } from "../universal/scanResult.js";
import { logger } from "./logging";
-import { isUsingMockONEREPndpoint } from "../universal/mock.ts";
+import { isUsingMockONEREPEndpoint } from "../universal/mock.ts";
export const monthlyScansQuota = parseInt(
(process.env.MONTHLY_SCANS_QUOTA as string) ?? "0",
@@ -334,7 +334,7 @@ export async function listScanResults(
}> = {},
): Promise {
let mockEmail = "";
- if (isUsingMockONEREPndpoint()) {
+ if (isUsingMockONEREPEndpoint()) {
mockEmail = (await getEmailForProfile(profileId)) || mockEmail;
}
const queryParams = new URLSearchParams({
diff --git a/src/app/functions/universal/mock.ts b/src/app/functions/universal/mock.ts
index 46db7685223..9b610658505 100644
--- a/src/app/functions/universal/mock.ts
+++ b/src/app/functions/universal/mock.ts
@@ -6,7 +6,7 @@ export function isUsingMockHIBPEndpoint() {
return process.env.HIBP_KANON_API_ROOT?.includes("api/mock") as boolean;
}
-export function isUsingMockONEREPndpoint() {
+export function isUsingMockONEREPEndpoint() {
return process.env.ONEREP_API_BASE?.includes("api/mock") as boolean;
}
From c05d519bde1f7bbc0c7a07158da25d540b29cd6e Mon Sep 17 00:00:00 2001
From: Florian Zia
Date: Thu, 18 Jul 2024 15:36:53 +0200
Subject: [PATCH 100/137] chore: Add ctaButton view event
---
.../(redesign)/(public)/SignUpForm.tsx | 3 ++-
src/app/hooks/useViewTelemetry.ts | 5 +++--
src/telemetry/metrics.yaml | 18 ++++++++----------
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx b/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
index cb02d4c31f0..c3efb8b3b5f 100644
--- a/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
+++ b/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
@@ -38,8 +38,9 @@ export const SignUpForm = (props: Props) => {
const record = useTelemetry();
const { view } = props.eventId;
const refViewTelemetry = useViewTelemetry(
+ "ctaButton",
{
- element_id: view,
+ button_id: view,
},
{
skip: typeof view === "undefined",
diff --git a/src/app/hooks/useViewTelemetry.ts b/src/app/hooks/useViewTelemetry.ts
index 49c8528c5c8..863785c12db 100644
--- a/src/app/hooks/useViewTelemetry.ts
+++ b/src/app/hooks/useViewTelemetry.ts
@@ -7,9 +7,10 @@ import { TelemetryArgs, useTelemetry } from "./useTelemetry";
import { GleanMetricMap } from "../../telemetry/generated/_map";
export function useViewTelemetry<
- EventModule extends "view",
+ EventModule extends keyof Pick,
EventName extends keyof GleanMetricMap[EventModule],
>(
+ eventModule: EventModule,
args: TelemetryArgs & GleanMetricMap[EventModule][EventName],
options?: IntersectionOptions,
) {
@@ -24,7 +25,7 @@ export function useViewTelemetry<
if (!inView) {
return;
}
- recordTelemetry("view", "enter", telemetryArgs);
+ recordTelemetry(eventModule, "view", telemetryArgs);
},
});
diff --git a/src/telemetry/metrics.yaml b/src/telemetry/metrics.yaml
index b4e52c276c9..37d1cd582c1 100644
--- a/src/telemetry/metrics.yaml
+++ b/src/telemetry/metrics.yaml
@@ -396,11 +396,11 @@ collapse:
description: Which tier of plan the user is on [Free, Plus]
type: string
-view:
- enter:
+cta_button:
+ click:
type: event
description: |
- A DOM element entered the viewport.
+ A click on a button that has a specific call-to-action.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1823766
data_reviews:
@@ -423,18 +423,16 @@ view:
flow_id:
description: A randomly generated unique identifier for following user flows within the FxA system.
type: string
- element_id:
- description: The ID of the element that entered the viewport, or some way to identify where on the viewport the element is located.
- type: string
+ button_id:
+ description: The ID of the button that was clicked on, or some way to identify where on the page the interaction is located.
plan_tier:
description: Which tier of plan the user is on [Free, Plus]
type: string
-cta_button:
- click:
+ view:
type: event
description: |
- A click on a button that has a specific call-to-action.
+ A button that has a specific call-to-action entered the viewport.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1823766
data_reviews:
@@ -458,7 +456,7 @@ cta_button:
description: A randomly generated unique identifier for following user flows within the FxA system.
type: string
button_id:
- description: The ID of the button that was clicked on, or some way to identify where on the page the interaction is located.
+ description: The ID of the button that entered the viewport, or some way to identify where on the page the interaction is located.
plan_tier:
description: Which tier of plan the user is on [Free, Plus]
type: string
From 85adb1547a830a748f6964705295b11367f77c67 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 18 Jul 2024 14:52:10 +0000
Subject: [PATCH 101/137] chore(deps): bump the aws-sdk group across 1
directory with 2 updates
Bumps the aws-sdk group with 2 updates in the / directory: [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) and [@aws-sdk/lib-storage](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/lib/lib-storage).
Updates `@aws-sdk/client-s3` from 3.606.0 to 3.614.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.614.0/clients/client-s3)
Updates `@aws-sdk/lib-storage` from 3.606.0 to 3.614.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/lib/lib-storage/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.614.0/lib/lib-storage)
---
updated-dependencies:
- dependency-name: "@aws-sdk/client-s3"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: aws-sdk
- dependency-name: "@aws-sdk/lib-storage"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: aws-sdk
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 984 +++++++++++++++++++++++-----------------------
package.json | 4 +-
2 files changed, 494 insertions(+), 494 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 3a89ec6e4bb..f66cd9dc370 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,8 +9,8 @@
"version": "1.0.0",
"license": "MPL-2.0",
"dependencies": {
- "@aws-sdk/client-s3": "^3.606.0",
- "@aws-sdk/lib-storage": "^3.606.0",
+ "@aws-sdk/client-s3": "^3.614.0",
+ "@aws-sdk/lib-storage": "^3.614.0",
"@fluent/bundle": "^0.18.0",
"@fluent/langneg": "^0.7.0",
"@fluent/react": "^0.15.2",
@@ -322,67 +322,67 @@
}
},
"node_modules/@aws-sdk/client-s3": {
- "version": "3.606.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.606.0.tgz",
- "integrity": "sha512-IGM/E8kVk/NY/kZwLdmGRsX1QYtuPljoNutM5kBRdtGahQL5VwVAve5PElPUArcsTkfTyW+LfXpznDeeHxMCcA==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.614.0.tgz",
+ "integrity": "sha512-9BlhfeBegvyjOqHtcr9kvrT80wiy7EVUiqYyTFiiDv/hJIcG88XHQCZdLU7658XBkQ7aFrr5b8rF2HRD1oroxw==",
"dependencies": {
"@aws-crypto/sha1-browser": "5.2.0",
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/client-sso-oidc": "3.606.0",
- "@aws-sdk/client-sts": "3.606.0",
- "@aws-sdk/core": "3.598.0",
- "@aws-sdk/credential-provider-node": "3.600.0",
- "@aws-sdk/middleware-bucket-endpoint": "3.598.0",
- "@aws-sdk/middleware-expect-continue": "3.598.0",
- "@aws-sdk/middleware-flexible-checksums": "3.598.0",
- "@aws-sdk/middleware-host-header": "3.598.0",
- "@aws-sdk/middleware-location-constraint": "3.598.0",
- "@aws-sdk/middleware-logger": "3.598.0",
- "@aws-sdk/middleware-recursion-detection": "3.598.0",
- "@aws-sdk/middleware-sdk-s3": "3.598.0",
- "@aws-sdk/middleware-signing": "3.598.0",
- "@aws-sdk/middleware-ssec": "3.598.0",
- "@aws-sdk/middleware-user-agent": "3.598.0",
- "@aws-sdk/region-config-resolver": "3.598.0",
- "@aws-sdk/signature-v4-multi-region": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@aws-sdk/util-endpoints": "3.598.0",
- "@aws-sdk/util-user-agent-browser": "3.598.0",
- "@aws-sdk/util-user-agent-node": "3.598.0",
- "@aws-sdk/xml-builder": "3.598.0",
- "@smithy/config-resolver": "^3.0.2",
- "@smithy/core": "^2.2.1",
- "@smithy/eventstream-serde-browser": "^3.0.2",
- "@smithy/eventstream-serde-config-resolver": "^3.0.1",
- "@smithy/eventstream-serde-node": "^3.0.2",
- "@smithy/fetch-http-handler": "^3.0.2",
- "@smithy/hash-blob-browser": "^3.1.0",
- "@smithy/hash-node": "^3.0.1",
- "@smithy/hash-stream-node": "^3.1.0",
- "@smithy/invalid-dependency": "^3.0.1",
- "@smithy/md5-js": "^3.0.1",
- "@smithy/middleware-content-length": "^3.0.1",
- "@smithy/middleware-endpoint": "^3.0.2",
- "@smithy/middleware-retry": "^3.0.4",
- "@smithy/middleware-serde": "^3.0.1",
- "@smithy/middleware-stack": "^3.0.1",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/node-http-handler": "^3.0.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/smithy-client": "^3.1.2",
- "@smithy/types": "^3.1.0",
- "@smithy/url-parser": "^3.0.1",
+ "@aws-sdk/client-sso-oidc": "3.614.0",
+ "@aws-sdk/client-sts": "3.614.0",
+ "@aws-sdk/core": "3.614.0",
+ "@aws-sdk/credential-provider-node": "3.614.0",
+ "@aws-sdk/middleware-bucket-endpoint": "3.614.0",
+ "@aws-sdk/middleware-expect-continue": "3.609.0",
+ "@aws-sdk/middleware-flexible-checksums": "3.614.0",
+ "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/middleware-location-constraint": "3.609.0",
+ "@aws-sdk/middleware-logger": "3.609.0",
+ "@aws-sdk/middleware-recursion-detection": "3.609.0",
+ "@aws-sdk/middleware-sdk-s3": "3.614.0",
+ "@aws-sdk/middleware-signing": "3.609.0",
+ "@aws-sdk/middleware-ssec": "3.609.0",
+ "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/region-config-resolver": "3.614.0",
+ "@aws-sdk/signature-v4-multi-region": "3.614.0",
+ "@aws-sdk/types": "3.609.0",
+ "@aws-sdk/util-endpoints": "3.614.0",
+ "@aws-sdk/util-user-agent-browser": "3.609.0",
+ "@aws-sdk/util-user-agent-node": "3.614.0",
+ "@aws-sdk/xml-builder": "3.609.0",
+ "@smithy/config-resolver": "^3.0.5",
+ "@smithy/core": "^2.2.6",
+ "@smithy/eventstream-serde-browser": "^3.0.4",
+ "@smithy/eventstream-serde-config-resolver": "^3.0.3",
+ "@smithy/eventstream-serde-node": "^3.0.4",
+ "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/hash-blob-browser": "^3.1.2",
+ "@smithy/hash-node": "^3.0.3",
+ "@smithy/hash-stream-node": "^3.1.2",
+ "@smithy/invalid-dependency": "^3.0.3",
+ "@smithy/md5-js": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-endpoint": "^3.0.5",
+ "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-serde": "^3.0.3",
+ "@smithy/middleware-stack": "^3.0.3",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/node-http-handler": "^3.1.2",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/smithy-client": "^3.1.7",
+ "@smithy/types": "^3.3.0",
+ "@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.4",
- "@smithy/util-defaults-mode-node": "^3.0.4",
- "@smithy/util-endpoints": "^2.0.2",
- "@smithy/util-retry": "^3.0.1",
- "@smithy/util-stream": "^3.0.2",
+ "@smithy/util-defaults-mode-browser": "^3.0.9",
+ "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-endpoints": "^2.0.5",
+ "@smithy/util-retry": "^3.0.3",
+ "@smithy/util-stream": "^3.0.6",
"@smithy/util-utf8": "^3.0.0",
- "@smithy/util-waiter": "^3.0.1",
+ "@smithy/util-waiter": "^3.1.2",
"tslib": "^2.6.2"
},
"engines": {
@@ -390,46 +390,46 @@
}
},
"node_modules/@aws-sdk/client-sso": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.598.0.tgz",
- "integrity": "sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.614.0.tgz",
+ "integrity": "sha512-p5pyYaxRzBttjBkqfc8i3K7DzBdTg3ECdVgBo6INIUxfvDy0J8QUE8vNtCgvFIkq+uPw/8M+Eo4zzln7anuO0Q==",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "3.598.0",
- "@aws-sdk/middleware-host-header": "3.598.0",
- "@aws-sdk/middleware-logger": "3.598.0",
- "@aws-sdk/middleware-recursion-detection": "3.598.0",
- "@aws-sdk/middleware-user-agent": "3.598.0",
- "@aws-sdk/region-config-resolver": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@aws-sdk/util-endpoints": "3.598.0",
- "@aws-sdk/util-user-agent-browser": "3.598.0",
- "@aws-sdk/util-user-agent-node": "3.598.0",
- "@smithy/config-resolver": "^3.0.2",
- "@smithy/core": "^2.2.1",
- "@smithy/fetch-http-handler": "^3.0.2",
- "@smithy/hash-node": "^3.0.1",
- "@smithy/invalid-dependency": "^3.0.1",
- "@smithy/middleware-content-length": "^3.0.1",
- "@smithy/middleware-endpoint": "^3.0.2",
- "@smithy/middleware-retry": "^3.0.4",
- "@smithy/middleware-serde": "^3.0.1",
- "@smithy/middleware-stack": "^3.0.1",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/node-http-handler": "^3.0.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/smithy-client": "^3.1.2",
- "@smithy/types": "^3.1.0",
- "@smithy/url-parser": "^3.0.1",
+ "@aws-sdk/core": "3.614.0",
+ "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/middleware-logger": "3.609.0",
+ "@aws-sdk/middleware-recursion-detection": "3.609.0",
+ "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/region-config-resolver": "3.614.0",
+ "@aws-sdk/types": "3.609.0",
+ "@aws-sdk/util-endpoints": "3.614.0",
+ "@aws-sdk/util-user-agent-browser": "3.609.0",
+ "@aws-sdk/util-user-agent-node": "3.614.0",
+ "@smithy/config-resolver": "^3.0.5",
+ "@smithy/core": "^2.2.6",
+ "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/hash-node": "^3.0.3",
+ "@smithy/invalid-dependency": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-endpoint": "^3.0.5",
+ "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-serde": "^3.0.3",
+ "@smithy/middleware-stack": "^3.0.3",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/node-http-handler": "^3.1.2",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/smithy-client": "^3.1.7",
+ "@smithy/types": "^3.3.0",
+ "@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.4",
- "@smithy/util-defaults-mode-node": "^3.0.4",
- "@smithy/util-endpoints": "^2.0.2",
- "@smithy/util-middleware": "^3.0.1",
- "@smithy/util-retry": "^3.0.1",
+ "@smithy/util-defaults-mode-browser": "^3.0.9",
+ "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-endpoints": "^2.0.5",
+ "@smithy/util-middleware": "^3.0.3",
+ "@smithy/util-retry": "^3.0.3",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
},
@@ -438,47 +438,47 @@
}
},
"node_modules/@aws-sdk/client-sso-oidc": {
- "version": "3.606.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.606.0.tgz",
- "integrity": "sha512-gL1FHPS6hwgMNS/A+Qh5bUyHOeRVOqdb7c6+i+9gR3wtGvt2lvoSm8w5DhS08Xiiacz2AqYRDEapp0xuyCrbBQ==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.614.0.tgz",
+ "integrity": "sha512-BI1NWcpppbHg/28zbUg54dZeckork8BItZIcjls12vxasy+p3iEzrJVG60jcbUTTsk3Qc1tyxNfrdcVqx0y7Ww==",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "3.598.0",
- "@aws-sdk/credential-provider-node": "3.600.0",
- "@aws-sdk/middleware-host-header": "3.598.0",
- "@aws-sdk/middleware-logger": "3.598.0",
- "@aws-sdk/middleware-recursion-detection": "3.598.0",
- "@aws-sdk/middleware-user-agent": "3.598.0",
- "@aws-sdk/region-config-resolver": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@aws-sdk/util-endpoints": "3.598.0",
- "@aws-sdk/util-user-agent-browser": "3.598.0",
- "@aws-sdk/util-user-agent-node": "3.598.0",
- "@smithy/config-resolver": "^3.0.2",
- "@smithy/core": "^2.2.1",
- "@smithy/fetch-http-handler": "^3.0.2",
- "@smithy/hash-node": "^3.0.1",
- "@smithy/invalid-dependency": "^3.0.1",
- "@smithy/middleware-content-length": "^3.0.1",
- "@smithy/middleware-endpoint": "^3.0.2",
- "@smithy/middleware-retry": "^3.0.4",
- "@smithy/middleware-serde": "^3.0.1",
- "@smithy/middleware-stack": "^3.0.1",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/node-http-handler": "^3.0.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/smithy-client": "^3.1.2",
- "@smithy/types": "^3.1.0",
- "@smithy/url-parser": "^3.0.1",
+ "@aws-sdk/core": "3.614.0",
+ "@aws-sdk/credential-provider-node": "3.614.0",
+ "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/middleware-logger": "3.609.0",
+ "@aws-sdk/middleware-recursion-detection": "3.609.0",
+ "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/region-config-resolver": "3.614.0",
+ "@aws-sdk/types": "3.609.0",
+ "@aws-sdk/util-endpoints": "3.614.0",
+ "@aws-sdk/util-user-agent-browser": "3.609.0",
+ "@aws-sdk/util-user-agent-node": "3.614.0",
+ "@smithy/config-resolver": "^3.0.5",
+ "@smithy/core": "^2.2.6",
+ "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/hash-node": "^3.0.3",
+ "@smithy/invalid-dependency": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-endpoint": "^3.0.5",
+ "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-serde": "^3.0.3",
+ "@smithy/middleware-stack": "^3.0.3",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/node-http-handler": "^3.1.2",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/smithy-client": "^3.1.7",
+ "@smithy/types": "^3.3.0",
+ "@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.4",
- "@smithy/util-defaults-mode-node": "^3.0.4",
- "@smithy/util-endpoints": "^2.0.2",
- "@smithy/util-middleware": "^3.0.1",
- "@smithy/util-retry": "^3.0.1",
+ "@smithy/util-defaults-mode-browser": "^3.0.9",
+ "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-endpoints": "^2.0.5",
+ "@smithy/util-middleware": "^3.0.3",
+ "@smithy/util-retry": "^3.0.3",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
},
@@ -486,52 +486,52 @@
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-sts": "^3.606.0"
+ "@aws-sdk/client-sts": "^3.614.0"
}
},
"node_modules/@aws-sdk/client-sts": {
- "version": "3.606.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.606.0.tgz",
- "integrity": "sha512-b11mAhjrkm3MMiAPoMGcmd6vsaz2120lg8rHG/NZCo9vB1K6Kc7WP+a1Q05TRMseer2egTtpWJfn44aVO97VqA==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.614.0.tgz",
+ "integrity": "sha512-i6QmaVA1KHHYNnI2VYQy/sc31rLm4+jSp8b/YbQpFnD0w3aXsrEEHHlxek45uSkHb4Nrj1omFBVy/xp1WVYx2Q==",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/client-sso-oidc": "3.606.0",
- "@aws-sdk/core": "3.598.0",
- "@aws-sdk/credential-provider-node": "3.600.0",
- "@aws-sdk/middleware-host-header": "3.598.0",
- "@aws-sdk/middleware-logger": "3.598.0",
- "@aws-sdk/middleware-recursion-detection": "3.598.0",
- "@aws-sdk/middleware-user-agent": "3.598.0",
- "@aws-sdk/region-config-resolver": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@aws-sdk/util-endpoints": "3.598.0",
- "@aws-sdk/util-user-agent-browser": "3.598.0",
- "@aws-sdk/util-user-agent-node": "3.598.0",
- "@smithy/config-resolver": "^3.0.2",
- "@smithy/core": "^2.2.1",
- "@smithy/fetch-http-handler": "^3.0.2",
- "@smithy/hash-node": "^3.0.1",
- "@smithy/invalid-dependency": "^3.0.1",
- "@smithy/middleware-content-length": "^3.0.1",
- "@smithy/middleware-endpoint": "^3.0.2",
- "@smithy/middleware-retry": "^3.0.4",
- "@smithy/middleware-serde": "^3.0.1",
- "@smithy/middleware-stack": "^3.0.1",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/node-http-handler": "^3.0.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/smithy-client": "^3.1.2",
- "@smithy/types": "^3.1.0",
- "@smithy/url-parser": "^3.0.1",
+ "@aws-sdk/client-sso-oidc": "3.614.0",
+ "@aws-sdk/core": "3.614.0",
+ "@aws-sdk/credential-provider-node": "3.614.0",
+ "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/middleware-logger": "3.609.0",
+ "@aws-sdk/middleware-recursion-detection": "3.609.0",
+ "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/region-config-resolver": "3.614.0",
+ "@aws-sdk/types": "3.609.0",
+ "@aws-sdk/util-endpoints": "3.614.0",
+ "@aws-sdk/util-user-agent-browser": "3.609.0",
+ "@aws-sdk/util-user-agent-node": "3.614.0",
+ "@smithy/config-resolver": "^3.0.5",
+ "@smithy/core": "^2.2.6",
+ "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/hash-node": "^3.0.3",
+ "@smithy/invalid-dependency": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-endpoint": "^3.0.5",
+ "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-serde": "^3.0.3",
+ "@smithy/middleware-stack": "^3.0.3",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/node-http-handler": "^3.1.2",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/smithy-client": "^3.1.7",
+ "@smithy/types": "^3.3.0",
+ "@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.4",
- "@smithy/util-defaults-mode-node": "^3.0.4",
- "@smithy/util-endpoints": "^2.0.2",
- "@smithy/util-middleware": "^3.0.1",
- "@smithy/util-retry": "^3.0.1",
+ "@smithy/util-defaults-mode-browser": "^3.0.9",
+ "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-endpoints": "^2.0.5",
+ "@smithy/util-middleware": "^3.0.3",
+ "@smithy/util-retry": "^3.0.3",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
},
@@ -540,15 +540,15 @@
}
},
"node_modules/@aws-sdk/core": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.598.0.tgz",
- "integrity": "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g==",
- "dependencies": {
- "@smithy/core": "^2.2.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/signature-v4": "^3.1.0",
- "@smithy/smithy-client": "^3.1.2",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.614.0.tgz",
+ "integrity": "sha512-BUuS5/1YkgmKc4J0bg83XEtMyDHVyqG2QDzfmhYe8gbOIZabUl1FlrFVwhCAthtrrI6MPGTQcERB4BtJKUSplw==",
+ "dependencies": {
+ "@smithy/core": "^2.2.6",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/signature-v4": "^3.1.2",
+ "@smithy/smithy-client": "^3.1.7",
+ "@smithy/types": "^3.3.0",
"fast-xml-parser": "4.2.5",
"tslib": "^2.6.2"
},
@@ -557,13 +557,13 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.598.0.tgz",
- "integrity": "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.609.0.tgz",
+ "integrity": "sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -571,18 +571,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.598.0.tgz",
- "integrity": "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g==",
- "dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/fetch-http-handler": "^3.0.2",
- "@smithy/node-http-handler": "^3.0.1",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/smithy-client": "^3.1.2",
- "@smithy/types": "^3.1.0",
- "@smithy/util-stream": "^3.0.2",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.614.0.tgz",
+ "integrity": "sha512-YIEjlNUKb3Vo/iTnGAPdsiDC3FUUnNoex2OwU8LmR7AkYZiWdB8nx99DfgkkY+OFMUpw7nKD2PCOtuFONelfGA==",
+ "dependencies": {
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/node-http-handler": "^3.1.2",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/smithy-client": "^3.1.7",
+ "@smithy/types": "^3.3.0",
+ "@smithy/util-stream": "^3.0.6",
"tslib": "^2.6.2"
},
"engines": {
@@ -590,45 +590,45 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.598.0.tgz",
- "integrity": "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA==",
- "dependencies": {
- "@aws-sdk/credential-provider-env": "3.598.0",
- "@aws-sdk/credential-provider-http": "3.598.0",
- "@aws-sdk/credential-provider-process": "3.598.0",
- "@aws-sdk/credential-provider-sso": "3.598.0",
- "@aws-sdk/credential-provider-web-identity": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@smithy/credential-provider-imds": "^3.1.1",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/shared-ini-file-loader": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.614.0.tgz",
+ "integrity": "sha512-KfLuLFGwlvFSZ2MuzYwWGPb1y5TeiwX5okIDe0aQ1h10oD3924FXbN+mabOnUHQ8EFcGAtCaWbrC86mI7ktC6A==",
+ "dependencies": {
+ "@aws-sdk/credential-provider-env": "3.609.0",
+ "@aws-sdk/credential-provider-http": "3.614.0",
+ "@aws-sdk/credential-provider-process": "3.614.0",
+ "@aws-sdk/credential-provider-sso": "3.614.0",
+ "@aws-sdk/credential-provider-web-identity": "3.609.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/credential-provider-imds": "^3.1.4",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/shared-ini-file-loader": "^3.1.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-sts": "^3.598.0"
+ "@aws-sdk/client-sts": "^3.614.0"
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.600.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.600.0.tgz",
- "integrity": "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw==",
- "dependencies": {
- "@aws-sdk/credential-provider-env": "3.598.0",
- "@aws-sdk/credential-provider-http": "3.598.0",
- "@aws-sdk/credential-provider-ini": "3.598.0",
- "@aws-sdk/credential-provider-process": "3.598.0",
- "@aws-sdk/credential-provider-sso": "3.598.0",
- "@aws-sdk/credential-provider-web-identity": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@smithy/credential-provider-imds": "^3.1.1",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/shared-ini-file-loader": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.614.0.tgz",
+ "integrity": "sha512-4J6gPEuFZP0mkWq5E//oMS1vrmMM88iNNcv7TEljYnsc6JTAlKejCyFwx6CN+nkIhmIZsl06SXIhBemzBdBPfg==",
+ "dependencies": {
+ "@aws-sdk/credential-provider-env": "3.609.0",
+ "@aws-sdk/credential-provider-http": "3.614.0",
+ "@aws-sdk/credential-provider-ini": "3.614.0",
+ "@aws-sdk/credential-provider-process": "3.614.0",
+ "@aws-sdk/credential-provider-sso": "3.614.0",
+ "@aws-sdk/credential-provider-web-identity": "3.609.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/credential-provider-imds": "^3.1.4",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/shared-ini-file-loader": "^3.1.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -636,14 +636,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.598.0.tgz",
- "integrity": "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA==",
- "dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/shared-ini-file-loader": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.614.0.tgz",
+ "integrity": "sha512-Q0SI0sTRwi8iNODLs5+bbv8vgz8Qy2QdxbCHnPk/6Cx6LMf7i3dqmWquFbspqFRd8QiqxStrblwxrUYZi09tkA==",
+ "dependencies": {
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/shared-ini-file-loader": "^3.1.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -651,16 +651,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.598.0.tgz",
- "integrity": "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA==",
- "dependencies": {
- "@aws-sdk/client-sso": "3.598.0",
- "@aws-sdk/token-providers": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/shared-ini-file-loader": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.614.0.tgz",
+ "integrity": "sha512-55+gp0JY4451cWI1qXmVMFM0GQaBKiQpXv2P0xmd9P3qLDyeFUSEW8XPh0d2lb1ICr6x4s47ynXVdGCIv2mXMg==",
+ "dependencies": {
+ "@aws-sdk/client-sso": "3.614.0",
+ "@aws-sdk/token-providers": "3.614.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/shared-ini-file-loader": "^3.1.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -668,30 +668,30 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.598.0.tgz",
- "integrity": "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.609.0.tgz",
+ "integrity": "sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-sts": "^3.598.0"
+ "@aws-sdk/client-sts": "^3.609.0"
}
},
"node_modules/@aws-sdk/lib-storage": {
- "version": "3.606.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.606.0.tgz",
- "integrity": "sha512-SagGtmyU0Zyjq5ZA+EvccqPrJTrRNAHXE/rjk9Z2ENqtTYI2pK451sD5kLQqgNIAHNf/6U1TX7hnYz1wkInLUQ==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.614.0.tgz",
+ "integrity": "sha512-Bzni+r7pS+nRiqcmWPpB/OiQEM4GszGRp1DXpL3rKnwaeu+Qgf2w12DULxWUacIvOc4IzLsv6tpEidQ/P1zKQg==",
"dependencies": {
- "@smithy/abort-controller": "^3.0.1",
- "@smithy/middleware-endpoint": "^3.0.2",
- "@smithy/smithy-client": "^3.1.2",
+ "@smithy/abort-controller": "^3.1.1",
+ "@smithy/middleware-endpoint": "^3.0.5",
+ "@smithy/smithy-client": "^3.1.7",
"buffer": "5.6.0",
"events": "3.3.0",
"stream-browserify": "3.0.0",
@@ -701,19 +701,19 @@
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.606.0"
+ "@aws-sdk/client-s3": "^3.614.0"
}
},
"node_modules/@aws-sdk/middleware-bucket-endpoint": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.598.0.tgz",
- "integrity": "sha512-PM7BcFfGUSkmkT6+LU9TyJiB4S8yI7dfuKQDwK5ZR3P7MKaK4Uj4yyDiv0oe5xvkF6+O2+rShj+eh8YuWkOZ/Q==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.614.0.tgz",
+ "integrity": "sha512-TqEY8KcZeZ0LIxXaqG9RSSNnDHvD8RAFP4Xenwsxqnyad0Yn7LgCoFwRByelJ0t54ROYL1/ETJleWE4U4TOXdg==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
+ "@aws-sdk/types": "3.609.0",
"@aws-sdk/util-arn-parser": "3.568.0",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/types": "^3.1.0",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/types": "^3.3.0",
"@smithy/util-config-provider": "^3.0.0",
"tslib": "^2.6.2"
},
@@ -722,13 +722,13 @@
}
},
"node_modules/@aws-sdk/middleware-expect-continue": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.598.0.tgz",
- "integrity": "sha512-ZuHW18kaeHR8TQyhEOYMr8VwiIh0bMvF7J1OTqXHxDteQIavJWA3CbfZ9sgS4XGtrBZDyHJhjZKeCfLhN2rq3w==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.609.0.tgz",
+ "integrity": "sha512-+zeg//mSer4JZRxOB/4mUOMUJyuYPwATnIC5moBB8P8Xe+mJaVRFy8qlCtzYNj2TycnlsBPzTK0j7P1yvDh97w==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -736,16 +736,16 @@
}
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.598.0.tgz",
- "integrity": "sha512-xukAzds0GQXvMEY9G6qt+CzwVzTx8NyKKh04O2Q+nOch6QQ8Rs+2kTRy3Z4wQmXq2pK9hlOWb5nXA7HWpmz6Ng==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.614.0.tgz",
+ "integrity": "sha512-ZLpxVXMboDeMT7p2Kdp5m1uLVKOktkZoMgLvvbe3zbrU4Ji5IU5xVE0aa4X7H28BtuODCs6SLESnPs19bhMKlA==",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
"@aws-crypto/crc32c": "5.2.0",
- "@aws-sdk/types": "3.598.0",
+ "@aws-sdk/types": "3.609.0",
"@smithy/is-array-buffer": "^3.0.0",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/types": "^3.1.0",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/types": "^3.3.0",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
},
@@ -754,13 +754,13 @@
}
},
"node_modules/@aws-sdk/middleware-host-header": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.598.0.tgz",
- "integrity": "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.609.0.tgz",
+ "integrity": "sha512-iTKfo158lc4jLDfYeZmYMIBHsn8m6zX+XB6birCSNZ/rrlzAkPbGE43CNdKfvjyWdqgLMRXF+B+OcZRvqhMXPQ==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -768,12 +768,12 @@
}
},
"node_modules/@aws-sdk/middleware-location-constraint": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.598.0.tgz",
- "integrity": "sha512-8oybQxN3F1ISOMULk7JKJz5DuAm5hCUcxMW9noWShbxTJuStNvuHf/WLUzXrf8oSITyYzIHPtf8VPlKR7I3orQ==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.609.0.tgz",
+ "integrity": "sha512-xzsdoTkszGVqGVPjUmgoP7TORiByLueMHieI1fhQL888WPdqctwAx3ES6d/bA9Q/i8jnc6hs+Fjhy8UvBTkE9A==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -781,12 +781,12 @@
}
},
"node_modules/@aws-sdk/middleware-logger": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.598.0.tgz",
- "integrity": "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz",
+ "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -794,13 +794,13 @@
}
},
"node_modules/@aws-sdk/middleware-recursion-detection": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.598.0.tgz",
- "integrity": "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.609.0.tgz",
+ "integrity": "sha512-6sewsYB7/o/nbUfA99Aa/LokM+a/u4Wpm/X2o0RxOsDtSB795ObebLJe2BxY5UssbGaWkn7LswyfvrdZNXNj1w==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -808,17 +808,17 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.598.0.tgz",
- "integrity": "sha512-5AGtLAh9wyK6ANPYfaKTqJY1IFJyePIxsEbxa7zS6REheAqyVmgJFaGu3oQ5XlxfGr5Uq59tFTRkyx26G1HkHA==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.614.0.tgz",
+ "integrity": "sha512-9fJTaiuuOfFV4FqmUEhPYzrtv7JOfYpB7q65oG3uayVH4ngWHIJkjnnX79zRhNZKdPGta+XIsnZzjEghg82ngA==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
+ "@aws-sdk/types": "3.609.0",
"@aws-sdk/util-arn-parser": "3.568.0",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/signature-v4": "^3.1.0",
- "@smithy/smithy-client": "^3.1.2",
- "@smithy/types": "^3.1.0",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/signature-v4": "^3.1.2",
+ "@smithy/smithy-client": "^3.1.7",
+ "@smithy/types": "^3.3.0",
"@smithy/util-config-provider": "^3.0.0",
"tslib": "^2.6.2"
},
@@ -827,16 +827,16 @@
}
},
"node_modules/@aws-sdk/middleware-signing": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.598.0.tgz",
- "integrity": "sha512-XKb05DYx/aBPqz6iCapsCbIl8aD8EihTuPCs51p75QsVfbQoVr4TlFfIl5AooMSITzojdAQqxt021YtvxjtxIQ==",
- "dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/signature-v4": "^3.1.0",
- "@smithy/types": "^3.1.0",
- "@smithy/util-middleware": "^3.0.1",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.609.0.tgz",
+ "integrity": "sha512-2w3dBLjQVKIajYzokO4hduq8/0hSMUYHHmIo1Kdl+MSY8uwRBt12bLL6pyreobTcRMxizvn2ph/CQ9I1ST/WGQ==",
+ "dependencies": {
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/signature-v4": "^3.1.2",
+ "@smithy/types": "^3.3.0",
+ "@smithy/util-middleware": "^3.0.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -844,12 +844,12 @@
}
},
"node_modules/@aws-sdk/middleware-ssec": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.598.0.tgz",
- "integrity": "sha512-f0p2xP8IC1uJ5e/tND1l81QxRtRFywEdnbtKCE0H6RSn4UIt2W3Dohe1qQDbnh27okF0PkNW6BJGdSAz3p7qbA==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.609.0.tgz",
+ "integrity": "sha512-GZSD1s7+JswWOTamVap79QiDaIV7byJFssBW68GYjyRS5EBjNfwA/8s+6uE6g39R3ojyTbYOmvcANoZEhSULXg==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -857,14 +857,14 @@
}
},
"node_modules/@aws-sdk/middleware-user-agent": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.598.0.tgz",
- "integrity": "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg==",
- "dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@aws-sdk/util-endpoints": "3.598.0",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.614.0.tgz",
+ "integrity": "sha512-xUxh0UPQiMTG6E31Yvu6zVYlikrIcFDKljM11CaatInzvZubGTGiX0DjpqRlfGzUNsuPc/zNrKwRP2+wypgqIw==",
+ "dependencies": {
+ "@aws-sdk/types": "3.609.0",
+ "@aws-sdk/util-endpoints": "3.614.0",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -872,15 +872,15 @@
}
},
"node_modules/@aws-sdk/region-config-resolver": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.598.0.tgz",
- "integrity": "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz",
+ "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/types": "^3.3.0",
"@smithy/util-config-provider": "^3.0.0",
- "@smithy/util-middleware": "^3.0.1",
+ "@smithy/util-middleware": "^3.0.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -888,15 +888,15 @@
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.598.0.tgz",
- "integrity": "sha512-1r/EyTrO1gSa1FirnR8V7mabr7gk+l+HkyTI0fcTSr8ucB7gmYyW6WjkY8JCz13VYHFK62usCEDS7yoJoJOzTA==",
- "dependencies": {
- "@aws-sdk/middleware-sdk-s3": "3.598.0",
- "@aws-sdk/types": "3.598.0",
- "@smithy/protocol-http": "^4.0.1",
- "@smithy/signature-v4": "^3.1.0",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.614.0.tgz",
+ "integrity": "sha512-6mW3ONW4oLzxrePznYhz7sNT9ji9Am9ufLeV722tbOVS5lArBOZ6E1oPz0uYBhisUPznWKhcLRMggt7vIJWMng==",
+ "dependencies": {
+ "@aws-sdk/middleware-sdk-s3": "3.614.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/protocol-http": "^4.0.3",
+ "@smithy/signature-v4": "^3.1.2",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -904,29 +904,29 @@
}
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.598.0.tgz",
- "integrity": "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA==",
- "dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/property-provider": "^3.1.1",
- "@smithy/shared-ini-file-loader": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz",
+ "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==",
+ "dependencies": {
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/property-provider": "^3.1.3",
+ "@smithy/shared-ini-file-loader": "^3.1.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-sso-oidc": "^3.598.0"
+ "@aws-sdk/client-sso-oidc": "^3.614.0"
}
},
"node_modules/@aws-sdk/types": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.598.0.tgz",
- "integrity": "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz",
+ "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==",
"dependencies": {
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -945,13 +945,13 @@
}
},
"node_modules/@aws-sdk/util-endpoints": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.598.0.tgz",
- "integrity": "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz",
+ "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/types": "^3.1.0",
- "@smithy/util-endpoints": "^2.0.2",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/types": "^3.3.0",
+ "@smithy/util-endpoints": "^2.0.5",
"tslib": "^2.6.2"
},
"engines": {
@@ -970,24 +970,24 @@
}
},
"node_modules/@aws-sdk/util-user-agent-browser": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.598.0.tgz",
- "integrity": "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz",
+ "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/types": "^3.3.0",
"bowser": "^2.11.0",
"tslib": "^2.6.2"
}
},
"node_modules/@aws-sdk/util-user-agent-node": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.598.0.tgz",
- "integrity": "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A==",
+ "version": "3.614.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz",
+ "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==",
"dependencies": {
- "@aws-sdk/types": "3.598.0",
- "@smithy/node-config-provider": "^3.1.1",
- "@smithy/types": "^3.1.0",
+ "@aws-sdk/types": "3.609.0",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -1003,11 +1003,11 @@
}
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.598.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.598.0.tgz",
- "integrity": "sha512-ZIa2RK7CHFTZ4gwK77WRtsZ6vF7xwRXxJ8KQIxK2duhoTVcn0xYxpFLdW9WZZZvdP9GIF3Loqvf8DRdeU5Jc7Q==",
+ "version": "3.609.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.609.0.tgz",
+ "integrity": "sha512-l9XxNcA4HX98rwCC2/KoiWcmEiRfZe4G+mYwDbCFT87JIMj6GBhLDkAzr/W8KAaA2IDr8Vc6J8fZPgVulxxfMA==",
"dependencies": {
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -8308,11 +8308,11 @@
}
},
"node_modules/@smithy/config-resolver": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.4.tgz",
- "integrity": "sha512-VwiOk7TwXoE7NlNguV/aPq1hFH72tqkHCw8eWXbr2xHspRyyv9DLpLXhq+Ieje+NwoqXrY0xyQjPXdOE6cGcHA==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz",
+ "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==",
"dependencies": {
- "@smithy/node-config-provider": "^3.1.3",
+ "@smithy/node-config-provider": "^3.1.4",
"@smithy/types": "^3.3.0",
"@smithy/util-config-provider": "^3.0.0",
"@smithy/util-middleware": "^3.0.3",
@@ -8323,15 +8323,15 @@
}
},
"node_modules/@smithy/core": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.4.tgz",
- "integrity": "sha512-qdY3LpMOUyLM/gfjjMQZui+UTNS7kBRDWlvyIhVOql5dn2J3isk9qUTBtQ1CbDH8MTugHis1zu3h4rH+Qmmh4g==",
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.8.tgz",
+ "integrity": "sha512-1Y0XX0Ucyg0LWTfTVLWpmvSRtFRniykUl3dQ0os1sTd03mKDudR6mVyX+2ak1phwPXx2aEWMAAdW52JNi0mc3A==",
"dependencies": {
- "@smithy/middleware-endpoint": "^3.0.4",
- "@smithy/middleware-retry": "^3.0.7",
+ "@smithy/middleware-endpoint": "^3.0.5",
+ "@smithy/middleware-retry": "^3.0.11",
"@smithy/middleware-serde": "^3.0.3",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/smithy-client": "^3.1.5",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/smithy-client": "^3.1.9",
"@smithy/types": "^3.3.0",
"@smithy/util-middleware": "^3.0.3",
"tslib": "^2.6.2"
@@ -8341,11 +8341,11 @@
}
},
"node_modules/@smithy/credential-provider-imds": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.3.tgz",
- "integrity": "sha512-U1Yrv6hx/mRK6k8AncuI6jLUx9rn0VVSd9NPEX6pyYFBfkSkChOc/n4zUb8alHUVg83TbI4OdZVo1X0Zfj3ijA==",
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.4.tgz",
+ "integrity": "sha512-NKyH01m97Xa5xf3pB2QOF3lnuE8RIK0hTVNU5zvZAwZU8uspYO4DHQVlK+Y5gwSrujTfHvbfd1D9UFJAc0iYKQ==",
"dependencies": {
- "@smithy/node-config-provider": "^3.1.3",
+ "@smithy/node-config-provider": "^3.1.4",
"@smithy/property-provider": "^3.1.3",
"@smithy/types": "^3.3.0",
"@smithy/url-parser": "^3.0.3",
@@ -8356,23 +8356,23 @@
}
},
"node_modules/@smithy/eventstream-codec": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.0.tgz",
- "integrity": "sha512-XFDl70ZY+FabSnTX3oQGGYvdbEaC8vPEFkCEOoBkumqaZIwR1WjjJCDu2VMXlHbKWKshefWXdT0NYteL5v6uFw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.2.tgz",
+ "integrity": "sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"@smithy/util-hex-encoding": "^3.0.0",
"tslib": "^2.6.2"
}
},
"node_modules/@smithy/eventstream-serde-browser": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.2.tgz",
- "integrity": "sha512-6147vdedQGaWn3Nt4P1KV0LuV8IH4len1SAeycyko0p8oRLWFyYyx0L8JHGclePDSphkjxZqBHtyIfyupCaTGg==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.5.tgz",
+ "integrity": "sha512-dEyiUYL/ekDfk+2Ra4GxV+xNnFoCmk1nuIXg+fMChFTrM2uI/1r9AdiTYzPqgb72yIv/NtAj6C3dG//1wwgakQ==",
"dependencies": {
- "@smithy/eventstream-serde-universal": "^3.0.2",
- "@smithy/types": "^3.1.0",
+ "@smithy/eventstream-serde-universal": "^3.0.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -8380,11 +8380,11 @@
}
},
"node_modules/@smithy/eventstream-serde-config-resolver": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.1.tgz",
- "integrity": "sha512-6+B8P+5Q1mll4u7IoI7mpmYOSW3/c2r3WQoYLdqOjbIKMixJFGmN79ZjJiNMy4X2GZ4We9kQ6LfnFuczSlhcyw==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.3.tgz",
+ "integrity": "sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==",
"dependencies": {
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -8392,12 +8392,12 @@
}
},
"node_modules/@smithy/eventstream-serde-node": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.2.tgz",
- "integrity": "sha512-DLtmGAfqxZAql8rB+HqyPlUne22u3EEVj+hxlUjgXk0hXt+SfLGK0ljzRFmiWQ3qGpHu1NdJpJA9e5JE/dJxFw==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.4.tgz",
+ "integrity": "sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==",
"dependencies": {
- "@smithy/eventstream-serde-universal": "^3.0.2",
- "@smithy/types": "^3.1.0",
+ "@smithy/eventstream-serde-universal": "^3.0.4",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -8405,12 +8405,12 @@
}
},
"node_modules/@smithy/eventstream-serde-universal": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.2.tgz",
- "integrity": "sha512-d3SgAIQ/s4EbU8HAHJ8m2MMJPAL30nqJktyVgvqZWNznA8PJl61gJw5gj/yjIt/Fvs3d4fU8FmPPAhdp2yr/7A==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.4.tgz",
+ "integrity": "sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==",
"dependencies": {
- "@smithy/eventstream-codec": "^3.1.0",
- "@smithy/types": "^3.1.0",
+ "@smithy/eventstream-codec": "^3.1.2",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -8418,11 +8418,11 @@
}
},
"node_modules/@smithy/fetch-http-handler": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.0.tgz",
- "integrity": "sha512-vFvDxMrc6sO5Atec8PaISckMcAwsCrRhYxwUylg97bRT2KZoumOF7qk5+6EVUtuM1IG9AJV5aqXnHln9ZdXHpg==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.2.tgz",
+ "integrity": "sha512-3LaWlBZObyGrOOd7e5MlacnAKEwFBmAeiW/TOj2eR9475Vnq30uS2510+tnKbxrGjROfNdOhQqGo5j3sqLT6bA==",
"dependencies": {
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/querystring-builder": "^3.0.3",
"@smithy/types": "^3.3.0",
"@smithy/util-base64": "^3.0.0",
@@ -8430,13 +8430,13 @@
}
},
"node_modules/@smithy/hash-blob-browser": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.0.tgz",
- "integrity": "sha512-lKEHDN6bLzYdx5cFmdMHfYVmmTZTmjphwPBSumgkaniEYwRAXnbDEGETeuzfquS9Py1aH6cmqzXWxxkD7mV3sA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.2.tgz",
+ "integrity": "sha512-hAbfqN2UbISltakCC2TP0kx4LqXBttEv2MqSPE98gVuDFMf05lU+TpC41QtqGP3Ff5A3GwZMPfKnEy0VmEUpmg==",
"dependencies": {
"@smithy/chunked-blob-reader": "^3.0.0",
"@smithy/chunked-blob-reader-native": "^3.0.0",
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
}
},
@@ -8455,11 +8455,11 @@
}
},
"node_modules/@smithy/hash-stream-node": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.1.0.tgz",
- "integrity": "sha512-OkU9vjN17yYsXTSrouctZn2iYwG4z8WSc7F50+9ogG2crOtMopkop+22j35tX2ry2i/vLRCYgnqEmBWfvnYT2g==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.1.2.tgz",
+ "integrity": "sha512-PBgDMeEdDzi6JxKwbfBtwQG9eT9cVwsf0dZzLXoJF4sHKHs5HEo/3lJWpn6jibfJwT34I1EBXpBnZE8AxAft6g==",
"dependencies": {
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
},
@@ -8488,21 +8488,21 @@
}
},
"node_modules/@smithy/md5-js": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.1.tgz",
- "integrity": "sha512-wQa0YGsR4Zb1GQLGwOOgRAbkj22P6CFGaFzu5bKk8K4HVNIC2dBlIxqZ/baF0pLiSZySAPdDZT7CdZ7GkGXt5A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.3.tgz",
+ "integrity": "sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==",
"dependencies": {
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
}
},
"node_modules/@smithy/middleware-content-length": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.3.tgz",
- "integrity": "sha512-Dbz2bzexReYIQDWMr+gZhpwBetNXzbhnEMhYKA6urqmojO14CsXjnsoPYO8UL/xxcawn8ZsuVU61ElkLSltIUQ==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.4.tgz",
+ "integrity": "sha512-wySGje/KfhsnF8YSh9hP16pZcl3C+X6zRsvSfItQGvCyte92LliilU3SD0nR7kTlxnAJwxY8vE/k4Eoezj847Q==",
"dependencies": {
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -8511,13 +8511,13 @@
}
},
"node_modules/@smithy/middleware-endpoint": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.4.tgz",
- "integrity": "sha512-whUJMEPwl3ANIbXjBXZVdJNgfV2ZU8ayln7xUM47rXL2txuenI7jQ/VFFwCzy5lCmXScjp6zYtptW5Evud8e9g==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.5.tgz",
+ "integrity": "sha512-V4acqqrh5tDxUEGVTOgf2lYMZqPQsoGntCrjrJZEeBzEzDry2d2vcI1QCXhGltXPPY+BMc6eksZMguA9fIY8vA==",
"dependencies": {
"@smithy/middleware-serde": "^3.0.3",
- "@smithy/node-config-provider": "^3.1.3",
- "@smithy/shared-ini-file-loader": "^3.1.3",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/shared-ini-file-loader": "^3.1.4",
"@smithy/types": "^3.3.0",
"@smithy/url-parser": "^3.0.3",
"@smithy/util-middleware": "^3.0.3",
@@ -8528,14 +8528,14 @@
}
},
"node_modules/@smithy/middleware-retry": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.7.tgz",
- "integrity": "sha512-f5q7Y09G+2h5ivkSx5CHvlAT4qRR3jBFEsfXyQ9nFNiWQlr8c48blnu5cmbTQ+p1xmIO14UXzKoF8d7Tm0Gsjw==",
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.11.tgz",
+ "integrity": "sha512-/TIRWmhwMpv99JCGuMhJPnH7ggk/Lah7s/uNDyr7faF02BxNsyD/fz9Tw7pgCf9tYOKgjimm2Qml1Aq1pbkt6g==",
"dependencies": {
- "@smithy/node-config-provider": "^3.1.3",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/node-config-provider": "^3.1.4",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/service-error-classification": "^3.0.3",
- "@smithy/smithy-client": "^3.1.5",
+ "@smithy/smithy-client": "^3.1.9",
"@smithy/types": "^3.3.0",
"@smithy/util-middleware": "^3.0.3",
"@smithy/util-retry": "^3.0.3",
@@ -8571,12 +8571,12 @@
}
},
"node_modules/@smithy/node-config-provider": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.3.tgz",
- "integrity": "sha512-rxdpAZczzholz6CYZxtqDu/aKTxATD5DAUDVj7HoEulq+pDSQVWzbg0btZDlxeFfa6bb2b5tUvgdX5+k8jUqcg==",
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz",
+ "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==",
"dependencies": {
"@smithy/property-provider": "^3.1.3",
- "@smithy/shared-ini-file-loader": "^3.1.3",
+ "@smithy/shared-ini-file-loader": "^3.1.4",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -8585,12 +8585,12 @@
}
},
"node_modules/@smithy/node-http-handler": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.1.tgz",
- "integrity": "sha512-L71NLyPeP450r2J/mfu1jMc//Z1YnqJt2eSNw7uhiItaONnBLDA68J5jgxq8+MBDsYnFwNAIc7dBG1ImiWBiwg==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.3.tgz",
+ "integrity": "sha512-UiKZm8KHb/JeOPzHZtRUfyaRDO1KPKPpsd7iplhiwVGOeVdkiVJ5bVe7+NhWREMOKomrDIDdSZyglvMothLg0Q==",
"dependencies": {
"@smithy/abort-controller": "^3.1.1",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/querystring-builder": "^3.0.3",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
@@ -8612,9 +8612,9 @@
}
},
"node_modules/@smithy/protocol-http": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.3.tgz",
- "integrity": "sha512-x5jmrCWwQlx+Zv4jAtc33ijJ+vqqYN+c/ZkrnpvEe/uDas7AT7A/4Rc2CdfxgWv4WFGmEqODIrrUToPN6DDkGw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.4.tgz",
+ "integrity": "sha512-fAA2O4EFyNRyYdFLVIv5xMMeRb+3fRKc/Rt2flh5k831vLvUmNFXcydeg7V3UeEhGURJI4c1asmGJBjvmF6j8Q==",
"dependencies": {
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
@@ -8660,9 +8660,9 @@
}
},
"node_modules/@smithy/shared-ini-file-loader": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.3.tgz",
- "integrity": "sha512-Z8Y3+08vgoDgl4HENqNnnzSISAaGrF2RoKupoC47u2wiMp+Z8P/8mDh1CL8+8ujfi2U5naNvopSBmP/BUj8b5w==",
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz",
+ "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==",
"dependencies": {
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
@@ -8672,14 +8672,14 @@
}
},
"node_modules/@smithy/signature-v4": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.0.tgz",
- "integrity": "sha512-m0/6LW3IQ3/JBcdhqjpkpABPTPhcejqeAn0U877zxBdNLiWAnG2WmCe5MfkUyVuvpFTPQnQwCo/0ZBR4uF5kxg==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.2.tgz",
+ "integrity": "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==",
"dependencies": {
"@smithy/is-array-buffer": "^3.0.0",
- "@smithy/types": "^3.1.0",
+ "@smithy/types": "^3.3.0",
"@smithy/util-hex-encoding": "^3.0.0",
- "@smithy/util-middleware": "^3.0.1",
+ "@smithy/util-middleware": "^3.0.3",
"@smithy/util-uri-escape": "^3.0.0",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
@@ -8689,15 +8689,15 @@
}
},
"node_modules/@smithy/smithy-client": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.5.tgz",
- "integrity": "sha512-x9bL9Mx2CT2P1OiUlHM+ZNpbVU6TgT32f9CmTRzqIHA7M4vYrROCWEoC3o4xHNJASoGd4Opos3cXYPgh+/m4Ww==",
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.9.tgz",
+ "integrity": "sha512-My2RaInZ4gSwJUPMaiLR/Nk82+c4LlvqpXA+n7lonGYgCZq23Tg+/xFhgmiejJ6XPElYJysTPyV90vKyp17+1g==",
"dependencies": {
- "@smithy/middleware-endpoint": "^3.0.4",
+ "@smithy/middleware-endpoint": "^3.0.5",
"@smithy/middleware-stack": "^3.0.3",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
- "@smithy/util-stream": "^3.0.5",
+ "@smithy/util-stream": "^3.1.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -8781,12 +8781,12 @@
}
},
"node_modules/@smithy/util-defaults-mode-browser": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.7.tgz",
- "integrity": "sha512-Q2txLyvQyGfmjsaDbVV7Sg8psefpFcrnlGapDzXGFRPFKRBeEg6OvFK8FljqjeHSaCZ6/UuzQExUPqBR/2qlDA==",
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.11.tgz",
+ "integrity": "sha512-O3s9DGb3bmRvEKmT8RwvSWK4A9r6svfd+MnJB+UMi9ZcCkAnoRtliulOnGF0qCMkKF9mwk2tkopBBstalPY/vg==",
"dependencies": {
"@smithy/property-provider": "^3.1.3",
- "@smithy/smithy-client": "^3.1.5",
+ "@smithy/smithy-client": "^3.1.9",
"@smithy/types": "^3.3.0",
"bowser": "^2.11.0",
"tslib": "^2.6.2"
@@ -8796,15 +8796,15 @@
}
},
"node_modules/@smithy/util-defaults-mode-node": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.7.tgz",
- "integrity": "sha512-F4Qcj1fG6MGi2BSWCslfsMSwllws/WzYONBGtLybyY+halAcXdWhcew+mej8M5SKd5hqPYp4f7b+ABQEaeytgg==",
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.11.tgz",
+ "integrity": "sha512-qd4a9qtyOa/WY14aHHOkMafhh9z8D2QTwlcBoXMTPnEwtcY+xpe1JyFm9vya7VsB8hHsfn3XodEtwqREiu4ygQ==",
"dependencies": {
- "@smithy/config-resolver": "^3.0.4",
- "@smithy/credential-provider-imds": "^3.1.3",
- "@smithy/node-config-provider": "^3.1.3",
+ "@smithy/config-resolver": "^3.0.5",
+ "@smithy/credential-provider-imds": "^3.1.4",
+ "@smithy/node-config-provider": "^3.1.4",
"@smithy/property-provider": "^3.1.3",
- "@smithy/smithy-client": "^3.1.5",
+ "@smithy/smithy-client": "^3.1.9",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -8813,11 +8813,11 @@
}
},
"node_modules/@smithy/util-endpoints": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.4.tgz",
- "integrity": "sha512-ZAtNf+vXAsgzgRutDDiklU09ZzZiiV/nATyqde4Um4priTmasDH+eLpp3tspL0hS2dEootyFMhu1Y6Y+tzpWBQ==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz",
+ "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==",
"dependencies": {
- "@smithy/node-config-provider": "^3.1.3",
+ "@smithy/node-config-provider": "^3.1.4",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -8862,12 +8862,12 @@
}
},
"node_modules/@smithy/util-stream": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.5.tgz",
- "integrity": "sha512-xC3L5PKMAT/Bh8fmHNXP9sdQ4+4aKVUU3EEJ2CF/lLk7R+wtMJM+v/1B4en7jO++Wa5spGzFDBCl0QxgbUc5Ug==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.1.tgz",
+ "integrity": "sha512-EhRnVvl3AhoHAT2rGQ5o+oSDRM/BUSMPLZZdRJZLcNVUsFAjOs4vHaPdNQivTSzRcFxf5DA4gtO46WWU2zimaw==",
"dependencies": {
- "@smithy/fetch-http-handler": "^3.2.0",
- "@smithy/node-http-handler": "^3.1.1",
+ "@smithy/fetch-http-handler": "^3.2.2",
+ "@smithy/node-http-handler": "^3.1.3",
"@smithy/types": "^3.3.0",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-buffer-from": "^3.0.0",
@@ -8903,12 +8903,12 @@
}
},
"node_modules/@smithy/util-waiter": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.0.1.tgz",
- "integrity": "sha512-wwnrVQdjQxvWGOAiLmqlEhENGCcDIN+XJ/+usPOgSZObAslrCXgKlkX7rNVwIWW2RhPguTKthvF+4AoO0Z6KpA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.2.tgz",
+ "integrity": "sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==",
"dependencies": {
- "@smithy/abort-controller": "^3.0.1",
- "@smithy/types": "^3.1.0",
+ "@smithy/abort-controller": "^3.1.1",
+ "@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
"engines": {
diff --git a/package.json b/package.json
index a2ef69c894c..6d1ec52a639 100644
--- a/package.json
+++ b/package.json
@@ -59,8 +59,8 @@
"npm": "10.8.0"
},
"dependencies": {
- "@aws-sdk/client-s3": "^3.606.0",
- "@aws-sdk/lib-storage": "^3.606.0",
+ "@aws-sdk/client-s3": "^3.614.0",
+ "@aws-sdk/lib-storage": "^3.614.0",
"@fluent/bundle": "^0.18.0",
"@fluent/langneg": "^0.7.0",
"@fluent/react": "^0.15.2",
From 5f2dc9e50d94205557fdbf0c3330f966441d4e80 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 18 Jul 2024 14:57:12 +0000
Subject: [PATCH 102/137] chore(deps): bump the sentry group across 1 directory
with 3 updates
Bumps the sentry group with 1 update in the / directory: [@sentry/nextjs](https://github.com/getsentry/sentry-javascript).
Updates `@sentry/nextjs` from 8.2.1 to 8.18.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.2.1...8.18.0)
Updates `@sentry/node` from 8.2.1 to 8.18.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.2.1...8.18.0)
Updates `@sentry/utils` from 8.2.1 to 8.18.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.2.1...8.18.0)
---
updated-dependencies:
- dependency-name: "@sentry/nextjs"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: sentry
- dependency-name: "@sentry/node"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: sentry
- dependency-name: "@sentry/utils"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: sentry
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 1193 ++++++++++++++++++++-------------------------
package.json | 2 +-
2 files changed, 523 insertions(+), 672 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index f66cd9dc370..bcae66a0f75 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
"@leeoniya/ufuzzy": "^1.0.14",
"@mozilla/glean": "^5.0.2",
"@next/third-parties": "^14.2.5",
- "@sentry/nextjs": "^8.2.1",
+ "@sentry/nextjs": "^8.18.0",
"@sentry/node": "^8.0.0",
"@sentry/utils": "^8.0.0",
"@stripe/stripe-js": "^4.0.0",
@@ -5506,9 +5506,9 @@
}
},
"node_modules/@opentelemetry/api-logs": {
- "version": "0.51.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz",
- "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==",
+ "version": "0.52.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.52.1.tgz",
+ "integrity": "sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==",
"dependencies": {
"@opentelemetry/api": "^1.0.0"
},
@@ -5517,46 +5517,46 @@
}
},
"node_modules/@opentelemetry/context-async-hooks": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.24.1.tgz",
- "integrity": "sha512-R5r6DO4kgEOVBxFXhXjwospLQkv+sYxwCfjvoZBe7Zm6KKXAV9kDSJhi/D1BweowdZmO+sdbENLs374gER8hpQ==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.25.1.tgz",
+ "integrity": "sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==",
"engines": {
"node": ">=14"
},
"peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
}
},
"node_modules/@opentelemetry/core": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz",
- "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz",
+ "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==",
"dependencies": {
- "@opentelemetry/semantic-conventions": "1.24.1"
+ "@opentelemetry/semantic-conventions": "1.25.1"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
}
},
"node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation": {
- "version": "0.51.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz",
- "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==",
+ "version": "0.52.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.52.1.tgz",
+ "integrity": "sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==",
"dependencies": {
- "@opentelemetry/api-logs": "0.51.1",
+ "@opentelemetry/api-logs": "0.52.1",
"@types/shimmer": "^1.0.2",
- "import-in-the-middle": "1.7.4",
+ "import-in-the-middle": "^1.8.1",
"require-in-the-middle": "^7.1.1",
"semver": "^7.5.2",
"shimmer": "^1.2.1"
@@ -5569,13 +5569,13 @@
}
},
"node_modules/@opentelemetry/instrumentation-connect": {
- "version": "0.36.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.36.0.tgz",
- "integrity": "sha512-k9++bmJZ9zDEs3u3DnKTn2l7QTiNFg3gPx7G9rW0TPnP+xZoBSBTrEcGYBaqflQlrFG23Q58+X1sM2ayWPv5Fg==",
+ "version": "0.38.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.38.0.tgz",
+ "integrity": "sha512-2/nRnx3pjYEmdPIaBwtgtSviTKHWnDZN3R+TkRUnhIVrvBKVcq+I5B2rtd6mr6Fe9cHlZ9Ojcuh7pkNh/xdWWg==",
"dependencies": {
"@opentelemetry/core": "^1.8.0",
- "@opentelemetry/instrumentation": "^0.51.0",
- "@opentelemetry/semantic-conventions": "^1.0.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
+ "@opentelemetry/semantic-conventions": "^1.22.0",
"@types/connect": "3.4.36"
},
"engines": {
@@ -5585,6 +5585,14 @@
"@opentelemetry/api": "^1.3.0"
}
},
+ "node_modules/@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@opentelemetry/instrumentation-connect/node_modules/@types/connect": {
"version": "3.4.36",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz",
@@ -5594,12 +5602,12 @@
}
},
"node_modules/@opentelemetry/instrumentation-express": {
- "version": "0.38.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.38.0.tgz",
- "integrity": "sha512-izId/qcgMgfWV292ZI9b9E7HdV9446vi0Z5zu5fSlt4MF+R6LZXbZLTQAaboJ4Y2+JbtH7apvko1DF93qTFtqw==",
+ "version": "0.41.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.41.0.tgz",
+ "integrity": "sha512-/B7fbMdaf3SYe5f1P973tkqd6s7XZirjpfkoJ63E7nltU30qmlgm9tY5XwZOzAFI0rHS9tbrFI2HFPAvQUFe/A==",
"dependencies": {
"@opentelemetry/core": "^1.8.0",
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/semantic-conventions": "^1.22.0"
},
"engines": {
@@ -5610,20 +5618,20 @@
}
},
"node_modules/@opentelemetry/instrumentation-express/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-fastify": {
- "version": "0.36.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.36.1.tgz",
- "integrity": "sha512-3Nfm43PI0I+3EX+1YbSy6xbDu276R1Dh1tqAk68yd4yirnIh52Kd5B+nJ8CgHA7o3UKakpBjj6vSzi5vNCzJIA==",
+ "version": "0.38.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.38.0.tgz",
+ "integrity": "sha512-HBVLpTSYpkQZ87/Df3N0gAw7VzYZV3n28THIBrJWfuqw3Or7UqdhnjeuMIPQ04BKk3aZc0cWn2naSQObbh5vXw==",
"dependencies": {
"@opentelemetry/core": "^1.8.0",
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/semantic-conventions": "^1.22.0"
},
"engines": {
@@ -5634,19 +5642,19 @@
}
},
"node_modules/@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-graphql": {
- "version": "0.40.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.40.0.tgz",
- "integrity": "sha512-LVRdEHWACWOczv2imD+mhUrLMxsEjPPi32vIZJT57zygR5aUiA4em8X3aiGOCycgbMWkIu8xOSGSxdx3JmzN+w==",
+ "version": "0.42.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.42.0.tgz",
+ "integrity": "sha512-N8SOwoKL9KQSX7z3gOaw5UaTeVQcfDO1c21csVHnmnmGUoqsXbArK2B8VuwPWcv6/BC/i3io+xTo7QGRZ/z28Q==",
"dependencies": {
- "@opentelemetry/instrumentation": "^0.51.0"
+ "@opentelemetry/instrumentation": "^0.52.0"
},
"engines": {
"node": ">=14"
@@ -5656,13 +5664,13 @@
}
},
"node_modules/@opentelemetry/instrumentation-hapi": {
- "version": "0.38.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.38.0.tgz",
- "integrity": "sha512-ZcOqEuwuutTDYIjhDIStix22ECblG/i9pHje23QGs4Q4YS4RMaZ5hKCoQJxW88Z4K7T53rQkdISmoXFKDV8xMg==",
+ "version": "0.40.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.40.0.tgz",
+ "integrity": "sha512-8U/w7Ifumtd2bSN1OLaSwAAFhb9FyqWUki3lMMB0ds+1+HdSxYBe9aspEJEgvxAqOkrQnVniAPTEGf1pGM7SOw==",
"dependencies": {
"@opentelemetry/core": "^1.8.0",
- "@opentelemetry/instrumentation": "^0.51.0",
- "@opentelemetry/semantic-conventions": "^1.0.0"
+ "@opentelemetry/instrumentation": "^0.52.0",
+ "@opentelemetry/semantic-conventions": "^1.22.0"
},
"engines": {
"node": ">=14"
@@ -5671,14 +5679,22 @@
"@opentelemetry/api": "^1.3.0"
}
},
+ "node_modules/@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@opentelemetry/instrumentation-http": {
- "version": "0.51.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.51.1.tgz",
- "integrity": "sha512-6b3nZnFFEz/3xZ6w8bVxctPUWIPWiXuPQ725530JgxnN1cvYFd8CJ75PrHZNjynmzSSnqBkN3ef4R9N+RpMh8Q==",
+ "version": "0.52.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.52.1.tgz",
+ "integrity": "sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==",
"dependencies": {
- "@opentelemetry/core": "1.24.1",
- "@opentelemetry/instrumentation": "0.51.1",
- "@opentelemetry/semantic-conventions": "1.24.1",
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/instrumentation": "0.52.1",
+ "@opentelemetry/semantic-conventions": "1.25.1",
"semver": "^7.5.2"
},
"engines": {
@@ -5689,17 +5705,17 @@
}
},
"node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-http/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"bin": {
"semver": "bin/semver.js"
},
@@ -5708,13 +5724,13 @@
}
},
"node_modules/@opentelemetry/instrumentation-ioredis": {
- "version": "0.40.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.40.0.tgz",
- "integrity": "sha512-Jv/fH7KhpWe4KBirsiqeUJIYrsdR2iu2l4nWhfOlRvaZ+zYIiLEzTQR6QhBbyRoAbU4OuYJzjWusOmmpGBnwng==",
+ "version": "0.42.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.42.0.tgz",
+ "integrity": "sha512-P11H168EKvBB9TUSasNDOGJCSkpT44XgoM6d3gRIWAa9ghLpYhl0uRkS8//MqPzcJVHr3h3RmfXIpiYLjyIZTw==",
"dependencies": {
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/redis-common": "^0.36.2",
- "@opentelemetry/semantic-conventions": "^1.0.0"
+ "@opentelemetry/semantic-conventions": "^1.23.0"
},
"engines": {
"node": ">=14"
@@ -5723,16 +5739,22 @@
"@opentelemetry/api": "^1.3.0"
}
},
+ "node_modules/@opentelemetry/instrumentation-ioredis/node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@opentelemetry/instrumentation-koa": {
- "version": "0.40.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.40.0.tgz",
- "integrity": "sha512-dJc3H/bKMcgUYcQpLF+1IbmUKus0e5Fnn/+ru/3voIRHwMADT3rFSUcGLWSczkg68BCgz0vFWGDTvPtcWIFr7A==",
+ "version": "0.42.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.42.0.tgz",
+ "integrity": "sha512-H1BEmnMhho8o8HuNRq5zEI4+SIHDIglNB7BPKohZyWG4fWNuR7yM4GTlR01Syq21vODAS7z5omblScJD/eZdKw==",
"dependencies": {
"@opentelemetry/core": "^1.8.0",
- "@opentelemetry/instrumentation": "^0.51.0",
- "@opentelemetry/semantic-conventions": "^1.22.0",
- "@types/koa": "2.14.0",
- "@types/koa__router": "12.0.3"
+ "@opentelemetry/instrumentation": "^0.52.0",
+ "@opentelemetry/semantic-conventions": "^1.22.0"
},
"engines": {
"node": ">=14"
@@ -5742,19 +5764,19 @@
}
},
"node_modules/@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-mongodb": {
- "version": "0.43.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.43.0.tgz",
- "integrity": "sha512-bMKej7Y76QVUD3l55Q9YqizXybHUzF3pujsBFjqbZrRn2WYqtsDtTUlbCK7fvXNPwFInqZ2KhnTqd0gwo8MzaQ==",
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.46.0.tgz",
+ "integrity": "sha512-VF/MicZ5UOBiXrqBslzwxhN7TVqzu1/LN/QDpkskqM0Zm0aZ4CVRbUygL8d7lrjLn15x5kGIe8VsSphMfPJzlA==",
"dependencies": {
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/sdk-metrics": "^1.9.1",
"@opentelemetry/semantic-conventions": "^1.22.0"
},
@@ -5766,20 +5788,20 @@
}
},
"node_modules/@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-mongoose": {
- "version": "0.38.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.38.1.tgz",
- "integrity": "sha512-zaeiasdnRjXe6VhYCBMdkmAVh1S5MmXC/0spet+yqoaViGnYst/DOxPvhwg3yT4Yag5crZNWsVXnA538UjP6Ow==",
+ "version": "0.40.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.40.0.tgz",
+ "integrity": "sha512-niRi5ZUnkgzRhIGMOozTyoZIvJKNJyhijQI4nF4iFSb+FUx2v5fngfR+8XLmdQAO7xmsD8E5vEGdDVYVtKbZew==",
"dependencies": {
"@opentelemetry/core": "^1.8.0",
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/semantic-conventions": "^1.22.0"
},
"engines": {
@@ -5790,19 +5812,19 @@
}
},
"node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-mysql": {
- "version": "0.38.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.38.1.tgz",
- "integrity": "sha512-+iBAawUaTfX/HAlvySwozx0C2B6LBfNPXX1W8Z2On1Uva33AGkw2UjL9XgIg1Pj4eLZ9R4EoJ/aFz+Xj4E/7Fw==",
+ "version": "0.40.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.40.0.tgz",
+ "integrity": "sha512-d7ja8yizsOCNMYIJt5PH/fKZXjb/mS48zLROO4BzZTtDfhNCl2UM/9VIomP2qkGIFVouSJrGr/T00EzY7bPtKA==",
"dependencies": {
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/semantic-conventions": "^1.22.0",
"@types/mysql": "2.15.22"
},
@@ -5814,19 +5836,19 @@
}
},
"node_modules/@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-mysql2": {
- "version": "0.38.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.38.1.tgz",
- "integrity": "sha512-qkpHMgWSDTYVB1vlZ9sspf7l2wdS5DDq/rbIepDwX5BA0N0068JTQqh0CgAh34tdFqSCnWXIhcyOXC2TtRb0sg==",
+ "version": "0.40.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.40.0.tgz",
+ "integrity": "sha512-0xfS1xcqUmY7WE1uWjlmI67Xg3QsSUlNT+AcXHeA4BDUPwZtWqF4ezIwLgpVZfHOnkAEheqGfNSWd1PIu3Wnfg==",
"dependencies": {
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/semantic-conventions": "^1.22.0",
"@opentelemetry/sql-common": "^0.40.1"
},
@@ -5838,20 +5860,20 @@
}
},
"node_modules/@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation-nestjs-core": {
- "version": "0.37.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.37.1.tgz",
- "integrity": "sha512-ebYQjHZEmGHWEALwwDGhSQVLBaurFnuLIkZD5igPXrt7ohfF4lc5/4al1LO+vKc0NHk8SJWStuRueT86ISA8Vg==",
+ "version": "0.39.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.39.0.tgz",
+ "integrity": "sha512-mewVhEXdikyvIZoMIUry8eb8l3HUjuQjSjVbmLVTt4NQi35tkpnHQrG9bTRBrl3403LoWZ2njMPJyg4l6HfKvA==",
"dependencies": {
- "@opentelemetry/instrumentation": "^0.51.0",
- "@opentelemetry/semantic-conventions": "^1.0.0"
+ "@opentelemetry/instrumentation": "^0.52.0",
+ "@opentelemetry/semantic-conventions": "^1.23.0"
},
"engines": {
"node": ">=14"
@@ -5860,12 +5882,20 @@
"@opentelemetry/api": "^1.3.0"
}
},
+ "node_modules/@opentelemetry/instrumentation-nestjs-core/node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@opentelemetry/instrumentation-pg": {
- "version": "0.41.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.41.0.tgz",
- "integrity": "sha512-BSlhpivzBD77meQNZY9fS4aKgydA8AJBzv2dqvxXFy/Hq64b7HURgw/ztbmwFeYwdF5raZZUifiiNSMLpOJoSA==",
+ "version": "0.43.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.43.0.tgz",
+ "integrity": "sha512-og23KLyoxdnAeFs1UWqzSonuCkePUzCX30keSYigIzJe/6WSYA8rnEI5lobcxPEzg+GcU06J7jzokuEHbjVJNw==",
"dependencies": {
- "@opentelemetry/instrumentation": "^0.51.0",
+ "@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/semantic-conventions": "^1.22.0",
"@opentelemetry/sql-common": "^0.40.1",
"@types/pg": "8.6.1",
@@ -5879,17 +5909,41 @@
}
},
"node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@opentelemetry/instrumentation-redis-4": {
+ "version": "0.41.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.41.0.tgz",
+ "integrity": "sha512-H7IfGTqW2reLXqput4yzAe8YpDC0fmVNal95GHMLOrS89W+qWUKIqxolSh63hJyfmwPSFwXASzj7wpSk8Az+Dg==",
+ "dependencies": {
+ "@opentelemetry/instrumentation": "^0.52.0",
+ "@opentelemetry/redis-common": "^0.36.2",
+ "@opentelemetry/semantic-conventions": "^1.22.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ }
+ },
+ "node_modules/@opentelemetry/instrumentation-redis-4/node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/instrumentation/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"bin": {
"semver": "bin/semver.js"
},
@@ -5906,64 +5960,64 @@
}
},
"node_modules/@opentelemetry/resources": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz",
- "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.25.1.tgz",
+ "integrity": "sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==",
"dependencies": {
- "@opentelemetry/core": "1.24.1",
- "@opentelemetry/semantic-conventions": "1.24.1"
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/semantic-conventions": "1.25.1"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
}
},
"node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@opentelemetry/sdk-metrics": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.24.1.tgz",
- "integrity": "sha512-FrAqCbbGao9iKI+Mgh+OsC9+U2YMoXnlDHe06yH7dvavCKzE3S892dGtX54+WhSFVxHR/TMRVJiK/CV93GR0TQ==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.1.tgz",
+ "integrity": "sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==",
"dependencies": {
- "@opentelemetry/core": "1.24.1",
- "@opentelemetry/resources": "1.24.1",
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/resources": "1.25.1",
"lodash.merge": "^4.6.2"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
- "@opentelemetry/api": ">=1.3.0 <1.9.0"
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
}
},
"node_modules/@opentelemetry/sdk-trace-base": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.24.1.tgz",
- "integrity": "sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz",
+ "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==",
"dependencies": {
- "@opentelemetry/core": "1.24.1",
- "@opentelemetry/resources": "1.24.1",
- "@opentelemetry/semantic-conventions": "1.24.1"
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/resources": "1.25.1",
+ "@opentelemetry/semantic-conventions": "1.25.1"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
}
},
"node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
@@ -6087,137 +6141,13 @@
}
},
"node_modules/@prisma/instrumentation": {
- "version": "5.13.0",
- "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-5.13.0.tgz",
- "integrity": "sha512-MEJX1aWLsEjS+2iheBkEy1LlzQuUruPgKEzA9HPMwzitCoUUK1qn5o+yIphU7wWs47Le/cED0egYQL7y9/rSsA==",
- "dependencies": {
- "@opentelemetry/api": "1.8.0",
- "@opentelemetry/instrumentation": "0.50.0",
- "@opentelemetry/sdk-trace-base": "1.23.0"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": {
- "version": "0.50.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.50.0.tgz",
- "integrity": "sha512-JdZuKrhOYggqOpUljAq4WWNi5nB10PmgoF0y2CvedLGXd0kSawb/UBnWT8gg1ND3bHCNHStAIVT0ELlxJJRqrA==",
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-5.16.1.tgz",
+ "integrity": "sha512-4m5gRFWnQb8s/yTyGbMZkL7A5uJgqOWcWJxapwcAD0T0kh5sGPEVSQl/zTQvE9aduXhFAxOtC3gO+R8Hb5xO1Q==",
"dependencies": {
- "@opentelemetry/api": "^1.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/core": {
- "version": "1.23.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.23.0.tgz",
- "integrity": "sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==",
- "dependencies": {
- "@opentelemetry/semantic-conventions": "1.23.0"
- },
- "engines": {
- "node": ">=14"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.9.0"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": {
- "version": "0.50.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.50.0.tgz",
- "integrity": "sha512-bhGhbJiZKpuu7wTaSak4hyZcFPlnDeuSF/2vglze8B4w2LubcSbbOnkVTzTs5SXtzh4Xz8eRjaNnAm+u2GYufQ==",
- "dependencies": {
- "@opentelemetry/api-logs": "0.50.0",
- "@types/shimmer": "^1.0.2",
- "import-in-the-middle": "1.7.1",
- "require-in-the-middle": "^7.1.1",
- "semver": "^7.5.2",
- "shimmer": "^1.2.1"
- },
- "engines": {
- "node": ">=14"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.3.0"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/resources": {
- "version": "1.23.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.23.0.tgz",
- "integrity": "sha512-iPRLfVfcEQynYGo7e4Di+ti+YQTAY0h5mQEUJcHlU9JOqpb4x965O6PZ+wMcwYVY63G96KtdS86YCM1BF1vQZg==",
- "dependencies": {
- "@opentelemetry/core": "1.23.0",
- "@opentelemetry/semantic-conventions": "1.23.0"
- },
- "engines": {
- "node": ">=14"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.9.0"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/sdk-trace-base": {
- "version": "1.23.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.23.0.tgz",
- "integrity": "sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ==",
- "dependencies": {
- "@opentelemetry/core": "1.23.0",
- "@opentelemetry/resources": "1.23.0",
- "@opentelemetry/semantic-conventions": "1.23.0"
- },
- "engines": {
- "node": ">=14"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.9.0"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.23.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.23.0.tgz",
- "integrity": "sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==",
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/acorn-import-assertions": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
- "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
- "peerDependencies": {
- "acorn": "^8"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/import-in-the-middle": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.1.tgz",
- "integrity": "sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==",
- "dependencies": {
- "acorn": "^8.8.2",
- "acorn-import-assertions": "^1.9.0",
- "cjs-module-lexer": "^1.2.2",
- "module-details-from-path": "^1.0.3"
- }
- },
- "node_modules/@prisma/instrumentation/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
+ "@opentelemetry/api": "^1.8",
+ "@opentelemetry/instrumentation": "^0.49 || ^0.50 || ^0.51 || ^0.52.0",
+ "@opentelemetry/sdk-trace-base": "^1.22"
}
},
"node_modules/@protobufjs/aspromise": {
@@ -7661,22 +7591,22 @@
}
},
"node_modules/@rollup/plugin-commonjs": {
- "version": "24.0.0",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.0.tgz",
- "integrity": "sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==",
+ "version": "26.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-26.0.1.tgz",
+ "integrity": "sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"commondir": "^1.0.1",
"estree-walker": "^2.0.2",
- "glob": "^8.0.3",
+ "glob": "^10.4.1",
"is-reference": "1.2.1",
- "magic-string": "^0.27.0"
+ "magic-string": "^0.30.3"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=16.0.0 || 14 >= 14.17"
},
"peerDependencies": {
- "rollup": "^2.68.0||^3.0.0"
+ "rollup": "^2.68.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
@@ -7685,9 +7615,9 @@
}
},
"node_modules/@rollup/pluginutils": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
- "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
+ "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
@@ -7711,96 +7641,96 @@
"integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA=="
},
"node_modules/@sentry-internal/browser-utils": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.2.1.tgz",
- "integrity": "sha512-jWueDzeb+LPEMfnJ5OR4YM5+PVnWbBI35DNwbT0TMiHNsqFjp2xtWAr8rpK9OayuLXEe5YtcoeyTUwU5c6i3DA==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.18.0.tgz",
+ "integrity": "sha512-1R7QXp7Gu6ovJGWvGjbgHcDcvDstsQba3miHtUCyDSH9kXtnAVLCAItDkseetFh+JLsjBXf3QFi2H3HPY4hRCw==",
"dependencies": {
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/feedback": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.2.1.tgz",
- "integrity": "sha512-HN2ys/dvisKmUybO3U6DwhutXujwZP+9bbuhBQWex7wu+iZrkIxT8TVb9Vye2Q0nsxupwD43dSzpKdGYBwx5XQ==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.18.0.tgz",
+ "integrity": "sha512-on6+4ZRkfdnsNgXecGQ6ME8aO26VTzkuM6y/kNN+bG2hSdxsmuU957B4x1Z5wEXiOWswuf3rhqGepg8JIdPkMQ==",
"dependencies": {
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.2.1.tgz",
- "integrity": "sha512-Jwpbig9jJ4WoLpaZ/jhQRqI0ND9gPf+MrwXCDYf2NgKnvaKjbQiv0/DGVMpKdLZiasGqoEU3POI/UGd+GzTuxw==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.18.0.tgz",
+ "integrity": "sha512-cCLib/HjD8UR0fB2F5hV6KsFBD6yTOEsi67RBllm5gT5vJt87VYoPliF6O7mmMNw8TWkQ0uc5laKld3q9ph+ug==",
"dependencies": {
- "@sentry-internal/browser-utils": "8.2.1",
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry-internal/browser-utils": "8.18.0",
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.2.1.tgz",
- "integrity": "sha512-pP/ga8BR1qYDFnmhfNO+eruNjjpYeeB84mc/vfeZz0Ah5zh5LuaH/BIQM/jW615Ts77H82RFNdXYSwESz9AWPw==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.18.0.tgz",
+ "integrity": "sha512-fcuLJBrhw3Ql8sU8veUgDCRYo6toQldFU807cpYphQ0uEw2oVZwNNPDQSu1651Ykvp0P/x+9hk/jjJxMohrO9g==",
"dependencies": {
- "@sentry-internal/replay": "8.2.1",
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry-internal/replay": "8.18.0",
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/babel-plugin-component-annotate": {
- "version": "2.16.0",
- "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.16.0.tgz",
- "integrity": "sha512-+uy1qPkA5MSNgJ0L9ur/vNTydfdHwHnBX2RQ+0thsvkqf90fU788YjkkXwUiBBNuqNyI69JiOW6frixAWy7oUg==",
+ "version": "2.20.1",
+ "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.20.1.tgz",
+ "integrity": "sha512-4mhEwYTK00bIb5Y9UWIELVUfru587Vaeg0DQGswv4aIRHIiMKLyNqCEejaaybQ/fNChIZOKmvyqXk430YVd7Qg==",
"engines": {
"node": ">= 14"
}
},
"node_modules/@sentry/browser": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.2.1.tgz",
- "integrity": "sha512-s9LcHtHOCYQYCnHYMJOcVbSQLeYRjAogskCCLNjVcxpBcfDU+fXnabRZq1rvH3IZnOogp3O6kvIgmLuO3yOBTw==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.18.0.tgz",
+ "integrity": "sha512-E2w9u76JcjxcmgvroJrB7bcbG5oBCYI/pME1CtprBgZSS9mMYDsyBe6JKqGHdw2wvT3xNxNtkm7hf1O6+3NWUQ==",
"dependencies": {
- "@sentry-internal/browser-utils": "8.2.1",
- "@sentry-internal/feedback": "8.2.1",
- "@sentry-internal/replay": "8.2.1",
- "@sentry-internal/replay-canvas": "8.2.1",
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry-internal/browser-utils": "8.18.0",
+ "@sentry-internal/feedback": "8.18.0",
+ "@sentry-internal/replay": "8.18.0",
+ "@sentry-internal/replay-canvas": "8.18.0",
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/bundler-plugin-core": {
- "version": "2.16.0",
- "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.16.0.tgz",
- "integrity": "sha512-dhgIZsIR3L9KnE2OO5JJm6hPtStAjEPYKQsZzxRr69uVhd9xAvfXeXr0afKVNVEcIDksas6yMgHqwQ2wOXFIAg==",
+ "version": "2.20.1",
+ "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.20.1.tgz",
+ "integrity": "sha512-6ipbmGzHekxeRCbp7eoefr6bdd/lW4cNA9eNnrmd9+PicubweGaZZbH2NjhFHsaxzgOezwipDHjrTaap2kTHgw==",
"dependencies": {
"@babel/core": "^7.18.5",
- "@sentry/babel-plugin-component-annotate": "2.16.0",
+ "@sentry/babel-plugin-component-annotate": "2.20.1",
"@sentry/cli": "^2.22.3",
"dotenv": "^16.3.1",
"find-up": "^5.0.0",
"glob": "^9.3.2",
- "magic-string": "0.27.0",
+ "magic-string": "0.30.8",
"unplugin": "1.0.1"
},
"engines": {
@@ -7808,9 +7738,9 @@
}
},
"node_modules/@sentry/bundler-plugin-core/node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"bin": {
"acorn": "bin/acorn"
},
@@ -7843,6 +7773,17 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/@sentry/bundler-plugin-core/node_modules/magic-string": {
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.15"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@sentry/bundler-plugin-core/node_modules/minimatch": {
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
@@ -7877,9 +7818,9 @@
}
},
"node_modules/@sentry/cli": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.31.2.tgz",
- "integrity": "sha512-2aKyUx6La2P+pplL8+2vO67qJ+c1C79KYWAyQBE0JIT5kvKK9JpwtdNoK1F0/2mRpwhhYPADCz3sVIRqmL8cQQ==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.32.2.tgz",
+ "integrity": "sha512-m/6Z3FWu+rTd8jepVlJPKQhvbT8vCjt0N7BSWZiEUVW/8mhwAYJiwO0b+Ch/u4IqbBg1dp3805q5TFPl4AdrNw==",
"hasInstallScript": true,
"dependencies": {
"https-proxy-agent": "^5.0.0",
@@ -7895,19 +7836,19 @@
"node": ">= 10"
},
"optionalDependencies": {
- "@sentry/cli-darwin": "2.31.2",
- "@sentry/cli-linux-arm": "2.31.2",
- "@sentry/cli-linux-arm64": "2.31.2",
- "@sentry/cli-linux-i686": "2.31.2",
- "@sentry/cli-linux-x64": "2.31.2",
- "@sentry/cli-win32-i686": "2.31.2",
- "@sentry/cli-win32-x64": "2.31.2"
+ "@sentry/cli-darwin": "2.32.2",
+ "@sentry/cli-linux-arm": "2.32.2",
+ "@sentry/cli-linux-arm64": "2.32.2",
+ "@sentry/cli-linux-i686": "2.32.2",
+ "@sentry/cli-linux-x64": "2.32.2",
+ "@sentry/cli-win32-i686": "2.32.2",
+ "@sentry/cli-win32-x64": "2.32.2"
}
},
"node_modules/@sentry/cli-darwin": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.31.2.tgz",
- "integrity": "sha512-BHA/JJXj1dlnoZQdK4efRCtHRnbBfzbIZUKAze7oRR1RfNqERI84BVUQeKateD3jWSJXQfEuclIShc61KOpbKw==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.32.2.tgz",
+ "integrity": "sha512-GDtePIavx3FKSRowdPdtIssahn46MfFFYNN+s7a9MjlhFwJtvC9A1bSDw7ksEtDaQolepUwmLPHaVe19y0T/zw==",
"optional": true,
"os": [
"darwin"
@@ -7917,9 +7858,9 @@
}
},
"node_modules/@sentry/cli-linux-arm": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.31.2.tgz",
- "integrity": "sha512-W8k5mGYYZz/I/OxZH65YAK7dCkQAl+wbuoASGOQjUy5VDgqH0QJ8kGJufXvFPM+f3ZQGcKAnVsZ6tFqZXETBAw==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.32.2.tgz",
+ "integrity": "sha512-u9s08wr8bDDqsAl6pk9iGGlOHtU+T8btU6voNKy71QzeIBpV9c8VVk/OnmP9aswp/ea4NY416yjnzcTvCrFKAw==",
"cpu": [
"arm"
],
@@ -7933,9 +7874,9 @@
}
},
"node_modules/@sentry/cli-linux-arm64": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.31.2.tgz",
- "integrity": "sha512-FLVKkJ/rWvPy/ka7OrUdRW63a/z8HYI1Gt8Pr6rWs50hb7YJja8lM8IO10tYmcFE/tODICsnHO9HTeUg2g2d1w==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.32.2.tgz",
+ "integrity": "sha512-VECLVC1rLyvXk6rTVUfmfs4vhANjMgm4BVKGlA3rydmf2PJw2/NfipH3KeyijdE2vEoyLri+/6HH883pP0iniQ==",
"cpu": [
"arm64"
],
@@ -7949,9 +7890,9 @@
}
},
"node_modules/@sentry/cli-linux-i686": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.31.2.tgz",
- "integrity": "sha512-A64QtzaPi3MYFpZ+Fwmi0mrSyXgeLJ0cWr4jdeTGrzNpeowSteKgd6tRKU+LVq0k5shKE7wdnHk+jXnoajulMA==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.32.2.tgz",
+ "integrity": "sha512-XhofQz32OqLrQK1DEOsryhT7d29Df6VkccvxueGoIt2gpXEXtgRczsUwZjZqquDdkNCt+HPj9eUGcj8pY8JkmQ==",
"cpu": [
"x86",
"ia32"
@@ -7966,9 +7907,9 @@
}
},
"node_modules/@sentry/cli-linux-x64": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.31.2.tgz",
- "integrity": "sha512-YL/r+15R4mOEiU3mzn7iFQOeFEUB6KxeKGTTrtpeOGynVUGIdq4nV5rHow5JDbIzOuBS3SpOmcIMluvo1NCh0g==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.32.2.tgz",
+ "integrity": "sha512-anyng4Qqt7zX4ZY4IzDH1RJWAVZNBe6sUHcuciNy7giCU3B4/XnxAHlwYmBSN5txpaumsWdstPgRKEUJG6AOSA==",
"cpu": [
"x64"
],
@@ -7982,9 +7923,9 @@
}
},
"node_modules/@sentry/cli-win32-i686": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.31.2.tgz",
- "integrity": "sha512-Az/2bmW+TFI059RE0mSBIxTBcoShIclz7BDebmIoCkZ+retrwAzpmBnBCDAHow+Yi43utOow+3/4idGa2OxcLw==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.32.2.tgz",
+ "integrity": "sha512-/auqx7QXG7F556fNK7vaB26pX7Far1CQMfI65iV4u/VWg6gV2WfvJWXB4iowhjqkYv56sZ+zOymLkEVF0R8wtg==",
"cpu": [
"x86",
"ia32"
@@ -7998,9 +7939,9 @@
}
},
"node_modules/@sentry/cli-win32-x64": {
- "version": "2.31.2",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.31.2.tgz",
- "integrity": "sha512-XIzyRnJu539NhpFa+JYkotzVwv3NrZ/4GfHB/JWA2zReRvsk39jJG8D5HOmm0B9JA63QQT7Dt39RW8g3lkmb6w==",
+ "version": "2.32.2",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.32.2.tgz",
+ "integrity": "sha512-w7hW2sEWVYQquqdILBSFhcVW+HdoyLqVPPkLPAXRSLTwBnuni9nQEIdXr0h/7db+K3cm7PvWndp5ixVyswLHZA==",
"cpu": [
"x64"
],
@@ -8013,32 +7954,33 @@
}
},
"node_modules/@sentry/core": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.2.1.tgz",
- "integrity": "sha512-xHS+DGZodTwXkoqe35UnNR9zWZ7I8pptXGxHntPrNnd/PmXK3ysj4NsRBshtSzDX3gWfwUsMN+vmjrYSwcfYeQ==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.18.0.tgz",
+ "integrity": "sha512-8moEMC3gp4W6mH9w5amb/zrYk6bNW8WGgcLRMCs5rguxny8YP5i8ISOJ0T0LP9x/RxSK/6xix5D2bzI/5ECzlw==",
"dependencies": {
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/nextjs": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/nextjs/-/nextjs-8.2.1.tgz",
- "integrity": "sha512-vP6FEqThcuZQvZO759/NuxJGwdMxpav4SgtqDvdJV7Y+XRB7YpGdCN1wHDVZVeoIk+vnIGep669vVuaEZm/e9g==",
- "dependencies": {
- "@opentelemetry/instrumentation-http": "0.51.1",
- "@rollup/plugin-commonjs": "24.0.0",
- "@sentry/core": "8.2.1",
- "@sentry/node": "8.2.1",
- "@sentry/opentelemetry": "8.2.1",
- "@sentry/react": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1",
- "@sentry/vercel-edge": "8.2.1",
- "@sentry/webpack-plugin": "2.16.0",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/nextjs/-/nextjs-8.18.0.tgz",
+ "integrity": "sha512-fmBFxaChOWHU/5Mo5X1ASxFVMF3ZjYImJhM+iLWKpw0Yuu9f9T6p8FPPQC2mPerxTX0yHUqTeVlhHufSPjZNEg==",
+ "dependencies": {
+ "@opentelemetry/instrumentation-http": "0.52.1",
+ "@opentelemetry/semantic-conventions": "^1.25.1",
+ "@rollup/plugin-commonjs": "26.0.1",
+ "@sentry/core": "8.18.0",
+ "@sentry/node": "8.18.0",
+ "@sentry/opentelemetry": "8.18.0",
+ "@sentry/react": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0",
+ "@sentry/vercel-edge": "8.18.0",
+ "@sentry/webpack-plugin": "2.20.1",
"chalk": "3.0.0",
"resolve": "1.22.8",
"rollup": "3.29.4",
@@ -8048,8 +7990,7 @@
"node": ">=14.18"
},
"peerDependencies": {
- "next": "^13.2.0 || ^14.0",
- "react": "16.x || 17.x || 18.x",
+ "next": "^13.2.0 || ^14.0 || ^15.0.0-rc.0",
"webpack": ">= 5.0.0"
},
"peerDependenciesMeta": {
@@ -8058,158 +7999,175 @@
}
}
},
- "node_modules/@sentry/nextjs/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "node_modules/@sentry/nextjs/node_modules/@opentelemetry/api": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
+ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
"peer": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@sentry/nextjs/node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@sentry/nextjs/node_modules/@sentry/opentelemetry": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.2.1.tgz",
- "integrity": "sha512-VXc6nOwSoP8ofE9gRrQ7Eaec344jxi+36zJnDDRfjtbX1Ah3XoRuQFwhMSS6nTz5leySXLxgYruZTZhj3r2V2A==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.18.0.tgz",
+ "integrity": "sha512-P2OoXXJcU2RiRZmpBqOkK+NLGkwQrYizlOHl1zckHI1nYmQgOD1tcJj4c1xOYzH+eGPLp/IViXHO6vaBr8BGGg==",
"dependencies": {
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
},
"peerDependencies": {
- "@opentelemetry/api": "^1.8.0",
- "@opentelemetry/core": "^1.24.1",
- "@opentelemetry/instrumentation": "^0.51.1",
- "@opentelemetry/sdk-trace-base": "^1.23.0",
- "@opentelemetry/semantic-conventions": "^1.23.0"
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/core": "^1.25.1",
+ "@opentelemetry/instrumentation": "^0.52.1",
+ "@opentelemetry/sdk-trace-base": "^1.25.1",
+ "@opentelemetry/semantic-conventions": "^1.25.1"
}
},
"node_modules/@sentry/node": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/node/-/node-8.2.1.tgz",
- "integrity": "sha512-7vQQnn+M6qqqWISwrjOaRGx24g9V2Tz+UvrPOWAsZyPBy3kSkuVFef4gHE1geo6CSXMsVpnWkZ8VKJ9I7PaxPg==",
- "dependencies": {
- "@opentelemetry/api": "^1.8.0",
- "@opentelemetry/context-async-hooks": "^1.23.0",
- "@opentelemetry/core": "^1.24.1",
- "@opentelemetry/instrumentation": "^0.51.1",
- "@opentelemetry/instrumentation-connect": "0.36.0",
- "@opentelemetry/instrumentation-express": "0.38.0",
- "@opentelemetry/instrumentation-fastify": "0.36.1",
- "@opentelemetry/instrumentation-graphql": "0.40.0",
- "@opentelemetry/instrumentation-hapi": "0.38.0",
- "@opentelemetry/instrumentation-http": "0.51.1",
- "@opentelemetry/instrumentation-ioredis": "0.40.0",
- "@opentelemetry/instrumentation-koa": "0.40.0",
- "@opentelemetry/instrumentation-mongodb": "0.43.0",
- "@opentelemetry/instrumentation-mongoose": "0.38.1",
- "@opentelemetry/instrumentation-mysql": "0.38.1",
- "@opentelemetry/instrumentation-mysql2": "0.38.1",
- "@opentelemetry/instrumentation-nestjs-core": "0.37.1",
- "@opentelemetry/instrumentation-pg": "0.41.0",
- "@opentelemetry/resources": "^1.23.0",
- "@opentelemetry/sdk-trace-base": "^1.23.0",
- "@opentelemetry/semantic-conventions": "^1.23.0",
- "@prisma/instrumentation": "5.13.0",
- "@sentry/core": "8.2.1",
- "@sentry/opentelemetry": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/node/-/node-8.18.0.tgz",
+ "integrity": "sha512-a+W477bmt28I1DT51xJKmp4Y7hBAdEGqQ2K7gfOn3mRBHoihuhKl2Xe8BMwFH7+v4mAEZEwAZBUOLAC7h+Tjig==",
+ "dependencies": {
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/context-async-hooks": "^1.25.1",
+ "@opentelemetry/core": "^1.25.1",
+ "@opentelemetry/instrumentation": "^0.52.1",
+ "@opentelemetry/instrumentation-connect": "0.38.0",
+ "@opentelemetry/instrumentation-express": "0.41.0",
+ "@opentelemetry/instrumentation-fastify": "0.38.0",
+ "@opentelemetry/instrumentation-graphql": "0.42.0",
+ "@opentelemetry/instrumentation-hapi": "0.40.0",
+ "@opentelemetry/instrumentation-http": "0.52.1",
+ "@opentelemetry/instrumentation-ioredis": "0.42.0",
+ "@opentelemetry/instrumentation-koa": "0.42.0",
+ "@opentelemetry/instrumentation-mongodb": "0.46.0",
+ "@opentelemetry/instrumentation-mongoose": "0.40.0",
+ "@opentelemetry/instrumentation-mysql": "0.40.0",
+ "@opentelemetry/instrumentation-mysql2": "0.40.0",
+ "@opentelemetry/instrumentation-nestjs-core": "0.39.0",
+ "@opentelemetry/instrumentation-pg": "0.43.0",
+ "@opentelemetry/instrumentation-redis-4": "0.41.0",
+ "@opentelemetry/resources": "^1.25.1",
+ "@opentelemetry/sdk-trace-base": "^1.25.1",
+ "@opentelemetry/semantic-conventions": "^1.25.1",
+ "@prisma/instrumentation": "5.16.1",
+ "@sentry/core": "8.18.0",
+ "@sentry/opentelemetry": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
},
"optionalDependencies": {
- "opentelemetry-instrumentation-fetch-node": "1.2.0"
+ "opentelemetry-instrumentation-fetch-node": "1.2.3"
+ }
+ },
+ "node_modules/@sentry/node/node_modules/@opentelemetry/api": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
+ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
+ "engines": {
+ "node": ">=8.0.0"
}
},
"node_modules/@sentry/node/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
- "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
"engines": {
"node": ">=14"
}
},
"node_modules/@sentry/node/node_modules/@sentry/opentelemetry": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.2.1.tgz",
- "integrity": "sha512-VXc6nOwSoP8ofE9gRrQ7Eaec344jxi+36zJnDDRfjtbX1Ah3XoRuQFwhMSS6nTz5leySXLxgYruZTZhj3r2V2A==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.18.0.tgz",
+ "integrity": "sha512-P2OoXXJcU2RiRZmpBqOkK+NLGkwQrYizlOHl1zckHI1nYmQgOD1tcJj4c1xOYzH+eGPLp/IViXHO6vaBr8BGGg==",
"dependencies": {
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
},
"peerDependencies": {
- "@opentelemetry/api": "^1.8.0",
- "@opentelemetry/core": "^1.24.1",
- "@opentelemetry/instrumentation": "^0.51.1",
- "@opentelemetry/sdk-trace-base": "^1.23.0",
- "@opentelemetry/semantic-conventions": "^1.23.0"
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/core": "^1.25.1",
+ "@opentelemetry/instrumentation": "^0.52.1",
+ "@opentelemetry/sdk-trace-base": "^1.25.1",
+ "@opentelemetry/semantic-conventions": "^1.25.1"
}
},
"node_modules/@sentry/react": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.2.1.tgz",
- "integrity": "sha512-kat+Rs4V1DtlGy5rV3aKZ/Kweklqv3E3hsaEd6ZLY5eoqP+ENLiHPEgM7lOaxlPxZclxSHwZQtoB0OtnnNJWYw==",
- "dependencies": {
- "@sentry/browser": "8.2.1",
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.18.0.tgz",
+ "integrity": "sha512-ckCKdxmeFdfR6moE/Aiq+cJyQuCUKoUqU/++xZwqVbgecuImsk4s7CzzpX9T6JoYK7jqru2SvuRSiwcdtLN6AQ==",
+ "dependencies": {
+ "@sentry/browser": "8.18.0",
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0",
"hoist-non-react-statics": "^3.3.2"
},
"engines": {
"node": ">=14.18"
},
"peerDependencies": {
- "react": "16.x || 17.x || 18.x"
+ "react": "^16.14.0 || 17.x || 18.x || 19.x"
}
},
"node_modules/@sentry/types": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.2.1.tgz",
- "integrity": "sha512-22ZuANU6Dj/XSvaGhcmNTKD+6WcMc7Zn5uKd8Oj7YcuME6rOnrU8dPGEVwbGTQkE87mTDjVTDSxl8ipb0L+Eag==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.18.0.tgz",
+ "integrity": "sha512-5J+uOqptnmAnW3Rk31AHIqW36Wzvlo3UOM+p2wjSYGrC/PgcE47Klzr+w4UcOhN6AZqefalGd3vaUXz9NaFdRg==",
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/utils": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.2.1.tgz",
- "integrity": "sha512-qFeiCdo+QUVpwNSwe63LOPEKc8GWmJ051twtV3tfZ62XgUYOOi2C0qC6mliY3+GKiGVV8fQE6S930nM//j7G1w==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.18.0.tgz",
+ "integrity": "sha512-7wq7cgaeSIGJncl9/2VMu81ZN5ep4lp4H1/+O8+xUxOmnPb/05ZZcbn9/VxVQvIoqZSZdwCLPeBz6PEVukvokA==",
"dependencies": {
- "@sentry/types": "8.2.1"
+ "@sentry/types": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/vercel-edge": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@sentry/vercel-edge/-/vercel-edge-8.2.1.tgz",
- "integrity": "sha512-+zcAfYhqJ0K/4dZOYYLMjGp8dZMcqCIiM0qk7a0sqg0Bc/Eta9qJjGpIBx0yVM3pV3XosYqbf2clseO/NjwvmQ==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@sentry/vercel-edge/-/vercel-edge-8.18.0.tgz",
+ "integrity": "sha512-V8jPZNWI93sf1u1sYLAg62oD7Jxw6uGT5bPPHBHbF2XmowW8sIyuXmkXYKVy+s6sOPCyJoW3/0j4BFf/qLowsg==",
"dependencies": {
- "@sentry/core": "8.2.1",
- "@sentry/types": "8.2.1",
- "@sentry/utils": "8.2.1"
+ "@sentry/core": "8.18.0",
+ "@sentry/types": "8.18.0",
+ "@sentry/utils": "8.18.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/webpack-plugin": {
- "version": "2.16.0",
- "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-2.16.0.tgz",
- "integrity": "sha512-BeKLmtK4OD9V3j92fm/lm6yp+++s2U5Uf17HwNFGt39PEOq+wUDISsx0dhXA5Qls2Bg3WhguDK71blCaVefMeg==",
+ "version": "2.20.1",
+ "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-2.20.1.tgz",
+ "integrity": "sha512-U6LzoE09Ndt0OCWROoRaZqqIHGxyMRdKpBhbqoBqyyfVwXN/zGW3I/cWZ1e8rreiKFj+2+c7+X0kOS+NGMTUrg==",
"dependencies": {
- "@sentry/bundler-plugin-core": "2.16.0",
+ "@sentry/bundler-plugin-core": "2.20.1",
"unplugin": "1.0.1",
"uuid": "^9.0.0"
},
@@ -8221,9 +8179,9 @@
}
},
"node_modules/@sentry/webpack-plugin/node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"bin": {
"acorn": "bin/acorn"
},
@@ -9259,15 +9217,6 @@
"undici-types": "~5.26.4"
}
},
- "node_modules/@storybook/builder-webpack5/node_modules/magic-string": {
- "version": "0.30.10",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
- "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
- }
- },
"node_modules/@storybook/builder-webpack5/node_modules/semver": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
@@ -10070,15 +10019,6 @@
"undici-types": "~5.26.4"
}
},
- "node_modules/@storybook/preset-react-webpack/node_modules/magic-string": {
- "version": "0.30.10",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
- "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
- }
- },
"node_modules/@storybook/preset-react-webpack/node_modules/semver": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
@@ -10572,14 +10512,6 @@
"optional": true,
"peer": true
},
- "node_modules/@types/accepts": {
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz",
- "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==",
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/@types/adm-zip": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.5.tgz",
@@ -10640,6 +10572,7 @@
"version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
+ "dev": true,
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
@@ -10660,31 +10593,16 @@
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "dev": true,
"dependencies": {
"@types/node": "*"
}
},
- "node_modules/@types/content-disposition": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz",
- "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg=="
- },
"node_modules/@types/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
},
- "node_modules/@types/cookies": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz",
- "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==",
- "dependencies": {
- "@types/connect": "*",
- "@types/express": "*",
- "@types/keygrip": "*",
- "@types/node": "*"
- }
- },
"node_modules/@types/cross-spawn": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz",
@@ -10739,6 +10657,7 @@
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
+ "dev": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -10750,6 +10669,7 @@
"version": "4.17.41",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
"integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
+ "dev": true,
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
@@ -10790,15 +10710,11 @@
"integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==",
"dev": true
},
- "node_modules/@types/http-assert": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz",
- "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g=="
- },
"node_modules/@types/http-errors": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
- "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="
+ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
+ "dev": true
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.6",
@@ -10920,42 +10836,6 @@
"integrity": "sha512-I/WFyFgk5GrNbkpmt14auGO3yFK1Wt4jXzkLuI+fDBNtO5ZI2rbymyGd6bKzfSBEuyRdM64ZUwxU1+eDcPSOEQ==",
"dev": true
},
- "node_modules/@types/keygrip": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz",
- "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ=="
- },
- "node_modules/@types/koa": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.14.0.tgz",
- "integrity": "sha512-DTDUyznHGNHAl+wd1n0z1jxNajduyTh8R53xoewuerdBzGo6Ogj6F2299BFtrexJw4NtgjsI5SMPCmV9gZwGXA==",
- "dependencies": {
- "@types/accepts": "*",
- "@types/content-disposition": "*",
- "@types/cookies": "*",
- "@types/http-assert": "*",
- "@types/http-errors": "*",
- "@types/keygrip": "*",
- "@types/koa-compose": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/koa__router": {
- "version": "12.0.3",
- "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-12.0.3.tgz",
- "integrity": "sha512-5YUJVv6NwM1z7m6FuYpKfNLTZ932Z6EF6xy2BbtpJSyn13DKNQEkXVffFVSnJHxvwwWh2SAeumpjAYUELqgjyw==",
- "dependencies": {
- "@types/koa": "*"
- }
- },
- "node_modules/@types/koa-compose": {
- "version": "3.2.8",
- "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz",
- "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==",
- "dependencies": {
- "@types/koa": "*"
- }
- },
"node_modules/@types/lodash": {
"version": "4.14.202",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz",
@@ -10976,7 +10856,8 @@
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
- "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true
},
"node_modules/@types/mjml": {
"version": "4.7.4",
@@ -11059,12 +10940,14 @@
"node_modules/@types/qs": {
"version": "6.9.10",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
- "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw=="
+ "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==",
+ "dev": true
},
"node_modules/@types/range-parser": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
- "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true
},
"node_modules/@types/react": {
"version": "18.2.79",
@@ -11123,6 +11006,7 @@
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
+ "dev": true,
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
@@ -11132,6 +11016,7 @@
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
"integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
+ "dev": true,
"dependencies": {
"@types/http-errors": "*",
"@types/mime": "*",
@@ -11139,9 +11024,9 @@
}
},
"node_modules/@types/shimmer": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.5.tgz",
- "integrity": "sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww=="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz",
+ "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg=="
},
"node_modules/@types/stack-utils": {
"version": "2.0.3",
@@ -17061,18 +16946,19 @@
"dev": true
},
"node_modules/glob": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
- "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^5.0.1",
- "once": "^1.3.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
},
- "engines": {
- "node": ">=12"
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -17102,15 +16988,40 @@
"balanced-match": "^1.0.0"
}
},
+ "node_modules/glob/node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
"node_modules/glob/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/global-modules": {
@@ -17816,9 +17727,9 @@
}
},
"node_modules/import-in-the-middle": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz",
- "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==",
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.9.1.tgz",
+ "integrity": "sha512-E+3tEOutU1MV0mxhuCwfSPNNWRkbTJ3/YyL5be+blNIbHwZc53uYHQfuIhAU77xWR0BoF2eT7cqDJ6VlU5APPg==",
"dependencies": {
"acorn": "^8.8.2",
"acorn-import-attributes": "^1.9.5",
@@ -17827,9 +17738,9 @@
}
},
"node_modules/import-in-the-middle/node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"bin": {
"acorn": "bin/acorn"
},
@@ -20110,49 +20021,6 @@
"node": ">=14"
}
},
- "node_modules/js-beautify/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/js-beautify/node_modules/glob": {
- "version": "10.3.10",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
- "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^2.3.5",
- "minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
- "path-scurry": "^1.10.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/js-beautify/node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/js-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
@@ -21317,14 +21185,11 @@
}
},
"node_modules/magic-string": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
- "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+ "version": "0.30.10",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
+ "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.13"
- },
- "engines": {
- "node": ">=12"
+ "@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"node_modules/make-dir": {
@@ -21713,27 +21578,6 @@
"balanced-match": "^1.0.0"
}
},
- "node_modules/mjml-cli/node_modules/glob": {
- "version": "10.3.10",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
- "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^2.3.5",
- "minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
- "path-scurry": "^1.10.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/mjml-cli/node_modules/minimatch": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
@@ -22890,27 +22734,29 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/opentelemetry-instrumentation-fetch-node": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/opentelemetry-instrumentation-fetch-node/-/opentelemetry-instrumentation-fetch-node-1.2.0.tgz",
- "integrity": "sha512-aiSt/4ubOTyb1N5C2ZbGrBvaJOXIZhZvpRPYuUVxQJe27wJZqf/o65iPrqgLcgfeOLaQ8cS2Q+762jrYvniTrA==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/opentelemetry-instrumentation-fetch-node/-/opentelemetry-instrumentation-fetch-node-1.2.3.tgz",
+ "integrity": "sha512-Qb11T7KvoCevMaSeuamcLsAD+pZnavkhDnlVL0kRozfhl42dKG5Q3anUklAFKJZjY3twLR+BnRa6DlwwkIE/+A==",
"optional": true,
"dependencies": {
- "@opentelemetry/api": "^1.6.0",
- "@opentelemetry/instrumentation": "^0.43.0",
+ "@opentelemetry/instrumentation": "^0.46.0",
"@opentelemetry/semantic-conventions": "^1.17.0"
},
"engines": {
"node": ">18.0.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.6.0"
}
},
"node_modules/opentelemetry-instrumentation-fetch-node/node_modules/@opentelemetry/instrumentation": {
- "version": "0.43.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.43.0.tgz",
- "integrity": "sha512-S1uHE+sxaepgp+t8lvIDuRgyjJWisAb733198kwQTUc9ZtYQ2V2gmyCtR1x21ePGVLoMiX/NWY7WA290hwkjJQ==",
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.46.0.tgz",
+ "integrity": "sha512-a9TijXZZbk0vI5TGLZl+0kxyFfrXHhX6Svtz7Pp2/VBlCSKrazuULEyoJQrOknJyFWNMEmbbJgOciHCCpQcisw==",
"optional": true,
"dependencies": {
"@types/shimmer": "^1.0.2",
- "import-in-the-middle": "1.4.2",
+ "import-in-the-middle": "1.7.1",
"require-in-the-middle": "^7.1.1",
"semver": "^7.5.2",
"shimmer": "^1.2.1"
@@ -22923,9 +22769,9 @@
}
},
"node_modules/opentelemetry-instrumentation-fetch-node/node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"optional": true,
"bin": {
"acorn": "bin/acorn"
@@ -22944,9 +22790,9 @@
}
},
"node_modules/opentelemetry-instrumentation-fetch-node/node_modules/import-in-the-middle": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz",
- "integrity": "sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==",
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.1.tgz",
+ "integrity": "sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==",
"optional": true,
"dependencies": {
"acorn": "^8.8.2",
@@ -22956,9 +22802,9 @@
}
},
"node_modules/opentelemetry-instrumentation-fetch-node/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"optional": true,
"bin": {
"semver": "bin/semver.js"
@@ -23098,6 +22944,11 @@
"node": ">=6"
}
},
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
+ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw=="
+ },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
diff --git a/package.json b/package.json
index 6d1ec52a639..881e2e85f2e 100644
--- a/package.json
+++ b/package.json
@@ -70,7 +70,7 @@
"@leeoniya/ufuzzy": "^1.0.14",
"@mozilla/glean": "^5.0.2",
"@next/third-parties": "^14.2.5",
- "@sentry/nextjs": "^8.2.1",
+ "@sentry/nextjs": "^8.18.0",
"@sentry/node": "^8.0.0",
"@sentry/utils": "^8.0.0",
"@stripe/stripe-js": "^4.0.0",
From c264e69281d949da76cf13f9a76bab10c1d0145f Mon Sep 17 00:00:00 2001
From: Vincent
Date: Tue, 16 Jul 2024 13:57:08 +0200
Subject: [PATCH 103/137] Sort-of port update-remote-settings cron to TS
The request was to port it to TypeScript even though this code
couldn't run yet, because we might be enabling this again soonish.
Thus, this ports it to TypeScript, recovers the module that it
referenced but no longer existed, replaces that module's use of the
`got` package with `fetch`, and ensures it builds. I don't have the
right access to be able to verify that it actually runs as expected
though.
---
package.json | 3 +-
scripts/updatebreaches.js | 57 -------
.../updateBreachesInRemoteSettings.ts | 149 ++++++++++++++++++
3 files changed, 151 insertions(+), 58 deletions(-)
delete mode 100644 scripts/updatebreaches.js
create mode 100644 src/scripts/cronjobs/updateBreachesInRemoteSettings.ts
diff --git a/package.json b/package.json
index 881e2e85f2e..ac5bfa839e6 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"dev:cron:monthly-activity": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/monthlyActivity.tsx",
"dev:cron:db-delete-unverified-subscribers": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/deleteUnverifiedSubscribers.ts",
"dev:cron:db-pull-breaches": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/syncBreaches.ts",
+ "dev:cron:remote-settings-pull-breaches": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/updateBreachesInRemoteSettings.ts",
"dev:cron:onerep-limits-alert": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/onerepStatsAlert.ts",
"dev:nimbus": "node --watch-path config/nimbus.yaml src/scripts/build/nimbusTypes.js",
"build": "npm run get-location-data && npm run build-glean && npm run build-nimbus && next build && npm run build-cronjobs",
@@ -29,7 +30,7 @@
"cron:breach-alerts": "node src/scripts/emailBreachAlerts.js",
"cron:db-delete-unverified-subscribers": "node dist/scripts/cronjobs/deleteUnverifiedSubscribers.js",
"cron:db-pull-breaches": "node dist/scripts/cronjobs/syncBreaches.js",
- "cron:remote-settings-pull-breaches": "node scripts/updatebreaches.js",
+ "cron:remote-settings-pull-breaches": "node dist/scripts/cronjobs/updateBreachesInRemoteSettings.js",
"cron:onerep-limits-alert": "node dist/scripts/cronjobs/onerepStatsAlert.js",
"db:migrate": "node -r dotenv-flow/config node_modules/knex/bin/cli.js migrate:latest --knexfile src/db/knexfile.js",
"db:rollback": "node -r dotenv-flow/config node_modules/knex/bin/cli.js migrate:rollback --knexfile src/db/knexfile.js",
diff --git a/scripts/updatebreaches.js b/scripts/updatebreaches.js
deleted file mode 100644
index d870c653faa..00000000000
--- a/scripts/updatebreaches.js
+++ /dev/null
@@ -1,57 +0,0 @@
-'use strict'
-
-/**
- * Cron: Daily
- * From all the HIBP breaches, we parse out the new breaches that are not already present
- * in firefox remote settings, and update the data source accordingly
- */
-const AppConstants = require('../app-constants')
-const HIBP = require('../hibp')
-const RemoteSettings = require('../lib/remote-settings')
-
-if (
- !AppConstants.FX_REMOTE_SETTINGS_WRITER_USER ||
- !AppConstants.FX_REMOTE_SETTINGS_WRITER_PASS ||
- !AppConstants.FX_REMOTE_SETTINGS_WRITER_SERVER
-) {
- console.error('updatebreaches requires FX_REMOTE_SETTINGS_WRITER_SERVER, FX_REMOTE_SETTINGS_WRITER_USER, FX_REMOTE_SETTINGS_WRITER_PASS.')
- process.exit(1)
-}
-
-(async () => {
- const allHibpBreaches = await HIBP.req('/breaches')
- const verifiedSiteBreaches = HIBP.filterBreaches(allHibpBreaches.body)
- const verifiedSiteBreachesWithPWs = verifiedSiteBreaches.filter(breach => breach.DataClasses.includes('Passwords'))
-
- const newBreaches = await RemoteSettings.whichBreachesAreNotInRemoteSettingsYet(verifiedSiteBreachesWithPWs)
-
- if (newBreaches.length <= 0) {
- console.log('No new breaches detected.')
- process.exit(0)
- }
-
- console.log(`${newBreaches.length} new breach(es) found.`)
-
- for (const breach of newBreaches) {
- const data = {
- Name: breach.Name,
- Domain: breach.Domain,
- BreachDate: breach.BreachDate,
- PwnCount: breach.PwnCount,
- AddedDate: breach.AddedDate,
- DataClasses: breach.DataClasses
- }
-
- console.log('New breach detected: \n', data)
-
- try {
- await RemoteSettings.postNewBreachToBreachesCollection(data)
- } catch (e) {
- console.error(e)
- process.exit(1)
- }
- }
-
- console.log('Requesting review on breaches collection')
- await RemoteSettings.requestReviewOnBreachesCollection()
-})()
diff --git a/src/scripts/cronjobs/updateBreachesInRemoteSettings.ts b/src/scripts/cronjobs/updateBreachesInRemoteSettings.ts
new file mode 100644
index 00000000000..74c2738e82e
--- /dev/null
+++ b/src/scripts/cronjobs/updateBreachesInRemoteSettings.ts
@@ -0,0 +1,149 @@
+"use strict";
+
+/**
+ * Cron: Daily
+ * From all the HIBP breaches, we parse out the new breaches that are not already present
+ * in firefox remote settings, and update the data source accordingly
+ */
+
+/*
+ *
+ *
+ *
+ *
+ *********************************** Warning ***********************************
+ *
+ * This script was in the repository unused, and referenced a module
+ * `remote-settings.js` that no longer existed at the time of writing (it was
+ * deleted in commit c727bfe968937e51b0cd42efefd010c7c401aeae).
+ * I dug it up from the Git history, inlined it in this file, and made sure
+ * it compiled, but I didn't get to actually run it.
+ *
+ * Thus, it could be used as a starting point when re-enabling the remote
+ * settings upload, but shouldn't be expected to work without modifications.
+ *
+ *********************************** Warning ***********************************
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+import AppConstants from "../../appConstants";
+import * as HIBP from "../../utils/hibp";
+import type { Breach } from "../../app/functions/universal/breach";
+
+type RemoteSettingsBreach = Pick<
+ Breach,
+ "Name" | "Domain" | "BreachDate" | "PwnCount" | "AddedDate" | "DataClasses"
+>;
+
+const BREACHES_COLLECTION = "fxmonitor-breaches";
+const FX_RS_COLLECTION = `${AppConstants.FX_REMOTE_SETTINGS_WRITER_SERVER}/buckets/main-workspace/collections/${BREACHES_COLLECTION}`;
+const FX_RS_RECORDS = `${FX_RS_COLLECTION}/records`;
+const FX_RS_WRITER_USER = AppConstants.FX_REMOTE_SETTINGS_WRITER_USER;
+const FX_RS_WRITER_PASS = AppConstants.FX_REMOTE_SETTINGS_WRITER_PASS;
+
+async function whichBreachesAreNotInRemoteSettingsYet(breaches: Breach[]) {
+ const response = await fetch(FX_RS_RECORDS, {
+ headers: {
+ Authorization: `Basic ${Buffer.from(FX_RS_WRITER_USER + ":" + FX_RS_WRITER_PASS).toString("base64")}`,
+ },
+ });
+ const fxRSRecords = await response.json();
+ const remoteSettingsBreachesSet = new Set(
+ fxRSRecords.body.data.map((b: Breach) => b.Name),
+ );
+
+ return breaches.filter(({ Name }) => !remoteSettingsBreachesSet.has(Name));
+}
+
+async function postNewBreachToBreachesCollection(data: RemoteSettingsBreach) {
+ // Create the record
+ const response = await fetch(FX_RS_RECORDS, {
+ method: "POST",
+ body: JSON.stringify(data),
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Basic ${Buffer.from(FX_RS_WRITER_USER + ":" + FX_RS_WRITER_PASS).toString("base64")}`,
+ },
+ });
+ return response.json();
+}
+
+async function requestReviewOnBreachesCollection() {
+ const response = await fetch(FX_RS_COLLECTION, {
+ method: "PATCH",
+ body: JSON.stringify({ data: { status: "to-review" } }),
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Basic ${Buffer.from(FX_RS_WRITER_USER + ":" + FX_RS_WRITER_PASS).toString("base64")}`,
+ },
+ });
+ return response.json();
+}
+
+if (
+ !AppConstants.FX_REMOTE_SETTINGS_WRITER_USER ||
+ !AppConstants.FX_REMOTE_SETTINGS_WRITER_PASS ||
+ !AppConstants.FX_REMOTE_SETTINGS_WRITER_SERVER
+) {
+ console.error(
+ "updatebreaches requires FX_REMOTE_SETTINGS_WRITER_SERVER, FX_REMOTE_SETTINGS_WRITER_USER, FX_REMOTE_SETTINGS_WRITER_PASS.",
+ );
+ process.exit(1);
+}
+
+(async () => {
+ const allHibpBreaches = (await HIBP.req("/breaches")) as { body: Breach[] };
+ const verifiedSiteBreaches = allHibpBreaches.body.filter((breach) => {
+ return (
+ !breach.IsRetired &&
+ !breach.IsSpamList &&
+ !breach.IsFabricated &&
+ breach.IsVerified &&
+ breach.Domain !== ""
+ );
+ });
+ const verifiedSiteBreachesWithPWs = verifiedSiteBreaches.filter((breach) =>
+ breach.DataClasses.includes("Passwords"),
+ );
+
+ const newBreaches = await whichBreachesAreNotInRemoteSettingsYet(
+ verifiedSiteBreachesWithPWs,
+ );
+
+ if (newBreaches.length <= 0) {
+ console.log("No new breaches detected.");
+ process.exit(0);
+ }
+
+ console.log(`${newBreaches.length} new breach(es) found.`);
+
+ for (const breach of newBreaches) {
+ const data: RemoteSettingsBreach = {
+ Name: breach.Name,
+ Domain: breach.Domain,
+ BreachDate: breach.BreachDate,
+ PwnCount: breach.PwnCount,
+ AddedDate: breach.AddedDate,
+ DataClasses: breach.DataClasses,
+ };
+
+ console.log("New breach detected: \n", data);
+
+ try {
+ await postNewBreachToBreachesCollection(data);
+ } catch (e) {
+ console.error(e);
+ process.exit(1);
+ }
+ }
+
+ console.log("Requesting review on breaches collection");
+ await requestReviewOnBreachesCollection();
+})();
From 95afc7ff30ca6e505e6cc218c77e5e4dfea8693e Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Thu, 18 Jul 2024 09:24:01 -0700
Subject: [PATCH 104/137] fix: use account uri
---
src/utils/fxa.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/utils/fxa.js b/src/utils/fxa.js
index d2a8e281a19..b8a49a6effc 100644
--- a/src/utils/fxa.js
+++ b/src/utils/fxa.js
@@ -126,7 +126,7 @@ async function getSubscriptions(bearerToken) {
*/
async function getBillingAndSubscriptions(bearerToken) {
- const subscriptionIdUrl = `${process.env.OAUTH_API_URI}/oauth/mozilla-subscriptions/customer/billing-and-subscriptions`
+ const subscriptionIdUrl = `${process.env.OAUTH_ACCOUNT_URI}/oauth/mozilla-subscriptions/customer/billing-and-subscriptions`
try {
const getResp = await fetch(subscriptionIdUrl, {
From b1ad919acb03183bf5df3c78187219b535672394 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Thu, 18 Jul 2024 09:31:23 -0700
Subject: [PATCH 105/137] fix: consistency
---
src/utils/fxa.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/utils/fxa.js b/src/utils/fxa.js
index b8a49a6effc..4ab47dba7c4 100644
--- a/src/utils/fxa.js
+++ b/src/utils/fxa.js
@@ -126,7 +126,7 @@ async function getSubscriptions(bearerToken) {
*/
async function getBillingAndSubscriptions(bearerToken) {
- const subscriptionIdUrl = `${process.env.OAUTH_ACCOUNT_URI}/oauth/mozilla-subscriptions/customer/billing-and-subscriptions`
+ const subscriptionIdUrl = `${AppConstants.OAUTH_ACCOUNT_URI}/oauth/mozilla-subscriptions/customer/billing-and-subscriptions`
try {
const getResp = await fetch(subscriptionIdUrl, {
From 70ee0686f279a5a1a52cd9ac16718b95c62fb9e5 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Thu, 18 Jul 2024 09:41:05 -0700
Subject: [PATCH 106/137] fix: get rid of API URI
---
.env | 1 -
.env.local.example | 1 -
.github/workflows/preview_deploy_gcp.yml | 1 -
3 files changed, 3 deletions(-)
diff --git a/.env b/.env
index e7538055d1d..fa101866a92 100755
--- a/.env
+++ b/.env
@@ -40,7 +40,6 @@ OAUTH_AUTHORIZATION_URI=https://oauth.stage.mozaws.net/v1/authorization
OAUTH_PROFILE_URI=https://profile.stage.mozaws.net/v1/profile
OAUTH_TOKEN_URI=https://oauth.stage.mozaws.net/v1/token
OAUTH_ACCOUNT_URI = "https://oauth.accounts.firefox.com/v1"
-OAUTH_API_URI="https://api-accounts.stage.mozaws.net/v1"
# HIBP API for breach data
# How many seconds to wait before refreshing upstream breach data from HIBP
diff --git a/.env.local.example b/.env.local.example
index 1a82ca694a7..804444bffc8 100644
--- a/.env.local.example
+++ b/.env.local.example
@@ -64,7 +64,6 @@ PREMIUM_PLAN_ID_YEARLY_US=price_1NvqawKb9q6OnNsLRTnYrtrV
FXA_SUBSCRIPTIONS_URL=https://accounts.stage.mozaws.net/subscriptions
FXA_SETTINGS_URL=https://accounts.stage.mozaws.net/settings
OAUTH_CLIENT_ID=edd29a80019d61a1
-OAUTH_API_URI="https://api-accounts.stage.mozaws.net/v1"
# Set based on https://accounts.stage.mozaws.net/.well-known/openid-configuration
OAUTH_AUTHORIZATION_URI=https://accounts.stage.mozaws.net/authorization
OAUTH_PROFILE_URI=https://profile.stage.mozaws.net/v1/profile
diff --git a/.github/workflows/preview_deploy_gcp.yml b/.github/workflows/preview_deploy_gcp.yml
index 9f7bbf5ef70..c6fdef23a32 100644
--- a/.github/workflows/preview_deploy_gcp.yml
+++ b/.github/workflows/preview_deploy_gcp.yml
@@ -63,7 +63,6 @@ jobs:
NEXTAUTH_URL= ${{ secrets.NEXTAUTH_URL }}
NEXTAUTH_SECRET=${{ secrets.NEXTAUTH_SECRET }}
OAUTH_ACCOUNT_URI=${{ secrets.OAUTH_ACCOUNT_URI }}
- OAUTH_API_URI=${{ secrets.OAUTH_API_URI }}
OAUTH_CLIENT_ID=${{ secrets.OAUTH_CLIENT_ID }}
OAUTH_CLIENT_SECRET=${{ secrets.OAUTH_CLIENT_SECRET }}
ONEREP_API_KEY=${{ secrets.ONEREP_API_KEY }}
From 53b00c772b6f505dfcb0e0286ffea28b46ee87de Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 9 Jul 2024 08:59:15 +0000
Subject: [PATCH 107/137] chore(deps): bump node from 22.3-alpine to
22.4-alpine
Bumps node from 22.3-alpine to 22.4-alpine.
---
updated-dependencies:
- dependency-name: node
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
---
Dockerfile | 2 +-
Dockerfile.cloudrun | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 5f49577777f..6df05dc6dea 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:22.3-alpine
+FROM node:22.4-alpine
RUN addgroup -g 10001 app && \
adduser -D -G app -h /app -u 10001 app
diff --git a/Dockerfile.cloudrun b/Dockerfile.cloudrun
index dc0b8110a6d..179005eac42 100644
--- a/Dockerfile.cloudrun
+++ b/Dockerfile.cloudrun
@@ -1,4 +1,4 @@
-FROM node:22.3-alpine
+FROM node:22.4-alpine
RUN addgroup -g 10001 app && \
adduser -D -G app -h /app -u 10001 app
From 70269cccd32025c7ca7ae5c62dc8c33c8b3ef373 Mon Sep 17 00:00:00 2001
From: Robert Helmer
Date: Wed, 10 Jul 2024 08:42:12 -0700
Subject: [PATCH 108/137] bump to node 22.4.1 and npm 10.8.1
---
.github/workflows/build.yaml | 2 +-
.github/workflows/e2e_cron.yml | 2 +-
.github/workflows/e2e_pr.yml | 2 +-
.github/workflows/lint.yaml | 2 +-
.github/workflows/unittests.yaml | 2 +-
esbuild.cronjobs.js | 2 +-
netlify.toml | 2 +-
package-lock.json | 2 +-
package.json | 6 +++---
9 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 053c5070923..e22647197ec 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.3.x'
+ node-version: '22.4.x'
- run: npm ci
- run: npm run build-glean
# Verify that the build (incl. type-checking) succeeds
diff --git a/.github/workflows/e2e_cron.yml b/.github/workflows/e2e_cron.yml
index 1e4b93b7d8e..08f68c3dd61 100644
--- a/.github/workflows/e2e_cron.yml
+++ b/.github/workflows/e2e_cron.yml
@@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 22.3
+ node-version: 22.4
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/e2e_pr.yml b/.github/workflows/e2e_pr.yml
index 8dca4b381d7..d6f3986c6c6 100644
--- a/.github/workflows/e2e_pr.yml
+++ b/.github/workflows/e2e_pr.yml
@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 22.3
+ node-version: 22.4
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index e5827c7cabb..c97a575e6fd 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.3.x'
+ node-version: '22.4.x'
- run: npm ci
- run: npm run build-glean
- run: npm run build-nimbus
diff --git a/.github/workflows/unittests.yaml b/.github/workflows/unittests.yaml
index c934ad1fac3..8bcc252faeb 100644
--- a/.github/workflows/unittests.yaml
+++ b/.github/workflows/unittests.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.3.x'
+ node-version: '22.4.x'
- run: npm ci
- run: npm run build-glean
- run: npm test
diff --git a/esbuild.cronjobs.js b/esbuild.cronjobs.js
index b8be0739677..dcbea0261b0 100644
--- a/esbuild.cronjobs.js
+++ b/esbuild.cronjobs.js
@@ -21,6 +21,6 @@ build({
format: "esm",
outdir: "dist/scripts/cronjobs/",
sourcemap: true,
- target: "node22.3",
+ target: "node22.4",
packages: "external",
});
diff --git a/netlify.toml b/netlify.toml
index 8f21f1b47a8..1957208e9d3 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -18,4 +18,4 @@
# Default build command.
command = "npm ci; npm run build-storybook"
- environment = { NODE_VERSION = "22.3.0", NPM_VERSION = "10.8.0" }
+ environment = { NODE_VERSION = "22.4.1", NPM_VERSION = "10.8.1" }
diff --git a/package-lock.json b/package-lock.json
index bcae66a0f75..93df26589f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -105,7 +105,7 @@
"yaml": "^2.4.5"
},
"engines": {
- "node": "22.3.x",
+ "node": "22.4.x",
"npm": "10.8.x"
}
},
diff --git a/package.json b/package.json
index ac5bfa839e6..d24420e07e9 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "Firefox Monitor",
"engines": {
- "node": "22.3.x",
+ "node": "22.4.x",
"npm": "10.8.x"
},
"type": "module",
@@ -56,8 +56,8 @@
"homepage": "https://github.com/mozilla/blurts-server",
"license": "MPL-2.0",
"volta": {
- "node": "22.3.0",
- "npm": "10.8.0"
+ "node": "22.4.1",
+ "npm": "10.8.1"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.614.0",
From fe6b56064d59327914143ba9f8480a457c12ab17 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Thu, 18 Jul 2024 16:14:24 -0700
Subject: [PATCH 109/137] fix: typo
---
.github/workflows/production_deploy.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/production_deploy.yml b/.github/workflows/production_deploy.yml
index 3e29b551b4b..fe87ef491c5 100644
--- a/.github/workflows/production_deploy.yml
+++ b/.github/workflows/production_deploy.yml
@@ -34,7 +34,7 @@ jobs:
run: docker pull ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.originalImageTag }}
- name: Retag image
- run: docker tag ${{ env.DOCKER_IMAGE_NAME }}${{ inputs.originalImageTag }} ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.environment }}-${{ inputs.originalImageTag }}
+ run: docker tag ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.originalImageTag }} ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.environment }}-${{ inputs.originalImageTag }}
- name: Redeploy image
run: docker push ${{ env.DOCKER_IMAGE_NAME }}:${{ inputs.environment }}-${{ inputs.originalImageTag }}
\ No newline at end of file
From bb4e3db0e30f0f6941f4dbcc89f295a552f00b29 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Thu, 18 Jul 2024 17:52:28 -0700
Subject: [PATCH 110/137] fix: avoid crashing with profile call
---
src/app/functions/server/onerep.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/app/functions/server/onerep.ts b/src/app/functions/server/onerep.ts
index be35d5379b8..c83ba353d63 100644
--- a/src/app/functions/server/onerep.ts
+++ b/src/app/functions/server/onerep.ts
@@ -477,9 +477,9 @@ export async function getProfilesStats(
logger.error(
`Failed to fetch OneRep profile: [${response.status}] [${response.statusText}]`,
);
- throw new Error(
- `Failed to fetch OneRep profile: [${response.status}] [${response.statusText}]`,
- );
+ // throw new Error(
+ // `Failed to fetch OneRep profile: [${response.status}] [${response.statusText}]`,
+ // );
}
const profileStats: ProfileStats = await response.json();
From d31f7f5a3f5e1d417c1d7a45787c0ed08492b7e9 Mon Sep 17 00:00:00 2001
From: Joey Zhou
Date: Thu, 18 Jul 2024 17:52:58 -0700
Subject: [PATCH 111/137] fix: avoid crashing with profile call
---
src/app/functions/server/onerep.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/app/functions/server/onerep.ts b/src/app/functions/server/onerep.ts
index c83ba353d63..5137553c123 100644
--- a/src/app/functions/server/onerep.ts
+++ b/src/app/functions/server/onerep.ts
@@ -475,10 +475,10 @@ export async function getProfilesStats(
);
if (!response.ok) {
logger.error(
- `Failed to fetch OneRep profile: [${response.status}] [${response.statusText}]`,
+ `Failed to fetch OneRep profile stats: [${response.status}] [${response.statusText}]`,
);
// throw new Error(
- // `Failed to fetch OneRep profile: [${response.status}] [${response.statusText}]`,
+ // `Failed to fetch OneRep profile stats: [${response.status}] [${response.statusText}]`,
// );
}
From f0c641071edba69db62778e59e2052ee44e4d24b Mon Sep 17 00:00:00 2001
From: Florian Zia
Date: Fri, 19 Jul 2024 03:30:34 +0200
Subject: [PATCH 112/137] chore: Add unit test coverage
---
.../(redesign)/(public)/FreeScanCta.tsx | 25 +++++--------
.../(redesign)/(public)/LandingView.test.tsx | 37 ++++++++++++++++++-
.../(redesign)/(public)/LandingView.tsx | 5 ---
.../(redesign)/(public)/SignUpForm.tsx | 18 +++------
src/app/hooks/useViewTelemetry.ts | 5 +++
5 files changed, 56 insertions(+), 34 deletions(-)
diff --git a/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx b/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx
index be4ddc2d119..7f715142692 100644
--- a/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx
+++ b/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx
@@ -6,24 +6,14 @@
import { signIn } from "next-auth/react";
import { useCookies } from "react-cookie";
-import { SignUpForm, Props as SignUpFormProps } from "./SignUpForm";
+import { Props, SignUpForm } from "./SignUpForm";
import { TelemetryButton } from "../../../components/client/TelemetryButton";
import { modifyAttributionsForUrlSearchParams } from "../../../functions/universal/attributions";
import { ExperimentData } from "../../../../telemetry/generated/nimbus/experiments";
import { useL10n } from "../../../hooks/l10n";
import { WaitlistCta } from "./ScanLimit";
-
-export type Props = {
- eligibleForPremium: boolean;
- signUpCallbackUrl: string;
- isHero?: boolean;
- eventId: {
- cta: string;
- field?: string;
- };
- scanLimitReached: boolean;
- placeholder?: string;
-};
+import { useViewTelemetry } from "../../../hooks/useViewTelemetry";
+import { RefObject } from "react";
export function getAttributionSearchParams({
cookies,
@@ -60,12 +50,16 @@ export function getAttributionSearchParams({
}
export const FreeScanCta = (
- props: SignUpFormProps & {
+ props: Props & {
experimentData: ExperimentData;
},
) => {
const l10n = useL10n();
const [cookies] = useCookies(["attributionsFirstTouch"]);
+ const telemetryButtonId = `${props.eventId.cta}-${props.experimentData["landing-page-free-scan-cta"].variant}`;
+ const refViewTelemetry = useViewTelemetry("ctaButton", {
+ button_id: telemetryButtonId,
+ });
if (
!props.experimentData["landing-page-free-scan-cta"].enabled ||
props.experimentData["landing-page-free-scan-cta"].variant ===
@@ -88,12 +82,13 @@ export const FreeScanCta = (
) : (
}
variant="primary"
event={{
module: "ctaButton",
name: "click",
data: {
- button_id: `${props.eventId.cta}-${props.experimentData["landing-page-free-scan-cta"].variant}`,
+ button_id: telemetryButtonId,
},
}}
onPress={() => {
diff --git a/src/app/(proper_react)/(redesign)/(public)/LandingView.test.tsx b/src/app/(proper_react)/(redesign)/(public)/LandingView.test.tsx
index cff25795f40..3793bf44a68 100644
--- a/src/app/(proper_react)/(redesign)/(public)/LandingView.test.tsx
+++ b/src/app/(proper_react)/(redesign)/(public)/LandingView.test.tsx
@@ -5,6 +5,7 @@
import { it, expect } from "@jest/globals";
import { composeStory } from "@storybook/react";
import {
+ act,
getAllByRole,
getByRole,
getByText,
@@ -27,6 +28,7 @@ import Meta, {
} from "./LandingView.stories";
import { deleteAllCookies } from "../../../functions/client/deleteAllCookies";
import { defaultExperimentData } from "../../../../telemetry/generated/nimbus/experiments";
+import { mockIsIntersecting } from "react-intersection-observer/test-utils";
jest.mock("next-auth/react", () => {
return {
@@ -950,7 +952,7 @@ describe("Free scan CTA experiment", () => {
expect(waitlistCta[0]).toBeInTheDocument();
});
- it("sends telemetry for the different experiment variants", async () => {
+ it("sends telemetry when clicking on one of the experiment variants", async () => {
const mockedRecord = useTelemetry();
const user = userEvent.setup();
const ComposedDashboard = composeStory(LandingUs, Meta);
@@ -983,6 +985,39 @@ describe("Free scan CTA experiment", () => {
);
});
+ it("sends telemetry when a free scan CTA is shown in the viewport", () => {
+ const mockedRecord = useTelemetry();
+ const ComposedDashboard = composeStory(LandingUs, Meta);
+ render(
+ ,
+ );
+
+ // jsdom will complain about not being able to navigate to a different page
+ // after clicking the link; suppress that error, as it's not relevant to the
+ // test:
+ jest.spyOn(console, "error").mockImplementation(() => undefined);
+
+ const submitButton = screen.getAllByRole("button", {
+ name: "Get free scan",
+ });
+ act(() => {
+ mockIsIntersecting(submitButton[0], true);
+ });
+ expect(mockedRecord).toHaveBeenCalledWith(
+ "ctaButton",
+ "view",
+ expect.objectContaining({ button_id: "clicked_get_scan_header-ctaOnly" }),
+ );
+ });
+
it("passes the expected URL to the identity provider", async () => {
const user = userEvent.setup();
const ComposedDashboard = composeStory(LandingUs, Meta);
diff --git a/src/app/(proper_react)/(redesign)/(public)/LandingView.tsx b/src/app/(proper_react)/(redesign)/(public)/LandingView.tsx
index a3f2aa96eac..82ec8d4bff5 100644
--- a/src/app/(proper_react)/(redesign)/(public)/LandingView.tsx
+++ b/src/app/(proper_react)/(redesign)/(public)/LandingView.tsx
@@ -67,7 +67,6 @@ export const View = (props: Props) => {
eventId={{
cta: "clicked_get_scan_header",
field: "entered_email_address_header",
- view: "viewed_get_scan_header",
}}
experimentData={props.experimentData}
/>
@@ -140,7 +139,6 @@ export const View = (props: Props) => {
eventId={{
cta: "clicked_get_scan_second",
field: "entered_email_address_second",
- view: "viewed_get_scan_second",
}}
experimentData={props.experimentData}
/>
@@ -188,7 +186,6 @@ export const View = (props: Props) => {
eventId={{
cta: "clicked_get_scan_third",
field: "entered_email_address_third",
- view: "viewed_get_scan_third",
}}
experimentData={props.experimentData}
/>
@@ -209,7 +206,6 @@ export const View = (props: Props) => {
eventId={{
cta: "clicked_get_scan_fourth",
field: "entered_email_address_fourth",
- view: "viewed_get_scan_fourth",
}}
scanLimitReached={props.scanLimitReached}
experimentData={props.experimentData}
@@ -254,7 +250,6 @@ export const View = (props: Props) => {
eventId={{
cta: "clicked_get_scan_last",
field: "entered_email_address_last",
- view: "viewed_get_scan_last",
}}
scanLimitReached={props.scanLimitReached}
experimentData={props.experimentData}
diff --git a/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx b/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
index c3efb8b3b5f..9e40827f2de 100644
--- a/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
+++ b/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
@@ -19,15 +19,14 @@ import { ExperimentData } from "../../../../telemetry/generated/nimbus/experimen
export type Props = {
eligibleForPremium: boolean;
- signUpCallbackUrl: string;
- isHero?: boolean;
eventId: {
cta: string;
field?: string;
- view?: string;
};
scanLimitReached: boolean;
+ signUpCallbackUrl: string;
experimentData?: ExperimentData;
+ isHero?: boolean;
placeholder?: string;
};
@@ -36,16 +35,9 @@ export const SignUpForm = (props: Props) => {
const l10n = useL10n();
const [emailInput, setEmailInput] = useState("");
const record = useTelemetry();
- const { view } = props.eventId;
- const refViewTelemetry = useViewTelemetry(
- "ctaButton",
- {
- button_id: view,
- },
- {
- skip: typeof view === "undefined",
- },
- );
+ const refViewTelemetry = useViewTelemetry("ctaButton", {
+ button_id: props.eventId.cta,
+ });
const [cookies] = useCookies(["attributionsFirstTouch"]);
const onSubmit: FormEventHandler = (event) => {
diff --git a/src/app/hooks/useViewTelemetry.ts b/src/app/hooks/useViewTelemetry.ts
index 863785c12db..b7ff9e720fb 100644
--- a/src/app/hooks/useViewTelemetry.ts
+++ b/src/app/hooks/useViewTelemetry.ts
@@ -22,6 +22,11 @@ export function useViewTelemetry<
triggerOnce: true,
...options,
onChange: (inView) => {
+ // Since this function is only triggered once when an element is entering
+ // the viewport and not again after leaving it. With the current setting
+ // the following condition is not expected to get called. Keeping the
+ // condition in place in case this changes.
+ /* c8 ignore next 3 */
if (!inView) {
return;
}
From 4a68966f429e952573e24bcb4552b28003a86d71 Mon Sep 17 00:00:00 2001
From: Robert Helmer
Date: Thu, 18 Jul 2024 18:54:56 -0700
Subject: [PATCH 113/137] ongoing incident: catch and log profile stats being
down (#4832)
---
src/app/functions/server/onerep.ts | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/src/app/functions/server/onerep.ts b/src/app/functions/server/onerep.ts
index 5137553c123..c24e04fe6e3 100644
--- a/src/app/functions/server/onerep.ts
+++ b/src/app/functions/server/onerep.ts
@@ -482,10 +482,21 @@ export async function getProfilesStats(
// );
}
- const profileStats: ProfileStats = await response.json();
-
- // cache results in map, with a flush hack to keep the size low
- if (profileStatsCache.size > 5) profileStatsCache.clear();
- profileStatsCache.set(queryParamsString, profileStats);
- return profileStats;
+ try {
+ const profileStats: ProfileStats = await response.json();
+
+ // cache results in map, with a flush hack to keep the size low
+ if (profileStatsCache.size > 5) profileStatsCache.clear();
+ profileStatsCache.set(queryParamsString, profileStats);
+ return profileStats;
+ } catch (e) {
+ if (e instanceof Error) {
+ logger.error("failed_fetching_stats", {
+ stack: e.stack,
+ message: e.message,
+ });
+ } else {
+ logger.error("failed_fetching_stats", { e });
+ }
+ }
}
From 044902cb95c7eb9386f98c55d59545e95e9db4c8 Mon Sep 17 00:00:00 2001
From: mansaj
Date: Thu, 18 Jul 2024 19:20:52 -0700
Subject: [PATCH 114/137] Revert "chore(deps): bump node from 22.3-alpine to
22.4-alpine" (#4833)
* Revert "bump to node 22.4.1 and npm 10.8.1"
This reverts commit 70269cccd32025c7ca7ae5c62dc8c33c8b3ef373.
* Revert "chore(deps): bump node from 22.3-alpine to 22.4-alpine"
This reverts commit 53b00c772b6f505dfcb0e0286ffea28b46ee87de.
---
.github/workflows/build.yaml | 2 +-
.github/workflows/e2e_cron.yml | 2 +-
.github/workflows/e2e_pr.yml | 2 +-
.github/workflows/lint.yaml | 2 +-
.github/workflows/unittests.yaml | 2 +-
Dockerfile | 2 +-
Dockerfile.cloudrun | 2 +-
esbuild.cronjobs.js | 2 +-
netlify.toml | 2 +-
package-lock.json | 2 +-
package.json | 6 +++---
11 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index e22647197ec..053c5070923 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.4.x'
+ node-version: '22.3.x'
- run: npm ci
- run: npm run build-glean
# Verify that the build (incl. type-checking) succeeds
diff --git a/.github/workflows/e2e_cron.yml b/.github/workflows/e2e_cron.yml
index 08f68c3dd61..1e4b93b7d8e 100644
--- a/.github/workflows/e2e_cron.yml
+++ b/.github/workflows/e2e_cron.yml
@@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 22.4
+ node-version: 22.3
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/e2e_pr.yml b/.github/workflows/e2e_pr.yml
index 813dade02d0..53d92d28e91 100644
--- a/.github/workflows/e2e_pr.yml
+++ b/.github/workflows/e2e_pr.yml
@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 22.4
+ node-version: 22.3
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index c97a575e6fd..e5827c7cabb 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.4.x'
+ node-version: '22.3.x'
- run: npm ci
- run: npm run build-glean
- run: npm run build-nimbus
diff --git a/.github/workflows/unittests.yaml b/.github/workflows/unittests.yaml
index 8bcc252faeb..c934ad1fac3 100644
--- a/.github/workflows/unittests.yaml
+++ b/.github/workflows/unittests.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.4.x'
+ node-version: '22.3.x'
- run: npm ci
- run: npm run build-glean
- run: npm test
diff --git a/Dockerfile b/Dockerfile
index 6df05dc6dea..5f49577777f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:22.4-alpine
+FROM node:22.3-alpine
RUN addgroup -g 10001 app && \
adduser -D -G app -h /app -u 10001 app
diff --git a/Dockerfile.cloudrun b/Dockerfile.cloudrun
index 179005eac42..dc0b8110a6d 100644
--- a/Dockerfile.cloudrun
+++ b/Dockerfile.cloudrun
@@ -1,4 +1,4 @@
-FROM node:22.4-alpine
+FROM node:22.3-alpine
RUN addgroup -g 10001 app && \
adduser -D -G app -h /app -u 10001 app
diff --git a/esbuild.cronjobs.js b/esbuild.cronjobs.js
index dcbea0261b0..b8be0739677 100644
--- a/esbuild.cronjobs.js
+++ b/esbuild.cronjobs.js
@@ -21,6 +21,6 @@ build({
format: "esm",
outdir: "dist/scripts/cronjobs/",
sourcemap: true,
- target: "node22.4",
+ target: "node22.3",
packages: "external",
});
diff --git a/netlify.toml b/netlify.toml
index 1957208e9d3..8f21f1b47a8 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -18,4 +18,4 @@
# Default build command.
command = "npm ci; npm run build-storybook"
- environment = { NODE_VERSION = "22.4.1", NPM_VERSION = "10.8.1" }
+ environment = { NODE_VERSION = "22.3.0", NPM_VERSION = "10.8.0" }
diff --git a/package-lock.json b/package-lock.json
index 93df26589f2..bcae66a0f75 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -105,7 +105,7 @@
"yaml": "^2.4.5"
},
"engines": {
- "node": "22.4.x",
+ "node": "22.3.x",
"npm": "10.8.x"
}
},
diff --git a/package.json b/package.json
index d24420e07e9..ac5bfa839e6 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "Firefox Monitor",
"engines": {
- "node": "22.4.x",
+ "node": "22.3.x",
"npm": "10.8.x"
},
"type": "module",
@@ -56,8 +56,8 @@
"homepage": "https://github.com/mozilla/blurts-server",
"license": "MPL-2.0",
"volta": {
- "node": "22.4.1",
- "npm": "10.8.1"
+ "node": "22.3.0",
+ "npm": "10.8.0"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.614.0",
From e8542f3147490e308e0e845f42b0e14020a6ad93 Mon Sep 17 00:00:00 2001
From: Robert Helmer
Date: Thu, 18 Jul 2024 19:25:19 -0700
Subject: [PATCH 115/137] Revert "MNTOR-3353: add refresh token logic to
session management" (#4834)
---
.github/workflows/e2e_pr.yml | 7 ++-
.../dashboard/[[...slug]]/page.tsx | 2 +-
.../user/(dashboard)/settings/page.tsx | 5 +-
src/app/api/utils/auth.ts | 44 +----------------
src/app/auth/logout/page.tsx | 18 -------
src/app/functions/server/applyCoupon.ts | 8 +--
src/app/functions/server/checkSession.ts | 5 --
src/db/tables/emailAddresses.js | 5 +-
src/db/tables/subscribers.js | 48 +-----------------
src/next-auth.d.ts | 1 -
src/utils/fxa.js | 49 +++----------------
11 files changed, 22 insertions(+), 170 deletions(-)
delete mode 100644 src/app/auth/logout/page.tsx
diff --git a/.github/workflows/e2e_pr.yml b/.github/workflows/e2e_pr.yml
index 53d92d28e91..8dca4b381d7 100644
--- a/.github/workflows/e2e_pr.yml
+++ b/.github/workflows/e2e_pr.yml
@@ -63,8 +63,8 @@ jobs:
run: npm run e2e:smoke
timeout-minutes: 10
env:
- E2E_TEST_ENV: local
- E2E_TEST_BASE_URL: http://localhost:6060
+ E2E_TEST_ENV: ${{ inputs.environment != null && inputs.environment || 'local' }}
+ E2E_TEST_BASE_URL: ${{ secrets.E2E_TEST_BASE_URL }}
E2E_TEST_ACCOUNT_EMAIL: ${{ secrets.E2E_TEST_ACCOUNT_EMAIL }}
E2E_TEST_ACCOUNT_EMAIL_ZERO_BREACHES: ${{ secrets.E2E_TEST_ACCOUNT_EMAIL_ZERO_BREACHES }}
E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED: ${{ secrets.E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED }}
@@ -72,8 +72,7 @@ jobs:
E2E_TEST_PAYPAL_LOGIN: ${{ secrets.E2E_TEST_PAYPAL_LOGIN }}
E2E_TEST_PAYPAL_PASSWORD: ${{ secrets.E2E_TEST_PAYPAL_PASSWORD }}
ADMINS: ${{ secrets.ADMINS }}
- OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET_LOCAL }}
- OAUTH_ACCOUNT_URI: ${{ secrets.OAUTH_ACCOUNT_URI }}
+ OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET }}
ONEREP_API_KEY: ${{ secrets.ONEREP_API_KEY }}
NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }}
NEXTAUTH_URL: ${{ secrets.NEXTAUTH_URL }}
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx
index 074db109a32..81e3b826df3 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx
@@ -57,7 +57,7 @@ type Props = {
export default async function DashboardPage({ params, searchParams }: Props) {
const session = await getServerSession();
if (!checkSession(session) || !session?.user?.subscriber?.id) {
- return redirect("/auth/logout");
+ return redirect("/");
}
const { slug } = params;
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx
index c6f0d82363c..b06fa5df122 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx
@@ -23,7 +23,6 @@ import { getExperiments } from "../../../../../../functions/server/getExperiment
import { getLocale } from "../../../../../../functions/universal/getLocale";
import { getCountryCode } from "../../../../../../functions/server/getCountryCode";
import { getSubscriberById } from "../../../../../../../db/tables/subscribers";
-import { checkSession } from "../../../../../../functions/server/checkSession";
import { checkUserHasMonthlySubscription } from "../../../../../../functions/universal/user";
type Props = {
@@ -36,8 +35,8 @@ export default async function SettingsPage({ searchParams }: Props) {
const session = await getServerSession();
console.debug(searchParams);
- if (!session?.user?.subscriber?.id || !checkSession(session)) {
- return redirect("/auth/logout");
+ if (!session?.user?.subscriber?.id) {
+ return redirect("/");
}
const emailAddresses = await getUserEmails(session.user.subscriber.id);
diff --git a/src/app/api/utils/auth.ts b/src/app/api/utils/auth.ts
index e89ba0b19d5..0f75f3a7780 100644
--- a/src/app/api/utils/auth.ts
+++ b/src/app/api/utils/auth.ts
@@ -12,13 +12,11 @@ import {
getSubscriberByFxaUid,
updateFxAData,
incrementSignInCountForEligibleFreeUser,
- getFxATokens,
- updateFxATokens,
} from "../../../db/tables/subscribers.js";
import { addSubscriber } from "../../../db/tables/emailAddresses.js";
import { getBreaches } from "../../functions/server/getBreaches";
import { getBreachesForEmail } from "../../../utils/hibp.js";
-import { getSha1, refreshOAuthTokens } from "../../../utils/fxa.js";
+import { getSha1 } from "../../../utils/fxa.js";
import {
getEmailCtaDashboardHref,
initEmail,
@@ -132,7 +130,6 @@ export const authOptions: AuthOptions = {
existingUser,
account.access_token,
account.refresh_token,
- account.expires_at ?? 0,
JSON.stringify(profile),
);
// MNTOR-2599 The breach_resolution object can get pretty big,
@@ -147,7 +144,6 @@ export const authOptions: AuthOptions = {
profile.locale,
account.access_token,
account.refresh_token,
- account.expires_at,
JSON.stringify(profile),
);
// The date fields of `verifiedSubscriber` get converted to an ISO 8601
@@ -213,7 +209,7 @@ export const authOptions: AuthOptions = {
}
return token;
},
- async session({ session, token }) {
+ session({ session, token }) {
if (token.fxa) {
session.user.fxa = {
locale: token.fxa.locale,
@@ -226,43 +222,7 @@ export const authOptions: AuthOptions = {
}
if (token.subscriber) {
session.user.subscriber = token.subscriber;
-
- // refresh token
- const dbFxATokens = await getFxATokens(token.subscriber.id);
- if (
- !dbFxATokens?.fxa_session_expiry ||
- dbFxATokens.fxa_session_expiry.getTime() < Date.now()
- ) {
- // If the access token has expired, try to refresh it
- if (!dbFxATokens?.fxa_refresh_token) {
- logger.error("no_fxa_refresh_token", { dbFxATokens });
- session.error = "RefreshAccessTokenError";
- return session;
- }
- try {
- const responseTokens = await refreshOAuthTokens(
- dbFxATokens.fxa_refresh_token,
- );
- const updatedUser = await updateFxATokens(
- token.subscriber,
- responseTokens.access_token,
- responseTokens.refresh_token,
- Date.now() + responseTokens.expires_in * 1000,
- );
-
- // MNTOR-2599 The breach_resolution object can get pretty big,
- // causing the session token cookie to balloon in size,
- // eventually resulting in a 400 Bad Request due to headers being too large.
- delete updatedUser.breach_resolution;
- token.subscriber = updatedUser;
- } catch (error) {
- logger.error("refresh_access_token", error);
- // The error property can be used client-side to handle the refresh token error
- session.error = "RefreshAccessTokenError";
- }
- }
}
-
return session;
},
},
diff --git a/src/app/auth/logout/page.tsx b/src/app/auth/logout/page.tsx
deleted file mode 100644
index d1bf7bda1a7..00000000000
--- a/src/app/auth/logout/page.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use client";
-import { signOut } from "next-auth/react";
-import { useEffect } from "react";
-
-export default function LogoutPage() {
- useEffect(() => {
- void signOut({
- redirect: true,
- callbackUrl: "/",
- });
- }, []);
-
- return <>>;
-}
diff --git a/src/app/functions/server/applyCoupon.ts b/src/app/functions/server/applyCoupon.ts
index d337ac75ca7..3ac308b257b 100644
--- a/src/app/functions/server/applyCoupon.ts
+++ b/src/app/functions/server/applyCoupon.ts
@@ -66,10 +66,10 @@ export async function checkCurrentCouponCode(
const currentCouponCode = process.env.CURRENT_COUPON_CODE_ID;
if (!currentCouponCode) {
- logger.error("fxa_check_coupon_failed", {
- exception:
- "Coupon code ID is not set. Please set the env var: CURRENT_COUPON_CODE_ID",
- });
+ logger.error(
+ "fxa_check_coupon_failed",
+ "Coupon code ID is not set. Please set the env var: CURRENT_COUPON_CODE_ID",
+ );
return {
success: false,
};
diff --git a/src/app/functions/server/checkSession.ts b/src/app/functions/server/checkSession.ts
index a60d553c2b9..7dbdfd4c2fb 100644
--- a/src/app/functions/server/checkSession.ts
+++ b/src/app/functions/server/checkSession.ts
@@ -18,11 +18,6 @@ export function checkSession(session: Session | null) {
} else if (!session.user.subscriber.id) {
logger.warn("no_subscriber_id_in_session", { session });
return false;
- } else if (session.error === "RefreshAccessTokenError") {
- logger.error("refresh_access_token_failed", {
- exception: "Refreshing access token failed... require login again",
- });
- return false;
} else {
return true;
}
diff --git a/src/db/tables/emailAddresses.js b/src/db/tables/emailAddresses.js
index 23fc6c3a027..f58ba88f12b 100644
--- a/src/db/tables/emailAddresses.js
+++ b/src/db/tables/emailAddresses.js
@@ -218,19 +218,18 @@ async function _addEmailHash (sha1, email, signupLanguage, verified = false) {
* @param {string} signupLanguage from Accept-Language
* @param {string | null} fxaAccessToken from Firefox Account Oauth
* @param {string | null} fxaRefreshToken from Firefox Account Oauth
- * @param {number} sessionExpiresAt from Firefox Account Oauth
* @param {string | null} fxaProfileData from Firefox Account
* @returns {Promise} subscriber knex object added to DB
*/
// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
/* c8 ignore start */
-async function addSubscriber (email, signupLanguage, fxaAccessToken = null, fxaRefreshToken = null, sessionExpiresAt = 0, fxaProfileData = null) {
+async function addSubscriber (email, signupLanguage, fxaAccessToken = null, fxaRefreshToken = null, fxaProfileData = null) {
const lowerCaseEmail = email.toLowerCase()
const emailHash = await _addEmailHash(getSha1(lowerCaseEmail), lowerCaseEmail, signupLanguage, true)
const verified = await _verifySubscriber(emailHash)
const verifiedSubscriber = Array.isArray(verified) ? verified[0] : null
if (fxaRefreshToken || fxaProfileData) {
- return updateFxAData(verifiedSubscriber, fxaAccessToken, fxaRefreshToken, sessionExpiresAt, fxaProfileData)
+ return updateFxAData(verifiedSubscriber, fxaAccessToken, fxaRefreshToken, fxaProfileData)
}
return verifiedSubscriber
}
diff --git a/src/db/tables/subscribers.js b/src/db/tables/subscribers.js
index c742a3c7dea..30c081d119c 100644
--- a/src/db/tables/subscribers.js
+++ b/src/db/tables/subscribers.js
@@ -121,13 +121,12 @@ async function updatePrimaryEmail (subscriber, updatedEmail) {
* @param {any} subscriber knex object in DB
* @param {string | null} fxaAccessToken from Firefox Account Oauth
* @param {string | null} fxaRefreshToken from Firefox Account Oauth
- * @param {number} sessionExpiresAt from Firefox Account Oauth
* @param {any} fxaProfileData from Firefox Account
* @returns {Promise} updated subscriber knex object in DB
*/
// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
/* c8 ignore start */
-async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, sessionExpiresAt, fxaProfileData) {
+async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, fxaProfileData) {
const fxaUID = JSON.parse(fxaProfileData).uid
const updated = await knex('subscribers')
.where('id', '=', subscriber.id)
@@ -135,7 +134,6 @@ async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, sessi
fxa_uid: fxaUID,
fxa_access_token: fxaAccessToken,
fxa_refresh_token: fxaRefreshToken,
- fxa_session_expiry: new Date(sessionExpiresAt),
fxa_profile_json: fxaProfileData,
// @ts-ignore knex.fn.now() results in it being set to a date,
// even if it's not typed as a JS date object:
@@ -150,48 +148,6 @@ async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, sessi
}
/* c8 ignore stop */
-/**
- * Update fxa tokens for subscriber
- *
- * @param {any} subscriber knex object in DB
- * @param {string | null} fxaAccessToken from Firefox Account Oauth
- * @param {string | null} fxaRefreshToken from Firefox Account Oauth
- * @param {number} sessionExpiresAt from Firefox Account Oauth
- * @returns {Promise} updated subscriber knex object in DB
- */
-// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
-/* c8 ignore start */
-async function updateFxATokens (subscriber, fxaAccessToken, fxaRefreshToken, sessionExpiresAt) {
- const updateResp = await knex('subscribers')
- .where('id', '=', subscriber.id)
- .update({
- fxa_access_token: fxaAccessToken,
- fxa_refresh_token: fxaRefreshToken,
- fxa_session_expiry: new Date(sessionExpiresAt),
- // @ts-ignore knex.fn.now() results in it being set to a date,
- // even if it's not typed as a JS date object:
- updated_at: knex.fn.now(),
- })
- .returning('*');
- return (Array.isArray(updateResp) && updateResp.length > 0) ? updateResp[0] : null;
-}
-/* c8 ignore stop */
-
-/**
- * Get fxa tokens and expiry for subscriber
- *
- * @param {number} subscriberId
- */
-// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
-/* c8 ignore start */
-async function getFxATokens (subscriberId) {
- const res = await knex('subscribers')
- .first('fxa_access_token', 'fxa_refresh_token', 'fxa_session_expiry')
- .where('id', subscriberId)
- return res ?? null
-}
-/* c8 ignore stop */
-
/**
* Update fxa_profile_json for subscriber
*
@@ -670,8 +626,6 @@ export {
getSubscribersWithUnresolvedBreachesCount,
updatePrimaryEmail,
updateFxAData,
- updateFxATokens,
- getFxATokens,
updateFxAProfileData,
setAllEmailsToPrimary,
setMonthlyMonitorReport,
diff --git a/src/next-auth.d.ts b/src/next-auth.d.ts
index 00153ed7364..ec4330a4e51 100644
--- a/src/next-auth.d.ts
+++ b/src/next-auth.d.ts
@@ -42,7 +42,6 @@ declare module "next-auth" {
/** Session data available after deserialising the JWT */
interface Session {
- error?: "RefreshAccessTokenError";
user: {
fxa?: {
/** The value of the Accept-Language header when the user signed up for their Firefox Account */
diff --git a/src/utils/fxa.js b/src/utils/fxa.js
index 26af41e4803..4ab47dba7c4 100644
--- a/src/utils/fxa.js
+++ b/src/utils/fxa.js
@@ -73,41 +73,6 @@ async function revokeOAuthTokens(subscriber) {
await destroyOAuthToken({ token: subscriber.fxa_refresh_token, token_type_hint: "refresh_token" })
}
-/**
- * @param {string} refreshToken
- * @returns {Promise<{access_token: string, refresh_token: string, expires_in: number}>}
- */
-// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
-/* c8 ignore start */
-async function refreshOAuthTokens(refreshToken) {
- const subscriptionIdUrl = `${AppConstants.OAUTH_ACCOUNT_URI}/oauth/token`
- try {
- const postResp = await fetch(subscriptionIdUrl, {
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({
- client_id: AppConstants.OAUTH_CLIENT_ID,
- client_secret: AppConstants.OAUTH_CLIENT_SECRET,
- grant_type: "refresh_token",
- refresh_token: refreshToken,
- ttl: 604800, // request 7 days ttl
- }),
- method: "POST",
-
- })
-
- const responseTokens = await postResp.json();
- if (!postResp.ok) throw responseTokens;
- return responseTokens
-
- } catch (e) {
- if (e instanceof Error) {
- console.error('refresh_fxa_access_token', { stack: e.stack })
- }
- throw e
- }
-}
-/* c8 ignore stop */
-
/**
* @param {string} bearerToken
* @returns {Promise | null>}
@@ -123,12 +88,13 @@ async function getSubscriptions(bearerToken) {
Authorization: `Bearer ${bearerToken}`
}
})
- const resp = getResp.json()
- if (!getResp.ok) throw resp;
- console.info(`get_fxa_subscriptions: success`)
- return resp;
-
+ if (!getResp.ok) {
+ throw new InternalServerError(`bad response: ${getResp.status}`)
+ } else {
+ console.info(`get_fxa_subscriptions: success`)
+ return await getResp.json()
+ }
} catch (e) {
if (e instanceof Error) {
console.error('get_fxa_subscriptions', { stack: e.stack })
@@ -257,7 +223,7 @@ async function applyCoupon(bearerToken, couponCodeId) {
})
if (!response.ok) {
const errMsg = await response.text()
- console.error(`apply_coupon: failed - ${errMsg}`)
+ console.info(`apply_coupon: failed - ${errMsg}`)
throw new Error(`apply_coupon: failed - ${errMsg}`)
} else {
console.info(`apply_coupon: success - ${JSON.stringify(await response.json())}`)
@@ -283,7 +249,6 @@ function getSha1(email) {
}
export {
- refreshOAuthTokens,
destroyOAuthToken,
revokeOAuthTokens,
getSha1,
From b0b2c368b64c4c3d2ecd9c2450601fa4771c5c5e Mon Sep 17 00:00:00 2001
From: mansaj
Date: Thu, 18 Jul 2024 20:20:40 -0700
Subject: [PATCH 116/137] =?UTF-8?q?Revert=20"Revert=20"MNTOR-3353:=20add?=
=?UTF-8?q?=20refresh=20token=20logic=20to=20session=20management"=20(#?=
=?UTF-8?q?=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit e8542f3147490e308e0e845f42b0e14020a6ad93.
---
.github/workflows/e2e_pr.yml | 7 +--
.../dashboard/[[...slug]]/page.tsx | 2 +-
.../user/(dashboard)/settings/page.tsx | 5 +-
src/app/api/utils/auth.ts | 44 ++++++++++++++++-
src/app/auth/logout/page.tsx | 18 +++++++
src/app/functions/server/applyCoupon.ts | 8 +--
src/app/functions/server/checkSession.ts | 5 ++
src/db/tables/emailAddresses.js | 5 +-
src/db/tables/subscribers.js | 48 +++++++++++++++++-
src/next-auth.d.ts | 1 +
src/utils/fxa.js | 49 ++++++++++++++++---
11 files changed, 170 insertions(+), 22 deletions(-)
create mode 100644 src/app/auth/logout/page.tsx
diff --git a/.github/workflows/e2e_pr.yml b/.github/workflows/e2e_pr.yml
index 8dca4b381d7..53d92d28e91 100644
--- a/.github/workflows/e2e_pr.yml
+++ b/.github/workflows/e2e_pr.yml
@@ -63,8 +63,8 @@ jobs:
run: npm run e2e:smoke
timeout-minutes: 10
env:
- E2E_TEST_ENV: ${{ inputs.environment != null && inputs.environment || 'local' }}
- E2E_TEST_BASE_URL: ${{ secrets.E2E_TEST_BASE_URL }}
+ E2E_TEST_ENV: local
+ E2E_TEST_BASE_URL: http://localhost:6060
E2E_TEST_ACCOUNT_EMAIL: ${{ secrets.E2E_TEST_ACCOUNT_EMAIL }}
E2E_TEST_ACCOUNT_EMAIL_ZERO_BREACHES: ${{ secrets.E2E_TEST_ACCOUNT_EMAIL_ZERO_BREACHES }}
E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED: ${{ secrets.E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED }}
@@ -72,7 +72,8 @@ jobs:
E2E_TEST_PAYPAL_LOGIN: ${{ secrets.E2E_TEST_PAYPAL_LOGIN }}
E2E_TEST_PAYPAL_PASSWORD: ${{ secrets.E2E_TEST_PAYPAL_PASSWORD }}
ADMINS: ${{ secrets.ADMINS }}
- OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET }}
+ OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET_LOCAL }}
+ OAUTH_ACCOUNT_URI: ${{ secrets.OAUTH_ACCOUNT_URI }}
ONEREP_API_KEY: ${{ secrets.ONEREP_API_KEY }}
NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }}
NEXTAUTH_URL: ${{ secrets.NEXTAUTH_URL }}
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx
index 81e3b826df3..074db109a32 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/[[...slug]]/page.tsx
@@ -57,7 +57,7 @@ type Props = {
export default async function DashboardPage({ params, searchParams }: Props) {
const session = await getServerSession();
if (!checkSession(session) || !session?.user?.subscriber?.id) {
- return redirect("/");
+ return redirect("/auth/logout");
}
const { slug } = params;
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx
index b06fa5df122..c6f0d82363c 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/page.tsx
@@ -23,6 +23,7 @@ import { getExperiments } from "../../../../../../functions/server/getExperiment
import { getLocale } from "../../../../../../functions/universal/getLocale";
import { getCountryCode } from "../../../../../../functions/server/getCountryCode";
import { getSubscriberById } from "../../../../../../../db/tables/subscribers";
+import { checkSession } from "../../../../../../functions/server/checkSession";
import { checkUserHasMonthlySubscription } from "../../../../../../functions/universal/user";
type Props = {
@@ -35,8 +36,8 @@ export default async function SettingsPage({ searchParams }: Props) {
const session = await getServerSession();
console.debug(searchParams);
- if (!session?.user?.subscriber?.id) {
- return redirect("/");
+ if (!session?.user?.subscriber?.id || !checkSession(session)) {
+ return redirect("/auth/logout");
}
const emailAddresses = await getUserEmails(session.user.subscriber.id);
diff --git a/src/app/api/utils/auth.ts b/src/app/api/utils/auth.ts
index 0f75f3a7780..e89ba0b19d5 100644
--- a/src/app/api/utils/auth.ts
+++ b/src/app/api/utils/auth.ts
@@ -12,11 +12,13 @@ import {
getSubscriberByFxaUid,
updateFxAData,
incrementSignInCountForEligibleFreeUser,
+ getFxATokens,
+ updateFxATokens,
} from "../../../db/tables/subscribers.js";
import { addSubscriber } from "../../../db/tables/emailAddresses.js";
import { getBreaches } from "../../functions/server/getBreaches";
import { getBreachesForEmail } from "../../../utils/hibp.js";
-import { getSha1 } from "../../../utils/fxa.js";
+import { getSha1, refreshOAuthTokens } from "../../../utils/fxa.js";
import {
getEmailCtaDashboardHref,
initEmail,
@@ -130,6 +132,7 @@ export const authOptions: AuthOptions = {
existingUser,
account.access_token,
account.refresh_token,
+ account.expires_at ?? 0,
JSON.stringify(profile),
);
// MNTOR-2599 The breach_resolution object can get pretty big,
@@ -144,6 +147,7 @@ export const authOptions: AuthOptions = {
profile.locale,
account.access_token,
account.refresh_token,
+ account.expires_at,
JSON.stringify(profile),
);
// The date fields of `verifiedSubscriber` get converted to an ISO 8601
@@ -209,7 +213,7 @@ export const authOptions: AuthOptions = {
}
return token;
},
- session({ session, token }) {
+ async session({ session, token }) {
if (token.fxa) {
session.user.fxa = {
locale: token.fxa.locale,
@@ -222,7 +226,43 @@ export const authOptions: AuthOptions = {
}
if (token.subscriber) {
session.user.subscriber = token.subscriber;
+
+ // refresh token
+ const dbFxATokens = await getFxATokens(token.subscriber.id);
+ if (
+ !dbFxATokens?.fxa_session_expiry ||
+ dbFxATokens.fxa_session_expiry.getTime() < Date.now()
+ ) {
+ // If the access token has expired, try to refresh it
+ if (!dbFxATokens?.fxa_refresh_token) {
+ logger.error("no_fxa_refresh_token", { dbFxATokens });
+ session.error = "RefreshAccessTokenError";
+ return session;
+ }
+ try {
+ const responseTokens = await refreshOAuthTokens(
+ dbFxATokens.fxa_refresh_token,
+ );
+ const updatedUser = await updateFxATokens(
+ token.subscriber,
+ responseTokens.access_token,
+ responseTokens.refresh_token,
+ Date.now() + responseTokens.expires_in * 1000,
+ );
+
+ // MNTOR-2599 The breach_resolution object can get pretty big,
+ // causing the session token cookie to balloon in size,
+ // eventually resulting in a 400 Bad Request due to headers being too large.
+ delete updatedUser.breach_resolution;
+ token.subscriber = updatedUser;
+ } catch (error) {
+ logger.error("refresh_access_token", error);
+ // The error property can be used client-side to handle the refresh token error
+ session.error = "RefreshAccessTokenError";
+ }
+ }
}
+
return session;
},
},
diff --git a/src/app/auth/logout/page.tsx b/src/app/auth/logout/page.tsx
new file mode 100644
index 00000000000..d1bf7bda1a7
--- /dev/null
+++ b/src/app/auth/logout/page.tsx
@@ -0,0 +1,18 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use client";
+import { signOut } from "next-auth/react";
+import { useEffect } from "react";
+
+export default function LogoutPage() {
+ useEffect(() => {
+ void signOut({
+ redirect: true,
+ callbackUrl: "/",
+ });
+ }, []);
+
+ return <>>;
+}
diff --git a/src/app/functions/server/applyCoupon.ts b/src/app/functions/server/applyCoupon.ts
index 3ac308b257b..d337ac75ca7 100644
--- a/src/app/functions/server/applyCoupon.ts
+++ b/src/app/functions/server/applyCoupon.ts
@@ -66,10 +66,10 @@ export async function checkCurrentCouponCode(
const currentCouponCode = process.env.CURRENT_COUPON_CODE_ID;
if (!currentCouponCode) {
- logger.error(
- "fxa_check_coupon_failed",
- "Coupon code ID is not set. Please set the env var: CURRENT_COUPON_CODE_ID",
- );
+ logger.error("fxa_check_coupon_failed", {
+ exception:
+ "Coupon code ID is not set. Please set the env var: CURRENT_COUPON_CODE_ID",
+ });
return {
success: false,
};
diff --git a/src/app/functions/server/checkSession.ts b/src/app/functions/server/checkSession.ts
index 7dbdfd4c2fb..a60d553c2b9 100644
--- a/src/app/functions/server/checkSession.ts
+++ b/src/app/functions/server/checkSession.ts
@@ -18,6 +18,11 @@ export function checkSession(session: Session | null) {
} else if (!session.user.subscriber.id) {
logger.warn("no_subscriber_id_in_session", { session });
return false;
+ } else if (session.error === "RefreshAccessTokenError") {
+ logger.error("refresh_access_token_failed", {
+ exception: "Refreshing access token failed... require login again",
+ });
+ return false;
} else {
return true;
}
diff --git a/src/db/tables/emailAddresses.js b/src/db/tables/emailAddresses.js
index f58ba88f12b..23fc6c3a027 100644
--- a/src/db/tables/emailAddresses.js
+++ b/src/db/tables/emailAddresses.js
@@ -218,18 +218,19 @@ async function _addEmailHash (sha1, email, signupLanguage, verified = false) {
* @param {string} signupLanguage from Accept-Language
* @param {string | null} fxaAccessToken from Firefox Account Oauth
* @param {string | null} fxaRefreshToken from Firefox Account Oauth
+ * @param {number} sessionExpiresAt from Firefox Account Oauth
* @param {string | null} fxaProfileData from Firefox Account
* @returns {Promise} subscriber knex object added to DB
*/
// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
/* c8 ignore start */
-async function addSubscriber (email, signupLanguage, fxaAccessToken = null, fxaRefreshToken = null, fxaProfileData = null) {
+async function addSubscriber (email, signupLanguage, fxaAccessToken = null, fxaRefreshToken = null, sessionExpiresAt = 0, fxaProfileData = null) {
const lowerCaseEmail = email.toLowerCase()
const emailHash = await _addEmailHash(getSha1(lowerCaseEmail), lowerCaseEmail, signupLanguage, true)
const verified = await _verifySubscriber(emailHash)
const verifiedSubscriber = Array.isArray(verified) ? verified[0] : null
if (fxaRefreshToken || fxaProfileData) {
- return updateFxAData(verifiedSubscriber, fxaAccessToken, fxaRefreshToken, fxaProfileData)
+ return updateFxAData(verifiedSubscriber, fxaAccessToken, fxaRefreshToken, sessionExpiresAt, fxaProfileData)
}
return verifiedSubscriber
}
diff --git a/src/db/tables/subscribers.js b/src/db/tables/subscribers.js
index 30c081d119c..c742a3c7dea 100644
--- a/src/db/tables/subscribers.js
+++ b/src/db/tables/subscribers.js
@@ -121,12 +121,13 @@ async function updatePrimaryEmail (subscriber, updatedEmail) {
* @param {any} subscriber knex object in DB
* @param {string | null} fxaAccessToken from Firefox Account Oauth
* @param {string | null} fxaRefreshToken from Firefox Account Oauth
+ * @param {number} sessionExpiresAt from Firefox Account Oauth
* @param {any} fxaProfileData from Firefox Account
* @returns {Promise} updated subscriber knex object in DB
*/
// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
/* c8 ignore start */
-async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, fxaProfileData) {
+async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, sessionExpiresAt, fxaProfileData) {
const fxaUID = JSON.parse(fxaProfileData).uid
const updated = await knex('subscribers')
.where('id', '=', subscriber.id)
@@ -134,6 +135,7 @@ async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, fxaPr
fxa_uid: fxaUID,
fxa_access_token: fxaAccessToken,
fxa_refresh_token: fxaRefreshToken,
+ fxa_session_expiry: new Date(sessionExpiresAt),
fxa_profile_json: fxaProfileData,
// @ts-ignore knex.fn.now() results in it being set to a date,
// even if it's not typed as a JS date object:
@@ -148,6 +150,48 @@ async function updateFxAData (subscriber, fxaAccessToken, fxaRefreshToken, fxaPr
}
/* c8 ignore stop */
+/**
+ * Update fxa tokens for subscriber
+ *
+ * @param {any} subscriber knex object in DB
+ * @param {string | null} fxaAccessToken from Firefox Account Oauth
+ * @param {string | null} fxaRefreshToken from Firefox Account Oauth
+ * @param {number} sessionExpiresAt from Firefox Account Oauth
+ * @returns {Promise} updated subscriber knex object in DB
+ */
+// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
+/* c8 ignore start */
+async function updateFxATokens (subscriber, fxaAccessToken, fxaRefreshToken, sessionExpiresAt) {
+ const updateResp = await knex('subscribers')
+ .where('id', '=', subscriber.id)
+ .update({
+ fxa_access_token: fxaAccessToken,
+ fxa_refresh_token: fxaRefreshToken,
+ fxa_session_expiry: new Date(sessionExpiresAt),
+ // @ts-ignore knex.fn.now() results in it being set to a date,
+ // even if it's not typed as a JS date object:
+ updated_at: knex.fn.now(),
+ })
+ .returning('*');
+ return (Array.isArray(updateResp) && updateResp.length > 0) ? updateResp[0] : null;
+}
+/* c8 ignore stop */
+
+/**
+ * Get fxa tokens and expiry for subscriber
+ *
+ * @param {number} subscriberId
+ */
+// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
+/* c8 ignore start */
+async function getFxATokens (subscriberId) {
+ const res = await knex('subscribers')
+ .first('fxa_access_token', 'fxa_refresh_token', 'fxa_session_expiry')
+ .where('id', subscriberId)
+ return res ?? null
+}
+/* c8 ignore stop */
+
/**
* Update fxa_profile_json for subscriber
*
@@ -626,6 +670,8 @@ export {
getSubscribersWithUnresolvedBreachesCount,
updatePrimaryEmail,
updateFxAData,
+ updateFxATokens,
+ getFxATokens,
updateFxAProfileData,
setAllEmailsToPrimary,
setMonthlyMonitorReport,
diff --git a/src/next-auth.d.ts b/src/next-auth.d.ts
index ec4330a4e51..00153ed7364 100644
--- a/src/next-auth.d.ts
+++ b/src/next-auth.d.ts
@@ -42,6 +42,7 @@ declare module "next-auth" {
/** Session data available after deserialising the JWT */
interface Session {
+ error?: "RefreshAccessTokenError";
user: {
fxa?: {
/** The value of the Accept-Language header when the user signed up for their Firefox Account */
diff --git a/src/utils/fxa.js b/src/utils/fxa.js
index 4ab47dba7c4..26af41e4803 100644
--- a/src/utils/fxa.js
+++ b/src/utils/fxa.js
@@ -73,6 +73,41 @@ async function revokeOAuthTokens(subscriber) {
await destroyOAuthToken({ token: subscriber.fxa_refresh_token, token_type_hint: "refresh_token" })
}
+/**
+ * @param {string} refreshToken
+ * @returns {Promise<{access_token: string, refresh_token: string, expires_in: number}>}
+ */
+// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy
+/* c8 ignore start */
+async function refreshOAuthTokens(refreshToken) {
+ const subscriptionIdUrl = `${AppConstants.OAUTH_ACCOUNT_URI}/oauth/token`
+ try {
+ const postResp = await fetch(subscriptionIdUrl, {
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ client_id: AppConstants.OAUTH_CLIENT_ID,
+ client_secret: AppConstants.OAUTH_CLIENT_SECRET,
+ grant_type: "refresh_token",
+ refresh_token: refreshToken,
+ ttl: 604800, // request 7 days ttl
+ }),
+ method: "POST",
+
+ })
+
+ const responseTokens = await postResp.json();
+ if (!postResp.ok) throw responseTokens;
+ return responseTokens
+
+ } catch (e) {
+ if (e instanceof Error) {
+ console.error('refresh_fxa_access_token', { stack: e.stack })
+ }
+ throw e
+ }
+}
+/* c8 ignore stop */
+
/**
* @param {string} bearerToken
* @returns {Promise | null>}
@@ -88,13 +123,12 @@ async function getSubscriptions(bearerToken) {
Authorization: `Bearer ${bearerToken}`
}
})
+ const resp = getResp.json()
+ if (!getResp.ok) throw resp;
- if (!getResp.ok) {
- throw new InternalServerError(`bad response: ${getResp.status}`)
- } else {
- console.info(`get_fxa_subscriptions: success`)
- return await getResp.json()
- }
+ console.info(`get_fxa_subscriptions: success`)
+ return resp;
+
} catch (e) {
if (e instanceof Error) {
console.error('get_fxa_subscriptions', { stack: e.stack })
@@ -223,7 +257,7 @@ async function applyCoupon(bearerToken, couponCodeId) {
})
if (!response.ok) {
const errMsg = await response.text()
- console.info(`apply_coupon: failed - ${errMsg}`)
+ console.error(`apply_coupon: failed - ${errMsg}`)
throw new Error(`apply_coupon: failed - ${errMsg}`)
} else {
console.info(`apply_coupon: success - ${JSON.stringify(await response.json())}`)
@@ -249,6 +283,7 @@ function getSha1(email) {
}
export {
+ refreshOAuthTokens,
destroyOAuthToken,
revokeOAuthTokens,
getSha1,
From 20a7d58097db8f0f6173ff4781cf2d300d377134 Mon Sep 17 00:00:00 2001
From: mansaj
Date: Thu, 18 Jul 2024 20:20:58 -0700
Subject: [PATCH 117/137] Revert "Revert "chore(deps): bump node from
22.3-alpine to 22.4-alpine" (#4833)"
This reverts commit 044902cb95c7eb9386f98c55d59545e95e9db4c8.
---
.github/workflows/build.yaml | 2 +-
.github/workflows/e2e_cron.yml | 2 +-
.github/workflows/e2e_pr.yml | 2 +-
.github/workflows/lint.yaml | 2 +-
.github/workflows/unittests.yaml | 2 +-
Dockerfile | 2 +-
Dockerfile.cloudrun | 2 +-
esbuild.cronjobs.js | 2 +-
netlify.toml | 2 +-
package-lock.json | 2 +-
package.json | 6 +++---
11 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 053c5070923..e22647197ec 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.3.x'
+ node-version: '22.4.x'
- run: npm ci
- run: npm run build-glean
# Verify that the build (incl. type-checking) succeeds
diff --git a/.github/workflows/e2e_cron.yml b/.github/workflows/e2e_cron.yml
index 1e4b93b7d8e..08f68c3dd61 100644
--- a/.github/workflows/e2e_cron.yml
+++ b/.github/workflows/e2e_cron.yml
@@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 22.3
+ node-version: 22.4
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/e2e_pr.yml b/.github/workflows/e2e_pr.yml
index 8dca4b381d7..d6f3986c6c6 100644
--- a/.github/workflows/e2e_pr.yml
+++ b/.github/workflows/e2e_pr.yml
@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 22.3
+ node-version: 22.4
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index e5827c7cabb..c97a575e6fd 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.3.x'
+ node-version: '22.4.x'
- run: npm ci
- run: npm run build-glean
- run: npm run build-nimbus
diff --git a/.github/workflows/unittests.yaml b/.github/workflows/unittests.yaml
index c934ad1fac3..8bcc252faeb 100644
--- a/.github/workflows/unittests.yaml
+++ b/.github/workflows/unittests.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
- node-version: '22.3.x'
+ node-version: '22.4.x'
- run: npm ci
- run: npm run build-glean
- run: npm test
diff --git a/Dockerfile b/Dockerfile
index 5f49577777f..6df05dc6dea 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:22.3-alpine
+FROM node:22.4-alpine
RUN addgroup -g 10001 app && \
adduser -D -G app -h /app -u 10001 app
diff --git a/Dockerfile.cloudrun b/Dockerfile.cloudrun
index dc0b8110a6d..179005eac42 100644
--- a/Dockerfile.cloudrun
+++ b/Dockerfile.cloudrun
@@ -1,4 +1,4 @@
-FROM node:22.3-alpine
+FROM node:22.4-alpine
RUN addgroup -g 10001 app && \
adduser -D -G app -h /app -u 10001 app
diff --git a/esbuild.cronjobs.js b/esbuild.cronjobs.js
index b8be0739677..dcbea0261b0 100644
--- a/esbuild.cronjobs.js
+++ b/esbuild.cronjobs.js
@@ -21,6 +21,6 @@ build({
format: "esm",
outdir: "dist/scripts/cronjobs/",
sourcemap: true,
- target: "node22.3",
+ target: "node22.4",
packages: "external",
});
diff --git a/netlify.toml b/netlify.toml
index 8f21f1b47a8..1957208e9d3 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -18,4 +18,4 @@
# Default build command.
command = "npm ci; npm run build-storybook"
- environment = { NODE_VERSION = "22.3.0", NPM_VERSION = "10.8.0" }
+ environment = { NODE_VERSION = "22.4.1", NPM_VERSION = "10.8.1" }
diff --git a/package-lock.json b/package-lock.json
index bcae66a0f75..93df26589f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -105,7 +105,7 @@
"yaml": "^2.4.5"
},
"engines": {
- "node": "22.3.x",
+ "node": "22.4.x",
"npm": "10.8.x"
}
},
diff --git a/package.json b/package.json
index ac5bfa839e6..d24420e07e9 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "Firefox Monitor",
"engines": {
- "node": "22.3.x",
+ "node": "22.4.x",
"npm": "10.8.x"
},
"type": "module",
@@ -56,8 +56,8 @@
"homepage": "https://github.com/mozilla/blurts-server",
"license": "MPL-2.0",
"volta": {
- "node": "22.3.0",
- "npm": "10.8.0"
+ "node": "22.4.1",
+ "npm": "10.8.1"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.614.0",
From c2a379d21f9e2c454f28e91c5e126430da4ce67f Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Thu, 18 Jul 2024 23:59:06 -0700
Subject: [PATCH 118/137] fixed landing spec
---
src/e2e/pages/landingPage.ts | 12 +++-
src/e2e/specs/landing.spec.ts | 119 ++++++++++++++++++++++------------
src/e2e/utils/helpers.ts | 4 ++
3 files changed, 92 insertions(+), 43 deletions(-)
diff --git a/src/e2e/pages/landingPage.ts b/src/e2e/pages/landingPage.ts
index 463dbc3c059..97aa2189c79 100644
--- a/src/e2e/pages/landingPage.ts
+++ b/src/e2e/pages/landingPage.ts
@@ -79,6 +79,9 @@ export class LandingPage {
readonly monitorPlusTooltipText: Locator;
readonly closeTooltips: Locator;
+ // Landing-page-free-scan-cta experiment enabled
+ readonly emailInputPrompt: Locator;
+
constructor(page: Page) {
this.page = page;
this.freeMonitoringTooltipTrigger = page
@@ -166,7 +169,7 @@ export class LandingPage {
has: this.reuseEmailInputField,
});
this.couldBeAtRiskFormInputSubmitButton = this.couldBeAtRiskSection.filter({
- has: this.reuseButton,
+ hasText: "Get free scan",
});
this.couldBeAtRiskGraphic = page.locator(
'img[data-testid="leaked-password-example"]',
@@ -184,7 +187,7 @@ export class LandingPage {
has: this.reuseEmailInputField,
});
this.getStartedScanFormSubmitButton = this.getStartedScanSection.filter({
- has: this.reuseButton,
+ hasText: "Get free scan",
});
// choose your level of protection section
@@ -235,6 +238,11 @@ export class LandingPage {
this.startFreeMonitoringButton = page.getByRole("button", {
name: "Start free monitoring",
});
+
+ // Landing-page-free-scan-cta experiment enabled
+ this.emailInputPrompt = page.locator(
+ '//label[text()="Enter your email address to check for data breach exposures and sites selling your info."]',
+ );
}
async open() {
diff --git a/src/e2e/specs/landing.spec.ts b/src/e2e/specs/landing.spec.ts
index acb202d4656..9a3b2ec59b8 100644
--- a/src/e2e/specs/landing.spec.ts
+++ b/src/e2e/specs/landing.spec.ts
@@ -5,6 +5,7 @@
import { test, expect } from "../fixtures/basePage.js";
import {
defaultScreenshotOpts,
+ emailInputShouldExist,
getVerificationCode,
} from "../utils/helpers.js";
@@ -41,8 +42,10 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page content`, (
await expect(landingPage.monitorHeroSubtitle).toHaveText(
"We scan to see if your phone number, passwords or home address have been leaked, and help you make it private again.",
);
- await expect(landingPage.monitorHeroFormEmailInputField).toBeVisible();
- await expect(landingPage.monitorHeroFormInputSubmitButton).toBeVisible();
+ if (await emailInputShouldExist(landingPage)) {
+ await expect(landingPage.monitorHeroFormEmailInputField).toBeVisible();
+ await expect(landingPage.monitorHeroFormInputSubmitButton).toBeVisible();
+ }
await expect(landingPage.monitorLandingMidHeading).toBeVisible();
});
@@ -57,8 +60,10 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page content`, (
await expect(landingPage.fixExposuresTitle).toBeVisible();
await expect(landingPage.fixExposuresSubtitle).toBeVisible();
- await expect(landingPage.fixExposuresFormEmailInputField).toBeVisible();
- await expect(landingPage.fixExposuresFormInputSubmitButton).toBeVisible();
+ if (await emailInputShouldExist(landingPage)) {
+ await expect(landingPage.fixExposuresFormEmailInputField).toBeVisible();
+ await expect(landingPage.fixExposuresFormInputSubmitButton).toBeVisible();
+ }
await expect(landingPage.fixExposuresGraphic).toBeVisible();
});
@@ -73,7 +78,9 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page content`, (
await expect(landingPage.couldBeAtRiskTitle).toBeVisible();
await expect(landingPage.couldBeAtRiskSubtitle).toBeVisible();
- await expect(landingPage.couldBeAtRiskFormEmailInputField).toBeVisible();
+ if (await emailInputShouldExist(landingPage)) {
+ await expect(landingPage.couldBeAtRiskFormEmailInputField).toBeVisible();
+ }
await expect(landingPage.couldBeAtRiskFormInputSubmitButton).toBeVisible();
await expect(landingPage.couldBeAtRiskGraphic).toBeVisible();
});
@@ -88,7 +95,8 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page content`, (
});
await expect(landingPage.getStartedScanTitle).toBeVisible();
- await expect(landingPage.getStartedScanFormEmailInputField).toBeVisible();
+ if (await emailInputShouldExist(landingPage))
+ await expect(landingPage.getStartedScanFormEmailInputField).toBeVisible();
await expect(landingPage.getStartedScanFormSubmitButton).toBeVisible();
});
@@ -130,8 +138,12 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page content`, (
});
await expect(landingPage.takeBackControlTitle).toBeVisible();
- await expect(landingPage.takeBackControlFormEmailInputField).toBeVisible();
- await expect(landingPage.takeBackControlFormSubmitButton).toBeVisible();
+ if (await emailInputShouldExist(landingPage)) {
+ await expect(
+ landingPage.takeBackControlFormEmailInputField,
+ ).toBeVisible();
+ await expect(landingPage.takeBackControlFormSubmitButton).toBeVisible();
+ }
});
test("Observe footer section", async ({ landingPage }) => {
@@ -182,17 +194,30 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page content`, (
description:
"https://testrail.stage.mozaws.net/index.php?/cases/view/2463504",
});
-
- await landingPage.monitorHeroFormEmailInputField.fill("invalid");
- await landingPage.monitorHeroFormInputSubmitButton.click();
- // Stays on same page
- await expect(landingPage.monitorHeroFormEmailInputField).toBeVisible();
-
- const randomEmail = `_${Date.now()}_tstact@restmail.net`;
- await landingPage.monitorHeroFormEmailInputField.fill(randomEmail);
- await landingPage.monitorHeroFormInputSubmitButton.click();
- await authPage.passwordInputField.waitFor();
- await expect(authPage.passwordInputField).toBeVisible();
+ if (await emailInputShouldExist(landingPage)) {
+ ///free-scan-cta experiment is off
+ await landingPage.monitorHeroFormEmailInputField.fill("invalid");
+ await landingPage.monitorHeroFormInputSubmitButton.click();
+ await expect(landingPage.monitorHeroFormEmailInputField).toBeVisible();
+
+ const randomEmail = `_${Date.now()}_tstact@restmail.net`;
+ await landingPage.monitorHeroFormEmailInputField.fill(randomEmail);
+ await landingPage.monitorHeroFormInputSubmitButton.click();
+ await authPage.passwordInputField.waitFor();
+ await expect(authPage.passwordInputField).toBeVisible();
+ } else {
+ ///free-scan-cta experiment is on
+ await landingPage.monitorHeroFormInputSubmitButton.click();
+ await authPage.emailInputField.waitFor({
+ state: "visible",
+ timeout: 10000,
+ });
+ const randomEmail = `_${Date.now()}_tstact@restmail.net`;
+ await authPage.emailInputField.fill(randomEmail);
+ await authPage.continueButton.click();
+ await authPage.passwordInputField.waitFor();
+ await expect(authPage.passwordInputField).toBeVisible();
+ }
});
test('Verify manual/automatic removal "more info" tips from "Choose your level of protection" section', async ({
@@ -221,20 +246,27 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page Functionali
page,
authPage,
}) => {
- // link to testrail case
test.info().annotations.push({
type: "testrail",
description:
"https://testrail.stage.mozaws.net/index.php?/cases/view/2463502",
});
- // fill out free scan form
const randomEmail = `${Date.now()}_tstact@restmail.net`;
- await landingPage.monitorHeroFormEmailInputField.fill(randomEmail);
- await landingPage.monitorHeroFormInputSubmitButton.click();
- await page.waitForURL("**/oauth/**");
-
- // complete registration form
+ if (await emailInputShouldExist(landingPage)) {
+ await landingPage.monitorHeroFormEmailInputField.fill(randomEmail);
+ await landingPage.monitorHeroFormInputSubmitButton.click();
+ await page.waitForURL("**/oauth/**");
+ } else {
+ await landingPage.monitorHeroFormInputSubmitButton.click();
+ await authPage.emailInputField.waitFor({
+ state: "visible",
+ timeout: 10000,
+ });
+ await authPage.emailInputField.fill(randomEmail);
+ await authPage.continueButton.click();
+ }
+ // continue with the common steps
await authPage.passwordInputField.fill(
process.env.E2E_TEST_ACCOUNT_PASSWORD as string,
);
@@ -243,12 +275,8 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page Functionali
);
await authPage.ageInputField.fill("31");
await authPage.continueButton.click();
-
- // enter registration verification code
const vc = await getVerificationCode(randomEmail, page);
await authPage.enterVerificationCode(vc);
-
- // verify dashboard redirect
const successUrl = process.env.E2E_TEST_BASE_URL + "/user/welcome";
expect(page.url()).toBe(successUrl);
});
@@ -298,12 +326,23 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page Functionali
"https://testrail.stage.mozaws.net/index.php?/cases/view/2463503",
});
- // fill out free scan form
- await landingPage.monitorHeroFormEmailInputField.fill(
- process.env.E2E_TEST_ACCOUNT_EMAIL as string,
- );
- await landingPage.monitorHeroFormInputSubmitButton.click();
- await page.waitForURL("**/oauth/**");
+ const existingEmail = process.env.E2E_TEST_ACCOUNT_EMAIL as string;
+
+ if (await emailInputShouldExist(landingPage)) {
+ // Scenario where the form is still used
+ await landingPage.monitorHeroFormEmailInputField.fill(existingEmail);
+ await landingPage.monitorHeroFormInputSubmitButton.click();
+ await page.waitForURL("**/oauth/**");
+ } else {
+ // Scenario where direct redirection happens
+ await landingPage.monitorHeroFormInputSubmitButton.click();
+ await authPage.emailInputField.waitFor({
+ state: "visible",
+ timeout: 10000,
+ });
+ await authPage.emailInputField.fill(existingEmail);
+ await authPage.continueButton.click();
+ }
// complete sign in form
await authPage.enterPassword();
@@ -311,11 +350,9 @@ test.describe(`${process.env.E2E_TEST_ENV} - Verify the Landing Page Functionali
// verify dashboard redirect
const successUrl =
process.env.E2E_TEST_BASE_URL +
- `${
- process.env.E2E_TEST_ENV === "local"
- ? "/user/welcome"
- : "/user/dashboard"
- }`;
+ (process.env.E2E_TEST_ENV === "local"
+ ? "/user/welcome"
+ : "/user/dashboard");
expect(page.url()).toBe(successUrl);
});
diff --git a/src/e2e/utils/helpers.ts b/src/e2e/utils/helpers.ts
index 0d398436dd0..ddb6da2800f 100644
--- a/src/e2e/utils/helpers.ts
+++ b/src/e2e/utils/helpers.ts
@@ -222,3 +222,7 @@ export const forceLoginAs = async (
await page.waitForURL("**/user/dashboard");
await expect(page).toHaveURL(/.*\/user\/dashboard.*/);
};
+
+export async function emailInputShouldExist(landingPage: LandingPage) {
+ return 0 < (await landingPage.emailInputPrompt.count());
+}
From f43dbf285ce7f5205460973ca711842950d2ba66 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Fri, 19 Jul 2024 02:42:26 -0700
Subject: [PATCH 119/137] changed the paypal button locator
---
src/e2e/pages/purchasePage.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/e2e/pages/purchasePage.ts b/src/e2e/pages/purchasePage.ts
index e1ead13b02e..2892c736f75 100644
--- a/src/e2e/pages/purchasePage.ts
+++ b/src/e2e/pages/purchasePage.ts
@@ -39,7 +39,10 @@ export class PurchasePage {
this.returnToDashboardButton = page.getByLabel("Return to dashboard");
this.goToNextStep = page.getByLabel("Go to next step");
this.planDetails = page.locator(".plan-details-description");
- this.paypalButton = page.getByTitle("PayPal").nth(1);
+ this.paypalButton = this.page
+ .frameLocator('//iframe[@title="PayPal"]')
+ .first()
+ .locator('div[role="link"]');
}
async fillOutStripeCardInfo() {
From b7214c8d958d14dfc568b54496287107a3ca3e93 Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Fri, 19 Jul 2024 03:41:21 -0700
Subject: [PATCH 120/137] slightly modified the locators for a failing test
---
src/e2e/specs/dashboard.spec.ts | 1 +
src/e2e/utils/helpers.ts | 10 ++++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/e2e/specs/dashboard.spec.ts b/src/e2e/specs/dashboard.spec.ts
index a72dba31d56..92b77d78f44 100644
--- a/src/e2e/specs/dashboard.spec.ts
+++ b/src/e2e/specs/dashboard.spec.ts
@@ -515,6 +515,7 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Overview Card`
});
await dashboardPage.open();
+ await page.waitForURL("**/dashboard/**");
//get the number of exposures count
const overviewCardSummary =
diff --git a/src/e2e/utils/helpers.ts b/src/e2e/utils/helpers.ts
index ddb6da2800f..406bec589c4 100644
--- a/src/e2e/utils/helpers.ts
+++ b/src/e2e/utils/helpers.ts
@@ -208,12 +208,10 @@ export const forceLoginAs = async (
await page.context().clearCookies();
await landingPage.open();
await landingPage.goToSignIn();
- let visible = true;
- try {
- await expect(authPage.useDifferentEmailButton).toBeVisible();
- } catch {
- visible = false;
- }
+ await page
+ .locator("//input[@type='password'] | //div/input[@type='email']")
+ .waitFor({ state: "visible" });
+ const visible = await authPage.useDifferentEmailButton.isVisible();
if (visible) {
await authPage.useDifferentEmailButton.click();
await page.waitForURL(/^(?!.*signin).*/);
From a3e9e7785c221bf0eb29c61010e57dd2a55dbc1c Mon Sep 17 00:00:00 2001
From: Mukhamediyar Kudaikulov
Date: Fri, 19 Jul 2024 11:58:01 -0700
Subject: [PATCH 121/137] skipping an inconsistent test
---
src/e2e/pages/dashBoardPage.ts | 4 +-
src/e2e/specs/dashboard.spec.ts | 79 ++++++++++++++++++---------------
2 files changed, 47 insertions(+), 36 deletions(-)
diff --git a/src/e2e/pages/dashBoardPage.ts b/src/e2e/pages/dashBoardPage.ts
index 25f5939df65..80cd54082bb 100644
--- a/src/e2e/pages/dashBoardPage.ts
+++ b/src/e2e/pages/dashBoardPage.ts
@@ -241,7 +241,9 @@ export class DashboardPage {
this.faqsPageLink = page.getByTitle("Frequently asked questions").first();
//upsell button
- this.upsellScreenButton = page.getByText(/Let’s (keep going|fix it)/);
+ this.upsellScreenButton = page
+ .locator("a")
+ .getByText(/Let’s (keep going|fix it)/);
this.overviewCard = page.locator("[class*='DashboardTopBanner_container']");
this.overviewCardSummary = page.locator(
"[aria-label='Dashboard summary'] > div > p",
diff --git a/src/e2e/specs/dashboard.spec.ts b/src/e2e/specs/dashboard.spec.ts
index 92b77d78f44..34908776270 100644
--- a/src/e2e/specs/dashboard.spec.ts
+++ b/src/e2e/specs/dashboard.spec.ts
@@ -720,40 +720,49 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Navigation`, (
});
});
-test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Data Breaches`, () => {
- test.beforeEach(async ({ landingPage, page, authPage }) => {
- const emailToUse = process.env
- .E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED as string;
- const pwdToUse = process.env.E2E_TEST_ACCOUNT_PASSWORD as string;
- expect(emailToUse).not.toBeUndefined();
- expect(pwdToUse).not.toBeUndefined();
- await forceLoginAs(emailToUse, pwdToUse, page, landingPage, authPage);
- });
-
- test("Verify that the High risk data breaches step is displayed correctly", async ({
- dashboardPage,
- dataBrokersPage,
- page,
- }) => {
- test.info().annotations.push({
- type: "testrail",
- description:
- "https://testrail.stage.mozaws.net/index.php?/cases/view/2463592",
+// This test has inconsistent results - may need to rely on mocks.
+test.describe.skip(
+ `${process.env.E2E_TEST_ENV} - Breaches Dashboard - Data Breaches`,
+ () => {
+ test.beforeEach(async ({ landingPage, page, authPage }) => {
+ const emailToUse = process.env
+ .E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED as string;
+ const pwdToUse = process.env.E2E_TEST_ACCOUNT_PASSWORD as string;
+ expect(emailToUse).not.toBeUndefined();
+ expect(pwdToUse).not.toBeUndefined();
+ await forceLoginAs(emailToUse, pwdToUse, page, landingPage, authPage);
});
- await expect(dashboardPage.upsellScreenButton).toBeVisible();
- await dashboardPage.upsellScreenButton.click();
- await page.waitForURL(/.*\/data-broker-profiles\/view-data-brokers\/?/);
- await expect(dataBrokersPage.forwardArrowButton).toBeVisible();
- await dataBrokersPage.forwardArrowButton.click();
- await page.waitForURL(/.*\/high-risk-data-breaches.*/);
- const highRiskDataBreachLi = page.locator(
- 'li:has(div:has-text("High risk data breaches"))',
- );
- await expect(highRiskDataBreachLi).toBeVisible();
- await expect(highRiskDataBreachLi).toHaveAttribute("aria-current", "step");
- await expect(
- highRiskDataBreachLi.locator("div").getByText("High risk data breaches"),
- ).toBeVisible();
- });
-});
+ test("Verify that the High risk data breaches step is displayed correctly", async ({
+ dashboardPage,
+ dataBrokersPage,
+ page,
+ }) => {
+ test.info().annotations.push({
+ type: "testrail",
+ description:
+ "https://testrail.stage.mozaws.net/index.php?/cases/view/2463592",
+ });
+
+ await expect(dashboardPage.upsellScreenButton).toBeVisible();
+ await dashboardPage.upsellScreenButton.click();
+ await page.waitForURL(/.*\/data-broker-profiles\/view-data-brokers\/?/);
+ await expect(dataBrokersPage.forwardArrowButton).toBeVisible();
+ await dataBrokersPage.forwardArrowButton.click();
+ await page.waitForURL(/.*\/high-risk-data-breaches.*/);
+ const highRiskDataBreachLi = page.locator(
+ 'li:has(div:has-text("High risk data breaches"))',
+ );
+ await expect(highRiskDataBreachLi).toBeVisible();
+ await expect(highRiskDataBreachLi).toHaveAttribute(
+ "aria-current",
+ "step",
+ );
+ await expect(
+ highRiskDataBreachLi
+ .locator("div")
+ .getByText("High risk data breaches"),
+ ).toBeVisible();
+ });
+ },
+);
From 4e55128f72c470df18865bda08970b833a64c3d2 Mon Sep 17 00:00:00 2001
From: mozilla-pontoon
Date: Sun, 21 Jul 2024 12:01:23 +0000
Subject: [PATCH 122/137] Import translations from l10n repository (2024-07-21)
---
locales/cs/landing-all.ftl | 6 +-----
locales/cy/landing-all.ftl | 6 +-----
locales/de/landing-all.ftl | 6 +-----
locales/el/landing-all.ftl | 6 +-----
locales/en-GB/landing-all.ftl | 6 +-----
locales/es-AR/landing-all.ftl | 6 +-----
locales/es-CL/landing-all.ftl | 6 +-----
locales/fi/dashboard.ftl | 20 ++------------------
locales/fi/fix.ftl | 9 ++++++++-
locales/fi/landing-all.ftl | 6 +-----
locales/fi/settings.ftl | 1 +
locales/fr/landing-all.ftl | 6 +-----
locales/hu/landing-all.ftl | 6 +-----
locales/ia/landing-all.ftl | 6 +-----
locales/id/landing-all.ftl | 6 +-----
locales/it/landing-all.ftl | 6 +-----
locales/nl/landing-all.ftl | 6 +-----
locales/nn-NO/breaches.ftl | 2 ++
locales/pt-PT/landing-all.ftl | 6 +-----
locales/ru/landing-all.ftl | 6 +-----
locales/sl/dashboard.ftl | 6 ++----
locales/sl/landing-all.ftl | 1 +
locales/sv-SE/landing-all.ftl | 6 +-----
locales/tr/landing-all.ftl | 6 +-----
locales/vi/landing-all.ftl | 6 +-----
locales/zh-CN/landing-all.ftl | 6 +-----
locales/zh-TW/landing-all.ftl | 6 +-----
27 files changed, 37 insertions(+), 128 deletions(-)
diff --git a/locales/cs/landing-all.ftl b/locales/cs/landing-all.ftl
index 835a81552ba..67b8cfcdf52 100644
--- a/locales/cs/landing-all.ftl
+++ b/locales/cs/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Zjistěte, kde jsou vaše soukromé informace odhalené — a vezměte si je zpět
landing-all-hero-lead = Prověřujeme úniky údajů a zjišťujeme, zda nedošlo k úniku vašich údajů. Následně vám nabízíme kroky k nápravě.
-
landing-all-hero-emailform-input-placeholder = vasejmeno@example.com
landing-all-hero-emailform-input-label = Zadejte svou e-mailovou adresu a zkontrolujte, zda nedošlo k úniku údajů.
landing-all-hero-emailform-submit-label = Zkontrolovat
-
+landing-all-hero-emailform-submit-sign-in-label = Pro skenování zdarma se přihlaste
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = odhalení
@@ -66,7 +64,5 @@ landing-all-help-protect-you-feature-one = Vyhledáme vás ve všech známých p
landing-all-help-protect-you-feature-two = Provedeme vás kroky k vyřešení každého úniku.
landing-all-help-protect-you-feature-three = Průběžně budeme monitorovat a zasílat vám upozornění na nové úniky.
landing-all-help-protect-you-cta = Přihlásit se k odběru upozornění na úniky
-
landing-all-get-started = Zadejte svou e-mailovou adresu a začněte
landing-all-take-back-data = Získejte opět kontrolu nad svými údaji
-
diff --git a/locales/cy/landing-all.ftl b/locales/cy/landing-all.ftl
index 8a11bdfab1c..084c7456a49 100644
--- a/locales/cy/landing-all.ftl
+++ b/locales/cy/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Canfod lle mae'ch manylion preifat yn cael eu rhyddhau — a'u cipio nôl
landing-all-hero-lead = Rydym yn sganio tor-data i weld a yw'ch data wedi'u datgelu ac yn cynnig camau i chi i'w drwsio.
-
landing-all-hero-emailform-input-placeholder = eichenw@example.com
landing-all-hero-emailform-input-label = Rhowch eich cyfeiriad e-bost i wirio am ddatguddiadau tor-data.
landing-all-hero-emailform-submit-label = Cael sgan am ddim
-
+landing-all-hero-emailform-submit-sign-in-label = Mewngofnodwch i gael sgan am ddim
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = datgeliadau
@@ -72,7 +70,5 @@ landing-all-help-protect-you-feature-one = Byddwn yn chwilio amdanoch ym mhob ac
landing-all-help-protect-you-feature-two = Byddwn yn eich arwain trwy'r camau i ddatrys pob tor-data
landing-all-help-protect-you-feature-three = Byddwn yn monitro ac yn anfon rhybuddion atoch yn barhaus am unrhyw dor-data newydd
landing-all-help-protect-you-cta = Cofrestrwch am rybuddion tor-data
-
landing-all-get-started = Sganiwch eich e-bost i ddechrau
landing-all-take-back-data = Ail feddiannwch eich rheolaeth o'ch data
-
diff --git a/locales/de/landing-all.ftl b/locales/de/landing-all.ftl
index f98caf68133..6b87a33b972 100644
--- a/locales/de/landing-all.ftl
+++ b/locales/de/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Finden Sie heraus, wo Ihre persönlichen Daten offengelegt wurden – und holen Sie sie zurück
landing-all-hero-lead = Wir untersuchen Datenlecks, um zu sehen, ob Ihre Daten offengelegt wurden, und zeigen Ihnen die Schritte, um das Problem zu beheben.
-
landing-all-hero-emailform-input-placeholder = ihrname@example.com
landing-all-hero-emailform-input-label = Geben Sie Ihre E-Mail-Adresse ein, um sie auf Datenlecks zu überprüfen.
landing-all-hero-emailform-submit-label = Kostenloser Scan
-
+landing-all-hero-emailform-submit-sign-in-label = Melden Sie sich an, um einen kostenlosen Scan zu erhalten
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = Offenlegungen
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Wir suchen in allen bekannten Datenle
landing-all-help-protect-you-feature-two = Wir führen Sie durch die Schritte zur Behebung jedes einzelnen Datenlecks
landing-all-help-protect-you-feature-three = Wir führen unser Monitoring kontinuierlich durch und warnen Sie bei allen neuen Datenlecks
landing-all-help-protect-you-cta = Melden Sie sich an, um Warnungen bei Datenlecks zu erhalten
-
landing-all-get-started = Scannen Sie Ihre E-Mail-Adresse, um loszulegen
landing-all-take-back-data = Holen Sie sich die Kontrolle über Ihre Daten zurück
-
diff --git a/locales/el/landing-all.ftl b/locales/el/landing-all.ftl
index ae6b935e813..29df4c85723 100644
--- a/locales/el/landing-all.ftl
+++ b/locales/el/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Μάθετε πού εκτίθενται οι προσωπικές σας πληροφορίες και ανακτήστε τις
landing-all-hero-lead = Σαρώνουμε τις παραβιάσεις δεδομένων για να δούμε εάν έχουν διαρρεύσει τα δεδομένα σας και σας παρέχουμε μέτρα για τη διόρθωσή τους.
-
landing-all-hero-emailform-input-placeholder = toonomasas@example.com
landing-all-hero-emailform-input-label = Εισαγάγετε τη διεύθυνση email σας για να ελέγξετε εάν έχει εκτεθεί σε παραβιάσεις δεδομένων.
landing-all-hero-emailform-submit-label = Δωρεάν σάρωση
-
+landing-all-hero-emailform-submit-sign-in-label = Συνδεθείτε για να λάβετε τη δωρεάν σάρωση
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = εκθέσεις
@@ -62,7 +60,5 @@ landing-all-help-protect-you-feature-one = Θα κάνουμε αναζήτησ
landing-all-help-protect-you-feature-two = Θα σας καθοδηγήσουμε στα βήματα για την επίλυση κάθε παραβίασης
landing-all-help-protect-you-feature-three = Θα παρακολουθούμε συνεχώς και θα σας ειδοποιούμε για τυχόν νέες παραβιάσεις
landing-all-help-protect-you-cta = Εγγραφή για ειδοποιήσεις παραβιάσεων
-
landing-all-get-started = Σαρώστε το email σας για να ξεκινήσετε
landing-all-take-back-data = Ανακτήστε τον έλεγχο των δεδομένων σας
-
diff --git a/locales/en-GB/landing-all.ftl b/locales/en-GB/landing-all.ftl
index af3cc298445..500d9b91acd 100644
--- a/locales/en-GB/landing-all.ftl
+++ b/locales/en-GB/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Find where your private info is exposed — and take it back
landing-all-hero-lead = We scan data breaches to see if your data has been leaked and give you steps to fix it.
-
landing-all-hero-emailform-input-placeholder = yourname@example.com
landing-all-hero-emailform-input-label = Enter your email address to check for data breach exposures.
landing-all-hero-emailform-submit-label = Get free scan
-
+landing-all-hero-emailform-submit-sign-in-label = Sign in to get free scan
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = exposures
@@ -62,7 +60,5 @@ landing-all-help-protect-you-feature-one = We’ll search for you in all known d
landing-all-help-protect-you-feature-two = We’ll guide you through the steps to resolve each breach
landing-all-help-protect-you-feature-three = We’ll continuously monitor and send you alerts for any new breaches
landing-all-help-protect-you-cta = Sign up for breach alerts
-
landing-all-get-started = Scan your email to get started
landing-all-take-back-data = Take back control of your data
-
diff --git a/locales/es-AR/landing-all.ftl b/locales/es-AR/landing-all.ftl
index 0261141a9bf..bdc313612ab 100644
--- a/locales/es-AR/landing-all.ftl
+++ b/locales/es-AR/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Fijate si tu información privada fue expuesta — y recuperala
landing-all-hero-lead = Analizamos las filtraciones de datos para ver si tus datos se han filtrado y te brindamos pasos para solucionarlo.
-
landing-all-hero-emailform-input-placeholder = yourname@example.com
landing-all-hero-emailform-input-label = Ingresá tu dirección de correo electrónico para verificar si hay exposiciones a filtraciones de datos.
landing-all-hero-emailform-submit-label = Hacé un escaneo gratuito
-
+landing-all-hero-emailform-submit-sign-in-label = Iniciá sesión para escanear gratis
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = exposiciones
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Te buscaremos en todas las filtracion
landing-all-help-protect-you-feature-two = Te guiaremos a través de los pasos necesarios para resolver cada filtración
landing-all-help-protect-you-feature-three = Monitorearemos continuamente y te enviaremos alertas sobre cualquier nueva filtración.
landing-all-help-protect-you-cta = Registrate para recibir alertas de filtraciones
-
landing-all-get-started = Escaneá tu correo electrónico para empezar
landing-all-take-back-data = Recuperá el control de tus datos
-
diff --git a/locales/es-CL/landing-all.ftl b/locales/es-CL/landing-all.ftl
index 3765c5ecaf0..4d26261ee5f 100644
--- a/locales/es-CL/landing-all.ftl
+++ b/locales/es-CL/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Encuentra donde tu información privada fue expuesta — y recupérala
landing-all-hero-lead = Analizamos las filtraciones de datos para ver si tus datos se han filtrado y te brindamos pasos para solucionarlo.
-
landing-all-hero-emailform-input-placeholder = tunombre@example.com
landing-all-hero-emailform-input-label = Ingresa tu dirección de correo electrónico para verificar si hay exposiciones a filtraciones de datos.
landing-all-hero-emailform-submit-label = Obtén un escaneo gratuito
-
+landing-all-hero-emailform-submit-sign-in-label = Conéctate para obtener un escaneo gratuito
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = exposiciones
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Te buscaremos en todas las filtracion
landing-all-help-protect-you-feature-two = Te guiaremos a través de los pasos para resolver cada filtración
landing-all-help-protect-you-feature-three = Monitorearemos continuamente y te enviaremos alertas sobre cualquier nueva filtración.
landing-all-help-protect-you-cta = Regístrate para recibir alertas de filtraciones
-
landing-all-get-started = Escanea tu correo electrónico para comenzar
landing-all-take-back-data = Recupera el control de tu información
-
diff --git a/locales/fi/dashboard.ftl b/locales/fi/dashboard.ftl
index 48d0f383cc8..9e0a5d76192 100644
--- a/locales/fi/dashboard.ftl
+++ b/locales/fi/dashboard.ftl
@@ -25,23 +25,15 @@ exposure-chart-caption = Tämä kaavio näyttää, kuinka monta kertaa tietosi o
exposure-chart-returning-user-upgrade-prompt = Kotiosoite, perheenjäsenet ja muut eivät vielä sisälly.
exposure-chart-returning-user-upgrade-prompt-cta = Aloita ilmainen tarkistus
exposure-chart-scan-in-progress-prompt = Tarkistus käynnissä: osoite, perheenjäsenet ja muut eivät vielä sisälly.
-
modal-active-number-of-exposures-title = Tietoja aktiivisten altistumisten määrästä
-
modal-cta-ok = OK
-modal-open-alt = Avaa
-modal-close-alt = Sulje
-
+modal-cta-got-it = Selvä
progress-card-heres-what-we-fixed-headline-all = Tämän korjasit
progress-card-manually-fixed-headline = Käsin korjattu
-
dashboard-tab-label-action-needed = Toimenpiteitä tarvitaan
dashboard-tab-label-fixed = Korjattu
dashboard-exposures-all-fixed-label = Kaikki korjattu täällä!
-
-
dashboard-exposures-area-headline = Näytä kaikki sivustot, joissa tietosi ovat altistuneet
-
# Note: this line follows dashboard-exposures-area-description-all-line1.
# Variables:
# $data_breach_unresolved_num (number) - the unresolved number of data breaches the user has.
@@ -51,7 +43,6 @@ dashboard-exposures-area-description-all-line2 =
*[other] Se esiintyi { $data_breach_unresolved_num } tietovuodossa.
}
dashboard-fixed-area-headline-all = Näytä kaikki altistumiset, jotka on korjattu
-
# This is the label on a button that opens a popover menu, which shows a menu to adjust filters for the listed exposures.
dashboard-exposures-filter = Suodatin
dashboard-exposures-filter-company = Yritys
@@ -68,21 +59,14 @@ dashboard-exposures-filter-show-results = Näytä tulokset
dashboard-top-banner-section-label = Hallintapaneelin yhteenveto
dashboard-top-banner-scan-in-progress-title = Tarkistus on edelleen kesken
-
dashboard-top-banner-your-data-is-protected-title = Tietosi on suojattu
-
dashboard-top-banner-lets-keep-protecting-title = Jatketaan tietojesi suojaamista
dashboard-top-banner-lets-keep-protecting-cta = Jatketaan
-
dashboard-top-banner-protect-your-data-title = Suojataan tietosi
dashboard-top-banner-protect-your-data-cta = Korjataan se
-
dashboard-top-banner-no-exposures-found-title = Vuotoja ei löytynyt
dashboard-no-exposures-label = Vuotoja ei löytynyt
-
dashboard-top-banner-monitor-more-cta = Tarkkaile useampia sähköpostiosoitteita
-# About Exposure Statuses Modal
+# About Exposure Indicators Modal
-modal-exposure-status-title = Tietoja altistumistiloista
-modal-exposure-status-fixed = Korjattu tarkoittaa, että altistuminen on ratkaistu, eikä sinun tarvitse tehdä mitään.
diff --git a/locales/fi/fix.ftl b/locales/fi/fix.ftl
index 213de094158..87ae3db5aa3 100644
--- a/locales/fi/fix.ftl
+++ b/locales/fi/fix.ftl
@@ -5,7 +5,6 @@
fix-flow-nav-high-risk-data-breaches = Suuren riskin tietomurrot
fix-flow-nav-leaked-passwords = Vuotaneet salasanat
fix-flow-nav-security-recommendations = Turvallisuussuositukset
-
guided-resolution-flow-exit = Palaa hallintapaneeliin
guided-resolution-flow-next-arrow = Siirry seuraavaan vaiheeseen
guided-resolution-flow-step-navigation-label = Ohjatut vaiheet
@@ -117,6 +116,12 @@ security-recommendation-steps-cta-label = Selvä!
# Phone security recommendation
security-recommendation-phone-title = Suojaa puhelinnumerosi
+# $num_breaches is the number of breaches where the phone number was found.
+security-recommendation-phone-summary =
+ { $num_breaches ->
+ [one] Puhelinnumerosi paljastui { $num_breaches } tietovuodossa:
+ *[other] Puhelinnumerosi paljastui { $num_breaches } tietovuodossa:
+ }
security-recommendation-phone-step-two = Älä napsauta tuntemattomien lähettäjien tekstiviesteissä olevia linkkejä. Jos viesti vaikuttaa olevan luotettavasta lähteestä, soita lähettäjälle vahvistaaksesi
# Email security recommendation
@@ -143,6 +148,8 @@ security-recommendation-ip-summary =
[one] IP-osoitteesi paljastui { $num_breaches } tietovuodon yhteydessä:
*[other] IP-osoitteesi paljastui { $num_breaches } tietovuodon yhteydessä:
}
+security-recommendation-ip-description = IP-osoitteesi osoittaa sijaintisi ja Internet-palveluntarjoajasi. Hakkerit voivat käyttää näitä tietoja paikantaakseen sinut tai yrittääkseen muodostaa yhteyden laitteihisi.
+security-recommendation-ip-step-one = Käytä VPN:ää (kuten { -brand-mozilla-vpn }) piilottaaksesi todellisen IP-osoitteesi ja käyttääksesi Internetiä yksityisesti.
# Leaked Passwords
diff --git a/locales/fi/landing-all.ftl b/locales/fi/landing-all.ftl
index 936bc296df3..8196541b4ee 100644
--- a/locales/fi/landing-all.ftl
+++ b/locales/fi/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Selvitä missä yksityiset tietosi ovat paljastuneet – ja ota ne takaisin
landing-all-hero-lead = Tarkistamme tietovuodot havaitaksemme, ovatko tietosi vuotaneet, ja annamme ohjeita vuotojen korjaamiseksi.
-
landing-all-hero-emailform-input-placeholder = nimi@example.com
landing-all-hero-emailform-input-label = Syötä sähköpostiosoitteesi tarkistaaksesi mahdolliset tietovuodot.
landing-all-hero-emailform-submit-label = Hanki ilmainen tarkistus
-
+landing-all-hero-emailform-submit-sign-in-label = Kirjaudu sisään saadaksesi ilmaisen tarkistuksen
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = vuotoa
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Etsimme sinua kaikista tunnetuista ti
landing-all-help-protect-you-feature-two = Opastamme sinua kunkin tietovuodon ratkaisemiseksi
landing-all-help-protect-you-feature-three = Jatkamme tarkkailua ja lähetämme sinulle ilmoituksia uusista tietovuodoista
landing-all-help-protect-you-cta = Tilaa vuotohälytykset
-
landing-all-get-started = Tarkista sähköpostiosoitteesi aloittaaksesi
landing-all-take-back-data = Ota henkilökohtaiset tietosi takaisin hallintaasi
-
diff --git a/locales/fi/settings.ftl b/locales/fi/settings.ftl
index f67061c5c89..2c24cfd6486 100644
--- a/locales/fi/settings.ftl
+++ b/locales/fi/settings.ftl
@@ -53,6 +53,7 @@ settings-delete-monitor-free-account-title = Poista { -brand-monitor } -tili
settings-delete-monitor-free-account-description = Tämä poistaa pysyvästi { -brand-monitor } -tilisi ja poistaa kaikki ilmoitukset käytöstä.
settings-delete-monitor-free-account-cta-label = Poista tili
settings-delete-monitor-free-account-dialog-title = { -brand-monitor } -tilisi poistetaan pysyvästi
+settings-delete-monitor-free-account-dialog-lead-v2 = Kaikki { -brand-monitor } -tilisi tiedot poistetaan, emmekä enää seuraa uusia tietovuotoja. Tämä ei poista { -brand-mozilla-account }äsi.
settings-delete-monitor-free-account-dialog-cta-label = Poista tili
settings-delete-monitor-free-account-dialog-cancel-button-label = Unohdetaan tämä, palataan takaisin
settings-delete-monitor-account-confirmation-toast-label-2 = { -brand-monitor } -tilisi on nyt poistettu.
diff --git a/locales/fr/landing-all.ftl b/locales/fr/landing-all.ftl
index 8b27bc8b37d..067c7b8059c 100644
--- a/locales/fr/landing-all.ftl
+++ b/locales/fr/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Découvrez où vos informations personnelles ont fuité et reprenez le contrôle
landing-all-hero-lead = Nous analysons les fuites de données pour vérifier si vos données ont été divulguées et nous vous indiquons les étapes pour y remédier.
-
landing-all-hero-emailform-input-placeholder = votrenom@example.com
landing-all-hero-emailform-input-label = Saisissez votre adresse e-mail pour vérifier l’existence de fuites de données.
landing-all-hero-emailform-submit-label = Effectuer un scan gratuit
-
+landing-all-hero-emailform-submit-sign-in-label = Connectez-vous pour obtenir un scan gratuit
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = détections
@@ -60,7 +58,5 @@ landing-all-help-protect-you-feature-one = Nous vous rechercherons dans toutes l
landing-all-help-protect-you-feature-two = Nous vous guiderons à travers les étapes pour résoudre chaque fuite
landing-all-help-protect-you-feature-three = Nous effectuerons une surveillance permanente et vous enverrons des alertes lors de toute nouvelle fuite de données
landing-all-help-protect-you-cta = S’inscrire aux alertes de fuites de données
-
landing-all-get-started = Scannez votre adresse e-mail pour commencer
landing-all-take-back-data = Reprenez le contrôle de vos données
-
diff --git a/locales/hu/landing-all.ftl b/locales/hu/landing-all.ftl
index 4853d3b97b7..9efebe324ce 100644
--- a/locales/hu/landing-all.ftl
+++ b/locales/hu/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Tudja meg, hogy hol kerültek ki a személyes adatai – és szerezze vissza azokat
landing-all-hero-lead = Átvizsgáljuk az adatvédelmi incidenseket, hogy megtudjuk, kiszivárogtak-e az adatai, és lépéseket adunk a javításához.
-
landing-all-hero-emailform-input-placeholder = email@example.com
landing-all-hero-emailform-input-label = Adja meg az e-mail-címét, hogy ellenőrizze az adatvédelmi incidenseket.
landing-all-hero-emailform-submit-label = Ingyenes vizsgálat kérése
-
+landing-all-hero-emailform-submit-sign-in-label = Jelentkezzen be az ingyenes vizsgálathoz
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = kitettség
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Keresni fogjuk az összes ismert adat
landing-all-help-protect-you-feature-two = Végigvezetjük az egyes adatvédelmi incidensek megoldásához szükséges lépéseken
landing-all-help-protect-you-feature-three = Folyamatosan monitorozzuk, és figyelmeztetjük az új adatvédelmi incidensekről
landing-all-help-protect-you-cta = Iratkozzon fel az adatvédelmi incidensek figyelmeztetéseire
-
landing-all-get-started = A kezdéshez vizsgálja meg az e-mail-címét
landing-all-take-back-data = Szerezze vissza az adatai feletti irányítást
-
diff --git a/locales/ia/landing-all.ftl b/locales/ia/landing-all.ftl
index 13c47194e0f..bf9d417dc05 100644
--- a/locales/ia/landing-all.ftl
+++ b/locales/ia/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Discoperi ubi tu info private es exponite, e recupera los
landing-all-hero-lead = Nos scande le violationes de datos pro vider si tu datos ha essite revelate e dar te le passos pro corriger los.
-
landing-all-hero-emailform-input-placeholder = yourname@example.com
landing-all-hero-emailform-input-label = Insere tu adresse email pro controlar pro exposition a violation de datos.
landing-all-hero-emailform-submit-label = Recipe scansion gratuite
-
+landing-all-hero-emailform-submit-sign-in-label = Accede pro un scansion gratuite
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = expositiones
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Nos cercara pro te in tote le note vi
landing-all-help-protect-you-feature-two = Nos te guidara passo a passo a resolver cata violation
landing-all-help-protect-you-feature-three = Nos continuemente surveliara e te inviara avisos pro cata nove violation
landing-all-help-protect-you-cta = Inscribe te pro alertas de violationes
-
landing-all-get-started = Scande tu email pro comenciar
landing-all-take-back-data = Reprende le controlo de tu datos
-
diff --git a/locales/id/landing-all.ftl b/locales/id/landing-all.ftl
index 910fe49c15f..acad2a4c22d 100644
--- a/locales/id/landing-all.ftl
+++ b/locales/id/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Temukan di mana info pribadi Anda terbuka — dan ambil kembali
landing-all-hero-lead = Kami memindai kebocoran data untuk melihat apakah data Anda telah bocor dan memberi Anda langkah-langkah untuk memperbaikinya.
-
landing-all-hero-emailform-input-placeholder = namaanda@example.com
landing-all-hero-emailform-input-label = Masukkan alamat surel Anda untuk memeriksa eksposur pelanggaran data.
landing-all-hero-emailform-submit-label = Dapatkan pemindaian gratis
-
+landing-all-hero-emailform-submit-sign-in-label = Masuk untuk mendapatkan pindaian gratis
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = eksposur
@@ -62,7 +60,5 @@ landing-all-help-protect-you-feature-one = Kami akan mencari Anda di semua pembo
landing-all-help-protect-you-feature-two = Kami akan memandu Anda melalui langkah-langkah untuk menyelesaikan setiap pelanggaran
landing-all-help-protect-you-feature-three = Kami akan terus memantau dan mengirimi Anda peringatan untuk setiap pelanggaran baru
landing-all-help-protect-you-cta = Daftar untuk peringatan pembobolan
-
landing-all-get-started = Pindai surel Anda untuk memulai
landing-all-take-back-data = Ambil kembali kendali atas data Anda
-
diff --git a/locales/it/landing-all.ftl b/locales/it/landing-all.ftl
index fc326d836ff..78ef06c8f9e 100644
--- a/locales/it/landing-all.ftl
+++ b/locales/it/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Scopri dove sono esposte le tue informazioni personali e riprendine possesso
landing-all-hero-lead = Analizziamo le violazioni di dati per verificare se i tuoi dati sono stati esposti e ti forniamo suggerimenti per risolvere il problema.
-
landing-all-hero-emailform-input-placeholder = iltuonome@example.com
landing-all-hero-emailform-input-label = Inserisci il tuo indirizzo email per verificare la presenza di violazioni di dati.
landing-all-hero-emailform-submit-label = Ottieni una scansione gratuita
-
+landing-all-hero-emailform-submit-sign-in-label = Accedi per una scansione gratuita
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = esposizioni
@@ -60,7 +58,5 @@ landing-all-help-protect-you-feature-one = Ti cercheremo in tutte le violazioni
landing-all-help-protect-you-feature-two = Ti guideremo attraverso i passaggi per risolvere ogni violazione
landing-all-help-protect-you-feature-three = Continueremo a monitorare e ti invieremo avvisi per qualsiasi nuova violazione
landing-all-help-protect-you-cta = Iscriviti per ricevere avvisi sulle violazioni
-
landing-all-get-started = Scansiona la tua email per iniziare
landing-all-take-back-data = Riprendi il controllo dei tuoi dati
-
diff --git a/locales/nl/landing-all.ftl b/locales/nl/landing-all.ftl
index fb61fdced70..78a3702056f 100644
--- a/locales/nl/landing-all.ftl
+++ b/locales/nl/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Ontdek waar uw privégegevens zijn gelekt – en neem ze terug
landing-all-hero-lead = We scannen datalekken om te zien of uw gegevens zijn gelekt en bieden u stappen om dit op te lossen.
-
landing-all-hero-emailform-input-placeholder = uwnaam@example.com
landing-all-hero-emailform-input-label = Voer uw e-mailadres in om te controleren op datalekken.
landing-all-hero-emailform-submit-label = Ontvang een gratis scan
-
+landing-all-hero-emailform-submit-sign-in-label = Meld u aan om de gratis scan te ontvangen
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = lekken
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Wij gaan voor u op zoek in alle beken
landing-all-help-protect-you-feature-two = We leiden u door de stappen om elk lek op te lossen
landing-all-help-protect-you-feature-three = We monitoren voortdurend en sturen u waarschuwingen bij nieuwe lekken
landing-all-help-protect-you-cta = Inschrijven voor waarschuwingen over datalekken
-
landing-all-get-started = Scan uw e-mailadres om te beginnen
landing-all-take-back-data = Neem uw gegevens weer onder controle
-
diff --git a/locales/nn-NO/breaches.ftl b/locales/nn-NO/breaches.ftl
index 5efa6c6b97b..d5ee3533c88 100644
--- a/locales/nn-NO/breaches.ftl
+++ b/locales/nn-NO/breaches.ftl
@@ -48,6 +48,8 @@ breach-checklist-address-body = Det er lett å finne adresser i offentlege regis
## Prompts the user for changes when there is a breach detected of date of birth
+breach-checklist-dob-header = Endre alle passord eller PIN-kodar som inneheld fødselsdagen din.
+breach-checklist-dob-body = Fødselsdatoar er lette å finne i offentlege register, og folk som finn dei kan enkelt gjette PIN-koden din.
## Prompts the user for changes when there is a breach detected of phone number
diff --git a/locales/pt-PT/landing-all.ftl b/locales/pt-PT/landing-all.ftl
index 6c314434e37..0b5e67b74e2 100644
--- a/locales/pt-PT/landing-all.ftl
+++ b/locales/pt-PT/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Descubra onde a sua informação privada está exposta – e recupere o controlo
landing-all-hero-lead = Verificamos violações de dados para confirmar se os seus dados foram capturados e indicamos os passos que pode tomar para corrigir as mesmas.
-
landing-all-hero-emailform-input-placeholder = oseunome@example.com
landing-all-hero-emailform-input-label = Insira o seu endereço de e-mail para verificar se existe exposição a violações de dados.
landing-all-hero-emailform-submit-label = Obter verificação gratuita
-
+landing-all-hero-emailform-submit-sign-in-label = Iniciar sessão para obter a verificação gratuita
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = exposições
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Iremos procurar por si em todas as vi
landing-all-help-protect-you-feature-two = Iremos apoiar através de passos guiados para resolver cada violação de dados
landing-all-help-protect-you-feature-three = Iremos monitorizar de forma continua e enviar-lhe alertas para novas violações de dados
landing-all-help-protect-you-cta = Registe-se para alertas de falhas de segurança
-
landing-all-get-started = Analise o seu e-mail para começar
landing-all-take-back-data = Retome o controlo dos seus dados
-
diff --git a/locales/ru/landing-all.ftl b/locales/ru/landing-all.ftl
index e687d314e6c..bdbbed23e62 100644
--- a/locales/ru/landing-all.ftl
+++ b/locales/ru/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Найдите, где находится ваша личная информация, и верните обратно
landing-all-hero-lead = Мы сканируем утечки данных, чтобы определить, не произошла ли утечка ваших данных, и даем вам инструкции по исправлению.
-
landing-all-hero-emailform-input-placeholder = вашлогин@example.com
landing-all-hero-emailform-input-label = Введите свой адрес электронной почты, чтобы проверить наличие утечки данных.
landing-all-hero-emailform-submit-label = Получить бесплатное сканирование
-
+landing-all-hero-emailform-submit-sign-in-label = Войдите, чтобы получить бесплатное сканирование
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = утечки
@@ -66,7 +64,5 @@ landing-all-help-protect-you-feature-one = Мы будем искать вас
landing-all-help-protect-you-feature-two = Мы проведем вас через шаги по устранению каждой утечки
landing-all-help-protect-you-feature-three = Мы будем постоянно отслеживать и отправлять вам оповещения о любых новых утечках
landing-all-help-protect-you-cta = Подпишитесь на уведомления об утечках
-
landing-all-get-started = Просканируйте свой адрес электронной почты, чтобы начать
landing-all-take-back-data = Верните контроль над своими данными
-
diff --git a/locales/sl/dashboard.ftl b/locales/sl/dashboard.ftl
index b79bdcd1752..b1b35c3e6c1 100644
--- a/locales/sl/dashboard.ftl
+++ b/locales/sl/dashboard.ftl
@@ -47,6 +47,7 @@ modal-active-number-of-exposures-part-three-all = Ko bodo razrešene, bodo dodan
modal-fixed-number-of-exposures-title = O številu določenih izpostavljenosti
modal-fixed-number-of-exposures-all = Ta grafikon vključuje skupno število odpravljenih kraj podatkov za vse e-poštne naslove, ki jih trenutno spremljate. Ko so izpostavljenosti označene kot fiksne, bodo tukaj dodane skupni vsoti.
modal-cta-ok = V redu
+modal-cta-got-it = Razumem
open-modal-alt = Odpri način
close-modal-alt = Zapri modalno okno
open-tooltip-alt = Odpri opis orodja
@@ -143,9 +144,6 @@ dashboard-top-banner-non-us-your-data-is-protected-description =
}
dashboard-top-banner-monitor-more-cta = Spremljaj več naslovov
-# About Exposure Statuses Modal
+# About Exposure Indicators Modal
-modal-exposure-status-title = O stanjih izpostavljenosti
modal-exposure-status-description-all = Izpostavljenosti iščemo v vseh znanih krajah podatkov. Vaša izpostavljenost bo imela eno od naslednjih stanj:
-modal-exposure-status-action-needed = Potrebno je dejanje pomeni, da je trenutno aktiven in da ga morate popraviti.
-modal-exposure-status-fixed = Odpravljena pomeni, da je bila izpostavljenost rešena in ne morete storiti ničesar.
diff --git a/locales/sl/landing-all.ftl b/locales/sl/landing-all.ftl
index 288a6484e92..a000ff1040b 100644
--- a/locales/sl/landing-all.ftl
+++ b/locales/sl/landing-all.ftl
@@ -8,6 +8,7 @@ landing-all-hero-lead = Pregledamo kraje podatkov, da ugotovimo, ali so vaši po
landing-all-hero-emailform-input-placeholder = ime@example.com
landing-all-hero-emailform-input-label = Vnesite svoj e-poštni naslov za preverjanje izpostavljenosti kraji podatkov.
landing-all-hero-emailform-submit-label = Zagotovite si brezplačen pregled
+landing-all-hero-emailform-submit-sign-in-label = Prijavite se za brezplačno skeniranje
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = izpostavljenosti
diff --git a/locales/sv-SE/landing-all.ftl b/locales/sv-SE/landing-all.ftl
index 16baf436a8e..7ee23cf1beb 100644
--- a/locales/sv-SE/landing-all.ftl
+++ b/locales/sv-SE/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Hitta var din privata information är exponerad — och ta tillbaka den
landing-all-hero-lead = Vi skannar dataintrång för att se om din data har läckt och ger dig tips för att åtgärda det.
-
landing-all-hero-emailform-input-placeholder = dittnamn@exempel.se
landing-all-hero-emailform-input-label = Ange din e-postadress för att söka efter exponeringar för dataintrång.
landing-all-hero-emailform-submit-label = Få gratis skanning
-
+landing-all-hero-emailform-submit-sign-in-label = Logga in för att få gratis skanning
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = exponeringar
@@ -62,7 +60,5 @@ landing-all-help-protect-you-feature-one = Vi kommer att söka åt dig i alla k
landing-all-help-protect-you-feature-two = Vi guidar dig genom stegen för att lösa varje intrång
landing-all-help-protect-you-feature-three = Vi kommer kontinuerligt att övervaka och skicka dig varningar om nya intrång
landing-all-help-protect-you-cta = Registrera dig för intrångsvarningar
-
landing-all-get-started = Skanna din e-post för att komma igång
landing-all-take-back-data = Ta tillbaka kontrollen över din data
-
diff --git a/locales/tr/landing-all.ftl b/locales/tr/landing-all.ftl
index bff69a22785..c9b7ae8586c 100644
--- a/locales/tr/landing-all.ftl
+++ b/locales/tr/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Kişisel bilgilerinizin nerede ele geçirildiğini öğrenin
landing-all-hero-lead = Verilerinizin sızdırılıp sızdırılmadığını görmek için veri ihlallerini tarıyor ve bunları düzeltmeniz için gereken adımları söylüyoruz.
-
landing-all-hero-emailform-input-placeholder = kullanici@example.com
landing-all-hero-emailform-input-label = Veri ihlali risklerini kontrol etmek için e-posta adresinizi yazın.
landing-all-hero-emailform-submit-label = Ücretsiz taramayı başlat
-
+landing-all-hero-emailform-submit-sign-in-label = Ücretsiz tarama için giriş yapın
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = veri ihlali
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Bilinen veri ihlallerinde yer alıp a
landing-all-help-protect-you-feature-two = İhlalleri çözmeniz için gereken adımlarda size rehberlik edeceğiz
landing-all-help-protect-you-feature-three = Yeni ihlalleri sürekli olarak izleyip size uyarı göndereceğiz
landing-all-help-protect-you-cta = İhlal uyarılarına kaydolun
-
landing-all-get-started = Kullanmaya başlamak için e-postanızı tarayın
landing-all-take-back-data = Verilerinizin kontrolünü geri alın
-
diff --git a/locales/vi/landing-all.ftl b/locales/vi/landing-all.ftl
index 71f822d9533..4abf8996922 100644
--- a/locales/vi/landing-all.ftl
+++ b/locales/vi/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Tìm hiểu xem thông tin cá nhân của bạn bị lộ ở đâu — và lấy lại thông tin đó
landing-all-hero-lead = Chúng tôi quét các rò rỉ dữ liệu để xem dữ liệu của bạn có bị rò rỉ hay không và cung cấp cho bạn các bước để giải quyết.
-
landing-all-hero-emailform-input-placeholder = yourname@example.com
landing-all-hero-emailform-input-label = Nhập địa chỉ email của bạn để kiểm tra mức độ rò rỉ dữ liệu.
landing-all-hero-emailform-submit-label = Quét miễn phí
-
+landing-all-hero-emailform-submit-sign-in-label = Đăng nhập để được quét miễn phí
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = dữ liệu bị lộ
@@ -62,7 +60,5 @@ landing-all-help-protect-you-feature-one = Chúng tôi sẽ tìm kiếm bạn tr
landing-all-help-protect-you-feature-two = Chúng tôi sẽ hướng dẫn bạn các bước để giải quyết từng rò rỉ
landing-all-help-protect-you-feature-three = Chúng tôi sẽ liên tục theo dõi và gửi cho bạn thông báo về mọi rò rỉ mới
landing-all-help-protect-you-cta = Đăng ký cảnh báo vụ rò rỉ
-
landing-all-get-started = Quét email của bạn để bắt đầu
landing-all-take-back-data = Lấy lại quyền kiểm soát dữ liệu của bạn
-
diff --git a/locales/zh-CN/landing-all.ftl b/locales/zh-CN/landing-all.ftl
index 0d3723b191b..14f2a8fc2c3 100644
--- a/locales/zh-CN/landing-all.ftl
+++ b/locales/zh-CN/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = 扫描隐私信息泄露,收回属于您的秘密
landing-all-hero-lead = 我们会扫描您的数据是否曾遭外泄,并指导您采取措施解决问题。
-
landing-all-hero-emailform-input-placeholder = yourname@example.com
landing-all-hero-emailform-input-label = 输入邮箱地址即可检查数据外泄事件。
landing-all-hero-emailform-submit-label = 免费扫描
-
+landing-all-hero-emailform-submit-sign-in-label = 登录即可免费扫描
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = 次暴露
@@ -56,7 +54,5 @@ landing-all-help-protect-you-feature-one = 我们将在所有已知的数据外
landing-all-help-protect-you-feature-two = 我们指导您采取措施,逐项解决外泄事件问题
landing-all-help-protect-you-feature-three = 我们将持续监测动态,并在发现新的外泄事件时向您发出警报
landing-all-help-protect-you-cta = 订阅数据外泄警报
-
landing-all-get-started = 扫描邮箱地址,开始探查
landing-all-take-back-data = 夺回个人数据的控制权
-
diff --git a/locales/zh-TW/landing-all.ftl b/locales/zh-TW/landing-all.ftl
index 4f840e9a42e..f5a39b32d3a 100644
--- a/locales/zh-TW/landing-all.ftl
+++ b/locales/zh-TW/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = 看看您的隱私資訊在哪裡外洩,並且搶回控制權
landing-all-hero-lead = 我們可掃描已知的資安事件,看看您的資料是否已遭外洩並建議您處理方式。
-
landing-all-hero-emailform-input-placeholder = yourname@example.com
landing-all-hero-emailform-input-label = 輸入您的電子郵件地址,即可檢查是否曾遭資料外洩。
landing-all-hero-emailform-submit-label = 免費掃描
-
+landing-all-hero-emailform-submit-sign-in-label = 登入即可免費掃描
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = 資料曝光事件
@@ -62,7 +60,5 @@ landing-all-help-protect-you-feature-one = 我們會在已知的資料外洩事
landing-all-help-protect-you-feature-two = 我們會帶您逐步操作,針對每場資料外洩事件進行處理
landing-all-help-protect-you-feature-three = 我們將持續監控您的資料,並在發生新的外洩事件時警示您
landing-all-help-protect-you-cta = 訂閱資料外洩警報
-
landing-all-get-started = 掃描您的電子郵件地址,即可使用
landing-all-take-back-data = 搶回您的資料的控制權
-
From 1fc96933a5e64b14e3aa0b3b10d3ac15f4649136 Mon Sep 17 00:00:00 2001
From: mozilla-pontoon
Date: Mon, 22 Jul 2024 12:01:36 +0000
Subject: [PATCH 123/137] Import translations from l10n repository (2024-07-22)
---
locales/cs/dashboard.ftl | 6 +++---
locales/nl/landing-all.ftl | 2 +-
locales/pt-BR/landing-all.ftl | 6 +-----
3 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/locales/cs/dashboard.ftl b/locales/cs/dashboard.ftl
index 6974b2d4a31..26a1e69c7a9 100644
--- a/locales/cs/dashboard.ftl
+++ b/locales/cs/dashboard.ftl
@@ -139,6 +139,6 @@ dashboard-top-banner-monitor-more-cta = Monitorovat více e-mailů
# About Exposure Indicators Modal
modal-exposure-status-description-all = Hledáme úniky údajů ve všech známých únicích. Vaše odhalení bude mít jeden z následujících stavů:
-modal-exposure-indicator-title = Stavy kontaktů
-modal-exposure-indicator-action-needed = K dokončení akce je vyžadována pokročilá nebo ruční akce.
-modal-exposure-indicator-fixed = Problém byl vyřešen a vy už nemusíte podnikat žádné kroky.
+modal-exposure-indicator-title = Stavy odhalení
+modal-exposure-indicator-action-needed = K dokončení akce je nutná pokročilá nebo ruční akce.
+modal-exposure-indicator-fixed = Odhalení bylo vyřešeno a vy už nemusíte podnikat žádné kroky.
diff --git a/locales/nl/landing-all.ftl b/locales/nl/landing-all.ftl
index 78a3702056f..3c87031c54e 100644
--- a/locales/nl/landing-all.ftl
+++ b/locales/nl/landing-all.ftl
@@ -8,7 +8,7 @@ landing-all-hero-lead = We scannen datalekken om te zien of uw gegevens zijn gel
landing-all-hero-emailform-input-placeholder = uwnaam@example.com
landing-all-hero-emailform-input-label = Voer uw e-mailadres in om te controleren op datalekken.
landing-all-hero-emailform-submit-label = Ontvang een gratis scan
-landing-all-hero-emailform-submit-sign-in-label = Meld u aan om de gratis scan te ontvangen
+landing-all-hero-emailform-submit-sign-in-label = Meld u aan om een gratis scan te ontvangen
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = lekken
diff --git a/locales/pt-BR/landing-all.ftl b/locales/pt-BR/landing-all.ftl
index 6045411dd49..88c8ae8cd23 100644
--- a/locales/pt-BR/landing-all.ftl
+++ b/locales/pt-BR/landing-all.ftl
@@ -3,14 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
public-nav-name = { -brand-mozilla-monitor }
-
landing-all-hero-title = Descubra onde suas informações privativas estão sendo expostas e recupere o controle sobre elas
landing-all-hero-lead = Verificamos vazamentos de dados para ver se seus dados foram expostos e fornecemos instruções passo a passo para resolver.
-
landing-all-hero-emailform-input-placeholder = seunome@example.com
landing-all-hero-emailform-input-label = Insira seu endereço de email para verificar exposição em vazamentos de dados.
landing-all-hero-emailform-submit-label = Obtenha uma verificação gratuita
-
+landing-all-hero-emailform-submit-sign-in-label = Entre para obter uma análise gratuita
# This is a label underneath a big number "14" - it's an image that demos Monitor.
landing-all-hero-image-chart-label = exposições
@@ -64,7 +62,5 @@ landing-all-help-protect-you-feature-one = Procuramos em todos os vazamentos con
landing-all-help-protect-you-feature-two = Orientamos nas etapas para resolver cada vazamento
landing-all-help-protect-you-feature-three = Monitoramos continuamente e enviamos alertas sobre novos vazamentos
landing-all-help-protect-you-cta = Cadastre-se para receber alertas de vazamentos
-
landing-all-get-started = Verifique seu email para começar
landing-all-take-back-data = Reassuma o controle sobre seus dados
-
From 4637f12ed4ddd3f49509df659b222b2014757a4b Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 22 Jul 2024 12:09:36 +0000
Subject: [PATCH 124/137] chore(deps-dev): bump prettier from 3.3.2 to 3.3.3
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.2...3.3.3)
---
updated-dependencies:
- dependency-name: prettier
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 8 ++++----
package.json | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 93df26589f2..9f3780954f6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -93,7 +93,7 @@
"jest-fail-on-console": "^3.3.0",
"lint-staged": "^15.2.5",
"mjml-browser": "^4.15.3",
- "prettier": "3.3.2",
+ "prettier": "3.3.3",
"react-intersection-observer": "^9.10.3",
"sass": "^1.77.6",
"storybook": "^8.1.11",
@@ -23765,9 +23765,9 @@
}
},
"node_modules/prettier": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
- "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+ "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
diff --git a/package.json b/package.json
index d24420e07e9..a22fd69da0d 100644
--- a/package.json
+++ b/package.json
@@ -144,7 +144,7 @@
"jest-fail-on-console": "^3.3.0",
"lint-staged": "^15.2.5",
"mjml-browser": "^4.15.3",
- "prettier": "3.3.2",
+ "prettier": "3.3.3",
"react-intersection-observer": "^9.10.3",
"sass": "^1.77.6",
"storybook": "^8.1.11",
From 85841725e0a369e6e0b688d27618ccdd51ee9a2c Mon Sep 17 00:00:00 2001
From: Vincent
Date: Thu, 18 Jul 2024 12:20:40 +0200
Subject: [PATCH 125/137] Re-add allowlist functionality for feature flags
---
.../components/FlagEditor.module.scss | 88 +++++++++
.../feature-flags/components/FlagEditor.tsx | 180 ++++++++++++++++++
.../components/ToggleFlagEnabled.tsx | 63 ------
.../admin/feature-flags/page.module.scss | 14 ++
.../admin/feature-flags/page.tsx | 102 +++-------
.../v1/admin/feature-flags/[flagId]/route.ts | 24 ++-
src/db/tables/featureFlags.ts | 2 +-
src/knex-tables.d.ts | 6 +-
8 files changed, 331 insertions(+), 148 deletions(-)
create mode 100644 src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.module.scss
create mode 100644 src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.tsx
delete mode 100644 src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/ToggleFlagEnabled.tsx
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.module.scss b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.module.scss
new file mode 100644
index 00000000000..f8a8982f219
--- /dev/null
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.module.scss
@@ -0,0 +1,88 @@
+@import "../../../../../../tokens";
+
+.flagWrapper {
+ display: flex;
+ flex-direction: column;
+ gap: $spacing-md;
+ background-color: $color-white;
+ padding: $spacing-lg;
+ border-radius: $border-radius-md;
+ max-width: $content-md;
+}
+
+.flagName {
+ font: $text-title-3xs;
+}
+
+.enabledControl {
+ display: flex;
+ gap: $spacing-xs;
+ font: $text-body-lg;
+}
+
+.allowListWrapper {
+ h4 {
+ font: $text-body-md;
+ font-weight: bold;
+ }
+}
+
+.allowList {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ padding: 0;
+ list-style-type: none;
+}
+
+.addressListing {
+ display: flex;
+ align-items: center;
+ gap: $spacing-xs;
+ font: $text-body-lg;
+
+ :first-child {
+ flex-grow: 1;
+ }
+
+ button {
+ background-color: transparent;
+ border: none;
+ border-radius: $border-radius-xl;
+ aspect-ratio: 1;
+
+ &:hover {
+ cursor: pointer;
+ background-color: $color-blue-50;
+ color: $color-white;
+ }
+ }
+}
+
+.addressAdder {
+ display: flex;
+ align-items: center;
+ gap: $spacing-sm;
+
+ // This rule is more specific than the button:hover in `.addressListing`,
+ // but that class doesn't apply to the same elements:
+ /* stylelint-disable no-descending-specificity */
+ button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100%;
+ background-color: transparent;
+ color: $color-blue-50;
+ border: none;
+ border-radius: $border-radius-sm;
+ padding: $spacing-sm;
+
+ &:hover {
+ cursor: pointer;
+ background-color: $color-blue-50;
+ color: $color-white;
+ }
+ }
+ /* stylelint-enable no-descending-specificity */
+}
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.tsx
new file mode 100644
index 00000000000..8378e7a6f59
--- /dev/null
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/FlagEditor.tsx
@@ -0,0 +1,180 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use client";
+import { FeatureFlagRow } from "knex/types/tables";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+import styles from "./FlagEditor.module.scss";
+import {
+ CheckIcon,
+ DeleteIcon,
+} from "../../../../../../components/server/Icons";
+import type { UpdateFeatureFlagRequestBody } from "../../../../../../api/v1/admin/feature-flags/[flagId]/route";
+import { Button } from "../../../../../../components/client/Button";
+
+export const FlagEditor = (props: { flag: FeatureFlagRow }) => {
+ const [isEnabled, setIsEnabled] = useState(props.flag.is_enabled);
+ const [newAddress, setNewAddress] = useState("");
+ const [newAllowlistedAddresses, setNewAllowListedAddresses] = useState<
+ string[]
+ >([]);
+ const [unAllowlistedAddresses, setUnAllowListedAddresses] = useState<
+ string[]
+ >([]);
+ const router = useRouter();
+
+ const updateFlag = async () => {
+ try {
+ if (isEnabled !== props.flag.is_enabled) {
+ const isEnabledResonse = await sendUpdateRequest(props.flag.name, {
+ id: "isEnabled",
+ isEnabled: isEnabled,
+ });
+ if (!isEnabledResonse.ok) {
+ throw new Error(await isEnabledResonse.text());
+ }
+ }
+
+ const allowList = (props.flag.allow_list ?? [])
+ .filter((address) => !unAllowlistedAddresses.includes(address))
+ .concat(newAllowlistedAddresses);
+ const allowListResponse = await sendUpdateRequest(props.flag.name, {
+ id: "allowList",
+ value: allowList.map((address) => address.trim()).join(","),
+ });
+ if (!allowListResponse.ok) {
+ throw new Error(await allowListResponse.text());
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ router.refresh();
+ };
+
+ return (
+
+
{props.flag.name}
+
+ setIsEnabled(e.target.checked)}
+ />
+
+
+
+ {" "}
+
+ {(props.flag.allow_list?.length ?? 0) -
+ unAllowlistedAddresses.length ===
+ 0 && newAllowlistedAddresses.length === 0 ? (
+ <>Enabled for everyone>
+ ) : (
+ <>Only enable for:>
+ )}
+
+
+ {(props.flag.allow_list ?? [])
+ .filter((address) => !unAllowlistedAddresses.includes(address))
+ .map((address) => {
+ return (
+ -
+
+ setUnAllowListedAddresses((prev) => [...prev, address])
+ }
+ />
+
+ );
+ })}
+ {newAllowlistedAddresses.map((address) => {
+ return (
+ -
+
+ setNewAllowListedAddresses((prev) =>
+ prev.filter((a) => a !== address),
+ )
+ }
+ />
+
+ );
+ })}
+
+
+
{
+ e.preventDefault();
+
+ setNewAllowListedAddresses((prev) => [...prev, newAddress]);
+ setNewAddress("");
+ }}
+ className={styles.addressAdder}
+ >
+
+ setNewAddress(e.target.value)}
+ />
+
+
+
+
+ );
+};
+
+const AllowlistedAddress = (props: {
+ address: string;
+ onRemove: () => void;
+}) => {
+ return (
+
+ {props.address}
+
+
+ );
+};
+
+async function sendUpdateRequest(
+ flagName: string,
+ body: UpdateFeatureFlagRequestBody,
+) {
+ const endpoint = `/api/v1/admin/feature-flags/${flagName}`;
+ const options = {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(body),
+ };
+ return fetch(endpoint, options);
+}
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/ToggleFlagEnabled.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/ToggleFlagEnabled.tsx
deleted file mode 100644
index 3bf7976b6b7..00000000000
--- a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/components/ToggleFlagEnabled.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use client";
-import { useRouter } from "next/navigation";
-import { ChangeEventHandler } from "react";
-
-interface FeatureToggleElement {
- id: string | null;
- name: string | null;
- checked: string | null;
-}
-
-export const ToggleFlagEnabled = (props: {
- id: string | undefined;
- name: string | undefined;
- isEnabled: boolean | undefined;
-}) => {
- const router = useRouter();
-
- const handleChange = (
- event: ChangeEventHandler & {
- target: FeatureToggleElement;
- },
- ) => {
- const eventTarget: FeatureToggleElement = event.target;
-
- const id = eventTarget.id;
- const name = eventTarget.name;
- const isEnabled = eventTarget.checked ? true : false;
-
- if (!name) {
- throw new Error("No flag name provided");
- }
-
- const endpoint = `/api/v1/admin/feature-flags/${name}`;
- const options = {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ id, name, isEnabled }),
- };
- fetch(endpoint, options)
- .then((response) => {
- if (response.ok) {
- router.refresh();
- }
- })
- .catch((ex) => console.error(ex));
- };
-
- return (
- }
- >
- );
-};
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.module.scss b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.module.scss
index 4e6488eee58..9c7e7f512ae 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.module.scss
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.module.scss
@@ -4,6 +4,7 @@
width: 100%;
height: 100%;
background-color: $color-grey-05;
+ overflow: auto;
.tabBar {
height: $tab-bar-height;
@@ -37,4 +38,17 @@
border: 1px solid;
padding: 10px;
}
+
+ h3 {
+ padding: 0 $spacing-2xl;
+ font: $text-title-2xs;
+ }
+}
+
+.flagList {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ gap: $spacing-lg;
+ padding: $spacing-2xl;
}
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.tsx
index 2c686d8df4b..7e41786ce4d 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/admin/feature-flags/page.tsx
@@ -4,14 +4,8 @@
import { notFound, redirect } from "next/navigation";
import { getServerSession } from "../../../../../functions/server/getServerSession";
-import {
- getAllFeatureFlags,
- getDeletedFeatureFlags,
-} from "../../../../../../db/tables/featureFlags";
+import { getAllFeatureFlags } from "../../../../../../db/tables/featureFlags";
import { AddFeatureFlag } from "./components/AddFeatureFlag";
-import { DeleteFeatureFlag } from "./components/DeleteFeatureFlag";
-import { ToggleFlagEnabled } from "./components/ToggleFlagEnabled";
-import { FeatureFlagRow } from "knex/types/tables";
import { isAdmin } from "../../../../../api/utils/auth";
import { Toolbar } from "../../../../../components/client/toolbar/Toolbar";
import styles from "./page.module.scss";
@@ -20,6 +14,7 @@ import {
getPremiumSubscriptionUrl,
} from "../../../../../functions/server/getPremiumSubscriptionInfo";
import { defaultExperimentData } from "../../../../../../telemetry/generated/nimbus/experiments";
+import { FlagEditor } from "./components/FlagEditor";
export default async function FeatureFlagPage() {
const session = await getServerSession();
@@ -36,72 +31,10 @@ export default async function FeatureFlagPage() {
return notFound();
}
- const ActiveFlagsTable = (featureFlags: { data: Array }) => {
- const { data } = featureFlags;
-
- if (!data || data.length === 0) {
- return No data
;
- }
-
- return (
-
-
-
- Name |
- Enabled |
-
-
-
- {data.map((item) => (
-
- {item.name} |
-
-
- {item.is_enabled}
- |
-
-
- |
-
- ))}
-
-
- );
- };
-
- const DeletedFlagsTable = (featureFlags: { data: Array }) => {
- const { data } = featureFlags;
-
- if (!data || data.length === 0) {
- return No data
;
- }
-
- return (
-
-
-
- Name |
- Deleted At |
-
-
-
- {data.map((item) => (
-
- {item.name} |
- {item.deleted_at?.toString()} |
-
- ))}
-
-
- );
- };
-
- const featureFlags = (await getAllFeatureFlags()) ?? null;
- const deletedFeatureFlags = (await getDeletedFeatureFlags()) ?? null;
+ const featureFlags =
+ (await getAllFeatureFlags()).toSorted(
+ (flagA, flagB) => flagB.created_at.getTime() - flagA.created_at.getTime(),
+ ) ?? [];
return (
@@ -124,18 +57,29 @@ export default async function FeatureFlagPage() {
- Note: Feaure flags are deprecated, use{" "}
+ Note: Feature flags are deprecated, use{" "}
Experimenter.
Add New Feature Flag
-
Active Feature Flags
-
-
-
Deleted Feature Flags
-
+
Enabled Feature Flags
+
+ {featureFlags
+ .filter((flag) => flag.is_enabled)
+ .map((flag) => (
+
+ ))}
+
+
Disabled Feature Flags
+
+ {featureFlags
+ .filter((flag) => !flag.is_enabled)
+ .map((flag) => (
+
+ ))}
+
);
diff --git a/src/app/api/v1/admin/feature-flags/[flagId]/route.ts b/src/app/api/v1/admin/feature-flags/[flagId]/route.ts
index df369961c35..56b4f2c9241 100644
--- a/src/app/api/v1/admin/feature-flags/[flagId]/route.ts
+++ b/src/app/api/v1/admin/feature-flags/[flagId]/route.ts
@@ -37,6 +37,28 @@ export async function GET(
}
}
+export type UpdateFeatureFlagRequestBody =
+ | {
+ id: "isEnabled";
+ isEnabled: boolean;
+ }
+ | {
+ id: "dependencies";
+ value: string;
+ }
+ | {
+ id: "allowList";
+ value: string;
+ }
+ | {
+ id: "waitList";
+ value: string;
+ }
+ | {
+ id: "owner";
+ value: string;
+ };
+
export async function PUT(req: NextRequest) {
const session = await getServerSession();
if (isAdmin(session?.user?.email || "")) {
@@ -46,7 +68,7 @@ export async function PUT(req: NextRequest) {
if (!flagName) {
throw new Error("No flag name provided");
}
- const result = await req.json();
+ const result: UpdateFeatureFlagRequestBody = await req.json();
if (result.id === "isEnabled") {
await enableFeatureFlagByName(flagName, result.isEnabled);
diff --git a/src/db/tables/featureFlags.ts b/src/db/tables/featureFlags.ts
index 24e461f5857..70c9b081050 100644
--- a/src/db/tables/featureFlags.ts
+++ b/src/db/tables/featureFlags.ts
@@ -93,7 +93,7 @@ export async function getFeatureFlagByName(name: string) {
*/
export async function addFeatureFlag(flag: FeatureFlag) {
logger.info("addFeatureFlag", flag);
- const featureFlagDb: FeatureFlagRow = {
+ const featureFlagDb: Omit = {
name: flag.name,
is_enabled: flag.isEnabled,
description: flag.description,
diff --git a/src/knex-tables.d.ts b/src/knex-tables.d.ts
index b5d58d3197c..e3f9c2d9c28 100644
--- a/src/knex-tables.d.ts
+++ b/src/knex-tables.d.ts
@@ -47,8 +47,8 @@ declare module "knex/types/tables" {
dependencies?: string[];
allow_list?: string[];
wait_list?: string[];
- added_at?: Date;
- modified_at?: Date;
+ created_at: Date;
+ modified_at: Date;
expired_at?: Date;
deleted_at?: Date;
owner?: string;
@@ -60,8 +60,6 @@ declare module "knex/types/tables" {
| "dependencies"
| "allow_list"
| "wait_list"
- | "added_at"
- | "modified_at"
| "expired_at"
| "owner"
>;
From 309ed8f39bce41b07e64ae665e7c8a9d2733cde8 Mon Sep 17 00:00:00 2001
From: Vincent
Date: Thu, 18 Jul 2024 10:01:47 +0200
Subject: [PATCH 126/137] Port breach alerts cronjob to TS
This job uses appConstants, and ESBuild bundles everything into a
single module. That means that resolving the .env files relative to
the dirname would fail for the cronjob. Thus, I reverted that back
to have dotenv-flow autodetect the .env file, and migrated the DB
script (for which the dirname-relative resolving was added) to use
process.env directly instead.
---
README.md | 7 +-
package.json | 3 +-
src/appConstants.js | 11 +-
src/db/knexfile.js | 11 +-
.../emailBreachAlerts.test.ts} | 106 +++++++++--------
.../emailBreachAlerts.ts} | 108 ++++++++++++++----
src/utils/hibp.js | 31 ++---
7 files changed, 180 insertions(+), 97 deletions(-)
rename src/scripts/{emailBreachAlerts.test.js => cronjobs/emailBreachAlerts.test.ts} (78%)
rename src/scripts/{emailBreachAlerts.js => cronjobs/emailBreachAlerts.ts} (73%)
diff --git a/README.md b/README.md
index efc5ec215e2..993c089e762 100644
--- a/README.md
+++ b/README.md
@@ -145,6 +145,8 @@ Monitor uses GCP PubSub for processing incoming breach data, this can be tested
gcloud beta emulators pubsub start --project=your-project-name
```
+(Set `your-project-name` as the value for `GCP_PUBSUB_PROJECT_ID` in your `.env.local`.)
+
### In a different shell, set the environment to point at the emulator and run Monitor in dev mode:
```sh
@@ -160,10 +162,13 @@ curl -d '{ "breachName": "000webhost", "hashPrefix": "test", "hashSuffixes": ["t
http://localhost:6060/api/v1/hibp/notify
```
+This emulates HIBP notifying our API that a new breach was found. Our API will
+then add it to the (emulated) pubsub queue.
+
### This pubsub queue will be consumed by this cron job, which is responsible for looking up and emailing impacted users:
```sh
-node src/scripts/emailBreachAlerts.js
+npm run dev:cron:breach-alerts
```
### Emails
diff --git a/package.json b/package.json
index a22fd69da0d..843ba663eaa 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"dev": "npm run build-nimbus && next dev --port=6060",
"dev:cron:first-data-broker-removal-fixed": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/firstDataBrokerRemovalFixed.tsx",
"dev:cron:monthly-activity": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/monthlyActivity.tsx",
+ "dev:cron:breach-alerts": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/emailBreachAlerts.ts",
"dev:cron:db-delete-unverified-subscribers": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/deleteUnverifiedSubscribers.ts",
"dev:cron:db-pull-breaches": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/syncBreaches.ts",
"dev:cron:remote-settings-pull-breaches": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/updateBreachesInRemoteSettings.ts",
@@ -27,7 +28,7 @@
"e2e:smoke": "playwright test src/e2e/ --grep @smoke",
"cron:first-data-broker-removal-fixed": "node dist/scripts/cronjobs/firstDataBrokerRemovalFixed.js",
"cron:monthly-activity": "node dist/scripts/cronjobs/monthlyActivity.js",
- "cron:breach-alerts": "node src/scripts/emailBreachAlerts.js",
+ "cron:breach-alerts": "node dist/scripts/cronjobs/emailBreachAlerts.js",
"cron:db-delete-unverified-subscribers": "node dist/scripts/cronjobs/deleteUnverifiedSubscribers.js",
"cron:db-pull-breaches": "node dist/scripts/cronjobs/syncBreaches.js",
"cron:remote-settings-pull-breaches": "node dist/scripts/cronjobs/updateBreachesInRemoteSettings.js",
diff --git a/src/appConstants.js b/src/appConstants.js
index 7dac001fd49..9069e2ec5b5 100644
--- a/src/appConstants.js
+++ b/src/appConstants.js
@@ -2,21 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-// TODO: these vars were copy/pasted from the old app-constants.js and should be cleaned up
-import path from "path";
-import url from "url";
-
if (typeof process.env.NEXT_RUNTIME === "undefined" && typeof process.env.STORYBOOK === "undefined") {
// Next.js already loads env vars by itself, and dotenv-flow will throw an
// error if loaded in that context (about `fs` not existing), so only load
// it if we're not running in a Next.js-context (e.g. cron jobs):
- const __filename = url.fileURLToPath(import.meta.url);
- const __dirname = path.dirname(__filename);
-
- const dotenvFlow = await import("dotenv-flow");
- dotenvFlow.config({ path: path.resolve(__dirname, "../") });
+ await import("dotenv-flow/config");
}
+// TODO: these vars were copy/pasted from the old app-constants.js and should be cleaned up
const requiredEnvVars = [
'ADMINS',
'APP_ENV',
diff --git a/src/db/knexfile.js b/src/db/knexfile.js
index 80e793c1362..d9118c7d6a8 100644
--- a/src/db/knexfile.js
+++ b/src/db/knexfile.js
@@ -6,7 +6,7 @@
// `pg-connection-string` works, triggering a false positive for this lint rule:
/* eslint-disable import/no-named-as-default-member */
import pgConnectionStr from "pg-connection-string";
-import AppConstants from "../appConstants.js";
+import "dotenv-flow/config";
/**
* @typedef {object} KnexConfig
@@ -14,9 +14,12 @@ import AppConstants from "../appConstants.js";
* @property {import("pg-connection-string").ConnectionOptions} connection
*/
-const { DATABASE_URL, APP_ENV, NODE_ENV, PG_HOST } = AppConstants;
+const DATABASE_URL = process.env.DATABASE_URL ?? "";
+const APP_ENV = process.env.APP_ENV ?? "production";
+/** @type {string} */
+const NODE_ENV = process.env.NODE_ENV ?? "production";
const connectionObj = pgConnectionStr.parse(DATABASE_URL);
-if (APP_ENV === "heroku") {
+if (typeof process.env.APP_ENV === "string" && process.env.APP_ENV === "heroku") {
// @ts-ignore TODO: Check if this typing error is correct, or if the types are wrong?
connectionObj.ssl = { rejectUnauthorized: false };
}
@@ -40,7 +43,7 @@ let exportConfig = NODE_ENV === "tests" ? TESTS_CONFIG : RUNTIME_CONFIG
if (APP_ENV === "cloudrun") {
// @ts-ignore TODO: Check if this typing error is correct, or if the types are wrong?
connectionObj.ssl = false;
- connectionObj.host = PG_HOST
+ connectionObj.host = /** @type {string} */ (process.env.PG_HOST)
exportConfig = {
client: "pg",
connection: connectionObj
diff --git a/src/scripts/emailBreachAlerts.test.js b/src/scripts/cronjobs/emailBreachAlerts.test.ts
similarity index 78%
rename from src/scripts/emailBreachAlerts.test.js
rename to src/scripts/cronjobs/emailBreachAlerts.test.ts
index 9766ae85617..839597a3e3b 100644
--- a/src/scripts/emailBreachAlerts.test.js
+++ b/src/scripts/cronjobs/emailBreachAlerts.test.ts
@@ -4,6 +4,9 @@
import { test, expect, jest } from "@jest/globals";
+process.env.GCP_PUBSUB_PROJECT_ID = "arbitrary-id";
+process.env.GCP_PUBSUB_SUBSCRIPTION_NAME = "arbitrary-name";
+
jest.mock("@sentry/nextjs", () => {
return {
init: jest.fn(),
@@ -11,7 +14,7 @@ jest.mock("@sentry/nextjs", () => {
};
});
-jest.mock("../utils/email.js", () => {
+jest.mock("../../utils/email.js", () => {
return {
initEmail: jest.fn(),
EmailTemplateType: jest.fn(),
@@ -20,7 +23,7 @@ jest.mock("../utils/email.js", () => {
};
});
-jest.mock("../utils/hibp.js", () => {
+jest.mock("../../utils/hibp.js", () => {
return {
getAddressesAndLanguageForEmail: jest.fn(() => {
return {
@@ -34,19 +37,19 @@ jest.mock("../utils/hibp.js", () => {
};
});
-jest.mock("../db/tables/subscribers.js", () => {
+jest.mock("../../db/tables/subscribers.js", () => {
return {
getSubscribersByHashes: jest.fn(() => [""]),
};
});
-jest.mock("../db/tables/emailAddresses.js", () => {
+jest.mock("../../db/tables/emailAddresses.js", () => {
return {
getEmailAddressesByHashes: jest.fn(() => [""]),
};
});
-jest.mock("../db/tables/email_notifications.js", () => {
+jest.mock("../../db/tables/email_notifications.js", () => {
return {
getNotifiedSubscribersForBreach: jest.fn(() => [""]),
addEmailNotification: jest.fn(),
@@ -54,7 +57,7 @@ jest.mock("../db/tables/email_notifications.js", () => {
};
});
-jest.mock("../utils/fluent.js", () => {
+jest.mock("../../utils/fluent.js", () => {
return {
initFluentBundles: jest.fn(),
getMessage: jest.fn(),
@@ -62,24 +65,24 @@ jest.mock("../utils/fluent.js", () => {
};
});
-jest.mock("../emails/email2022.js", () => {
+jest.mock("../../emails/email2022.js", () => {
return {
getTemplate: jest.fn(),
};
});
-jest.mock("../emails/emailBreachAlert.js", () => {
+jest.mock("../../emails/emailBreachAlert.js", () => {
return {
breachAlertEmailPartial: jest.fn(),
};
});
-const subClient = {
+const subClient: any = {
subscriptionPath: jest.fn(),
acknowledge: jest.fn(),
};
-function buildReceivedMessages(testBreachAlert) {
+function buildReceivedMessages(testBreachAlert: any) {
return [
{
ackId: "testAckId",
@@ -101,12 +104,14 @@ beforeEach(() => {
});
test("rejects invalid messages", async () => {
- const { poll } = await import("./emailBreachAlerts.js");
+ const { poll } = await import("./emailBreachAlerts");
const consoleError = jest
.spyOn(console, "error")
.mockImplementation(() => {});
- const consoleLog = jest.spyOn(console, "log").mockImplementation();
+ const consoleLog = jest
+ .spyOn(console, "log")
+ .mockImplementation(() => undefined);
await poll(
subClient,
@@ -174,14 +179,19 @@ test("rejects invalid messages", async () => {
});
test("processes valid messages", async () => {
- const consoleLog = jest.spyOn(console, "log").mockImplementation();
+ const consoleLog = jest
+ .spyOn(console, "log")
+ .mockImplementation(() => undefined);
// It's not clear if the calls to console.info are important enough to remain,
// but since they were already there when adding the "no logs" rule in tests,
// I'm respecting Chesterton's Fence and leaving them in place for now:
- jest.spyOn(console, "info").mockImplementation();
- const { sendEmail } = await import("../utils/email.js");
+ jest.spyOn(console, "info").mockImplementation(() => undefined);
+ const emailMod = await import("../../utils/email.js");
+ const sendEmail = emailMod.sendEmail as jest.Mock<
+ (typeof emailMod)["sendEmail"]
+ >;
- const mockedUtilsHibp = jest.requireMock("../utils/hibp.js");
+ const mockedUtilsHibp: any = jest.requireMock("../../utils/hibp.js");
mockedUtilsHibp.getBreachByName.mockReturnValue({
IsVerified: true,
Domain: "test1",
@@ -195,7 +205,7 @@ test("processes valid messages", async () => {
hashSuffixes: ["test-suffix1"],
});
- const { poll } = await import("./emailBreachAlerts.js");
+ const { poll } = await import("./emailBreachAlerts");
await poll(subClient, receivedMessages);
// Fabricated but valid breach is acknowledged.
@@ -265,13 +275,15 @@ test("processes valid messages", async () => {
});
test("skipping email when subscriber id exists in email_notifications table", async () => {
- const consoleLog = jest.spyOn(console, "log").mockImplementation();
+ const consoleLog = jest
+ .spyOn(console, "log")
+ .mockImplementation(() => undefined);
// It's not clear if the calls to console.info are important enough to remain,
// but since they were already there when adding the "no logs" rule in tests,
// I'm respecting Chesterton's Fence and leaving them in place for now:
- jest.spyOn(console, "info").mockImplementation();
- const { sendEmail } = await import("../utils/email.js");
- const mockedUtilsHibp = jest.requireMock("../utils/hibp.js");
+ jest.spyOn(console, "info").mockImplementation(() => undefined);
+ const { sendEmail } = await import("../../utils/email.js");
+ const mockedUtilsHibp: any = jest.requireMock("../../utils/hibp.js");
mockedUtilsHibp.getBreachByName.mockReturnValue({
IsVerified: true,
Domain: "test1",
@@ -280,19 +292,19 @@ test("skipping email when subscriber id exists in email_notifications table", as
Id: 1,
});
- jest.mock("../db/tables/subscribers.js", () => {
+ jest.mock("../../db/tables/subscribers.js", () => {
return {
getSubscribersByHashes: jest.fn(() => [{ id: 1 }]),
};
});
- jest.mock("../db/tables/emailAddresses.js", () => {
+ jest.mock("../../db/tables/emailAddresses.js", () => {
return {
getEmailAddressesByHashes: jest.fn(() => []),
};
});
- jest.mock("../db/tables/email_notifications.js", () => {
+ jest.mock("../../db/tables/email_notifications.js", () => {
return {
getNotifiedSubscribersForBreach: jest.fn(() => [1]),
addEmailNotification: jest.fn(),
@@ -305,7 +317,7 @@ test("skipping email when subscriber id exists in email_notifications table", as
hashSuffixes: ["test-suffix1"],
});
- const { poll } = await import("./emailBreachAlerts.js");
+ const { poll } = await import("./emailBreachAlerts");
await poll(subClient, receivedMessages);
// Verified, not fabricated, not spam list breaches are acknowledged.
@@ -318,13 +330,15 @@ test("skipping email when subscriber id exists in email_notifications table", as
});
test("throws an error when addEmailNotification fails", async () => {
- const consoleLog = jest.spyOn(console, "log").mockImplementation();
+ const consoleLog = jest
+ .spyOn(console, "log")
+ .mockImplementation(() => undefined);
// It's not clear if the calls to console.info are important enough to remain,
// but since they were already there when adding the "no logs" rule in tests,
// I'm respecting Chesterton's Fence and leaving them in place for now:
- jest.spyOn(console, "info").mockImplementation();
- const { sendEmail } = await import("../utils/email.js");
- const mockedUtilsHibp = jest.requireMock("../utils/hibp.js");
+ jest.spyOn(console, "info").mockImplementation(() => undefined);
+ const { sendEmail } = await import("../../utils/email.js");
+ const mockedUtilsHibp: any = jest.requireMock("../../utils/hibp.js");
mockedUtilsHibp.getBreachByName.mockReturnValue({
IsVerified: true,
Domain: "test1",
@@ -333,19 +347,19 @@ test("throws an error when addEmailNotification fails", async () => {
Id: 1,
});
- jest.mock("../db/tables/subscribers.js", () => {
+ jest.mock("../../db/tables/subscribers.js", () => {
return {
getSubscribersByHashes: jest.fn(() => [{ id: 1 }]),
};
});
- jest.mock("../db/tables/emailAddresses.js", () => {
+ jest.mock("../../db/tables/emailAddresses.js", () => {
return {
getEmailAddressesByHashes: jest.fn(() => [""]),
};
});
- jest.mock("../db/tables/email_notifications.js", () => {
+ jest.mock("../../db/tables/email_notifications.js", () => {
return {
getNotifiedSubscribersForBreach: jest.fn(() => [2]),
addEmailNotification: jest.fn().mockImplementationOnce(() => {
@@ -359,13 +373,13 @@ test("throws an error when addEmailNotification fails", async () => {
hashSuffixes: ["test-suffix1"],
});
- const { poll } = await import("./emailBreachAlerts.js");
+ const { poll } = await import("./emailBreachAlerts");
try {
await poll(subClient, receivedMessages);
- } catch (e) {
+ } catch (e: unknown) {
expect(console.error).toBeCalled();
- expect(e.message).toBe("add failed");
+ expect((e as Error).message).toBe("add failed");
}
expect(consoleLog).toHaveBeenCalledWith(
@@ -375,13 +389,15 @@ test("throws an error when addEmailNotification fails", async () => {
});
test("throws an error when markEmailAsNotified fails", async () => {
- const consoleLog = jest.spyOn(console, "log").mockImplementation();
+ const consoleLog = jest
+ .spyOn(console, "log")
+ .mockImplementation(() => undefined);
// It's not clear if the calls to console.info are important enough to remain,
// but since they were already there when adding the "no logs" rule in tests,
// I'm respecting Chesterton's Fence and leaving them in place for now:
- jest.spyOn(console, "info").mockImplementation();
- const { sendEmail } = await import("../utils/email.js");
- const mockedUtilsHibp = jest.requireMock("../utils/hibp.js");
+ jest.spyOn(console, "info").mockImplementation(() => undefined);
+ const { sendEmail } = await import("../../utils/email.js");
+ const mockedUtilsHibp: any = jest.requireMock("../../utils/hibp.js");
mockedUtilsHibp.getBreachByName.mockReturnValue({
IsVerified: true,
Domain: "test1",
@@ -390,19 +406,19 @@ test("throws an error when markEmailAsNotified fails", async () => {
Id: 1,
});
- jest.mock("../db/tables/subscribers.js", () => {
+ jest.mock("../../db/tables/subscribers.js", () => {
return {
getSubscribersByHashes: jest.fn(() => [{ id: 1 }]),
};
});
- jest.mock("../db/tables/emailAddresses.js", () => {
+ jest.mock("../../db/tables/emailAddresses.js", () => {
return {
getEmailAddressesByHashes: jest.fn(() => [""]),
};
});
- jest.mock("../db/tables/email_notifications.js", () => {
+ jest.mock("../../db/tables/email_notifications.js", () => {
return {
getNotifiedSubscribersForBreach: jest.fn(() => [2]),
addEmailNotification: jest.fn(),
@@ -417,13 +433,13 @@ test("throws an error when markEmailAsNotified fails", async () => {
hashSuffixes: ["test-suffix1"],
});
- const { poll } = await import("./emailBreachAlerts.js");
+ const { poll } = await import("./emailBreachAlerts");
try {
await poll(subClient, receivedMessages);
- } catch (e) {
+ } catch (e: unknown) {
expect(console.error).toBeCalled();
- expect(e.message).toBe("mark failed");
+ expect((e as Error).message).toBe("mark failed");
}
expect(consoleLog).toHaveBeenCalledWith(
'Received message: {"breachName":"test1","hashPrefix":"test-prefix1","hashSuffixes":["test-suffix1"]}',
diff --git a/src/scripts/emailBreachAlerts.js b/src/scripts/cronjobs/emailBreachAlerts.ts
similarity index 73%
rename from src/scripts/emailBreachAlerts.js
rename to src/scripts/cronjobs/emailBreachAlerts.ts
index d4c333abf11..d58a72a60d9 100644
--- a/src/scripts/emailBreachAlerts.js
+++ b/src/scripts/cronjobs/emailBreachAlerts.ts
@@ -4,40 +4,42 @@
import Sentry from "@sentry/nextjs";
import { acceptedLanguages, negotiateLanguages } from "@fluent/langneg";
-import { localStorage } from "../utils/localStorage.js";
+import { localStorage } from "../../utils/localStorage.js";
import * as pubsub from "@google-cloud/pubsub";
import * as grpc from "@grpc/grpc-js";
+import type { SubscriberClient } from "@google-cloud/pubsub/build/src/v1/subscriber_client.js";
+import type { EmailAddressRow, SubscriberRow } from "knex/types/tables";
import {
getSubscribersByHashes,
knexSubscribers,
-} from "../db/tables/subscribers.js";
+} from "../../db/tables/subscribers.js";
import {
getEmailAddressesByHashes,
knexEmailAddresses,
-} from "../db/tables/emailAddresses.js";
+} from "../../db/tables/emailAddresses.js";
import {
getNotifiedSubscribersForBreach,
addEmailNotification,
markEmailAsNotified,
-} from "../db/tables/email_notifications.js";
-import { getTemplate } from "../emails/email2022.js";
-import { breachAlertEmailPartial } from "../emails/emailBreachAlert.js";
+} from "../../db/tables/email_notifications.js";
+import { getTemplate } from "../../emails/email2022.js";
+import { breachAlertEmailPartial } from "../../emails/emailBreachAlert.js";
import {
initEmail,
EmailTemplateType,
getEmailCtaDashboardHref,
sendEmail,
-} from "../utils/email.js";
+} from "../../utils/email.js";
-import { initFluentBundles, getMessage } from "../utils/fluent.js";
+import { initFluentBundles, getMessage } from "../../utils/fluent.js";
import {
getAddressesAndLanguageForEmail,
getBreachByName,
getAllBreachesFromDb,
knexHibp,
-} from "../utils/hibp.js";
+} from "../../utils/hibp.js";
const SENTRY_SLUG = "cron-breach-alerts";
@@ -55,7 +57,8 @@ const checkInId = Sentry.captureCheckIn({
// Only process this many messages before exiting.
/* c8 ignore start */
const maxMessages = parseInt(
- process.env.EMAIL_BREACH_ALERT_MAX_MESSAGES || 10000,
+ process.env.EMAIL_BREACH_ALERT_MAX_MESSAGES ?? "10000",
+ 10,
);
/* c8 ignore stop */
const projectId = process.env.GCP_PUBSUB_PROJECT_ID;
@@ -71,7 +74,28 @@ const subscriptionName = process.env.GCP_PUBSUB_SUBSCRIPTION_NAME;
*
* More about how account identities are anonymized: https://blog.mozilla.org/security/2018/06/25/scanning-breached-accounts-k-anonymity/
*/
-export async function poll(subClient, receivedMessages) {
+export async function poll(
+ subClient: SubscriberClient,
+ receivedMessages: Array<{
+ ackId?: string | null;
+ deliveryAttempt?: number | null;
+ message?: {
+ messageId?: string | null;
+ orderingKey?: string | undefined | null;
+ data?: string | Uint8Array | null;
+ } | null;
+ }>,
+) {
+ // These env vars are always set in tests:
+ /* c8 ignore next 8 */
+ if (!projectId) {
+ throw new Error("Environment variable [$GCP_PUBSUB_PROJECT_ID] not set.");
+ }
+ if (!subscriptionName) {
+ throw new Error(
+ "Environment variable [$GCP_PUBSUB_SUBSCRIPTION_NAME] not set.",
+ );
+ }
const formattedSubscription = subClient.subscriptionPath(
projectId,
subscriptionName,
@@ -81,8 +105,12 @@ export async function poll(subClient, receivedMessages) {
// Process the messages. Skip any that cannot be processed, and do not mark as acknowledged.
for (const message of receivedMessages) {
- console.log(`Received message: ${message.message.data}`);
- const data = JSON.parse(message.message.data);
+ console.log(`Received message: ${message.message?.data}`);
+ const data = JSON.parse(message.message?.data as string) as {
+ breachName: string;
+ hashPrefix: string;
+ hashSuffixes: string[];
+ };
if (!(data.breachName && data.hashPrefix && data.hashSuffixes)) {
console.error(
@@ -143,7 +171,14 @@ export async function poll(subClient, receivedMessages) {
subClient.acknowledge({
subscription: formattedSubscription,
- ackIds: [message.ackId],
+ ackIds:
+ typeof message.ackId === "string"
+ ? [message.ackId]
+ : /* c8 ignore next 4 */
+ // When porting this code to TypeScript, the undefined/null case
+ // wasn't dealt with, so presumably our messages always have an
+ // ackId:
+ message.ackId,
});
continue;
@@ -157,7 +192,9 @@ export async function poll(subClient, receivedMessages) {
const subscribers = await getSubscribersByHashes(hashes);
const emailAddresses = await getEmailAddressesByHashes(hashes);
- const recipients = subscribers.concat(emailAddresses);
+ const recipients: Array<
+ SubscriberRow | (SubscriberRow & EmailAddressRow)
+ > = subscribers.concat(emailAddresses);
console.info(EmailTemplateType.Notification, {
breachAlertName: breachAlert.Name,
@@ -165,7 +202,7 @@ export async function poll(subClient, receivedMessages) {
});
const utmCampaignId = "breach-alert";
- const notifiedRecipients = [];
+ const notifiedRecipients: string[] = [];
for (const recipient of recipients) {
console.info("notify", { recipient });
@@ -175,7 +212,11 @@ export async function poll(subClient, receivedMessages) {
// Get subscriber ID from:
// - `subscriber_id`: if `email_addresses` record
// - `id`: if `subscribers` record
- const subscriberId = recipient.subscriber_id ?? recipient.id;
+ /* c8 ignore next 4 */
+ // TODO: Add unit test when changing this code:
+ const subscriberId = hasEmailAddressAttached(recipient)
+ ? recipient.subscriber_id
+ : recipient.id;
if (notifiedSubs.includes(subscriberId)) {
console.info("Subscriber already notified, skipping: ", subscriberId);
continue;
@@ -189,7 +230,7 @@ export async function poll(subClient, receivedMessages) {
: [];
/* c8 ignore stop */
- const availableLanguages = process.env.SUPPORTED_LOCALES.split(",");
+ const availableLanguages = process.env.SUPPORTED_LOCALES!.split(",");
const supportedLocales = negotiateLanguages(
requestedLanguage,
availableLanguages,
@@ -246,7 +287,7 @@ export async function poll(subClient, receivedMessages) {
breachId,
data.recipientEmail,
);
- } catch (e) {
+ } catch (e: any) {
console.error("Failed to mark email as notified: ", e);
throw new Error(e);
}
@@ -260,7 +301,14 @@ export async function poll(subClient, receivedMessages) {
subClient.acknowledge({
subscription: formattedSubscription,
- ackIds: [message.ackId],
+ ackIds:
+ typeof message.ackId === "string"
+ ? [message.ackId]
+ : /* c8 ignore next 4 */
+ // When porting this code to TypeScript, the undefined/null case
+ // wasn't dealt with, so presumably our messages always have an
+ // ackId:
+ message.ackId,
});
/* c8 ignore start */
} catch (error) {
@@ -281,6 +329,16 @@ async function pullMessages() {
sslCreds: grpc.credentials.createInsecure(),
};
}
+ // These env vars are always set in tests:
+ /* c8 ignore next 8 */
+ if (!projectId) {
+ throw new Error("Environment variable [$GCP_PUBSUB_PROJECT_ID] not set.");
+ }
+ if (!subscriptionName) {
+ throw new Error(
+ "Environment variable [$GCP_PUBSUB_SUBSCRIPTION_NAME] not set.",
+ );
+ }
const subClient = new pubsub.v1.SubscriberClient(options);
@@ -297,14 +355,14 @@ async function pullMessages() {
maxMessages,
});
- return [subClient, response.receivedMessages];
+ return [subClient, response.receivedMessages] as const;
}
async function init() {
await initFluentBundles();
await initEmail();
const [subClient, receivedMessages] = await pullMessages();
- await poll(subClient, receivedMessages);
+ await poll(subClient, receivedMessages ?? []);
}
if (process.env.NODE_ENV !== "test") {
@@ -331,3 +389,9 @@ if (process.env.NODE_ENV !== "test") {
});
}
/* c8 ignore stop */
+
+function hasEmailAddressAttached(
+ row: SubscriberRow | (SubscriberRow & EmailAddressRow),
+): row is SubscriberRow & EmailAddressRow {
+ return typeof (row as EmailAddressRow).subscriber_id !== "undefined";
+}
diff --git a/src/utils/hibp.js b/src/utils/hibp.js
index 4f7b7ce461e..a79a4d3de22 100644
--- a/src/utils/hibp.js
+++ b/src/utils/hibp.js
@@ -229,31 +229,24 @@ async function loadBreachesIntoApp(app) {
/**
* Get addresses and language from either subscribers or email_addresses fields:
*
- * @param {*} recipient
+ * @param {import('knex/types/tables').SubscriberRow | (import('knex/types/tables').SubscriberRow & import('knex/types/tables').EmailAddressRow)} recipient
* @returns
*/
// TODO: Add unit test when changing this code:
/* c8 ignore start */
function getAddressesAndLanguageForEmail(recipient) {
- const {
- all_emails_to_primary: allEmailsToPrimary,
- email: breachedEmail,
- primary_email: primaryEmail,
- signup_language: signupLanguage
- } = recipient
-
- if (breachedEmail) {
+ if (hasEmailAddressAttached(recipient)) {
return {
- breachedEmail,
- recipientEmail: allEmailsToPrimary ? primaryEmail : breachedEmail,
- signupLanguage
+ breachedEmail: recipient.email,
+ recipientEmail: recipient.all_emails_to_primary ? recipient.primary_email : recipient.email,
+ signupLanguage: recipient.signup_language,
}
}
return {
- breachedEmail: primaryEmail,
- recipientEmail: primaryEmail,
- signupLanguage
+ breachedEmail: recipient.primary_email,
+ recipientEmail: recipient.primary_email,
+ signupLanguage: recipient.signup_language,
}
}
/* c8 ignore stop */
@@ -407,6 +400,14 @@ async function deleteSubscribedHash(sha1) {
}
/* c8 ignore stop */
+/**
+ * @param {import('knex/types/tables').SubscriberRow} subscriberRow
+ * @returns {subscriberRow is import('knex/types/tables').SubscriberRow & import('knex/types/tables').EmailAddressRow}
+ */
+function hasEmailAddressAttached(subscriberRow) {
+ return typeof (/** @type {import('knex/types/tables').SubscriberRow & import('knex/types/tables').EmailAddressRow} */ (subscriberRow)).email === "string";
+}
+
export {
req,
kAnonReq,
From 946e41705db124b2ab33f5d96bdda46cf39a881e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 22 Jul 2024 10:15:32 -0400
Subject: [PATCH 127/137] chore(deps): bump actions/checkout from 2 to 4
(#4840)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v4)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Kaitlyn Andres
---
.github/workflows/production_deploy.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/production_deploy.yml b/.github/workflows/production_deploy.yml
index fe87ef491c5..093a3ba512d 100644
--- a/.github/workflows/production_deploy.yml
+++ b/.github/workflows/production_deploy.yml
@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
From 3d29d1de50acc06b4ccd56a45bc69429cb45e299 Mon Sep 17 00:00:00 2001
From: Florian Zia
Date: Mon, 22 Jul 2024 16:36:51 +0200
Subject: [PATCH 128/137] chore: Add react-intersection-observer as dependency
---
package-lock.json | 10 +++++-----
package.json | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 93df26589f2..827d63181e5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,6 +44,7 @@
"react-aria": "^3.33.1",
"react-cookie": "^7.1.0",
"react-dom": "^18.2.0",
+ "react-intersection-observer": "^9.13.0",
"react-stately": "^3.31.1",
"server-only": "^0.0.1",
"uuid": "^9.0.1",
@@ -94,7 +95,6 @@
"lint-staged": "^15.2.5",
"mjml-browser": "^4.15.3",
"prettier": "3.3.2",
- "react-intersection-observer": "^9.10.3",
"sass": "^1.77.6",
"storybook": "^8.1.11",
"stylelint": "^16.7.0",
@@ -24240,10 +24240,10 @@
"dev": true
},
"node_modules/react-intersection-observer": {
- "version": "9.10.3",
- "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.10.3.tgz",
- "integrity": "sha512-9NYfKwPZRovB6QJee7fDg0zz/SyYrqXtn5xTZU0vwLtLVBtfu9aZt1pVmr825REE49VPDZ7Lm5SNHjJBOTZHpA==",
- "dev": true,
+ "version": "9.13.0",
+ "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.13.0.tgz",
+ "integrity": "sha512-y0UvBfjDiXqC8h0EWccyaj4dVBWMxgEx0t5RGNzQsvkfvZwugnKwxpu70StY4ivzYuMajavwUDjH4LJyIki9Lw==",
+ "license": "MIT",
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
diff --git a/package.json b/package.json
index d24420e07e9..03779eb5d35 100644
--- a/package.json
+++ b/package.json
@@ -95,6 +95,7 @@
"react-aria": "^3.33.1",
"react-cookie": "^7.1.0",
"react-dom": "^18.2.0",
+ "react-intersection-observer": "^9.13.0",
"react-stately": "^3.31.1",
"server-only": "^0.0.1",
"uuid": "^9.0.1",
@@ -145,7 +146,6 @@
"lint-staged": "^15.2.5",
"mjml-browser": "^4.15.3",
"prettier": "3.3.2",
- "react-intersection-observer": "^9.10.3",
"sass": "^1.77.6",
"storybook": "^8.1.11",
"stylelint": "^16.7.0",
From c247fcc23b366c2882661bb81f993324140a64e2 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 22 Jul 2024 13:56:12 +0000
Subject: [PATCH 129/137] chore(deps-dev): bump the storybook group with 9
updates
Bumps the storybook group with 9 updates:
| Package | From | To |
| --- | --- | --- |
| [@storybook/addon-a11y](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y) | `8.2.2` | `8.2.5` |
| [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/actions) | `8.2.2` | `8.2.5` |
| [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/essentials) | `8.2.2` | `8.2.5` |
| [@storybook/addon-interactions](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/interactions) | `8.2.2` | `8.2.5` |
| [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links) | `8.2.2` | `8.2.5` |
| [@storybook/blocks](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/blocks) | `8.2.2` | `8.2.5` |
| [@storybook/nextjs](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/nextjs) | `8.2.2` | `8.2.5` |
| [@storybook/react](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/react) | `8.2.2` | `8.2.5` |
| [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/cli) | `8.2.2` | `8.2.5` |
Updates `@storybook/addon-a11y` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/addons/a11y)
Updates `@storybook/addon-actions` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/addons/actions)
Updates `@storybook/addon-essentials` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/addons/essentials)
Updates `@storybook/addon-interactions` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/addons/interactions)
Updates `@storybook/addon-links` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/addons/links)
Updates `@storybook/blocks` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/lib/blocks)
Updates `@storybook/nextjs` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/frameworks/nextjs)
Updates `@storybook/react` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/renderers/react)
Updates `storybook` from 8.2.2 to 8.2.5
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.2.5/code/lib/cli)
---
updated-dependencies:
- dependency-name: "@storybook/addon-a11y"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: "@storybook/addon-actions"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: "@storybook/addon-essentials"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: "@storybook/addon-interactions"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: "@storybook/addon-links"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: "@storybook/blocks"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: "@storybook/nextjs"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: "@storybook/react"
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
- dependency-name: storybook
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: storybook
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 434 ++++++++++++++++++++++++++--------------------
package.json | 12 +-
2 files changed, 251 insertions(+), 195 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9f3780954f6..af1104b0a9a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -52,13 +52,13 @@
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@playwright/test": "^1.43.1",
- "@storybook/addon-a11y": "^8.2.2",
- "@storybook/addon-actions": "^8.2.2",
- "@storybook/addon-essentials": "^8.2.2",
- "@storybook/addon-interactions": "^8.2.2",
- "@storybook/addon-links": "^8.2.2",
+ "@storybook/addon-a11y": "^8.2.5",
+ "@storybook/addon-actions": "^8.2.5",
+ "@storybook/addon-essentials": "^8.2.5",
+ "@storybook/addon-interactions": "^8.2.5",
+ "@storybook/addon-links": "^8.2.5",
"@storybook/blocks": "^8.0.0",
- "@storybook/nextjs": "^8.2.2",
+ "@storybook/nextjs": "^8.2.5",
"@storybook/react": "^8.0.0",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
@@ -8874,12 +8874,12 @@
}
},
"node_modules/@storybook/addon-a11y": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-8.2.2.tgz",
- "integrity": "sha512-wW7aU0L+TCi+mTxvS6zmfVVe81vLcjBVNbhjzFHdWVwYej8rguwVpKXo2/UhQyXb38xe6qYICB5HAJyUYOO5Hg==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-8.2.5.tgz",
+ "integrity": "sha512-sQxX/6mVSF15JnB/HEPrfY43Z6SvgyzAQYfMvqWS+sQBK04busLJBWElQRgekZo80sDCq52mq98lm+ZgpZs42A==",
"dev": true,
"dependencies": {
- "@storybook/addon-highlight": "8.2.2",
+ "@storybook/addon-highlight": "8.2.5",
"axe-core": "^4.2.0"
},
"funding": {
@@ -8887,13 +8887,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-actions": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.2.2.tgz",
- "integrity": "sha512-SN4cSRt3f0qXi5te+yhMseSdQuZntA8lGlASbRmN77YQTpIaGsNiH88xFoky0s9qz531hiRfU1R0ZSMylBwSKw==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.2.5.tgz",
+ "integrity": "sha512-8kevyvbvEdo0qn+hL/ub/RVsCGlWvCgL6ZAsZm50aWl1GXPpXj3nggKnyJwgAGUQzDC0CDPlNpSOP4ri3NY8tw==",
"dev": true,
"dependencies": {
"@storybook/global": "^5.0.0",
@@ -8907,13 +8907,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-backgrounds": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.2.2.tgz",
- "integrity": "sha512-m/xJe7uKL+kfJx7pQcHwAeIvJ3tdLIpDGrMAVDNDJHcAxfe44cFjIInaV/1HKf3y5Awap+DZFW66ekkxuI9zzA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.2.5.tgz",
+ "integrity": "sha512-FZowGG+58qWHePjE6tGTTjT+m4/ZTI1uZD7GA++phdi5m8V/LGwJl8zBNZqUha/ygJ0i3Yvnj4tclWDSa8wtnQ==",
"dev": true,
"dependencies": {
"@storybook/global": "^5.0.0",
@@ -8925,13 +8925,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-controls": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.2.2.tgz",
- "integrity": "sha512-y241aOANGzT5XBADUIvALwG/xF5eC6UItzmWJaFvOzSBCq74GIA0+Hu9atyFdvFQbXOrdvPWC4jR+9iuBFRxAA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.2.5.tgz",
+ "integrity": "sha512-8IoeEmiOyg5aTIyW4gdUUV/xJZk8y5bACkNhDTIepyfTZLoVNsVXS1tjqrG4EXQR6dNY4XV9dDIUIRI11/K6tQ==",
"dev": true,
"dependencies": {
"dequal": "^2.0.2",
@@ -8943,21 +8943,21 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-docs": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.2.2.tgz",
- "integrity": "sha512-qk/yjAR9RpsSrKLLbeCgb6u58c8TmYqyJSnXgbAozZZNKHBWlIpvZ/hTNYud8qo0coPlxnLdjnZf32TykWGlAg==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.2.5.tgz",
+ "integrity": "sha512-fJ2Aam6rQO5BVRIDrA4gVxxnVmMCkk4wC6RDi8oSTOcjM0FRl3ktv+6gPbNWq/+b8dqU23Y4wSyM4UUAIP0PAA==",
"dev": true,
"dependencies": {
"@babel/core": "^7.24.4",
"@mdx-js/react": "^3.0.0",
- "@storybook/blocks": "8.2.2",
- "@storybook/csf-plugin": "8.2.2",
+ "@storybook/blocks": "8.2.5",
+ "@storybook/csf-plugin": "8.2.5",
"@storybook/global": "^5.0.0",
- "@storybook/react-dom-shim": "8.2.2",
+ "@storybook/react-dom-shim": "8.2.5",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"fs-extra": "^11.1.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
@@ -8971,24 +8971,24 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-essentials": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.2.2.tgz",
- "integrity": "sha512-yN//BFMbSvNV0+Sll2hcKmgJX06TUKQDm6pZimUjkXczFtOmK7K/UdDmKjWS+qjhfJdWpxdRoEpxoHvvRmNfsA==",
- "dev": true,
- "dependencies": {
- "@storybook/addon-actions": "8.2.2",
- "@storybook/addon-backgrounds": "8.2.2",
- "@storybook/addon-controls": "8.2.2",
- "@storybook/addon-docs": "8.2.2",
- "@storybook/addon-highlight": "8.2.2",
- "@storybook/addon-measure": "8.2.2",
- "@storybook/addon-outline": "8.2.2",
- "@storybook/addon-toolbars": "8.2.2",
- "@storybook/addon-viewport": "8.2.2",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.2.5.tgz",
+ "integrity": "sha512-SmA4QOiI9/d9bycagStm1gtlt2iR1EpWXJnhct4oqcj5nxmp+jviyhv1Pb+Rm/zKNE5qcaI4AcRDRVTJRUwESw==",
+ "dev": true,
+ "dependencies": {
+ "@storybook/addon-actions": "8.2.5",
+ "@storybook/addon-backgrounds": "8.2.5",
+ "@storybook/addon-controls": "8.2.5",
+ "@storybook/addon-docs": "8.2.5",
+ "@storybook/addon-highlight": "8.2.5",
+ "@storybook/addon-measure": "8.2.5",
+ "@storybook/addon-outline": "8.2.5",
+ "@storybook/addon-toolbars": "8.2.5",
+ "@storybook/addon-viewport": "8.2.5",
"ts-dedent": "^2.0.0"
},
"funding": {
@@ -8996,13 +8996,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-highlight": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.2.2.tgz",
- "integrity": "sha512-yDTRzzL+IJAymgY32xoZl09BGBVmPOUV2wVNGYcZkkBLvz2GSQMTfUe1/7F4jAx//+rFBu48/MQzsTC7Bk8kPw==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.2.5.tgz",
+ "integrity": "sha512-fgzmilW3jGD68xYiR8sRjOB+joETc6/2+Fmj4S85BNnKy2ViXc1D+LHIw1id5/oT9MNN1i62D517EXRZkPakGw==",
"dev": true,
"dependencies": {
"@storybook/global": "^5.0.0"
@@ -9012,18 +9012,18 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-interactions": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.2.2.tgz",
- "integrity": "sha512-zRRuUwm/l41JtTUgjIoQTUgLT99Hsdz9cqKca/8NYo1MGBdEcKE41DH4aBIzKaOKFu7p9q00/o/X1EqYX4LMUA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.2.5.tgz",
+ "integrity": "sha512-YVdpU/VRrRvX3BUiYxno6jDttbbQxngOkgcY8u+LLXbo3LfFLeXwpUmJXvGOrIU1wDHsZ4FAPBS/beFntcFhBw==",
"dev": true,
"dependencies": {
"@storybook/global": "^5.0.0",
- "@storybook/instrumenter": "8.2.2",
- "@storybook/test": "8.2.2",
+ "@storybook/instrumenter": "8.2.5",
+ "@storybook/test": "8.2.5",
"polished": "^4.2.2",
"ts-dedent": "^2.2.0"
},
@@ -9032,13 +9032,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-links": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.2.2.tgz",
- "integrity": "sha512-eGh7O7SgTJMtnuXC0HlRPOegu1njcJS2cnVqjbzjvjxsPSBhbHpdYMi9Q9E7al/FKuqMUOjIR9YLIlmK1AJaqA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.2.5.tgz",
+ "integrity": "sha512-jcD1/KXSqEE/QkQtBx3beD7UQJ3NQLEqYjCiF6UzsdFzcbfgAlfL5fKv8Lh/g8VynPcQzpfhMnSkj445EmF9hQ==",
"dev": true,
"dependencies": {
"@storybook/csf": "0.1.11",
@@ -9051,7 +9051,7 @@
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
},
"peerDependenciesMeta": {
"react": {
@@ -9060,9 +9060,9 @@
}
},
"node_modules/@storybook/addon-measure": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.2.2.tgz",
- "integrity": "sha512-3rCo/aMltt5FrBVdr2dYlD8HlE2q9TLKGJZnwh9on4QyL6ArHbdYw0LmyHe/LrFahJ49w1XQZBMSJcAdRkkS7w==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.2.5.tgz",
+ "integrity": "sha512-rC/kukXM+3Sd1U5Wboozs82p3rLaHBRCmQfk3bFhWyGKvbYWEWmSr7w0DLH8/X7pi1u8IMSqeRll7tDJrEXeaw==",
"dev": true,
"dependencies": {
"@storybook/global": "^5.0.0",
@@ -9073,13 +9073,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-outline": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.2.2.tgz",
- "integrity": "sha512-Y+PQtfTNO8GLX5nz+3x5AMfHNvdGvBXazJ29+Rl1ygYN1+Q9ZhRJDE1kAK0wLxb7CG14peAgdYEaQb3Rduv7HQ==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.2.5.tgz",
+ "integrity": "sha512-YRS60tyZH79FfH9NEOndGVG/AmlXdYMd3nT2XfMBPZ+uTay/hcUzp6/wVsL+ucyVXi0avHbyNjY+iFP6m/MhRw==",
"dev": true,
"dependencies": {
"@storybook/global": "^5.0.0",
@@ -9090,26 +9090,26 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-toolbars": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.2.2.tgz",
- "integrity": "sha512-JGOueOc3EPljlCl9dVSQee0aMYoqGNvN0UH+R6wYJ3bDZ+tUG/iYpsZVPUOvS8vzp3Imk5Is1kzQbQYJtzdGLg==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.2.5.tgz",
+ "integrity": "sha512-XqjJxpXjTKurL81QF+Xa69J/8TSstXvLWVqeX+132C0//Yq3VeUir87hvI2qw/qbQT9sGeRX72vqKhoxS+kvIQ==",
"dev": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/addon-viewport": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.2.2.tgz",
- "integrity": "sha512-gkZ8bsjGGP0NuevkT2iKC+szezSy+w4BrBDknf490mRU2K/B2e7TGojf/j/AtxzILMzD4IKzKUXbE/zwcqjZvA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.2.5.tgz",
+ "integrity": "sha512-QH2A+rzoMf8dcREOUpAsx1vvP7w3MQ8HbZCawk7KdkW/KS0L8zhkHfsNL9cfLcgCJA0wtOmRPD25ZVGoxUAHSA==",
"dev": true,
"dependencies": {
"memoizerific": "^1.11.3"
@@ -9119,13 +9119,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/blocks": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.2.2.tgz",
- "integrity": "sha512-av0Tryg4toDl2L/d1ABErtsAk9wvM1su6+M4wq5/Go50sk5IjGTldhbZFa9zNOohxLkZwaj0Q5xAgJ1Y+m5KrQ==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.2.5.tgz",
+ "integrity": "sha512-SJXo9NxgdXEeFA4OgfMaffjOxFBrMFIq/27F6/Z+JEs6lHZhayaBsofFcVbKEtivsg9+MbOLnN1TbwgnjjRw5g==",
"dev": true,
"dependencies": {
"@storybook/csf": "0.1.11",
@@ -9150,7 +9150,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
},
"peerDependenciesMeta": {
"react": {
@@ -9162,12 +9162,12 @@
}
},
"node_modules/@storybook/builder-webpack5": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.2.2.tgz",
- "integrity": "sha512-ud6a3pRusbC/TvT1ed15INxSivyL2y2zI61O/MWQZmM8sZOIC6ObdHLtzU4+535IIqiXhPoQ/QiOBbejqjgZvw==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.2.5.tgz",
+ "integrity": "sha512-qY/CuTYNPBYmeLihfawfe6O+6dDErhQ+xbwjxabt5Ba2QqUPhJZ0WEhWt0UidCb+G4ommLC4HOgri1pVHPObbw==",
"dev": true,
"dependencies": {
- "@storybook/core-webpack": "8.2.2",
+ "@storybook/core-webpack": "8.2.5",
"@types/node": "^18.0.0",
"@types/semver": "^7.3.4",
"browser-assert": "^1.2.1",
@@ -9200,7 +9200,7 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
},
"peerDependenciesMeta": {
"typescript": {
@@ -9209,18 +9209,18 @@
}
},
"node_modules/@storybook/builder-webpack5/node_modules/@types/node": {
- "version": "18.19.39",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
- "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
+ "version": "18.19.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz",
+ "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@storybook/builder-webpack5/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -9236,15 +9236,15 @@
"dev": true
},
"node_modules/@storybook/codemod": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.2.tgz",
- "integrity": "sha512-wRUVKLHVUhbLJYKW3QOufUxJGwaUT4jTCD8+HOGpHPdJO3NrwXu186xt4tuPZO2Y/NnacPeCQPsaK5ok4O8o7A==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.5.tgz",
+ "integrity": "sha512-bUCvOqW3LUjz6epmTfocWBm0S7Ae52xmHvhVqgAUsKp9bVw2CGt9uaPR8dVE4IfI1yJZKRjf3u7Y60OTfWew4g==",
"dev": true,
"dependencies": {
"@babel/core": "^7.24.4",
"@babel/preset-env": "^7.24.4",
"@babel/types": "^7.24.0",
- "@storybook/core": "8.2.2",
+ "@storybook/core": "8.2.5",
"@storybook/csf": "0.1.11",
"@types/cross-spawn": "^6.0.2",
"cross-spawn": "^7.0.3",
@@ -9304,10 +9304,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@storybook/components": {
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.2.5.tgz",
+ "integrity": "sha512-/cqAzQ1w9tK44BvKDNkY3MxcqoDaMvZeI5c4rGh/nYMjulXV4cAOTSlVK07XfkOJENj/wHHSDz8tZTrl2FhmuQ==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.5"
+ }
+ },
"node_modules/@storybook/core": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.2.tgz",
- "integrity": "sha512-L4ojYI+Os/i5bCReDIlFgEDQSS94mbJlNU9WRzEGZpqNC5/hbFEC9Tip7P1MiRx9NrewkzU7b+UCP7mi3e4drQ==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.5.tgz",
+ "integrity": "sha512-KjaeIkbdcog4Jmx3MoSjQZpfESin1qHEcFiLoOkICOpuKsj37xdMFcuSre8IbcVGCJPkt1RvEmfeu1N90jOgww==",
"dev": true,
"dependencies": {
"@storybook/csf": "0.1.11",
@@ -9328,9 +9341,9 @@
}
},
"node_modules/@storybook/core-webpack": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.2.2.tgz",
- "integrity": "sha512-M5wzgNbotVXcfo7WkXIuDxcBl7tTjnQ27lmlSBk+cu63pDvNn4UMDan621FcvxWq2DbjgIj+PASZ4DzM5O+ovA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.2.5.tgz",
+ "integrity": "sha512-Kg1pgUavDM4wdKkvl6djNuyA9vhVaQcsU1nL8t14A9jjF8rqOqP40eunrR7oLf/QmvbWk35wThW3PJi0dvrBhg==",
"dev": true,
"dependencies": {
"@types/node": "^18.0.0",
@@ -9341,13 +9354,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/core-webpack/node_modules/@types/node": {
- "version": "18.19.39",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
- "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
+ "version": "18.19.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz",
+ "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -9722,9 +9735,9 @@
}
},
"node_modules/@storybook/core/node_modules/@types/node": {
- "version": "18.19.39",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
- "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
+ "version": "18.19.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz",
+ "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -9778,9 +9791,9 @@
}
},
"node_modules/@storybook/csf-plugin": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.2.2.tgz",
- "integrity": "sha512-3K2RUpDDvq3DT46qAIj2VBC+fzTTebRUcZUsRfS6G1AzaX9p25iClEHiwcJacFkgQKhkci8A/Ly3Z4JJ3b4Pgw==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.2.5.tgz",
+ "integrity": "sha512-YpkvfDbKyilI54QMz/NyHGOlXxVeE+3LTKLx4GV/JrnGW+EtqQTYNaWWnTsesX0AsUICBAvxqyO9HtFtRjeL+Q==",
"dev": true,
"dependencies": {
"unplugin": "^1.3.1"
@@ -9790,7 +9803,7 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/global": {
@@ -9813,9 +9826,9 @@
}
},
"node_modules/@storybook/instrumenter": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.2.2.tgz",
- "integrity": "sha512-refwnHqKHhya45MgqakhMG0jKhTiEIAl0aOwAaQy9+zf9ncMIYQAXRQsSZ2Z188lFWE24wbeHKteb62a5ZfWwQ==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.2.5.tgz",
+ "integrity": "sha512-HeETFUYYZDM3A76oO8p7V1nCrxdAglhO+3FtPa2EqSWueYISANyOOTu/8NIW3EbKP3GsfWi509ofQhsLBHy9dQ==",
"dev": true,
"dependencies": {
"@storybook/global": "^5.0.0",
@@ -9827,13 +9840,26 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
+ }
+ },
+ "node_modules/@storybook/manager-api": {
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.2.5.tgz",
+ "integrity": "sha512-4UHRlpcbYF2UiO9tonafnJMC2wJXWjTXivHjuf3ehbJXmopkNe/4zLtNTRyf3Hozf4CuYtNotw0tXflBrGlIlw==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/nextjs": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-8.2.2.tgz",
- "integrity": "sha512-yjQwsbGsrwb8icl2aNqWN5BvbW7lx5niH3hVfdDxlhRFhTKaiLYo0gntJdr4MYBeejyxNFrqeYgQe3igkoOq+w==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-8.2.5.tgz",
+ "integrity": "sha512-Bnw1xAOdwMGyqx6N71gbaG66W8F5qn7tok0xP8C0nim6vVAcZvCSXbXcl9DV4tasxTPkzD7KdGS97gqk5cGPEg==",
"dev": true,
"dependencies": {
"@babel/core": "^7.24.4",
@@ -9850,10 +9876,10 @@
"@babel/preset-typescript": "^7.24.1",
"@babel/runtime": "^7.24.4",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
- "@storybook/builder-webpack5": "8.2.2",
- "@storybook/preset-react-webpack": "8.2.2",
- "@storybook/react": "8.2.2",
- "@storybook/test": "8.2.2",
+ "@storybook/builder-webpack5": "8.2.5",
+ "@storybook/preset-react-webpack": "8.2.5",
+ "@storybook/react": "8.2.5",
+ "@storybook/test": "8.2.5",
"@types/node": "^18.0.0",
"@types/semver": "^7.3.4",
"babel-loader": "^9.1.3",
@@ -9890,7 +9916,7 @@
"next": "^13.5.0 || ^14.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "storybook": "^8.2.2",
+ "storybook": "^8.2.5",
"webpack": "^5.0.0"
},
"peerDependenciesMeta": {
@@ -9973,13 +9999,13 @@
"dev": true
},
"node_modules/@storybook/preset-react-webpack": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.2.2.tgz",
- "integrity": "sha512-GJkDtw4Ac8icD66fotGXYE3rmZkIwASpNLOeGzyP4eMMNaf5vlvTDxwkY551cGbnA5P7r4UkGjDiWinB9XE4VQ==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.2.5.tgz",
+ "integrity": "sha512-kKN+wXv9IdxtAmWLsCS621pHpCs4i+NIWJ7SZW5VfurQrkFme7+FxeXvph/ZKTi2Z2adU1b46Y/svPHBgMup2A==",
"dev": true,
"dependencies": {
- "@storybook/core-webpack": "8.2.2",
- "@storybook/react": "8.2.2",
+ "@storybook/core-webpack": "8.2.5",
+ "@storybook/react": "8.2.5",
"@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0",
"@types/node": "^18.0.0",
"@types/semver": "^7.3.4",
@@ -10002,7 +10028,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
},
"peerDependenciesMeta": {
"typescript": {
@@ -10011,18 +10037,18 @@
}
},
"node_modules/@storybook/preset-react-webpack/node_modules/@types/node": {
- "version": "18.19.39",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
- "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
+ "version": "18.19.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz",
+ "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@storybook/preset-react-webpack/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -10031,14 +10057,31 @@
"node": ">=10"
}
},
+ "node_modules/@storybook/preview-api": {
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.2.5.tgz",
+ "integrity": "sha512-C5A3MtubUM5Tq1An1gIqiEmiBX4ybaTzAeBuohsqToPmWHvM2uIdSl6XpTyQQJowkvrqBKjchqZUy/2mynX4lQ==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.5"
+ }
+ },
"node_modules/@storybook/react": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.2.2.tgz",
- "integrity": "sha512-U4p/RV78yhjEwEzem8U7wE5/3sSpnqreGsPdAHMCIHd69e9tVeF0rwrTJGp917RClPjBKgEcfelCuvOlby4MrA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.2.5.tgz",
+ "integrity": "sha512-Wgr7a8ZHSDIJyKNDEYdwwu+AEkaG1yM7UBBmROr8WrYHgKaC49ekEgY0i3bck6HArUvu3A6Z448mJTMY+XtK5Q==",
"dev": true,
"dependencies": {
+ "@storybook/components": "^8.2.5",
"@storybook/global": "^5.0.0",
- "@storybook/react-dom-shim": "8.2.2",
+ "@storybook/manager-api": "^8.2.5",
+ "@storybook/preview-api": "^8.2.5",
+ "@storybook/react-dom-shim": "8.2.5",
+ "@storybook/theming": "^8.2.5",
"@types/escodegen": "^0.0.6",
"@types/estree": "^0.0.51",
"@types/node": "^18.0.0",
@@ -10065,7 +10108,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "storybook": "^8.2.2",
+ "storybook": "^8.2.5",
"typescript": ">= 4.2.x"
},
"peerDependenciesMeta": {
@@ -10094,9 +10137,9 @@
}
},
"node_modules/@storybook/react-dom-shim": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.2.2.tgz",
- "integrity": "sha512-4fb1/yT9WXHzHjs0In6orIEZxga5eXd9UaXEFGudBgowCjDUVP9LabDdKTbGusz20lfaAkATsRG/W+EcSLoh8w==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.2.5.tgz",
+ "integrity": "sha512-r+ZppgZR1AmM+2E9GRIaL/JjD3C/kl8sexD1mrGN4PBzrqqy6BNedHroWvf9JmfAvD/bp55peJ+LWAsSU/NvQQ==",
"dev": true,
"funding": {
"type": "opencollective",
@@ -10105,7 +10148,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/react/node_modules/@types/estree": {
@@ -10157,13 +10200,13 @@
"dev": true
},
"node_modules/@storybook/test": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.2.2.tgz",
- "integrity": "sha512-X2qAKErjTh1X7XLAZqCMtU0ZK8JuwdKmgiqU0oXWxIDmCX6/Dm9ZIcdMZHs/S+K/UnIByjNlQpTShLVfRUeN1w==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.2.5.tgz",
+ "integrity": "sha512-8fo5qh3dNTlcUsnpYB5klcsnjIhEpkyVC+KCqapDI/iFD6qDmZXzbEcP/HsVMICwGTanr2kFCmf5c8kfAiOMew==",
"dev": true,
"dependencies": {
"@storybook/csf": "0.1.11",
- "@storybook/instrumenter": "8.2.2",
+ "@storybook/instrumenter": "8.2.5",
"@testing-library/dom": "10.1.0",
"@testing-library/jest-dom": "6.4.5",
"@testing-library/user-event": "14.5.2",
@@ -10176,7 +10219,7 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^8.2.2"
+ "storybook": "^8.2.5"
}
},
"node_modules/@storybook/test/node_modules/@testing-library/jest-dom": {
@@ -10230,6 +10273,19 @@
"integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
"dev": true
},
+ "node_modules/@storybook/theming": {
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.2.5.tgz",
+ "integrity": "sha512-EEOSmW55MeLB3iskf5uUqffsqu003tTta8XQ1Xg8em3gePxPsjqzQtly1Ws5PtRg1Zvt1Zc6NKHwabiVzxothA==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.5"
+ }
+ },
"node_modules/@stripe/stripe-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-4.0.0.tgz",
@@ -10666,9 +10722,9 @@
}
},
"node_modules/@types/express-serve-static-core": {
- "version": "4.17.41",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
- "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
+ "version": "4.19.5",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz",
+ "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==",
"dev": true,
"dependencies": {
"@types/node": "*",
@@ -10938,9 +10994,9 @@
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
},
"node_modules/@types/qs": {
- "version": "6.9.10",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
- "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==",
+ "version": "6.9.15",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
+ "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==",
"dev": true
},
"node_modules/@types/range-parser": {
@@ -11013,14 +11069,14 @@
}
},
"node_modules/@types/serve-static": {
- "version": "1.15.5",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
- "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
+ "version": "1.15.7",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
+ "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
"dev": true,
"dependencies": {
"@types/http-errors": "*",
- "@types/mime": "*",
- "@types/node": "*"
+ "@types/node": "*",
+ "@types/send": "*"
}
},
"node_modules/@types/shimmer": {
@@ -12142,6 +12198,18 @@
"node": "*"
}
},
+ "node_modules/ast-types": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
+ "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/ast-types-flow": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
@@ -13927,9 +13995,9 @@
}
},
"node_modules/css-loader/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -16520,9 +16588,9 @@
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="
},
"node_modules/flow-parser": {
- "version": "0.239.1",
- "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.239.1.tgz",
- "integrity": "sha512-topOrETNxJ6T2gAnQiWqAlzGPj8uI2wtmNOlDIMNB+qyvGJZ6R++STbUOTAYmvPhOMz2gXnXPH0hOvURYmrBow==",
+ "version": "0.241.0",
+ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.241.0.tgz",
+ "integrity": "sha512-82yKXpz7iWknWFsognZUf5a6mBQLnVrYoYSU9Nbu7FTOpKlu3v9ehpiI9mYXuaIO3J0ojX1b83M/InXvld9HUw==",
"dev": true,
"engines": {
"node": ">=0.4.0"
@@ -16626,9 +16694,9 @@
}
},
"node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -24326,9 +24394,9 @@
}
},
"node_modules/recast": {
- "version": "0.23.6",
- "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.6.tgz",
- "integrity": "sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ==",
+ "version": "0.23.9",
+ "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz",
+ "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==",
"dev": true,
"dependencies": {
"ast-types": "^0.16.1",
@@ -24341,18 +24409,6 @@
"node": ">= 4"
}
},
- "node_modules/recast/node_modules/ast-types": {
- "version": "0.16.1",
- "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
- "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
- "dev": true,
- "dependencies": {
- "tslib": "^2.0.1"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/recast/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -25445,15 +25501,15 @@
}
},
"node_modules/storybook": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.2.tgz",
- "integrity": "sha512-xDT9gyzAEFQNeK7P+Mj/8bNzN+fbm6/4D6ihdSzmczayjydpNjMs74HDHMY6S4Bfu6tRVyEK2ALPGnr6ZVofBA==",
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.5.tgz",
+ "integrity": "sha512-nfcly5CY3D6KuHbsfhScPaGeraRA9EJhO9GF00/dnI0GXW4ILS8Kwket515IkKAuKcdjdZis6maEuosbG//Kbg==",
"dev": true,
"dependencies": {
"@babel/core": "^7.24.4",
"@babel/types": "^7.24.0",
- "@storybook/codemod": "8.2.2",
- "@storybook/core": "8.2.2",
+ "@storybook/codemod": "8.2.5",
+ "@storybook/core": "8.2.5",
"@types/semver": "^7.3.4",
"@yarnpkg/fslib": "2.10.3",
"@yarnpkg/libzip": "2.3.0",
diff --git a/package.json b/package.json
index 843ba663eaa..da147366448 100644
--- a/package.json
+++ b/package.json
@@ -104,13 +104,13 @@
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@playwright/test": "^1.43.1",
- "@storybook/addon-a11y": "^8.2.2",
- "@storybook/addon-actions": "^8.2.2",
- "@storybook/addon-essentials": "^8.2.2",
- "@storybook/addon-interactions": "^8.2.2",
- "@storybook/addon-links": "^8.2.2",
+ "@storybook/addon-a11y": "^8.2.5",
+ "@storybook/addon-actions": "^8.2.5",
+ "@storybook/addon-essentials": "^8.2.5",
+ "@storybook/addon-interactions": "^8.2.5",
+ "@storybook/addon-links": "^8.2.5",
"@storybook/blocks": "^8.0.0",
- "@storybook/nextjs": "^8.2.2",
+ "@storybook/nextjs": "^8.2.5",
"@storybook/react": "^8.0.0",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
From 6618a558dc6acc841886a6187cc795998b4f7eae Mon Sep 17 00:00:00 2001
From: Florian Zia
Date: Mon, 22 Jul 2024 16:43:06 +0200
Subject: [PATCH 130/137] chore: Move type assertion to useTelemetryView hook
---
src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx | 2 +-
src/app/hooks/useViewTelemetry.ts | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx b/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx
index 7f715142692..0251217dd56 100644
--- a/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx
+++ b/src/app/(proper_react)/(redesign)/(public)/FreeScanCta.tsx
@@ -82,7 +82,7 @@ export const FreeScanCta = (
) : (
}
+ buttonRef={refViewTelemetry as RefObject}
variant="primary"
event={{
module: "ctaButton",
diff --git a/src/app/hooks/useViewTelemetry.ts b/src/app/hooks/useViewTelemetry.ts
index b7ff9e720fb..5bafa869f1c 100644
--- a/src/app/hooks/useViewTelemetry.ts
+++ b/src/app/hooks/useViewTelemetry.ts
@@ -5,6 +5,7 @@
import { IntersectionOptions, useInView } from "react-intersection-observer";
import { TelemetryArgs, useTelemetry } from "./useTelemetry";
import { GleanMetricMap } from "../../telemetry/generated/_map";
+import { RefObject } from "react";
export function useViewTelemetry<
EventModule extends keyof Pick,
@@ -34,5 +35,5 @@ export function useViewTelemetry<
},
});
- return ref;
+ return ref as unknown as RefObject;
}
From 017c203fa627046937fa5c1106e860fc7dbaaeaa Mon Sep 17 00:00:00 2001
From: Florian Zia
Date: Mon, 22 Jul 2024 17:13:40 +0200
Subject: [PATCH 131/137] fix: HTMLFormElement type
---
src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx b/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
index 9e40827f2de..83051921292 100644
--- a/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
+++ b/src/app/(proper_react)/(redesign)/(public)/SignUpForm.tsx
@@ -4,7 +4,7 @@
"use client";
-import { FormEventHandler, useId, useState } from "react";
+import { FormEventHandler, RefObject, useId, useState } from "react";
import { signIn } from "next-auth/react";
import { useL10n } from "../../../hooks/l10n";
import { Button } from "../../../components/client/Button";
@@ -66,7 +66,11 @@ export const SignUpForm = (props: Props) => {
return props.scanLimitReached ? (
) : (
-
+ }
+ className={styles.form}
+ onSubmit={onSubmit}
+ >
Date: Mon, 22 Jul 2024 14:41:58 +0000
Subject: [PATCH 132/137] chore(deps-dev): bump lint-staged from 15.2.5 to
15.2.7
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 15.2.5 to 15.2.7.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/master/CHANGELOG.md)
- [Commits](https://github.com/okonet/lint-staged/compare/v15.2.5...v15.2.7)
---
updated-dependencies:
- dependency-name: lint-staged
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 8 ++++----
package.json | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index af1104b0a9a..e779016121e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -91,7 +91,7 @@
"jest-canvas-mock": "^2.5.2",
"jest-environment-jsdom": "^29.7.0",
"jest-fail-on-console": "^3.3.0",
- "lint-staged": "^15.2.5",
+ "lint-staged": "^15.2.7",
"mjml-browser": "^4.15.3",
"prettier": "3.3.3",
"react-intersection-observer": "^9.10.3",
@@ -20618,9 +20618,9 @@
"dev": true
},
"node_modules/lint-staged": {
- "version": "15.2.5",
- "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.5.tgz",
- "integrity": "sha512-j+DfX7W9YUvdzEZl3Rk47FhDF6xwDBV5wwsCPw6BwWZVPYJemusQmvb9bRsW23Sqsaa+vRloAWogbK4BUuU2zA==",
+ "version": "15.2.7",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz",
+ "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==",
"dev": true,
"dependencies": {
"chalk": "~5.3.0",
diff --git a/package.json b/package.json
index da147366448..c30e71b0252 100644
--- a/package.json
+++ b/package.json
@@ -143,7 +143,7 @@
"jest-canvas-mock": "^2.5.2",
"jest-environment-jsdom": "^29.7.0",
"jest-fail-on-console": "^3.3.0",
- "lint-staged": "^15.2.5",
+ "lint-staged": "^15.2.7",
"mjml-browser": "^4.15.3",
"prettier": "3.3.3",
"react-intersection-observer": "^9.10.3",
From 3f6f51a48dbe398b7e6e9e4ea0b1c3eac1d9b0ef Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 22 Jul 2024 15:33:26 +0000
Subject: [PATCH 133/137] chore(deps): bump @aws-sdk/lib-storage in the aws-sdk
group
Bumps the aws-sdk group with 1 update: [@aws-sdk/lib-storage](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/lib/lib-storage).
Updates `@aws-sdk/lib-storage` from 3.614.0 to 3.616.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/lib/lib-storage/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.616.0/lib/lib-storage)
---
updated-dependencies:
- dependency-name: "@aws-sdk/lib-storage"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: aws-sdk
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 320 +++++++++++++++++++++++-----------------------
package.json | 2 +-
2 files changed, 162 insertions(+), 160 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e779016121e..0fd204601df 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"license": "MPL-2.0",
"dependencies": {
"@aws-sdk/client-s3": "^3.614.0",
- "@aws-sdk/lib-storage": "^3.614.0",
+ "@aws-sdk/lib-storage": "^3.616.0",
"@fluent/bundle": "^0.18.0",
"@fluent/langneg": "^0.7.0",
"@fluent/react": "^0.15.2",
@@ -322,65 +322,65 @@
}
},
"node_modules/@aws-sdk/client-s3": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.614.0.tgz",
- "integrity": "sha512-9BlhfeBegvyjOqHtcr9kvrT80wiy7EVUiqYyTFiiDv/hJIcG88XHQCZdLU7658XBkQ7aFrr5b8rF2HRD1oroxw==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.616.0.tgz",
+ "integrity": "sha512-6gyZnBlAgOU8cwNqPhFO9s6maGI4/iHV3cmqvQgUn3uqhi1EgTSZSsTMuRzKEgBpTGgC+9Bm6djKqOderMqjdA==",
"dependencies": {
"@aws-crypto/sha1-browser": "5.2.0",
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/client-sso-oidc": "3.614.0",
- "@aws-sdk/client-sts": "3.614.0",
- "@aws-sdk/core": "3.614.0",
- "@aws-sdk/credential-provider-node": "3.614.0",
- "@aws-sdk/middleware-bucket-endpoint": "3.614.0",
- "@aws-sdk/middleware-expect-continue": "3.609.0",
- "@aws-sdk/middleware-flexible-checksums": "3.614.0",
- "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/client-sso-oidc": "3.616.0",
+ "@aws-sdk/client-sts": "3.616.0",
+ "@aws-sdk/core": "3.616.0",
+ "@aws-sdk/credential-provider-node": "3.616.0",
+ "@aws-sdk/middleware-bucket-endpoint": "3.616.0",
+ "@aws-sdk/middleware-expect-continue": "3.616.0",
+ "@aws-sdk/middleware-flexible-checksums": "3.616.0",
+ "@aws-sdk/middleware-host-header": "3.616.0",
"@aws-sdk/middleware-location-constraint": "3.609.0",
"@aws-sdk/middleware-logger": "3.609.0",
- "@aws-sdk/middleware-recursion-detection": "3.609.0",
- "@aws-sdk/middleware-sdk-s3": "3.614.0",
- "@aws-sdk/middleware-signing": "3.609.0",
+ "@aws-sdk/middleware-recursion-detection": "3.616.0",
+ "@aws-sdk/middleware-sdk-s3": "3.616.0",
+ "@aws-sdk/middleware-signing": "3.616.0",
"@aws-sdk/middleware-ssec": "3.609.0",
- "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/middleware-user-agent": "3.616.0",
"@aws-sdk/region-config-resolver": "3.614.0",
- "@aws-sdk/signature-v4-multi-region": "3.614.0",
+ "@aws-sdk/signature-v4-multi-region": "3.616.0",
"@aws-sdk/types": "3.609.0",
"@aws-sdk/util-endpoints": "3.614.0",
"@aws-sdk/util-user-agent-browser": "3.609.0",
"@aws-sdk/util-user-agent-node": "3.614.0",
"@aws-sdk/xml-builder": "3.609.0",
"@smithy/config-resolver": "^3.0.5",
- "@smithy/core": "^2.2.6",
+ "@smithy/core": "^2.2.7",
"@smithy/eventstream-serde-browser": "^3.0.4",
"@smithy/eventstream-serde-config-resolver": "^3.0.3",
"@smithy/eventstream-serde-node": "^3.0.4",
- "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/fetch-http-handler": "^3.2.2",
"@smithy/hash-blob-browser": "^3.1.2",
"@smithy/hash-node": "^3.0.3",
"@smithy/hash-stream-node": "^3.1.2",
"@smithy/invalid-dependency": "^3.0.3",
"@smithy/md5-js": "^3.0.3",
- "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.4",
"@smithy/middleware-endpoint": "^3.0.5",
- "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-retry": "^3.0.10",
"@smithy/middleware-serde": "^3.0.3",
"@smithy/middleware-stack": "^3.0.3",
"@smithy/node-config-provider": "^3.1.4",
- "@smithy/node-http-handler": "^3.1.2",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/node-http-handler": "^3.1.3",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/smithy-client": "^3.1.8",
"@smithy/types": "^3.3.0",
"@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.9",
- "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-defaults-mode-browser": "^3.0.10",
+ "@smithy/util-defaults-mode-node": "^3.0.10",
"@smithy/util-endpoints": "^2.0.5",
"@smithy/util-retry": "^3.0.3",
- "@smithy/util-stream": "^3.0.6",
+ "@smithy/util-stream": "^3.1.0",
"@smithy/util-utf8": "^3.0.0",
"@smithy/util-waiter": "^3.1.2",
"tslib": "^2.6.2"
@@ -390,43 +390,43 @@
}
},
"node_modules/@aws-sdk/client-sso": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.614.0.tgz",
- "integrity": "sha512-p5pyYaxRzBttjBkqfc8i3K7DzBdTg3ECdVgBo6INIUxfvDy0J8QUE8vNtCgvFIkq+uPw/8M+Eo4zzln7anuO0Q==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.616.0.tgz",
+ "integrity": "sha512-hwW0u1f8U4dSloAe61/eupUiGd5Q13B72BuzGxvRk0cIpYX/2m0KBG8DDl7jW1b2QQ+CflTLpG2XUf2+vRJxGA==",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "3.614.0",
- "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/core": "3.616.0",
+ "@aws-sdk/middleware-host-header": "3.616.0",
"@aws-sdk/middleware-logger": "3.609.0",
- "@aws-sdk/middleware-recursion-detection": "3.609.0",
- "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/middleware-recursion-detection": "3.616.0",
+ "@aws-sdk/middleware-user-agent": "3.616.0",
"@aws-sdk/region-config-resolver": "3.614.0",
"@aws-sdk/types": "3.609.0",
"@aws-sdk/util-endpoints": "3.614.0",
"@aws-sdk/util-user-agent-browser": "3.609.0",
"@aws-sdk/util-user-agent-node": "3.614.0",
"@smithy/config-resolver": "^3.0.5",
- "@smithy/core": "^2.2.6",
- "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/core": "^2.2.7",
+ "@smithy/fetch-http-handler": "^3.2.2",
"@smithy/hash-node": "^3.0.3",
"@smithy/invalid-dependency": "^3.0.3",
- "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.4",
"@smithy/middleware-endpoint": "^3.0.5",
- "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-retry": "^3.0.10",
"@smithy/middleware-serde": "^3.0.3",
"@smithy/middleware-stack": "^3.0.3",
"@smithy/node-config-provider": "^3.1.4",
- "@smithy/node-http-handler": "^3.1.2",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/node-http-handler": "^3.1.3",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/smithy-client": "^3.1.8",
"@smithy/types": "^3.3.0",
"@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.9",
- "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-defaults-mode-browser": "^3.0.10",
+ "@smithy/util-defaults-mode-node": "^3.0.10",
"@smithy/util-endpoints": "^2.0.5",
"@smithy/util-middleware": "^3.0.3",
"@smithy/util-retry": "^3.0.3",
@@ -438,44 +438,44 @@
}
},
"node_modules/@aws-sdk/client-sso-oidc": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.614.0.tgz",
- "integrity": "sha512-BI1NWcpppbHg/28zbUg54dZeckork8BItZIcjls12vxasy+p3iEzrJVG60jcbUTTsk3Qc1tyxNfrdcVqx0y7Ww==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.616.0.tgz",
+ "integrity": "sha512-YY1hpYS/G1uRGjQf88dL8VLHkP/IjGxKeXdhy+JnzMdCkAWl3V9j0fEALw40NZe0x79gr6R2KUOUH/IKYQfUmg==",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "3.614.0",
- "@aws-sdk/credential-provider-node": "3.614.0",
- "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/core": "3.616.0",
+ "@aws-sdk/credential-provider-node": "3.616.0",
+ "@aws-sdk/middleware-host-header": "3.616.0",
"@aws-sdk/middleware-logger": "3.609.0",
- "@aws-sdk/middleware-recursion-detection": "3.609.0",
- "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/middleware-recursion-detection": "3.616.0",
+ "@aws-sdk/middleware-user-agent": "3.616.0",
"@aws-sdk/region-config-resolver": "3.614.0",
"@aws-sdk/types": "3.609.0",
"@aws-sdk/util-endpoints": "3.614.0",
"@aws-sdk/util-user-agent-browser": "3.609.0",
"@aws-sdk/util-user-agent-node": "3.614.0",
"@smithy/config-resolver": "^3.0.5",
- "@smithy/core": "^2.2.6",
- "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/core": "^2.2.7",
+ "@smithy/fetch-http-handler": "^3.2.2",
"@smithy/hash-node": "^3.0.3",
"@smithy/invalid-dependency": "^3.0.3",
- "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.4",
"@smithy/middleware-endpoint": "^3.0.5",
- "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-retry": "^3.0.10",
"@smithy/middleware-serde": "^3.0.3",
"@smithy/middleware-stack": "^3.0.3",
"@smithy/node-config-provider": "^3.1.4",
- "@smithy/node-http-handler": "^3.1.2",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/node-http-handler": "^3.1.3",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/smithy-client": "^3.1.8",
"@smithy/types": "^3.3.0",
"@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.9",
- "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-defaults-mode-browser": "^3.0.10",
+ "@smithy/util-defaults-mode-node": "^3.0.10",
"@smithy/util-endpoints": "^2.0.5",
"@smithy/util-middleware": "^3.0.3",
"@smithy/util-retry": "^3.0.3",
@@ -486,49 +486,49 @@
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-sts": "^3.614.0"
+ "@aws-sdk/client-sts": "^3.616.0"
}
},
"node_modules/@aws-sdk/client-sts": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.614.0.tgz",
- "integrity": "sha512-i6QmaVA1KHHYNnI2VYQy/sc31rLm4+jSp8b/YbQpFnD0w3aXsrEEHHlxek45uSkHb4Nrj1omFBVy/xp1WVYx2Q==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.616.0.tgz",
+ "integrity": "sha512-FP7i7hS5FpReqnysQP1ukQF1OUWy8lkomaOnbu15H415YUrfCp947SIx6+BItjmx+esKxPkEjh/fbCVzw2D6hQ==",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/client-sso-oidc": "3.614.0",
- "@aws-sdk/core": "3.614.0",
- "@aws-sdk/credential-provider-node": "3.614.0",
- "@aws-sdk/middleware-host-header": "3.609.0",
+ "@aws-sdk/client-sso-oidc": "3.616.0",
+ "@aws-sdk/core": "3.616.0",
+ "@aws-sdk/credential-provider-node": "3.616.0",
+ "@aws-sdk/middleware-host-header": "3.616.0",
"@aws-sdk/middleware-logger": "3.609.0",
- "@aws-sdk/middleware-recursion-detection": "3.609.0",
- "@aws-sdk/middleware-user-agent": "3.614.0",
+ "@aws-sdk/middleware-recursion-detection": "3.616.0",
+ "@aws-sdk/middleware-user-agent": "3.616.0",
"@aws-sdk/region-config-resolver": "3.614.0",
"@aws-sdk/types": "3.609.0",
"@aws-sdk/util-endpoints": "3.614.0",
"@aws-sdk/util-user-agent-browser": "3.609.0",
"@aws-sdk/util-user-agent-node": "3.614.0",
"@smithy/config-resolver": "^3.0.5",
- "@smithy/core": "^2.2.6",
- "@smithy/fetch-http-handler": "^3.2.1",
+ "@smithy/core": "^2.2.7",
+ "@smithy/fetch-http-handler": "^3.2.2",
"@smithy/hash-node": "^3.0.3",
"@smithy/invalid-dependency": "^3.0.3",
- "@smithy/middleware-content-length": "^3.0.3",
+ "@smithy/middleware-content-length": "^3.0.4",
"@smithy/middleware-endpoint": "^3.0.5",
- "@smithy/middleware-retry": "^3.0.9",
+ "@smithy/middleware-retry": "^3.0.10",
"@smithy/middleware-serde": "^3.0.3",
"@smithy/middleware-stack": "^3.0.3",
"@smithy/node-config-provider": "^3.1.4",
- "@smithy/node-http-handler": "^3.1.2",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/node-http-handler": "^3.1.3",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/smithy-client": "^3.1.8",
"@smithy/types": "^3.3.0",
"@smithy/url-parser": "^3.0.3",
"@smithy/util-base64": "^3.0.0",
"@smithy/util-body-length-browser": "^3.0.0",
"@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.9",
- "@smithy/util-defaults-mode-node": "^3.0.9",
+ "@smithy/util-defaults-mode-browser": "^3.0.10",
+ "@smithy/util-defaults-mode-node": "^3.0.10",
"@smithy/util-endpoints": "^2.0.5",
"@smithy/util-middleware": "^3.0.3",
"@smithy/util-retry": "^3.0.3",
@@ -540,14 +540,14 @@
}
},
"node_modules/@aws-sdk/core": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.614.0.tgz",
- "integrity": "sha512-BUuS5/1YkgmKc4J0bg83XEtMyDHVyqG2QDzfmhYe8gbOIZabUl1FlrFVwhCAthtrrI6MPGTQcERB4BtJKUSplw==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.616.0.tgz",
+ "integrity": "sha512-O/urkh2kECs/IqZIVZxyeyHZ7OR2ZWhLNK7btsVQBQvJKrEspLrk/Fp20Qfg5JDerQfBN83ZbyRXLJOOucdZpw==",
"dependencies": {
- "@smithy/core": "^2.2.6",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/signature-v4": "^3.1.2",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/core": "^2.2.7",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/signature-v4": "^4.0.0",
+ "@smithy/smithy-client": "^3.1.8",
"@smithy/types": "^3.3.0",
"fast-xml-parser": "4.2.5",
"tslib": "^2.6.2"
@@ -571,18 +571,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.614.0.tgz",
- "integrity": "sha512-YIEjlNUKb3Vo/iTnGAPdsiDC3FUUnNoex2OwU8LmR7AkYZiWdB8nx99DfgkkY+OFMUpw7nKD2PCOtuFONelfGA==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.616.0.tgz",
+ "integrity": "sha512-1rgCkr7XvEMBl7qWCo5BKu3yAxJs71dRaZ55Xnjte/0ZHH6Oc93ZrHzyYy6UH6t0nZrH+FAuw7Yko2YtDDwDeg==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
- "@smithy/fetch-http-handler": "^3.2.1",
- "@smithy/node-http-handler": "^3.1.2",
+ "@smithy/fetch-http-handler": "^3.2.2",
+ "@smithy/node-http-handler": "^3.1.3",
"@smithy/property-provider": "^3.1.3",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/smithy-client": "^3.1.8",
"@smithy/types": "^3.3.0",
- "@smithy/util-stream": "^3.0.6",
+ "@smithy/util-stream": "^3.1.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -590,14 +590,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.614.0.tgz",
- "integrity": "sha512-KfLuLFGwlvFSZ2MuzYwWGPb1y5TeiwX5okIDe0aQ1h10oD3924FXbN+mabOnUHQ8EFcGAtCaWbrC86mI7ktC6A==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.616.0.tgz",
+ "integrity": "sha512-5gQdMr9cca3xV7FF2SxpxWGH2t6+t4o+XBGiwsHm8muEjf4nUmw7Ij863x25Tjt2viPYV0UStczSb5Sihp7bkA==",
"dependencies": {
"@aws-sdk/credential-provider-env": "3.609.0",
- "@aws-sdk/credential-provider-http": "3.614.0",
+ "@aws-sdk/credential-provider-http": "3.616.0",
"@aws-sdk/credential-provider-process": "3.614.0",
- "@aws-sdk/credential-provider-sso": "3.614.0",
+ "@aws-sdk/credential-provider-sso": "3.616.0",
"@aws-sdk/credential-provider-web-identity": "3.609.0",
"@aws-sdk/types": "3.609.0",
"@smithy/credential-provider-imds": "^3.1.4",
@@ -610,19 +610,19 @@
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-sts": "^3.614.0"
+ "@aws-sdk/client-sts": "^3.616.0"
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.614.0.tgz",
- "integrity": "sha512-4J6gPEuFZP0mkWq5E//oMS1vrmMM88iNNcv7TEljYnsc6JTAlKejCyFwx6CN+nkIhmIZsl06SXIhBemzBdBPfg==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.616.0.tgz",
+ "integrity": "sha512-Se+u6DAxjDPjKE3vX1X2uxjkWgGq69BTo0uTB0vDUiWwBVgh16s9BsBhSAlKEH1CCbbJHvOg4YdTrzjwzqyClg==",
"dependencies": {
"@aws-sdk/credential-provider-env": "3.609.0",
- "@aws-sdk/credential-provider-http": "3.614.0",
- "@aws-sdk/credential-provider-ini": "3.614.0",
+ "@aws-sdk/credential-provider-http": "3.616.0",
+ "@aws-sdk/credential-provider-ini": "3.616.0",
"@aws-sdk/credential-provider-process": "3.614.0",
- "@aws-sdk/credential-provider-sso": "3.614.0",
+ "@aws-sdk/credential-provider-sso": "3.616.0",
"@aws-sdk/credential-provider-web-identity": "3.609.0",
"@aws-sdk/types": "3.609.0",
"@smithy/credential-provider-imds": "^3.1.4",
@@ -651,11 +651,11 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.614.0.tgz",
- "integrity": "sha512-55+gp0JY4451cWI1qXmVMFM0GQaBKiQpXv2P0xmd9P3qLDyeFUSEW8XPh0d2lb1ICr6x4s47ynXVdGCIv2mXMg==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.616.0.tgz",
+ "integrity": "sha512-3rsWs9GBi8Z8Gps5ROwqguxtw+J6OIg1vawZMLRNMqqZoBvbOToe9wEnpid8ylU+27+oG8uibJNlNuRyXApUjw==",
"dependencies": {
- "@aws-sdk/client-sso": "3.614.0",
+ "@aws-sdk/client-sso": "3.616.0",
"@aws-sdk/token-providers": "3.614.0",
"@aws-sdk/types": "3.609.0",
"@smithy/property-provider": "^3.1.3",
@@ -685,13 +685,13 @@
}
},
"node_modules/@aws-sdk/lib-storage": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.614.0.tgz",
- "integrity": "sha512-Bzni+r7pS+nRiqcmWPpB/OiQEM4GszGRp1DXpL3rKnwaeu+Qgf2w12DULxWUacIvOc4IzLsv6tpEidQ/P1zKQg==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.616.0.tgz",
+ "integrity": "sha512-VhuJGCbJvI1TGGWDd5pdnCa+pobKAGv5/H4MqN1GlyRuWd6Biwby+pRaFb2nL4GT3bOJdCcM24CyZXO2PefPaw==",
"dependencies": {
"@smithy/abort-controller": "^3.1.1",
"@smithy/middleware-endpoint": "^3.0.5",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/smithy-client": "^3.1.8",
"buffer": "5.6.0",
"events": "3.3.0",
"stream-browserify": "3.0.0",
@@ -701,18 +701,18 @@
"node": ">=16.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.614.0"
+ "@aws-sdk/client-s3": "^3.616.0"
}
},
"node_modules/@aws-sdk/middleware-bucket-endpoint": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.614.0.tgz",
- "integrity": "sha512-TqEY8KcZeZ0LIxXaqG9RSSNnDHvD8RAFP4Xenwsxqnyad0Yn7LgCoFwRByelJ0t54ROYL1/ETJleWE4U4TOXdg==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.616.0.tgz",
+ "integrity": "sha512-KZv78s8UE7+s3qZCfG3pE9U9XV5WTP478aNWis5gDXmsb5LF7QWzEeR8kve5dnjNlK6qVQ33v+mUZa6lR5PwMw==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
"@aws-sdk/util-arn-parser": "3.568.0",
"@smithy/node-config-provider": "^3.1.4",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
"@smithy/util-config-provider": "^3.0.0",
"tslib": "^2.6.2"
@@ -722,12 +722,12 @@
}
},
"node_modules/@aws-sdk/middleware-expect-continue": {
- "version": "3.609.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.609.0.tgz",
- "integrity": "sha512-+zeg//mSer4JZRxOB/4mUOMUJyuYPwATnIC5moBB8P8Xe+mJaVRFy8qlCtzYNj2TycnlsBPzTK0j7P1yvDh97w==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.616.0.tgz",
+ "integrity": "sha512-IM1pfJPm7pDUXa55js9bnGjS8o3ldzDwf95mL9ZAYdEsm10q6i0ZxZbbro2gTq25Ap5ykdeeS34lOSzIqPiW1A==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -736,15 +736,15 @@
}
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.614.0.tgz",
- "integrity": "sha512-ZLpxVXMboDeMT7p2Kdp5m1uLVKOktkZoMgLvvbe3zbrU4Ji5IU5xVE0aa4X7H28BtuODCs6SLESnPs19bhMKlA==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.616.0.tgz",
+ "integrity": "sha512-Mrco/dURoTXVqwcnYRcyrFaPTIg36ifg2PK0kUYfSVTGEOClZOQXlVG5zYCZoo3yEMgy/gLT907FjUQxwoifIw==",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
"@aws-crypto/crc32c": "5.2.0",
"@aws-sdk/types": "3.609.0",
"@smithy/is-array-buffer": "^3.0.0",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
"@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
@@ -754,12 +754,12 @@
}
},
"node_modules/@aws-sdk/middleware-host-header": {
- "version": "3.609.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.609.0.tgz",
- "integrity": "sha512-iTKfo158lc4jLDfYeZmYMIBHsn8m6zX+XB6birCSNZ/rrlzAkPbGE43CNdKfvjyWdqgLMRXF+B+OcZRvqhMXPQ==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.616.0.tgz",
+ "integrity": "sha512-mhNfHuGhCDZwYCABebaOvTgOM44UCZZRq2cBpgPZLVKP0ydAv5aFHXv01goexxXHqgHoEGx0uXWxlw0s2EpFDg==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -794,12 +794,12 @@
}
},
"node_modules/@aws-sdk/middleware-recursion-detection": {
- "version": "3.609.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.609.0.tgz",
- "integrity": "sha512-6sewsYB7/o/nbUfA99Aa/LokM+a/u4Wpm/X2o0RxOsDtSB795ObebLJe2BxY5UssbGaWkn7LswyfvrdZNXNj1w==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.616.0.tgz",
+ "integrity": "sha512-LQKAcrZRrR9EGez4fdCIVjdn0Ot2HMN12ChnoMGEU6oIxnQ2aSC7iASFFCV39IYfeMh7iSCPj7Wopqw8rAouzg==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -808,18 +808,20 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.614.0.tgz",
- "integrity": "sha512-9fJTaiuuOfFV4FqmUEhPYzrtv7JOfYpB7q65oG3uayVH4ngWHIJkjnnX79zRhNZKdPGta+XIsnZzjEghg82ngA==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.616.0.tgz",
+ "integrity": "sha512-heq9pzn0NRX6VL/oMlmwZdgcCh5eJUDscvwMl/oGev0tNdTpB2oGU+wPaNMka7IrW3eBPn7APmY9fdS1kBaBoQ==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
"@aws-sdk/util-arn-parser": "3.568.0",
"@smithy/node-config-provider": "^3.1.4",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/signature-v4": "^3.1.2",
- "@smithy/smithy-client": "^3.1.7",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/signature-v4": "^4.0.0",
+ "@smithy/smithy-client": "^3.1.8",
"@smithy/types": "^3.3.0",
"@smithy/util-config-provider": "^3.0.0",
+ "@smithy/util-stream": "^3.1.0",
+ "@smithy/util-utf8": "^3.0.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -827,14 +829,14 @@
}
},
"node_modules/@aws-sdk/middleware-signing": {
- "version": "3.609.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.609.0.tgz",
- "integrity": "sha512-2w3dBLjQVKIajYzokO4hduq8/0hSMUYHHmIo1Kdl+MSY8uwRBt12bLL6pyreobTcRMxizvn2ph/CQ9I1ST/WGQ==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.616.0.tgz",
+ "integrity": "sha512-wwzZFlXyURwo40oz1NmufreQa5DqwnCF8hR8tIP5+oKCyhbkmlmv8xG4Wn51bzY2WEbQhvFebgZSFTEvelCoCg==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
"@smithy/property-provider": "^3.1.3",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/signature-v4": "^3.1.2",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/signature-v4": "^4.0.0",
"@smithy/types": "^3.3.0",
"@smithy/util-middleware": "^3.0.3",
"tslib": "^2.6.2"
@@ -857,13 +859,13 @@
}
},
"node_modules/@aws-sdk/middleware-user-agent": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.614.0.tgz",
- "integrity": "sha512-xUxh0UPQiMTG6E31Yvu6zVYlikrIcFDKljM11CaatInzvZubGTGiX0DjpqRlfGzUNsuPc/zNrKwRP2+wypgqIw==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.616.0.tgz",
+ "integrity": "sha512-iMcAb4E+Z3vuEcrDsG6T2OBNiqWAquwahP9qepHqfmnmJqHr1mSHtXDYTGBNid31+621sUQmneUQ+fagpGAe4w==",
"dependencies": {
"@aws-sdk/types": "3.609.0",
"@aws-sdk/util-endpoints": "3.614.0",
- "@smithy/protocol-http": "^4.0.3",
+ "@smithy/protocol-http": "^4.0.4",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -888,14 +890,14 @@
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.614.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.614.0.tgz",
- "integrity": "sha512-6mW3ONW4oLzxrePznYhz7sNT9ji9Am9ufLeV722tbOVS5lArBOZ6E1oPz0uYBhisUPznWKhcLRMggt7vIJWMng==",
+ "version": "3.616.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.616.0.tgz",
+ "integrity": "sha512-WQn43cfnwbG6jnPjh/SyujDQVqbRjGFY9tGI/tqtUvvGwoDhI343TSDCA7fvs0FEC6Za6vgOBq1CwPv3CFyfhA==",
"dependencies": {
- "@aws-sdk/middleware-sdk-s3": "3.614.0",
+ "@aws-sdk/middleware-sdk-s3": "3.616.0",
"@aws-sdk/types": "3.609.0",
- "@smithy/protocol-http": "^4.0.3",
- "@smithy/signature-v4": "^3.1.2",
+ "@smithy/protocol-http": "^4.0.4",
+ "@smithy/signature-v4": "^4.0.0",
"@smithy/types": "^3.3.0",
"tslib": "^2.6.2"
},
@@ -8630,9 +8632,9 @@
}
},
"node_modules/@smithy/signature-v4": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.2.tgz",
- "integrity": "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.0.0.tgz",
+ "integrity": "sha512-ervYjQ+ZvmNG51Ui77IOTPri7nOyo8Kembzt9uwwlmtXJPmFXvslOahbA1blvAVs7G0KlYMiOBog1rAt7RVXxg==",
"dependencies": {
"@smithy/is-array-buffer": "^3.0.0",
"@smithy/types": "^3.3.0",
diff --git a/package.json b/package.json
index c30e71b0252..d03150fccac 100644
--- a/package.json
+++ b/package.json
@@ -62,7 +62,7 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.614.0",
- "@aws-sdk/lib-storage": "^3.614.0",
+ "@aws-sdk/lib-storage": "^3.616.0",
"@fluent/bundle": "^0.18.0",
"@fluent/langneg": "^0.7.0",
"@fluent/react": "^0.15.2",
From 252178516c6a83d30c7ad06a92d463ad10aed823 Mon Sep 17 00:00:00 2001
From: Florian Zia
Date: Mon, 22 Jul 2024 17:38:00 +0200
Subject: [PATCH 134/137] fix: Unit tests
---
package-lock.json | 25 +++++++++++++------------
package.json | 24 +++++++++++-------------
2 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 19c16beeabd..6ee0d3399a8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,7 +44,6 @@
"react-aria": "^3.33.1",
"react-cookie": "^7.1.0",
"react-dom": "^18.2.0",
- "react-intersection-observer": "^9.13.0",
"react-stately": "^3.31.1",
"server-only": "^0.0.1",
"uuid": "^9.0.1",
@@ -53,13 +52,13 @@
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@playwright/test": "^1.43.1",
- "@storybook/addon-a11y": "^8.2.5",
- "@storybook/addon-actions": "^8.2.5",
- "@storybook/addon-essentials": "^8.2.5",
- "@storybook/addon-interactions": "^8.2.5",
- "@storybook/addon-links": "^8.2.5",
+ "@storybook/addon-a11y": "^8.2.2",
+ "@storybook/addon-actions": "^8.2.2",
+ "@storybook/addon-essentials": "^8.2.2",
+ "@storybook/addon-interactions": "^8.2.2",
+ "@storybook/addon-links": "^8.2.2",
"@storybook/blocks": "^8.0.0",
- "@storybook/nextjs": "^8.2.5",
+ "@storybook/nextjs": "^8.2.2",
"@storybook/react": "^8.0.0",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
@@ -94,7 +93,7 @@
"jest-fail-on-console": "^3.3.0",
"lint-staged": "^15.2.5",
"mjml-browser": "^4.15.3",
- "prettier": "3.3.3",
+ "prettier": "3.3.2",
"react-intersection-observer": "^9.10.3",
"sass": "^1.77.6",
"storybook": "^8.1.11",
@@ -106,7 +105,7 @@
"yaml": "^2.4.5"
},
"engines": {
- "node": "22.4.x",
+ "node": "22.3.x",
"npm": "10.8.x"
}
},
@@ -23834,10 +23833,11 @@
}
},
"node_modules/prettier": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
- "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
+ "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
"dev": true,
+ "license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -24312,6 +24312,7 @@
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.13.0.tgz",
"integrity": "sha512-y0UvBfjDiXqC8h0EWccyaj4dVBWMxgEx0t5RGNzQsvkfvZwugnKwxpu70StY4ivzYuMajavwUDjH4LJyIki9Lw==",
+ "dev": true,
"license": "MIT",
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
diff --git a/package.json b/package.json
index 72234a65788..ac5bfa839e6 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "Firefox Monitor",
"engines": {
- "node": "22.4.x",
+ "node": "22.3.x",
"npm": "10.8.x"
},
"type": "module",
@@ -11,7 +11,6 @@
"dev": "npm run build-nimbus && next dev --port=6060",
"dev:cron:first-data-broker-removal-fixed": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/firstDataBrokerRemovalFixed.tsx",
"dev:cron:monthly-activity": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/monthlyActivity.tsx",
- "dev:cron:breach-alerts": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/emailBreachAlerts.ts",
"dev:cron:db-delete-unverified-subscribers": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/deleteUnverifiedSubscribers.ts",
"dev:cron:db-pull-breaches": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/syncBreaches.ts",
"dev:cron:remote-settings-pull-breaches": "tsx --tsconfig tsconfig.cronjobs.json src/scripts/cronjobs/updateBreachesInRemoteSettings.ts",
@@ -28,7 +27,7 @@
"e2e:smoke": "playwright test src/e2e/ --grep @smoke",
"cron:first-data-broker-removal-fixed": "node dist/scripts/cronjobs/firstDataBrokerRemovalFixed.js",
"cron:monthly-activity": "node dist/scripts/cronjobs/monthlyActivity.js",
- "cron:breach-alerts": "node dist/scripts/cronjobs/emailBreachAlerts.js",
+ "cron:breach-alerts": "node src/scripts/emailBreachAlerts.js",
"cron:db-delete-unverified-subscribers": "node dist/scripts/cronjobs/deleteUnverifiedSubscribers.js",
"cron:db-pull-breaches": "node dist/scripts/cronjobs/syncBreaches.js",
"cron:remote-settings-pull-breaches": "node dist/scripts/cronjobs/updateBreachesInRemoteSettings.js",
@@ -57,8 +56,8 @@
"homepage": "https://github.com/mozilla/blurts-server",
"license": "MPL-2.0",
"volta": {
- "node": "22.4.1",
- "npm": "10.8.1"
+ "node": "22.3.0",
+ "npm": "10.8.0"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.614.0",
@@ -96,7 +95,6 @@
"react-aria": "^3.33.1",
"react-cookie": "^7.1.0",
"react-dom": "^18.2.0",
- "react-intersection-observer": "^9.13.0",
"react-stately": "^3.31.1",
"server-only": "^0.0.1",
"uuid": "^9.0.1",
@@ -105,13 +103,13 @@
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@playwright/test": "^1.43.1",
- "@storybook/addon-a11y": "^8.2.5",
- "@storybook/addon-actions": "^8.2.5",
- "@storybook/addon-essentials": "^8.2.5",
- "@storybook/addon-interactions": "^8.2.5",
- "@storybook/addon-links": "^8.2.5",
+ "@storybook/addon-a11y": "^8.2.2",
+ "@storybook/addon-actions": "^8.2.2",
+ "@storybook/addon-essentials": "^8.2.2",
+ "@storybook/addon-interactions": "^8.2.2",
+ "@storybook/addon-links": "^8.2.2",
"@storybook/blocks": "^8.0.0",
- "@storybook/nextjs": "^8.2.5",
+ "@storybook/nextjs": "^8.2.2",
"@storybook/react": "^8.0.0",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
@@ -146,7 +144,7 @@
"jest-fail-on-console": "^3.3.0",
"lint-staged": "^15.2.5",
"mjml-browser": "^4.15.3",
- "prettier": "3.3.3",
+ "prettier": "3.3.2",
"react-intersection-observer": "^9.10.3",
"sass": "^1.77.6",
"storybook": "^8.1.11",
From 4ea711820ee0741a0f5e1cd960192d6ac54d275f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 22 Jul 2024 15:42:07 +0000
Subject: [PATCH 135/137] chore(deps): bump winston from 3.13.0 to 3.13.1
Bumps [winston](https://github.com/winstonjs/winston) from 3.13.0 to 3.13.1.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.13.0...v3.13.1)
---
updated-dependencies:
- dependency-name: winston
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 10 +++++-----
package.json | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0fd204601df..06809b49497 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -47,7 +47,7 @@
"react-stately": "^3.31.1",
"server-only": "^0.0.1",
"uuid": "^9.0.1",
- "winston": "^3.13.0"
+ "winston": "^3.13.1"
},
"devDependencies": {
"@faker-js/faker": "^8.4.1",
@@ -28304,15 +28304,15 @@
}
},
"node_modules/winston": {
- "version": "3.13.0",
- "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz",
- "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==",
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.1.tgz",
+ "integrity": "sha512-SvZit7VFNvXRzbqGHsv5KSmgbEYR5EiQfDAL9gxYkRqa934Hnk++zze0wANKtMHcy/gI4W/3xmSDwlhf865WGw==",
"dependencies": {
"@colors/colors": "^1.6.0",
"@dabh/diagnostics": "^2.0.2",
"async": "^3.2.3",
"is-stream": "^2.0.0",
- "logform": "^2.4.0",
+ "logform": "^2.6.0",
"one-time": "^1.0.0",
"readable-stream": "^3.4.0",
"safe-stable-stringify": "^2.3.1",
diff --git a/package.json b/package.json
index d03150fccac..e45c082685f 100644
--- a/package.json
+++ b/package.json
@@ -99,7 +99,7 @@
"react-stately": "^3.31.1",
"server-only": "^0.0.1",
"uuid": "^9.0.1",
- "winston": "^3.13.0"
+ "winston": "^3.13.1"
},
"devDependencies": {
"@faker-js/faker": "^8.4.1",
From 3ddef11c3cfffac11462bd99ec17eb7af94ce4fb Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 22 Jul 2024 16:12:04 +0000
Subject: [PATCH 136/137] chore(deps): bump the sentry group with 3 updates
Bumps the sentry group with 3 updates: [@sentry/nextjs](https://github.com/getsentry/sentry-javascript), [@sentry/node](https://github.com/getsentry/sentry-javascript) and [@sentry/utils](https://github.com/getsentry/sentry-javascript).
Updates `@sentry/nextjs` from 8.18.0 to 8.19.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.18.0...8.19.0)
Updates `@sentry/node` from 8.18.0 to 8.19.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.18.0...8.19.0)
Updates `@sentry/utils` from 8.18.0 to 8.19.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.18.0...8.19.0)
---
updated-dependencies:
- dependency-name: "@sentry/nextjs"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: sentry
- dependency-name: "@sentry/node"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: sentry
- dependency-name: "@sentry/utils"
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: sentry
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 192 +++++++++++++++++++++++-----------------------
package.json | 2 +-
2 files changed, 97 insertions(+), 97 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index dcec0566781..af238ce75ae 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
"@leeoniya/ufuzzy": "^1.0.14",
"@mozilla/glean": "^5.0.2",
"@next/third-parties": "^14.2.5",
- "@sentry/nextjs": "^8.18.0",
+ "@sentry/nextjs": "^8.19.0",
"@sentry/node": "^8.0.0",
"@sentry/utils": "^8.0.0",
"@stripe/stripe-js": "^4.0.0",
@@ -6143,9 +6143,9 @@
}
},
"node_modules/@prisma/instrumentation": {
- "version": "5.16.1",
- "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-5.16.1.tgz",
- "integrity": "sha512-4m5gRFWnQb8s/yTyGbMZkL7A5uJgqOWcWJxapwcAD0T0kh5sGPEVSQl/zTQvE9aduXhFAxOtC3gO+R8Hb5xO1Q==",
+ "version": "5.17.0",
+ "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-5.17.0.tgz",
+ "integrity": "sha512-c1Sle4ji8aasMcYfBBHFM56We4ljfenVtRmS8aY06BllS7SoU6SmJBwG7vil+GHiR0Yrh+t9iBwt4AY0Jr4KNQ==",
"dependencies": {
"@opentelemetry/api": "^1.8",
"@opentelemetry/instrumentation": "^0.49 || ^0.50 || ^0.51 || ^0.52.0",
@@ -7643,54 +7643,54 @@
"integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA=="
},
"node_modules/@sentry-internal/browser-utils": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.18.0.tgz",
- "integrity": "sha512-1R7QXp7Gu6ovJGWvGjbgHcDcvDstsQba3miHtUCyDSH9kXtnAVLCAItDkseetFh+JLsjBXf3QFi2H3HPY4hRCw==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.19.0.tgz",
+ "integrity": "sha512-kM/2KlikKuBR63nFi2q7MGS3V9K9hakjvUknhr/jHZqDVfEuBKmp1ZlHFAdJtglKHHJy07gPj/XqDH7BbYh5yg==",
"dependencies": {
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/feedback": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.18.0.tgz",
- "integrity": "sha512-on6+4ZRkfdnsNgXecGQ6ME8aO26VTzkuM6y/kNN+bG2hSdxsmuU957B4x1Z5wEXiOWswuf3rhqGepg8JIdPkMQ==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.19.0.tgz",
+ "integrity": "sha512-Jc77H8fEaGcBhERc2U/o7Q8CZHvlZLT9vAlzq0ZZR20v/1vwYcJW1ysKfTuvmw22hCR6ukhFNl6pqJocXFVhvA==",
"dependencies": {
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.18.0.tgz",
- "integrity": "sha512-cCLib/HjD8UR0fB2F5hV6KsFBD6yTOEsi67RBllm5gT5vJt87VYoPliF6O7mmMNw8TWkQ0uc5laKld3q9ph+ug==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.19.0.tgz",
+ "integrity": "sha512-EW9e1J6XbqXUXQST1AfSIzT9O8OwPyeFOkhkn9/gqOQv08TJvQEIBtWJEoJS+XFMEUuB8IqIzVWNVko/DnGt9A==",
"dependencies": {
- "@sentry-internal/browser-utils": "8.18.0",
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry-internal/browser-utils": "8.19.0",
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.18.0.tgz",
- "integrity": "sha512-fcuLJBrhw3Ql8sU8veUgDCRYo6toQldFU807cpYphQ0uEw2oVZwNNPDQSu1651Ykvp0P/x+9hk/jjJxMohrO9g==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.19.0.tgz",
+ "integrity": "sha512-l4pKJDHrXEctxrK7Xme/+fKToXpGwr/G2t77BzeE1WEw9LwSwADz/hi8HoMdZzuKWriM2BNbz20tpVS84sODxA==",
"dependencies": {
- "@sentry-internal/replay": "8.18.0",
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry-internal/replay": "8.19.0",
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
@@ -7705,17 +7705,17 @@
}
},
"node_modules/@sentry/browser": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.18.0.tgz",
- "integrity": "sha512-E2w9u76JcjxcmgvroJrB7bcbG5oBCYI/pME1CtprBgZSS9mMYDsyBe6JKqGHdw2wvT3xNxNtkm7hf1O6+3NWUQ==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.19.0.tgz",
+ "integrity": "sha512-ZC1HxIFm4TIGONyy9MkPG6Dw8IAhzq43t5mq9PqrB1ehuWj8GX6Vk3E26kuc2sydAm4AXbj0562OmvZHsAJpUA==",
"dependencies": {
- "@sentry-internal/browser-utils": "8.18.0",
- "@sentry-internal/feedback": "8.18.0",
- "@sentry-internal/replay": "8.18.0",
- "@sentry-internal/replay-canvas": "8.18.0",
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry-internal/browser-utils": "8.19.0",
+ "@sentry-internal/feedback": "8.19.0",
+ "@sentry-internal/replay": "8.19.0",
+ "@sentry-internal/replay-canvas": "8.19.0",
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
@@ -7956,32 +7956,32 @@
}
},
"node_modules/@sentry/core": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.18.0.tgz",
- "integrity": "sha512-8moEMC3gp4W6mH9w5amb/zrYk6bNW8WGgcLRMCs5rguxny8YP5i8ISOJ0T0LP9x/RxSK/6xix5D2bzI/5ECzlw==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.19.0.tgz",
+ "integrity": "sha512-MrgjsZCEjOJgQjIznnDSrLEy7qL+4LVpNieAvr49cV1rzBNSwGmWRnt/puVaPsLyCUgupVx/43BPUHB/HtKNUw==",
"dependencies": {
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/nextjs": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/nextjs/-/nextjs-8.18.0.tgz",
- "integrity": "sha512-fmBFxaChOWHU/5Mo5X1ASxFVMF3ZjYImJhM+iLWKpw0Yuu9f9T6p8FPPQC2mPerxTX0yHUqTeVlhHufSPjZNEg==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/nextjs/-/nextjs-8.19.0.tgz",
+ "integrity": "sha512-WafL2zXKEp1jQJ0bC8H15zEUGT4m6bDiCwlaP8xAI3dz5E1e6f29OFlStvgzU3Tpx/Wi6qNTs5AGuwV3wK9qdg==",
"dependencies": {
"@opentelemetry/instrumentation-http": "0.52.1",
"@opentelemetry/semantic-conventions": "^1.25.1",
"@rollup/plugin-commonjs": "26.0.1",
- "@sentry/core": "8.18.0",
- "@sentry/node": "8.18.0",
- "@sentry/opentelemetry": "8.18.0",
- "@sentry/react": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0",
- "@sentry/vercel-edge": "8.18.0",
+ "@sentry/core": "8.19.0",
+ "@sentry/node": "8.19.0",
+ "@sentry/opentelemetry": "8.19.0",
+ "@sentry/react": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0",
+ "@sentry/vercel-edge": "8.19.0",
"@sentry/webpack-plugin": "2.20.1",
"chalk": "3.0.0",
"resolve": "1.22.8",
@@ -8019,13 +8019,13 @@
}
},
"node_modules/@sentry/nextjs/node_modules/@sentry/opentelemetry": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.18.0.tgz",
- "integrity": "sha512-P2OoXXJcU2RiRZmpBqOkK+NLGkwQrYizlOHl1zckHI1nYmQgOD1tcJj4c1xOYzH+eGPLp/IViXHO6vaBr8BGGg==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.19.0.tgz",
+ "integrity": "sha512-L1aSxO/aJJ7D3pIlTaVOgbiZJAnUHXezobTc8j5pqFCQACjxnLMSDrt53QfFV52CcjbliDWCYe4IB8umu4DgpA==",
"dependencies": {
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
@@ -8039,9 +8039,9 @@
}
},
"node_modules/@sentry/node": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/node/-/node-8.18.0.tgz",
- "integrity": "sha512-a+W477bmt28I1DT51xJKmp4Y7hBAdEGqQ2K7gfOn3mRBHoihuhKl2Xe8BMwFH7+v4mAEZEwAZBUOLAC7h+Tjig==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/node/-/node-8.19.0.tgz",
+ "integrity": "sha512-r7AeKxfB9eE/UW0NZT3AMh+hNA65NFEwtsMYO6iI52FPLFZh0DLOvzVOeNsmsJqPpyetooUGTtUYpBdinZldWA==",
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/context-async-hooks": "^1.25.1",
@@ -8065,11 +8065,11 @@
"@opentelemetry/resources": "^1.25.1",
"@opentelemetry/sdk-trace-base": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.25.1",
- "@prisma/instrumentation": "5.16.1",
- "@sentry/core": "8.18.0",
- "@sentry/opentelemetry": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@prisma/instrumentation": "5.17.0",
+ "@sentry/core": "8.19.0",
+ "@sentry/opentelemetry": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
@@ -8095,13 +8095,13 @@
}
},
"node_modules/@sentry/node/node_modules/@sentry/opentelemetry": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.18.0.tgz",
- "integrity": "sha512-P2OoXXJcU2RiRZmpBqOkK+NLGkwQrYizlOHl1zckHI1nYmQgOD1tcJj4c1xOYzH+eGPLp/IViXHO6vaBr8BGGg==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-8.19.0.tgz",
+ "integrity": "sha512-L1aSxO/aJJ7D3pIlTaVOgbiZJAnUHXezobTc8j5pqFCQACjxnLMSDrt53QfFV52CcjbliDWCYe4IB8umu4DgpA==",
"dependencies": {
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
@@ -8115,14 +8115,14 @@
}
},
"node_modules/@sentry/react": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.18.0.tgz",
- "integrity": "sha512-ckCKdxmeFdfR6moE/Aiq+cJyQuCUKoUqU/++xZwqVbgecuImsk4s7CzzpX9T6JoYK7jqru2SvuRSiwcdtLN6AQ==",
- "dependencies": {
- "@sentry/browser": "8.18.0",
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.19.0.tgz",
+ "integrity": "sha512-MzuMy4AEdSuIrBEyp3W7c4+v215+2MiU9ba7Y0KBKcC/Nrf1cGfRFRbjl9OYm/JIuxkaop7kgYs6sPMrVJVlrQ==",
+ "dependencies": {
+ "@sentry/browser": "8.19.0",
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0",
"hoist-non-react-statics": "^3.3.2"
},
"engines": {
@@ -8133,32 +8133,32 @@
}
},
"node_modules/@sentry/types": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.18.0.tgz",
- "integrity": "sha512-5J+uOqptnmAnW3Rk31AHIqW36Wzvlo3UOM+p2wjSYGrC/PgcE47Klzr+w4UcOhN6AZqefalGd3vaUXz9NaFdRg==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.19.0.tgz",
+ "integrity": "sha512-52C8X5V7mK2KIxMJt8MV5TxXAFHqrQR1RKm1oPTwKVWm8hKr1ZYJXINymNrWvpAc3oVIKLC/sa9WFYgXQh+YlA==",
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/utils": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.18.0.tgz",
- "integrity": "sha512-7wq7cgaeSIGJncl9/2VMu81ZN5ep4lp4H1/+O8+xUxOmnPb/05ZZcbn9/VxVQvIoqZSZdwCLPeBz6PEVukvokA==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.19.0.tgz",
+ "integrity": "sha512-8dWJJKaUN6Hf92Oxw2TBmHchGua2W3ZmonrZTTwLvl06jcAigbiQD0MGuF5ytZP8PHx860orV+SbTGKFzfU3Pg==",
"dependencies": {
- "@sentry/types": "8.18.0"
+ "@sentry/types": "8.19.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/vercel-edge": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/@sentry/vercel-edge/-/vercel-edge-8.18.0.tgz",
- "integrity": "sha512-V8jPZNWI93sf1u1sYLAg62oD7Jxw6uGT5bPPHBHbF2XmowW8sIyuXmkXYKVy+s6sOPCyJoW3/0j4BFf/qLowsg==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/@sentry/vercel-edge/-/vercel-edge-8.19.0.tgz",
+ "integrity": "sha512-I1G19SGWKcwUo1VT57xD/c/ZBnl8qkz6V+6j+vCbms4i0GTFw3eASnUIAOd25kc59/Wih2tUVj5mfV6aX5/DFg==",
"dependencies": {
- "@sentry/core": "8.18.0",
- "@sentry/types": "8.18.0",
- "@sentry/utils": "8.18.0"
+ "@sentry/core": "8.19.0",
+ "@sentry/types": "8.19.0",
+ "@sentry/utils": "8.19.0"
},
"engines": {
"node": ">=14.18"
diff --git a/package.json b/package.json
index 5af6960ec94..94dc65abd0c 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
"@leeoniya/ufuzzy": "^1.0.14",
"@mozilla/glean": "^5.0.2",
"@next/third-parties": "^14.2.5",
- "@sentry/nextjs": "^8.18.0",
+ "@sentry/nextjs": "^8.19.0",
"@sentry/node": "^8.0.0",
"@sentry/utils": "^8.0.0",
"@stripe/stripe-js": "^4.0.0",
From f969fad4498958d31767545c4c2585de3764ed4a Mon Sep 17 00:00:00 2001
From: Robert Helmer
Date: Mon, 22 Jul 2024 14:36:44 -0700
Subject: [PATCH 137/137] change OAUTH_ACCOUNT_URI to stage to match other
OAUTH defaults (#4850)
---
.env | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.env b/.env
index 06a5b7c2685..7e8de40d8ed 100755
--- a/.env
+++ b/.env
@@ -39,8 +39,7 @@ OAUTH_CLIENT_SECRET=get-this-from-groovecoder-or-fxmonitor-engineering
OAUTH_AUTHORIZATION_URI=https://oauth.stage.mozaws.net/v1/authorization
OAUTH_PROFILE_URI=https://profile.stage.mozaws.net/v1/profile
OAUTH_TOKEN_URI=https://oauth.stage.mozaws.net/v1/token
-OAUTH_ACCOUNT_URI = "https://oauth.accounts.firefox.com/v1"
-OAUTH_API_URI="https://api-accounts.stage.mozaws.net/v1"
+OAUTH_ACCOUNT_URI="https://api-accounts.stage.mozaws.net/v1"
# HIBP API for breach data
# How many seconds to wait before refreshing upstream breach data from HIBP