Skip to content

Commit 963a2e6

Browse files
author
stephanbuettig
committed
merge: resolve conflict with upstream/main in multi-selection-summary-pane
Upstream refactored the class component to a functional component. Adapted ZIP export features (dialog state, export button, ZipExportDialog) to the new functional component pattern using React.useState instead of MobX @observable/@action decorators. PinIcon uses upstream's styled(Icon) .attrs() approach.
2 parents fbd57d4 + 4dab2fc commit 963a2e6

23 files changed

Lines changed: 1798 additions & 1255 deletions

package-lock.json

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

src/components/account/login-modal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const Modal = styled.dialog`
1616
top: 50%;
1717
left: 50%;
1818
transform: translate(-50%, -50%);
19-
z-index: 100;
19+
z-index: 1000;
2020
margin: 0;
2121
2222
width: auto;

src/components/account/modal-overlay.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const ModalOverlay = styled.div<{ opacity?: number }>`
1010
1111
background: ${p => p.theme.modalGradient};
1212
13-
z-index: 10;
13+
z-index: 90;
1414
opacity: ${p => p.opacity || 0.9};
1515
`;
1616

src/components/account/pro-placeholders.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,15 @@ const OverlayGetProButton = styled(GetProButton)`
115115

116116
@observer
117117
export class GetProOverlay extends React.Component<{
118+
className?: string,
118119
getPro: (source: string) => void,
119120
source: string,
120121
children: React.ReactNode
121122
}> {
122123
private buttonRef = React.createRef<HTMLButtonElement>();
123124

124125
render() {
125-
return <OverlayContainer>
126+
return <OverlayContainer className={this.props.className}>
126127
<OverlayGetProButton
127128
ref={this.buttonRef}
128129
onClick={() => this.props.getPro(this.props.source)}

src/components/settings/proxy-settings-card.tsx

Lines changed: 103 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import { IconButton } from '../common/icon-button';
3232
import {
3333
SettingsButton,
3434
SettingsExplanation,
35-
SettingsSubheading
35+
SettingsSubheading,
36+
SettingsSubheadingRow
3637
} from './settings-components';
3738
import { StringSettingsList } from './string-settings-list';
3839

@@ -91,6 +92,24 @@ const Http2Select = styled(Select)`
9192
padding: 3px;
9293
`;
9394

95+
const TlsPassthroughModeToggle = styled.button.attrs(() => ({
96+
type: 'button' as const
97+
}))`
98+
display: flex;
99+
align-items: center;
100+
gap: 6px;
101+
cursor: pointer;
102+
103+
margin-left: auto;
104+
105+
background: none;
106+
border: none;
107+
padding: 0;
108+
color: ${p => p.theme.mainColor};
109+
font-family: ${p => p.theme.fontFamily};
110+
font-size: ${p => p.theme.textSize};
111+
`;
112+
94113
const TlsKeyLogInputContainer = styled.div`
95114
margin: 10px 0;
96115
display: flex;
@@ -177,22 +196,45 @@ export class ProxySettingsCard extends React.Component<
177196
else this.props.proxyStore!.setPortConfig(this.portConfig);
178197
}
179198

199+
private get tlsHostnames() {
200+
const config = this.props.proxyStore!.tlsInterceptionConfig;
201+
return 'tlsPassthrough' in config
202+
? config.tlsPassthrough
203+
: config.tlsInterceptOnly;
204+
}
205+
206+
private get tlsMode(): 'passthrough' | 'intercept-only' {
207+
return 'tlsInterceptOnly' in this.props.proxyStore!.tlsInterceptionConfig
208+
? 'intercept-only'
209+
: 'passthrough';
210+
}
211+
180212
@action.bound
181213
addTlsPassthroughHostname(hostname: string) {
182-
const { tlsPassthroughConfig } = this.props.proxyStore!;
183-
tlsPassthroughConfig.push({ hostname });
214+
this.tlsHostnames.push({ hostname });
184215
}
185216

186217
@action.bound
187218
removeTlsPassthroughHostname(hostname: string) {
188-
const { tlsPassthroughConfig } = this.props.proxyStore!;
189-
const hostnameIndex = _.findIndex(tlsPassthroughConfig, (passthroughItem) =>
190-
passthroughItem.hostname === hostname
219+
const hostnames = this.tlsHostnames;
220+
const hostnameIndex = _.findIndex(hostnames, (item) =>
221+
item.hostname === hostname
191222
);
192223

193224
if (hostnameIndex === -1) return;
194225

195-
tlsPassthroughConfig.splice(hostnameIndex, 1);
226+
hostnames.splice(hostnameIndex, 1);
227+
}
228+
229+
@action.bound
230+
toggleTlsMode() {
231+
const proxyStore = this.props.proxyStore!;
232+
const hostnames = this.tlsHostnames;
233+
if (this.tlsMode === 'passthrough') {
234+
proxyStore.tlsInterceptionConfig = { tlsInterceptOnly: hostnames };
235+
} else {
236+
proxyStore.tlsInterceptionConfig = { tlsPassthrough: hostnames };
237+
}
196238
}
197239

198240
@observable
@@ -233,13 +275,16 @@ export class ProxySettingsCard extends React.Component<
233275
http2Enabled,
234276
http2CurrentlyEnabled,
235277

236-
tlsPassthroughConfig,
237-
currentTlsPassthroughConfig,
278+
tlsInterceptionConfig,
279+
currentTlsInterceptionConfig,
238280

239281
keyLogFilePath,
240282
currentKeyLogFilePath
241283
} = proxyStore!;
242284

285+
const tlsMode = this.tlsMode;
286+
const tlsHostnames = this.tlsHostnames;
287+
243288
return <CollapsibleCard {...cardProps}>
244289
<header>
245290
<CollapsibleCardHeading onCollapseToggled={
@@ -252,7 +297,7 @@ export class ProxySettingsCard extends React.Component<
252297
visible={
253298
(this.isCurrentPortConfigValid && !this.isCurrentPortInRange) ||
254299
http2Enabled !== http2CurrentlyEnabled ||
255-
!_.isEqual(tlsPassthroughConfig, currentTlsPassthroughConfig) ||
300+
!_.isEqual(tlsInterceptionConfig, currentTlsInterceptionConfig) ||
256301
keyLogFilePath !== currentKeyLogFilePath
257302
}
258303
/>
@@ -301,36 +346,67 @@ export class ProxySettingsCard extends React.Component<
301346

302347
{
303348
versionSatisfies(serverVersion.value, TLS_PASSTHROUGH_SUPPORTED) && <>
304-
<SettingsSubheading>
305-
TLS Passthrough { !_.isEqual(tlsPassthroughConfig, currentTlsPassthroughConfig) &&
349+
<SettingsSubheadingRow>
350+
<SettingsSubheading>TLS Passthrough</SettingsSubheading>
351+
352+
{ !_.isEqual(tlsInterceptionConfig, currentTlsInterceptionConfig) &&
306353
<UnsavedIcon title="Restart app to apply changes" />
307354
}
308-
</SettingsSubheading>
355+
356+
<TlsPassthroughModeToggle
357+
title={tlsMode === 'passthrough'
358+
? "Listed hostnames are not intercepted. Click to switch to intercept-only mode."
359+
: "Only listed hostnames are intercepted. Click to switch to passthrough mode."
360+
}
361+
onClick={this.toggleTlsMode}
362+
>
363+
{ tlsMode === 'passthrough'
364+
? 'Exclude hostnames'
365+
: 'Intercept only these hostnames'
366+
}
367+
<Icon icon={['fas',
368+
tlsMode === 'passthrough' ? 'toggle-on' : 'toggle-off'
369+
]} />
370+
</TlsPassthroughModeToggle>
371+
</SettingsSubheadingRow>
309372

310373
<StringSettingsList
311-
values={tlsPassthroughConfig.map(c => c.hostname)}
374+
values={tlsHostnames.map(c => c.hostname)}
312375
onAdd={this.addTlsPassthroughHostname}
313376
onDelete={this.removeTlsPassthroughHostname}
314-
placeholder='A hostname whose TLS connections should not be intercepted'
377+
placeholder={tlsMode === 'intercept-only'
378+
? 'A hostname whose TLS connections should be intercepted'
379+
: 'A hostname whose TLS connections should not be intercepted'
380+
}
315381
validationFn={hostnameValidation}
316382
/>
317383

318384
<SettingsExplanation>
319-
Incoming TLS connections to these hostnames will bypass HTTP Toolkit, and will
320-
be forwarded upstream untouched instead of being intercepted. Clients will not see
321-
HTTP Toolkit's certificate, which may solve some connection issues, but traffic
322-
within these TLS connections will not be accessible.
385+
{ tlsMode === 'intercept-only'
386+
? <>
387+
Only TLS connections to these hostnames will be intercepted by HTTP Toolkit.
388+
All other TLS connections will be forwarded upstream without
389+
interception. Non-TLS traffic is always visible regardless of this setting.
390+
</>
391+
: <>
392+
TLS connections to these hostnames will be forwarded upstream untouched, without
393+
interception. This may solve some certificate trust connectivity issues,
394+
but traffic within these TLS connections will not be accessible.
395+
</>
396+
}
323397
</SettingsExplanation>
324398
</>
325399
}
326400

327401
{
328402
versionSatisfies(serverVersion.value, INITIAL_HTTP2_RANGE) && <>
329-
<SettingsSubheading>
330-
HTTP/2 Support { http2Enabled !== http2CurrentlyEnabled &&
403+
<SettingsSubheadingRow>
404+
<SettingsSubheading>HTTP/2 Support</SettingsSubheading>
405+
406+
{ http2Enabled !== http2CurrentlyEnabled &&
331407
<UnsavedIcon title="Restart app to apply changes" />
332408
}
333-
</SettingsSubheading>
409+
</SettingsSubheadingRow>
334410

335411
<Http2Select
336412
value={JSON.stringify(http2Enabled)}
@@ -350,11 +426,13 @@ export class ProxySettingsCard extends React.Component<
350426

351427
{
352428
versionSatisfies(serverVersion.value, KEY_LOG_FILE_SUPPORTED) && <>
353-
<SettingsSubheading>
354-
TLS Key Log File { keyLogFilePath !== currentKeyLogFilePath &&
429+
<SettingsSubheadingRow>
430+
<SettingsSubheading>TLS Key Log File</SettingsSubheading>
431+
432+
{ keyLogFilePath !== currentKeyLogFilePath &&
355433
<UnsavedIcon title="Restart app to apply changes" />
356434
}
357-
</SettingsSubheading>
435+
</SettingsSubheadingRow>
358436

359437
<TlsKeyLogInputContainer>
360438
{ versionSatisfies(desktopVersion.value, DESKTOP_SELECT_SAVE_FILE_SUPPORTED)

src/components/settings/settings-components.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,22 @@ export const SettingsExplanation = styled.p`
2525
`;
2626

2727
export const SettingsSubheading = styled(ContentLabel)`
28+
&:not(header + &):not(:first-child) {
29+
margin-top: 40px;
30+
}
31+
`;
32+
33+
// Subheaders can be wrapped with this if there are other controls
34+
export const SettingsSubheadingRow = styled.div`
35+
display: flex;
36+
align-items: center;
37+
justify-content: start;
38+
2839
&:not(header + &) {
2940
margin-top: 40px;
3041
}
42+
43+
${SettingsSubheading} {
44+
margin-top: 0;
45+
}
3146
`;

src/components/split-pane.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const SplitPane = styled(ReactSplitPane)<{
1717
.Resizer {
1818
background: #000;
1919
opacity: .5;
20-
z-index: 100;
20+
z-index: 25;
2121
-moz-box-sizing: border-box;
2222
-webkit-box-sizing: border-box;
2323
box-sizing: border-box;

0 commit comments

Comments
 (0)