Merge pull request #54 from covidpass-org/dev

Add camera errors
This commit is contained in:
Marvin Sextro 2021-07-25 22:55:47 +02:00 committed by GitHub
commit 2b4b4423dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 113 additions and 60 deletions

View File

@ -10,7 +10,7 @@ function Alert(props: AlertProps): JSX.Element {
return (
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 mt-5 rounded relative" role="alert">
<span className="block sm:inline" id="message">{props.errorMessage}</span>
<span className="block sm:inline pr-6" id="message">{props.errorMessage}</span>
<span className="absolute top-0 bottom-0 right-0 px-4 py-3" onClick={props.onClose}>
<svg className="fill-current h-6 w-6 text-red-500" role="button" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">

View File

@ -29,6 +29,11 @@ function Form(): JSX.Element {
// Check if there is a translation and replace message accordingly
const setErrorMessage = (message: string) => {
if (message == undefined) {
_setErrorMessage(undefined);
return;
}
const translation = t('errors:'.concat(message));
_setErrorMessage(translation !== message ? translation : message);
};
@ -68,7 +73,20 @@ function Form(): JSX.Element {
const codeReader = new BrowserQRCodeReader();
// Needs to be called before any camera can be accessed
await BrowserQRCodeReader.listVideoInputDevices();
let deviceList: MediaDeviceInfo[];
try {
deviceList = await BrowserQRCodeReader.listVideoInputDevices();
} catch (e) {
setErrorMessage('noCameraAccess');
return;
}
// Check if camera device is present
if (deviceList.length == 0) {
setErrorMessage("noCameraFound");
return;
}
// Get preview Element to show camera stream
const previewElem: HTMLVideoElement = document.querySelector('#cameraPreview');
@ -89,6 +107,9 @@ function Form(): JSX.Element {
setGlobalControls(undefined);
setIsCameraOpen(false);
}
if (error !== undefined) {
setErrorMessage(error.message);
}
}
)
);
@ -101,6 +122,12 @@ function Form(): JSX.Element {
event.preventDefault();
setLoading(true);
if(navigator.userAgent.match('CriOS')) {
setErrorMessage('safariSupportOnly');
setLoading(false);
return;
}
if (!file && !qrCode) {
setErrorMessage('noFileOrQrCode')
setLoading(false);
@ -228,7 +255,7 @@ function Form(): JSX.Element {
{t('index:addToWallet')}
</button>
<div id="spin" className={loading ? undefined : "hidden"}>
<svg className="animate-spin h-5 w-5 ml-2" viewBox="0 0 24 24">
<svg className="animate-spin h-5 w-5 ml-3" viewBox="0 0 24 24">
<circle className="opacity-0" cx="12" cy="12" r="10" stroke="currentColor"
strokeWidth="4"/>
<path className="opacity-75" fill="currentColor"

View File

@ -14,4 +14,7 @@ couldNotFindQrCode: QR-Code konnte in der ausgewählten Datei nicht gefunden wer
invalidQrCode: Ungültiger QR-Code
certificateType: Kein gültiger Zertifikatstyp gefunden
invalidTestResult: Ungültiges Testergebnis
invalidTestType: Ungültiger Testtyp
invalidTestType: Ungültiger Testtyp
noCameraAccess: Kein Zugriff auf die Kamera möglich. Überprüfe die Berechtigungen unter Einstellungen > Safari > Kamera.
noCameraFound: Keine Kamera gefunden.
safariSupportOnly: Bitte verwende unter iOS den Safari Browser.

View File

@ -14,4 +14,7 @@ couldNotFindQrCode: Could not find QR Code in provided file
invalidQrCode: Invalid QR code
certificateType: No valid certificate type found
invalidTestResult: Invalid test result
invalidTestType: Invalid test type
invalidTestType: Invalid test type
noCameraAccess: Could not access camera. Check permissions under Settings > Safari > Camera.
noCameraFound: Could not find camera.
safariSupportOnly: On iOS, please use the Safari Browser.

View File

@ -14,4 +14,7 @@ couldNotFindQrCode: QR-koodia ei löytynyt annetusta tiedostosta
invalidQrCode: Virheellinen QR-koodi
certificateType: Kelvollista varmennetyyppiä ei löytynyt
invalidTestResult: Virheellinen testitulos
invalidTestType: Virheellinen testityyppi
invalidTestType: Virheellinen testityyppi
noCameraAccess: Kameraan ei päässyt käsiksi. Tarkista käyttöoikeudet kohdasta Asetukset > Safari > Kamera.
noCameraFound: En löytänyt kameraa.
safariSupportOnly: Käytä iOS:ssä Safari-selainta.

View File

@ -14,4 +14,7 @@ couldNotFindQrCode: Impossible de trouver le QR Code dans le fichier fourni
invalidQrCode: QR Code non valide
certificateType: Aucun type de certificat valide n'a été trouvé
invalidTestResult: Résultat du test non valide
invalidTestType: Type de test non valide
invalidTestType: Type de test non valide
noCameraAccess: Impossible d'accéder à la caméra. Vérifiez les autorisations sous Paramètres > Safari > Appareil photo.
noCameraFound: Impossible de trouver la caméra.
safariSupportOnly: Sur iOS, veuillez utiliser le navigateur Safari.

View File

@ -14,4 +14,7 @@ couldNotFindQrCode: Kon de QR-code niet vinden in het verstrekte bestand
invalidQrCode: Ongeldige QR-code
certificateType: Geen geldig certificaattype gevonden
invalidTestResult: Ongeldig testresultaat
invalidTestType: Ongeldig testtype
invalidTestType: Ongeldig testtype
noCameraAccess: Kon geen toegang krijgen tot de camera. Controleer de machtigingen onder Instellingen > Safari > Camera.
noCameraFound: Ik kon de camera niet vinden.
safariSupportOnly: Gebruik op iOS de Safari-browser.

View File

@ -2,7 +2,7 @@ import {ValueSets} from "./value_sets";
import {Constants} from "./constants";
enum CertificateType {
Vaccination = 'Vaccination',
Vaccine = 'Vaccine',
Test = 'Test',
Recovery = 'Recovery',
}
@ -63,25 +63,35 @@ export class Payload {
throw new Error('certificateData');
}
// Get name and date of birth information
// Get name information
const nameInformation = covidCertificate['nam'];
const dateOfBirthInformation = covidCertificate['dob'];
if (nameInformation == undefined) {
throw new Error('nameMissing');
}
if (dateOfBirthInformation == undefined) {
throw new Error('dobMissing');
}
const name = `${nameInformation['fn']}, ${nameInformation['gn']}`;
const dateOfBirth = dateOfBirthInformation;
const firstName = nameInformation['gn'];
const lastName = nameInformation['fn'];
const transliteratedFirstName = nameInformation['gnt'].replaceAll('<', ' ');
const transliteratedLastName = nameInformation['fnt'].replaceAll('<', ' ');
// Check if name contains non-latin characters
const nameRegex = new RegExp('^[\\p{Script=Latin}\\p{P}\\p{M}\\p{Z}]+$', 'u');
let name: string;
if (nameRegex.test(firstName) && nameRegex.test(lastName)) {
name = `${firstName} ${lastName}`;
} else {
name = `${transliteratedFirstName} ${transliteratedLastName}`;
}
let properties: object;
// Set certificate type and properties
if (covidCertificate['v'] !== undefined) {
this.certificateType = CertificateType.Vaccination;
this.certificateType = CertificateType.Vaccine;
properties = covidCertificate['v'][0];
}
if (covidCertificate['t'] !== undefined) {
@ -96,23 +106,16 @@ export class Payload {
throw new Error('certificateType')
}
// Get country code, identifier and issuer
const countryCode = properties['co'];
// Get identifier and issuer
const uvci = properties['ci'];
const certificateIssuer = properties['is'];
if (!(countryCode in valueSets.countryCodes)) {
throw new Error('invalidCountryCode');
}
const country = valueSets.countryCodes[countryCode].display;
const generic: PassDictionary = {
headerFields: [
{
key: "type",
label: "Certificate Type",
value: this.certificateType
label: "EU Digital COVID",
value: this.certificateType + " Certificate"
}
],
primaryFields: [
@ -123,14 +126,7 @@ export class Payload {
}
],
secondaryFields: [],
auxiliaryFields: [
{
key: "dob",
label: "Date of Birth",
value: dateOfBirth,
textAlignment: TextAlignment.right
}
],
auxiliaryFields: [],
backFields: [
{
key: "uvci",
@ -141,11 +137,6 @@ export class Payload {
key: "issuer",
label: "Certificate Issuer",
value: certificateIssuer
},
{
key: "country",
label: "Country",
value: country
}
]
}
@ -164,8 +155,17 @@ export class Payload {
}
static fillPassData(type: CertificateType, data: PassDictionary, properties: Object, valueSets: ValueSets): PassDictionary {
// Get country name
const countryCode = properties['co'];
if (!(countryCode in valueSets.countryCodes)) {
throw new Error('invalidCountryCode');
}
const country = valueSets.countryCodes[countryCode].display;
switch (type) {
case CertificateType.Vaccination:
case CertificateType.Vaccine:
const dose = `${properties['dn']}/${properties['sd']}`;
const dateOfVaccination = properties['dt'];
const medialProductKey = properties['mp'];
@ -178,7 +178,7 @@ export class Payload {
throw new Error('invalidManufacturer')
}
const vaccineName = valueSets.medicalProducts[medialProductKey].display;
const vaccineName = valueSets.medicalProducts[medialProductKey].display.replace(/\s*\([^)]*\)\s*/g, "");
const manufacturer = valueSets.manufacturers[manufacturerKey].display;
data.secondaryFields.push(...[
@ -194,11 +194,19 @@ export class Payload {
textAlignment: TextAlignment.right
}
]);
data.auxiliaryFields.splice(0, 0, {
key: "vaccine",
label: "Vaccine",
value: vaccineName
});
data.auxiliaryFields.push(...[
{
key: "vaccine",
label: "Vaccine",
value: vaccineName
},
{
key: "cov",
label: "Country of Vaccination",
value: country,
textAlignment: TextAlignment.right
}
]);
data.backFields.push(...[
{
key: "manufacturer",
@ -234,7 +242,7 @@ export class Payload {
data.secondaryFields.push(...[
{
key: "result",
label: "Result",
label: "Test Result",
value: testResult
},
{
@ -244,7 +252,6 @@ export class Payload {
textAlignment: TextAlignment.right
}
]);
data.auxiliaryFields.pop();
data.auxiliaryFields.push(...[
{
key: "test",
@ -258,6 +265,11 @@ export class Payload {
textAlignment: TextAlignment.right
},
]);
data.backFields.push({
key: "cot",
label: "Country of Test",
value: country
});
if (testingCentre !== undefined)
data.backFields.push({
key: "centre",
@ -276,29 +288,28 @@ export class Payload {
const validUntil = properties['du'];
data.secondaryFields.push(...[
{
key: "result",
label: "Test Result",
value: "Detected"
},
{
key: "from",
label: "Valid From",
value: validFrom,
},
{
key: "dov",
label: "Date of positive Test",
value: firstPositiveTestDate,
textAlignment: TextAlignment.right
}
]);
data.auxiliaryFields.pop();
data.auxiliaryFields.push(...[
{
key: "testdate",
label: "Test Date",
value: firstPositiveTestDate
},
{
key: "until",
label: "Valid Until",
value: validUntil,
},
{
key: "cov",
label: "Country of Test",
value: country,
textAlignment: TextAlignment.right
},
]);