@bigbinary/neeto-webhooks-frontend 1.6.8 → 1.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,6 +68,8 @@ You can learn more about the setup and usage here:
68
68
  ```zsh
69
69
  yarn add @bigbinary/neeto-webhooks-frontend
70
70
  ```
71
+ ### Instructions for development
72
+ Check the [Frontend package development guide](https://neeto-engineering.neetokb.com/p/a-d34cb4b0) for step-by-step instructions to develop the frontend package.
71
73
 
72
74
  ### Components
73
75
  #### `NeetoWebhooks` ([source code](https://github.com/bigbinary/neeto-webhooks-nano/blob/52aa6b3fc38dce1afb9f6a7a821f3d2d12cb6a6a/app/javascript/src/components/NeetoWebhooks.jsx))
@@ -15,7 +15,9 @@
15
15
  "cancel": "Cancel",
16
16
  "delete": "Delete",
17
17
  "edit": "Edit",
18
- "viewDetails": "View details"
18
+ "viewDetails": "View details",
19
+ "regenerate": "Regenerate",
20
+ "addSecretKey": "Add secret key"
19
21
  },
20
22
  "errors": {
21
23
  "webhook": {
package/dist/index.cjs.js CHANGED
@@ -19,9 +19,9 @@ var DateFormat = require('@bigbinary/neeto-molecules/DateFormat');
19
19
  var i18next = require('i18next');
20
20
  var ramda = require('ramda');
21
21
  var neetoIcons = require('@bigbinary/neeto-icons');
22
+ var MoreDropdown = require('@bigbinary/neeto-molecules/MoreDropdown');
22
23
  var formik = require('@bigbinary/neetoui/formik');
23
24
  var utils = require('@bigbinary/neeto-commons-frontend/utils');
24
- var MoreDropdown = require('@bigbinary/neeto-molecules/MoreDropdown');
25
25
  var yup = require('yup');
26
26
 
27
27
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -1014,7 +1014,73 @@ var useFetchEvents = function useFetchEvents() {
1014
1014
  });
1015
1015
  };
1016
1016
 
1017
- var WEBHOOK_HELP_URL = "https://help.neetocal.com/articles/webhook";
1017
+ var WEBHOOK_HELP_URL = "https://neetocalhelp.neetokb.com/p/a-4bb6c2a2";
1018
+ var WEBHOOK_SECRETS_HELP_URL = "https://neetocalhelp.neetokb.com/p/a-80de90bd";
1019
+
1020
+ // Unique ID creation requires a high quality random # generator. In the browser we therefore
1021
+ // require the crypto API and do not support built-in fallback to lower quality random number
1022
+ // generators (like Math.random()).
1023
+ let getRandomValues;
1024
+ const rnds8 = new Uint8Array(16);
1025
+ function rng() {
1026
+ // lazy load so that environments that need to polyfill have a chance to do so
1027
+ if (!getRandomValues) {
1028
+ // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
1029
+ getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
1030
+
1031
+ if (!getRandomValues) {
1032
+ throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
1033
+ }
1034
+ }
1035
+
1036
+ return getRandomValues(rnds8);
1037
+ }
1038
+
1039
+ /**
1040
+ * Convert array of 16 byte values to UUID string format of the form:
1041
+ * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
1042
+ */
1043
+
1044
+ const byteToHex = [];
1045
+
1046
+ for (let i = 0; i < 256; ++i) {
1047
+ byteToHex.push((i + 0x100).toString(16).slice(1));
1048
+ }
1049
+
1050
+ function unsafeStringify(arr, offset = 0) {
1051
+ // Note: Be careful editing this code! It's been tuned for performance
1052
+ // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
1053
+ return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
1054
+ }
1055
+
1056
+ const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
1057
+ var native = {
1058
+ randomUUID
1059
+ };
1060
+
1061
+ function v4(options, buf, offset) {
1062
+ if (native.randomUUID && !buf && !options) {
1063
+ return native.randomUUID();
1064
+ }
1065
+
1066
+ options = options || {};
1067
+ const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
1068
+
1069
+ rnds[6] = rnds[6] & 0x0f | 0x40;
1070
+ rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
1071
+
1072
+ if (buf) {
1073
+ offset = offset || 0;
1074
+
1075
+ for (let i = 0; i < 16; ++i) {
1076
+ buf[offset + i] = rnds[i];
1077
+ }
1078
+
1079
+ return buf;
1080
+ }
1081
+
1082
+ return unsafeStringify(rnds);
1083
+ }
1018
1084
 
1019
1085
  var MENU_ITEMS = {
1020
1086
  EDIT: "edit",
@@ -1124,6 +1190,9 @@ var buildColumns = function buildColumns(_ref6) {
1124
1190
  width: 400
1125
1191
  }];
1126
1192
  };
1193
+ var generateRandomSecret = function generateRandomSecret() {
1194
+ return v4().replace(/-/g, "");
1195
+ };
1127
1196
 
