Skip to content

Commit 26665c0

Browse files
authored
'import' syntax compatible and TypeScript declaration file (#1038)
* exports * Add TypeScript declaration file (index.d.ts) * Add example for TypeScript * Add flow for NodeJS with Typescript example * CHANGELOG.md updated * added import_module.mjs and test * downgrade typescript to 4.4 to be compatible with node 12 * update workflow
1 parent e924f76 commit 26665c0

File tree

15 files changed

+387
-3
lines changed

15 files changed

+387
-3
lines changed

.github/workflows/test-nodejs.yaml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
paths:
66
- '.github/workflows/test-nodejs.yaml'
77
- 'docs/examples/js/**'
8+
- 'docs/examples/ts/**'
89
- 'src/soter/**'
910
- 'src/themis/**'
1011
- 'src/wrappers/themis/jsthemis/**'
@@ -132,3 +133,62 @@ jobs:
132133
node secure_comparator_client.js
133134
kill -SIGTERM "$!"
134135
echo "ok"
136+
- name: Test 'import' syntax
137+
if: always()
138+
run: |
139+
cd $GITHUB_WORKSPACE/docs/examples/js/
140+
echo "Test import syntax..."
141+
node import_module.mjs
142+
echo "ok"
143+
- name: Install Typescript deps
144+
if: always()
145+
run: |
146+
cd $GITHUB_WORKSPACE/docs/examples/ts/
147+
npm install
148+
npm run compile
149+
- name: Test Typescript examples (Secure Keygen)
150+
if: always()
151+
run: |
152+
cd $GITHUB_WORKSPACE/docs/examples/ts
153+
echo "Test Secure Keygen..."
154+
node secure_keygen.js
155+
echo "ok"
156+
- name: Test Typescript examples (Secure Cell)
157+
if: always()
158+
run: |
159+
cd $GITHUB_WORKSPACE/docs/examples/ts
160+
echo "Test Secure Cell..."
161+
node secure_cell.js
162+
echo "ok"
163+
- name: Test Typescript examples (Secure Message)
164+
if: always()
165+
run: |
166+
cd $GITHUB_WORKSPACE/docs/examples/ts
167+
echo "Test Secure Message..."
168+
alice=($(node secure_keygen.js | cut -c 15-))
169+
bob=($(node secure_keygen.js | cut -c 15-))
170+
enc=$(node secure_message.js enc "${alice[1]}" "${bob[2]}" message)
171+
dec=$(node secure_message.js dec "${bob[1]}" "${alice[2]}" "$enc")
172+
test "$dec" = "message"
173+
echo "ok"
174+
- name: Test Typescript examples (Secure Session)
175+
if: always()
176+
run: |
177+
cd $GITHUB_WORKSPACE/docs/examples/ts
178+
echo "Test Secure Session..."
179+
node secure_session_server.js &
180+
sleep 1 # give the server time to launch
181+
node secure_session_client.js > output.txt
182+
kill -SIGTERM "$!"
183+
grep -q 'Hello server!!!' output.txt
184+
echo "ok"
185+
- name: Test Typescript examples (Secure Comparator)
186+
if: always()
187+
run: |
188+
cd $GITHUB_WORKSPACE/docs/examples/ts
189+
echo "Test Secure Comparator..."
190+
node secure_comparator_server.js &
191+
sleep 1 # give the server time to launch
192+
node secure_comparator_client.js
193+
kill -SIGTERM "$!"
194+
echo "ok"

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44

55
Changes that are currently in development and have not been released yet.
66

7-
## [0.15.2](https://github.com/cossacklabs/themis/releases/tag/0.15.2), October 03 2023
7+
## [0.15.2](https://github.com/cossacklabs/themis/releases/tag/0.15.2), November 24 2023
8+
9+
### JsThemis wrapper
10+
- Added the ability to use the `import` syntax for the jsthemis module.
11+
- Added a declaration file for TypeScript.
812

913
### Android, ReactNative wrappers
1014
Updated versions of dependencies. New minimum versions of iOS, Android are set.

docs/examples/js/import_module.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import themis from 'jsthemis';
2+
const { SymmetricKey, KeyPair} = themis;
3+
4+
let masterKey = new SymmetricKey()
5+
console.log(masterKey);
6+
7+
let keypair = new KeyPair()
8+
let privateKey = keypair.private()
9+
let publicKey = keypair.public()
10+
console.log(privateKey);
11+
console.log(publicKey);

docs/examples/ts/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Examples for JsThemis using TypeScript
2+
3+
## Install
4+
```
5+
git clone https://github.com/cossacklabs/themis.git
6+
cd docs/examples/ts
7+
npm install
8+
```
9+
10+
## Compile
11+
```
12+
npm run compile
13+
```
14+
The command will compile TypeScript code into Javascript.
15+
16+
## Run
17+
```
18+
node ./secure_keygen.js
19+
node ./secure_cell.js
20+
node ./secure_message.js enc private1 public2 message
21+
node ./secure_message.js dec private2 public1 message
22+
node ./secure_comparator_server.js
23+
node ./secure_comparator_client.js
24+
node ./secure_session_server.js
25+
node ./secure_session_client.js
26+
```
27+
`private1, private2, public1, public2` is the keys which can be generated by `secure_keygen.js`
28+
29+
Just run command by command to see how examples work.
30+
31+
## Clean
32+
```
33+
npm run clean
34+
```
35+
The command will delete all compiled JS files.

docs/examples/ts/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "ts_examples_themis",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "secure_keygen.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1",
8+
"clean": "rm *.js",
9+
"compile": "find . -maxdepth 1 -type f -name '*.ts' -exec ./node_modules/.bin/tsc {} \\;"
10+
},
11+
"author": "",
12+
"license": "ISC",
13+
"dependencies": {
14+
"@types/node": "^20.9.5",
15+
"typescript": "^4.4"
16+
}
17+
}

