Comparing version 1.1.0 to 1.1.5
import Express, { Handler, Send } from "express"; | ||
import { BasicRSA, BasicRSAConfig } from "./basic"; | ||
type DefaultHandler = (req: any, res: any, ...unused: any) => any; | ||
export interface ExtendedRequest extends Express.Request { | ||
@@ -10,3 +9,3 @@ RSA: RSAServer; | ||
/** Returns an http handler responsible for exposing the public key of the RSA service */ | ||
publish(): DefaultHandler; | ||
publish(_: any, res: any): any; | ||
gate(handler?: Handler): Handler; | ||
@@ -17,2 +16,1 @@ injectedSend(send: Send, key: string | string[]): Send; | ||
} | ||
export {}; |
@@ -14,13 +14,11 @@ "use strict"; | ||
/** Returns an http handler responsible for exposing the public key of the RSA service */ | ||
publish() { | ||
return (_, res) => { | ||
if (typeof res.contentType === "function") | ||
res.contentType("text"); | ||
if (typeof res.status === "function") | ||
res.status(200); | ||
return res.json({ | ||
key: this.publicKey("public"), | ||
format: "public", | ||
}); | ||
}; | ||
publish(_, res) { | ||
if (typeof (res === null || res === void 0 ? void 0 : res.contentType) === "function") | ||
res.contentType("text"); | ||
if (typeof (res === null || res === void 0 ? void 0 : res.status) === "function") | ||
res.status(200); | ||
return res === null || res === void 0 ? void 0 : res.json({ | ||
key: this.publicKey("public"), | ||
format: "public", | ||
}); | ||
} | ||
@@ -27,0 +25,0 @@ gate(handler) { |
@@ -31,3 +31,2 @@ "use strict"; | ||
const chai_as_promised_1 = __importDefault(require("chai-as-promised")); | ||
const node_test_1 = require("node:test"); | ||
const basic_1 = require("../modules/basic"); | ||
@@ -58,6 +57,6 @@ const server_1 = require("../modules/server"); | ||
-----END RSA PRIVATE KEY-----`; | ||
(0, node_test_1.describe)("BasicRSA Validation", () => { | ||
(0, node_test_1.describe)("Validation with random keys", () => { | ||
describe("BasicRSA Validation", () => { | ||
describe("Validation with random keys", () => { | ||
const memory = {}; | ||
(0, node_test_1.it)("create with default config", () => { | ||
it("create with default config", () => { | ||
const rsa = new basic_1.BasicRSA(); | ||
@@ -71,3 +70,3 @@ (0, chai_1.expect)(rsa).not.to.be.equal(null).equal(undefined); | ||
}); | ||
(0, node_test_1.it)("create instance with random keys", () => { | ||
it("create instance with random keys", () => { | ||
const rsa = new basic_1.BasicRSA({ bits: 1024 }); | ||
@@ -81,3 +80,3 @@ (0, chai_1.expect)(rsa).not.to.be.equal(null).equal(undefined); | ||
}); | ||
(0, node_test_1.it)("encrypt using public key", () => { | ||
it("encrypt using public key", () => { | ||
const rsa = memory.rsa; | ||
@@ -88,3 +87,3 @@ memory.text = "my cat is funny"; | ||
}); | ||
(0, node_test_1.it)("decrypt using private key", () => { | ||
it("decrypt using private key", () => { | ||
const rsa = memory.rsa; | ||
@@ -96,3 +95,3 @@ const target = memory.text; | ||
}); | ||
(0, node_test_1.it)("encrypt using public key on another", () => { | ||
it("encrypt using public key on another", () => { | ||
const rsa = memory.rsa; | ||
@@ -104,5 +103,5 @@ const target = memory.text; | ||
}); | ||
(0, node_test_1.describe)("Validation with custom keys", () => { | ||
describe("Validation with custom keys", () => { | ||
const memory = {}; | ||
(0, node_test_1.it)("create instance with random keys", () => { | ||
it("create instance with random keys", () => { | ||
const rsa = new basic_1.BasicRSA({ | ||
@@ -121,3 +120,3 @@ keys: { | ||
}); | ||
(0, node_test_1.it)("encryp using public key", () => { | ||
it("encryp using public key", () => { | ||
const rsa = memory.rsa; | ||
@@ -128,3 +127,3 @@ memory.text = "my cat is funny"; | ||
}); | ||
(0, node_test_1.it)("decrypt using private key", () => { | ||
it("decrypt using private key", () => { | ||
const rsa = memory.rsa; | ||
@@ -136,3 +135,3 @@ const target = memory.text; | ||
}); | ||
(0, node_test_1.it)("encrypt using public key on ", () => { | ||
it("encrypt using public key on ", () => { | ||
const rsa = memory.rsa; | ||
@@ -144,4 +143,4 @@ const target = memory.text; | ||
}); | ||
(0, node_test_1.describe)("Validation with invalid inputs", () => { | ||
(0, node_test_1.it)("invalid constructor config", () => { | ||
describe("Validation with invalid inputs", () => { | ||
it("invalid constructor config", () => { | ||
try { | ||
@@ -156,3 +155,3 @@ // @ts-ignore | ||
}); | ||
(0, node_test_1.it)("invalid constructor keys", () => { | ||
it("invalid constructor keys", () => { | ||
try { | ||
@@ -172,3 +171,3 @@ // @ts-ignore | ||
}); | ||
(0, node_test_1.it)("invalid encrypt input", () => { | ||
it("invalid encrypt input", () => { | ||
try { | ||
@@ -183,3 +182,3 @@ // @ts-ignore | ||
}); | ||
(0, node_test_1.it)("invalid decrypt input", () => { | ||
it("invalid decrypt input", () => { | ||
try { | ||
@@ -194,3 +193,3 @@ // @ts-ignore | ||
}); | ||
(0, node_test_1.it)("invalid decrypt input", () => { | ||
it("invalid decrypt input", () => { | ||
try { | ||
@@ -205,3 +204,3 @@ // @ts-ignore | ||
}); | ||
(0, node_test_1.it)("missing private/public key", () => { | ||
it("missing private/public key", () => { | ||
try { | ||
@@ -232,3 +231,3 @@ new basic_1.BasicRSA({ | ||
}); | ||
(0, node_test_1.it)("missing private/public key format", () => { | ||
it("missing private/public key format", () => { | ||
try { | ||
@@ -269,5 +268,5 @@ new basic_1.BasicRSA({ | ||
}); | ||
(0, node_test_1.describe)("Server Validation", () => { | ||
describe("Server Validation", () => { | ||
const memory = {}; | ||
(0, node_test_1.it)("create server instance", () => { | ||
it("create server instance", () => { | ||
const rsa = new server_1.RSAServer({ | ||
@@ -278,3 +277,3 @@ keys: { private: privateKey, public: publicKey }, | ||
}); | ||
(0, node_test_1.it)("testing public key handle", () => { | ||
it("testing public key handle", () => { | ||
const rsa = memory.rsa; | ||
@@ -289,3 +288,3 @@ function send(data) { | ||
} | ||
rsa.publish()(null, { | ||
rsa.publish(null, { | ||
json, | ||
@@ -292,0 +291,0 @@ send, |
{ | ||
"name": "rsa-bridge", | ||
"version": "1.1.0", | ||
"version": "1.1.5", | ||
"description": "Encrypted communication bridge between client and server using Node-RSA library", | ||
@@ -36,2 +36,4 @@ "main": "./dist/index.js", | ||
"@types/chai-as-promised": "^7.1.8", | ||
"@types/express": "^4.17.21", | ||
"@types/mocha": "^10.0.6", | ||
"@types/node": "^20.11.30", | ||
@@ -43,7 +45,8 @@ "@types/node-rsa": "^1.1.4", | ||
"express": "^4.19.1", | ||
"i": "^0.3.7", | ||
"mocha": "^10.3.0", | ||
"npm": "^10.5.0", | ||
"shx": "^0.3.4", | ||
"supertest": "^6.3.4", | ||
"typescript": "^5.4.2", | ||
"@types/express": "^4.17.21" | ||
"typescript": "^5.4.2" | ||
}, | ||
@@ -50,0 +53,0 @@ "dependencies": { |
238
README.md
# RSA-BRIDGE | ||
Encrypted communication bridge between client and server using [Node-RSA](https://www.npmjs.com/package/node-rsa) library. | ||
###### Encrypted communication bridge between client and server using [Node-RSA](https://www.npmjs.com/package/node-rsa) library. | ||
<ul> | ||
<li>Encrypted Communication</li> | ||
<li>Streamlined Client-Server Integration</li> | ||
<li>Development simplification</li> | ||
<li>Key Generation</li> | ||
<li>Powered by a solid library</li> | ||
</ul> | ||
- Encrypted Communication | ||
- Streamlined Client-Server Integration | ||
- Development simplification | ||
- Key Generation | ||
- Powered by a solid library | ||
The library uses Node-RSA to create a bridge between server-client with encrypted communication, enabling secure end-to-end communication. | ||
 | ||
## Example | ||
RSA Bridge Server Instance | ||
```js | ||
import { RSAServer } from "rsa-bridge"; | ||
const rsa = new RSAServer({ bits: 1024 }); | ||
app.use( | ||
rsa.gate((req, res, next) => { | ||
// your handler functions | ||
}) | ||
); | ||
``` | ||
RSA Bridge Client Instance | ||
```js | ||
import { RSAClient } from "rsa-bridge"; | ||
const rsa = new RSAClient({ bits: 1024 }); | ||
rsa.connect(); | ||
rsa.fetch(INPUT, OPTIONS); | ||
``` | ||
### Installing | ||
```sh | ||
npm install rsa-bridge | ||
``` | ||
#### Testing | ||
```sh | ||
npm test | ||
``` | ||
--- | ||
## Usage | ||
Its use is divided into an **client** instance (`RSAClient`) and an **server** instance (`RSAServer`). | ||
The **server instance** must expose the public key (`publish`) and have the middleware (`gate`) to inject RSA into the handler. | ||
The **client instance** must have the public key exposure endpoint (`connect`) to encrypt the data. | ||
#### Instantiating | ||
<a name="instantiating"></a> | ||
To instantiate the service on the server it is necessary to specify `bits` or `keys` that will be used. | ||
Below is an example of instantiating the model used both on the server and on the client | ||
```javascript | ||
import { BasicRSA } from "rsa-bridge"; | ||
const rsa = new BasicRSA(BasicRSAConfig); | ||
``` | ||
- **random** - <span style="color: purple;">BasicRSAConfig</span> - you can generate random keys by entering the `bits` | ||
```js | ||
{ | ||
bits: number; | ||
} | ||
``` | ||
- **custom** - <span style="color: purple;">BasicRSAConfig</span> - you can specify your keys using the configuration below | ||
```js | ||
{ | ||
keys: { | ||
private: string, | ||
public: string, | ||
... | ||
} | ||
} | ||
``` | ||
### Client-side | ||
#### Instantiating | ||
The instance configuration is the same as found [here](#instantiating). Although it is possible, a `custom` key is <span style="color: red">not recommended</span> for clients. | ||
```javascript | ||
import { RSAClient } from "rsa-bridge"; | ||
const rsa = new RSAClient(BasicRSAConfig); | ||
``` | ||
#### Connect | ||
Obtains a connection to the server's RSA service, via the endpoint defined for public key exposure. | ||
The `PATH` must point to the address defined [here](#expose). | ||
```javascript | ||
rsa.connect(PATH); | ||
``` | ||
#### Fetch | ||
Execute a request to the server using the encryption bridge. | ||
```javascript | ||
rsa.fetch(INPUT, OPTIONS).then(({ body, response }) => { | ||
// decrypted data | ||
}); | ||
``` | ||
### Server-side | ||
#### Instantiating | ||
The instance configuration is the same as found [here](#instantiating). | ||
```javascript | ||
import { RSAServer } from "rsa-bridge"; | ||
const rsa = new RSAServer(BasicRSAConfig); | ||
``` | ||
#### Publish | ||
<a name="expose"></a> | ||
The public key must be exposed for the bridge to work. The method must be **`GET`**. | ||
```javascript | ||
app.get(PATH, rsa.publish); | ||
``` | ||
- **path** - <span style="color: darkblue;">string</span> - the HTTP path | ||
#### Gate | ||
It can be used as a **middleware**, propagating the service to **all routes** | ||
```javascript | ||
app.use(rsa.gate); | ||
app.post("example", HANDLER); | ||
``` | ||
It can also be used on a , as in the **single path** | ||
```javascript | ||
app.post("/example", rsa.gate(HANDLER)); | ||
``` | ||
#### Getting Data | ||
If the request passed the gate, the data sent in the body can be obtained | ||
```javascript | ||
app.use(rsa.gate); | ||
app.post("/example", (req, res) => { | ||
req.body; // decrypted data | ||
}); | ||
``` | ||
#### Send | ||
The `send` function will be wrapped by the `gate` to encrypt the data before sending it to the client. | ||
Predecessors like `.json()` and `.status()` can be used as well. | ||
```javascript | ||
app.use(rsa.gate); | ||
app.post("/example", (req, res) => { | ||
res.status(200).send(DATA); // L0SQ23..... | ||
}); | ||
``` | ||
The wrapped `res` will extend throughout the _request_ until the _response_, even with the use of `next()` for example. | ||
```javascript | ||
app.use(rsa.gate); | ||
app.use((req, res, next) => { | ||
next(); | ||
}); | ||
app.use((req, res) => { | ||
res.status(200).json(DATA); // L0SQ23..... | ||
}); | ||
``` | ||
### Basic RSA Functions | ||
#### Encrypt | ||
Returns encrypted data as `base64` | ||
```javascript | ||
const encrypted = rsa.encrypt(data); | ||
``` | ||
#### Decrypt | ||
returns decrypted data as `utf8` | ||
```javascript | ||
const decrypted = rsa.decrypt(data); | ||
``` | ||
#### encryptWithKey | ||
returns encrypted data as `base64` encrypted with a different key | ||
```javascript | ||
const encrypted = rsa.encryptWithKey(key, data, format?); | ||
``` | ||
#### publicKey | ||
exports the node's public key. The default encoding is "UTF8" but can be changed. | ||
```javascript | ||
const publicKey = rsa.publicKey(KeyFormat, OutputEncoding); | ||
``` | ||
--- | ||
### ReactJS Example | ||
An example implementation with reactJS is available in [examples](https://github.com/HugoRodriguesQW/rsa-bridge/tree/main/examples). There is a live version at [https://rsa-bridge.vercel.app](https://rsa-bridge.vercel.app) | ||
<a href="https://pkg-size.dev/rsa-bridge"><img src="https://pkg-size.dev/badge/install/254646" title="Install size for rsa-bridge"></a> <a href="https://pkg-size.dev/rsa-bridge"><img src="https://pkg-size.dev/badge/bundle/68049" title="Bundle size for rsa-bridge"> </a>[](https://github.com/HugoRodriguesQW/rsa-bridge/actions/workflows/testing.yml)   |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
55222
234
16
688