Merge branch 'master' into feature-agentless-server-monitor

This commit is contained in:
Ibukun Dairo
2020-12-11 19:20:22 +01:00
89 changed files with 70922 additions and 30617 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -21,8 +21,8 @@
"puppeteer": "^2.1.1",
"puppeteer-cluster": "^0.21.0",
"query-string": "^5.1.1",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-frontload": "^1.0.3",
"react-ga": "^2.5.3",
"react-redux": "^5.0.7",
@@ -46,7 +46,7 @@
"test": "jest --forceExit --runInBand ./src/test/*.test.js",
"enterprise-test": "jest --forceExit --runInBand ./src/test/*.test.enterprise.js",
"start": "node index.js",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"light-house": "node lighthouse.js --web",
"light-house-mobile": "node lighthouse.js --mobile",
"dep-check": "depcheck ./ --skip-missing=true --ignores='browserslist,loadable-components,@beam-australia/react-env'"
@@ -56,7 +56,6 @@
"commander": "^4.0.1",
"depcheck": "^0.9.2",
"lighthouse": "^6.2.0",
"npm-audit-ci-wrapper": "^2.5.1",
"ora": "^4.0.3",
"should": "^13.2.3",
"workbox-build": "^4.3.1"

View File

@@ -0,0 +1,16 @@
import React from 'react';
function DataPathHoC(WrappedComponent, data) {
return class extends React.Component {
static displayName = 'HocCom';
render() {
// Wraps the input component in a container, without mutating it. Good!
return (
<WrappedComponent {...this.props} webhook={data} data={data} />
);
}
};
}
DataPathHoC.displayName = 'DataPathHoC';
export default DataPathHoC;

View File

