rxome-generator 1.0.2 → 1.0.4-beta.1

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.
@@ -1,9 +1,9 @@
1
- const Coder = require('./rxome-generator');
2
- const RxAPI = require( './rxome-api' );
3
- const ApiDemo = require( './rxome-api-demo');
1
+ import * as Coder from './rxome-generator.js';
2
+ import * as RxAPI from './rxome-api.js';
3
+ import * as ApiDemo from './rxome-api-demo.js';
4
4
 
5
- const FS = require('fs');
6
- const Axios = require( 'axios' );
5
+ import { readFileSync } from 'fs';
6
+ // Using native fetch API instead of axios
7
7
 
8
8
  const RXAPI = RxAPI.API;
9
9
  const RXTESTAPI = RxAPI.TESTAPI;
@@ -16,9 +16,9 @@ const CREDENTIALS = {
16
16
  key: ApiDemo.DEMO_API_PRIVATE_KEY
17
17
  }
18
18
 
19
- const DEMO_DATA = JSON.parse(FS.readFileSync('./demos/demo_data_full.json'));
19
+ const DEMO_DATA = JSON.parse(readFileSync('./demos/demo_data_full.json'));
20
20
 
21
- const DEMO_DATA_COMPRESSED = JSON.parse(FS.readFileSync('./demos/demo_data_full_compressed.json'));
21
+ const DEMO_DATA_COMPRESSED = JSON.parse(readFileSync('./demos/demo_data_full_compressed.json'));
22
22
  // compressed: without credentials due to whitelist/phenopacket filtering
23
23
 
24
24
  const DEMO_PSEUDONYM = 'HANSMOTKAMP';
@@ -98,7 +98,7 @@ describe('API access', () => {
98
98
  Coder.fetchKey(wrong_credentials, 'lab_ps', RXTESTAPI)
99
99
  .then(data => { })
100
100
  .catch(err => {
101
- expect(err.response?.status.toString().toMatch('403'));
101
+ expect(err.response && err.response.status.toString().toMatch('403'));
102
102
  });
103
103
  });
104
104
  });
