firewallo-sdk 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Firewall SDK
2
+
3
+ The `firewallb-sdk` is a JavaScript library designed to integrate with your web application to block malicious IPs and protect sensitive content. It validates user IP addresses against a firewall API and prevents unauthorized access.
4
+
5
+ ## Features
6
+
7
+ - **IP Validation**: Validates whether a user's IP is blocked by the firewall API.
8
+ - **ProtectedPage Component**: Wraps content and ensures that only authorized users can access it.
9
+ - **Easy Setup**: Simple configuration through environment variables.
10
+
11
+ ## Installation
12
+
13
+ To install the `firewallb-sdk`, use npm:
14
+
15
+ ### Using npm
16
+
17
+ `npm install firewallb-sdk`
18
+
19
+ ---
20
+
21
+ ## Configuration & Usage
22
+
23
+ ### Step 1: Set Environment Variables
24
+
25
+ Before using the `firewallb-sdk`, you need to configure your environment variables. These variables contain your API key and app ID, which are essential for connecting your app to the firewall service.
26
+
27
+ In your project's root directory, create or update the `.env` file with the following configuration:
28
+
29
+ ```
30
+ REACT_APP_FIREWALL_API_KEY="your-api-key"
31
+ REACT_APP_FIREWALL_APP_ID="your-app-id"
32
+ ```
33
+
34
+ - `REACT_APP_FIREWALL_API_KEY`: Your unique API key provided by the firewall service.
35
+ - `REACT_APP_FIREWALL_APP_ID`: The app ID associated with your firewall service account.
36
+
37
+ Ensure these variables are correctly set in your `.env` file. They will be used by the SDK to authenticate and make requests to the firewall service.
38
+
39
+ ### Important Notes:
40
+
41
+ - The `REACT_APP_` prefix is required for environment variables to be accessible in React applications created with Create React App or Vite.
42
+ - Do not commit your `.env` file to version control (e.g., Git) for security reasons. Add it to your `.gitignore` file.
43
+
44
+ ---
45
+
46
+ ### Step 2: Set Configuration in Your App
47
+
48
+ Once the environment variables are set, configure the SDK using the `setConfig` function. This function will allow the SDK to access the firewall service with the provided API key and app ID.
49
+
50
+ In your main app file (e.g., `App.js` or `App.jsx`), use the following code to configure the firewall SDK:
51
+
52
+ ```
53
+ import React from "react";
54
+ import { setConfig, ProtectedPage } from "firewallb-sdk";
55
+
56
+ // Set the configuration for the firewall
57
+ setConfig({
58
+ API_KEY: process.env.REACT_APP_FIREWALL_API_KEY,
59
+ APP_ID: process.env.REACT_APP_FIREWALL_APP_ID,
60
+ });
61
+
62
+ function App() {
63
+ return (
64
+ <div className="App">
65
+ <ProtectedPage>
66
+ <h1>Protected Content</h1>
67
+ <p>This content is protected by the firewall SDK.</p>
68
+ </ProtectedPage>
69
+ </div>
70
+ );
71
+ }
72
+
73
+ export default App;
74
+ ```
75
+
76
+ This code will initialize the SDK with the API key and app ID from your environment variables.
77
+
78
+ ---
79
+
80
+ ### Step 3: Use `ProtectedPage` to Protect Content
81
+
82
+ Once the SDK is configured, you can use the `ProtectedPage` component to protect content within your application. Here's how:
83
+
84
+ ```
85
+ <ProtectedPage>
86
+ <h1>Protected Content</h1>
87
+ <p>This content is protected by the firewall SDK.</p>
88
+ </ProtectedPage>
89
+ ```
90
+
91
+ The `ProtectedPage` component ensures that only authorized users can access the content inside it, while unauthorized users will be blocked.
92
+
93
+ ---
94
+
95
+ ## Final Notes
96
+
97
+ - Make sure to test your app after integration to ensure the firewall SDK is working as expected.
98
+ - If you encounter any issues with the firewall or SDK setup, please check the API key and app ID in the environment variables.
99
+
100
+ ---
101
+
102
+ This guide covers the basic steps to configure and use the `firewallb-sdk` in your React application. Let us know if you need further assistance!
103
+
104
+ ---
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.validateIP = exports.listenForTrafficUpdates = exports.disconnectWebSocket = exports.connectWebSocket = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _config = require("../config/config");
11
+ var _socket = _interopRequireDefault(require("socket.io-client"));
12
+ var _axios = _interopRequireDefault(require("axios"));
13
+ // Import socket.io-client
14
+ // Import axios for API requests
15
+
16
+ // WebSocket setup for real-time monitoring
17
+ var socket;
18
+ var trafficUpdateCallback = null;
19
+ var connectWebSocket = exports.connectWebSocket = function connectWebSocket() {
20
+ var _getConfig = (0, _config.getConfig)(),
21
+ FIREWALL_API_URL = _getConfig.FIREWALL_API_URL,
22
+ APP_ID = _getConfig.APP_ID,
23
+ API_KEY = _getConfig.API_KEY;
24
+ if (!socket) {
25
+ // Initialize WebSocket connection
26
+ socket = (0, _socket["default"])(FIREWALL_API_URL, {
27
+ query: {
28
+ apiKey: API_KEY,
29
+ // Include API Key
30
+ appId: APP_ID // Include App ID
31
+ }
32
+ });
33
+ socket.on("connect", function () {
34
+ console.log("Connected to WebSocket for real-time updates");
35
+ });
36
+ socket.on("traffic-update-".concat(APP_ID), function (data) {
37
+ console.log("Received real-time traffic update:", data);
38
+ if (trafficUpdateCallback) {
39
+ trafficUpdateCallback(data);
40
+ }
41
+ });
42
+ socket.on("ip-blocked", function (data) {
43
+ console.log("IP Blocked:", data);
44
+ });
45
+ socket.on("ip-unblocked", function (data) {
46
+ console.log("IP Unblocked:", data);
47
+ });
48
+ socket.on("disconnect", function () {
49
+ console.log("Disconnected from WebSocket");
50
+ });
51
+ }
52
+ };
53
+
54
+ // Function to disconnect WebSocket when it's no longer needed
55
+ var disconnectWebSocket = exports.disconnectWebSocket = function disconnectWebSocket() {
56
+ if (socket) {
57
+ socket.disconnect();
58
+ socket = null;
59
+ console.log("WebSocket disconnected");
60
+ }
61
+ };
62
+
63
+ // Function to subscribe to traffic updates
64
+ var listenForTrafficUpdates = exports.listenForTrafficUpdates = function listenForTrafficUpdates(callback) {
65
+ trafficUpdateCallback = callback;
66
+ };
67
+
68
+ // Function to validate IP using the firewall backend API
69
+ var validateIP = exports.validateIP = /*#__PURE__*/function () {
70
+ var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(ip) {
71
+ var _getConfig2, FIREWALL_API_URL, APP_ID, API_KEY, response;
72
+ return _regenerator["default"].wrap(function _callee$(_context) {
73
+ while (1) switch (_context.prev = _context.next) {
74
+ case 0:
75
+ _getConfig2 = (0, _config.getConfig)(), FIREWALL_API_URL = _getConfig2.FIREWALL_API_URL, APP_ID = _getConfig2.APP_ID, API_KEY = _getConfig2.API_KEY;
76
+ _context.prev = 1;
77
+ _context.next = 4;
78
+ return _axios["default"].post("".concat(FIREWALL_API_URL, "/api/apps/").concat(APP_ID, "/validate-ip"), {
79
+ ip: ip
80
+ }, {
81
+ headers: {
82
+ "Content-Type": "application/json",
83
+ "x-api-key": API_KEY
84
+ }
85
+ });
86
+ case 4:
87
+ response = _context.sent;
88
+ return _context.abrupt("return", response.data);
89
+ case 8:
90
+ _context.prev = 8;
91
+ _context.t0 = _context["catch"](1);
92
+ console.error("Error in validateIP (firewallApi.js):", _context.t0);
93
+ throw _context.t0;
94
+ case 12:
95
+ case "end":
96
+ return _context.stop();
97
+ }
98
+ }, _callee, null, [[1, 8]]);
99
+ }));
100
+ return function validateIP(_x) {
101
+ return _ref.apply(this, arguments);
102
+ };
103
+ }();
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = void 0;
9
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
+ var _react = _interopRequireWildcard(require("react"));
13
+ var _firewallService = require("../services/firewallService");
14
+ var _firewallApi = require("../api/firewallApi");
15
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
16
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
17
+ // Add WebSocket import
18
+
19
+ var ProtectedPage = function ProtectedPage(_ref) {
20
+ var children = _ref.children;
21
+ var _useState = (0, _react.useState)(false),
22
+ _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
23
+ isBlocked = _useState2[0],
24
+ setIsBlocked = _useState2[1];
25
+ var _useState3 = (0, _react.useState)(true),
26
+ _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
27
+ loading = _useState4[0],
28
+ setLoading = _useState4[1];
29
+ (0, _react.useEffect)(function () {
30
+ var validateIP = /*#__PURE__*/function () {
31
+ var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
32
+ var blocked;
33
+ return _regenerator["default"].wrap(function _callee$(_context) {
34
+ while (1) switch (_context.prev = _context.next) {
35
+ case 0:
36
+ _context.prev = 0;
37
+ _context.next = 3;
38
+ return (0, _firewallService.checkIP)();
39
+ case 3:
40
+ blocked = _context.sent;
41
+ setIsBlocked(blocked);
42
+ _context.next = 11;
43
+ break;
44
+ case 7:
45
+ _context.prev = 7;
46
+ _context.t0 = _context["catch"](0);
47
+ console.error("Error validating IP:", _context.t0);
48
+ setIsBlocked(false);
49
+ case 11:
50
+ _context.prev = 11;
51
+ setLoading(false);
52
+ return _context.finish(11);
53
+ case 14:
54
+ case "end":
55
+ return _context.stop();
56
+ }
57
+ }, _callee, null, [[0, 7, 11, 14]]);
58
+ }));
59
+ return function validateIP() {
60
+ return _ref2.apply(this, arguments);
61
+ };
62
+ }();
63
+
64
+ // Establish WebSocket connection for real-time updates
65
+ (0, _firewallApi.connectWebSocket)();
66
+
67
+ // Validate IP on load
68
+ validateIP();
69
+
70
+ // Cleanup WebSocket connection on component unmount
71
+ return function () {
72
+ (0, _firewallApi.disconnectWebSocket)();
73
+ };
74
+ }, []);
75
+ if (loading) {
76
+ return /*#__PURE__*/_react["default"].createElement("div", null, "Loading...");
77
+ }
78
+ if (isBlocked) {
79
+ return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("h1", null, "Access Denied"), /*#__PURE__*/_react["default"].createElement("p", null, "Your IP address has been blocked. Please contact support if you believe this is an error."));
80
+ }
81
+ return /*#__PURE__*/_react["default"].createElement("div", null, children);
82
+ };
83
+ var _default = exports["default"] = ProtectedPage;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.setConfig = exports.getConfig = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ 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; }
10
+ 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) { (0, _defineProperty2["default"])(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; }
11
+ var config = {
12
+ FIREWALL_API_URL: "http://localhost:4000",
13
+ // Default API URL
14
+ API_KEY: "",
15
+ APP_ID: ""
16
+ };
17
+ var setConfig = exports.setConfig = function setConfig(newConfig) {
18
+ config = _objectSpread(_objectSpread({}, config), newConfig);
19
+ };
20
+ var getConfig = exports.getConfig = function getConfig() {
21
+ return config;
22
+ };
package/lib/index.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "ProtectedPage", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _ProtectedPage["default"];
11
+ }
12
+ });
13
+ Object.defineProperty(exports, "connectWebSocket", {
14
+ enumerable: true,
15
+ get: function get() {
16
+ return _firewallApi.connectWebSocket;
17
+ }
18
+ });
19
+ Object.defineProperty(exports, "disconnectWebSocket", {
20
+ enumerable: true,
21
+ get: function get() {
22
+ return _firewallApi.disconnectWebSocket;
23
+ }
24
+ });
25
+ Object.defineProperty(exports, "listenForTrafficUpdates", {
26
+ enumerable: true,
27
+ get: function get() {
28
+ return _firewallApi.listenForTrafficUpdates;
29
+ }
30
+ });
31
+ Object.defineProperty(exports, "setConfig", {
32
+ enumerable: true,
33
+ get: function get() {
34
+ return _config.setConfig;
35
+ }
36
+ });
37
+ var _ProtectedPage = _interopRequireDefault(require("./components/ProtectedPage"));
38
+ var _config = require("./config/config");
39
+ var _firewallApi = require("./api/firewallApi");
40
+ // Import WebSocket functions
41
+
42
+ // Optionally, connect WebSocket on initialization
43
+ (0, _firewallApi.connectWebSocket)();
44
+
45
+ // Export components and functions
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.checkIP = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _ipUtils = require("../utils/ipUtils");
11
+ var _firewallApi = require("../api/firewallApi");
12
+ // Import validateIP
13
+
14
+ var checkIP = exports.checkIP = /*#__PURE__*/function () {
15
+ var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
16
+ var ip, result;
17
+ return _regenerator["default"].wrap(function _callee$(_context) {
18
+ while (1) switch (_context.prev = _context.next) {
19
+ case 0:
20
+ _context.prev = 0;
21
+ _context.next = 3;
22
+ return (0, _ipUtils.getUserIP)();
23
+ case 3:
24
+ ip = _context.sent;
25
+ if (ip) {
26
+ _context.next = 6;
27
+ break;
28
+ }
29
+ throw new Error("Unable to fetch IP address.");
30
+ case 6:
31
+ _context.next = 8;
32
+ return (0, _firewallApi.validateIP)(ip);
33
+ case 8:
34
+ result = _context.sent;
35
+ return _context.abrupt("return", result.blocked);
36
+ case 12:
37
+ _context.prev = 12;
38
+ _context.t0 = _context["catch"](0);
39
+ console.error("Error checking IP:", _context.t0);
40
+ return _context.abrupt("return", false);
41
+ case 16:
42
+ case "end":
43
+ return _context.stop();
44
+ }
45
+ }, _callee, null, [[0, 12]]);
46
+ }));
47
+ return function checkIP() {
48
+ return _ref.apply(this, arguments);
49
+ };
50
+ }();
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getUserIP = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var getUserIP = exports.getUserIP = /*#__PURE__*/function () {
11
+ var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
12
+ var response, data;
13
+ return _regenerator["default"].wrap(function _callee$(_context) {
14
+ while (1) switch (_context.prev = _context.next) {
15
+ case 0:
16
+ _context.prev = 0;
17
+ _context.next = 3;
18
+ return fetch("https://api.ipify.org?format=json");
19
+ case 3:
20
+ response = _context.sent;
21
+ _context.next = 6;
22
+ return response.json();
23
+ case 6:
24
+ data = _context.sent;
25
+ return _context.abrupt("return", data.ip);
26
+ case 10:
27
+ _context.prev = 10;
28
+ _context.t0 = _context["catch"](0);
29
+ console.error("Error fetching user IP:", _context.t0);
30
+ return _context.abrupt("return", null);
31
+ case 14:
32
+ case "end":
33
+ return _context.stop();
34
+ }
35
+ }, _callee, null, [[0, 10]]);
36
+ }));
37
+ return function getUserIP() {
38
+ return _ref.apply(this, arguments);
39
+ };
40
+ }();
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.validateIP = validateIP;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _config = require("./config/config");
11
+ var _axios = _interopRequireDefault(require("axios"));
12
+ // Function to validate IP using axios
13
+ function validateIP(_x) {
14
+ return _validateIP.apply(this, arguments);
15
+ }
16
+ function _validateIP() {
17
+ _validateIP = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(ip) {
18
+ var _getConfig, FIREWALL_API_URL, APP_ID, API_KEY, response;
19
+ return _regenerator["default"].wrap(function _callee$(_context) {
20
+ while (1) switch (_context.prev = _context.next) {
21
+ case 0:
22
+ _getConfig = (0, _config.getConfig)(), FIREWALL_API_URL = _getConfig.FIREWALL_API_URL, APP_ID = _getConfig.APP_ID, API_KEY = _getConfig.API_KEY;
23
+ _context.prev = 1;
24
+ _context.next = 4;
25
+ return _axios["default"].post("".concat(FIREWALL_API_URL, "/api/apps/").concat(APP_ID, "/validate-ip"), {
26
+ ip: ip
27
+ }, {
28
+ headers: {
29
+ "Content-Type": "application/json",
30
+ "x-api-key": API_KEY
31
+ }
32
+ });
33
+ case 4:
34
+ response = _context.sent;
35
+ return _context.abrupt("return", response.data);
36
+ case 8:
37
+ _context.prev = 8;
38
+ _context.t0 = _context["catch"](1);
39
+ console.error("Error in validateIP (validateIP.js):", _context.t0);
40
+ throw _context.t0;
41
+ case 12:
42
+ case "end":
43
+ return _context.stop();
44
+ }
45
+ }, _callee, null, [[1, 8]]);
46
+ }));
47
+ return _validateIP.apply(this, arguments);
48
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "firewallo-sdk",
3
+ "version": "1.0.1",
4
+ "description": "Firewall SDK to protect web apps by validating IP addresses.",
5
+ "main": "lib/index.js",
6
+ "files": [
7
+ "lib"
8
+ ],
9
+ "module": "src/index.js",
10
+ "author": "SridharSolaris",
11
+ "license": "MIT",
12
+ "peerDependencies": {
13
+ "react": "^18.0.0",
14
+ "react-dom": "^18.0.0"
15
+ },
16
+ "scripts": {
17
+ "build": "babel src --out-dir lib",
18
+ "start": "babel src --out-dir lib --watch"
19
+ },
20
+ "devDependencies": {
21
+ "@babel/cli": "^7.26.4",
22
+ "@babel/plugin-transform-runtime": "^7.25.9",
23
+ "@babel/preset-env": "^7.26.7",
24
+ "@babel/preset-react": "^7.26.3"
25
+ },
26
+ "dependencies": {
27
+ "axios": "^1.7.9",
28
+ "socket.io-client": "^4.8.1"
29
+ }
30
+ }