rxome-generator 1.0.2 → 1.0.3
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 +519 -230
- package/demos/demo_data_full.json +1 -1
- package/demos/demo_data_full_compressed.json +1 -1
- package/demos/demo_data_without_key.json +1 -2
- package/demos/qrcode.json +1 -0
- package/lib/rxome-api-demo.cjs +4 -2
- package/lib/rxome-api.cjs +57 -0
- package/lib/rxome-generator.cjs +2 -2
- package/package.json +12 -11
- package/rxcode.js +53 -2
- package/README.TODO +0 -4
- package/qrcode.png +0 -0
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# TODO:
|
|
2
|
+
* how to connect to docker container (shell)
|
|
3
|
+
|
|
4
|
+
# FindMe2care (RxOME) QR-code generator
|
|
5
|
+
Generates QR codes containing medical information for use with the FindMe2care platform
|
|
3
6
|
(formerly called RxOME).
|
|
4
|
-
**Right now, it works only with the test API (-t, Coder.TESTAPI)**
|
|
5
7
|
|
|
6
8
|
## LICENSE
|
|
7
9
|
|
|
@@ -10,9 +12,13 @@ Copyright (c) 2023 RxOME GmbH
|
|
|
10
12
|
All rights reserved, unauthorized use prohibited.
|
|
11
13
|
|
|
12
14
|
## Purpose
|
|
15
|
+
The *rxome* packages generate QR codes from medical data for use with the FindMe2care platform.
|
|
16
|
+
|
|
17
|
+
The package *rxome-generator* offers a JavaScript library as well as
|
|
18
|
+
a command line tool as front end to this library. Additonally, the packages *rxome-server* and *rxome-server-win*
|
|
19
|
+
provide a web service based on the rxome library.
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
a command line tool as front end to this library. Both expect the medical data in JSON format
|
|
21
|
+
The packages expect the medical data in JSON format
|
|
16
22
|
according to a subset of the PhenoPacket standard (with some additions), see below.
|
|
17
23
|
The medical data will be encrypted before generating the QR code. This encrypted data can be decrypted
|
|
18
24
|
by the database backend only. The meta data is transmitted unencrypted.
|
|
@@ -24,7 +30,7 @@ a public key is uploaded to the server and used to verify the signature,
|
|
|
24
30
|
see generating user credentials.
|
|
25
31
|
|
|
26
32
|
When generating a QR code and, thus, downloading a pseudonym, the user needs to specify the
|
|
27
|
-
corresponding credentials (keyID and key) for accessing the
|
|
33
|
+
corresponding credentials (keyID and key) for accessing the FindMe2care server.
|
|
28
34
|
The command line tool offers command line options for the API access credentials. Further, they
|
|
29
35
|
can be specified in the input JSON file (see 'MetaData and credentials' below),
|
|
30
36
|
where the command line options precede the data in the JSON file.
|
|
@@ -33,19 +39,20 @@ In case the patient already has a pseudonym that will be used for the QR code,
|
|
|
33
39
|
the known pseudonym can be specified in the MetaData section of the input JSON data.
|
|
34
40
|
Additionally, the command line tool
|
|
35
41
|
offers a command line argument, `-p`, for specifying a known pseudonym.
|
|
36
|
-
Note that this pseudonym must be a valid
|
|
37
|
-
|
|
38
|
-
generated QR-Code useless, as it cannot be processed by
|
|
42
|
+
Note that this pseudonym must be a valid FindMe2care pseudonym, that is, it has to be generated by
|
|
43
|
+
FindMe2care for a previous medical statement. Using an arbitrary pseudonym will render the
|
|
44
|
+
generated QR-Code useless, as it cannot be processed by FindMe2care.
|
|
39
45
|
|
|
40
46
|
By default, the keywords in the JSON file are expected to be noted in camelCase. However, the tool
|
|
41
|
-
can convert snake_case to camelCase (command line: -s, library
|
|
47
|
+
can convert snake_case to camelCase (command line: -s, library function: convertToCamelCase).
|
|
42
48
|
|
|
43
|
-
##
|
|
49
|
+
## 1. Library and Command-Line Tool
|
|
50
|
+
### 1.1 Installation
|
|
44
51
|
> `npm install rxome-generator`
|
|
45
52
|
|
|
46
|
-
|
|
53
|
+
### 1.2 Basic Usage
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
#### Command Line Tool
|
|
49
56
|
|
|
50
57
|
Generate a QR code *inputfile*.png from a JSON file *inputfile*.json containing all medical data in PhenoPacket format, meta data and credentials (using camelCase for keywords):
|
|
51
58
|
|
|
@@ -54,7 +61,7 @@ Generate a QR code *inputfile*.png from a JSON file *inputfile*.json containing
|
|
|
54
61
|
For detailed descriptions see
|
|
55
62
|
> `rxcode g --help`
|
|
56
63
|
|
|
57
|
-
|
|
64
|
+
#### Library Functions
|
|
58
65
|
Import the library with
|
|
59
66
|
> `const Coder = require( 'rxome-generator' );`
|
|
60
67
|
|
|
@@ -95,8 +102,329 @@ Additionally, the data can be verified with
|
|
|
95
102
|
|
|
96
103
|
Note that the credential information perhaps stored in the data package is *not* part of the PhenoPacket standard.
|
|
97
104
|
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
### 1.3 Command-Line Tool
|
|
106
|
+
|
|
107
|
+
#### Overview
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
FindMe2care QR Code generation tool
|
|
111
|
+
|
|
112
|
+
Usage: rxcode [options] [command]
|
|
113
|
+
|
|
114
|
+
Basic usage: rxcode g <input json file>: generates QR Code with the basefilename of the inputfile.
|
|
115
|
+
Before first use, please generate an API access key (rxcode -k) and deposit the public key on the
|
|
116
|
+
FindMe2care server.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
Options:
|
|
120
|
+
-V, --version output the version number
|
|
121
|
+
-h, --help display help for command
|
|
122
|
+
|
|
123
|
+
Commands:
|
|
124
|
+
generate|g [options] [input file] generate QR Code from PhenoPacket JSON
|
|
125
|
+
upload|U [input file] [key ID] [key] For debug purposes: Upload and decode QR Code PNG to server (only
|
|
126
|
+
for test server)
|
|
127
|
+
convert|c [options] [input file] convert case style of keys in JSON files from snake_case to
|
|
128
|
+
camelCase (and vice versa)
|
|
129
|
+
preprocess|p [options] [input file] perform preprocessing steps
|
|
130
|
+
verify|v [input file] verify input file against phenopacket schema
|
|
131
|
+
apikeys|k [options] [file prefix] generate key pair for API access
|
|
132
|
+
ping|P [options] <id> <key> Ping API/check API credentials
|
|
133
|
+
encrypt|e [options] [input file] encrypt message (just for testing)
|
|
134
|
+
decrypt|d [options] [input file] decrypt coded message or medical data
|
|
135
|
+
data-keys|K [options] [file prefix] generate data encryption key pair (see -e, -d; just for testing)
|
|
136
|
+
pheno2proto|E [options] [input file] encode PhenoPacket to protobuf (just for testing)
|
|
137
|
+
proto2pheno|D [options] [input file] decode protobuf to PhenoPacket (just for testing)
|
|
138
|
+
settings|S [options] Print current settings
|
|
139
|
+
statistics|s [input file] print memory consuption for several stages and alternatives
|
|
140
|
+
help [command] display help for command
|
|
141
|
+
|
|
142
|
+
Author: Tom Kamphans, GeneTalk GmbH, 2022, (c) 2023 RxOME GmbH
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Generating QR codes
|
|
146
|
+
|
|
147
|
+
Use the 'g' command for actually generating a QR code:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
FindMe2care QR Code generation tool
|
|
151
|
+
|
|
152
|
+
Usage: rxcode generate|g [options] [input file]
|
|
153
|
+
|
|
154
|
+
Generate QR Code from PhenoPacket JSON. The credential information keyId and either key or keyFile
|
|
155
|
+
are mandatory and can be specified either in the input JSON file or by command line arguments.
|
|
156
|
+
The command line arguments precede the data from the JSON input file.
|
|
157
|
+
Output: prints the given or new pseudonym.
|
|
158
|
+
|
|
159
|
+
Arguments:
|
|
160
|
+
input file Input JSON file (default: STDIN)
|
|
161
|
+
|
|
162
|
+
Options:
|
|
163
|
+
-o, --output <filename> Filename for the QR code (default: <inputfile>.png)
|
|
164
|
+
-p, --pseudonym <pseudonym> For re-evaluations: pseudonym for patient. Otherwise a new is generated
|
|
165
|
+
(default: "")
|
|
166
|
+
-i, --keyId <id> API access ID (default: input file, credentials.keyId or metaData.createdBy)
|
|
167
|
+
-k, --keyFile <filename> Filename with API access key (default: use -s)
|
|
168
|
+
-s, --key <key string> API access key (default: input file, credentials.key)
|
|
169
|
+
-u, --user <user string> API access user (default: credentials.user or metaData.submittedBy or
|
|
170
|
+
info@rxome.net)
|
|
171
|
+
-c, --created <date> Date (default: input file, metaData.created)
|
|
172
|
+
-l, --lab <lab> Laboratory name (default: input file, metaData.createdBy or lab name stored
|
|
173
|
+
in the user account)
|
|
174
|
+
-e, --email <email> Laboratory email (default: input file, metaData.submittedBy)
|
|
175
|
+
-S, --snake Read payload formatted in snake_case (default: camelCase)
|
|
176
|
+
-t, --test Use test API instead of production API
|
|
177
|
+
-L, --localhost Connect to localhost API
|
|
178
|
+
-D, --debug Some output for debugging
|
|
179
|
+
-h, --help display help for command
|
|
180
|
+
|
|
181
|
+
Author: Tom Kamphans, GeneTalk GmbH, 2022, (c) 2023 RxOME GmbH
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Writes the pseudonym used to generate the QR code to STDOUT. With -D given, this further writes the
|
|
185
|
+
(unencrypted) content of the QR code to STDOUT.
|
|
186
|
+
|
|
187
|
+
#### Generating API Access Keys
|
|
188
|
+
To communicate with the server API you need access credentials, that is, an id for your lab (the keyId) and a pair of corresponding keys. First, generate a pair of keys with
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
rxcode k myLabId
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
This yields two files: `myLabId.private.apikey` and `myLabId.public.apikey`. Store the
|
|
195
|
+
private key safely.
|
|
196
|
+
Create a lab account on `app.findme2care.de/generate` and upload the public key to your profile.
|
|
197
|
+
Afterwards, you should be able to access the API (see 'debugging' below).
|
|
198
|
+
|
|
199
|
+
#### Demo
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
rxcode g -t -o qrcode.png demos/demo_data_full.json
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
<img src="qrcode.png" width="400">
|
|
206
|
+
|
|
207
|
+
#### Testing your installation
|
|
208
|
+
To check the connection to the API on RxOME server API use
|
|
209
|
+
|
|
210
|
+
> `rxcode P -d ` *your_id* *your_key*
|
|
211
|
+
|
|
212
|
+
If you want to make sure that all data from your input is transmitted correctly, you can
|
|
213
|
+
use the `pheno2proto` and the corresponding `proto2pheno` commands to encode and decode your
|
|
214
|
+
file. Compare the output of `proto2pheno` with your original file:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
rxcode E -b my_file.json > my_file.pbuf
|
|
218
|
+
rxcode D -bp my_file.pbuf > my_new_file.json
|
|
219
|
+
diff my_new_file.json my_file.json
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Further, you can check a QR Code that was generated on the test server (using the `-t` option in `rxcode g `) by uploading and decoding it to the test server with the `upload` command:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
rxcode U my_qr_code.png my_key_id my_private_key
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 2. QR-code generator service
|
|
229
|
+
The packages *rxome-server* generates QR codes containing medical information for use with the FindMe2Care database
|
|
230
|
+
(formerly called RxOME). The command line tool `rxsrv` starts the QR generator as local service listening on localhost:*port* (default: port 1607).
|
|
231
|
+
A client can send POST requests to this port and retrieves the generated QR code by HTTP protocol.
|
|
232
|
+
|
|
233
|
+
A second package, *rxome-server-win*, build up on rxome-server installs the server as windows service.
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
### 2.1 Prerequisites
|
|
237
|
+
Running the QR-Code server requires either `node.js` or `docker`.
|
|
238
|
+
|
|
239
|
+
### 2.2 Using Node.js
|
|
240
|
+
|
|
241
|
+
#### Installation
|
|
242
|
+
Either install the QR-Code Server or the Windows service installer using
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
npm install -q rxome-server
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
or
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
npm install -q rxome-server-win
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
#### Starting the QR-Code Server
|
|
256
|
+
|
|
257
|
+
For detailed descriptions see
|
|
258
|
+
```
|
|
259
|
+
rxsrv --help
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Generating API access keys
|
|
263
|
+
You can generate new API access keys using the command line:
|
|
264
|
+
```
|
|
265
|
+
rxsrv --newkey
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
or in the Windows version:
|
|
269
|
+
```
|
|
270
|
+
rxsrv_win.cmd command
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
or start the server with dummy FindMe2Care credentials and access the '/key' entrypoint of the server.
|
|
274
|
+
|
|
275
|
+
#### Configuring using Environment Variables
|
|
276
|
+
|
|
277
|
+
The following command starts the server and reads the configuration from environment variables.
|
|
278
|
+
Note that the env variables can be set in the
|
|
279
|
+
environment's config file, e.g. when using Docker or NGINX. Setting the port is optional.
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
export RXID=rxome
|
|
283
|
+
export RXKEY=private_key_for_rxome
|
|
284
|
+
export RXPORT=4242
|
|
285
|
+
|
|
286
|
+
rxsrv -e
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Where `RXID` is the username of the laboratory on the FindMe2Care platform, `RXKEY` is the
|
|
290
|
+
private API access key matching the public key stored on the lab's profile on the
|
|
291
|
+
FindMe2Care platform. See the README of the rxome-qrcode-generator for generating the
|
|
292
|
+
API keys.
|
|
293
|
+
|
|
294
|
+
Note that storing secret information in environment variables may pose a security risk; therefore, this option is not recommended and should only be used if the software runs in an isolated environment.
|
|
295
|
+
|
|
296
|
+
#### Configuring using Config File
|
|
297
|
+
|
|
298
|
+
Example config file (setting the port is optional.)
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
cat demo.cfg
|
|
302
|
+
{
|
|
303
|
+
"id": "rxome",
|
|
304
|
+
"key": "private_key_for_rxome",
|
|
305
|
+
"port": "4242"
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Start the server and read settings from config file:
|
|
310
|
+
|
|
311
|
+
```
|
|
312
|
+
rxsrv -c demo.cfg
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
#### Registering and Unregistering the Windows Service
|
|
317
|
+
The npm package `rxome-server-win` provides a Windows executable that you can start with:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
rxsrv_win.cmd command
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
where command is one of
|
|
324
|
+
|
|
325
|
+
- install
|
|
326
|
+
- uninstall
|
|
327
|
+
- ping
|
|
328
|
+
- newkey
|
|
329
|
+
- help
|
|
330
|
+
|
|
331
|
+
Note that the Windows service is configured with a config file given by `%RXCFG%` or, if none specified,
|
|
332
|
+
the default file `%APPDATA\npm\node_modules\rxome-server-win\demo.cfg` is used.
|
|
333
|
+
|
|
334
|
+
### 2.3 Using Docker
|
|
335
|
+
Instead of installing node.js and starting the server manually, you can use a docker image to run the server, e.g. by
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
docker run -d -p 1607:1607 -e RXID="rxome" -e RXKEY="...private_key..." tomkamphans/rxsrv
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Where `RXID` is the lab's user name and `RXKEY` the private API key as described above.
|
|
342
|
+
|
|
343
|
+
Note that the first port number in `-p 1607:1607` denotes the port on *localhost* to which the docker internal port (denoted the second port number, in this case 1607 also) is mapped. So if you need to run the service on another port, say 8081, use
|
|
344
|
+
`docker run -p 8081:1607 ...`.
|
|
345
|
+
|
|
346
|
+
Hint for Docker on Windows: set the start type of *Docker Desktop Service* to *automatic* using the Windows Services App (services.msc).
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
### 2.4 API Endpoints
|
|
350
|
+
|
|
351
|
+
The server provides the following endpoints, see descriptions below:
|
|
352
|
+
|
|
353
|
+
* `GET /`
|
|
354
|
+
* `GET /demo`
|
|
355
|
+
* `POST /`
|
|
356
|
+
* `POST /img`
|
|
357
|
+
* `GET /key`
|
|
358
|
+
|
|
359
|
+
#### Testing connection
|
|
360
|
+
|
|
361
|
+
Querying the url `localhost:<port>/` should yield a line such as
|
|
362
|
+
|
|
363
|
+
```This is the RxOME QRcode generator API Version 0.0.1 for lab id rxome running on port 1607 with PID 26584```
|
|
364
|
+
|
|
365
|
+
#### Getting Demo Data
|
|
366
|
+
For convenient testing, the server provides a demo JSON file by sending a GET request to `/data`.
|
|
367
|
+
|
|
368
|
+
#### Getting a QR-Code in PNG
|
|
369
|
+
Send a JSON file with the data for the RxOME code generator by POST request to `/img`, e.g.
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
curl -X POST -H "Content-Type: application/json" -d @demo_data_full.json --output qrcode.png localhost:1607/img
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
#### Getting QR-Code and Pseudonym in JSON Format
|
|
376
|
+
In addition to the QR-Code itself, the code generator yields the pseudonym given to this patient
|
|
377
|
+
and the full unencrypted content of the QR code. The laboratory may
|
|
378
|
+
use this pseudonym if the patient is re-evaluated and gets a new QR-Code. Thus, the former medical data can be
|
|
379
|
+
overwritten in the FindMe2Care Database. To get the QR-code and the pseudonyme in JSON format, send the input JSON file to `/`:
|
|
380
|
+
|
|
381
|
+
```
|
|
382
|
+
curl -X POST -H "Content-Type: application/json" -d @demo_data_full.json --output qrcode.json localhost:1607/
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
This yields a JSON response containing
|
|
386
|
+
|
|
387
|
+
```
|
|
388
|
+
{
|
|
389
|
+
qr_code: (QR code),
|
|
390
|
+
pseudonym: (pseudonym used to generate the QR code),
|
|
391
|
+
qr_content: content of the QR code but with unencrypted medical data for documentation purposes
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### 2.5 Server Command-Line Tool
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
RxOME QR Code generation server
|
|
399
|
+
|
|
400
|
+
Usage: rxsrv usage: rxsrv -i <id> (-e | -c <cfg_file> | -k <key_file> | -s <key>) [-p <port>]
|
|
401
|
+
|
|
402
|
+
Start the QR-code tool as service listening on localhost:<port>.
|
|
403
|
+
Before first use, please generate an API access key with rxcode and deposit the public key on the
|
|
404
|
+
RxOME server.
|
|
405
|
+
|
|
406
|
+
The command-line parameters -k, -s, -p precede the environment variables (if -e specified), which, in
|
|
407
|
+
turn, precede the config file (if -c is also specified). A key string (-s) has precedence over a key
|
|
408
|
+
from a key file (-k).
|
|
409
|
+
|
|
410
|
+
Options:
|
|
411
|
+
-c, --config <filename> JSON file with config, entries id, key, [port]; -c-- to read from stdin
|
|
412
|
+
-e, --environment use environment variables RXID, RXKEY, RXPORT to configure rxsrv (useful
|
|
413
|
+
for working with docker)
|
|
414
|
+
-i, --keyId <id> API access ID
|
|
415
|
+
-k, --keyFile <filename> Filename with API access key (default: use -s)
|
|
416
|
+
-s, --key <key string> API access key
|
|
417
|
+
-p, --port <port> Set port for server, default: 1607
|
|
418
|
+
-V, --version output the version number
|
|
419
|
+
-h, --help display help
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
## 3. Data Format
|
|
426
|
+
### 3.1 Modifications to the PhenoPacket Standard
|
|
427
|
+
#### Meta Data and Credentials
|
|
100
428
|
For convenience, all data needed to generate a QR code can be specified in one JSON file
|
|
101
429
|
(or, when using the library functions, one JavaScript object).
|
|
102
430
|
In addition to the medical data, the JSON files or objects accepted by rxcode and the
|
|
@@ -132,7 +460,7 @@ pseudonym used will be part of the output for futher processing or storing.
|
|
|
132
460
|
}
|
|
133
461
|
```
|
|
134
462
|
|
|
135
|
-
|
|
463
|
+
#### Phenotypic Features
|
|
136
464
|
|
|
137
465
|
The rxome library extends the PhenoPacket schema for storing phenotypicFeatures (HPO terms). In addition the notation suggested by PhenoPackets:
|
|
138
466
|
|
|
@@ -176,10 +504,46 @@ the terms can be stored in a shorter and more convenient form:
|
|
|
176
504
|
]
|
|
177
505
|
}
|
|
178
506
|
```
|
|
507
|
+
|
|
508
|
+
#### Additional Data
|
|
509
|
+
|
|
510
|
+
The RxOME data format allows to store informations that are not provided by the phenopacket format by using
|
|
511
|
+
the phenopacket extension fields in the form
|
|
512
|
+
|
|
513
|
+
```
|
|
514
|
+
"extensions": [
|
|
515
|
+
{
|
|
516
|
+
"name": "...",
|
|
517
|
+
"value": "..."
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"name": "...",
|
|
521
|
+
"value": "..."
|
|
522
|
+
}
|
|
523
|
+
]
|
|
524
|
+
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
* The type of genetic test performed to obtain a variant (extension field name *test-type*)
|
|
528
|
+
* CNV information (field name *cnv*). Possible values:
|
|
529
|
+
* 0 = Not provided (default)
|
|
530
|
+
* 1 = Deletion
|
|
531
|
+
* 2 = Duplication
|
|
532
|
+
|
|
533
|
+
* Methylation (field name *meth*). Possible values:
|
|
534
|
+
* 0 = Not provided
|
|
535
|
+
* 1 = Hypermethylation
|
|
536
|
+
* 2 = Hypomethylation
|
|
537
|
+
* 3 = Intermediate
|
|
538
|
+
|
|
539
|
+
* Allele Frequency (field name *af*)
|
|
540
|
+
* Repeat length (field name *rl*)
|
|
541
|
+
* Chromosomal Region (field name *chr*)
|
|
542
|
+
* Methylation site (field name *site*)
|
|
179
543
|
|
|
180
|
-
|
|
544
|
+
###### Example: test type
|
|
181
545
|
|
|
182
|
-
The type of genetic test performed to obtain a variant can be specified in an extension field to the genomic interpretation:
|
|
546
|
+
The type of genetic test performed to obtain a variant can be specified in an extension field to the genomic interpretation in the *variationDescriptor* section:
|
|
183
547
|
|
|
184
548
|
```
|
|
185
549
|
"genomicInterpretations": [
|
|
@@ -200,7 +564,8 @@ The type of genetic test performed to obtain a variant can be specified in an ex
|
|
|
200
564
|
},
|
|
201
565
|
"extensions": [
|
|
202
566
|
{
|
|
203
|
-
"name": "
|
|
567
|
+
"name": "test-type",
|
|
568
|
+
"value": "Single gene sequencing"
|
|
204
569
|
}
|
|
205
570
|
]
|
|
206
571
|
}
|
|
@@ -211,7 +576,7 @@ The type of genetic test performed to obtain a variant can be specified in an ex
|
|
|
211
576
|
]
|
|
212
577
|
```
|
|
213
578
|
|
|
214
|
-
|
|
579
|
+
#### Additional Remarks
|
|
215
580
|
|
|
216
581
|
Additional remarks can be specified in a *comment* field on the top level:
|
|
217
582
|
|
|
@@ -223,7 +588,7 @@ Additional remarks can be specified in a *comment* field on the top level:
|
|
|
223
588
|
...
|
|
224
589
|
```
|
|
225
590
|
|
|
226
|
-
|
|
591
|
+
#### Whitelist Filter
|
|
227
592
|
|
|
228
593
|
Before packing the data, needless sections (that is, sections that are not evaluted by RxOME)
|
|
229
594
|
are removed. On top level, the following section will be passed over to the QR code:
|
|
@@ -237,253 +602,177 @@ are removed. On top level, the following section will be passed over to the QR c
|
|
|
237
602
|
* metaData
|
|
238
603
|
* credentials (not passed to QR code, but also not removed by whitelist filtering)
|
|
239
604
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
data-keys|K [options] [file prefix] generate key pair for data encryption (see -e, -d; just for testing)
|
|
268
|
-
pheno2proto|E [options] [input file] encode PhenoPacket to protobuf (just for testing)
|
|
269
|
-
proto2pheno|D [options] [input file] decode protobuf to PhenoPacket (just for testing)
|
|
270
|
-
settings|S [options] Print current settings
|
|
271
|
-
statistics|s [input file] print memory consuption for several stages and alternatives
|
|
272
|
-
help [command] display help for command
|
|
273
|
-
|
|
274
|
-
Author: Tom Kamphans, GeneTalk GmbH, 2022, (c) 2023 RxOME GmbH
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Generating QR codes
|
|
278
|
-
|
|
279
|
-
Use the 'g' command for actually generating a QR code:
|
|
280
|
-
|
|
281
|
-
```
|
|
282
|
-
FindMe2care QR Code generation tool
|
|
283
|
-
|
|
284
|
-
Usage: rxcode generate|g [options] [input file]
|
|
285
|
-
|
|
286
|
-
Generate QR Code from PhenoPacket JSON. The credential information keyId and either key or keyFile
|
|
287
|
-
are mandatory and can be specified either in the input JSON file or by command line arguments.
|
|
288
|
-
The command line arguments precede the data from the JSON input file.
|
|
289
|
-
Output: prints the given or new pseudonym.
|
|
290
|
-
|
|
291
|
-
Arguments:
|
|
292
|
-
input file Input JSON file (default: STDIN)
|
|
293
|
-
|
|
294
|
-
Options:
|
|
295
|
-
-o, --output <filename> Filename for the QR code (default: <inputfile>.png)
|
|
296
|
-
-p, --pseudonym <pseudonym> For re-evaluations: pseudonym for patient. Otherwise a new is generated
|
|
297
|
-
(default: "")
|
|
298
|
-
-i, --keyId <id> API access ID (default: input file, credentials.keyId or metaData.createdBy)
|
|
299
|
-
-k, --keyFile <filename> Filename with API access key (default: use -s)
|
|
300
|
-
-s, --key <key string> API access key (default: input file, credentials.key)
|
|
301
|
-
-u, --user <user string> API access user (default: credentials.user or metaData.submittedBy or
|
|
302
|
-
info@rxome.net)
|
|
303
|
-
-c, --created <date> Date (default: input file, metaData.created)
|
|
304
|
-
-l, --lab <lab> Laboratory name (default: input file, metaData.createdBy or lab name stored in
|
|
305
|
-
the user account)
|
|
306
|
-
-e, --email <email> Laboratory email (default: input file, metaData.submittedBy)
|
|
307
|
-
-S, --snake Read payload formatted in snake_case (default: camelCase)
|
|
308
|
-
-t, --test Use test API instead of production API
|
|
309
|
-
-L, --localhost Connect to localhost API
|
|
310
|
-
-D, --debug Some output for debugging
|
|
311
|
-
-h, --help display help for command
|
|
312
|
-
|
|
313
|
-
Author: Tom Kamphans, GeneTalk GmbH, 2022, (c) 2023 RxOME GmbH
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
Writes the pseudonym used to generate the QR code to STDOUT. With -D given, this further writes the
|
|
317
|
-
(unencrypted) content of the QR code to STDOUT.
|
|
318
|
-
|
|
319
|
-
### Generating API Access Keys
|
|
320
|
-
To communicate with the server API you need access credentials, that is, an id for your lab (the keyId) and a pair of corresponding keys. First, generate a pair of keys with
|
|
321
|
-
|
|
322
|
-
```
|
|
323
|
-
rxcode k myLabId
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
This yields two files: `myLabId.private.apikey` and `myLabId.public.apikey`. Store the
|
|
327
|
-
private key safely.
|
|
328
|
-
Create a lab account on `app.findme2care.de/generate` and upload the public key to your profile.
|
|
329
|
-
Afterwards, you should be able to access the API (see 'debugging' below).
|
|
330
|
-
|
|
331
|
-
## Demo
|
|
332
|
-
|
|
333
|
-
```
|
|
334
|
-
rxcode g -t -o qrcode.png demos/demo_data_full.json
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
<img src="qrcode.png" width="400">
|
|
338
|
-
|
|
339
|
-
## Debugging
|
|
340
|
-
To check the connection to the API on RxOME server API use
|
|
341
|
-
|
|
342
|
-
> `rxcode P -d ` *your_id* *your_key*
|
|
343
|
-
|
|
344
|
-
If you want to make sure that all data from your input is transmitted correctly, you can
|
|
345
|
-
use the `pheno2proto` and the corresponding `proto2pheno` commands to encode and decode your
|
|
346
|
-
file. Compare the output of `proto2pheno` with your original file:
|
|
347
|
-
|
|
348
|
-
```
|
|
349
|
-
rxcode E -b my_file.json > my_file.pbuf
|
|
350
|
-
rxcode D -bp my_file.pbuf > my_new_file.json
|
|
351
|
-
diff my_new_file.json my_file.json
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## Payload Example File
|
|
605
|
+
### 3.2 Special phenopacket entries
|
|
606
|
+
In this section, we give some additional explanations to some of the fields in the phenopacket schema.
|
|
607
|
+
|
|
608
|
+
#### Diagnosis/Disease
|
|
609
|
+
The diagnosis can be specified in the *disease* field.
|
|
610
|
+
IMPORTANT: Note that the
|
|
611
|
+
|
|
612
|
+
#### Zygosity
|
|
613
|
+
The zygosity is specified in the field *allelicState* in the *variationDescriptor* section. According to the
|
|
614
|
+
phenopacket standard, possible values are
|
|
615
|
+
|
|
616
|
+
* GENO\_0000137 for 'unspecified\_zygosity'
|
|
617
|
+
* GENO\_0000136 for 'homozygous'
|
|
618
|
+
* GENO\_0000135 for 'heterozygous'
|
|
619
|
+
* GENO\_0000402 for 'compound_heterozygous'
|
|
620
|
+
* GENO\_0000134 for 'hemizygous'
|
|
621
|
+
* GENO\_0000604 for 'hemizygous\_X\_linked'
|
|
622
|
+
* GENO\_0000605 for 'hemizygous\_Y\_linked'
|
|
623
|
+
* GENO\_0000606 for 'hemizygous\_insertion\_linked'
|
|
624
|
+
* GENO\_0000392 for 'aneusomic\_zygosity'
|
|
625
|
+
* GENO\_0000393 for 'trisomic\_homozygous'
|
|
626
|
+
* GENO\_0000394 for 'trisomic\_heterozygous'
|
|
627
|
+
* GENO\_0000602 for 'homoplasmic'
|
|
628
|
+
* GENO\_0000603 for 'heteroplasmic'
|
|
629
|
+
* GENO\_0000964 for 'mosaic'
|
|
630
|
+
|
|
631
|
+
### 3.3 Payload Example File
|
|
355
632
|
|
|
356
633
|
```
|
|
357
634
|
{
|
|
358
|
-
"id": "
|
|
359
|
-
"comment": "useful remarks",
|
|
635
|
+
"id": "232DTCEZZCQX",
|
|
360
636
|
"subject": {
|
|
361
|
-
"
|
|
362
|
-
"
|
|
363
|
-
|
|
637
|
+
"dateOfBirth": "2021-07-16",
|
|
638
|
+
"sex": 1
|
|
639
|
+
},
|
|
640
|
+
"comment": "Demo record",
|
|
641
|
+
"compressedFeatures": {
|
|
642
|
+
"includes": [
|
|
643
|
+
"HP:0003155",
|
|
644
|
+
"HP:0001250",
|
|
645
|
+
"HP:0001249"
|
|
646
|
+
],
|
|
647
|
+
"excludes": [
|
|
648
|
+
"HP:0031360"
|
|
649
|
+
]
|
|
364
650
|
},
|
|
365
|
-
"phenotypicFeatures": [
|
|
366
|
-
{
|
|
367
|
-
"type": {
|
|
368
|
-
"id": "HP:0030084"
|
|
369
|
-
}
|
|
370
|
-
},
|
|
371
|
-
{
|
|
372
|
-
"type": {
|
|
373
|
-
"id": "HP:0000555"
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
"type": {
|
|
378
|
-
"id": "HP:0000486"
|
|
379
|
-
}
|
|
380
|
-
},
|
|
381
|
-
{
|
|
382
|
-
"type": {
|
|
383
|
-
"id": "HP:0000541"
|
|
384
|
-
}
|
|
385
|
-
},
|
|
386
|
-
{
|
|
387
|
-
"type": {
|
|
388
|
-
"id": "HP:0084369"
|
|
389
|
-
}
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
"type": {
|
|
393
|
-
"id": "HP:0112358"
|
|
394
|
-
}
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
"type": {
|
|
398
|
-
"id": "HP:0000145"
|
|
399
|
-
}
|
|
400
|
-
},
|
|
401
|
-
{
|
|
402
|
-
"type": {
|
|
403
|
-
"id": "HP:1234567"
|
|
404
|
-
}
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
"type": {
|
|
408
|
-
"id": "HP:9876543"
|
|
409
|
-
}
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
"type": {
|
|
413
|
-
"id": "HP:5678912"
|
|
414
|
-
}
|
|
415
|
-
},
|
|
416
|
-
{
|
|
417
|
-
"type": {
|
|
418
|
-
"id": "HP:0031360"
|
|
419
|
-
},
|
|
420
|
-
"excluded": true
|
|
421
|
-
},
|
|
422
|
-
{
|
|
423
|
-
"type": {
|
|
424
|
-
"id": "HP:0001234",
|
|
425
|
-
},
|
|
426
|
-
"excluded": true
|
|
427
|
-
}
|
|
428
|
-
],
|
|
429
651
|
"interpretations": [
|
|
430
652
|
{
|
|
431
|
-
"id": "
|
|
432
|
-
"progressStatus":
|
|
653
|
+
"id": "first",
|
|
654
|
+
"progressStatus": 3,
|
|
433
655
|
"diagnosis": {
|
|
434
656
|
"disease": {
|
|
435
|
-
"id": "OMIM:
|
|
657
|
+
"id": "OMIM:614207"
|
|
436
658
|
},
|
|
437
659
|
"genomicInterpretations": [
|
|
438
660
|
{
|
|
661
|
+
"subjectOrBiosampleId": "0vlqzsw094u.0",
|
|
662
|
+
"interpretationStatus": "3",
|
|
439
663
|
"variantInterpretation": {
|
|
440
|
-
"acmgPathogenicityClassification": "
|
|
664
|
+
"acmgPathogenicityClassification": "5",
|
|
441
665
|
"variationDescriptor": {
|
|
442
666
|
"geneContext": {
|
|
443
|
-
"valueId": "
|
|
444
|
-
"symbol": "
|
|
667
|
+
"valueId": "26031",
|
|
668
|
+
"symbol": "PIGV",
|
|
669
|
+
"alternateIds": [
|
|
670
|
+
"55650"
|
|
671
|
+
]
|
|
445
672
|
},
|
|
446
673
|
"expressions": [
|
|
447
674
|
{
|
|
448
675
|
"syntax": "hgvs.c",
|
|
449
|
-
"value": "
|
|
676
|
+
"value": "NM_017837.4(PIGV):c.1022C>A (p.Ala341Glu)"
|
|
450
677
|
}
|
|
451
678
|
],
|
|
452
|
-
"allelicState": {
|
|
453
|
-
"id": "GENO:0000135"
|
|
454
|
-
},
|
|
455
679
|
"extensions": [
|
|
456
680
|
{
|
|
457
681
|
"name": "test-type",
|
|
458
|
-
"value": "
|
|
682
|
+
"value": "Single gene sequencing"
|
|
459
683
|
}
|
|
460
|
-
]
|
|
684
|
+
],
|
|
685
|
+
"allelicState": {
|
|
686
|
+
"id": "GENO_0000136"
|
|
687
|
+
}
|
|
461
688
|
}
|
|
462
689
|
}
|
|
463
690
|
},
|
|
464
691
|
{
|
|
692
|
+
"subjectOrBiosampleId": "qpsczs5l7y.907m2ybforb",
|
|
465
693
|
"variantInterpretation": {
|
|
466
|
-
"acmgPathogenicityClassification": "
|
|
694
|
+
"acmgPathogenicityClassification": "1",
|
|
467
695
|
"variationDescriptor": {
|
|
468
696
|
"geneContext": {
|
|
469
|
-
"valueId": "
|
|
470
|
-
"symbol": "
|
|
697
|
+
"valueId": "31369",
|
|
698
|
+
"symbol": "TOMM5",
|
|
699
|
+
"alternateIds": [
|
|
700
|
+
"401505"
|
|
701
|
+
]
|
|
471
702
|
},
|
|
472
703
|
"expressions": [
|
|
473
704
|
{
|
|
474
705
|
"syntax": "hgvs.c",
|
|
475
|
-
"value": "
|
|
706
|
+
"value": "... hgvs code ..."
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
"syntax": "iscn",
|
|
710
|
+
"value": "... iscn data ..."
|
|
711
|
+
}
|
|
712
|
+
],
|
|
713
|
+
"extensions": [
|
|
714
|
+
{
|
|
715
|
+
"name": "test-type",
|
|
716
|
+
"value": "Multigene panel"
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"name": "cnv",
|
|
720
|
+
"value": "1"
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
"name": "meth",
|
|
724
|
+
"value": "1"
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
"name": "af",
|
|
728
|
+
"value": "...allele frequency..."
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
"name": "rl",
|
|
732
|
+
"value": "... repeat length ..."
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
"name": "chr",
|
|
736
|
+
"value": "... chromosomal region ..."
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
"name": "site",
|
|
740
|
+
"value": " ... methylation site ..."
|
|
476
741
|
}
|
|
477
742
|
],
|
|
478
743
|
"allelicState": {
|
|
479
|
-
"
|
|
744
|
+
"id": "GENO_0000136"
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
"subjectOrBiosampleId": "qpsczs5l7y.k0z7yqgy8gi",
|
|
751
|
+
"variantInterpretation": {
|
|
752
|
+
"acmgPathogenicityClassification": "Unknown",
|
|
753
|
+
"variationDescriptor": {
|
|
754
|
+
"geneContext": {
|
|
755
|
+
"valueId": "34528",
|
|
756
|
+
"symbol": "TOMM6",
|
|
757
|
+
"alternateIds": [
|
|
758
|
+
"100188893"
|
|
759
|
+
]
|
|
480
760
|
},
|
|
761
|
+
"expressions": [
|
|
762
|
+
{
|
|
763
|
+
"syntax": "hgvs.c",
|
|
764
|
+
"value": "HGVS2"
|
|
765
|
+
}
|
|
766
|
+
],
|
|
481
767
|
"extensions": [
|
|
482
768
|
{
|
|
483
769
|
"name": "test-type",
|
|
484
|
-
"value": "
|
|
770
|
+
"value": "Multigene panel"
|
|
485
771
|
}
|
|
486
|
-
]
|
|
772
|
+
],
|
|
773
|
+
"allelicState": {
|
|
774
|
+
"id": "None"
|
|
775
|
+
}
|
|
487
776
|
}
|
|
488
777
|
}
|
|
489
778
|
}
|
|
@@ -492,10 +781,10 @@ diff my_new_file.json my_file.json
|
|
|
492
781
|
}
|
|
493
782
|
],
|
|
494
783
|
"metaData": {
|
|
495
|
-
"created": "
|
|
496
|
-
"createdBy": "
|
|
497
|
-
"submittedBy": "
|
|
498
|
-
"
|
|
784
|
+
"created": "2024-08-13",
|
|
785
|
+
"createdBy": "ACME Genetics",
|
|
786
|
+
"submittedBy": "genetics@acme.org",
|
|
787
|
+
"pseudonym": "232DTCEZZCQX"
|
|
499
788
|
}
|
|
500
789
|
}
|
|
501
790
|
```
|
|
@@ -505,4 +794,4 @@ diff my_new_file.json my_file.json
|
|
|
505
794
|
openpgp https://openpgpjs.org/
|
|
506
795
|
node-qrcode https://github.com/soldair/node-qrcode
|
|
507
796
|
noble-ed25519
|
|
508
|
-
-->
|
|
797
|
+
-->
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"status":422,"message":"Request failed with status code 403"}
|
package/lib/rxome-api-demo.cjs
CHANGED
|
@@ -35,8 +35,10 @@ VBvfFVhJAPoDhf5yKxJ+oJV3ls8IyoBBAeMeAYFBrA8r89fKT0nFBA==
|
|
|
35
35
|
`
|
|
36
36
|
|
|
37
37
|
const R_ID = 'rxome';
|
|
38
|
-
const R_PUBLIC_KEY = '
|
|
39
|
-
const R_PRIVATE_KEY = '
|
|
38
|
+
const R_PUBLIC_KEY = '4OShAt7RQ/RJA0qAvoaOQ2jx7SFBYef70XPIz7r9924=';
|
|
39
|
+
const R_PRIVATE_KEY = 'Rf7VbeUBQmjvAagwsWx6riaZYc7h4OBD4CuxYyZ5bgA=';
|
|
40
|
+
// const R_PUBLIC_KEY = '60uReCXTn7KTEIExM4KveKstBGI3TaSrQss4biaesNs=';
|
|
41
|
+
// const R_PRIVATE_KEY = 'lBSkSxe/+UBWOeF5OJdQgf9qZhiI85hYE6yJCuWjCNk=';
|
|
40
42
|
// const R_PRIVATE_KEY = 'NamaTB+xwDFxtkQyBBkjRr5GEaXNtCw/G4qydnhQk5Y=';
|
|
41
43
|
// const R_PUBLIC_KEY = 'XvbhLWKbA1wfKsx3B7FKQuDQsZTZ/dMXWiD1MehBxZg=';
|
|
42
44
|
|
package/lib/rxome-api.cjs
CHANGED
|
@@ -133,3 +133,60 @@ exports.fetchData = async ( url, credentials, pseudonym = '', debug = false ) =>
|
|
|
133
133
|
return res.data
|
|
134
134
|
})
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
exports.pushData = async ( url, credentials, msg, debug = false ) => {
|
|
138
|
+
debug && console.log( 'Pushing to ', url )
|
|
139
|
+
console.log( 'Pushing to ', url )
|
|
140
|
+
|
|
141
|
+
const created = Date.now();
|
|
142
|
+
const keyId = credentials.keyId || "rxome";
|
|
143
|
+
const user = credentials.user || `${keyId}@rxome.net`;
|
|
144
|
+
const keyB64 = credentials.key || readSigKey( process.cwd()+'/'+credentials.keyFile );
|
|
145
|
+
|
|
146
|
+
const auth = await exports.signData( keyId, user, keyB64, created, debug );
|
|
147
|
+
|
|
148
|
+
FS = require( 'fs' );
|
|
149
|
+
return Axios({
|
|
150
|
+
url: url,
|
|
151
|
+
method: 'POST',
|
|
152
|
+
data: msg,
|
|
153
|
+
headers: {
|
|
154
|
+
Authorization: auth,
|
|
155
|
+
'x-date': created,
|
|
156
|
+
'x-rxome-user': user
|
|
157
|
+
},
|
|
158
|
+
timeout: 5000
|
|
159
|
+
})
|
|
160
|
+
.then(res => {
|
|
161
|
+
debug && console.log( "Result Data= ", res.data )
|
|
162
|
+
return res.data
|
|
163
|
+
})
|
|
164
|
+
.catch( (error) => {
|
|
165
|
+
// setIsLoading(false);
|
|
166
|
+
let msg=null;
|
|
167
|
+
if (error.response) {
|
|
168
|
+
// Request made and server responded
|
|
169
|
+
if (error.response?.data?.message){
|
|
170
|
+
console.log( '[SendData Response Error] ', error.response.data.message );
|
|
171
|
+
msg=`Response Error: ${error.response.data.message}`;
|
|
172
|
+
console.log(error.response.data);
|
|
173
|
+
} else {
|
|
174
|
+
console.log( '[SendData Response Error] no message' );
|
|
175
|
+
msg='Unknown response error';
|
|
176
|
+
}
|
|
177
|
+
console.log(error.response.status);
|
|
178
|
+
console.log(error.response.headers);
|
|
179
|
+
} else if (error.request) {
|
|
180
|
+
// The request was made but no response was received
|
|
181
|
+
console.log('[SendData Request Error] ', error.request);
|
|
182
|
+
msg = 'No response from server';
|
|
183
|
+
} else {
|
|
184
|
+
// Something happened in setting up the request that triggered an Error
|
|
185
|
+
console.log('[SendData Request Error] ', error.message);
|
|
186
|
+
msg = `Request Error: ${error.message}`;
|
|
187
|
+
}
|
|
188
|
+
const err = new Error( `Error sending data: ${msg}` );
|
|
189
|
+
console.log(err.name + ': ' + err.message);
|
|
190
|
+
throw err;
|
|
191
|
+
})
|
|
192
|
+
}
|
package/lib/rxome-generator.cjs
CHANGED
|
@@ -87,7 +87,7 @@ exports.generateRxomeKeys = async (name = 'rxome') => {
|
|
|
87
87
|
|
|
88
88
|
exports.fetchKey = async ( credentials, pseudonym = '', api = RXAPI, debug = false, apiEntry = APIENTRY ) => {
|
|
89
89
|
const result = await RxAPI.fetchData( `${api}/${apiEntry}/getpseudonym`, credentials, pseudonym, debug )
|
|
90
|
-
if (
|
|
90
|
+
if ( result.pseudonym === '' )
|
|
91
91
|
result.pseudonym = pseudonym;
|
|
92
92
|
return result;
|
|
93
93
|
}
|
|
@@ -291,7 +291,7 @@ exports.prepareQR = async ( data, api = RXAPI, apiEntry = APIENTRY ) => {
|
|
|
291
291
|
const protobufMedical = exports.encodePhenoPacket( compressedMedical );
|
|
292
292
|
const base64Medical = RxAPI.bufferToBase64(protobufMedical);
|
|
293
293
|
|
|
294
|
-
const key = await this.fetchKey( credentials, metaData
|
|
294
|
+
const key = await this.fetchKey( credentials, metaData?.pseudonym || '', api, false, apiEntry );
|
|
295
295
|
|
|
296
296
|
// check:
|
|
297
297
|
const buff = RxAPI.base64ToBuffer( base64Medical );
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rxome-generator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
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,28 @@
|
|
|
25
25
|
"phenopacket"
|
|
26
26
|
],
|
|
27
27
|
"author": "Tom Kamphans",
|
|
28
|
-
"license"
|
|
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": "^
|
|
35
|
-
"axios": "^
|
|
36
|
-
"commander": "^
|
|
34
|
+
"@noble/ed25519": "^2.2.3",
|
|
35
|
+
"axios": "^1.7.9",
|
|
36
|
+
"commander": "^13.1.0",
|
|
37
37
|
"json-key-converter": "^1.0.0",
|
|
38
38
|
"noble-ed25519": "^1.2.6",
|
|
39
|
-
"openpgp": "^
|
|
40
|
-
"protobufjs": "
|
|
41
|
-
"protobufjs-cli": "^1.
|
|
42
|
-
"qrcode": "^1.5.
|
|
39
|
+
"openpgp": "^6.1.0",
|
|
40
|
+
"protobufjs": "^7.4.0",
|
|
41
|
+
"protobufjs-cli": "^1.1.3",
|
|
42
|
+
"qrcode": "^1.5.4",
|
|
43
|
+
"sharp": "^0.33.5"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"jest": "^
|
|
46
|
+
"jest": "^29.7.0",
|
|
46
47
|
"json-loader": "^0.5.7"
|
|
47
48
|
},
|
|
48
49
|
"bin": {
|
|
49
|
-
"rxcode": "
|
|
50
|
+
"rxcode": "rxcode.js"
|
|
50
51
|
}
|
|
51
52
|
}
|
package/rxcode.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
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
7
|
import * as Coder from './lib/rxome-generator.cjs';
|
|
6
8
|
import * as ApiDemo from './lib/rxome-api-demo.cjs' ;
|
|
@@ -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.
|
|
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) );
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
|
|
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 ));
|
|
103
153
|
});
|
|
104
154
|
|
|
105
155
|
|
|
106
|
-
program.command('convert')
|
|
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)')
|
|
@@ -339,6 +389,7 @@ program.command('settings')
|
|
|
339
389
|
.action( (options) => {
|
|
340
390
|
|
|
341
391
|
console.log('This RxOME/FindMe2care QR generator V', VERSION );
|
|
392
|
+
console.log(`Running under Node ${process.version} for ${process.arch}`);
|
|
342
393
|
console.log('Connecting to', options.test ? RxAPI.TESTAPI : RxAPI.API );
|
|
343
394
|
console.log('API', options.test ? RxAPI.APIENTRY : RxAPI.APIENTRY );
|
|
344
395
|
|
package/README.TODO
DELETED
package/qrcode.png
DELETED
|
Binary file
|