diff --git a/app/components/SHCCard.js b/app/components/SHCCard.js
new file mode 100644
index 0000000..ae9930d
--- /dev/null
+++ b/app/components/SHCCard.js
@@ -0,0 +1,324 @@
+import React, {Component} from 'react';
+import { StyleSheet, View, Image, Button, FlatList, TouchableOpacity } from 'react-native';
+import { Text, Card, Divider } from 'react-native-elements';
+import AsyncStorage from '@react-native-async-storage/async-storage';
+import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
+
+import Moment from 'moment';
+
+import { CardStyles as styles } from '../themes/CardStyles'
+
+const VACCINE_CODES = {
+ 54 :'adenovirus, type 4',
+ 55 :'adenovirus, type 7',
+ 82 :'adenovirus, unspecified formulation',
+ 24 :'anthrax',
+ 19 :'BCG',
+ 27 :'botulinum antitoxin',
+ 26 :'cholera, unspecified formulation',
+ 29 :'CMVIG',
+ 56 :'dengue fever',
+ 12 :'diphtheria antitoxin',
+ 28 :'DT (pediatric)',
+ 20 :'DTaP',
+ 106 :'DTaP, 5 pertussis antigens',
+ 107 :'DTaP, unspecified formulation',
+ 110 :'DTaP-Hep B-IPV',
+ 50 :'DTaP-Hib',
+ 120 :'DTaP-Hib-IPV',
+ 130 :'DTaP-IPV',
+ 1 :'DTP',
+ 22 :'DTP-Hib',
+ 102 :'DTP-Hib-Hep B',
+ 57 :'hantavirus',
+ 52 :'Hep A, adult',
+ 83 :'Hep A, ped/adol, 2 dose',
+ 84 :'Hep A, ped/adol, 3 dose',
+ 31 :'Hep A, pediatric, unspecified formulation',
+ 85 :'Hep A, unspecified formulation',
+ 104 :'Hep A-Hep B',
+ 30 :'HBIG',
+ 8 :'Hep B, adolescent or pediatric',
+ 42 :'Hep B, adolescent/high risk infant',
+ 43 :'Hep B, adult',
+ 44 :'Hep B, dialysis',
+ 45 :'Hep B, unspecified formulation',
+ 58 :'Hep C',
+ 59 :'Hep E',
+ 60 :'herpes simplex 2',
+ 46 :'Hib (PRP-D)',
+ 47 :'Hib (HbOC)',
+ 48 :'Hib (PRP-T)',
+ 49 :'Hib (PRP-OMP)',
+ 17 :'Hib, unspecified formulation',
+ 51 :'Hib-Hep B',
+ 61 :'HIV',
+ 118 :'HPV, bivalent',
+ 62 :'HPV, quadrivalent',
+ 86 :'IG',
+ 87 :'IGIV',
+ 14 :'IG, unspecified formulation',
+ 111 :'influenza, live, intranasal',
+ 15 :'influenza, split (incl. purified surface antigen)',
+ 16 :'influenza, whole',
+ 88 :'influenza, unspecified formulation',
+ 123 :'influenza, H5N1-1203',
+ 10 :'IPV',
+ 2 :'OPV',
+ 89 :'polio, unspecified formulation',
+ 39 :'Japanese encephalitis SC',
+ 63 :'Junin virus',
+ 64 :'leishmaniasis',
+ 65 :'leprosy',
+ 66 :'Lyme disease',
+ 3 :'MMR',
+ 4 :'M/R',
+ 94 :'MMRV',
+ 67 :'malaria',
+ 5 :'measles',
+ 68 :'melanoma',
+ 32 :'meningococcal MPSV4',
+ 103 :'meningococcal C conjugate',
+ 114 :'meningococcal MCV4P',
+ 108 :'meningococcal ACWY, unspecified formulation',
+ 7 :'mumps',
+ 69 :'parainfluenza-3',
+ 11 :'pertussis',
+ 23 :'plague',
+ 33 :'pneumococcal polysaccharide PPV23',
+ 100 :'pneumococcal conjugate PCV 7',
+ 109 :'pneumococcal, unspecified formulation',
+ 70 :'Q fever',
+ 18 :'rabies, intramuscular injection',
+ 40 :'rabies, intradermal injection',
+ 90 :'rabies, unspecified formulation',
+ 72 :'rheumatic fever',
+ 73 :'Rift Valley fever',
+ 34 :'RIG',
+ 119 :'rotavirus, monovalent',
+ 122 :'rotavirus, unspecified formulation',
+ 116 :'rotavirus, pentavalent',
+ 74 :'rotavirus, tetravalent',
+ 71 :'RSV-IGIV',
+ 93 :'RSV-MAb',
+ 6 :'rubella',
+ 38 :'rubella/mumps',
+ 76 :'Staphylococcus bacterio lysate',
+ 113 :'Td (adult), 5 Lf tetanus toxoid, preservative free, adsorbed',
+ 9 :'Td (adult), 2 Lf tetanus toxoid, preservative free, adsorbed',
+ 115 :'Tdap',
+ 35 :'tetanus toxoid, adsorbed',
+ 112 :'tetanus toxoid, unspecified formulation',
+ 77 :'tick-borne encephalitis',
+ 13 :'TIG',
+ 95 :'TST-OT tine test',
+ 96 :'TST-PPD intradermal',
+ 97 :'TST-PPD tine test',
+ 98 :'TST, unspecified formulation',
+ 78 :'tularemia vaccine',
+ 91 :'typhoid, unspecified formulation',
+ 25 :'typhoid, oral',
+ 41 :'typhoid, parenteral',
+ 53 :'typhoid, parenteral, AKD (U.S. military)',
+ 101 :'typhoid, ViCPs',
+ 75 :'vaccinia (smallpox)',
+ 105 :'vaccinia (smallpox) diluted',
+ 79 :'vaccinia immune globulin',
+ 21 :'varicella',
+ 81 :'VEE, inactivated',
+ 80 :'VEE, live',
+ 92 :'VEE, unspecified formulation',
+ 36 :'VZIG',
+ 117 :'VZIG (IND)',
+ 37 :'yellow fever',
+ 121 :'zoster live',
+ 998 :'no vaccine administered',
+ 999 :'unknown',
+ 99 :'RESERVED - do not use',
+ 133 :'Pneumococcal conjugate PCV 13',
+ 134 :'Japanese Encephalitis IM',
+ 137 :'HPV, unspecified formulation',
+ 136 :'Meningococcal MCV4O',
+ 135 :'Influenza, high dose seasonal',
+ 131 :'typhus, historical',
+ 132 :'DTaP-IPV-HIB-HEP B, historical',
+ 128 :'Novel Influenza-H1N1-09, all formulations',
+ 125 :'Novel Influenza-H1N1-09, nasal',
+ 126 :'Novel influenza-H1N1-09, preservative-free',
+ 127 :'Novel influenza-H1N1-09',
+ 138 :'Td (adult)',
+ 139 :'Td(adult) unspecified formulation',
+ 140 :'Influenza, seasonal, injectable, preservative free',
+ 129 :'Japanese Encephalitis, unspecified formulation',
+ 141 :'Influenza, seasonal, injectable',
+ 142 :'tetanus toxoid, not adsorbed',
+ 143 :'Adenovirus types 4 and 7',
+ 144 :'influenza, seasonal, intradermal, preservative free',
+ 145 :'RSV-MAb (new)',
+ 146 :'DTaP,IPV,Hib,HepB',
+ 147 :'meningococcal MCV4, unspecified formulation',
+ 148 :'Meningococcal C/Y-HIB PRP',
+ 149 :'influenza, live, intranasal, quadrivalent',
+ 150 :'influenza, injectable, quadrivalent, preservative free',
+ 151 :'influenza nasal, unspecified formulation',
+ 152 :'Pneumococcal Conjugate, unspecified formulation',
+ 153 :'Influenza, injectable, MDCK, preservative free',
+ 154 :'Hep A, IG',
+ 155 :'influenza, recombinant, injectable, preservative free',
+ 156 :'Rho(D)-IG',
+ 157 :'Rho(D) -IG IM',
+ 158 :'influenza, injectable, quadrivalent',
+ 159 :'Rho(D) - Unspecified formulation',
+ 160 :'Influenza A monovalent (H5N1), ADJUVANTED-2013',
+ 801 :'AS03 Adjuvant',
+ 161 :'Influenza, injectable,quadrivalent, preservative free, pediatric',
+ 162 :'meningococcal B, recombinant',
+ 163 :'meningococcal B, OMV',
+ 164 :'meningococcal B, unspecified',
+ 165 :'HPV9',
+ 166 :'influenza, intradermal, quadrivalent, preservative free',
+ 167 :'meningococcal, unknown serogroups',
+ 168 :'influenza, trivalent, adjuvanted',
+ 169 :'Hep A, live attenuated',
+ 170 :'DTAP/IPV/HIB - non-US',
+ 171 :'Influenza, injectable, MDCK, preservative free, quadrivalent',
+ 172 :'cholera, WC-rBS',
+ 173 :'cholera, BivWC',
+ 174 :'cholera, live attenuated',
+ 175 :'Rabies - IM Diploid cell culture',
+ 176 :'Rabies - IM fibroblast culture',
+ 177 :'PCV10',
+ 178 :'OPV bivalent',
+ 179 :'OPV ,monovalent, unspecified',
+ 180 :'tetanus immune globulin',
+ 181 :'anthrax immune globulin',
+ 182 :'OPV, Unspecified',
+ 183 :'Yellow fever vaccine - alt',
+ 184 :'Yellow fever, unspecified formulation',
+ 185 :'influenza, recombinant, quadrivalent,injectable, preservative free',
+ 186 :'Influenza, injectable, MDCK, quadrivalent, preservative',
+ 187 :'zoster recombinant',
+ 188 :'zoster, unspecified formulation',
+ 189 :'HepB-CpG',
+ 190 :'Typhoid conjugate vaccine (TCV)',
+ 191 :'meningococcal A polysaccharide (non-US)',
+ 192 :'meningococcal AC polysaccharide (non-US)',
+ 193 :'Hep A-Hep B, pediatric/adolescent',
+ 194 :'Influenza, Southern Hemisphere',
+ 195 :'DT, IPV adsorbed',
+ 196 :'Td, adsorbed, preservative free, adult use, Lf unspecified',
+ 197 :'influenza, high-dose, quadrivalent',
+ 200 :'influenza, Southern Hemisphere, pediatric, preservative free',
+ 201 :'influenza, Southern Hemisphere, preservative free',
+ 202 :'influenza, Southern Hemisphere, quadrivalent, with preservative',
+ 198 :'DTP-hepB-Hib Pentavalent Non-US',
+ 203 :'meningococcal polysaccharide (groups A, C, Y, W-135) TT conjugate',
+ 205 :'Influenza vaccine, quadrivalent, adjuvanted',
+ 206 :'Smallpox monkeypox vaccine (National Stockpile)',
+ 207 :'COVID-19, mRNA, LNP-S, PF, 100 mcg/0.5 mL dose',
+ 208 :'COVID-19, mRNA, LNP-S, PF, 30 mcg/0.3 mL dose',
+ 213 :'SARS-COV-2 (COVID-19) vaccine, UNSPECIFIED',
+ 210 :'COVID-19 vaccine, vector-nr, rS-ChAdOx1, PF, 0.5 mL ',
+ 212 :'COVID-19 vaccine, vector-nr, rS-Ad26, PF, 0.5 mL',
+ 204 :'Ebola Zaire vaccine, live, recombinant, 1mL dose',
+ 214 :'Ebola, unspecified',
+ 211 :'COVID-19 vaccine, Subunit, rS-nanoparticle+Matrix-M1 Adjuvant, PF, 0.5 mL'
+}
+
+
+export default class SHCCard extends Component {
+
+ patientRecords = () => {
+ return this.props.detail.cert.vc.credentialSubject.fhirBundle.entry.filter(entry => entry.resource.resourceType === "Patient");
+ }
+
+ otherRecords = () => {
+ return this.props.detail.cert.vc.credentialSubject.fhirBundle.entry.filter(entry => entry.resource.resourceType !== "Patient");
+ }
+
+ patientName = () => {
+ let pat = this.patientRecords();
+ return pat[0].resource.name[0].given.join(' ') + " " + pat[0].resource.name[0].family
+ }
+
+ patientDob = () => {
+ let pat = this.patientRecords();
+ return new Date(pat[0].resource.birthDate);
+ }
+
+ issuerName = (card) => {
+ if (card.pub_key.toLowerCase() === "https://myvaccinerecord.cdph.ca.gov/creds")
+ return "State of California"
+ return card.pub_key.toLowerCase();
+ }
+
+ issuedAt = (card) => {
+ return Moment(new Date(parseInt(card.cert.nbf)*1000)).format('MMM DD, YYYY');
+ }
+
+ showQR = (card) => {
+ this.props.navigation.navigate({name: 'QRShow', params: {
+ qr: card.rawQR,
+ title: this.patientName(),
+ detail: "DoB: " + Moment(this.patientDob()).format('MMM DD, YYYY'),
+ signedBy: this.issuerName(card) + " on " + this.issuedAt(card)
+ }
+ });
+ }
+
+ renderCard = () => {
+ return (
+
+
+ {Moment(this.props.detail.scanDate).format('MMM DD, hh:mma')} - Vaccine Record
+ this.props.removeItem(this.props.detail.signature)} solid/>
+
+
+
+ {this.patientName()}
+
+
+
+ DoB: {Moment(this.patientDob()).format('MMM DD, YYYY')}
+
+
+
+
+ item.fullUrl}
+ renderItem={({item}) => {
+ return (
+
+
+ {item.resource.resourceType} at {item.resource.occurrenceDateTime}
+
+
+
+
+ Vaccine: {VACCINE_CODES[item.resource.vaccineCode.coding[0].code]}, Lot #{item.resource.lotNumber}
+
+
+
+ )
+ }} />
+
+
+
+
+
+ {this.issuerName(this.props.detail)} on {this.issuedAt(this.props.detail)}
+
+
+ );
+ }
+
+
+ render() {
+ return this.props.pressable ?
+ ( this.showQR(this.props.detail)}>
+ {this.renderCard()}
+
+ ) : this.renderCard();
+ }
+}
\ No newline at end of file
diff --git a/app/screens/Entry.js b/app/screens/Entry.js
index 80a6807..5156c95 100644
--- a/app/screens/Entry.js
+++ b/app/screens/Entry.js
@@ -15,6 +15,8 @@ import VaccineCard from './../components/VaccineCard';
import CouponCard from './../components/CouponCard';
import StatusCard from './../components/StatusCard';
import PassKeyCard from './../components/PassKeyCard';
+import SHCCard from './../components/SHCCard';
+
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { SearchBar } from 'react-native-elements';
@@ -139,6 +141,8 @@ function Entry({ navigation }) {
return
if (item.type === "COWIN")
return
+ if (item.type === "FHIRBundle")
+ return
}} />
diff --git a/app/screens/QRReader.js b/app/screens/QRReader.js
index bb24a30..0f9c595 100644
--- a/app/screens/QRReader.js
+++ b/app/screens/QRReader.js
@@ -7,6 +7,7 @@ import {useTheme} from '../themes/ThemeProvider';
import {importPCF} from '../utils/ImportPCF';
import {importDivoc} from '../utils/ImportDivoc';
+import {importSHC} from '../utils/ImportSHC';
const screenHeight = Math.round(Dimensions.get('window').height);
@@ -41,6 +42,11 @@ function QRReader({ navigation }) {
return;
}
+ if (e.data && e.data.startsWith("shc:")) {
+ await checkResult(await importSHC(e.data));
+ return;
+ }
+
if ((e.data && e.data.startsWith("PK")) || (e.data == null && e.rawData)) {
if (!e.rawData) {
showErrorMessage("Phone/OS is unable to read Binary QRs");
@@ -57,7 +63,7 @@ function QRReader({ navigation }) {
return;
}
- showErrorMessage("Not a Health Passport" + e.data);
+ showErrorMessage("Not a supported QR" + e.data);
return;
}
diff --git a/app/screens/QRResult.js b/app/screens/QRResult.js
index 596a4f9..8ad7533 100644
--- a/app/screens/QRResult.js
+++ b/app/screens/QRResult.js
@@ -12,6 +12,7 @@ import VaccineCard from './../components/VaccineCard';
import CouponCard from './../components/CouponCard';
import StatusCard from './../components/StatusCard';
import PassKeyCard from './../components/PassKeyCard';
+import SHCCard from './../components/SHCCard';
const screenWidth = Math.round(Dimensions.get('window').width)-50;
@@ -42,6 +43,7 @@ function QRResult({ navigation, route }) {
{ qr.type === "STATUS" && }
{ qr.type === "PASSKEY" && }
{ qr.type === "COWIN" && }
+ { qr.type === "FHIRBundle" && }
{
+ // Saving
+ await AsyncStorage.setItem('CARDS'+card.signature, JSON.stringify(card));
+}
+
+const importSHC = async (certificateData) => {
+ let payload = await SHC.unpackAndVerify(certificateData);
+
+ if (payload) {
+ let baseCard = {
+ format: "SHC",
+ type: "FHIRBundle",
+ pub_key: payload.iss,
+ signature: await sha256(JSON.stringify(payload)),
+ scanDate: new Date().toJSON(),
+ verified: "Valid",
+ rawQR: certificateData
+ };
+
+ baseCard.cert = payload;
+
+ await saveCard(baseCard);
+
+ return {status: "OK", payload: baseCard};
+ } else {
+ return {status: "Could not verify"};
+ }
+}
+
+export { importSHC }
\ No newline at end of file
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index b5aa42a..b320e9f 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -354,6 +354,8 @@ PODS:
- React-Core
- RNScreens (2.18.1):
- React-Core
+ - RNSha256 (1.4.7):
+ - React
- RNSVG (12.1.1):
- React
- RNVectorIcons (8.1.0):
@@ -446,6 +448,7 @@ DEPENDENCIES:
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNPermissions (from `../node_modules/react-native-permissions`)
- RNScreens (from `../node_modules/react-native-screens`)
+ - RNSha256 (from `../node_modules/react-native-sha256`)
- RNSVG (from `../node_modules/react-native-svg`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- UMAppLoader (from `../node_modules/unimodules-app-loader/ios`)
@@ -559,6 +562,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-permissions"
RNScreens:
:path: "../node_modules/react-native-screens"
+ RNSha256:
+ :path: "../node_modules/react-native-sha256"
RNSVG:
:path: "../node_modules/react-native-svg"
RNVectorIcons:
@@ -644,6 +649,7 @@ SPEC CHECKSUMS:
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
RNPermissions: c46788f4cd402287425983e04a4c9bb4356036eb
RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d
+ RNSha256: bf2c90a9e0cec6dcbcc4100e4e19715ae7feaa34
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
UMAppLoader: fe2708bb0ac5cd70052bc207d06aa3b7e72b9e97
diff --git a/package-lock.json b/package-lock.json
index 0eb87d3..0fb7864 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"dependencies": {
"@pathcheck/cred-sdk": "^0.0.6",
"@pathcheck/divoc-sdk": "^0.1.0",
+ "@pathcheck/shc-sdk": "^0.0.3",
"@react-native-async-storage/async-storage": "^1.15.4",
"@react-navigation/native": "^5.9.4",
"@react-navigation/stack": "^5.14.4",
@@ -31,6 +32,7 @@
"react-native-qrcode-svg": "^6.1.1",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^2.18.1",
+ "react-native-sha256": "^1.4.7",
"react-native-simple-crypto": "^0.2.15",
"react-native-svg": "^12.1.1",
"react-native-unimodules": "^0.13.3",
@@ -3793,6 +3795,23 @@
"node": ">=10"
}
},
+ "node_modules/@pathcheck/shc-sdk": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/@pathcheck/shc-sdk/-/shc-sdk-0.0.3.tgz",
+ "integrity": "sha512-dmHrTrasbfRuGsdGnYLkAsrhjr3gnIcAj+AO+XJrTYOD5yNINA+eGZBXaMJKX28KDDqwUQuwXamqFD5kFuMdWQ==",
+ "dependencies": {
+ "base64url": "^3.0.1",
+ "cross-fetch": "^3.1.4",
+ "esm": "^3.2.25",
+ "node-jose": "^2.0.0",
+ "pako": "^2.0.3"
+ }
+ },
+ "node_modules/@pathcheck/shc-sdk/node_modules/pako": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.3.tgz",
+ "integrity": "sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw=="
+ },
"node_modules/@react-native-async-storage/async-storage": {
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.5.tgz",
@@ -7529,6 +7548,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es6-promise": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
+ },
"node_modules/escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -12231,6 +12255,11 @@
"logkitty": "bin/logkitty.js"
}
},
+ "node_modules/long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -13021,6 +13050,54 @@
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
"integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs="
},
+ "node_modules/node-jose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.0.0.tgz",
+ "integrity": "sha512-j8zoFze1gijl8+DK/dSXXqX7+o2lMYv1XS+ptnXgGV/eloQaqq1YjNtieepbKs9jBS4WTnMOqyKSaQuunJzx0A==",
+ "dependencies": {
+ "base64url": "^3.0.1",
+ "buffer": "^5.5.0",
+ "es6-promise": "^4.2.8",
+ "lodash": "^4.17.15",
+ "long": "^4.0.0",
+ "node-forge": "^0.10.0",
+ "pako": "^1.0.11",
+ "process": "^0.11.10",
+ "uuid": "^3.3.3"
+ }
+ },
+ "node_modules/node-jose/node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/node-jose/node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
"node_modules/node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -14483,6 +14560,11 @@
"react-native": "*"
}
},
+ "node_modules/react-native-sha256": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/react-native-sha256/-/react-native-sha256-1.4.7.tgz",
+ "integrity": "sha512-VcIjOBGvHG6V2OCgbGnEKOymcatYC7byf1aM6mmCoUDqOUFQrGIjnU9fUMWGoMERAljVqisvsG/M1GdfhilkFg=="
+ },
"node_modules/react-native-simple-crypto": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/react-native-simple-crypto/-/react-native-simple-crypto-0.2.15.tgz",
@@ -20803,6 +20885,25 @@
"vaccination-context": "^1.0.8"
}
},
+ "@pathcheck/shc-sdk": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/@pathcheck/shc-sdk/-/shc-sdk-0.0.3.tgz",
+ "integrity": "sha512-dmHrTrasbfRuGsdGnYLkAsrhjr3gnIcAj+AO+XJrTYOD5yNINA+eGZBXaMJKX28KDDqwUQuwXamqFD5kFuMdWQ==",
+ "requires": {
+ "base64url": "^3.0.1",
+ "cross-fetch": "^3.1.4",
+ "esm": "^3.2.25",
+ "node-jose": "^2.0.0",
+ "pako": "^2.0.3"
+ },
+ "dependencies": {
+ "pako": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.3.tgz",
+ "integrity": "sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw=="
+ }
+ }
+ },
"@react-native-async-storage/async-storage": {
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.5.tgz",
@@ -23769,6 +23870,11 @@
"is-symbol": "^1.0.2"
}
},
+ "es6-promise": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
+ },
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -27356,6 +27462,11 @@
"yargs": "^15.1.0"
}
},
+ "long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+ },
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -28018,6 +28129,38 @@
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
"integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs="
},
+ "node-jose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.0.0.tgz",
+ "integrity": "sha512-j8zoFze1gijl8+DK/dSXXqX7+o2lMYv1XS+ptnXgGV/eloQaqq1YjNtieepbKs9jBS4WTnMOqyKSaQuunJzx0A==",
+ "requires": {
+ "base64url": "^3.0.1",
+ "buffer": "^5.5.0",
+ "es6-promise": "^4.2.8",
+ "lodash": "^4.17.15",
+ "long": "^4.0.0",
+ "node-forge": "^0.10.0",
+ "pako": "^1.0.11",
+ "process": "^0.11.10",
+ "uuid": "^3.3.3"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+ }
+ }
+ },
"node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -29140,6 +29283,11 @@
"integrity": "sha512-r5WZLpmx2hHjC1RgMdPq5YpSU9tEhBpUaZ5M1SUtNIONyiLqQVxabhRCINdebIk4depJiIl7yw2Q85zJyeX6fw==",
"requires": {}
},
+ "react-native-sha256": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/react-native-sha256/-/react-native-sha256-1.4.7.tgz",
+ "integrity": "sha512-VcIjOBGvHG6V2OCgbGnEKOymcatYC7byf1aM6mmCoUDqOUFQrGIjnU9fUMWGoMERAljVqisvsG/M1GdfhilkFg=="
+ },
"react-native-simple-crypto": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/react-native-simple-crypto/-/react-native-simple-crypto-0.2.15.tgz",
diff --git a/package.json b/package.json
index 64433ee..9ceb3d7 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"dependencies": {
"@pathcheck/cred-sdk": "^0.0.6",
"@pathcheck/divoc-sdk": "^0.1.0",
+ "@pathcheck/shc-sdk": "^0.0.3",
"@react-native-async-storage/async-storage": "^1.15.4",
"@react-navigation/native": "^5.9.4",
"@react-navigation/stack": "^5.14.4",
@@ -34,6 +35,7 @@
"react-native-qrcode-svg": "^6.1.1",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^2.18.1",
+ "react-native-sha256": "^1.4.7",
"react-native-simple-crypto": "^0.2.15",
"react-native-svg": "^12.1.1",
"react-native-unimodules": "^0.13.3",