Skip to content

Commit

Permalink
Malware schema update
Browse files Browse the repository at this point in the history
  • Loading branch information
mgurgel committed Dec 2, 2024
1 parent e1ec133 commit 6c6fe47
Show file tree
Hide file tree
Showing 35 changed files with 326 additions and 118 deletions.
5 changes: 0 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,5 @@ let package = Package(
.copy("app/img"),
.copy ("app/public"),
.copy ("app/index.html")]),

.testTarget(
name: "PrivacyDashboardTests",
dependencies: ["PrivacyDashboardResources"],
path: "swift-package/Tests"),
]
)
22 changes: 22 additions & 0 deletions integration-tests/DashboardPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,28 @@ export class DashboardPage {
await expect(page.locator('#main-nav div')).toContainText('Site May Be Deceptive');
}

async hasMalwareIcon() {
const { page } = this;
await expect(page.locator('#key-insight div').nth(1)).toHaveClass(/hero-icon--phishing/);
}

async hasMalwareHeadingText() {
const { page } = this;
await expect(page.getByRole('heading', { name: 'privacy-test-pages.site' })).toBeVisible();
}

async hasMalwareWarningText() {
const { page } = this;
await expect(page.locator('#popup-container')).toContainText(
'This site has been flagged for distributing malware designed to compromise your device or steal your personal information.'
);
}

async hasMalwareStatusText() {
const { page } = this;
await expect(page.locator('#main-nav div')).toContainText('Site May Be Deceptive');
}

async connectionLinkDoesntShow() {
await expect(this.connectInfoLink()).not.toBeVisible();
}
Expand Down
12 changes: 12 additions & 0 deletions integration-tests/macos.spec-int.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ test('phishing warning', { tag: '@screenshots' }, async ({ page }) => {
await dash.connectionLinkDoesntShow();
});

test('malware warning', { tag: '@screenshots' }, async ({ page }) => {
/** @type {DashboardPage} */
const dash = await DashboardPage.webkit(page, { platform: 'macos' });
await dash.addState([testDataStates.malware]);
await dash.screenshot('malware-warning.png');
await dash.hasMalwareIcon();
await dash.hasMalwareHeadingText();
await dash.hasMalwareWarningText();
await dash.hasMalwareStatusText();
await dash.connectionLinkDoesntShow();
});

test('insecure certificate', async ({ page }) => {
/** @type {DashboardPage} */
const dash = await DashboardPage.webkit(page, { platform: 'macos' });
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions schema/__generated__/schema.parsers.mjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions schema/__generated__/schema.types.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions schema/get-privacy-dashboard-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
"localeSettings": {
"$ref": "./locale.json"
},
"phishingStatus": {
"$ref": "./phishing.json"
"maliciousSiteStatus": {
"$ref": "./malicious-site.json"
},
"parentEntity": { "$ref": "./parent-entity.json" },
"specialDomainName": {
Expand Down
14 changes: 14 additions & 0 deletions schema/malicious-site.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "MaliciousSiteStatus",
"type": "object",
"description": "This describes the payload required to set the phishing & malware status",
"additionalProperties": false,
"required": ["kind"],
"properties": {
"kind": {
"description": "Kind of threat detected",
"enum": ["phishing", "malware", null]
}
}
}
14 changes: 0 additions & 14 deletions schema/phishing.json

This file was deleted.

3 changes: 3 additions & 0 deletions schema/windows-view-model.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
},
"localeSettings": {
"$ref": "locale.json"
},
"maliciousSiteStatus": {
"$ref": "malicious-site.json"
}
}
}
6 changes: 6 additions & 0 deletions shared/data/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ export const httpsMessages = {
none: 'site:connectionNotSecure.title',
invalid: 'site:connectionNotSecureInvalidCertificate.title',
phishing: 'site:phishingWebsite.title',
malware: 'site:malwareWebsite.title',
};

