aboutsummaryrefslogtreecommitdiffstats
path: root/packages/main/src/stores
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-04-22 00:53:48 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-05-16 00:55:02 +0200
commit1184eb13f0bbe4768bf3dbd6cd31adf10c6c8dfe (patch)
tree78e6c699d8a232c948b40f643299f7af95a29215 /packages/main/src/stores
parentfeat(renderer): Insecure connection warning (diff)
downloadsophie-1184eb13f0bbe4768bf3dbd6cd31adf10c6c8dfe.tar.gz
sophie-1184eb13f0bbe4768bf3dbd6cd31adf10c6c8dfe.tar.zst
sophie-1184eb13f0bbe4768bf3dbd6cd31adf10c6c8dfe.zip
feat: Certificate viewer
Show certificates with an interface modeled after firefox's certificate viewer so that they can be inspected before trusting. The current implementation assumes that each certificate has a unique fingerprint (collisions are astronomically unlikely). Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/main/src/stores')
-rw-r--r--packages/main/src/stores/MainEnv.ts2
-rw-r--r--packages/main/src/stores/Service.ts41
2 files changed, 40 insertions, 3 deletions
diff --git a/packages/main/src/stores/MainEnv.ts b/packages/main/src/stores/MainEnv.ts
index 8923322..f9dc209 100644
--- a/packages/main/src/stores/MainEnv.ts
+++ b/packages/main/src/stores/MainEnv.ts
@@ -28,4 +28,6 @@ export default interface MainEnv {
28 openURLInExternalBrowser(url: string): void; 28 openURLInExternalBrowser(url: string): void;
29 29
30 openAboutDialog(): void; 30 openAboutDialog(): void;
31
32 saveTextFile(filename: string, value: string): Promise<void>;
31} 33}
diff --git a/packages/main/src/stores/Service.ts b/packages/main/src/stores/Service.ts
index d8f3166..1d46dc9 100644
--- a/packages/main/src/stores/Service.ts
+++ b/packages/main/src/stores/Service.ts
@@ -20,12 +20,13 @@
20 20
21import type { UnreadCount } from '@sophie/service-shared'; 21import type { UnreadCount } from '@sophie/service-shared';
22import { 22import {
23 CertificateSnapshotIn, 23 type Certificate,
24 type CertificateSnapshotIn,
24 defineServiceModel, 25 defineServiceModel,
25 ServiceAction, 26 ServiceAction,
26 ServiceStateSnapshotIn, 27 type ServiceStateSnapshotIn,
27} from '@sophie/shared'; 28} from '@sophie/shared';
28import { Instance, getSnapshot, cast } from 'mobx-state-tree'; 29import { type Instance, getSnapshot, cast, flow } from 'mobx-state-tree';
29 30
30import type { ServiceView } from '../infrastructure/electron/types'; 31import type { ServiceView } from '../infrastructure/electron/types';
31import { getLogger } from '../utils/log'; 32import { getLogger } from '../utils/log';
@@ -129,6 +130,35 @@ const Service = defineServiceModel(ServiceSettings)
129 toggleDeveloperTools(): void { 130 toggleDeveloperTools(): void {
130 self.serviceView?.toggleDeveloperTools(); 131 self.serviceView?.toggleDeveloperTools();
131 }, 132 },
133 downloadCertificate: flow(function* downloadCertificate(
134 fingerprint: string,
135 ) {
136 const { state } = self;
137 if (state.type !== 'certificateError') {
138 log.warn(
139 'Tried to save certificate',
140 fingerprint,
141 'when there is no certificate error',
142 );
143 return;
144 }
145 let { certificate } = state;
146 while (
147 certificate !== undefined &&
148 certificate.fingerprint !== fingerprint
149 ) {
150 certificate = certificate.issuerCert as Certificate;
151 }
152 if (certificate === undefined) {
153 log.warn(
154 'Tried to save certificate',
155 fingerprint,
156 'which is not part of the current certificate chain',
157 );
158 return;
159 }
160 yield getEnv(self).saveTextFile('certificate.pem', certificate.data);
161 }),
132 })) 162 }))
133 .actions((self) => { 163 .actions((self) => {
134 function setState(state: ServiceStateSnapshotIn): void { 164 function setState(state: ServiceStateSnapshotIn): void {
@@ -272,6 +302,11 @@ const Service = defineServiceModel(ServiceSettings)
272 case 'dismiss-all-popups': 302 case 'dismiss-all-popups':
273 self.dismissAllPopups(); 303 self.dismissAllPopups();
274 break; 304 break;
305 case 'download-certificate':
306 self.downloadCertificate(action.fingerprint).catch((error) => {
307 log.error('Error while saving certificate', error);
308 });
309 break;
275 default: 310 default:
276 log.error('Unknown action to dispatch', action); 311 log.error('Unknown action to dispatch', action);
277 break; 312 break;