mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #42369 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. **Done in backend task for whole story** - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added "Clear passcode" action for iOS and iPad hosts in the host actions menu, accessible only to Premium tier users with appropriate permissions. * Added confirmation modal for clearing device passcodes. * Passcode clearing activity now appears in the activity feed with actor information. * Action is conditionally disabled during specific device states (Lost Mode, pending wipe) with contextual tooltips. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
78 lines
1.9 KiB
TypeScript
78 lines
1.9 KiB
TypeScript
import React, { useContext } from "react";
|
|
|
|
import { NotificationContext } from "context/notification";
|
|
import hostAPI from "services/entities/hosts";
|
|
|
|
import Modal from "components/Modal";
|
|
import Button from "components/buttons/Button";
|
|
|
|
const baseClass = "clear-passcode-modal";
|
|
|
|
interface IClearPasscodeModalProps {
|
|
id: number;
|
|
onExit: () => void;
|
|
}
|
|
|
|
const ClearPasscodeModal = ({ id, onExit }: IClearPasscodeModalProps) => {
|
|
const { renderFlash } = useContext(NotificationContext);
|
|
const [isClearingPasscode, setIsClearingPasscode] = React.useState(false);
|
|
|
|
const onClearPasscode = async () => {
|
|
setIsClearingPasscode(true);
|
|
try {
|
|
await hostAPI.clearPasscode(id);
|
|
renderFlash(
|
|
"success",
|
|
"Successfully sent request to clear passcode on this host."
|
|
);
|
|
} catch (e) {
|
|
renderFlash(
|
|
"error",
|
|
"Couldn't send request to clear passcode on this host. Please try again."
|
|
);
|
|
} finally {
|
|
onExit();
|
|
setIsClearingPasscode(false);
|
|
}
|
|
};
|
|
|
|
const renderModalContent = () => {
|
|
return (
|
|
<p>
|
|
This will remove the current passcode and allow anyone with physical
|
|
access to unlock the host.
|
|
</p>
|
|
);
|
|
};
|
|
|
|
const renderModalButtons = () => {
|
|
return (
|
|
<>
|
|
<Button
|
|
type="button"
|
|
onClick={onClearPasscode}
|
|
className="clear-passcode-loading"
|
|
variant="alert"
|
|
isLoading={isClearingPasscode}
|
|
>
|
|
Clear Passcode
|
|
</Button>
|
|
<Button onClick={onExit} variant="inverse-alert">
|
|
Cancel
|
|
</Button>
|
|
</>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<Modal className={baseClass} title="Clear passcode" onExit={onExit}>
|
|
<div className={`${baseClass}__modal-content`}>
|
|
{renderModalContent()}
|
|
</div>
|
|
|
|
<div className="modal-cta-wrap">{renderModalButtons()}</div>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
export default ClearPasscodeModal;
|