Skip to content

Commit

Permalink
connect-form: break out components
Browse files Browse the repository at this point in the history
  • Loading branch information
calebdoxsey committed Jan 23, 2025
1 parent 3e84d2d commit cafccd0
Show file tree
Hide file tree
Showing 10 changed files with 501 additions and 409 deletions.
76 changes: 76 additions & 0 deletions src/renderer/components/AdvancedConnectionSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {
FormControlLabel,
FormHelperText,
Grid,
Switch,
Typography,
} from '@mui/material';
import React, { FC } from 'react';
import TextField from './TextField';
import { Connection } from '../../shared/pb/api';
import ClientCertSelection from './ClientCertSelection';

export type AdvancedConnectionSettingsProps = {
connection: Connection;
onChangeConnection: (connection: Connection) => void;
};
const AdvancedConnectionSettings: FC<AdvancedConnectionSettingsProps> = ({
connection,
onChangeConnection,
}) => {
const onToggleDisableTlsVerification = () => {
onChangeConnection({
...connection,
disableTlsVerification: !connection?.disableTlsVerification,
});
};
const onChangeUrl = (evt: React.ChangeEvent<HTMLInputElement>) => {
onChangeConnection({
...connection,
pomeriumUrl: evt.target.value.trim() || undefined,
});
};

return (
<Grid container spacing={2}>
<Grid item xs={12}>
<TextField
fullWidth
required
label="Pomerium URL"
value={connection?.pomeriumUrl || ''}
onChange={onChangeUrl}
variant="outlined"
autoFocus
helperText="URL of a Bastion host to use for the initial TLS connection"
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={
<Switch
checked={connection?.disableTlsVerification}
name="disable-tls-verification"
color="primary"
onChange={onToggleDisableTlsVerification}
/>
}
label="Disable TLS Verification"
/>
<FormHelperText sx={{ pl: 2 }}>
Skips TLS verification. No Cert Authority Needed.
</FormHelperText>
</Grid>
<Grid item xs={12}>
<Typography sx={{ fontWeight: 500, pt: 1 }}>
Client certificates
</Typography>
</Grid>
<ClientCertSelection
connection={connection}
onChangeConnection={onChangeConnection}
/>
</Grid>
);
};
export default AdvancedConnectionSettings;
2 changes: 1 addition & 1 deletion src/renderer/components/CertFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const CertFilter: React.FC<Props> = ({ label, data, onChange, disabled }) => {
onChange(attribute + '=' + newValue);
};

const valueInputRef = useRef(null);
const valueInputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
valueInputRef.current?.focus();
}, [attribute]);
Expand Down
156 changes: 156 additions & 0 deletions src/renderer/components/ClientCertSelection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React, { ChangeEvent, FC, useState } from 'react';

Check failure on line 1 in src/renderer/components/ClientCertSelection.tsx

View workflow job for this annotation

GitHub Actions / release (ubuntu-latest)

'ChangeEvent' is defined but never used

Check failure on line 1 in src/renderer/components/ClientCertSelection.tsx

View workflow job for this annotation

GitHub Actions / release (ubuntu-latest)

'ChangeEvent' is defined but never used
import { ClientCertFromStore, Connection } from '../../shared/pb/api';
import ManualClientCertSelection from './ManualClientCertSelection';
import {

Check failure on line 4 in src/renderer/components/ClientCertSelection.tsx

View workflow job for this annotation

GitHub Actions / release (ubuntu-latest)

`@mui/material` import should occur before import of `../../shared/pb/api`

Check failure on line 4 in src/renderer/components/ClientCertSelection.tsx

View workflow job for this annotation

GitHub Actions / release (ubuntu-latest)

`@mui/material` import should occur before import of `../../shared/pb/api`
FormControlLabel,
FormHelperText,
Grid,
Switch,
Typography,
} from '@mui/material';
import NestedAccordion from './NestedAccordion';
import NestedAccordionSummary from './NestedAccordionSummary';
import NestedAccordionDetails from './NestedAccordionDetails';
import CertFilter from './CertFilter';

