|
| 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