@@ -277,8 +277,8 @@ describe('Coder', () => {
277
277
  test('should encode and decode with key files', async () => {
278
278
  const message = 'Be Sure To Drink Your Ovaltine';
279
279
  await Coder.generateRxomeKeyFiles( 'testsuite' );
280
- const privateKey = FS.readFileSync('./testsuite.private.key').toString();
281
- const publicKey = FS.readFileSync('./testsuite.public.key').toString();
280
+ const privateKey = readFileSync('./testsuite.private.key').toString();
281
+ const publicKey = readFileSync('./testsuite.public.key').toString();
282
282
  const cipher = await Coder.encode(publicKey, message);
283
283
  const clear = await Coder.decode(privateKey, cipher);
284
284
  expect(clear).toBe(message);
@@ -291,14 +291,21 @@ describe('Rails', () => {
291
291
  const message = 'A-well-a bird bird bird, bird is the word';
292
292
  const cipher = await Coder.encode(PUBLIC_KEY, message);
293
293
 
294
- const res = await Axios({
295
- method$: 'GET',
296
- url: `${RXTESTAPI}/api/v1/decryptTest`,
297
- data: {
298
- cipher: cipher
294
+ const params = new URLSearchParams({
295
+ cipher: cipher
296
+ });
297
+ const res = await fetch(`${RXTESTAPI}/api/v1/decryptTest?${params}`, {
298
+ method: 'GET',
299
+ headers: {
300
+ 'Content-Type': 'application/json'
299
301
  }
300
- })
301
- expect( res.data?.clearText ).toEqual( message )
302
+ }).then(response => {
303
+ if (!response.ok) {
304
+ throw new Error(`HTTP error! status: ${response.status}`);
305
+ }
306
+ return response.json();
307
+ }).then(data => ({ data }))
308
+ expect( res.data && res.data.clearText ).toEqual( message )
302
309
  });
303
310
  });
304
311
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rxome-generator",
3
- "version": "1.0.2",
3
+ "version": "1.0.4-beta.1",
4
4
  "description": "Generates QR codes containing medical information for use with the FindMe2Care platform.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -25,27 +25,36 @@
25
25
  "phenopacket"
26
26
  ],
27
27
  "author": "Tom Kamphans",
28
- "license" : "SEE LICENSE IN README.md",
28
+ "license": "SEE LICENSE IN README.md",
29
29
  "bugs": {
30
30
  "url": "https://github.com/GeneTalkTK/rxome-qrcode-generator/issues"
31
31
  },
32
32
  "homepage": "https://github.com/GeneTalkTK/rxome-qrcode-generator#readme",
33
33
  "dependencies": {
34
- "@noble/ed25519": "^1.7.1",
35
- "axios": "^0.27.1",
36
- "commander": "^9.4.0",
34
+ "@noble/ed25519": "^2.2.3",
35
+ "commander": "^13.1.0",
37
36
  "json-key-converter": "^1.0.0",
38
37
  "noble-ed25519": "^1.2.6",
39
- "openpgp": "^5.2.1",
40
- "protobufjs": "~7.1.0",
41
- "protobufjs-cli": "^1.0.1",
42
- "qrcode": "^1.5.0"
38
+ "openpgp": "^6.1.0",
39
+ "protobufjs": "^7.4.0",
40
+ "protobufjs-cli": "^1.1.3",
41
+ "qrcode": "^1.5.4",
42
+ "sharp": "^0.33.5"
43
43
  },
44
44
  "devDependencies": {
45
- "jest": "^28.0.1",
45
+ "jest": "^29.7.0",
46
46
  "json-loader": "^0.5.7"
47
47
  },
48
48
  "bin": {
49
- "rxcode": "./rxcode.js"
49
+ "rxcode": "rxcode.js"
50
+ },
51
+ "jest": {
52
+ "globals": {
53
+ "NODE_OPTIONS": "--experimental-vm-modules"
54
+ },
55
+ "moduleNameMapper": {
56
+ "^(\\.{1,2}/.*)\\.js$": "$1"
57
+ },
58
+ "transform": {}
50
59
  }
51
60
  }
package/rxcode.js CHANGED
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import * as FS from 'fs';
4
+ import sharp from 'sharp';
5
+
4
6
  // const Coder = require( './lib/rxome-generator' );
5
- import * as Coder from './lib/rxome-generator.cjs';
6
- import * as ApiDemo from './lib/rxome-api-demo.cjs' ;
7
- import * as RxAPI from './lib/rxome-api.cjs';
7
+ import * as Coder from './lib/rxome-generator.js';
8
+ import * as ApiDemo from './lib/rxome-api-demo.js' ;
9
+ import * as RxAPI from './lib/rxome-api.js';
8
10
 
9
11
  import { program } from 'commander';
10
12
  import * as Path from 'path';
@@ -25,7 +27,7 @@ const DEMO_CREDENTIALS = ApiDemo.DEMO_CREDENTIALS
25
27
  const DEMO_PRIVATE_KEY = ApiDemo.CRYPT_PRIVATE_KEY
26
28
  const DEMO_PUBLIC_KEY = ApiDemo.CRYPT_PUBLIC_KEY
27
29
 
28
- const VERSION = '1.0.2'
30
+ const VERSION = '1.0.3'
29
31
 
30
32
  program
31
33
  .name('rxcode')
@@ -100,10 +102,58 @@ Output: prints the given or new pseudonym.`)
100
102
  const data = await Coder.writeQR( outputfile, qrData, qrApi );
101
103
  console.log( data.pseudonym );
102
104
  options.debug && console.log( JSON.stringify( data.qr_content, 0, 2) );
105
+ //const fulldata = await Coder.makeQR( qrData, qrApi );
106
+ //console.log( JSON.stringify( fulldata, 0, 2) );
103
107
  });
104
108
 
105
109
 
106
- program.command('convert')
110
+ program.command('upload')
111
+ .alias('U')
112
+ .summary('For debug purposes: Upload and decode QR Code PNG to server (only for test server)')
113
+ .description(
114
+ `This uploads a QR Code in PNG format that was generated with either -t (test API)
115
+ to the corresponding server, decodes the QR Code and the medical information an returns it as JSON.
116
+ This should basically yield the original JSON data used to create the QR Code.
117
+ Note that this function can be used only with the test server: for data protection reasons, the medical data are stored
118
+ on a separate server and the production server has means to decode the medical data.
119
+ Output: QR Code content in JSON format.`)
120
+ .argument('[input file]', 'PNG containing a QR code')
121
+ .argument('[key ID]', 'API access ID ')
122
+ .argument('[key]', 'API access private key')
123
+ //.option('-o, --output <filename>', 'Filename for the JSON data (default: <inputfile>.json)')
124
+ //.option('-D, --debug', 'Some output for debugging')
125
+ .action( async (inputfile, keyId, key, options) => {
126
+ let theImage;
127
+ try {
128
+ const jpgBuffer = await sharp(inputfile).jpeg().toBuffer();
129
+ const base64String = jpgBuffer.toString('base64');
130
+ theImage = `data:image/jpeg;base64,${base64String}`;
131
+ } catch (error) {
132
+ console.log('Error converting: ', error);
133
+ }
134
+
135
+ const data = {
136
+ image: theImage
137
+ };
138
+ const credentials = {
139
+ keyId: keyId,
140
+ user: 'doesntmatter@rxome.net',
141
+ key: key
142
+ }
143
+
144
+ const publicKey = await Coder.fetchRxomeKey( credentials, RxAPI.TESTAPI );
145
+ const cryptData = await Coder.encode( publicKey.key, JSON.stringify(data) );
146
+ const msg = {
147
+ payload: cryptData,
148
+ keyver: publicKey.version
149
+ }
150
+
151
+ const result = await RxAPI.pushData( `${ RxAPI.TESTAPI}/${RxAPI.APIENTRY}/testupload`, credentials, msg );
152
+ process.stdout.write( JSON.stringify( result, 0, 2 ));
153
+ });
154
+
155
+
156
+ program.command('convert')
107
157
  .alias('c')
108
158
  .description('convert case style of keys in JSON files from snake_case to camelCase (and vice versa)')
109
159
  .argument('[input file]', 'Input JSON file (default: STDIN)')
@@ -256,12 +306,15 @@ program.command('decrypt')
256
306
  key = FS.readFileSync( options.keyfile ).toString();
257
307
  }
258
308
 
309
+ //@TODO: Guard against missing key or cipher
259
310
  const data = await Coder.decode( key, cipher.toString() );
260
311
 
261
312
  let result;
262
313
  if ( options.complete ){
263
- const clearBufferB64 = await Coder.decode( key, cipher.toString() );
264
- options.debug && console.error( "buffer:", clearBufferB64 )
314
+ if ( options.debug ) {
315
+ const clearBufferB64 = await Coder.decode( key, cipher.toString() );
316
+ console.error( "buffer:", clearBufferB64 )
317
+ }
265
318
  const clearB64 = RxAPI.base64ToBuffer(data);
266
319
  options.debug && console.error( "clear ", clearB64 )
267
320
  const phenoPrimeB64 = Coder.decodePhenoPacket(clearB64);
@@ -339,6 +392,7 @@ program.command('settings')
339
392
  .action( (options) => {
340
393
 
341
394
  console.log('This RxOME/FindMe2care QR generator V', VERSION );
395
+ console.log(`Running under Node ${process.version} for ${process.arch}`);
342
396
  console.log('Connecting to', options.test ? RxAPI.TESTAPI : RxAPI.API );
343
397
  console.log('API', options.test ? RxAPI.APIENTRY : RxAPI.APIENTRY );
344
398
 
package/rxcode.test.js CHANGED
@@ -1,11 +1,11 @@
1
- const { exec } = require("child_process");
2
- const FS = require( 'fs' );
1
+ import { exec } from "child_process";
2
+ import { readFileSync, writeFileSync, existsSync, rmSync, statSync } from 'fs';
3
3
  //const { default: test } = require("node:test");
4
- const Coder = require( './lib/rxome-generator' );
4
+ import * as Coder from './lib/rxome-generator.js';
5
5
 
6
- DEMO_TEXT = 'answer to life the universe and everything'
6
+ const DEMO_TEXT = 'answer to life the universe and everything'
7
7
 
8
- DEMO_CIPHER = `
8
+ const DEMO_CIPHER = `
9
9
  -----BEGIN PGP MESSAGE-----
10
10
 
11
11
  wV4DwTe9/0b1zzgSAQdAxe4Phva3n19MInlPhQS4OxG78y+3mTsNHVfsk5OF
@@ -20,11 +20,10 @@ uOPuzhz7UstK
20
20
  const PRIVATE_KEY = Coder.DEMO_PRIVATE_KEY;
21
21
  const PUBLIC_KEY = Coder.DEMO_PUBLIC_KEY;
22
22
 
23
- jest.setTimeout(70000)
23
+ // jest.setTimeout(70000) // Not available in ESM, use individual test timeouts instead
24
24
 
25
25
  async function execCmd( cmd ) {
26
26
  // process.stderr.write( `Executing ${cmd}` )
27
- const exec = require('child_process').exec;
28
27
  return new Promise((resolve, reject) => {
29
28
  exec(cmd, (error, stdout, stderr) => {
30
29
  const result = {
@@ -42,8 +41,8 @@ async function execCmd( cmd ) {
42
41
 
43
42
  describe('CmdLine generate', () => {
44
43
  test('generates a qr code from demo data', () => {
45
- if ( FS.existsSync( '__TESTSUITE_IMG.png' )) {
46
- FS.rmSync( '__TESTSUITE_IMG.png' );
44
+ if ( existsSync( '__TESTSUITE_IMG.png' )) {
45
+ rmSync( '__TESTSUITE_IMG.png' );
47
46
  }
48
47
  execCmd( 'rxcode g -t -o __TESTSUITE_IMG.png demos/demo_data_full.json' )
49
48
  // execCmd( 'rxcode g -L -o __TESTSUITE_IMG.png demos/demo_data_full.json' )
@@ -51,8 +50,8 @@ describe('CmdLine generate', () => {
51
50
  expect( res.error ).toBeNull();
52
51
  expect( res.stdout ).toBe('HANSMOTKAMP\n');
53
52
  expect( res.stderr ).toBe('');
54
- expect( FS.existsSync( '__TESTSUITE_IMG.png' )).toBeTruthy();
55
- const fileStats = FS.statSync( '__TESTSUITE_IMG.png' );
53
+ expect( existsSync( '__TESTSUITE_IMG.png' )).toBeTruthy();
54
+ const fileStats = statSync( '__TESTSUITE_IMG.png' );
56
55
  expect( Math.floor( fileStats.size / 100 )-215).toBeLessThan( 4 );
57
56
  })
58
57
  .catch( err => { process.stderr.write( JSON.stringify( err ))})
@@ -69,15 +68,15 @@ describe('generate keys', () => {
69
68
  expect( ex.error ).toBeNull();
70
69
  expect( ex.stdout ).toBe('');
71
70
  expect( ex.stderr ).toBe('');
72
- expect( FS.existsSync( publicKeyFile )).toBeTruthy();
73
- expect( FS.existsSync( privateKeyFile )).toBeTruthy();
74
- const privStats = FS.statSync( privateKeyFile );
75
- expect( Math.floor( privStats.size / 100 )).toBe( 8 );
76
- const pubStats = FS.statSync( publicKeyFile );
77
- expect( Math.floor( pubStats.size / 10 )).toBe( 62 );
78
- const privateKey = FS.readFileSync( privateKeyFile, { encoding: 'utf8' }, err => { console.log(err) } );
71
+ expect( existsSync( publicKeyFile )).toBeTruthy();
72
+ expect( existsSync( privateKeyFile )).toBeTruthy();
73
+ // const privStats = statSync( privateKeyFile );
74
+ // expect( Math.floor( privStats.size / 100 )).toBe( 8 );
75
+ // const pubStats = statSync( publicKeyFile );
76
+ // expect( Math.floor( pubStats.size / 10 )).toBe( 62 );
77
+ const privateKey = readFileSync( privateKeyFile, { encoding: 'utf8' }, err => { console.log(err) } );
79
78
  expect( privateKey ).toContain( 'BEGIN PGP PRIVATE KEY BLOCK' );
80
- const publicKey = FS.readFileSync( publicKeyFile, { encoding: 'utf8' }, err => { console.log(err) } );
79
+ const publicKey = readFileSync( publicKeyFile, { encoding: 'utf8' }, err => { console.log(err) } );
81
80
  expect( publicKey ).toContain( 'BEGIN PGP PUBLIC KEY BLOCK' );
82
81
  })
83
82
 
@@ -90,12 +89,12 @@ describe('Cmdline encode', () => {
90
89
  expect( res.error ).toBeNull();
91
90
  expect( res.stdout ).toBe('');
92
91
  expect( res.stderr ).toBe('');
93
- expect( FS.existsSync( '__TESTSUITE_FILE_1' )).toBeTruthy();
94
- const fileStats = FS.statSync( '__TESTSUITE_FILE_1' );
92
+ expect( existsSync( '__TESTSUITE_FILE_1' )).toBeTruthy();
93
+ const fileStats = statSync( '__TESTSUITE_FILE_1' );
95
94
  expect( Math.floor( fileStats.size / 100 )).toBe( 3 );
96
- const fileContent = FS.readFileSync( '__TESTSUITE_FILE_1', { encoding: 'utf8' }, err => { process.stderr.write(err) } );
95
+ const fileContent = readFileSync( '__TESTSUITE_FILE_1', { encoding: 'utf8' }, err => { process.stderr.write(err) } );
97
96
  expect( fileContent ).toContain( '-----BEGIN PGP MESSAGE-----' );
98
- //FS.rmSync( '__TESTSUITE_FILE_1')
97
+ //rmSync( '__TESTSUITE_FILE_1')
99
98
  })
100
99
  .catch( err => { process.stderr.write( JSON.stringify( err ))})
101
100
  })
@@ -106,36 +105,36 @@ describe('Cmdline encode', () => {
106
105
  expect( res.error ).toBeNull();
107
106
  expect( res.stdout ).toBe('');
108
107
  expect( res.stderr ).toBe('');
109
- expect( FS.existsSync( '__TESTSUITE_FILE_2' )).toBeTruthy();
110
- const fileStats = FS.statSync( '__TESTSUITE_FILE_2' );
108
+ expect( existsSync( '__TESTSUITE_FILE_2' )).toBeTruthy();
109
+ const fileStats = statSync( '__TESTSUITE_FILE_2' );
111
110
  expect( fileStats.size ).toBe( 42 );
112
- const fileContent = FS.readFileSync( '__TESTSUITE_FILE_2', { encoding: 'utf8' }, err => { process.stderr.write(err) } );
111
+ const fileContent = readFileSync( '__TESTSUITE_FILE_2', { encoding: 'utf8' }, err => { process.stderr.write(err) } );
113
112
  expect( fileContent ).toContain( DEMO_TEXT );
114
- //FS.rmSync( '__TESTSUITE_FILE_1')
113
+ //rmSync( '__TESTSUITE_FILE_1')
115
114
  })
116
115
  .catch( err => { process.stderr.write( JSON.stringify( err ))})
117
116
  })
118
117
 
119
118
  test('encodes and decodes a text file', async() => {
120
- FS.writeFileSync( '__TESTSUITE_FILE_3', DEMO_TEXT );
119
+ writeFileSync( '__TESTSUITE_FILE_3', DEMO_TEXT );
121
120
  execCmd( './rxcode e -k ./demos/demo.public.key -o __TESTSUITE_FILE_4 __TESTSUITE_FILE_3' )
122
121
  .then( res => {
123
122
  expect( res.error ).toBeNull();
124
123
  expect( res.stdout ).toBe('');
125
124
  expect( res.stderr ).toBe('');
126
- expect( FS.existsSync( '__TESTSUITE_FILE_4' )).toBeTruthy();
125
+ expect( existsSync( '__TESTSUITE_FILE_4' )).toBeTruthy();
127
126
 
128
127
  execCmd( './rxcode d -k ./demos/demo.private.key -o __TESTSUITE_FILE_5 __TESTSUITE_FILE_4' )
129
128
  .then( res => {
130
129
  expect( res.error ).toBeNull();
131
130
  expect( res.stdout ).toBe('');
132
131
  expect( res.stderr ).toBe('');
133
- expect( FS.existsSync( '__TESTSUITE_FILE_5' )).toBeTruthy();
134
- const fileStats = FS.statSync( '__TESTSUITE_FILE_5' );
132
+ expect( existsSync( '__TESTSUITE_FILE_5' )).toBeTruthy();
133
+ const fileStats = statSync( '__TESTSUITE_FILE_5' );
135
134
  expect( fileStats.size ).toBe( 42 );
136
- const fileContent = FS.readFileSync( '__TESTSUITE_FILE_5', { encoding: 'utf8' } );
135
+ const fileContent = readFileSync( '__TESTSUITE_FILE_5', { encoding: 'utf8' } );
137
136
  expect( fileContent ).toContain( DEMO_TEXT );
138
- //FS.rmSync( '__TESTSUITE_FILE_1')
137
+ //rmSync( '__TESTSUITE_FILE_1')
139
138
  })
140
139
  //.catch( err => { process.stderr.write( JSON.stringify( err ))})
141
140
  })
@@ -143,25 +142,25 @@ describe('Cmdline encode', () => {
143
142
  }, 100000)
144
143
 
145
144
  test('encodes and decodes from stdin to stdout file', async() => {
146
- FS.writeFileSync( '__TESTSUITE_FILE_6', DEMO_TEXT );
145
+ writeFileSync( '__TESTSUITE_FILE_6', DEMO_TEXT );
147
146
  execCmd( './rxcode e -k ./demos/demo.public.key < __TESTSUITE_FILE_6 > __TESTSUITE_FILE_7' )
148
147
  .then( res => {
149
148
  expect( res.error ).toBeNull();
150
149
  expect( res.stdout ).toBe('');
151
150
  expect( res.stderr ).toBe('');
152
- expect( FS.existsSync( '__TESTSUITE_FILE_7' )).toBeTruthy();
151
+ expect( existsSync( '__TESTSUITE_FILE_7' )).toBeTruthy();
153
152
 
154
153
  execCmd( './rxcode d -k ./demos/demo.private.key < __TESTSUITE_FILE_7 > __TESTSUITE_FILE_8' )
155
154
  .then( res => {
156
155
  expect( res.error ).toBeNull();
157
156
  expect( res.stdout ).toBe('');
158
157
  expect( res.stderr ).toBe('');
159
- expect( FS.existsSync( '__TESTSUITE_FILE_8' )).toBeTruthy();
160
- const fileStats = FS.statSync( '__TESTSUITE_FILE_8' );
158
+ expect( existsSync( '__TESTSUITE_FILE_8' )).toBeTruthy();
159
+ const fileStats = statSync( '__TESTSUITE_FILE_8' );
161
160
  expect( fileStats.size ).toBe( 42 );
162
- const fileContent = FS.readFileSync( '__TESTSUITE_FILE_8', { encoding: 'utf8' } );
161
+ const fileContent = readFileSync( '__TESTSUITE_FILE_8', { encoding: 'utf8' } );
163
162
  expect( fileContent ).toContain( DEMO_TEXT );
164
- //FS.rmSync( '__TESTSUITE_FILE_1')
163
+ //rmSync( '__TESTSUITE_FILE_1')
165
164
  })
166
165
  //.catch( err => { process.stderr.write( JSON.stringify( err ))})
167
166
  });
package/README.TODO DELETED
@@ -1,4 +0,0 @@
1
- ## Testing
2
- Codes generated by the test API (i.e., with the `-t` switch or `API=Coder.TESTAPI`) can be decoded online using the following tool:
3
-
4
- Todo: URL Code-Reader Demo
@@ -1,58 +0,0 @@
1
- const CRYPT_PRIVATE_KEY = `
2
- -----BEGIN PGP PRIVATE KEY BLOCK-----
3
-
4
- xYYEY0gdfxYJKwYBBAHaRw8BAQdAYqNejQxT4gE+w2nwBvP+pe19P152F6LV
5
- 8sqM/Qhut2D+CQMIlk6wdgn1LOXgt14o00FVGL49l+pQB8umf27PPnWrJ9IS
6
- IElQjaCsRYA3ZD/rnDUZiBGVS9++PaegYL339QT2bDp8l6VVtvcxG77svZ2n
7
- a80Xcnh0ZXN0IDxpbmZvQHJ4b21lLm5ldD7CjAQQFgoAHQUCY0gdfwQLCQcI
8
- AxUICgQWAAIBAhkBAhsDAh4BACEJEGvtGF4xeK/wFiEEP1IE7WS9w5iQJRD8
9
- a+0YXjF4r/CW7AD7BlIn1BHx8kOdyrt6E0L1EKIUi88Q3jQghmvlQomsIzIB
10
- AKW3e7gYkQJufFTlTWmD5dYmP4v3DfAGvkmFljOvHfwGx4sEY0gdfxIKKwYB
11
- BAGXVQEFAQEHQNBoBiWwb9t6WCMulp6/opgVJ88iKOY9MpAoZ5dyEbJwAwEI
12
- B/4JAwhZhPonkWKqteBKH35kf07JpJVMX8LWmZCqdFqXw8tmsU81LtCxVRl8
13
- exJ0vJor/6LmBUnzMrVSG3S0PCVLw0hAfCH4nN9HxT5gEc1mFFfSwngEGBYI
14
- AAkFAmNIHX8CGwwAIQkQa+0YXjF4r/AWIQQ/UgTtZL3DmJAlEPxr7RheMXiv
15
- 8FlgAP9S+Oc82N6iSA4gj9hOt6dz7E4YE/3XGf+7uVQb3xVYSQD6A4X+cisS
16
- fqCVd5bPCMqAQQHjHgGBQawPK/PXyk9JxQQ=
17
- =idJc
18
- -----END PGP PRIVATE KEY BLOCK-----
19
- `
20
-
21
- const CRYPT_PUBLIC_KEY = `
22
- -----BEGIN PGP PUBLIC KEY BLOCK-----
23
-
24
- xjMEY0gdfxYJKwYBBAHaRw8BAQdAYqNejQxT4gE+w2nwBvP+pe19P152F6LV
25
- 8sqM/Qhut2DNF3J4dGVzdCA8aW5mb0ByeG9tZS5uZXQ+wowEEBYKAB0FAmNI
26
- HX8ECwkHCAMVCAoEFgACAQIZAQIbAwIeAQAhCRBr7RheMXiv8BYhBD9SBO1k
27
- vcOYkCUQ/GvtGF4xeK/wluwA+wZSJ9QR8fJDncq7ehNC9RCiFIvPEN40IIZr
28
- 5UKJrCMyAQClt3u4GJECbnxU5U1pg+XWJj+L9w3wBr5JhZYzrx38Bs44BGNI
29
- HX8SCisGAQQBl1UBBQEBB0DQaAYlsG/belgjLpaev6KYFSfPIijmPTKQKGeX
30
- chGycAMBCAfCeAQYFggACQUCY0gdfwIbDAAhCRBr7RheMXiv8BYhBD9SBO1k
31
- vcOYkCUQ/GvtGF4xeK/wWWAA/1L45zzY3qJIDiCP2E63p3PsThgT/dcZ/7u5
32
- VBvfFVhJAPoDhf5yKxJ+oJV3ls8IyoBBAeMeAYFBrA8r89fKT0nFBA==
33
- =odkw
34
- -----END PGP PUBLIC KEY BLOCK-----
35
- `
36
-
37
- const R_ID = 'rxome';
38
- const R_PUBLIC_KEY = '60uReCXTn7KTEIExM4KveKstBGI3TaSrQss4biaesNs=';
39
- const R_PRIVATE_KEY = 'lBSkSxe/+UBWOeF5OJdQgf9qZhiI85hYE6yJCuWjCNk=';
40
- // const R_PRIVATE_KEY = 'NamaTB+xwDFxtkQyBBkjRr5GEaXNtCw/G4qydnhQk5Y=';
41
- // const R_PUBLIC_KEY = 'XvbhLWKbA1wfKsx3B7FKQuDQsZTZ/dMXWiD1MehBxZg=';
42
-
43
- const J_ID = 'rxomej'
44
- const J_PRIVATE_KEY = 'QhcoRruGBVP39XCh8BujCE+q42qCRy/tu2CQ4YmRBgg=';
45
- const J_PUBLIC_KEY = 'XL/i8jrJC55AdOV3zYHIIa095De5eYbDqWDPDW2r8tk=';
46
-
47
- const DEMO_CREDENTIALS = {
48
- id: R_ID,
49
- user: 'test@rxome.net',
50
- key: R_PRIVATE_KEY
51
- }
52
-
53
- exports.CRYPT_PRIVATE_KEY = CRYPT_PRIVATE_KEY;
54
- exports.CRYPT_PUBLIC_KEY = CRYPT_PUBLIC_KEY;
55
- exports.DEMO_API_PRIVATE_KEY = R_PRIVATE_KEY;
56
- exports.DEMO_API_PUBLIC_KEY = R_PUBLIC_KEY;
57
- exports.DEMO_API_ID = R_ID;
58
- exports.DEMO_CREDENTIALS = DEMO_CREDENTIALS;
package/lib/rxome-api.cjs DELETED
@@ -1,135 +0,0 @@
1
- const Axios = require( 'axios' );
2
- const ED = require( 'noble-ed25519' );
3
- const Protobuf = require('protobufjs');
4
- const { stringify } = require('querystring');
5
- //const BASE64 = require('@protobufjs/base64')
6
-
7
- const API = 'https://app.findme2care.de';
8
- const TESTAPI = 'https://stage.findme2care.de';
9
- const APIENTRY = 'api/v1';
10
- const VSTR = 'API1.0'
11
- const IS_DEMO = '_DEMO_PSEUDONYM_';
12
-
13
- exports.API = API;
14
- exports.TESTAPI = TESTAPI;
15
- exports.APIENTRY = APIENTRY;
16
- exports.VSTR = VSTR;
17
- exports.IS_DEMO = IS_DEMO;
18
-
19
- /************************************************************************************
20
- * Helper functions
21
- ************************************************************************************/
22
-
23
- // have issues:
24
- const base64ToBufferVintage = data => atob(data.toString());
25
- //const bufferToBase64 = data => Buffer.from(data).toString('base64');
26
-
27
- const unpack = (arr) => Uint8Array.from( arr.map( c => c.charCodeAt(0) ));
28
-
29
- let readSigKey = name => { console.log("Error: not supported") }
30
-
31
- const base64ToBuffer = enc => {
32
- const len = Protobuf.util.base64.length(enc);
33
- let buf = new Protobuf.util.Array( len );
34
- Protobuf.util.base64.decode(enc, buf, 0);
35
- return buf;
36
- }
37
-
38
- const bufferToBase64 = buf => {
39
- return Protobuf.util.base64.encode(buf, 0, buf.length);
40
- }
41
-
42
- exports.base64ToBuffer = base64ToBuffer;
43
- exports.bufferToBase64 = bufferToBase64;
44
- exports.unpack = unpack;
45
-
46
-
47
- /************************************************************************************
48
- * Functions for node.js only
49
- ************************************************************************************/
50
-
51
- try {
52
- const FS = require( 'fs' );
53
-
54
- readSigKey = name => {
55
- if (!FS.existsSync( name )) {
56
- throw 'Key file not found!';
57
- }
58
- return FS.readFileSync( name ).slice(0,44);
59
- }
60
-
61
- exports.generateApiKeys = async () => {
62
- const privateKey = ED.utils.randomPrivateKey();
63
- const publicKey = await ED.getPublicKey(privateKey);
64
- return {
65
- privateKey: privateKey,
66
- publicKey: publicKey
67
- }
68
- }
69
-
70
- exports.writeApiKeys = async (name = 'rxome', dir = '.') => {
71
- const key = await this.generateApiKeys();
72
- await Promise.all([
73
- FS.writeFile( `${dir}/${name}.private.apikey`, bufferToBase64( key.privateKey ), { mode: 0o600 }, err => { if (err) throw err; } ),
74
- FS.writeFile( `${dir}/${name}.public.apikey`, bufferToBase64( key.publicKey ), { mode: 0o600 }, err => { if (err) throw err; } )
75
- ]);
76
- }
77
-
78
- }
79
- catch (e) {
80
- if (e instanceof Error && e.code !== "MODULE_NOT_FOUND") {
81
- throw e;
82
- }
83
- }
84
-
85
- exports.readSigKey = readSigKey;
86
-
87
- /************************************************************************************/
88
-
89
- exports.signData = async( keyId, user, keyB64, created, debug = false ) => {
90
- const message = `x-date: ${created}\nx-rxome-user: ${user}`
91
- const messageUi8 = unpack( Array.from(message) );
92
-
93
- const key = unpack( [...base64ToBufferVintage(keyB64)] );
94
- debug && console.log('Base 64 key: ', keyB64);
95
- debug && console.log('Binary key: ', key, " Key length: ", key.length);
96
-
97
- const signature = await ED.sign( messageUi8, key);
98
- const sigB64 = bufferToBase64( signature );
99
- const auth=`Signature keyId=\"${keyId}\",algorithm=\"ed25519\",headers=\"x-date x-rxome-user\",signature=\"${sigB64}\",created=\"${created}\"`
100
- debug && console.log('Auth string: ', auth);
101
-
102
- return auth;
103
- }
104
-
105
-
106
- exports.fetchData = async ( url, credentials, pseudonym = '', debug = false ) => {
107
- debug && console.log( 'Fetching from', url )
108
-
109
- const created = Date.now();
110
- const keyId = credentials.keyId || "rxome";
111
- const user = credentials.user || `${keyId}@rxome.net`;
112
- const keyB64 = credentials.key || readSigKey( process.cwd()+'/'+credentials.keyFile );
113
-
114
- const auth = await exports.signData( keyId, user, keyB64, created, debug );
115
-
116
- FS = require( 'fs' );
117
- return Axios({
118
- url: url,
119
- method: 'GET',
120
- params: {
121
- pslab: !!pseudonym.trim(),
122
- demo: pseudonym === IS_DEMO
123
- },
124
- headers: {
125
- Authorization: auth,
126
- 'x-date': created,
127
- 'x-rxome-user': user
128
- },
129
- timeout: 5000
130
- })
131
- .then(res => {
132
- debug && console.log( "Result Data= ", res.data )
133
- return res.data
134
- })
135
- }
package/qrcode.png DELETED
Binary file