@@ -0,0 +1,73 @@
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import { closeModal } from '../actions/modal';
class ExtraCharge extends React.Component {
handleClick = () => {
this.props.close();
};
render() {
return (
<div>
<div
className="ModalLayer-contents"
tabIndex={-1}
style={{ marginTop: 40 }}
>
<div className="bs-BIM">
<div className="bs-Modal bs-Modal--medium">
<div className="bs-Modal-header">
<div className="bs-Modal-header-copy">
<span className="Text-color--inherit Text-display--inline Text-fontSize--20 Text-fontWeight--medium Text-lineHeight--24 Text-typeface--base Text-wrap--wrap">
<span>Why we charge your cards at sign up?</span>
</span>
</div>
</div>
<div className="bs-Modal-content">
<div>We've had few issues with toll fraud in the past
and we want to make sure our customers who sign up to Fyipe
are 100% genuine. This is one of the steps we take to filter out
fraud. To learn about toll fraud,{' '}
<span style={{cursor:'pointer', textDecoration:"underline"}}><a style={{color:'green',}}
href="https://www.twilio.com/learn/voice-and-video/toll-fraud"
target="_blank" rel="noopener noreferrer">please click here</a></span>
</div>
</div>
<div className="bs-Modal-footer">
<div className="bs-Modal-footer-actions">
<button
className="bs-Button bs-DeprecatedButton bs-Button--grey"
type="button"
onClick={this.handleClick}
>
<span>{'Close'}</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
ExtraCharge.propTypes = {
close: PropTypes.func,
};
ExtraCharge.displayName = 'ExtraCharge';
const mapStateToProps = () => {
return {};
};
const mapDispatchToProps = dispatch => {
return {
close: () => {
dispatch(closeModal({ id: 1 }));
},
};
};
export default connect(mapStateToProps, mapDispatchToProps)(ExtraCharge);

View File

@@ -8,6 +8,9 @@ import Fade from 'react-reveal/Fade';
import { RenderField } from '../basic/RenderField';
import { PricingPlan, Validate, env } from '../../config';
import { ButtonSpinner } from '../basic/Loader.js';
import { openModal } from '../../actions/modal';
import DataPathHoc from '../DataPathHoC';
import ExtraCharge from '../ExtraCharge';
import {
CardNumberElement,
CardExpiryElement,
@@ -33,7 +36,6 @@ import {
logEvent,
} from '../../analytics';
import { SHOULD_LOG_ANALYTICS } from '../../config';
const createOptions = () => {
return {
style: {
@@ -179,7 +181,25 @@ class CardForm extends Component {
<h2>{header}</h2>
<p>
Your card will be charged $1.00 to check its
billability. You will be charged $
billability.{' '}
<span
style={{
color: 'green',
cursor: 'pointer',
textDecoration: 'underline',
}}
onClick={() =>
this.props.openModal({
id: 1,
content: DataPathHoc(
ExtraCharge
),
})
}
>
Learn More
</span>
<br></br> You will be charged $
{this.plan.amount}/
{this.plan.type === 'month' ? 'mo' : 'yr'}{' '}
after your 14 day free trial.
@@ -558,6 +578,7 @@ const mapDispatchToProps = dispatch => {
addCardSuccess,
addCardFailed,
addCardRequest,
openModal,
signUpRequest,
signupUser,
signupError,
@@ -577,6 +598,7 @@ function mapStateToProps(state) {
}
CardForm.propTypes = {
openModal: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
submitForm: PropTypes.func.isRequired,
register: PropTypes.object.isRequired,

File diff suppressed because it is too large Load Diff

View File

@@ -22,9 +22,9 @@
"prop-types": "^15.6.1",
"puppeteer": "^2.1.1",
"puppeteer-cluster": "^0.19.0",
"react": "^16.5.2",
"react": "^16.14.0",
"react-click-outside": "github:tj/react-click-outside",
"react-dom": "^16.5.2",
"react-dom": "^16.14.0",
"react-frontload": "^1.0.3",
"react-ga": "^2.5.3",
"react-json-view": "^1.19.1",
@@ -49,7 +49,7 @@
"test": "jest --forceExit --runInBand ./src/test/*.test.js",
"enterprise-test": "jest --forceExit --runInBand ./src/test/*.test.enterprise.js",
"start": "node index.js",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='babel-*,browserslist,loadable-components,js-uuid,acorn,@beam-australia/react-env'"
},
"devDependencies": {
@@ -60,7 +60,6 @@
"babel-runtime": "^6.26.0",
"depcheck": "^0.9.2",
"jest-localstorage-mock": "^2.2.0",
"npm-audit-ci-wrapper": "^2.5.1",
"should": "^13.2.3"
},
"jest": {

File diff suppressed because it is too large Load Diff

View File

@@ -22,12 +22,11 @@
"start": "node server.js",
"dev": "nodemon server.js",
"test": "echo \"no test required\"",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='babel-*,browserslist,ejs,path,loadable-components,js-uuid,acorn,@beam-australia/react-env'"
},
"devDependencies": {
"depcheck": "^0.9.2",
"nodemon": "^2.0.2",
"npm-audit-ci-wrapper": "^2.5.1"
"nodemon": "^2.0.2"
}
}

View File

@@ -773,4 +773,31 @@ router.post(
}
);
router.post(
'/:projectId/disableMonitor/:monitorId',
getUser,
isAuthorized,
async function(req, res) {
try {
const { monitorId } = req.params;
const monitor = await MonitorService.findOneBy({ _id: monitorId });
const disabled = monitor.disabled ? false : true;
const newMonitor = await MonitorService.updateOneBy(
{
_id: monitorId,
},
{ disabled: disabled }
);
await ProbeService.createMonitorDisabledStatus({
monitorId,
manuallyCreated: true,
status: disabled ? 'disabled' : 'enable',
});
return sendItemResponse(req, res, newMonitor);
} catch (error) {
return sendErrorResponse(req, res, error);
}
}
);
module.exports = router;

View File

@@ -16,6 +16,7 @@ module.exports = {
uptime: { r: 108, g: 219, b: 86, a: 1 },
downtime: { r: 250, g: 109, b: 70, a: 1 },
degraded: { r: 255, g: 222, b: 36, a: 1 },
disabled: { r: 136, g: 152, b: 170, a: 1 },
strokeChart: { r: 0, g: 0, b: 0, a: 1 },
fillChart: { r: 226, g: 225, b: 242, a: 1 },
},

View File

@@ -0,0 +1,32 @@
const { Mutex } = require('async-mutex');
const mongoose = require('mongoose');
const errorService = require('../services/errorService');
// this is a single mutex storage
// it contains one mutex per project
const projectMutexStorage = new Map();
/**
* gets an existing mutex for a project or creates a new one
*
* @param {*} projectId id of the project to use as a key
* @return {*} a mutex for the project
*/
const getProjectMutex = projectId => {
let projectMutex;
try {
if (mongoose.isValidObjectId(projectId)) {
projectMutex = projectMutexStorage.get(projectId);
if (!projectMutex) {
projectMutex = new Mutex();
projectMutexStorage.set(projectId, projectMutex);
}
}
return projectMutex;
} catch (error) {
errorService.log('ProjectMutexProvider.getProjectMutex', error);
return projectMutex;
}
};
module.exports = getProjectMutex;

View File

@@ -133,13 +133,22 @@ module.exports = {
isValidMonitor: async function(req, res, next) {
const id = req.params.id;
const monitor = await MonitorService.findBy({
let monitor = await MonitorService.findBy({
type: 'incomingHttpRequest',
'data.link': `${global.apiHost}/incomingHttpRequest/${id}`,
});
if (monitor && monitor.length) {
req.monitor = monitor && monitor[0] ? monitor[0] : monitor;
next();
monitor = monitor && monitor[0] ? monitor[0] : monitor;
if (monitor && monitor.disabled) {
return sendErrorResponse(req, res, {
code: 400,
message:
'Sorry this monitor is disabled.Please enable it to start monitoring again.',
});
} else {
req.monitor = monitor;
next();
}
} else {
return sendErrorResponse(req, res, {
code: 400,

View File

@@ -52,6 +52,7 @@ const monitorSchema = new Schema({
formData: [Object],
text: String,
headers: [Object],
disabled: { type: Boolean, default: false },
deleted: { type: Boolean, default: false },
deletedAt: {

View File

@@ -18,6 +18,7 @@ const monitorStatusSchema = new Schema({
type: Date,
default: null,
},
lastStatus: String,
createdAt: {
type: Date,
default: Date.now,

View File

@@ -10,7 +10,12 @@ const scheduleSchema = new Schema({
}, //which project this schedule belongs to.
createdById: { type: String, ref: 'User' },
monitorIds: [
{ type: Schema.Types.ObjectId, ref: 'Monitor', default: [], alias: 'monitors' },
{
type: Schema.Types.ObjectId,
ref: 'Monitor',
default: [],
alias: 'monitors',
},
],
escalationIds: [
{ type: String, ref: 'Escalation', default: [], alias: 'escalations' },

View File

@@ -5,34 +5,6 @@
*/
module.exports = {
hasEnoughBalance: async function(
projectId,
alertPhoneNumber,
userId,
alertType
) {
const project = await ProjectService.findOneBy({ _id: projectId });
const balance = project.balance;
const countryType = getCountryType(alertPhoneNumber);
const alertChargeAmount = getAlertChargeAmount(alertType, countryType);
const customThresholdAmount = project.alertOptions
? project.alertOptions.rechargeToBalance
: null;
const isBalanceMoreThanMinimum =
balance > alertChargeAmount.minimumBalance;
if (customThresholdAmount) {
const isBalanceMoreThanCustomThresholdAmount =
balance > customThresholdAmount;
return (
isBalanceMoreThanMinimum &&
isBalanceMoreThanCustomThresholdAmount
);
}
return isBalanceMoreThanMinimum;
},
doesPhoneNumberComplyWithHighRiskConfig: async function(
projectId,
alertPhoneNumber
@@ -837,34 +809,28 @@ module.exports = {
: 'Calls to High Risk country not enabled for this project',
});
}
const hasEnoughBalance = await _this.hasEnoughBalance(
project._id,
user.alertPhoneNumber,
const status = await PaymentService.checkAndRechargeProjectBalance(
project,
user._id,
user.alertPhoneNumber,
AlertType.Call
);
if (!hasEnoughBalance) {
// try to recharge amount
const projectBalanceRecharged = PaymentService.rechargeProjectBalance(
user._id,
project
);
if (!projectBalanceRecharged) {
return await _this.create({
projectId: incident.projectId,
monitorId,
schedule: schedule._id,
escalation: escalation._id,
onCallScheduleStatus: onCallScheduleStatus._id,
alertVia: AlertType.Call,
userId: user._id,
incidentId: incident._id,
alertStatus: null,
error: true,
errorMessage: 'Low Balance',
});
}
if (!status.success) {
return await _this.create({
projectId: incident.projectId,
monitorId,
schedule: schedule._id,
escalation: escalation._id,
onCallScheduleStatus: onCallScheduleStatus._id,
alertVia: AlertType.Call,
userId: user._id,
incidentId: incident._id,
alertStatus: null,
error: true,
errorMessage: status.message,
});
}
}
const alertStatus = await TwilioService.sendIncidentCreatedCall(
@@ -1028,34 +994,28 @@ module.exports = {
: 'SMS to High Risk country not enabled for this project',
});
}
const hasEnoughBalance = await _this.hasEnoughBalance(
incident.projectId,
user.alertPhoneNumber,
const status = await PaymentService.checkAndRechargeProjectBalance(
project,
user._id,
user.alertPhoneNumber,
AlertType.SMS
);
if (!hasEnoughBalance) {
// try to recharge amount
const projectBalanceRecharged = PaymentService.rechargeProjectBalance(
user._id,
project
);
if (!projectBalanceRecharged) {
return await _this.create({
projectId: incident.projectId,
monitorId,
schedule: schedule._id,
escalation: escalation._id,
onCallScheduleStatus: onCallScheduleStatus._id,
alertVia: AlertType.SMS,
userId: user._id,
incidentId: incident._id,
alertStatus: null,
error: true,
errorMessage: 'Low Balance',
});
}
if (!status.success) {
return await _this.create({
projectId: incident.projectId,
monitorId,
schedule: schedule._id,
escalation: escalation._id,
onCallScheduleStatus: onCallScheduleStatus._id,
alertVia: AlertType.SMS,
userId: user._id,
incidentId: incident._id,
alertStatus: null,
error: true,
errorMessage: status.message,
});
}
}
@@ -1139,7 +1099,6 @@ module.exports = {
const monitor = await MonitorService.findOneBy({
_id: incident.monitorId._id,
});
// eslint-disable-next-line no-unused-vars
const component = await ComponentService.findOneBy({
_id:
monitor.componentId && monitor.componentId._id
@@ -1776,14 +1735,43 @@ module.exports = {
const downTimeString = IncidentUtility.calculateHumanReadableDownTime(
incident.createdAt
);
webhookNotificationSent = await WebHookService.sendSubscriberNotification(
subscriber,
incident.projectId,
incident,
incident.monitorId,
component,
downTimeString
);
let alertStatus = 'Pending';
try {
webhookNotificationSent = await WebHookService.sendSubscriberNotification(
subscriber,
incident.projectId,
incident,
incident.monitorId,
component,
downTimeString
);
alertStatus = webhookNotificationSent ? 'Sent' : 'Not Sent';
} catch (error) {
alertStatus = null;
throw error;
} finally {
SubscriberAlertService.create({
projectId: incident.projectId,
incidentId: incident._id,
subscriberId: subscriber._id,
alertVia: AlertType.Webhook,
alertStatus: alertStatus,
eventType:
templateType === 'Subscriber Incident Acknowldeged'
? 'acknowledged'
: templateType ===
'Subscriber Incident Resolved'
? 'resolved'
: 'identified',
}).catch(error => {
ErrorService.log(
'AlertService.sendSubscriberAlert',
error
);
});
}
}
if (
!webhookNotificationSent ||
@@ -2087,38 +2075,32 @@ module.exports = {
: 'identified',
});
}
const hasEnoughBalance = await _this.hasEnoughBalance(
incident.projectId,
contactPhone,
const status = await PaymentService.checkAndRechargeProjectBalance(
project,
owner.userId,
contactPhone,
AlertType.SMS
);
if (!hasEnoughBalance) {
// try to recharge amount
const projectBalanceRecharged = PaymentService.rechargeProjectBalance(
owner.userId,
project
);
if (!projectBalanceRecharged) {
return await SubscriberAlertService.create({
projectId: incident.projectId,
incidentId: incident._id,
subscriberId: subscriber._id,
alertVia: AlertType.SMS,
alertStatus: null,
error: true,
errorMessage: 'Low Balance',
eventType:
templateType ===
'Subscriber Incident Acknowldeged'
? 'acknowledged'
: templateType ===
'Subscriber Incident Resolved'
? 'resolved'
: 'identified',
});
}
if (!status.success) {
return await SubscriberAlertService.create({
projectId: incident.projectId,
incidentId: incident._id,
subscriberId: subscriber._id,
alertVia: AlertType.SMS,
alertStatus: null,
error: true,
errorMessage: status.message,
eventType:
templateType ===
'Subscriber Incident Acknowldeged'
? 'acknowledged'
: templateType ===
'Subscriber Incident Resolved'
? 'resolved'
: 'identified',
});
}
}
@@ -2424,14 +2406,23 @@ module.exports = {
}
},
getBalanceStatus: async function(projectId, alertPhoneNumber, alertType) {
const project = await ProjectService.findOneBy({ _id: projectId });
const balance = project.balance;
const countryType = getCountryType(alertPhoneNumber);
const alertChargeAmount = getAlertChargeAmount(alertType, countryType);
return {
chargeAmount: alertChargeAmount.price,
closingBalance: balance,
};
try {
const project = await ProjectService.findOneBy({ _id: projectId });
const balance = project.balance;
const countryType = getCountryType(alertPhoneNumber);
const alertChargeAmount = getAlertChargeAmount(
alertType,
countryType
);
const closingBalance = balance - alertChargeAmount.price;
return {
chargeAmount: alertChargeAmount.price,
closingBalance,
};
} catch (error) {
ErrorService.log('AlertService.getBalanceStatus', error);
throw error;
}
},
//Return true, if the limit is not reached yet.

View File

@@ -39,112 +39,124 @@ module.exports = {
create: async function(data) {
try {
const _this = this;
//create a promise;
const project = await ProjectService.findOneBy({
_id: data.projectId,
});
const users =
project && project.users && project.users.length
? project.users.map(({ userId }) => userId)
: [];
const monitor = await MonitorService.findOneBy({
_id: data.monitorId,
});
if (monitor) {
let incident = new IncidentModel();
const incidentsCountInProject = await _this.countBy({
projectId: data.projectId,
});
const deletedIncidentsCountInProject = await _this.countBy({
projectId: data.projectId,
deleted: true,
});
incident.projectId = data.projectId || null;
incident.monitorId = data.monitorId || null;
incident.createdById = data.createdById || null;
incident.notClosedBy = users;
incident.incidentType = data.incidentType;
incident.manuallyCreated = data.manuallyCreated || false;
if (data.reason && data.reason.length > 0) {
incident.reason = data.reason.join('\n');
}
incident.response = data.response || null;
incident.idNumber =
incidentsCountInProject +
deletedIncidentsCountInProject +
1;
if (!incident.manuallyCreated) {
const incidentSettings = await IncidentSettingsService.findOne(
{
projectId: data.projectId,
}
);
const templatesInput = {
incidentType: data.incidentType,
monitorName: monitor.name,
projectName: project.name,
time: Moment().format('h:mm:ss a'),
date: Moment().format('MMM Do YYYY'),
};
const titleTemplate = Handlebars.compile(
incidentSettings.title
);
const descriptionTemplate = Handlebars.compile(
incidentSettings.description
);
incident.title = titleTemplate(templatesInput);
incident.description = descriptionTemplate(templatesInput);
incident.incidentPriority =
incidentSettings.incidentPriority;
if (data.probeId) {
incident.probes = [
{
probeId: data.probeId,
updatedAt: Date.now(),
status: true,
reportedStatus: data.incidentType,
},
];
}
} else {
incident.title = data.title;
incident.description = data.description;
incident.incidentPriority = data.incidentPriority;
}
incident = await incident.save();
_this.startInterval(data.projectId, data.monitorId, incident);
incident = await _this.findOneBy({ _id: incident._id });
const notification = await _this._sendIncidentCreatedAlert(
incident
);
incident.notificationId = notification._id;
incident = await incident.save();
await RealTimeService.sendCreatedIncident(incident);
await IncidentTimelineService.create({
incidentId: incident._id,
createdById: data.createdById,
probeId: data.probeId,
status: data.incidentType,
});
return incident;
} else {
const error = new Error('Monitor is not present.');
if (monitor && monitor.disabled) {
const error = new Error('Monitor is disabled.');
ErrorService.log('incidentService.create', error);
error.code = 400;
throw error;
} else {
const project = await ProjectService.findOneBy({
_id: data.projectId,
});
const users =
project && project.users && project.users.length
? project.users.map(({ userId }) => userId)
: [];
if (monitor) {
let incident = new IncidentModel();
const incidentsCountInProject = await _this.countBy({
projectId: data.projectId,
});
const deletedIncidentsCountInProject = await _this.countBy({
projectId: data.projectId,
deleted: true,
});
incident.projectId = data.projectId || null;
incident.monitorId = data.monitorId || null;
incident.createdById = data.createdById || null;
incident.notClosedBy = users;
incident.incidentType = data.incidentType;
incident.manuallyCreated = data.manuallyCreated || false;
if (data.reason && data.reason.length > 0) {
incident.reason = data.reason.join('\n');
}
incident.response = data.response || null;
incident.idNumber =
incidentsCountInProject +
deletedIncidentsCountInProject +
1;
if (!incident.manuallyCreated) {
const incidentSettings = await IncidentSettingsService.findOne(
{
projectId: data.projectId,
}
);
const templatesInput = {
incidentType: data.incidentType,
monitorName: monitor.name,
projectName: project.name,
time: Moment().format('h:mm:ss a'),
date: Moment().format('MMM Do YYYY'),
};
const titleTemplate = Handlebars.compile(
incidentSettings.title
);
const descriptionTemplate = Handlebars.compile(
incidentSettings.description
);
incident.title = titleTemplate(templatesInput);
incident.description = descriptionTemplate(
templatesInput
);
incident.incidentPriority =
incidentSettings.incidentPriority;
if (data.probeId) {
incident.probes = [
{
probeId: data.probeId,
updatedAt: Date.now(),
status: true,
reportedStatus: data.incidentType,
},
];
}
} else {
incident.title = data.title;
incident.description = data.description;
incident.incidentPriority = data.incidentPriority;
}
incident = await incident.save();
_this.startInterval(
data.projectId,
data.monitorId,
incident
);
incident = await _this.findOneBy({ _id: incident._id });
const notification = await _this._sendIncidentCreatedAlert(
incident
);
incident.notificationId = notification._id;
incident = await incident.save();
await RealTimeService.sendCreatedIncident(incident);
await IncidentTimelineService.create({
incidentId: incident._id,
createdById: data.createdById,
probeId: data.probeId,
status: data.incidentType,
});
return incident;
} else {
const error = new Error('Monitor is not present.');
ErrorService.log('incidentService.create', error);
error.code = 400;
throw error;
}
}
} catch (error) {
ErrorService.log('incidentService.create', error);

View File

@@ -431,6 +431,7 @@ module.exports = {
$and: [
{
deleted: false,
disabled: false,
scriptRunStatus: { $nin: ['inProgress'] },
},
{

View File

@@ -1,10 +1,10 @@
module.exports = {
create: async function(data) {
try {
const previousMonitorStatus = await this.findOneBy({
monitorId: data.monitorId,
probeId: data.probeId,
});
const query = {};
if (data.monitorId) query.monitorId = data.monitorId;
if (data.probeId) query.probeId = data.probeId;
const previousMonitorStatus = await this.findOneBy(query);
if (
!previousMonitorStatus ||
(previousMonitorStatus &&
@@ -14,6 +14,13 @@ module.exports = {
// check if previous status is different from the current status
// if different, end the previous status and create a new monitor status
if (previousMonitorStatus) {
if (
data.status === 'enable' &&
previousMonitorStatus.status === 'disabled' &&
previousMonitorStatus.lastStatus
) {
data.status = previousMonitorStatus.lastStatus;
}
await this.updateOneBy(
{
_id: previousMonitorStatus._id,
@@ -25,7 +32,9 @@ module.exports = {
}
const monitorStatus = new MonitorStatusModel();
if (data.lastStatus) {
monitorStatus.lastStatus = data.lastStatus;
}
monitorStatus.monitorId = data.monitorId;
monitorStatus.probeId = data.probeId || null;
monitorStatus.incidentId = data.incidentId || null;

View File

@@ -1,28 +1,136 @@
module.exports = {
/**
*checks whether a project's balance is enough
*
* @param {*} projectId ID of project
* @param {*} alertPhoneNumber alertNumber
* @param {*} userId ID of user
* @param {*} alertType type of alert
* @return {boolean} whether the project has enough balance
*/
hasEnoughBalance: async (
projectId,
alertPhoneNumber,
userId,
alertType
) => {
try {
const project = await ProjectService.findOneBy({ _id: projectId });
const balance = project.balance;
const countryType = getCountryType(alertPhoneNumber);
const alertChargeAmount = getAlertChargeAmount(
alertType,
countryType
);
const customThresholdAmount = project.alertOptions
? project.alertOptions.minimumBalance
: null;
const isBalanceMoreThanMinimum =
balance > alertChargeAmount.minimumBalance;
if (customThresholdAmount) {
const isBalanceMoreThanCustomThresholdAmount =
balance > customThresholdAmount;
return (
isBalanceMoreThanMinimum &&
isBalanceMoreThanCustomThresholdAmount
);
}
return isBalanceMoreThanMinimum;
} catch (error) {
ErrorService.log('PaymentService.hasEnoughBalance', error);
return false;
}
},
/**
* rechargest the project with the amount set in the project's alert options
* @param {*} userId current user id
* @param {*} project project to add blance to
* @returns {boolean} whether the balance is recharged to the project
*/
rechargeProjectBalance: async function(userId, project) {
let balanceRecharged;
fillProjectBalance: async (userId, project) => {
try {
let balanceRecharged;
const rechargeAmount = project.alertOptions
? project.alertOptions.rechargeToBalance
: null;
if (rechargeAmount) {
balanceRecharged = await StripeService.addBalance(
const rechargeAmount = project.alertOptions
? project.alertOptions.rechargeToBalance
: null;
if (rechargeAmount) {
balanceRecharged = await StripeService.addBalance(
userId,
rechargeAmount,
project._id.toString()
);
return balanceRecharged;
}
return false;
} catch (error) {
ErrorService.log('PaymentService.fillProjectBalance', error);
return false;
}
},
/**
* synchronously recharges a project balance if low
* @param {*} projectId ID of the project to check and recharge balance
* @param {*} userId ID of user
* @param {*} alertPhoneNumber alertNumber
* @param {*} alertType type of alert
* @returns {{success : boolean, message : string}} whether the balance is recharged successfully
*/
checkAndRechargeProjectBalance: async function(
project,
userId,
alertPhoneNumber,
alertType
) {
let release;
try {
const status = {};
const mutex = getProjectMutex(project._id.toString());
release = await mutex.acquire();
// check balance
const isBalanceEnough = await this.hasEnoughBalance(
project._id,
alertPhoneNumber,
userId,
rechargeAmount,
project._id.toString()
alertType
);
return balanceRecharged;
}
if (!isBalanceEnough) {
const lowBalanceRecharged = await this.fillProjectBalance(
userId,
project
);
if (lowBalanceRecharged) {
status.success = true;
status.message = 'Balance recharged successfully';
} else {
status.success = false;
status.message = 'Low Balance';
}
} else {
status.success = true;
status.message = 'Balance is enough';
}
return false;
return status;
} catch (error) {
ErrorService.log(
'PaymentService.checkAndRechargeProjectBalance',
error
);
throw error;
} finally {
if (release) {
release();
}
}
},
//Description: Retrieve payment intent.
//Params:
//Param 1: paymentIntent: Payment Intent
@@ -301,3 +409,5 @@ const ProjectService = require('./projectService');
const ProjectModel = require('../models/project');
const StripeService = require('./stripeService');
const NotificationService = require('./notificationService');
const { getAlertChargeAmount, getCountryType } = require('../config/alertType');
const getProjectMutex = require('../constants/projectMutexProvider');

View File

@@ -179,6 +179,27 @@ module.exports = {
}
},
createMonitorDisabledStatus: async function(data) {
try {
let monitorStatus = await MonitorStatusService.findOneBy({
monitorId: data.monitorId,
});
const lastStatus =
monitorStatus && monitorStatus.status
? monitorStatus.status
: null;
if (!lastStatus || (lastStatus && lastStatus !== data.status)) {
data.lastStatus = lastStatus ? lastStatus : null;
monitorStatus = await MonitorStatusService.create(data);
}
return monitorStatus;
} catch (error) {
ErrorService.log('ProbeService.createMonitorDisabledStatus', error);
throw error;
}
},
saveMonitorLog: async function(data) {
try {
const _this = this;

View File

@@ -292,7 +292,7 @@ const Services = {
metadata
);
// IMPORTANT: Payment Intent is sent for confirmation instally, not using the Stripe Webhook anymore.
paymentIntent = this.confirmPayment(paymentIntent);
paymentIntent = await this.confirmPayment(paymentIntent);
return paymentIntent;
} catch (error) {
ErrorService.log('stripeService.addBalance', error);

View File

@@ -125,6 +125,7 @@ module.exports = {
color: green,
title: `Incident Resolved`,
title_link: uri,
incidentId: incident._id,
text: `Incident on *${component.name} / ${
monitor.name
}* is resolved by ${
@@ -144,6 +145,7 @@ module.exports = {
color: yellow,
title: `Incident Acknowledged`,
title_link: uri,
incidentId: incident._id,
text: `Incident on *${component.name} / ${
monitor.name
}* is acknowledged by ${
@@ -169,6 +171,11 @@ module.exports = {
title: `New ${incident.incidentType} incident for ${monitor.name}`,
title_link: uri,
fields: [
{
title: 'Incident ID:',
value: incident._id,
short: true,
},
{
title: 'Project Name:',
value: project.name,
@@ -209,7 +216,7 @@ module.exports = {
]
: []),
{
title: 'Created By:',
title: 'Cause:',
value: incident.createdById
? incident.createdById.name
: 'Fyipe',
@@ -235,9 +242,10 @@ module.exports = {
monitorName: monitor.name,
monitorId: monitor._id,
projectId: project._id,
incidentId: incident._id,
projectName: project.name,
createdAt: incident.createdAt,
createdBy: incident.createdById
cause: incident.createdById
? incident.createdById.name
: 'Fyipe',
incidentStatus: incident.incidentType,

1083
backend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"airtable": "^0.10.0",
"async-mutex": "^0.2.6",
"axios": "^0.21.0",
"bcrypt": "^5.0.0",
"body-parser": "^1.19.0",
@@ -56,17 +57,16 @@
"dev": "cross-env NODE_ENV=development nodemon server.js",
"test": "cross-env NODE_ENV=development mocha --exit test/index.js",
"enterprise-test": "cross-env NODE_ENV=development mocha --exit test/enterprise.js",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='ejs'"
},
"devDependencies": {
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"chai-subset": "^1.6.0",
"depcheck": "^0.9.2",
"mocha": "^8.2.1",
"nodemon": "^2.0.4",
"npm-audit-ci-wrapper": "^2.5.1",
"sinon": "^4.5.0",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"chai-subset": "^1.6.0"
"sinon": "^4.5.0"
}
}

View File

@@ -1300,6 +1300,74 @@ describe('SMS/Calls Incident Alerts', function() {
expect(alertsSentList.includes('sms')).to.equal(true);
expect(alertsSentList.includes('call')).to.equal(true);
});
/**
* Global twilio settings: set
* Custom twilio settings: not set
* Global twilio settings SMS enable : true
* Global twilio settings Call enable : true
* SMS/Call alerts enabled for the project (billing): true
*/
it('should not cut project balance for invalid twilio settings', async function() {
// update global setting to enable call and sms
const globalSettings = await GlobalConfigModel.findOne({
name: 'twilio',
});
const { value } = globalSettings;
value['sms-enabled'] = true;
value['call-enabled'] = true;
// add a wrong config to twilio
value.phone = '+111111111';
await GlobalConfigModel.findOneAndUpdate(
{ name: 'twilio' },
{ value }
);
// enable billing for the project
const billingEndpointResponse = await request
.put(`/project/${projectId}/alertOptions`)
.set('Authorization', authorization)
.send({
alertEnable: true,
billingNonUSCountries: true,
billingRiskCountries: true,
billingUS: true,
minimumBalance: '100',
rechargeToBalance: '200',
_id: projectId,
});
expect(billingEndpointResponse).to.have.status(200);
// get the project balance before an alert is sent
const {
balance: originalProjectBalance,
} = await ProjectService.findOneBy({ _id: projectId });
const newIncident = await createIncident({
request,
authorization,
projectId,
monitorId,
payload: {
monitorId,
projectId,
title: 'test monitor is offline.',
incidentType: 'offline',
description: 'Incident description',
},
});
expect(newIncident).to.have.status(200);
await sleep(10 * 1000);
const {
balance: newProjectBalance,
} = await ProjectService.findOneBy({ _id: projectId });
expect(newProjectBalance).to.equal(originalProjectBalance);
});
/**
* Global twilio settings: set
* Custom twilio settings: not set
@@ -1358,17 +1426,18 @@ describe('SMS/Calls Incident Alerts', function() {
});
expect(newIncident).to.have.status(200);
await sleep(10 * 1000);
await sleep(15 * 1000);
// check the balance again
const { balance, alertOptions } = await ProjectService.findOneBy({
_id: projectId,
});
const rechargeAmount =
(alertOptions && alertOptions.rechargeToBalance) || NaN;
const { rechargeToBalance, minimumBalance } = alertOptions;
expect(balance).to.equal(rechargeAmount);
expect(balance).to.be.lessThan(rechargeToBalance);
expect(balance).to.be.greaterThan(minimumBalance);
});
});
describe('Custom twilio settings are set', async () => {

View File

@@ -9,7 +9,7 @@ audit_accounts:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd accounts
- npm ci

View File

@@ -9,7 +9,7 @@ audit_admin-dashboard:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd admin-dashboard
- npm ci

View File

@@ -9,7 +9,7 @@ audit_api-docs:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd api-docs
- npm ci

View File

@@ -9,7 +9,7 @@ audit_backend:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd backend
- npm ci

View File

@@ -9,7 +9,7 @@ audit_dashboard:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd dashboard
- npm ci

View File

@@ -9,7 +9,7 @@ audit_helm-chart:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
# Lint helm chart - helm lint needs a kubeconfig file and this is why we do staging deployment setup.
- chmod +x ./ci/scripts/deployment-setup.sh

View File

@@ -9,7 +9,7 @@ audit_home:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd home
- npm ci

View File

@@ -8,7 +8,7 @@ audit_http_test_server:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd http-test-server
- npm ci

View File

@@ -9,7 +9,7 @@ audit_init-script:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd init-script
- npm ci

View File

@@ -9,7 +9,7 @@ audit_java-sdk:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y maven
- sudo apt-get remove -y --purge openjdk* java-common default-jdk
- sudo apt-get autoremove -y --purge

View File

@@ -9,7 +9,7 @@ audit_js-sdk:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd js-sdk
- npm ci

View File

@@ -9,7 +9,7 @@ audit_licensing:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd licensing
- npm ci

View File

@@ -9,7 +9,7 @@ audit_probe:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd probe
- npm ci

View File

@@ -9,7 +9,7 @@ audit_server-monitor:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd server-monitor
- npm ci

View File

@@ -9,7 +9,7 @@ audit_statuspage:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd status-page
- npm ci

View File

@@ -9,7 +9,7 @@ audit_zapier:
- sudo apt-get update
- sudo apt-get install -y curl gcc
- sudo apt-get install -y build-essential
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
- sudo apt-get install -y nodejs
- cd zapier
- npm ci

27612
dashboard/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -54,7 +54,7 @@
"react-ga": "^2.5.3",
"react-google-charts": "^3.0.15",
"react-hover-observer": "^2.1.0",
"react-json-view": "^1.19.1",
"react-json-view": "^1.10.2",
"react-markdown": "^4.3.1",
"react-phone-input-2": "^2.13.8",
"react-redux": "^5.0.7",
@@ -91,7 +91,7 @@
"enterprise-test": "jest --forceExit --runInBand ./src/test/puppeteer/*.test.enterprise.js",
"start": "node index.js",
"dep-check": "depcheck ./ --skip-missing=true --ignores='eslint,babel-*,browserslist,loadable-components,@beam-australia/react-env'",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"fix-lint": "eslint . --fix"
},
"devDependencies": {
@@ -100,10 +100,9 @@
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-runtime": "^6.26.0",
"depcheck": "^0.9.2",
"depcheck": "^1.3.1",
"fyipe-server-monitor": "^3.0.6010",
"jest-localstorage-mock": "^2.2.0",
"npm-audit-ci-wrapper": "^2.5.1",
"redux-mock-store": "^1.5.3",
"should": "^13.2.3",
"workbox-build": "^4.3.1"

View File

@@ -325,6 +325,68 @@ export function deleteProjectMonitors(projectId) {
};
}
//Disable a monitor
export function disableMonitor(monitorId, projectId) {
return function(dispatch) {
const promise = postApi(
`monitor/${projectId}/disableMonitor/${monitorId}`,
{
monitorId,
}
);
dispatch(disableMonitorRequest(monitorId));
promise.then(
function(monitor) {
dispatch(
disableMonitorSuccess({
monitorId: monitor.data._id,
disable: monitor.data.disabled,
})
);
},
function(error) {
if (error && error.response && error.response.data)
error = error.response.data;
if (error && error.data) {
error = error.data;
}
if (error && error.message) {
error = error.message;
} else {
error = 'Network Error';
}
dispatch(
disableMonitorFailure({ error: errors(error), monitorId })
);
}
);
return promise;
};
}
export function disableMonitorSuccess(monitorData) {
return {
type: types.DISABLE_MONITOR_SUCCESS,
payload: monitorData,
};
}
export function disableMonitorRequest(monitorId) {
return {
type: types.DISABLE_MONITOR_REQUEST,
payload: monitorId,
};
}
export function disableMonitorFailure(error) {
return {
type: types.DISABLE_MONITOR_FAILURE,
payload: error,
};
}
//Fetch Incidents of monitors
//props -> {name: '', type, data -> { data.url}}
export function fetchMonitorsIncidents(projectId, monitorId, skip, limit) {

View File

@@ -32,6 +32,7 @@ class ResourceTabularList extends Component {
case 'api monitor':
case 'server monitor':
case 'script monitor':
case 'incomingHttpRequest monitor':
route = 'monitoring';
break;
case 'application security':
@@ -65,13 +66,17 @@ class ResourceTabularList extends Component {
case 'api monitor':
case 'server monitor':
case 'script monitor':
case 'incomingHttpRequest monitor':
// get monitor status
monitor = monitors.filter(
monitor => monitor._id === componentResource._id
)[0];
// Monitor already exists in the list of monitors
if (monitor) {
if (monitor.statuses && monitor.statuses[0]) {
if (monitor.disabled) {
// Get the latest status here if the monitor is changing status elsewheree
monitorStatus = 'disabled';
} else if (monitor.statuses && monitor.statuses[0]) {
// Get the latest status here if the monitor is changing status elsewheree
monitorStatus = monitor.statuses[0].statuses[0].status;
} else {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,124 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { FormLoader } from '../basic/Loader';
import { connect } from 'react-redux';
class DisableMonitor extends Component {
componentDidMount() {
window.addEventListener('keydown', this.handleKeyBoard);
}
componentWillUnmount() {
window.removeEventListener('keydown', this.handleKeyBoard);
}
handleKeyBoard = e => {
switch (e.key) {
case 'Escape':
return this.props.closeThisDialog();
case 'Enter':
return this.props.confirmThisDialog();
default:
return false;
}
};
render() {
let disabling = false;
if (
this.props.monitorState &&
this.props.monitorState.disableMonitor &&
this.props.monitorState.disableMonitor ===
this.props.data.monitor._id
) {
disabling = true;
}
const monitorOption =
this.props.data &&
this.props.data.monitor &&
this.props.data.monitor.disabled &&
this.props.data.monitor.disabled === true
? 'Enable'
: 'Disable';
return (
<div className="ModalLayer-wash Box-root Flex-flex Flex-alignItems--flexStart Flex-justifyContent--center">
<div
className="ModalLayer-contents"
tabIndex={-1}
style={{ marginTop: 40 }}
>
<div className="bs-BIM">
<div className="bs-Modal bs-Modal--medium">
<div className="bs-Modal-header">
<div className="bs-Modal-header-copy">
<span className="Text-color--inherit Text-display--inline Text-fontSize--20 Text-fontWeight--medium Text-lineHeight--24 Text-typeface--base Text-wrap--wrap">
<span>Confirm {monitorOption}</span>
</span>
</div>
</div>
<div className="bs-Modal-content">
<span className="Text-color--inherit Text-display--inline Text-fontSize--14 Text-fontWeight--regular Text-lineHeight--24 Text-typeface--base Text-wrap--wrap">
Are you sure you want to {monitorOption}{' '}
this monitor ?
</span>
</div>
<div className="bs-Modal-footer">
<div className="bs-Modal-footer-actions">
<button
className="bs-Button bs-DeprecatedButton bs-Button--grey btn__modal"
type="button"
onClick={this.props.closeThisDialog}
>
<span>Cancel</span>
<span className="cancel-btn__keycode">
Esc
</span>
</button>
<button
id="deleteMonitor"
className="bs-Button bs-DeprecatedButton bs-Button--red btn__modal"
type="button"
onClick={this.props.confirmThisDialog}
disabled={disabling}
autoFocus={true}
>
{!disabling && (
<>
<span>{monitorOption}</span>
<span className="delete-btn__keycode">
<span className="keycode__icon keycode__icon--enter" />
</span>
</>
)}
{disabling && <FormLoader />}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
DisableMonitor.displayName = 'DisableMonitorFormModal';
DisableMonitor.propTypes = {
confirmThisDialog: PropTypes.func.isRequired,
closeThisDialog: PropTypes.func.isRequired,
monitorState: PropTypes.object,
data: PropTypes.object,
};
const mapStateToProps = state => {
return {
monitorState: state.monitor,
};
};
const mapDispatchToProps = state_Ignored => {
return null;
};
export default connect(mapStateToProps, mapDispatchToProps)(DisableMonitor);

View File

@@ -0,0 +1,83 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class DisabledMessage extends Component {
componentDidMount() {
window.addEventListener('keydown', this.handleKeyBoard);
}
componentWillUnmount() {
window.removeEventListener('keydown', this.handleKeyBoard);
}
handleKeyBoard = e => {
switch (e.key) {
case 'Escape':
case 'Enter':
return this.props.closeThisDialog();
default:
return false;
}
};
render() {
return (
<div
className="ModalLayer-wash Box-root Flex-flex Flex-alignItems--flexStart Flex-justifyContent--center"
id="unauthorisedModal"
>
<div
className="ModalLayer-contents"
tabIndex={-1}
style={{ marginTop: 40 }}
>
<div className="bs-BIM">
<div className="bs-Modal bs-Modal--medium">
<div className="bs-Modal-header">
<div className="bs-Modal-header-copy">
<span className="Text-color--inherit Text-display--inline Text-fontSize--20 Text-fontWeight--medium Text-lineHeight--24 Text-typeface--base Text-wrap--wrap">
<span>Unauthorised Action</span>
</span>
</div>
</div>
<div className="bs-Modal-content">
<span className="Text-color--inherit Text-display--inline Text-fontSize--14 Text-fontWeight--regular Text-lineHeight--24 Text-typeface--base Text-wrap--wrap">
This monitor is disabled. You can not create
an incident on a disabled monitor. please
enable the monitor to create incidents.
</span>
</div>
<div className="bs-Modal-footer">
<div className="bs-Modal-footer-actions">
<button
className="bs-Button bs-DeprecatedButton bs-Button--grey btn__modal"
style={{
minWidth: 50,
textAlign: 'center',
}}
type="button"
onClick={this.props.closeThisDialog}
autoFocus={true}
>
<span>Ok</span>
<span className="cancel-btn__keycode">
Esc
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
DisabledMessage.displayName = 'DisabledMessage';
DisabledMessage.propTypes = {
closeThisDialog: PropTypes.func.isRequired,
};
export default DisabledMessage;

View File

@@ -283,9 +283,43 @@ export function MonitorChart({
const isCurrentlyNotMonitoring =
(lastAlive && moment(now).diff(moment(lastAlive), 'seconds') >= 300) ||
!lastAlive;
const isDisabled = monitor && monitor.disabled;
let monitorInfo;
if (type === 'server-monitor') {
if (isDisabled) {
monitorInfo = (
<div className="db-Trend">
<div className="block-chart-side line-chart">
<div className="db-TrendRow">
<div className="db-Trend-colInformation probe-offline">
<div
className="db-Trend-rowTitle"
title="Currently not monitoring"
>
<div className="db-Trend-title">
<strong>
<span className="chart-font">
Currently Disabled
</span>
</strong>
</div>
</div>
<div className="db-Trend-rowTitle">
<div className="db-Trend-title description">
<small>
<span className="chart-font">
We&apos;re currently not monitoring
this monitor.please reenable it to
resume monitoring.
</span>
</small>
</div>
</div>
</div>
</div>
</div>
</div>
);
} else if (type === 'server-monitor') {
monitorInfo = (
<Fragment>
<div className="db-Trend">

View File

@@ -18,6 +18,7 @@ import { FormLoader } from '../basic/Loader';
import CreateManualIncident from '../modals/CreateManualIncident';
import ShouldRender from '../basic/ShouldRender';
import MonitorUrl from '../modals/MonitorUrl';
import DisabledMessage from '../modals/DisabledMessage';
import DataPathHoC from '../DataPathHoC';
import Badge from '../common/Badge';
import { history } from '../../store';
@@ -211,7 +212,10 @@ export class MonitorDetail extends Component {
);
const requesting = monitorState.fetchMonitorLogsRequest;
const status = requesting
const monitorDisabled = monitor.disabled;
const status = monitorDisabled
? 'disabled'
: requesting
? 'requesting'
: getMonitorStatus(monitor.incidents, logs);
@@ -487,7 +491,9 @@ export class MonitorDetail extends Component {
this.props.openModal({
id: createIncidentModalId,
content: DataPathHoC(
CreateManualIncident,
monitorDisabled
? DisabledMessage
: CreateManualIncident,
{
monitorId: monitor._id,
projectId:
@@ -635,7 +641,8 @@ export class MonitorDetail extends Component {
which
belong
to this
monitor.
monitor
2.
</span>
</span>
</div>
@@ -698,7 +705,7 @@ export class MonitorDetail extends Component {
incidents
which belong
to this
monitor.
monitor 1.
</span>
</span>
</div>

View File

@@ -86,7 +86,6 @@ export class MonitorTitle extends Component {
badgeColor = 'blue';
break;
}
const isCurrentlyNotMonitoring =
(lastAlive &&
moment(this.state.now).diff(moment(lastAlive), 'seconds') >=

View File

@@ -0,0 +1,153 @@
import uuid from 'uuid';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { bindActionCreators } from 'redux';
import { FormLoader } from '../basic/Loader';
import ShouldRender from '../basic/ShouldRender';
import { openModal, closeModal } from '../../actions/modal';
import DisableMonitor from '../modals/DisableMonitor';
import { disableMonitor } from '../../actions/monitor';
import { history } from '../../store';
import DataPathHoC from '../DataPathHoC';
import { logEvent } from '../../analytics';
import { SHOULD_LOG_ANALYTICS } from '../../config';
export class MonitorViewDisableBox extends Component {
constructor(props) {
super(props);
this.state = { disableModalId: uuid.v4() };
}
disableMonitor = () => {
const projectId =
this.props.monitor.projectId._id || this.props.monitor.projectId;
const promise = this.props.disableMonitor(
this.props.monitor._id,
projectId
);
history.push(
`/dashboard/project/${this.props.currentProject._id}/${this.props.componentId}/monitoring`
);
if (SHOULD_LOG_ANALYTICS) {
logEvent(
'EVENT: DASHBOARD > PROJECT > COMPONENT > MONITOR > MONITOR DISABLED',
{
ProjectId: this.props.currentProject._id,
monitorId: this.props.monitor._id,
}
);
}
return promise;
};
handleKeyBoard = e => {
switch (e.key) {
case 'Escape':
return this.props.closeModal({ id: this.state.disableModalId });
default:
return false;
}
};
render() {
let disabling = false;
if (
this.props.monitorState &&
this.props.monitorState.disableMonitor &&
this.props.monitorState.disableMonitor === this.props.monitor._id
) {
disabling = true;
}
const { disableModalId } = this.state;
const disabledMonitor =
this.props.monitor && this.props.monitor.disabled;
return (
<div
onKeyDown={this.handleKeyBoard}
className="Box-root Margin-bottom--12"
>
<div className="bs-ContentSection Card-root Card-shadow--medium">
<div className="Box-root">
<div className="bs-ContentSection-content Box-root Box-divider--surface-bottom-1 Flex-flex Flex-alignItems--center Flex-justifyContent--spaceBetween Padding-horizontal--20 Padding-vertical--16">
<div className="Box-root">
<span className="Text-color--inherit Text-display--inline Text-fontSize--16 Text-fontWeight--medium Text-lineHeight--24 Text-typeface--base Text-wrap--wrap">
<span>Disable Monitor</span>
</span>
<p>
<span>
Click the button to disable this
monitor.
</span>
</p>
</div>
<div className="bs-ContentSection-footer bs-ContentSection-content Box-root Box-background--white Flex-flex Flex-alignItems--center Flex-justifyContent--spaceBetween Padding-horizontal--0 Padding-vertical--12">
<span className="db-SettingsForm-footerMessage"></span>
<div>
<button
className="bs-Button bs-DeprecatedButton bs-Button--grey"
disabled={disabling}
id={`disable_${this.props.monitor.name}`}
onClick={() =>
this.props.openModal({
id: disableModalId,
onClose: () => '',
onConfirm: () =>
this.disableMonitor(),
content: DataPathHoC(
DisableMonitor,
{
monitor: this.props
.monitor,
}
),
})
}
>
<ShouldRender if={!disabling}>
<span>
{disabledMonitor
? 'Enable'
: 'Disable'}
</span>
</ShouldRender>
<ShouldRender if={disabling}>
<FormLoader />
</ShouldRender>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
MonitorViewDisableBox.displayName = 'MonitorViewDisableBox';
const mapDispatchToProps = dispatch =>
bindActionCreators({ openModal, closeModal, disableMonitor }, dispatch);
const mapStateToProps = state => {
return {
monitorState: state.monitor,
currentProject: state.project.currentProject,
};
};
MonitorViewDisableBox.propTypes = {
currentProject: PropTypes.object.isRequired,
componentId: PropTypes.string.isRequired,
closeModal: PropTypes.func,
openModal: PropTypes.func.isRequired,
monitorState: PropTypes.object.isRequired,
monitor: PropTypes.object.isRequired,
disableMonitor: PropTypes.func.isRequired,
};
export default withRouter(
connect(mapStateToProps, mapDispatchToProps)(MonitorViewDisableBox)
);

View File

@@ -28,6 +28,7 @@ import { logEvent } from '../../analytics';
import { SHOULD_LOG_ANALYTICS } from '../../config';
import CreateManualIncident from '../modals/CreateManualIncident';
import DateTimeRangePicker from '../basic/DateTimeRangePicker';
import DisabledMessage from '../modals/DisabledMessage';
export class MonitorViewHeader extends Component {
constructor(props) {
@@ -171,7 +172,10 @@ export class MonitorViewHeader extends Component {
);
const monitorType = monitor.type;
const requesting = monitorState.fetchMonitorLogsRequest;
const status = requesting
const monitorDisabled = monitor.disabled;
const status = monitorDisabled
? 'disabled'
: requesting
? 'requesting'
: getMonitorStatus(
monitor.incidents,
@@ -264,7 +268,9 @@ export class MonitorViewHeader extends Component {
this.props.openModal({
id: createIncidentModalId,
content: DataPathHoC(
CreateManualIncident,
monitorDisabled
? DisabledMessage
: CreateManualIncident,
{
monitorId: monitor._id,
projectId:

View File

@@ -1580,77 +1580,50 @@ class NewMonitor extends Component {
Call Schedule
</label>
<div className="bs-Fieldset-fields">
<span class="flex">
<Field
className="db-select-nw"
component={
RenderSelect
}
name={`callSchedule_${this.props.index}`}
id="callSchedule"
placeholder="Call Schedule"
disabled={
requesting
}
style={{
height:
'28px',
}}
options={[
{
value:
'',
label:
'Select call schedule',
},
...(schedules &&
schedules.length >
0
? schedules.map(
schedule => ({
value:
schedule._id,
label:
schedule.name,
})
)
: []),
]}
/>
<Tooltip title="Call Schedule">
<div>
<p>
Call
Schedules
let's
you
connect
your
team
members
to
specific
monitors,
so
only
on-duty
members
who
are
responsible
for
certain
monitors
are
alerted
when
an
incident
is
created.
</p>
</div>
</Tooltip>
<span className="flex" >
<Field
className="db-select-nw"
component={
RenderSelect
}
name={`callSchedule_${this.props.index}`}
id="callSchedule"
placeholder="Call Schedule"
disabled={
requesting
}
style={{
height:
'28px',
}}
options={[
{
value:
'',
label:
'Select call schedule',
},
...(schedules &&
schedules.length >
0
? schedules.map(
schedule => ({
value:
schedule._id,
label:
schedule.name,
})
)
: []),
]}
/>
<Tooltip title="Call Schedule">
<div>
<p>
Call Schedules let's you connect your team members to specific monitors, so only on-duty members who are responsible for certain monitors are alerted when an incident is created.
</p>
</div>
</Tooltip>
</span>
</div>
</div>

View File

@@ -15,6 +15,9 @@ function StatusIndicator({ status, resourceName, monitorName }) {
case 'offline':
statusColor = 'red';
break;
case 'disabled':
statusColor = 'slate5';
break;
default:
statusColor = 'slate';
}

View File

@@ -187,6 +187,13 @@ let RenderMonitor = ({
disabled={!shouldEdit}
/>
)}
{type === 'incomingHttpRequest' && (
<Checkbox
label="Uptime"
name={`${monitor}.uptime`}
disabled={!shouldEdit}
/>
)}
{type === 'server-monitor' && (
<Fragment>
<Checkbox

View File

@@ -11,10 +11,7 @@ import DataPathHoC from '../DataPathHoC';
function HTD1() {
return (
<td
className="Table-cell Table-cell--align--left Table-cell--verticalAlign--top Table-cell--width--minimized Table-cell--wrap--noWrap db-ListViewItem-cell"
style={{ height: '1px', minWidth: '270px' }}
>
<td className="Table-cell Table-cell--align--left Table-cell--verticalAlign--top Table-cell--width--minimized Table-cell--wrap--noWrap db-ListViewItem-cell">
<div className="db-ListViewItem-cellContent Box-root Padding-all--8">
<span className="db-ListViewItem-text Text-color--dark Text-display--inline Text-fontSize--13 Text-fontWeight--medium Text-lineHeight--20 Text-typeface--upper Text-wrap--wrap">
<span>Monitor</span>
@@ -24,21 +21,26 @@ function HTD1() {
);
}
function HTD2() {
function HTD2({ name, style }) {
return (
<td
className="Table-cell Table-cell--align--right Table-cell--verticalAlign--top Table-cell--width--minimized Table-cell--wrap--noWrap db-ListViewItem-cell"
style={{ height: '1px' }}
style={style}
>
<div className="db-ListViewItem-cellContent Box-root Padding-all--8">
<span className="db-ListViewItem-text Text-align--right Text-color--dark Text-display--block Text-fontSize--13 Text-fontWeight--medium Text-lineHeight--20 Text-typeface--upper Text-wrap--wrap">
<span>Subscriber</span>
<span className="db-ListViewItem-text Text-align--left Text-color--dark Text-display--block Text-fontSize--13 Text-fontWeight--medium Text-lineHeight--20 Text-typeface--upper Text-wrap--wrap">
<span>{name}</span>
</span>
</div>
</td>
);
}
HTD2.propTypes = {
name: PropTypes.string.isRequired,
style: PropTypes.object,
};
function HTD3() {
return (
<td
@@ -127,7 +129,7 @@ TD1.propTypes = {
function TD2({ text }) {
return (
<td
className="Table-cell Table-cell--align--right Table-cell--verticalAlign--top Table-cell--width--minimized Table-cell--wrap--noWrap db-ListViewItem-cell"
className="Table-cell Table-cell--align--left Table-cell--verticalAlign--top Table-cell--width--minimized Table-cell--wrap--noWrap db-ListViewItem-cell"
style={{ height: '1px' }}
>
<div className="db-ListViewItem-link">
@@ -300,7 +302,7 @@ function SubscriberAlertTableHeader() {
return (
<tr className="Table-row db-ListViewItem db-ListViewItem-header">
<HTD1 />
<HTD2 />
<HTD2 name="Subscriber" />
<HTD3 />
<HTD4 />
<HTD5 />
@@ -342,17 +344,20 @@ class SubscriberAlertTableRowsClass extends React.Component {
}
>
<TD1 text={monitor ? monitor.name : 'Unknown'} />
<TD2
text={
alert.subscriberId
? alert.subscriberId.contactEmail ||
(alert.subscriberId.contactPhone &&
`+${countryTelephoneCode(
alert.subscriberId.countryCode.toUpperCase()
)}${
alert.subscriberId.contactPhone
}`) ||
alert.subscriberId.contactWebhook
? alert.alertVia === 'webhook'
? alert.subscriberId.contactWebhook
: alert.subscriberId.contactEmail ||
(alert.subscriberId.contactPhone &&
`+${countryTelephoneCode(
alert.subscriberId.countryCode.toUpperCase()
)}${
alert.subscriberId.contactPhone
}`) ||
alert.subscriberId.contactWebhook
: 'Unknown'
}
/>

View File

@@ -23,6 +23,11 @@ export const DELETE_MONITOR_FAILURE = 'DELETE_MONITOR_FAILURE';
export const DELETE_MONITOR_REQUEST = 'DELETE_MONITOR_REQUEST';
export const DELETE_PROJECT_MONITORS = 'DELETE_PROJECT_MONITORS';
//Disable a monitor
export const DISABLE_MONITOR_SUCCESS = 'DISABLE_MONITOR_SUCCESS';
export const DISABLE_MONITOR_FAILURE = 'DISABLE_MONITOR_FAILURE';
export const DISABLE_MONITOR_REQUEST = 'DISABLE_MONITOR_REQUEST';
//Fetch Incidents of monitors
export const FETCH_MONITORS_INCIDENT_REQUEST =
'FETCH_MONITORS_INCIDENT_REQUEST';

View File

@@ -16,6 +16,7 @@ import MonitorViewIncidentBox from '../components/monitor/MonitorViewIncidentBox
import MonitorViewLighthouseLogsBox from '../components/monitor/MonitorViewLighthouseLogsBox';
import MonitorViewSubscriberBox from '../components/monitor/MonitorViewSubscriberBox';
import MonitorViewDeleteBox from '../components/monitor/MonitorViewDeleteBox';
import MonitorViewDisableBox from '../components/monitor/MonitorViewDisableBox';
import NewMonitor from '../components/monitor/NewMonitor';
import ShouldRender from '../components/basic/ShouldRender';
import { LoadingState } from '../components/basic/Loader';
@@ -199,7 +200,8 @@ class MonitorView extends React.Component {
const componentMonitorsRoute = getParentRoute(pathname);
const defaultMonitorSla = monitorSlas.find(sla => sla.isDefault);
const disabledMonitor =
this.props.monitor && this.props.monitor.disabled;
return (
<Dashboard ready={this.ready}>
<Fade>
@@ -246,6 +248,52 @@ class MonitorView extends React.Component {
</TabList>
</div>
<div>{scheduleAlert}</div>
{disabledMonitor && this.state.tabIndex === 0 ? (
<div
className="Box-root Margin-vertical--12"
style={{ marginTop: 0, cursor: 'pointer' }}
id="noMonitorSlaBreached"
>
<div className="db-Trends bs-ContentSection Card-root Card-shadow--small">
<div className="Box-root Box-background--slate9 Card-shadow--medium Border-radius--4">
<div
className="bs-ContentSection-content Box-root Flex-flex Padding-horizontal--20 Padding-vertical--12"
style={{
justifyContent: 'space-between',
}}
>
<div
className="ContentHeader-title Text-fontSize--15 Text-fontWeight--regular Text-lineHeight--16"
style={{
color: 'rgb(76, 76, 76)',
paddingTop: '5px',
}}
>
<span>
This monitor is currently
disabled and not
monitoring.Re Enable it to
start monitoring again.
</span>
</div>
<div>
<button
className="bs-Button bs-DeprecatedButton bs-Button--grey"
id={`reEnable_${this.props.monitor.name}`}
onClick={() =>
this.tabSelected(3)
}
>
<span>Enable</span>
</button>
</div>
</div>
</div>
</div>
</div>
) : (
''
)}
{!this.props.requestingMonitorSla &&
this.props.monitor &&
(this.props.monitor.monitorSla ||
@@ -623,6 +671,37 @@ class MonitorView extends React.Component {
}
/>
</div>
<ShouldRender
if={
this
.props
.monitor &&
this
.props
.monitor
.type &&
this
.props
.monitor
.type !==
'manual'
}
>
<div className="Box-root Margin-bottom--12">
<MonitorViewDisableBox
componentId={
this
.props
.componentId
}
monitor={
this
.props
.monitor
}
/>
</div>
</ShouldRender>
</RenderIfSubProjectAdmin>
</Fade>
</TabPanel>

View File

@@ -56,6 +56,9 @@ import {
CLOSE_BREACHED_MONITOR_SLA_FAILURE,
CLOSE_BREACHED_MONITOR_SLA_REQUEST,
CLOSE_BREACHED_MONITOR_SLA_SUCCESS,
DISABLE_MONITOR_SUCCESS,
DISABLE_MONITOR_FAILURE,
DISABLE_MONITOR_REQUEST,
} from '../constants/monitor';
import moment from 'moment';
@@ -102,6 +105,7 @@ const INITIAL_STATE = {
fetchMonitorCriteriaRequest: false,
fetchMonitorsSubscriberRequest: false,
deleteMonitor: false,
disableMonitor: false,
monitorSlaBreaches: {
requesting: false,
error: null,
@@ -1177,6 +1181,59 @@ export default function monitor(state = INITIAL_STATE, action) {
deleteMonitor: action.payload,
});
case DISABLE_MONITOR_SUCCESS: {
return Object.assign({}, state, {
monitorsList: {
...state.monitorsList,
requesting: false,
error: null,
success: false,
monitors: state.monitorsList.monitors.map(
subProjectMonitor => {
subProjectMonitor.monitors = subProjectMonitor.monitors.map(
monitor => {
if (
String(monitor._id) ===
String(action.payload.monitorId)
) {
monitor.disabled =
action.payload.disable;
return monitor;
} else {
return monitor;
}
}
);
return subProjectMonitor;
}
),
},
disableMonitor: false,
});
}
case DISABLE_MONITOR_FAILURE:
return Object.assign({}, state, {
monitorsList: {
...state.monitorsList,
requesting: false,
error: action.payload,
success: false,
},
disableMonitor: false,
});
case DISABLE_MONITOR_REQUEST:
return Object.assign({}, state, {
monitorsList: {
...state.monitorsList,
requesting: false,
error: null,
success: false,
},
disableMonitor: action.payload,
});
case DELETE_PROJECT_MONITORS:
monitors = Object.assign([], state.monitorsList.monitors);
monitors = monitors.filter(

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,21 @@
{
"name": "helm-chart",
"version": "3.0.0",
"description": "Helm Chart Server for Fyipe",
"main": "server.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "echo \"no test required\"",
"audit": "npm-audit-ci-wrapper --threshold=high",
"dep-check": "depcheck ./ --skip-missing=true --ignores='ejs'"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1"
},
"devDependencies": {
"depcheck": "^0.9.2",
"npm-audit-ci-wrapper": "^2.5.1"
}
"name": "helm-chart",
"version": "3.0.0",
"description": "Helm Chart Server for Fyipe",
"main": "server.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "echo \"no test required\"",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='ejs'"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1"
},
"devDependencies": {
"depcheck": "^0.9.2"
}
}

12248
home/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
"lighthouse-test": "jest --forceExit lighthouse-tests/test/index.test.js --env=node",
"lighthouse": "start-server-and-test http://localhost:1444",
"smoketest": "jest --forceExit smoketest/index.test.js --env=node",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"light-house": "node lighthouse.js --web",
"light-house-mobile": "node lighthouse.js --mobile",
"dep-check": "depcheck ./ --skip-missing=true --ignores='ejs,puppeteer'"
@@ -29,7 +29,6 @@
"jest": "^26.2.2",
"lighthouse": "^6.2.0",
"nodemon": "^2.0.4",
"npm-audit-ci-wrapper": "^2.5.1",
"ora": "^4.0.3",
"puppeteer": "^1.20.0",
"start-server-and-test": "^1.9.1"

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
"scripts": {
"start": "node server.js",
"dev": "cross-env NODE_ENV=development nodemon server.js",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"test": "jest --forceExit --runInBand test",
"dep-check": "depcheck ./ --skip-missing=true --ignores='ejs'"
},
@@ -26,8 +26,7 @@
},
"devDependencies": {
"depcheck": "^0.9.2",
"nodemon": "^2.0.2",
"npm-audit-ci-wrapper": "^2.5.1"
"nodemon": "^2.0.2"
},
"jest": {
"collectCoverageFrom": [

View File

@@ -13,8 +13,7 @@
},
"devDependencies": {
"depcheck": "^0.9.2",
"jest": "^25.1.0",
"npm-audit-ci-wrapper": "^2.5.4"
"jest": "^25.1.0"
}
},
"node_modules/@babel/code-frame": {
@@ -1204,15 +1203,6 @@
"sprintf-js": "~1.0.2"
}
},
"node_modules/argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
"integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
"dev": true,
"engines": {
"node": ">=0.6.10"
}
},
"node_modules/arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -1751,18 +1741,6 @@
"node": ">=0.10.0"
}
},
"node_modules/cli-table": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
"integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
"dev": true,
"dependencies": {
"colors": "1.0.3"
},
"engines": {
"node": ">= 0.2.0"
}
},
"node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
@@ -1826,15 +1804,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"node_modules/colors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
"dev": true,
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -2180,12 +2149,6 @@
"webidl-conversions": "^4.0.2"
}
},
"node_modules/duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"node_modules/ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -2293,21 +2256,6 @@
"node": ">=0.10.0"
}
},
"node_modules/event-stream": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
"integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
"dev": true,
"dependencies": {
"duplexer": "^0.1.1",
"from": "^0.1.7",
"map-stream": "0.0.7",
"pause-stream": "^0.0.11",
"split": "^1.0.1",
"stream-combiner": "^0.2.2",
"through": "^2.3.8"
}
},
"node_modules/exec-sh": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
@@ -2638,12 +2586,6 @@
"node": ">=0.10.0"
}
},
"node_modules/from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
"dev": true
},
"node_modules/fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
@@ -4470,31 +4412,6 @@
"node": ">=6"
}
},
"node_modules/jsonparse": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
"integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
"dev": true,
"engines": [
"node >= 0.2.0"
]
},
"node_modules/JSONStream": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
"integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
"dev": true,
"dependencies": {
"jsonparse": "^1.2.0",
"through": ">=2.2.7 <3"
},
"bin": {
"JSONStream": "bin.js"
},
"engines": {
"node": "*"
}
},
"node_modules/jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -4628,12 +4545,6 @@
"node": ">=0.10.0"
}
},
"node_modules/map-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
"integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=",
"dev": true
},
"node_modules/map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -4982,21 +4893,6 @@
"node": ">=0.10.0"
}
},
"node_modules/npm-audit-ci-wrapper": {
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/npm-audit-ci-wrapper/-/npm-audit-ci-wrapper-2.5.4.tgz",
"integrity": "sha512-ZySswLcWteAv8tpBjYcHgaxA9xzIjQKtJF+wmtcL2ncOF6Qy+vFEMBS3EIXDv0gyHo7F7QtFRXl4ZgyCD3jjIQ==",
"dev": true,
"dependencies": {
"argv": "^0.0.2",
"cli-table": "^0.3.1",
"event-stream": "^4.0.1",
"JSONStream": "^1.3.5"
},
"bin": {
"npm-audit-ci-wrapper": "bin/index.js"
}
},
"node_modules/npm-bundled": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
@@ -5309,15 +5205,6 @@
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"node_modules/pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
"dev": true,
"dependencies": {
"through": "~2.3"
}
},
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -6315,18 +6202,6 @@
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
"dev": true
},
"node_modules/split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"dev": true,
"dependencies": {
"through": "2"
},
"engines": {
"node": "*"
}
},
"node_modules/split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -6408,16 +6283,6 @@
"node": ">=0.10.0"
}
},
"node_modules/stream-combiner": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
"integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
"dev": true,
"dependencies": {
"duplexer": "~0.1.1",
"through": "~2.3.4"
}
},
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -6620,12 +6485,6 @@
"integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
"dev": true
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"node_modules/tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -8256,12 +8115,6 @@
"sprintf-js": "~1.0.2"
}
},
"argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
"integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
"dev": true
},
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -8704,15 +8557,6 @@
}
}
},
"cli-table": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
"integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
"dev": true,
"requires": {
"colors": "1.0.3"
}
},
"cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
@@ -8766,12 +8610,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"colors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -9054,12 +8892,6 @@
"webidl-conversions": "^4.0.2"
}
},
"duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -9140,21 +8972,6 @@
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"event-stream": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
"integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
"dev": true,
"requires": {
"duplexer": "^0.1.1",
"from": "^0.1.7",
"map-stream": "0.0.7",
"pause-stream": "^0.0.11",
"split": "^1.0.1",
"stream-combiner": "^0.2.2",
"through": "^2.3.8"
}
},
"exec-sh": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
@@ -9428,12 +9245,6 @@
"map-cache": "^0.2.2"
}
},
"from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
"dev": true
},
"fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
@@ -10927,22 +10738,6 @@
"minimist": "^1.2.5"
}
},
"jsonparse": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
"integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
"dev": true
},
"JSONStream": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
"integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
"dev": true,
"requires": {
"jsonparse": "^1.2.0",
"through": ">=2.2.7 <3"
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -11051,12 +10846,6 @@
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
"dev": true
},
"map-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
"integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=",
"dev": true
},
"map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -11350,18 +11139,6 @@
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"npm-audit-ci-wrapper": {
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/npm-audit-ci-wrapper/-/npm-audit-ci-wrapper-2.5.4.tgz",
"integrity": "sha512-ZySswLcWteAv8tpBjYcHgaxA9xzIjQKtJF+wmtcL2ncOF6Qy+vFEMBS3EIXDv0gyHo7F7QtFRXl4ZgyCD3jjIQ==",
"dev": true,
"requires": {
"argv": "^0.0.2",
"cli-table": "^0.3.1",
"event-stream": "^4.0.1",
"JSONStream": "^1.3.5"
}
},
"npm-bundled": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
@@ -11607,15 +11384,6 @@
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
"dev": true,
"requires": {
"through": "~2.3"
}
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -12458,15 +12226,6 @@
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
"dev": true
},
"split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"dev": true,
"requires": {
"through": "2"
}
},
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -12532,16 +12291,6 @@
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true
},
"stream-combiner": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
"integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
"dev": true,
"requires": {
"duplexer": "~0.1.1",
"through": "~2.3.4"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -12702,12 +12451,6 @@
"integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
"dev": true
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",

View File

@@ -7,7 +7,7 @@
"test": "jest --forceExit tests",
"start": "node server.js",
"dev": "nodemon server.js",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='babel-*,browserslist,ejs,path,loadable-components,js-uuid,acorn,@beam-australia/react-env'"
},
"dependencies": {
@@ -16,8 +16,7 @@
},
"devDependencies": {
"depcheck": "^0.9.2",
"jest": "^25.1.0",
"npm-audit-ci-wrapper": "^2.5.4"
"jest": "^25.1.0"
},
"jest": {
"collectCoverageFrom": [

257
js-sdk/package-lock.json generated
View File

@@ -25,7 +25,6 @@
"chai-http": "^4.3.0",
"depcheck": "^0.9.2",
"mocha": "^7.2.0",
"npm-audit-ci-wrapper": "^2.6.6",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
@@ -1389,15 +1388,6 @@
"sprintf-js": "~1.0.2"
}
},
"node_modules/argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
"integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
"dev": true,
"engines": {
"node": ">=0.6.10"
}
},
"node_modules/arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -2152,18 +2142,6 @@
"node": ">=0.10.0"
}
},
"node_modules/cli-table": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
"integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
"dev": true,
"dependencies": {
"colors": "1.0.3"
},
"engines": {
"node": ">= 0.2.0"
}
},
"node_modules/cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
@@ -2203,15 +2181,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"node_modules/colors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
"dev": true,
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -2842,12 +2811,6 @@
"npm": ">=1.2"
}
},
"node_modules/duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"node_modules/duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -3060,21 +3023,6 @@
"node": ">=0.10.0"
}
},
"node_modules/event-stream": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
"integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
"dev": true,
"dependencies": {
"duplexer": "^0.1.1",
"from": "^0.1.7",
"map-stream": "0.0.7",
"pause-stream": "^0.0.11",
"split": "^1.0.1",
"stream-combiner": "^0.2.2",
"through": "^2.3.8"
}
},
"node_modules/events": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
@@ -3488,12 +3436,6 @@
"node": ">=0.10.0"
}
},
"node_modules/from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
"dev": true
},
"node_modules/from2": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
@@ -4291,31 +4233,6 @@
"node": ">=6"
}
},
"node_modules/jsonparse": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
"integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
"dev": true,
"engines": [
"node >= 0.2.0"
]
},
"node_modules/JSONStream": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
"integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
"dev": true,
"dependencies": {
"jsonparse": "^1.2.0",
"through": ">=2.2.7 <3"
},
"bin": {
"JSONStream": "bin.js"
},
"engines": {
"node": "*"
}
},
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -4479,12 +4396,6 @@
"node": ">=0.10.0"
}
},
"node_modules/map-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
"integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=",
"dev": true
},
"node_modules/map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -5035,21 +4946,6 @@
"node": ">=0.10.0"
}
},
"node_modules/npm-audit-ci-wrapper": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/npm-audit-ci-wrapper/-/npm-audit-ci-wrapper-2.6.6.tgz",
"integrity": "sha512-TDKIRtjTed8BYEY8fvXczHTydkNios3acT4kLovPulCSumMl6ny+0VDxV9YAO1DJKBzI2b/uqqrMS8E/nYdGYA==",
"dev": true,
"dependencies": {
"argv": "^0.0.2",
"cli-table": "^0.3.1",
"event-stream": "^4.0.1",
"JSONStream": "^1.3.5"
},
"bin": {
"npm-audit-ci-wrapper": "bin/index.js"
}
},
"node_modules/npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -5382,15 +5278,6 @@
"node": "*"
}
},
"node_modules/pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
"dev": true,
"dependencies": {
"through": "~2.3"
}
},
"node_modules/pbkdf2": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
@@ -6277,18 +6164,6 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"node_modules/split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"dev": true,
"dependencies": {
"through": "2"
},
"engines": {
"node": "*"
}
},
"node_modules/split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -6351,16 +6226,6 @@
"readable-stream": "^2.0.2"
}
},
"node_modules/stream-combiner": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
"integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
"dev": true,
"dependencies": {
"duplexer": "~0.1.1",
"through": "~2.3.4"
}
},
"node_modules/stream-each": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
@@ -6611,12 +6476,6 @@
"node": ">=0.10.0"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"node_modules/through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
@@ -8780,12 +8639,6 @@
"sprintf-js": "~1.0.2"
}
},
"argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
"integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
"dev": true
},
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -9442,15 +9295,6 @@
}
}
},
"cli-table": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
"integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
"dev": true,
"requires": {
"colors": "1.0.3"
}
},
"cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
@@ -9487,12 +9331,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"colors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -10029,12 +9867,6 @@
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"dev": true
},
"duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -10211,21 +10043,6 @@
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"event-stream": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
"integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
"dev": true,
"requires": {
"duplexer": "^0.1.1",
"from": "^0.1.7",
"map-stream": "0.0.7",
"pause-stream": "^0.0.11",
"split": "^1.0.1",
"stream-combiner": "^0.2.2",
"through": "^2.3.8"
}
},
"events": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
@@ -10576,12 +10393,6 @@
"map-cache": "^0.2.2"
}
},
"from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
"dev": true
},
"from2": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
@@ -11210,22 +11021,6 @@
"minimist": "^1.2.5"
}
},
"jsonparse": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
"integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
"dev": true
},
"JSONStream": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
"integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
"dev": true,
"requires": {
"jsonparse": "^1.2.0",
"through": ">=2.2.7 <3"
}
},
"kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -11352,12 +11147,6 @@
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
"dev": true
},
"map-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
"integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=",
"dev": true
},
"map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -11828,18 +11617,6 @@
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"npm-audit-ci-wrapper": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/npm-audit-ci-wrapper/-/npm-audit-ci-wrapper-2.6.6.tgz",
"integrity": "sha512-TDKIRtjTed8BYEY8fvXczHTydkNios3acT4kLovPulCSumMl6ny+0VDxV9YAO1DJKBzI2b/uqqrMS8E/nYdGYA==",
"dev": true,
"requires": {
"argv": "^0.0.2",
"cli-table": "^0.3.1",
"event-stream": "^4.0.1",
"JSONStream": "^1.3.5"
}
},
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -12102,15 +11879,6 @@
"integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
"dev": true
},
"pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
"dev": true,
"requires": {
"through": "~2.3"
}
},
"pbkdf2": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
@@ -12861,15 +12629,6 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"dev": true,
"requires": {
"through": "2"
}
},
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -12925,16 +12684,6 @@
"readable-stream": "^2.0.2"
}
},
"stream-combiner": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
"integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
"dev": true,
"requires": {
"duplexer": "~0.1.1",
"through": "~2.3.4"
}
},
"stream-each": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
@@ -13146,12 +12895,6 @@
}
}
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",

View File

@@ -7,7 +7,7 @@
"build-dev": "npm run build && npm link",
"test": "mocha --require @babel/polyfill --require @babel/register",
"build": "webpack --mode production",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='axios,webpack-cli'"
},
"keywords": [
@@ -30,7 +30,6 @@
"chai-http": "^4.3.0",
"depcheck": "^0.9.2",
"mocha": "^7.2.0",
"npm-audit-ci-wrapper": "^2.6.6",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@
"start": "node server.js",
"dev": "nodemon server.js",
"test": "mocha --exit test/index.js",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='ejs'"
},
"devDependencies": {
@@ -25,7 +25,6 @@
"custom-env": "^1.0.2",
"depcheck": "^0.9.2",
"mocha": "^8.1.1",
"nodemon": "^2.0.4",
"npm-audit-ci-wrapper": "^2.5.1"
"nodemon": "^2.0.4"
}
}

84
package-lock.json generated
View File

@@ -371,12 +371,6 @@
"any-observable": "^0.3.0"
}
},
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
"dev": true
},
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -860,16 +854,16 @@
}
},
"cosmiconfig": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
"integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
"integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
"dev": true,
"requires": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.1.0",
"import-fresh": "^3.2.1",
"parse-json": "^5.0.0",
"path-type": "^4.0.0",
"yaml": "^1.7.2"
"yaml": "^1.10.0"
}
},
"cross-spawn": {
@@ -1693,15 +1687,15 @@
}
},
"husky": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/husky/-/husky-4.2.3.tgz",
"integrity": "sha512-VxTsSTRwYveKXN4SaH1/FefRJYCtx+wx04sSVcOpD7N2zjoHxa+cEJ07Qg5NmV3HAK+IRKOyNVpi2YBIVccIfQ==",
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/husky/-/husky-4.3.5.tgz",
"integrity": "sha512-E5S/1HMoDDaqsH8kDF5zeKEQbYqe3wL9zJDyqyYqc8I4vHBtAoxkDBGXox0lZ9RI+k5GyB728vZdmnM4bYap+g==",
"dev": true,
"requires": {
"chalk": "^3.0.0",
"chalk": "^4.0.0",
"ci-info": "^2.0.0",
"compare-versions": "^3.5.1",
"cosmiconfig": "^6.0.0",
"compare-versions": "^3.6.0",
"cosmiconfig": "^7.0.0",
"find-versions": "^3.2.0",
"opencollective-postinstall": "^2.0.2",
"pkg-dir": "^4.2.0",
@@ -1711,19 +1705,18 @@
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -1752,9 +1745,9 @@
"dev": true
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
@@ -2058,6 +2051,12 @@
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
"dev": true
},
"json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2809,9 +2808,9 @@
}
},
"opencollective-postinstall": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
"integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
"dev": true
},
"optionator": {
@@ -2841,9 +2840,9 @@
"dev": true
},
"p-limit": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@@ -2896,14 +2895,14 @@
}
},
"parse-json": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
"integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
"integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
"json-parse-better-errors": "^1.0.1",
"json-parse-even-better-errors": "^2.3.0",
"lines-and-columns": "^1.1.6"
}
},
@@ -3834,13 +3833,10 @@
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"yaml": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz",
"integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==",
"dev": true,
"requires": {
"@babel/runtime": "^7.6.3"
}
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
"integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
"dev": true
}
}
}

View File

@@ -18,7 +18,7 @@
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.21.5",
"husky": "^4.2.3",
"husky": "^4.3.5",
"lint-staged": "^9.5.0",
"prettier": "^1.19.1"
},

3335
probe/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
"start": "node --max-http-header-size=80000 index.js",
"dev": "nodemon --max-http-header-size=80000 index.js",
"test": "echo 'no tests'",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true"
},
"repository": {
@@ -38,7 +38,6 @@
},
"devDependencies": {
"depcheck": "^0.9.2",
"nodemon": "^2.0.4",
"npm-audit-ci-wrapper": "^2.5.1"
"nodemon": "^2.0.4"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
"scripts": {
"start": "node ./bin/server-monitor.js",
"dev": "NODE_ENV=development nodemon ./bin/server-monitor.js",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"test": "NODE_ENV=development mocha --exit",
"doc": "jsdoc -r ./bin ./lib --readme README.md",
"dep-check": "depcheck ./ --skip-missing=true --ignores='pino-pretty,osx-temperature-sensor'"
@@ -23,6 +23,7 @@
"dotenv": "^8.1.0",
"forever-monitor": "^1.5.0",
"inquirer": "^6.5.2",
"osx-temperature-sensor": "^1.0.7",
"pino": "^5.13.4",
"pino-pretty": "^3.2.1",
"promise": "^8.0.3",
@@ -43,8 +44,7 @@
"depcheck": "^0.9.2",
"jsdoc": "^3.6.6",
"mocha": "^8.2.1",
"nodemon": "^2.0.6",
"npm-audit-ci-wrapper": "^2.5.1"
"nodemon": "^2.0.6"
},
"directories": {
"lib": "lib",

File diff suppressed because it is too large Load Diff

View File

@@ -39,8 +39,7 @@
"@storybook/react": "^5.1.9",
"cross-env": "^5.2.0",
"depcheck": "^0.9.2",
"jest-localstorage-mock": "^2.3.0",
"npm-audit-ci-wrapper": "^2.2.1"
"jest-localstorage-mock": "^2.3.0"
},
"scripts": {
"start": "npm run build && node index.js",
@@ -52,7 +51,7 @@
"snapshots:watch": "react-scripts test --env=jsdom --watchAll",
"storybook": "start-storybook -p 9009 -s public",
"build-storybook": "build-storybook -s public",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='serve'"
},
"browserslist": {

View File

@@ -178,6 +178,10 @@ div.block-chart::-webkit-scrollbar {
background: #FA6D46;
}
.graph-disabled {
fill: #8898aa;
background: #8898aa;
}
/******* Clearfix *******/
@@ -1071,13 +1075,13 @@ margin-left:10px;
}
.button-as-anchor {
display: inline !important;
border: none;
margin: 0;
padding: 0;
font: inherit;
border: none;
margin: 0;
padding: 0;
font: inherit;
font-size: inherit;
text-decoration: none;
cursor: pointer;
text-decoration: none;
cursor: pointer;
text-align: inherit;
background-color: inherit;
font-size: 0.8em;

View File

@@ -61,9 +61,36 @@ class BlockChart extends Component {
const { colors } = this.props.statusData;
if (this.props.time && this.props.time.status) {
if (this.props.time.status === 'offline') {
let downTimeInMinutes;
let downtime;
if (this.props.time.status === 'disabled') {
let disabledTimeInMinutes, disabledtime;
if (this.props.time.disabledTime < 60) {
disabledTimeInMinutes = this.props.time.disabledTime;
disabledtime = `${disabledTimeInMinutes} second${
disabledTimeInMinutes === 1 ? '' : 's'
}`;
} else {
disabledTimeInMinutes = Math.floor(
this.props.time.disabledTime / 60
);
disabledtime = `${disabledTimeInMinutes} minute${
disabledTimeInMinutes === 1 ? '' : 's'
}`;
}
if (disabledTimeInMinutes > 60) {
disabledtime = `${Math.floor(
disabledTimeInMinutes / 60
)} hrs ${disabledTimeInMinutes % 60} minutes`;
}
bar = 'bar down';
title = moment(this.props.time.date).format('LL');
title1 = `Disabled for ${disabledtime}`;
need = true;
if (colors)
backgroundColor = `rgba(${colors.disabled.r}, ${colors.disabled.g}, ${colors.disabled.b})`;
} else if (this.props.time.status === 'offline') {
let downTimeInMinutes, downtime;
if (this.props.time.downTime < 60) {
downTimeInMinutes = this.props.time.downTime;
downtime = `${downTimeInMinutes} second${

View File

@@ -280,14 +280,20 @@ class Main extends Component {
primaryText,
downtimeColor,
uptimeColor,
degradedColor;
degradedColor,
disabledColor,
disabled;
let statusBackground;
if (this.props.statusData && this.props.statusData.monitorsData) {
serviceStatus = getServiceStatus(this.props.monitorState, probes);
isGroupedByMonitorCategory = this.props.statusData
.isGroupedByMonitorCategory;
const colors = this.props.statusData.colors;
const disabledMonitors =
this.props.monitorState &&
this.props.monitorState.filter(m => m.disabled);
disabled =
disabledMonitors && disabledMonitors.length ? true : false;
if (serviceStatus === 'all') {
status = 'status-bubble status-up';
statusMessage = 'All services are online';
@@ -331,6 +337,10 @@ class Main extends Component {
backgroundColor: `rgba(${colors.degraded.r}, ${colors.degraded.g}, ${colors.degraded.b})`,
};
disabledColor = {
backgroundColor: `rgba(${colors.disabled.r}, ${colors.disabled.g}, ${colors.disabled.b})`,
};
if (serviceStatus === 'all') {
statusBackground = uptimeColor;
} else if (serviceStatus === 'some' || serviceStatus === 'none') {
@@ -673,6 +683,8 @@ class Main extends Component {
downtimeColor={downtimeColor}
uptimeColor={uptimeColor}
degradedColor={degradedColor}
disabledColor={disabledColor}
disabled={disabled}
/>
) : (
''

View File

@@ -27,6 +27,7 @@ const calculateTime = (statuses, start, range) => {
downTime: 0,
upTime: 0,
degradedTime: 0,
disabledTime: 0,
status: null,
emptytime: dayStart.toISOString(),
};
@@ -68,6 +69,9 @@ const calculateTime = (statuses, start, range) => {
timeObj.status = monitorStatus.status;
}
if (monitor.endTime === null && monitor.status === 'disabled') {
timeObj.status = monitor.status;
}
const start = moment(monitorStatus.startTime).isBefore(
dayStartIn
)
@@ -115,7 +119,9 @@ const calculateTime = (statuses, start, range) => {
} else {
//if the firstIncident has a higher priority
if (
firstIncident.status === 'offline' ||
firstIncident.status === 'disabled' ||
(firstIncident.status === 'offline' &&
nextIncident.status !== 'disabled') ||
(firstIncident.status === 'degraded' &&
nextIncident.status === 'online')
) {
@@ -187,6 +193,11 @@ const calculateTime = (statuses, start, range) => {
//Last step
for (const incident of incidentsHappenedDuringTheDay) {
const { start, end, status } = incident;
if (status === 'disabled') {
timeObj.disabledTime =
timeObj.disabledTime + end.diff(start, 'seconds');
timeObj.date = end.toISOString();
}
if (status === 'offline') {
timeObj.downTime =
timeObj.downTime + end.diff(start, 'seconds');
@@ -206,9 +217,11 @@ const calculateTime = (statuses, start, range) => {
totalTime +
timeObj.upTime +
timeObj.degradedTime +
timeObj.downTime;
timeObj.downTime +
timeObj.disabledTime;
if (timeObj.status === null || timeObj.status === 'online') {
if (timeObj.downTime > 0) timeObj.status = 'offline';
if (timeObj.disabledTime > 0) timeObj.status = 'disabled';
else if (timeObj.downTime > 0) timeObj.status = 'offline';
else if (timeObj.degradedTime > 0) timeObj.status = 'degraded';
else if (timeObj.upTime > 0) timeObj.status = 'online';
}
@@ -381,8 +394,10 @@ class MonitorInfo extends Component {
status.backgroundColor = `rgba(${colors.degraded.r}, ${colors.degraded.g}, ${colors.degraded.b})`; // "degraded-status";
} else if (monitorStatus === 'online') {
status.backgroundColor = `rgba(${colors.uptime.r}, ${colors.uptime.g}, ${colors.uptime.b})`; // "online-status";
} else {
} else if (monitorStatus === 'offline') {
status.backgroundColor = `rgba(${colors.downtime.r}, ${colors.downtime.g}, ${colors.downtime.b})`; // "red-downtime";
} else {
status.backgroundColor = `rgba(${colors.disabled.r}, ${colors.disabled.g}, ${colors.disabled.b})`; // "grey-disabled";
}
}

View File

@@ -7,6 +7,8 @@ const UptimeLegend = ({
downtimeColor,
uptimeColor,
degradedColor,
disabledColor,
disabled,
}) => (
<div className="uptime-legend box-inner clearfix" style={background}>
<span className="legend-item">
@@ -27,6 +29,17 @@ const UptimeLegend = ({
></span>
<label style={secondaryTextColor}>Downtime</label>
</span>
{disabled ? (
<span className="legend-item">
<span
className="legend-color graph-disabled"
style={disabledColor}
></span>
<label style={secondaryTextColor}>Disabled</label>
</span>
) : (
''
)}
</div>
);
@@ -38,6 +51,8 @@ UptimeLegend.propTypes = {
downtimeColor: PropTypes.object,
uptimeColor: PropTypes.object,
degradedColor: PropTypes.object,
disabledColor: PropTypes.object,
disabled: PropTypes.bool,
};
export default UptimeLegend;

2378
zapier/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
"main": "index.js",
"scripts": {
"test": "mocha --recursive",
"audit": "npm-audit-ci-wrapper --threshold=high",
"audit": "npm audit --audit-level=low",
"dep-check": "depcheck ./ --skip-missing=true --ignores='babel-*'"
},
"engine": {
@@ -22,7 +22,6 @@
"babel-preset-react": "^6.24.1",
"depcheck": "^0.9.2",
"mocha": "^8.1.1",
"npm-audit-ci-wrapper": "^2.2.1",
"should": "11.2.1"
}
}