Skip to content

Commit 749baba

Browse files
authored
Fixing implicit invalid certs (#363)
* certs: wait for cert info on macos/ios * lint * skipping some until router is fixed
1 parent b18a052 commit 749baba

File tree

11 files changed

+245
-29
lines changed

11 files changed

+245
-29
lines changed

integration-tests/android.spec-int.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ test.describe('breakage form', () => {
227227
await dash.screenshot('screen-breakage-form-empty-description.png');
228228
});
229229

230-
test('submits form with description', { tag: '@screenshots' }, async ({ page }) => {
230+
test.skip('submits form with description', { tag: '@screenshots' }, async ({ page }) => {
231231
/** @type {DashboardPage} */
232232
const dash = await DashboardPage.android(page, { screen: 'breakageForm' });
233233
await dash.reducedMotion();

integration-tests/windows.spec-int.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ test.describe('breakage form', () => {
114114
await dash.screenshot('screen-breakage-form-empty-description.png');
115115
});
116116

117-
test('submits form with description', { tag: '@screenshots' }, async ({ page }) => {
117+
test.skip('submits form with description', { tag: '@screenshots' }, async ({ page }) => {
118118
/** @type {DashboardPage} */
119119
const dash = await DashboardPage.windows(page, { screen: 'breakageForm' });
120120
await dash.reducedMotion();

schema/__generated__/schema.parsers.mjs

Lines changed: 31 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

schema/__generated__/schema.types.ts

Lines changed: 75 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

schema/api.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
},
4444
"extension-outgoing": {
4545
"$ref": "extension-outgoing.json"
46+
},
47+
"cert-data": {
48+
"$ref": "cert-data.json"
4649
}
4750
}
4851
}

schema/cert-data.json

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "CertData",
4+
"type": "object",
5+
"description": "",
6+
"required": ["secCertificateViewModels", "isInvalidCert"],
7+
"additionalProperties": false,
8+
"properties": {
9+
"secCertificateViewModels": {
10+
"type": "array",
11+
"items": {
12+
"$ref": "#/definitions/SecCertificateViewModel"
13+
}
14+
},
15+
"isInvalidCert": {
16+
"type": "boolean",
17+
"description": "`true` if the certificate is missing or invalid"
18+
}
19+
},
20+
"definitions": {
21+
"SecCertificateViewModel": {
22+
"title": "SecCertificateViewModel",
23+
"type": "object",
24+
"properties": {
25+
"summary": {
26+
"type": "string"
27+
},
28+
"commonName": {
29+
"type": "string"
30+
},
31+
"emails": {
32+
"type": "array",
33+
"items": {
34+
"type": "string"
35+
}
36+
},
37+
"publicKey": {
38+
"$ref": "#/definitions/SecKeyViewModel"
39+
}
40+
}
41+
},
42+
"SecKeyViewModel": {
43+
"title": "SecKeyViewModel",
44+
"description": "A model representing a SecKey with its properties and capabilities",
45+
"type": "object",
46+
"properties": {
47+
"keyId": {
48+
"type": ["string", "null"],
49+
"description": "Base64 encoded representation of the application label data"
50+
},
51+
"externalRepresentation": {
52+
"type": ["string", "null"],
53+
"description": "Base64 encoded external representation of the key"
54+
},
55+
"bitSize": {
56+
"type": ["integer", "null"],
57+
"description": "Size of the key in bits"
58+
},
59+
"blockSize": {
60+
"type": ["integer", "null"],
61+
"description": "Block size of the key"
62+
},
63+
"effectiveSize": {
64+
"type": ["integer", "null"],
65+
"description": "Effective size of the key in bits"
66+
},
67+
"canDecrypt": {
68+
"type": "boolean",
69+
"description": "Whether the key can be used for decryption"
70+
},
71+
"canDerive": {
72+
"type": "boolean",
73+
"description": "Whether the key can be used for key derivation"
74+
},
75+
"canEncrypt": {
76+
"type": "boolean",
77+
"description": "Whether the key can be used for encryption"
78+
},
79+
"canSign": {
80+
"type": "boolean",
81+
"description": "Whether the key can be used for signing"
82+
},
83+
"canUnwrap": {
84+
"type": "boolean",
85+
"description": "Whether the key can be used for unwrapping another key"
86+
},
87+
"canVerify": {
88+
"type": "boolean",
89+
"description": "Whether the key can be used for verification"
90+
},
91+
"canWrap": {
92+
"type": "boolean",
93+
"description": "Whether the key can be used for wrapping another key"
94+
},
95+
"isPermanent": {
96+
"type": ["boolean", "null"],
97+
"description": "Whether the key is stored permanently in the keychain"
98+
},
99+
"type": {
100+
"type": ["string", "null"],
101+
"description": "Type of the key (RSA, Elliptic Curve, etc.)",
102+
"enum": ["RSA", "Elliptic Curve", "Elliptic Curve (Prime Random)", null]
103+
}
104+
},
105+
"required": ["canDecrypt", "canDerive", "canEncrypt", "canSign", "canUnwrap", "canVerify", "canWrap"]
106+
}
107+
}
108+
}

shared/js/browser/macos-communication.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515
import invariant from 'tiny-invariant';
1616
import {
17+
certDataSchema,
1718
cookiePromptManagementStatusSchema,
1819
localeSettingsSchema,
1920
maliciousSiteStatusSchema,
@@ -55,7 +56,12 @@ const backgroundMessage = (backgroundModel) => {
5556
const getBackgroundTabDataPromises = [];
5657
let trackerBlockingData;
5758
let permissionsData;
59+
60+
/** @type {import('../../../schema/__generated__/schema.types').SecCertificateViewModel[]} */
5861
let certificateData;
62+
/** @type {null|boolean} */
63+
let isInvalidCert = null;
64+
5965
let upgradedHttps;
6066
/** @type {import("./utils/protections.mjs").Protections | undefined} */
6167
let protections;
@@ -80,6 +86,7 @@ const combineSources = () => ({
8086
cookiePromptManagementStatus,
8187
platformLimitations: true,
8288
locale,
89+
isInvalidCert,
8390
},
8491
permissionsData ? { permissions: permissionsData } : {},
8592
certificateData ? { certificate: certificateData } : {}
@@ -92,6 +99,9 @@ const resolveInitialRender = function () {
9299
const isTrackerBlockingDataSet = typeof trackerBlockingData === 'object';
93100
const isLocaleSet = typeof locale === 'string';
94101
const isMaliciousSiteSet = maliciousSiteStatus && maliciousSiteStatus.kind !== undefined;
102+
103+
// wait for cert info
104+
if (isInvalidCert === null) return console.log('isInvalidCert was not ready');
95105
if (!isLocaleSet || !isUpgradedHttpsSet || !isIsProtectedSet || !isTrackerBlockingDataSet || !isMaliciousSiteSet) {
96106
return;
97107
}
@@ -563,7 +573,16 @@ export function setupShared() {
563573
window.onChangeProtectionStatus = onChangeProtectionStatus;
564574
window.onChangeLocale = onChangeLocale;
565575
window.onChangeCertificateData = function (data) {
566-
certificateData = data.secCertificateViewModels;
576+
const parsed = certDataSchema.safeParse(data);
577+
if (!parsed.success) {
578+
console.error('could not parse incoming data from onChangeCertificateData');
579+
console.error(parsed.error);
580+
certificateData = [];
581+
isInvalidCert = false;
582+
return;
583+
}
584+
certificateData = parsed.data.secCertificateViewModels;
585+
isInvalidCert = parsed.data.isInvalidCert;
567586
channel?.send('updateTabData');
568587
};
569588
window.onIsPendingUpdates = function (data) {

shared/js/browser/utils/communication-mocks.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export function sharedMockDataProvider(params) {
4444
window.onChangeUpgradedHttps(state.upgradedHttps);
4545
window.onChangeCertificateData({
4646
secCertificateViewModels: state.certificate,
47+
isInvalidCert: state.isInvalidCert,
4748
});
4849
if (state.remoteFeatureSettings) {
4950
window.onChangeFeatureSettings?.(state.remoteFeatureSettings);

shared/js/ui/platform-features.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function createPlatformFeatures(platform) {
5555
supportsHover: desktop.includes(platform.name),
5656
initialScreen: screen,
5757
opener,
58-
supportsInvalidCertsImplicitly: platform.name !== 'browser' && platform.name !== 'windows',
58+
supportsInvalidCertsImplicitly: platform.name === 'android',
5959
supportsMaliciousSiteWarning:
6060
platform.name === 'macos' || platform.name === 'ios' || platform.name === 'android' || platform.name === 'windows',
6161
includeToggleOnBreakageForm,

shared/js/ui/templates/page-non-trackers.js

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,8 @@
11
import html from 'nanohtml';
22
import { ns } from '../base/localize.js';
33
import { states } from '../../browser/utils/request-details.mjs';
4-
import { heroFromTabNonTrackers } from './shared/hero.js';
54
import { renderSections } from './page-trackers.js';
65
import { adAttributionLink } from './shared/links';
7-
import { platformLimitations } from './shared/platform-limitations';
8-
import { topNav } from './shared/top-nav';
9-
10-
/** @this {{ model: { site: import('../models/site.js').PublicSiteModel }}} */
11-
export function nonTrackersTemplate() {
12-
if (!this.model) {
13-
return html`<section class="sliding-subview"></section>`;
14-
}
15-
16-
const sections = sectionsFromSiteNonTracker(this.model.site);
17-
const hero = heroFromTabNonTrackers(this.model.site.tab.requestDetails, this.model.site.protectionsEnabled);
18-
const limitations = this.model.site.tab.platformLimitations
19-
? html`<div class="padding-x-double">${platformLimitations()}</div>`
20-
: html`<div></div>`;
21-
22-
return html` <div class="site-info card page-inner" data-page="non-trackers">
23-
${topNav({ view: 'secondary' })}
24-
<div class="padding-x-double js-tracker-networks-hero">${hero}</div>
25-
<div class="padding-x-double js-tracker-networks-details">${sections}</div>
26-
${limitations}
27-
</div>`;
28-
}
296

307
/**
318
* @param {import('../models/site.js').PublicSiteModel} site

0 commit comments

Comments
 (0)