File "RiskData.js"
Full Path: /home/bytebmoc/tideswithin.com/RiskConfiguration/RiskData.js
File size: 7.89 KB
MIME-type: text/x-java
Charset: utf-8
/* Creates A Store For Risk Data using Zustand */
import {create} from 'zustand';
import * as rsssl_api from "../../utils/api";
import {__} from "@wordpress/i18n";
import {produce} from "immer";
import React from "react";
import {addUrlRef} from "../../utils/AddUrlRef";
const UseRiskData = create((set, get) => ({
dummyRiskData: [
{id:'force_update',name:'Force Update',value:'l',description:__('Force update the plugin or theme','really-simple-ssl')},
{id:'quarantine',name:'Quarantine',value:'m',description:__('Isolates the plugin or theme if no update can be performed','really-simple-ssl')},
],
riskData:[],
riskLevels: {
l: 1,
m: 2,
h: 3,
c: 4,
},
vulnerabilities: [],
processing:false,
dataLoaded: false,
// Stuff we need for the WPVulData component
updates: 0, //for letting the component know if there are updates available
HighestRisk: false, //for storing the highest risk
lastChecked: '', //for storing the last time the data was checked
vulEnabled: false, //for storing the status of the vulnerability scan
riskNaming: {}, //for storing the risk naming
vulList: [], //for storing the list of vulnerabilities
setDataLoaded: (value) => set({dataLoaded: value}),
//update Risk Data
updateRiskData: async (field, value) => {
if (get().processing) return;
set({processing:true});
set(
produce((state) => {
let index = state.riskData.findIndex((item) => item.id === field);
state.riskData[index].value = value;
state.riskData = get().enforceCascadingRiskLevels(state.riskData);
})
);
try {
await rsssl_api.doAction('vulnerabilities_measures_set', {
riskData: get().riskData,
});
set({dataLoaded: true, processing:false});
} catch (e) {
console.log(e);
}
set({processing:false})
},
enforceCascadingRiskLevels: (data) => {
if (data.length===0) return data;
//get risk levels for force_update
let forceUpdateRiskLevel = data.filter((item) => item.id==='force_update')[0].value;
let quarantineRiskLevel = data.filter((item) => item.id==='quarantine')[0].value;
//get the integer value of the risk level
forceUpdateRiskLevel = get().riskLevels.hasOwnProperty(forceUpdateRiskLevel) ? get().riskLevels[forceUpdateRiskLevel] : 5;
quarantineRiskLevel = get().riskLevels.hasOwnProperty(quarantineRiskLevel) ? get().riskLevels[quarantineRiskLevel] : 5;
let quarantineIndex = data.findIndex((item) => item.id==='quarantine');
//if the quarantine risk level is lower than the force update risk level, we set it to the force update risk level
if (quarantineRiskLevel<forceUpdateRiskLevel) {
data[quarantineIndex].value = Object.keys(get().riskLevels).find(key => get().riskLevels[key] === forceUpdateRiskLevel);
}
//if the force update risk level is none, set quarantine also to none.
if ( forceUpdateRiskLevel===5 ) {
data[quarantineIndex].value = '*';
}
//disable all values below this value
let disableUpTo = forceUpdateRiskLevel>0 ? forceUpdateRiskLevel : 0
//create an array of integers up to the forceUpdateRiskLevel
let disabledRiskLevels = Array.from(Array(disableUpTo).keys()).map(x => x);
disabledRiskLevels = disabledRiskLevels.map( (level) => {
return Object.keys(get().riskLevels).find(key => get().riskLevels[key] === level );
});
data[quarantineIndex].disabledRiskLevels = disabledRiskLevels;
return data;
},
fetchFirstRun: async () => {
if (get().processing) return;
set({processing:true});
await rsssl_api.doAction('vulnerabilities_scan_files');
set({processing:false});
},
/*
* Functions
*/
fetchVulnerabilities: async () => {
if (get().processing) return;
set({processing:true});
let data = {};
try {
const fetched = await rsssl_api.doAction('hardening_data', data);
let vulList = [];
let vulnerabilities = 0;
if (fetched.data.vulList) {
vulnerabilities = fetched.data.vulnerabilities;
vulList = fetched.data.vulList;
if (typeof vulList === 'object') {
//we make it an array
vulList = Object.values(vulList);
}
vulList.forEach(function (item, i) {
let updateUrl = item.update_available ? rsssl_settings.plugins_url + "?plugin_status=upgrade" : '#settings/vulnerabilities';
item.vulnerability_action = <div className="rsssl-action-buttons">
<a className="rsssl-button button-secondary"
href={addUrlRef("https://really-simple-ssl.com/vulnerability/" + item.rss_identifier)}
target={"_blank"} rel="noopener noreferrer">{__("Details", "really-simple-ssl")}</a>
<a disabled={!item.update_available} href={updateUrl}
className="rsssl-button button-primary"
>{__("Update", "really-simple-ssl")}</a>
</div>
});
}
let riskData = fetched.data.riskData;
if (!Array.isArray(riskData)) {riskData = []}
riskData = get().enforceCascadingRiskLevels(riskData);
set(
produce((state) => {
state.vulnerabilities = vulnerabilities;
state.vulList = vulList;
state.updates = fetched.data.updates;
state.dataLoaded = true;
state.riskNaming = fetched.data.riskNaming;
state.lastChecked = fetched.data.lastChecked;
state.vulEnabled = fetched.data.vulEnabled;
state.riskData = riskData;
state.processing = false;
})
)
} catch (e) {
console.error(e);
}
},
vulnerabilityCount: () => {
let vuls = get().vulList;
//we group the data by risk level
//first we make vuls an array
let vulsArray = [];
Object.keys(vuls).forEach(function (key) {
vulsArray.push(vuls[key]);
});
let riskLevels = ['c', 'h', 'm', 'l'];
//we count the amount of vulnerabilities per risk level
return riskLevels.map(function (level) {
return {
level: level,
count: vulsArray.filter(function (vul) {
return vul.risk_level === level;
}).length
};
});
},
vulnerabilityScore: () => {
let score = 0;
let vulnerabilitiesList = get().vulList;
Object.keys(vulnerabilitiesList).forEach(function (key) {
//if there are vulnerabilities with critical severity, score is 5
if (vulnerabilitiesList[key].risk_level === 'c') {
score = 5;
} else if (score < 1) {
score = 1;
}
});
return score;
},
hardeningScore: () => {
let score = 0;
let vulnerabilitiesList = get().vulnerabilities;
for (let i = 0; i < vulnerabilitiesList.length; i++) {
score += vulnerabilitiesList[i].hardening_score;
}
return score;
},
activateVulnerabilityScanner: async () => {
try {
const fetched = await rsssl_api.doAction('rsssl_scan_files');
if (fetched.request_success) {
//we get the data again
await get().fetchVulnerabilities();
}
} catch (e) {
console.error(e);
}
}
}));
export default UseRiskData;