aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/main/src/stores/Profile.ts43
-rw-r--r--packages/main/src/stores/Service.ts5
-rw-r--r--packages/shared/src/stores/Profile.ts23
-rw-r--r--packages/shared/src/stores/ServiceBase.ts11
-rw-r--r--packages/shared/src/stores/__tests__/ServiceBase.test.ts23
5 files changed, 43 insertions, 62 deletions
diff --git a/packages/main/src/stores/Profile.ts b/packages/main/src/stores/Profile.ts
index b4343a0..73f4f0b 100644
--- a/packages/main/src/stores/Profile.ts
+++ b/packages/main/src/stores/Profile.ts
@@ -18,21 +18,40 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { Certificate, Profile as ProfileBase } from '@sophie/shared'; 21import {
22import { clone, getSnapshot, Instance } from 'mobx-state-tree'; 22 type Certificate,
23 type CertificateSnapshotIn,
24 Profile as ProfileBase,
25} from '@sophie/shared';
26import { getSnapshot, type Instance } from 'mobx-state-tree';
23 27
24import type ProfileConfig from './config/ProfileConfig.js'; 28import type ProfileConfig from './config/ProfileConfig.js';
25 29
26const Profile = ProfileBase.views((self) => ({ 30const Profile = ProfileBase.volatile(
27 get config(): ProfileConfig { 31 (): {
28 const { id, settings } = self; 32 temporarilyTrustedCertificates: string[];
29 return { ...getSnapshot(settings), id }; 33 } => ({
30 }, 34 temporarilyTrustedCertificates: [],
31})).actions((self) => ({ 35 }),
32 temporarilyTrustCertificate(certificate: Certificate): void { 36)
33 self.temporarilyTrustedCertificates.push(clone(certificate)); 37 .views((self) => ({
34 }, 38 get config(): ProfileConfig {
35})); 39 const { id, settings } = self;
40 return { ...getSnapshot(settings), id };
41 },
42 isCertificateTemporarilyTrusted(
43 certificate: CertificateSnapshotIn,
44 ): boolean {
45 return self.temporarilyTrustedCertificates.includes(
46 certificate.fingerprint,
47 );
48 },
49 }))
50 .actions((self) => ({
51 temporarilyTrustCertificate(certificate: Certificate): void {
52 self.temporarilyTrustedCertificates.push(certificate.fingerprint);
53 },
54 }));
36 55
37/* 56/*
38 eslint-disable-next-line @typescript-eslint/no-redeclare -- 57 eslint-disable-next-line @typescript-eslint/no-redeclare --
diff --git a/packages/main/src/stores/Service.ts b/packages/main/src/stores/Service.ts
index 3b7d0b2..d062fe1 100644
--- a/packages/main/src/stores/Service.ts
+++ b/packages/main/src/stores/Service.ts
@@ -67,6 +67,11 @@ const Service = defineServiceModel(ServiceSettings)
67 get shouldBeLoaded(): boolean { 67 get shouldBeLoaded(): boolean {
68 return !self.crashed; 68 return !self.crashed;
69 }, 69 },
70 isCertificateTemporarilyTrusted(
71 certificate: CertificateSnapshotIn,
72 ): boolean {
73 return self.settings.profile.isCertificateTemporarilyTrusted(certificate);
74 },
70 })) 75 }))
71 .views((self) => ({ 76 .views((self) => ({
72 get shouldBeVisible(): boolean { 77 get shouldBeVisible(): boolean {
diff --git a/packages/shared/src/stores/Profile.ts b/packages/shared/src/stores/Profile.ts
index 076c639..7d00925 100644
--- a/packages/shared/src/stores/Profile.ts
+++ b/packages/shared/src/stores/Profile.ts
@@ -18,28 +18,15 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { Instance, types } from 'mobx-state-tree'; 21import { type Instance, types } from 'mobx-state-tree';
22 22
23import Certificate, { CertificateSnapshotIn } from './Certificate.js';
24import ProfileSettings from './ProfileSettings.js'; 23import ProfileSettings from './ProfileSettings.js';
25 24
26const Profile = /* @__PURE__ */ (() => 25const Profile = /* @__PURE__ */ (() =>
27 types 26 types.model('Profile', {
28 .model('Profile', { 27 id: types.identifier,
29 id: types.identifier, 28 settings: ProfileSettings,
30 settings: ProfileSettings, 29 }))();
31 temporarilyTrustedCertificates: types.array(Certificate),
32 })
33 .views((self) => ({
34 isCertificateTemporarilyTrusted(
35 certificate: CertificateSnapshotIn,
36 ): boolean {
37 return self.temporarilyTrustedCertificates.some(
38 (trustedCertificate) =>
39 trustedCertificate.fingerprint === certificate.fingerprint,
40 );
41 },
42 })))();
43 30
44/* 31/*
45 eslint-disable-next-line @typescript-eslint/no-redeclare -- 32 eslint-disable-next-line @typescript-eslint/no-redeclare --
diff --git a/packages/shared/src/stores/ServiceBase.ts b/packages/shared/src/stores/ServiceBase.ts
index 7bd1d68..b2aff67 100644
--- a/packages/shared/src/stores/ServiceBase.ts
+++ b/packages/shared/src/stores/ServiceBase.ts
@@ -18,10 +18,8 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { IAnyModelType, Instance, types } from 'mobx-state-tree'; 21import { type IAnyModelType, type Instance, types } from 'mobx-state-tree';
22 22
23import type { CertificateSnapshotIn } from './Certificate.js';
24import type Profile from './Profile.js';
25import ServiceSettingsBase from './ServiceSettingsBase.js'; 23import ServiceSettingsBase from './ServiceSettingsBase.js';
26import ServiceState from './ServiceState.js'; 24import ServiceState from './ServiceState.js';
27 25
@@ -56,13 +54,6 @@ export function defineServiceModel<TS extends IAnyModelType>(settings: TS) {
56 get crashed(): boolean { 54 get crashed(): boolean {
57 return self.state.type === 'crashed'; 55 return self.state.type === 'crashed';
58 }, 56 },
59 isCertificateTemporarilyTrusted(
60 certificate: CertificateSnapshotIn,
61 ): boolean {
62 return (
63 self.settings.profile as Profile
64 ).isCertificateTemporarilyTrusted(certificate);
65 },
66 get securityLabel(): SecurityLabelKind { 57 get securityLabel(): SecurityLabelKind {
67 const { 58 const {
68 state: { type: stateType }, 59 state: { type: stateType },
diff --git a/packages/shared/src/stores/__tests__/ServiceBase.test.ts b/packages/shared/src/stores/__tests__/ServiceBase.test.ts
index e7aa078..e2b0aa9 100644
--- a/packages/shared/src/stores/__tests__/ServiceBase.test.ts
+++ b/packages/shared/src/stores/__tests__/ServiceBase.test.ts
@@ -66,14 +66,10 @@ const testCertificate: SnapshotIn<typeof Certificate> = {
66 66
67function createTestService( 67function createTestService(
68 snapshot: Partial<SnapshotIn<typeof ServiceBase>>, 68 snapshot: Partial<SnapshotIn<typeof ServiceBase>>,
69 profileSnapshot?: Partial<SnapshotIn<typeof Profile>>,
70): ServiceBase { 69): ServiceBase {
71 const sharedStore = SharedStoreBase.create({ 70 const sharedStore = SharedStoreBase.create({
72 profilesById: { 71 profilesById: {
73 testProfile: { 72 testProfile,
74 ...testProfile,
75 ...profileSnapshot,
76 },
77 }, 73 },
78 servicesById: { 74 servicesById: {
79 testService: { 75 testService: {
@@ -187,20 +183,3 @@ test('shows a certificate error warning if there is a certificate error', () =>
187 expect(service.securityLabel).toBe(SecurityLabelKind.CertificateError); 183 expect(service.securityLabel).toBe(SecurityLabelKind.CertificateError);
188 expect(service.alwaysShowLocationBar).toBe(true); 184 expect(service.alwaysShowLocationBar).toBe(true);
189}); 185});
190
191test('does not trust an untrusted certificate', () => {
192 const service = createTestService({});
193
194 expect(service.isCertificateTemporarilyTrusted(testCertificate)).toBe(false);
195});
196
197test('trusts a trusted certificate', () => {
198 const service = createTestService(
199 {},
200 {
201 temporarilyTrustedCertificates: [testCertificate],
202 },
203 );
204
205 expect(service.isCertificateTemporarilyTrusted(testCertificate)).toBe(true);
206});