export const duckDuckGoURLs = {
phishingAndMalwareHelpPage: 'https://dub.duckduckgo.com/pages/duckduckgo/mgurgel-help-pages/privacy/phishing-and-malware-protection/',
reportSiteAsSafeForm: 'https://use-devtesting12.duckduckgo.com/malicious-site-protection/report-error?url=',
};
31 changes: 30 additions & 1 deletion shared/js/browser/android-communication.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
protectionsStatusSchema,
remoteFeatureSettingsSchema,
requestDataSchema,
maliciousSiteStatusSchema,
} from '../../../schema/__generated__/schema.parsers.mjs';
import { setupBlurOnLongPress, setupGlobalOpenerListener } from '../ui/views/utils/utils';
import {
Expand Down Expand Up @@ -52,10 +53,14 @@ let locale;
/** @type {import('../../../schema/__generated__/schema.types').RemoteFeatureSettings | undefined} */
let featureSettings;

/** @type {import('../../../schema/__generated__/schema.types').MaliciousSiteStatus} */
let maliciousSiteStatus;

const combineSources = () => ({
tab: Object.assign(
{},
trackerBlockingData || {},
{ maliciousSiteStatus: maliciousSiteStatus ?? false },
{
isPendingUpdates,
parentEntity,
Expand All @@ -73,7 +78,8 @@ const resolveInitialRender = function () {
const isIsProtectedSet = typeof protections !== 'undefined';
const isTrackerBlockingDataSet = typeof trackerBlockingData === 'object';
const isLocaleSet = typeof locale === 'string';
if (!isLocaleSet || !isUpgradedHttpsSet || !isIsProtectedSet || !isTrackerBlockingDataSet) {
const isMaliciousSiteSet = maliciousSiteStatus && maliciousSiteStatus.kind !== undefined;
if (!isLocaleSet || !isUpgradedHttpsSet || !isIsProtectedSet || !isTrackerBlockingDataSet || !isMaliciousSiteSet) {
return;
}

Expand Down Expand Up @@ -177,6 +183,28 @@ export function onChangeLocale(payload) {
channel?.send('updateTabData', { via: 'onChangeLocale' });
}

/**
* {@inheritDoc common.onChangeMaliciousSiteStatus}
* @type {import("./common.js").onChangeMaliciousSiteStatus}
* @group macOS -> JavaScript Interface
* @example
*
* ```swift
* // swift
* evaluate(js: "window.onChangeMaliciousSiteStatus(\(maliciousSiteStatusJsonString))", in: webView)
* ```
*/
export function onChangeMaliciousSiteStatus(payload) {
const parsed = maliciousSiteStatusSchema.safeParse(payload);
if (!parsed.success) {
console.error('could not parse incoming data from onChangeMaliciousSiteStatus');
console.error(parsed.error);
return;
}
maliciousSiteStatus = parsed.data;
resolveInitialRender();
}

/**
* {@inheritDoc common.onChangeFeatureSettings}
* @type {import("./common.js").onChangeFeatureSettings}
Expand Down Expand Up @@ -477,6 +505,7 @@ export function setup(debug) {
};
window.onChangeProtectionStatus = onChangeProtectionStatus;
window.onChangeLocale = onChangeLocale;
window.onChangeMaliciousSiteStatus = onChangeMaliciousSiteStatus;
window.onChangeRequestData = onChangeRequestData;
window.onChangeConsentManaged = onChangeConsentManaged;
window.onChangeFeatureSettings = onChangeFeatureSettings;
Expand Down
10 changes: 5 additions & 5 deletions shared/js/browser/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,19 +160,19 @@ export function assert(condition, message = '') {
export function onChangeLocale(payload) {}

/**
* Sets the phishing status for a page. This is a required call.
* Sets the phishing & malware status for a page. This is a required call.
*
* Example Payload: see {@link "Generated Schema Definitions".PhishingStatus}
* Example Payload: see {@link "Generated Schema Definitions".MaliciousSiteStatus}
*
* ```json
* {
* "phishingStatus": true
* "kind": "phishing"
* }
* ```
*
* @param {import('../../../schema/__generated__/schema.types').PhishingStatus} payload
* @param {import('../../../schema/__generated__/schema.types').MaliciousSiteStatus} payload
*/
export function onChangePhishingStatus(payload) {}
export function onChangeMaliciousSiteStatus(payload) {}

/**
* Sets the Feature Settings
Expand Down
28 changes: 14 additions & 14 deletions shared/js/browser/macos-communication.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import invariant from 'tiny-invariant';
import {
cookiePromptManagementStatusSchema,
localeSettingsSchema,
phishingStatusSchema,
maliciousSiteStatusSchema,
protectionsStatusSchema,
requestDataSchema,
toggleReportScreenSchema,
Expand Down Expand Up @@ -61,8 +61,8 @@ let isPendingUpdates;
let parentEntity;
const cookiePromptManagementStatus = {};

/** @type {boolean | undefined} */
let phishingStatus;
/** @type {import('../../../schema/__generated__/schema.types').MaliciousSiteStatus} */
let maliciousSiteStatus;

/** @type {string | undefined} */
let locale;
Expand All @@ -71,7 +71,7 @@ const combineSources = () => ({
tab: Object.assign(
{},
trackerBlockingData || {},
{ phishingStatus: phishingStatus ?? false },
{ maliciousSiteStatus: maliciousSiteStatus ?? false },
{
isPendingUpdates,
parentEntity,
Expand All @@ -89,8 +89,8 @@ const resolveInitialRender = function () {
const isIsProtectedSet = typeof protections !== 'undefined';
const isTrackerBlockingDataSet = typeof trackerBlockingData === 'object';
const isLocaleSet = typeof locale === 'string';
const isPhishingSet = typeof phishingStatus === 'boolean';
if (!isLocaleSet || !isUpgradedHttpsSet || !isIsProtectedSet || !isTrackerBlockingDataSet || !isPhishingSet) {
const isMaliciousSiteSet = maliciousSiteStatus && maliciousSiteStatus.kind !== undefined;
if (!isLocaleSet || !isUpgradedHttpsSet || !isIsProtectedSet || !isTrackerBlockingDataSet || !isMaliciousSiteSet) {
return;
}
getBackgroundTabDataPromises.forEach((resolve) => resolve(combineSources()));
Expand Down Expand Up @@ -178,24 +178,24 @@ export function onChangeLocale(payload) {
}

/**
* {@inheritDoc common.onChangePhishingStatus}
* @type {import("./common.js").onChangePhishingStatus}
* {@inheritDoc common.onChangeMaliciousSiteStatus}
* @type {import("./common.js").onChangeMaliciousSiteStatus}
* @group macOS -> JavaScript Interface
* @example
*
* ```swift
* // swift
* evaluate(js: "window.onChangePhishingStatus(\(phishingStatusJsonString))", in: webView)
* evaluate(js: "window.onChangeMaliciousSiteStatus(\(maliciousSiteStatusJsonString))", in: webView)
* ```
*/
export function onChangePhishingStatus(payload) {
const parsed = phishingStatusSchema.safeParse(payload);
export function onChangeMaliciousSiteStatus(payload) {
const parsed = maliciousSiteStatusSchema.safeParse(payload);
if (!parsed.success) {
console.error('could not parse incoming data from onChangePhishingStatus');
console.error('could not parse incoming data from onChangeMaliciousSiteStatus');
console.error(parsed.error);
return;
}
phishingStatus = parsed.data.phishingStatus;
maliciousSiteStatus = parsed.data;
resolveInitialRender();
}

Expand Down Expand Up @@ -537,7 +537,7 @@ export function setupShared() {
if (trackerBlockingData) trackerBlockingData.upgradedHttps = upgradedHttps;
resolveInitialRender();
};
window.onChangePhishingStatus = onChangePhishingStatus;
window.onChangeMaliciousSiteStatus = onChangeMaliciousSiteStatus;
window.onChangeProtectionStatus = onChangeProtectionStatus;
window.onChangeLocale = onChangeLocale;
window.onChangeCertificateData = function (data) {
Expand Down
2 changes: 1 addition & 1 deletion shared/js/browser/utils/communication-mocks.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export async function mockDataProvider(params) {
}
window.onChangeLocale?.(state.localeSettings);
window.onChangeRequestData(state.url, { requests: state.requests || [] });
window.onChangePhishingStatus?.(state.phishing);
window.onChangeMaliciousSiteStatus?.(state.maliciousSiteStatus);
}

export function windowsMockApis() {
Expand Down
Loading

0 comments on commit 6c6fe47

Please sign in to comment.