Skip to content

Commit

Permalink
feat(app): add settings option to reset ssh authorized keys (#13616)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjhuff authored Sep 21, 2023
1 parent 3633c12 commit 8677b18
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 2 deletions.
2 changes: 2 additions & 0 deletions app/src/assets/localization/en/device_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"clear_calibration_data": "Clear calibration data",
"clear_data_and_restart_robot": "Clear data and restart robot",
"clear_individual_data": "Clear individual data",
"clear_option_authorized_keys": "Clear SSH public keys",
"clear_option_boot_scripts": "Clear custom boot scripts",
"clear_option_boot_scripts_description": "Clears scripts that modify the robot's behavior when powered on.",
"clear_option_deck_calibration": "Clear deck calibration",
Expand Down Expand Up @@ -264,6 +265,7 @@
"software_is_up_to_date": "Your software is already up to date!",
"software_update_error": "Software update error",
"some_robot_controls_are_not_available": "Some robot controls are not available when run is in progress",
"ssh_public_keys": "SSH public keys",
"subnet_mask": "Subnet Mask",
"successfully_connected": "Successfully connected!",
"successfully_connected_to_network": "Successfully connected to {{ssid}}!",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ export function DeviceResetSlideout({
options != null ? options.filter(opt => opt.id.includes('bootScript')) : []
const runHistoryOption =
options != null ? options.filter(opt => opt.id.includes('runsHistory')) : []
const sshKeyOption =
options != null
? options.filter(opt => opt.id.includes('authorizedKeys'))
: []

React.useEffect(() => {
dispatch(fetchResetConfigOptions(robotName))
Expand Down Expand Up @@ -325,6 +329,28 @@ export function DeviceResetSlideout({
/>
))}
</Box>
<Box>
<StyledText
as="p"
css={TYPOGRAPHY.pSemiBold}
marginBottom={SPACING.spacing8}
>
{t('ssh_public_keys')}
</StyledText>
{sshKeyOption.map(opt => (
<CheckboxField
key={opt.id}
onChange={() =>
setResetOptions({
...resetOptions,
[opt.id]: !(resetOptions[opt.id] ?? false),
})
}
value={resetOptions[opt.id]}
label={t(`clear_option_${snakeCase(opt.id)}`)}
/>
))}
</Box>
</Flex>
</Flex>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ const mockResetConfigOptions = [
name: 'module calibration FooBar',
description: 'moduleCalibration fooBar description',
},
{
id: 'authorizedKeys',
name: 'SSH Keys Foo',
description: 'SSH Keys foo description',
},
]

const render = () => {
Expand Down Expand Up @@ -97,13 +102,15 @@ describe('RobotSettings DeviceResetSlideout', () => {
getByText('Clear protocol run history')
getByText('Boot scripts')
getByText('Clear custom boot scripts')
getByText('Clear SSH public keys')
const downloads = getAllByText('Download')
expect(downloads.length).toBe(2)
getByRole('checkbox', { name: 'Clear deck calibration' })
getByRole('checkbox', { name: 'Clear pipette offset calibrations' })
getByRole('checkbox', { name: 'Clear tip length calibrations' })
getByRole('checkbox', { name: 'Clear protocol run history' })
getByRole('checkbox', { name: 'Clear custom boot scripts' })
getByRole('checkbox', { name: 'Clear SSH public keys' })
getByRole('button', { name: 'Clear data and restart robot' })
getByTestId('Slideout_icon_close_Device Reset')
})
Expand Down
7 changes: 6 additions & 1 deletion app/src/organisms/RobotSettingsDashboard/DeviceReset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export function DeviceReset({
'moduleCalibration',
'runsHistory',
]

const availableOptions = options
// filtering out ODD setting because this gets implicitly cleared if all settings are selected
// filtering out boot scripts since product doesn't want this exposed to ODD users
Expand All @@ -81,6 +82,10 @@ export function DeviceReset({
)
const dispatch = useDispatch<Dispatch>()

const availableOptionsToDisplay = availableOptions.filter(
({ id }) => !['authorizedKeys'].includes(id)
)

const handleClick = (): void => {
if (resetOptions != null) {
// remove clearAllStoredData since its not a setting on the backend
Expand Down Expand Up @@ -163,7 +168,7 @@ export function DeviceReset({
marginTop="7.75rem"
>
<Flex gridGap={SPACING.spacing8} flexDirection={DIRECTION_COLUMN}>
{availableOptions.map(option => {
{availableOptionsToDisplay.map(option => {
const { optionText, subText } = renderText(option.id)
return (
<React.Fragment key={option.id}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ const mockResetConfigOptions = [
name: 'Module Calibration FooBar',
description: 'moduleCalibration fooBar description',
},
{
id: 'authorizedKeys',
name: 'SSH Keys Foo',
description: 'SSH Keys foo description',
},
]

const mockGetResetConfigOptions = getResetConfigOptions as jest.MockedFunction<
Expand Down Expand Up @@ -76,12 +81,13 @@ describe('DeviceReset', () => {
})

it('should render text and button', () => {
const [{ getByText, getByTestId }] = render(props)
const [{ getByText, getByTestId, queryByText }] = render(props)
getByText('Clear pipette calibration')
getByText('Clear gripper calibration')
getByText('Clear module calibration')
getByText('Clear protocol run history')
getByText('Clears information about past runs of all protocols.')
expect(queryByText('Clear the ssh authorized keys')).not.toBeInTheDocument()
expect(getByTestId('DeviceReset_clear_data_button')).toBeDisabled()
})

Expand Down

0 comments on commit 8677b18

Please sign in to comment.