diff options
Diffstat (limited to 'packages')
-rw-r--r-- | packages/main/src/stores/Profile.ts | 43 | ||||
-rw-r--r-- | packages/main/src/stores/Service.ts | 5 | ||||
-rw-r--r-- | packages/shared/src/stores/Profile.ts | 23 | ||||
-rw-r--r-- | packages/shared/src/stores/ServiceBase.ts | 11 | ||||
-rw-r--r-- | packages/shared/src/stores/__tests__/ServiceBase.test.ts | 23 |
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 | ||
21 | import { Certificate, Profile as ProfileBase } from '@sophie/shared'; | 21 | import { |
22 | import { clone, getSnapshot, Instance } from 'mobx-state-tree'; | 22 | type Certificate, |
23 | type CertificateSnapshotIn, | ||
24 | Profile as ProfileBase, | ||
25 | } from '@sophie/shared'; | ||
26 | import { getSnapshot, type Instance } from 'mobx-state-tree'; | ||
23 | 27 | ||
24 | import type ProfileConfig from './config/ProfileConfig.js'; | 28 | import type ProfileConfig from './config/ProfileConfig.js'; |
25 | 29 | ||
26 | const Profile = ProfileBase.views((self) => ({ | 30 | const 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 | ||
21 | import { Instance, types } from 'mobx-state-tree'; | 21 | import { type Instance, types } from 'mobx-state-tree'; |
22 | 22 | ||
23 | import Certificate, { CertificateSnapshotIn } from './Certificate.js'; | ||
24 | import ProfileSettings from './ProfileSettings.js'; | 23 | import ProfileSettings from './ProfileSettings.js'; |
25 | 24 | ||
26 | const Profile = /* @__PURE__ */ (() => | 25 | const 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 | ||
21 | import { IAnyModelType, Instance, types } from 'mobx-state-tree'; | 21 | import { type IAnyModelType, type Instance, types } from 'mobx-state-tree'; |
22 | 22 | ||
23 | import type { CertificateSnapshotIn } from './Certificate.js'; | ||
24 | import type Profile from './Profile.js'; | ||
25 | import ServiceSettingsBase from './ServiceSettingsBase.js'; | 23 | import ServiceSettingsBase from './ServiceSettingsBase.js'; |
26 | import ServiceState from './ServiceState.js'; | 24 | import 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 | ||
67 | function createTestService( | 67 | function 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 | |||
191 | test('does not trust an untrusted certificate', () => { | ||
192 | const service = createTestService({}); | ||
193 | |||
194 | expect(service.isCertificateTemporarilyTrusted(testCertificate)).toBe(false); | ||
195 | }); | ||
196 | |||
197 | test('trusts a trusted certificate', () => { | ||
198 | const service = createTestService( | ||
199 | {}, | ||
200 | { | ||
201 | temporarilyTrustedCertificates: [testCertificate], | ||
202 | }, | ||
203 | ); | ||
204 | |||
205 | expect(service.isCertificateTemporarilyTrusted(testCertificate)).toBe(true); | ||
206 | }); | ||