Skip to content

Commit 7fb9edd

Browse files
committed
Import project
1 parent d76f267 commit 7fb9edd

28 files changed

+2775
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

LICENSE

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Copyright 2016 Stratumn
2+
3+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4+
5+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6+
7+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8+
9+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10+
11+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

agent/agent.js

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
var fs = require('fs');
2+
var crypto = require('crypto');
3+
var Bitcore = require('bitcore-lib');
4+
var Message = require('bitcore-message');
5+
var bs58 = require('bs58');
6+
var AWS = require('aws-sdk');
7+
8+
/**
9+
* Put AWS credentials here.
10+
*/
11+
AWS.config.update({
12+
"accessKeyId": "",
13+
"secretAccessKey": "",
14+
"region": ""
15+
});
16+
17+
/**
18+
* Put Sendgrid credentials here.
19+
*/
20+
var SENDGRID_APIKEY = "";
21+
22+
module.exports = {
23+
/**
24+
* This is a called when a new map is created.
25+
* It is responsible for creating the first link of a map.
26+
*/
27+
init: function(data) {
28+
// You can modify the state of the first link and add values.
29+
// Here we setup up a title, a timestamp, and an empty message list.
30+
var that = this;
31+
var s3 = new AWS.S3();
32+
var params = {Bucket: 'file-upload-stratumn', Key: data.name, ContentType: data.type};
33+
s3.getSignedUrl('putObject', params, function(err, url) { //UPLOADS FILE
34+
if (err) {
35+
that.reject();
36+
return;
37+
}
38+
that.state.FormData = {Document_ID: data.name};
39+
that.state.SignedURLToUpload = url;
40+
that.meta.tags = ["method__init"];
41+
that.append();
42+
});
43+
},
44+
45+
getSignedUrlToUpload: function(data) {
46+
var that = this;
47+
var s3 = new AWS.S3();
48+
var params = {Bucket: 'file-upload-stratumn', Key: data.name, ContentType: data.type};
49+
s3.getSignedUrl('putObject', params, function(err, url) { //UPLOADS FILE
50+
if (err) {
51+
that.reject();
52+
return;
53+
}
54+
that.meta.tags = ["method__SignedUrlToUpload"]; that.meta.priority = "";
55+
that.state.SignedURLToUpload = url;
56+
that.append();
57+
});
58+
},
59+
60+
getSignedUrlToView: function(FileName) {
61+
FileName = this.state.FormData.Document_ID;
62+
var that = this;
63+
var s3 = new AWS.S3();
64+
var params = {
65+
Bucket: 'file-upload-stratumn',
66+
Key: FileName,
67+
Expires: 600
68+
};
69+
var url = s3.getSignedUrl('getObject', params, function (err, url) {
70+
if(err) {
71+
that.reject();
72+
return;
73+
}
74+
that.meta.tags = ["method__SignedUrlToView"]; that.meta.priority = "";
75+
that.state.SignedURLToView = url;
76+
that.append();
77+
});
78+
},
79+
80+
sendEmail: function(data){
81+
var sendgrid = require("sendgrid")(SENDGRID_APIKEY);
82+
var linkURL = "https://docchain.stratumn.com/sign.html?linkhash="
83+
+ this.linkHash + "&address=";
84+
var s3 = new AWS.S3();
85+
var params = {Bucket: 'file-upload-stratumn', Key: data.Document_ID};
86+
var reader = s3.getObject(params).createReadStream();
87+
var hash = crypto.createHash('sha256');
88+
var that = this;
89+
data.Invites = JSON.parse(data.Invites);
90+
that.meta.tags = [data.Document_ID, "consent"];
91+
that.meta.priority = data.Version;
92+
var InvitesLength = data.Invites.length;
93+
94+
reader.on('error', function(err) {
95+
// error handling
96+
that.state.error = err; that.append(); return;
97+
});
98+
99+
reader.on('data', function (data) {
100+
hash.update(data);
101+
});
102+
103+
reader.on('end', function () {
104+
var res = hash.digest('hex');
105+
data.FileHash = res;
106+
that.meta.tags.push(res);
107+
that.meta.tags.push("method__sendEmail");
108+
var keys = [];
109+
data.Invites.forEach(function(item, i){
110+
var privateKey = new Bitcore.PrivateKey();
111+
var WIF = privateKey.toWIF();
112+
var publicKey = privateKey.toPublicKey();
113+
var address = undefined;
114+
address = publicKey.toAddress(Bitcore.Networks.livenet);
115+
data.Invites[i] =
116+
({ Email: data.Invites[i].Email, Name: data.Invites[i].Name, Address: address});
117+
var email = new sendgrid.Email();
118+
email.addTo(item.Email);
119+
email.setFrom(data.Doctor_Email);
120+
email.setSubject(data.PDF_Title);
121+
var linkURLEmail = linkURL + privateKey;
122+
var HTMLText =
123+
`Bonjour ${item.Name},<br/>
124+
${data.Conditions}
125+
<p>Vous trouverez à cette adresse</p>
126+
<p>${linkURLEmail}</p>
127+
<p>le lien vers le formulaire de consentement au protocole. Nous vous invitons à prendre le soin de le lire attentivement avant d’accepter.</p>
128+
<p>Pour toute information relative à ce formulaire, veuillez vous adresser à l’investigateur-coordinateur dont le contact se trouve ci-après.</p>
129+
<p>Pour toute autre information, veuillez adresser un email à l’adresse : secretariat.epidemiologie@labo.fr</p>
130+
<p>Cordialement,<br/>
131+
<p>Le laboratoire</p>
132+
</p>`;
133+
email.setHtml(HTMLText);
134+
sendgrid.send(email, function(data, err){
135+
data.Invites[i] =
136+
({ Email: data.Invites[i].Email, Name: data.Invites[i].Name, Address: address, EmailResponse: JSON.stringify(err), Index: i});
137+
});
138+
});
139+
140+
!(function(that, data){
141+
setTimeout(function(){
142+
var email = new sendgrid.Email();
143+
email.addTo(data.Doctor_Email);
144+
email.setFrom(data.Doctor_Email);
145+
email.setSubject(data.PDF_Title);
146+
var linkURLEmail = "https://docchain.stratumn.com/version.html?mapId="
147+
+ that.meta.mapId;
148+
var HTMLText = "Hello "+ data.Doctor_Name + ",<br/>"
149+
+ "<p>You just emailed patients. <br/>"
150+
+ "To verify who signed, please use the link below: <br/>"
151+
+ "<a href='" + linkURLEmail + "'>" + linkURLEmail + "</a></p></br>"
152+
+ "Thank you,<br/>Stratumn";
153+
email.setHtml(HTMLText);
154+
sendgrid.send(email, function(data, err){
155+
//
156+
});
157+
158+
that.state.FormData = data;
159+
that.append(); return;
160+
}, 0);
161+
})(that, data);
162+
});
163+
},
164+
165+
getConsentForSigning: function(WIF) { //implement Address Not Found
166+
var privateKey = Bitcore.PrivateKey.fromWIF(WIF);
167+
var address = privateKey.toPublicKey().toAddress(Bitcore.Networks.livenet);
168+
var Details = this.state.FormData.Invites.filterObjects("Address", address);
169+
if (Details.length) {
170+
this.state.FormData.Detail = Details[0];
171+
var message = Message(this.state.FormData.FileHash);
172+
var signature = message.sign(privateKey);
173+
this.state.FormData.Signature = signature;
174+
this.meta.tags = ["method__getConsentForSigning"];
175+
this.meta.priority = "";
176+
}
177+
else {
178+
this.reject("No Address Found");
179+
}
180+
this.append();
181+
},
182+
183+
saveSignature: function(data) {
184+
// data.DateSigned, data.WIF, data.Signature, data.Consent
185+
var privateKey = Bitcore.PrivateKey.fromWIF(data.WIF);
186+
var address = privateKey.toPublicKey().toAddress(Bitcore.Networks.livenet);
187+
PatientIndex = this.state.FormData.Invites.indexOfObjects("Address", address);
188+
if (PatientIndex > -1) {
189+
var verified = Message(this.state.FormData.FileHash).verify(address, data.Signature);
190+
if (verified) {
191+
this.meta.tags = [
192+
// this.state.FormData.Document_ID,
193+
"signature",
194+
this.state.FormData.Invites[PatientIndex].Name,
195+
this.state.FormData.Invites[PatientIndex].Email,
196+
data.Consent,
197+
data.Signature,
198+
address,
199+
data.DateSigned,
200+
"method__saveSignature"
201+
];
202+
this.meta.priority = PatientIndex;
203+
this.append();
204+
205+
// sendemail to Doctor & Patient
206+
var that = this;
207+
var sendgrid = require("sendgrid")(SENDGRID_APIKEY);
208+
var email = new sendgrid.Email();
209+
email.addTo(this.state.FormData.Invites[PatientIndex].Email);
210+
email.setFrom(this.state.FormData.Doctor_Email);
211+
email.setSubject(this.state.FormData.PDF_Title);
212+
var consentString = "";
213+
if (data.Consent == 1) {
214+
consentString = "approbation";
215+
}
216+
else {
217+
consentString = "refus";
218+
}
219+
var HTMLText =
220+
`Bonjour ${this.state.FormData.Invites[PatientIndex].Name},<br/>
221+
<p>Vous venez de signer le formulaire de consentement V.${this.state.FormData.Version} du protocole ${this.state.FormData.PDF_Title} avec votre ${consentString}. Nous vous en remercions.</p>
222+
<p>Pour toute information relative au formulaire, veuillez vous adresser à l’investigateur-coordinateur dont le contact se trouve ci-après.</p>
223+
<p>Pour toute autre information, veuillez adresser un email à l’adresse : secretariat.epidemiologie@labo.fr</p>
224+
<p>Cordialement,<br/>
225+
<p>Le laboratoire</p>
226+
</p>`;
227+
email.setHtml(HTMLText);
228+
sendgrid.send(email, function(data, err){
229+
var email = new sendgrid.Email();
230+
email.addTo(that.state.FormData.Doctor_Email);
231+
email.setFrom(that.state.FormData.Doctor_Email);
232+
email.setSubject(that.state.FormData.PDF_Title);
233+
var HTMLText = "Hello "+ that.state.FormData.Doctor_Name + ",<br/>"
234+
+ "<p>Please be advised that " + that.state.FormData.Invites[PatientIndex].Name
235+
+ " just signed the consent form Version#"
236+
+ that.state.FormData.Version + " with a "
237+
+ consentString
238+
// + ". You can check it at<br/>"
239+
// + "https://docmap.stratumn.com/version.html?mapId="
240+
// + that.meta.mapId +
241+
+ ".</p>Thank you,<br/> Stratumn Support";
242+
email.setHtml(HTMLText);
243+
sendgrid.send(email, function(data, err){
244+
// that.append();
245+
});
246+
247+
});
248+
}
249+
else {
250+
this.reject("Signature can not be verified with the address");
251+
}
252+
}
253+
else {
254+
// this.state = {err: "No Address Found"};
255+
this.reject("No Address Found in the list of patients");
256+
}
257+
},
258+
259+
verifySignature: function(data) {
260+
var verified = ""; //Message(this.state.FormData).verify(data.address, data.signature);
261+
this.state = ""; this.meta.tags = ""; this.meta.priority = "";
262+
this.state.Verified = verified;
263+
this.meta.tags = ["method__verifySignature"];
264+
this.append();
265+
},
266+
267+
cancel: function() { // Add Email code
268+
this.state = ""; this.state.canceled = "1";
269+
this.meta.tags = ["canceled"];
270+
this.append();
271+
}
272+
273+
};
274+
275+
Array.prototype.filterObjects = function(key, value) {
276+
return this.filter(function(x) { return (JSON.stringify(x[key]) === JSON.stringify(value)); })
277+
}
278+
Array.prototype.indexOfObjects = function(key, value) {
279+
return this.map(function(x) { return JSON.stringify(x[key])}).indexOf(JSON.stringify(value));
280+
}

0 commit comments

Comments
 (0)