1128
1197
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1129
1198
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -1137,6 +1206,10 @@ var AddWebhookPane = function AddWebhookPane(_ref) {
1137
1206
  webhooks = _ref.webhooks;
1138
1207
  var _useTranslation = reactI18next.useTranslation(),
1139
1208
  t = _useTranslation.t;
1209
+ var _useState = React.useState(false),
1210
+ _useState2 = _slicedToArray(_useState, 2),
1211
+ isSecretInputFieldVisible = _useState2[0],
1212
+ setIsSecretInputFieldVisible = _useState2[1];
1140
1213
  var _useCreateWebhook = useCreateWebhook({
1141
1214
  onSuccess: function onSuccess() {
1142
1215
  onClose();
@@ -1177,6 +1250,24 @@ var AddWebhookPane = function AddWebhookPane(_ref) {
1177
1250
  entityType: entityType
1178
1251
  }));
1179
1252
  };
1253
+ var handleClick = function handleClick(setFieldValue) {
1254
+ var randomWebhookSecret = generateRandomSecret();
1255
+ setFieldValue("secret", randomWebhookSecret);
1256
+ setIsSecretInputFieldVisible(true);
1257
+ };
1258
+ var handleRegenerate = function handleRegenerate(setFieldValue) {
1259
+ var randomWebhookSecret = generateRandomSecret();
1260
+ setFieldValue("secret", randomWebhookSecret);
1261
+ };
1262
+ var handleDelete = function handleDelete(setFieldValue) {
1263
+ setFieldValue("secret", null);
1264
+ setIsSecretInputFieldVisible(false);
1265
+ };
1266
+ React.useEffect(function () {
1267
+ if (webhook !== null && webhook !== void 0 && webhook.secret) {
1268
+ setIsSecretInputFieldVisible(true);
1269
+ }
1270
+ }, [webhook]);
1180
1271
  return /*#__PURE__*/React__default["default"].createElement(neetoui.Pane, {
1181
1272
  isOpen: isOpen,
1182
1273
  onClose: onClose,
@@ -1206,7 +1297,8 @@ var AddWebhookPane = function AddWebhookPane(_ref) {
1206
1297
  }, function (_ref2) {
1207
1298
  var dirty = _ref2.dirty,
1208
1299
  isSubmitting = _ref2.isSubmitting,
1209
- isValid = _ref2.isValid;
1300
+ isValid = _ref2.isValid,
1301
+ setFieldValue = _ref2.setFieldValue;
1210
1302
  return isLoading ? /*#__PURE__*/React__default["default"].createElement("div", {
1211
1303
  className: "flex items-center justify-center"
1212
1304
  }, /*#__PURE__*/React__default["default"].createElement(neetoui.Spinner, null)) : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(neetoui.Pane.Body, null, /*#__PURE__*/React__default["default"].createElement("div", {
@@ -1228,15 +1320,16 @@ var AddWebhookPane = function AddWebhookPane(_ref) {
1228
1320
  name: "events",
1229
1321
  options: events,
1230
1322
  placeholder: t("neetoWebhooks.webhook.eventPlaceholder")
1231
- }), /*#__PURE__*/React__default["default"].createElement(formik.Input, {
1323
+ }), isSecretInputFieldVisible && /*#__PURE__*/React__default["default"].createElement("div", {
1324
+ className: "flex items-center justify-between space-x-3"
1325
+ }, /*#__PURE__*/React__default["default"].createElement(formik.Input, {
1232
1326
  "data-cy": "secret-key-input-field",
1233
1327
  name: "secret",
1234
- placeholder: t("neetoWebhooks.webhook.secretPlaceholder"),
1235
1328
  label: /*#__PURE__*/React__default["default"].createElement(reactI18next.Trans, {
1236
1329
  i18nKey: "neetoWebhooks.webhook.secret",
1237
1330
  components: {
1238
1331
  helpLink: /*#__PURE__*/React__default["default"].createElement("a", {
1239
- href: WEBHOOK_HELP_URL,
1332
+ href: WEBHOOK_SECRETS_HELP_URL,
1240
1333
  rel: "noreferrer",
1241
1334
  target: "_blank"
1242
1335
  }),
@@ -1245,10 +1338,36 @@ var AddWebhookPane = function AddWebhookPane(_ref) {
1245
1338
  size: 20
1246
1339
  })
1247
1340
  }
1248
- })
1249
- }), /*#__PURE__*/React__default["default"].createElement(formik.Switch, {
1341
+ }),
1342
+ placeholder: t("neetoWebhooks.webhook.secretPlaceholder")
1343
+ }), /*#__PURE__*/React__default["default"].createElement("div", {
1344
+ className: "mt-6"
1345
+ }, /*#__PURE__*/React__default["default"].createElement(MoreDropdown__default["default"], {
1346
+ menuItems: [{
1347
+ key: "regenerate-secret",
1348
+ label: t("neetoWebhooks.buttons.regenerate"),
1349
+ "data-cy": "regenerate-secret",
1350
+ onClick: function onClick() {
1351
+ return handleRegenerate(setFieldValue);
1352
+ }
1353
+ }, {
1354
+ key: "delete-secret",
1355
+ label: t("neetoWebhooks.buttons.delete"),
1356
+ "data-cy": "delete-secret",
1357
+ onClick: function onClick() {
1358
+ return handleDelete(setFieldValue);
1359
+ }
1360
+ }]
1361
+ }))), /*#__PURE__*/React__default["default"].createElement(formik.Switch, {
1250
1362
  label: t("neetoWebhooks.webhook.active"),
1251
1363
  name: "isActive"
1364
+ }), !isSecretInputFieldVisible && /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
1365
+ icon: neetoIcons.Plus,
1366
+ label: t("neetoWebhooks.buttons.addSecretKey"),
1367
+ style: "text",
1368
+ onClick: function onClick() {
1369
+ return handleClick(setFieldValue);
1370
+ }
1252
1371
  }))), /*#__PURE__*/React__default["default"].createElement(neetoui.Pane.Footer, {
1253
1372
  className: "flex gap-2"
1254
1373
  }, /*#__PURE__*/React__default["default"].createElement(formik.ActionBlock, {