improved error messages and instructions

most common problem... people has other versions of PDF that are not digitally signed by the province.
This commit is contained in:
Billy Lo 2021-09-01 21:20:11 -04:00
parent fac45c616b
commit 58c2bbf63c
11 changed files with 139 additions and 43 deletions

View File

@ -29,8 +29,7 @@ function Page(props: PageProps): JSX.Element {
<a href="mailto:grassroots@vaccine-ontario.ca" className="hover:underline">{t('common:contact')}</a>
<a href="https://vaccine-ontario.ca" className="hover:underline">{t('common:returnToMainSite')}</a>
{/* <a href="https://github.com/billylo1/covidpass" className="hover:underline">{t('common:gitHub')}</a> */}
{/* <Link href="/privacy"><a className="hover:underline">{t('common:privacyPolicy')}</a></Link>
<Link href="/imprint"><a className="hover:underline">{t('common:imprint')}</a></Link> */}
{/* {<Link href="/faq"><a className="hover:underline">{t('common:faq')}</a></Link>} */}
</nav>
</footer>
</main>

49
package-lock.json generated
View File

@ -21,6 +21,7 @@
"next-i18next": "^8.5.1",
"next-seo": "^4.26.0",
"node-fetch": "^2.6.1",
"node-pdf-verifier": "^1.0.1",
"pdfjs-dist": "^2.5.207",
"pngjs": "^6.0.0",
"qrcode": "^1.4.4",
@ -649,6 +650,14 @@
"integrity": "sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==",
"dev": true
},
"node_modules/asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"dependencies": {
"safer-buffer": "~2.1.0"
}
},
"node_modules/asn1.js": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
@ -2973,11 +2982,27 @@
"inherits": "2.0.3"
}
},
"node_modules/node-pdf-verifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/node-pdf-verifier/-/node-pdf-verifier-1.0.1.tgz",
"integrity": "sha512-s1i/d5RcBrv3jVr7wc53tm0q5wXdDsbd3rUsv+ESB5nh6WzNIXWGqpD+oXubNNVneCA2YXzTXJWOmq/9p17J+A==",
"dependencies": {
"node-rsa": "^1.1.1"
}
},
"node_modules/node-releases": {
"version": "1.1.73",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
"integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
},
"node_modules/node-rsa": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz",
"integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==",
"dependencies": {
"asn1": "^0.2.4"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -5516,6 +5541,14 @@
"integrity": "sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==",
"dev": true
},
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"asn1.js": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
@ -7349,11 +7382,27 @@
}
}
},
"node-pdf-verifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/node-pdf-verifier/-/node-pdf-verifier-1.0.1.tgz",
"integrity": "sha512-s1i/d5RcBrv3jVr7wc53tm0q5wXdDsbd3rUsv+ESB5nh6WzNIXWGqpD+oXubNNVneCA2YXzTXJWOmq/9p17J+A==",
"requires": {
"node-rsa": "^1.1.1"
}
},
"node-releases": {
"version": "1.1.73",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
"integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
},
"node-rsa": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz",
"integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==",
"requires": {
"asn1": "^0.2.4"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",

View File

@ -28,6 +28,7 @@
"next-i18next": "^8.5.1",
"next-seo": "^4.26.0",
"node-fetch": "^2.6.1",
"node-pdf-verifier": "^1.0.1",
"pdfjs-dist": "^2.5.207",
"pngjs": "^6.0.0",
"qrcode": "^1.4.4",

47
pages/faq.tsx Normal file
View File

@ -0,0 +1,47 @@
import {useTranslation} from 'next-i18next';
import {serverSideTranslations} from 'next-i18next/serverSideTranslations';
import Page from '../components/Page'
import Card from '../components/Card'
function Faq(): JSX.Element {
const { t } = useTranslation(['common', 'index', 'faq']);
const questionList = [
{description: 'Why have we taken time to build this?', answer: 'Gives the public something very easy to use before school year gets under way. #SafetyMatters', key: 1},
{description: 'Who built this?', answer: 'The same group of volunteers (Billy, Ryan, Evert, Jason, Anujan, Lisa) who brought the public the integrated vaccine appointment finding tool at vaccine-ontario.ca.', key: 2},
{description: 'Do you know CSS?', key: 3}
];
return (
<Page content={
<Card step="§" heading={t('common:faq')} content={
<div className="space-y-3">
<p className="font-bold">{t('faq:heading')}</p>
<ol>
{questionList.map(question => {
return (
<div>
<li key={question.key}><b>{question.key}. {question.description}</b></li>
<li key={question.key}>{question.answer}</li>
<br></br>
</div>
);
})}
</ol>
</div>
}/>
}/>
)
}
export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, ['index', 'faq', 'common']))
}
}
}
export default Faq;

