File "LearningMode.js"
Full Path: /home/bytebmoc/tideswithin.com/LimitLoginAttempts/LearningMode.js
File size: 17.96 KB
MIME-type: text/x-java
Charset: utf-8
import { __ } from '@wordpress/i18n';
import {useState,useEffect} from '@wordpress/element';
import ChangeStatus from "./ChangeStatus";
import Delete from "./Delete";
import Icon from "../../utils/Icon";
import useFields from "./../FieldsData";
import UseLearningMode from "./LearningModeData";
import {Button} from "@wordpress/components";
import React from "react";
import ManualCspAdditionModal from "./ManualCspAdditionModal";
import AddButton from "../GeoBlockList/AddButton";
import ManualCspAddition from "./ManualCspAddition";
const LearningMode = (props) => {
const {updateField, getFieldValue, getField, setChangedField, highLightField, saveFields} = useFields();
const {fetchLearningModeData, learningModeData, dataLoaded, updateStatus, deleteData} = UseLearningMode();
const {manualAdditionProcessing} = ManualCspAddition();
//used to show if a feature is already enforced by a third party
const [enforcedByThirdparty, setEnforcedByThirdparty] = useState(0);
//toggle from enforced to not enforced
const [enforce, setEnforce] = useState(0);
//toggle from learning mode to not learning mode
const [learningMode, setLearningMode] = useState(0);
//set learning mode to completed
const [learningModeCompleted, setLearningModeCompleted] = useState(0);
const [hasError, setHasError] = useState(false);
//check if learningmode has been enabled at least once
const [lmEnabledOnce, setLmEnabledOnce] = useState(0);
//filter the data
const [filterValue, setFilterValue] = useState(-1);
//the value that is used to enable or disable this feature. On or of.
const [controlField, setControlField] = useState(false);
// the value that is used to select and deselect rows
const [rowsSelected, setRowsSelected] = useState([]);
const [rowCleared, setRowCleared] = useState(false);
const [DataTable, setDataTable] = useState(null);
const [theme, setTheme] = useState(null);
const [modalOpen, setModalOpen] = useState(false);
useEffect( () => {
import('react-data-table-component').then(({ default: DataTable, createTheme }) => {
setDataTable(() => DataTable);
setTheme(() => createTheme('really-simple-plugins', {
divider: {
default: 'transparent',
},
}, 'light'));
});
}, []);
/**
* Styling
*/
const conditionalRowStyles = [
{
when: row => row.status ==0,
classNames: ['rsssl-datatables-revoked'],
},
];
const customStyles = {
headCells: {
style: {
paddingLeft: '0', // override the cell padding for head cells
paddingRight: '0',
},
},
cells: {
style: {
paddingLeft: '0', // override the cell padding for data cells
paddingRight: '0',
},
},
};
;
/**
* Initialize
*/
useEffect(() => {
const run = async () => {
await fetchLearningModeData(props.field.id);
let controlField = getField(props.field.control_field );
let enforced_by_thirdparty = controlField.value === 'enforced-by-thirdparty';
let enforce = enforced_by_thirdparty || controlField.value === 'enforce';
setControlField(controlField);
setEnforcedByThirdparty(enforced_by_thirdparty);
setLearningModeCompleted(controlField.value==='completed');
setHasError(controlField.value==='error');
setLmEnabledOnce(getFieldValue(props.field.control_field+'_lm_enabled_once'))
setEnforce(enforce);
setLearningMode(controlField.value === 'learning_mode');
}
run();
}, [enforce, learningMode] );
const toggleEnforce = async (e, enforceValue) => {
e.preventDefault();
//enforce this setting
let controlFieldValue = enforceValue==1 ? 'enforce' : 'disabled';
setEnforce(enforceValue);
setLearningModeCompleted(0);
setLearningMode(0);
setChangedField(controlField.id, controlFieldValue);
updateField(controlField.id, controlFieldValue);
await saveFields(true, false);
//await fetchLearningModeData();
}
const toggleLearningMode = async (e) => {
e.preventDefault();
let lmEnabledOnceField = getField(props.field.control_field+'_lm_enabled_once');
if ( learningMode ) {
setLmEnabledOnce(1);
updateField(lmEnabledOnceField.id, 1);
}
let controlFieldValue;
if ( learningMode || learningModeCompleted ) {
setLearningMode(0);
controlFieldValue = 'disabled';
} else {
setLearningMode(1);
controlFieldValue = 'learning_mode';
}
setLearningModeCompleted(0);
setChangedField(controlField.id, controlFieldValue);
updateField(controlField.id, controlFieldValue);
setChangedField(lmEnabledOnceField.id, lmEnabledOnceField.value);
updateField(lmEnabledOnceField, lmEnabledOnceField.value);
await saveFields(true, false);
}
const Filter = () => (
<>
<select onChange={ ( e ) => setFilterValue(e.target.value) } value={filterValue}>
<option value="-1" >{__("All", "really-simple-ssl")}</option>
<option value="1" >{__("Allowed", "really-simple-ssl")}</option>
<option value="0" >{__("Blocked", "really-simple-ssl")}</option>
</select>
</>
);
let field = props.field;
let configuringString = __(" The %s is now in report-only mode and will collect directives. This might take a while. Afterwards you can Exit, Edit and Enforce these Directives.", "really-simple-ssl").replace('%s', field.label);
let disabledString = __("%s has been disabled.", "really-simple-ssl").replace('%s', field.label);
let enforcedString = __("%s is enforced.", "really-simple-ssl").replace('%s', field.label);
let enforceDisabled = !lmEnabledOnce;
if (enforcedByThirdparty) disabledString = __("%s is already set outside Really Simple Security.", "really-simple-ssl").replace('%s', field.label);
let highLightClass = 'rsssl-field-wrap';
if ( highLightField===props.field.id ) {
highLightClass = 'rsssl-field-wrap rsssl-highlight';
}
//build our header
let columns = [];
field.columns.forEach(function(item, i) {
let newItem = {
name: item.name,
sortable: item.sortable,
width: item.width,
selector: item.column === 'documenturi' || item.column === 'method'
? row => <span title={row[item.column]}>{row[item.column]}</span>: row => row[item.column],
}
columns.push(newItem);
});
let data = learningModeData;
data = data.filter(item => item.status<2);
if (filterValue!=-1) {
data = data.filter(item => item.status==filterValue);
}
for (const item of data){
if (item.login_status) item.login_statusControl = item.login_status == 1 ? __("success", "really-simple-ssl") : __("failed", "really-simple-ssl");
item.statusControl = <ChangeStatus item={item} field={props.field} />;
item.deleteControl = <Delete item={item} field={props.field}/>;
item.grouped = <div className="rsssl-action-buttons">
<ChangeStatus item={item} field={props.field} />
<Delete item={item} field={props.field}/>
</div>
}
const handleMultiRowStatus = (status, selectedRows, type) => {
selectedRows.forEach(row => {
//the updateItemId allows us to update one specific item in a field set.
updateStatus(status, row, type);
});
setRowCleared(true);
setRowsSelected([]);
// Reset rowCleared back to false after the DataTable has re-rendered
setTimeout(() => setRowCleared(false), 0);
}
const handleMultiRowDelete = ( selectedRows, type) => {
selectedRows.forEach(row => {
//the updateItemId allows us to update one specific item in a field set.
deleteData( row, type );
});
setRowCleared(true);
setRowsSelected([]);
// Reset rowCleared back to false after the DataTable has re-rendered
setTimeout(() => setRowCleared(false), 0);
}
function handleSelection(state) {
setRowCleared(false);
setRowsSelected(state.selectedRows);
}
const handleClose = () => {
setModalOpen(false);
}
const handleOpen = () => {
setModalOpen(true);
}
if (!DataTable || !theme) return null;
return (
<>
{props.field.id === 'content_security_policy_source_directives' && (<>
<ManualCspAdditionModal
isOpen={modalOpen}
onRequestClose={handleClose}
status={'blocked'}
directives={props.field.modal.options}
parentId={props.field.id}
/>
<div className="rsssl-container" style={{paddingTop: "0px"}}>
<AddButton
handleOpen={handleOpen}
processing={manualAdditionProcessing}
allowedText={__("Add Entry", "really-simple-ssl")}
/>
</div>
</>)}
{!dataLoaded && <>
<div className="rsssl-learningmode-placeholder">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</>}
{rowsSelected.length > 0 && (
<div
style={{
marginTop: '1em',
marginBottom: '1em',
}}
>
<div
className={"rsssl-multiselect-datatable-form rsssl-primary"}
>
<div>
{__("You have selected", "really-simple-ssl")} {rowsSelected.length} {__("rows", "really-simple-ssl")}
</div>
<div className="rsssl-action-buttons">
{(Number(filterValue) === -1 || Number(filterValue) === 0) &&
<div className="rsssl-action-buttons__inner">
<Button
// className={"button button-red rsssl-action-buttons__button"}
className={"button button-secondary rsssl-status-allowed rsssl-action-buttons__button"}
onClick={() => handleMultiRowStatus(0, rowsSelected, props.field.id)}
>
{__('Allow', 'really-simple-ssl')}
</Button>
</div>
}
{(Number(filterValue) === -1 || Number(filterValue) === 1) &&
<div className="rsssl-action-buttons__inner">
<Button
// className={"button button-red rsssl-action-buttons__button"}
className={"button button-primary rsssl-action-buttons__button"}
onClick={() => handleMultiRowStatus(1, rowsSelected, props.field.id)}
>
{__('Revoke', 'really-simple-ssl')}
</Button>
</div>
}
<div className="rsssl-action-buttons__inner">
<Button
// className={"button button-red rsssl-action-buttons__button"}
className={"button button-red rsssl-action-buttons__button"}
onClick={() => handleMultiRowDelete(rowsSelected, props.field.id)}
>
{__('Remove', 'really-simple-ssl')}
</Button>
</div>
</div>
</div>
</div>
)}
{dataLoaded && <>
<DataTable
columns={columns}
data={data}
dense
pagination
noDataComponent={__("No results", "really-simple-ssl")}
persistTableHead
theme={theme}
customStyles={customStyles}
conditionalRowStyles={conditionalRowStyles}
paginationComponentOptions={{
rowsPerPageText: __('Rows per page:', 'really-simple-ssl'),
rangeSeparatorText: __('of', 'really-simple-ssl'),
noRowsPerPage: false,
selectAllRowsItem: false,
selectAllRowsItemText: __('All', 'really-simple-ssl'),
}}
selectableRows
selectableRowsHighlight={true}
onSelectedRowsChange={handleSelection}
clearSelectedRows={rowCleared}
/></>
}
<div className={"rsssl-learning-mode-footer"} style={{marginLeft:'0px'}}>
{hasError && <div className="rsssl-locked">
<div className="rsssl-locked-overlay">
<span
className="rsssl-progress-status rsssl-learning-mode-error">{__("Error detected", "really-simple-ssl")}</span>
{__("%s cannot be implemented due to server limitations. Check your notices for the detected issue.", "really-simple-ssl").replace('%s', field.label)}
<a className="rsssl-learning-mode-link" href="#"
onClick={(e) => toggleEnforce(e, false)}>{__("Disable", "really-simple-ssl")}</a>
</div>
</div>
}
{!hasError && <>
{enforce != 1 && <button disabled={enforceDisabled} className="button button-primary"
onClick={(e) => toggleEnforce(e, true)}>{__("Enforce", "really-simple-ssl")}</button>}
{!enforcedByThirdparty && enforce == 1 && <button className="button"
onClick={(e) => toggleEnforce(e, false)}>{__("Disable", "really-simple-ssl")}</button>}
<label>
<input type="checkbox"
disabled={enforce}
checked={learningMode == 1}
value={learningMode}
onChange={(e) => toggleLearningMode(e)}
/>
{__("Enable Learning Mode to configure automatically", "really-simple-ssl")}
</label>
{enforce == 1 && <div className="rsssl-locked">
<div className="rsssl-shield-overlay">
<Icon name="shield" size="80px"/>
</div>
<div className="rsssl-locked-overlay">
<span
className="rsssl-progress-status rsssl-learning-mode-enforced">{__("Enforced", "really-simple-ssl")}</span>
{enforcedString}
<a className="rsssl-learning-mode-link" href="#"
onClick={(e) => toggleEnforce(e)}>{__("Disable to configure", "really-simple-ssl")}</a>
</div>
</div>}
{learningMode == 1 && <div className="rsssl-locked">
<div className="rsssl-locked-overlay">
<span
className="rsssl-progress-status rsssl-learning-mode">{__("Learning Mode", "really-simple-ssl")}</span>
{configuringString}
<a className="rsssl-learning-mode-link" href="#"
onClick={(e) => toggleLearningMode(e)}>{__("Exit", "really-simple-ssl")}</a>
</div>
</div>}
{learningModeCompleted == 1 && <div className="rsssl-locked">
<div className="rsssl-locked-overlay">
<span
className="rsssl-progress-status rsssl-learning-mode-completed">{__("Learning Mode", "really-simple-ssl")}</span>
{__("We finished the configuration.", "really-simple-ssl")}
<a className="rsssl-learning-mode-link" href="#"
onClick={(e) => toggleLearningMode(e)}>{__("Review the settings and enforce the policy", "really-simple-ssl")}</a>
</div>
</div>}
{rsssl_settings.pro_plugin_active && props.disabled && <div className="rsssl-locked ">
<div className="rsssl-locked-overlay">
{!enforcedByThirdparty && <span
className="rsssl-progress-status rsssl-disabled">{__("Disabled", "really-simple-ssl")}</span>}
{enforcedByThirdparty && <span
className="rsssl-progress-status rsssl-learning-mode-enforced">{__("Enforced", "really-simple-ssl")}</span>}
{disabledString}
</div>
</div>}
</>
}
<Filter/>
</div>
</>
)
}
export default LearningMode