Fixed zip creation Bug

- Using do-not-zip
- Added loading Animation while creating pass
This commit is contained in:
Hauke Tönjes 2021-07-01 01:27:17 +02:00
parent 0aa4e32469
commit 98b01068d2
No known key found for this signature in database
GPG Key ID: 0BF2BC96C9FAAE9E
3 changed files with 39 additions and 49 deletions

View File

@ -21,6 +21,7 @@ function Form(): JSX.Element {
const [file, setFile] = useState<File>(undefined); const [file, setFile] = useState<File>(undefined);
const [errorMessage, setErrorMessage] = useState<string>(undefined); const [errorMessage, setErrorMessage] = useState<string>(undefined);
const [loading, setLoading] = useState<boolean>(false);
// File Input ref // File Input ref
const inputFile = useRef<HTMLInputElement>(undefined) const inputFile = useRef<HTMLInputElement>(undefined)
@ -88,9 +89,11 @@ function Form(): JSX.Element {
// Add Pass to wallet // Add Pass to wallet
async function addToWallet(event: FormEvent<HTMLFormElement>) { async function addToWallet(event: FormEvent<HTMLFormElement>) {
event.preventDefault(); event.preventDefault();
setLoading(true);
if (!file && !qrCode) { if (!file && !qrCode) {
setErrorMessage("Please scan a QR Code, or select a file to scan") setErrorMessage("Please scan a QR Code, or select a file to scan")
setLoading(false);
return; return;
} }
@ -108,8 +111,10 @@ function Form(): JSX.Element {
const passBlob = new Blob([pass], {type: "application/vnd.apple.pkpass"}); const passBlob = new Blob([pass], {type: "application/vnd.apple.pkpass"});
saveAs(passBlob, 'covid.pkpass'); saveAs(passBlob, 'covid.pkpass');
setLoading(false);
} catch (e) { } catch (e) {
setErrorMessage(e.toString()); setErrorMessage(e.toString());
setLoading(false);
} }
} }
@ -210,7 +215,7 @@ function Form(): JSX.Element {
className="focus:outline-none bg-green-600 py-2 px-3 text-white font-semibold rounded-md disabled:bg-gray-400"> className="focus:outline-none bg-green-600 py-2 px-3 text-white font-semibold rounded-md disabled:bg-gray-400">
Add to Wallet Add to Wallet
</button> </button>
<div id="spin" style={{"display": "none"}}> <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-2" viewBox="0 0 24 24">
<circle className="opacity-0" cx="12" cy="12" r="10" stroke="currentColor" <circle className="opacity-0" cx="12" cy="12" r="10" stroke="currentColor"
strokeWidth="4"/> strokeWidth="4"/>

View File

@ -6,60 +6,50 @@ const zlib = require('pako')
const cbor = require('cbor-js') const cbor = require('cbor-js')
export function typedArrayToBufferSliced(array) { export function typedArrayToBufferSliced(array) {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset) return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
} }
export function typedArrayToBuffer(array) { export function typedArrayToBuffer(array) {
var buffer = new ArrayBuffer(array.length) var buffer = new ArrayBuffer(array.length)
array.map(function(value, i) { array.map(function (value, i) {
buffer[i] = value buffer[i] = value
}) })
return array.buffer return array.buffer
}
export function toBuffer(ab) {
var buf = Buffer.alloc(ab.byteLength)
var view = new Uint8Array(ab)
for (var i = 0; i < buf.length; ++i) {
buf[i] = view[i]
}
return buf
} }
export function decodeData(data) { export function decodeData(data) {
data = data.toString('ASCII') data = data.toString('ASCII')
if (data.startsWith('HC1')) { if (data.startsWith('HC1')) {
data = data.substring(3) data = data.substring(3)
if (data.startsWith(':')) { if (data.startsWith(':')) {
data = data.substring(1) data = data.substring(1)
} else {
console.log("Warning: unsafe HC1: header - update to v0.0.4")
}
} else { } else {
console.log("Warning: unsafe HC1: header - update to v0.0.4") console.log("Warning: no HC1: header - update to v0.0.4")
} }
} else {
console.log("Warning: no HC1: header - update to v0.0.4")
}
data = base45.decode(data) data = base45.decode(data)
if (data[0] == 0x78) { if (data[0] == 0x78) {
data = zlib.inflate(data) data = zlib.inflate(data)
} }
data = cbor.decode(typedArrayToBuffer(data)) data = cbor.decode(typedArrayToBuffer(data))
if (!Array.isArray(data)) { if (!Array.isArray(data)) {
throw new Error('Expecting Array') throw new Error('Expecting Array')
} }
if (data.length !== 4) { if (data.length !== 4) {
throw new Error('Expecting Array of length 4') throw new Error('Expecting Array of length 4')
} }
let plaintext = data[2] let plaintext = data[2]
let decoded = cbor.decode(typedArrayToBufferSliced(plaintext)) let decoded = cbor.decode(typedArrayToBufferSliced(plaintext))
return decoded return decoded
} }

View File

@ -1,7 +1,7 @@
import {Constants} from "./constants"; import {Constants} from "./constants";
import {Payload, PayloadBody} from "./payload"; import {Payload, PayloadBody} from "./payload";
import {ValueSets} from "./value_sets"; import {ValueSets} from "./value_sets";
import {toBuffer} from "./decode"; import {toBuffer as createZip} from 'do-not-zip';
const crypto = require('crypto') const crypto = require('crypto')
@ -34,11 +34,6 @@ interface GenericFields {
backFields: Array<Field>; backFields: Array<Field>;
} }
interface ZipData {
path: string;
data: Buffer;
}
interface SignData { interface SignData {
PassJsonHash: string; PassJsonHash: string;
useBlackVersion: boolean; useBlackVersion: boolean;
@ -62,7 +57,7 @@ export class PassData {
generic: GenericFields; generic: GenericFields;
// Generates a sha1 hash from a given buffer // Generates a sha1 hash from a given buffer
private static getBufferHash(buffer: Buffer): string { private static getBufferHash(buffer: Buffer | string): string {
const sha = crypto.createHash('sha1'); const sha = crypto.createHash('sha1');
sha.update(buffer); sha.update(buffer);
return sha.digest('hex'); return sha.digest('hex');
@ -107,7 +102,7 @@ export class PassData {
const pass: PassData = new PassData(payload, qrCode); const pass: PassData = new PassData(payload, qrCode);
// Create new zip // Create new zip
const zip: Array<ZipData> = []; const zip = [] as { path: string; data: Buffer | string }[];
// Adding required fields // Adding required fields
@ -150,7 +145,7 @@ export class PassData {
// Add signature to zip // Add signature to zip
zip.push({path: 'signature', data: Buffer.from(manifestSignature)}); zip.push({path: 'signature', data: Buffer.from(manifestSignature)});
return toBuffer(zip); return createZip(zip);
} }
private constructor(payload: Payload, qrCode: QrCode) { private constructor(payload: Payload, qrCode: QrCode) {