View File

@ -9,7 +9,7 @@ function Imprint(): JSX.Element {
return (
<Page content={
<Card step="§" heading={t('common:imprint')} content={
<Card step="§" heading={t('common:faq')} content={
<div className="space-y-3">
<p className="font-bold">{t('imprint:heading')}</p>
<p>

View File

@ -1,8 +1,8 @@
title: Vaccination Receipt to Wallet
subtitle: This tool converts your vaccination receipt from Ontario Health to an Apple Wallet pass with an QR code. Other organizations (e.g. schools, workplaces) can then scan that QR code to validate in a privacy-respecting way.
subtitle: This tool converts your vaccination receipt from Ontario Ministry of Health to an Apple Wallet pass with a QR code. Other organizations (e.g. schools, workplaces) can then scan that QR code to validate in a privacy-respecting way.
privacyPolicy: Privacy Policy
donate: Sponsor
gitHub: GitHub
imprint: Imprint
faq: FAQ
contact: Contact Us
returnToMainSite: Return to Vaccine-Ontario.ca

View File

@ -0,0 +1,4 @@
heading: Frequently Asked Questions
contact: Contact
credits: Credits
creditsSource: Core engine from https://github.com/covidpass-org/covidpass

View File

@ -1,27 +1,4 @@
heading: Information according to § 5 TMG
heading: FAQ
contact: Contact
euDisputeResolution: EU Dispute Resolution
euDisputeResolutionParagraph: |
The European Commission provides a platform for online dispute resolution (OS) https://ec.europa.eu/consumers/odr.
You can find our e-mail address in the imprint above.
consumerDisputeResolution: Consumer dispute resolution / universal arbitration board
consumerDisputeResolutionParagraph: We are not willing or obliged to participate in dispute resolution proceedings before a consumer arbitration board.
liabilityForContents: Liability for contents
liabilityForContentsParagraph: |
As a service provider, we are responsible for our own content on these pages in accordance with § 7 paragraph 1 TMG under the general laws.
According to §§ 8 to 10 TMG, we are not obligated to monitor transmitted or stored information or to investigate circumstances that indicate illegal activity.
Obligations to remove or block the use of information under the general laws remain unaffected.
However, liability in this regard is only possible from the point in time at which a concrete infringement of the law becomes known.
If we become aware of any such infringements, we will remove the relevant content immediately.
liabilityForLinks: Liability for links
liabilityForLinksParagraph: |
Our offer contains links to external websites of third parties, on whose contents we have no influence.
Therefore, we cannot assume any liability for these external contents.
The respective provider or operator of the sites is always responsible for the content of the linked sites.
The linked pages were checked for possible legal violations at the time of linking.
Illegal contents were not recognizable at the time of linking.
However, a permanent control of the contents of the linked pages is not reasonable without concrete evidence of a violation of the law.
If we become aware of any infringements, we will remove such links immediately.
credits: Credits
creditsSource: With excerpts from https://www.e-recht24.de/impressum-generator.html
creditsTranslation: Translated with https://www.DeepL.com/Translator (free version)
creditsSource: Core engine from https://github.com/covidpass-org/covidpass

View File

@ -2,7 +2,7 @@ iosHint: On iOS, please use Safari.
errorClose: Close
selectCertificate: Select vaccination receipt (PDF)
selectCertificateDescription: |
Press "Select File", "Browse..." and select the PDF file you have saved in Step 1.
Press "Select File", "Browse..." and select the PDF file you have saved in Step 1. [ Reminder : Only receipts downloaded from the provincial web site can be verified and converted to Apple Wallet Pass.]
#stopCamera: Stop Camera
#startCamera: Start Camera
openFile: Select File

View File

@ -2,8 +2,9 @@ import {PayloadBody, Receipt} from "./payload";
import * as PdfJS from 'pdfjs-dist'
import {COLORS} from "./colors";
import { getCertificatesInfoFromPDF } from "@ninja-labs/verify-pdf"; // ES6
import { TextItem } from "pdfjs-dist/types/display/api";
// import verifyPDF from "@ninja-labs/verify-pdf";
// import {PNG} from 'pngjs'
// import {decodeData} from "./decode";
// import {Result} from "@zxing/library";
@ -32,27 +33,21 @@ export async function getPayloadBodyFromFile(file: File, color: COLORS): Promise
}
}
async function loadPDF(signedPdfBuffer): Promise<any> {
async function loadPDF(signedPdfBuffer : ArrayBuffer): Promise<any> {
try {
const certs = getCertificatesInfoFromPDF(signedPdfBuffer);
// console.log('certs = ' + JSON.stringify(certs, null, 2));
// check signature
// console.log("verifying");
// const verificationResult = verifyPDF(signedPdfBuffer); // not sure why it failed
const result = certs[0];
const isClientCertificate = result.clientCertificate;
const issuedByEntrust = (result.issuedBy.organizationName == 'Entrust, Inc.');
const issuedToOntarioHealth = (result.issuedTo.commonName == 'covid19signer.ontariohealth.ca');
console.log(`PDF is signed by ${result.issuedBy.organizationName}, issued to ${result.issuedTo.commonName}`);
if (isClientCertificate && issuedByEntrust && issuedToOntarioHealth) {
console.log('PDF looks good, getting payload');
console.log('getting receipt details inside PDF');
const receipt = await getPdfDetails(signedPdfBuffer);
console.log(JSON.stringify(receipt, null, 2));
// console.log(JSON.stringify(receipt, null, 2));
return Promise.resolve(receipt);
} else {
@ -63,6 +58,9 @@ async function loadPDF(signedPdfBuffer): Promise<any> {
} catch (e) {
console.error(e);
if (e.message.includes('Failed to locate ByteRange')) {
e.message = 'Sorry. Selected PDF file is not digitally signed. Please download official copy from Step 1 and retry. Thanks.'
}
return Promise.reject(e);
}

View File

@ -463,6 +463,13 @@
"minimalistic-assert" "^1.0.0"
"safer-buffer" "^2.1.0"
"asn1@^0.2.4":
"integrity" "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg=="
"resolved" "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz"
"version" "0.2.4"
dependencies:
"safer-buffer" "~2.1.0"
"assert@^1.1.1":
"integrity" "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA=="
"resolved" "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz"
@ -2105,11 +2112,25 @@
"util" "^0.11.0"
"vm-browserify" "^1.0.1"
"node-pdf-verifier@^1.0.1":
"integrity" "sha512-s1i/d5RcBrv3jVr7wc53tm0q5wXdDsbd3rUsv+ESB5nh6WzNIXWGqpD+oXubNNVneCA2YXzTXJWOmq/9p17J+A=="
"resolved" "https://registry.npmjs.org/node-pdf-verifier/-/node-pdf-verifier-1.0.1.tgz"
"version" "1.0.1"
dependencies:
"node-rsa" "^1.1.1"
"node-releases@^1.1.71":
"integrity" "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
"resolved" "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz"
"version" "1.1.73"
"node-rsa@^1.1.1":
"integrity" "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw=="
"resolved" "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz"
"version" "1.1.1"
dependencies:
"asn1" "^0.2.4"
"normalize-path@^3.0.0", "normalize-path@~3.0.0":
"integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
"resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
@ -2678,7 +2699,7 @@
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
"version" "5.1.2"
"safer-buffer@^2.1.0", "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
"safer-buffer@^2.1.0", "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", "safer-buffer@~2.1.0":
"integrity" "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
"resolved" "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
"version" "2.1.2"