export function getClientCertFiltersSummary(c?: ClientCertFromStore): string {
const filters: string[] = [];
if (c?.issuerFilter) {
filters.push('Issuer ' + c.issuerFilter);
}
if (c?.subjectFilter) {
filters.push('Subject ' + c.subjectFilter);
}
return filters.join(', ');
}

export type ClientCertSelectionProps = {
connection: Connection;
onChangeConnection: (connection: Connection) => void;
};
const ClientCertSelection: FC<ClientCertSelectionProps> = ({
connection,
onChangeConnection,
}) => {
const [clientCertFiltersExpanded, setClientCertFiltersExpanded] =
useState(false);
const clientCertFromStoreEnabled =
connection?.clientCertFromStore !== undefined;
const clientCertFiltersSummary = getClientCertFiltersSummary(
connection?.clientCertFromStore,
);

const onChangeClientCertIssuerFilter = (value: string | undefined): void => {
onChangeConnection({
...connection,
...{
clientCertFromStore: {
...connection.clientCertFromStore,
issuerFilter: value,
},
},
});
};
const onChangeClientCertSubjectFilter = (value: string | undefined): void => {
onChangeConnection({
...connection,
...{
clientCertFromStore: {
...connection.clientCertFromStore,
subjectFilter: value,
},
},
});
};
const onToggleClientCertFromStore = (): void => {
onChangeConnection({
...connection,
...{
clientCertFromStore: connection.clientCertFromStore ? undefined : {},
},
});
};

const supportsClientCertFromStore =
process.platform === 'win32' || process.platform === 'darwin';
if (!supportsClientCertFromStore) {
return (
<ManualClientCertSelection
connection={connection}
onChangeConnection={onChangeConnection}
/>
);
}

return (
<>
<Grid item xs={12}>
<FormControlLabel
control={
<Switch
checked={clientCertFromStoreEnabled}
color="primary"
onChange={onToggleClientCertFromStore}
/>
}
label="Search OS certificate store"
/>
<FormHelperText sx={{ pl: 2 }}>
Searches for a client certificate based on the trusted CA names
provided in the TLS connection handshake.
</FormHelperText>
</Grid>
<NestedAccordion
sx={{ mt: 2 }}
disabled={!clientCertFromStoreEnabled}
expanded={clientCertFiltersExpanded}
onChange={(evt, expanded) => setClientCertFiltersExpanded(expanded)}
>
<NestedAccordionSummary>
<Typography>
Additional OS certificate store filters
{!clientCertFiltersExpanded && clientCertFiltersSummary && (
<>
:<br />
{clientCertFiltersSummary}
</>
)}
</Typography>
</NestedAccordionSummary>
<NestedAccordionDetails>
{clientCertFromStoreEnabled && (
<>
<CertFilter
label="Issuer Name"
data={connection?.clientCertFromStore?.issuerFilter}
onChange={onChangeClientCertIssuerFilter}
disabled={!clientCertFromStoreEnabled}
/>
<CertFilter
label="Subject Name"
data={connection?.clientCertFromStore?.subjectFilter}
onChange={onChangeClientCertSubjectFilter}
disabled={!clientCertFromStoreEnabled}
/>
</>
)}
</NestedAccordionDetails>
</NestedAccordion>

<NestedAccordion sx={{ my: 2 }}>
<NestedAccordionSummary>
<Typography>Set client certificate manually</Typography>
</NestedAccordionSummary>
<NestedAccordionDetails>
<Grid container spacing={2} sx={{ pt: 1 }}>
<ManualClientCertSelection
connection={connection}
onChangeConnection={onChangeConnection}
/>
</Grid>
</NestedAccordionDetails>
</NestedAccordion>
</>
);
};
export default ClientCertSelection;
Loading

0 comments on commit cafccd0

Please sign in to comment.