docs/examples/ts/secure_cell.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { SecureCellSeal, SecureCellTokenProtect, SecureCellContextImprint } from "jsthemis"
2+
3+
const message = Buffer.from('Test Message Please Ignore', 'utf-8')
4+
const context = Buffer.from('Secure Cell example code','utf-8')
5+
const master_key = Buffer.from('bm8sIHRoaXMgaXMgbm90IGEgdmFsaWQgbWFzdGVyIGtleQ==', 'base64')
6+
const passphrase = 'My Litte Secret: Passphrase Is Magic'
7+
8+
console.log('# Secure Cell in Seal mode\n')
9+
console.log('## Master key API\n')
10+
const scellMK = SecureCellSeal.withKey(master_key)
11+
const encrypted_message = scellMK.encrypt(message)
12+
console.log('Encrypted: ' + Buffer.from(encrypted_message).toString('base64'))
13+
const decrypted_message = scellMK.decrypt(encrypted_message)
14+
console.log('Decrypted: ' + Buffer.from(decrypted_message).toString())
15+
console.log()
16+
17+
const encrypted_message2 = Buffer.from('AAEBQAwAAAAQAAAAEQAAAC0fCd2mOIxlDUORXz8+qCKuHCXcDii4bMF8OjOCOqsKEdV4+Ga2xTHPMupFvg==', 'base64')
18+
const decrypted_message2 = scellMK.decrypt(encrypted_message2)
19+
console.log('Decrypted (simulator): ' + Buffer.from(decrypted_message2).toString())
20+
console.log()
21+
console.log('## Passphrase API\n')
22+
23+
const scellPW = SecureCellSeal.withPassphrase(passphrase)
24+
const encrypted_message3 = scellPW.encrypt(message)
25+
console.log('Encrypted: ' + Buffer.from(encrypted_message3).toString('base64'))
26+
const decrypted_message3 = scellPW.decrypt(encrypted_message3)
27+
console.log('Decrypted: ' + Buffer.from(decrypted_message3).toString())
28+
console.log()
29+
30+
console.log('# Secure Cell in Token Protect mode\n')
31+
32+
const scellTP = SecureCellTokenProtect.withKey(master_key)
33+
const encrypted_message4 = scellTP.encrypt(message)
34+
console.log('Encrypted: ' + Buffer.from(encrypted_message4.data).toString('base64'))
35+
console.log('Auth token: ' + Buffer.from(encrypted_message4.token).toString('base64'))
36+
const decrypted_message4 = scellTP.decrypt(encrypted_message4.data, encrypted_message4.token)
37+
console.log('Decrypted: ' + Buffer.from(decrypted_message4).toString())
38+
console.log('')
39+
40+
console.log('# Secure Cell in Context Imprint mode\n')
41+
const scellCI = SecureCellContextImprint.withKey(master_key)
42+
const encrypted_message5 = scellCI.encrypt(message, context)
43+
console.log('Encrypted: ' + Buffer.from(encrypted_message5).toString('base64'))
44+
const decrypted_message5 = scellCI.decrypt(encrypted_message5, context)
45+
console.log('Decrypted: ' + Buffer.from(decrypted_message5).toString())
46+
console.log('')
47+
console.log('SecureCell example code finished')
48+
49+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Socket } from 'net';
2+
import { SecureComparator } from 'jsthemis';
3+
4+
const comparator = new SecureComparator(Buffer.from("secret"));
5+
6+
const client = new Socket();
7+
client.connect(1337, '127.0.0.1', () => {
8+
console.log('Connected');
9+
client.write(comparator.beginCompare());
10+
});
11+
12+
client.on('data', (data: Buffer) => {
13+
const d = comparator.proceedCompare(data);
14+
if (!comparator.isCompareComplete()) {
15+
client.write(d);
16+
} else {
17+
console.log(comparator.isMatch());
18+
client.destroy();
19+
}
20+
});
21+
22+
client.on('close', () => {
23+
console.log('Connection closed');
24+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createServer, Socket } from 'net';
2+
import { SecureComparator } from 'jsthemis';
3+
4+
const server = createServer((socket: Socket) => {
5+
const comparator = new SecureComparator(Buffer.from("secret"));
6+
7+
socket.on('data', (data: Buffer) => {
8+
const d = comparator.proceedCompare(data);
9+
socket.write(d);
10+
if (comparator.isCompareComplete()) {
11+
console.log(comparator.isMatch());
12+
socket.destroy();
13+
}
14+
});
15+
});
16+
17+
server.listen(1337, '127.0.0.1');

docs/examples/ts/secure_keygen.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { KeyPair, SymmetricKey } from 'jsthemis';
2+
3+
const masterKey = new SymmetricKey() as Uint8Array;
4+
console.log("master key: ", Buffer.from(masterKey).toString("base64"));
5+
6+
const keypair = new KeyPair();
7+
console.log("private key: ", Buffer.from(keypair.private()).toString("base64"));
8+
console.log("public key : ", Buffer.from(keypair.public()).toString("base64"));

docs/examples/ts/secure_message.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { SecureMessage } from 'jsthemis';
2+
3+
if (process.argv.length == 6) {
4+
const command = process.argv[2];
5+
const private_key = process.argv[3];
6+
const peer_public_key = process.argv[4];
7+
const secure_message = new SecureMessage(
8+
Buffer.from(private_key, "base64"),
9+
Buffer.from(peer_public_key, "base64"));
10+
11+
if (command == "enc") {
12+
const encrypted_message = secure_message.encrypt(Buffer.from(process.argv[5]));
13+
console.log(Buffer.from(encrypted_message).toString("base64"));
14+
} else if (command == "dec") {
15+
const decrypted_message = secure_message.decrypt(Buffer.from(process.argv[5], "base64"));
16+
console.log(Buffer.from(decrypted_message).toString("utf8"));
17+
} else {
18+
console.log("usage node secure_message.js <enc/dec> <private key> <peer public key> <message>");
19+
}
20+
} else {
21+
console.log("usage node secure_message.js <enc/dec> <private key> <peer public key> <message>");
22+
}

0 commit comments

Comments
 (0)