diff --git a/src/ssn/getPatch.ts b/src/ssn/getPatch.ts index 8050396..482ee7e 100644 --- a/src/ssn/getPatch.ts +++ b/src/ssn/getPatch.ts @@ -1,10 +1,9 @@ import downloadUrlContents from '../cdn/downloadUrlContents'; import getUrlContents from '../cdn/getUrlContents'; import { Product } from '../interfaces/ISettings'; -import { SsnDiffType } from '../interfaces/ISsnFileEntry'; -import extractFile from './extractFile'; import getSolidpkg from './getSolidpkg'; import readSsnFile from './reader/readSsnFile'; +import verifyPatch from './verify/verifyPatch'; export default async function getPatch(product: Product, from: number, to: number) { const solidpkg = await getSolidpkg(product, from, to); @@ -24,12 +23,7 @@ export default async function getPatch(product: Product, from: number, to: numbe console.debug(fileEntries); //Verify file entries - if (from === -1) { - fileEntries.filter((file) => file.diffType !== SsnDiffType.NewFile).forEach((file) => { - throw new Error(`Patches from -1 must be included in full, but this patch had a file "${file.name}" with diff type ${file.diffType}.`); - }); - } - //TODO: last file must always be `${product}.version` with diff type. Other files depend on diffType. + verifyPatch(fileEntries, product, from); //Then we need to wait for other files before we can extract them await Promise.all(diskFiles); diff --git a/src/ssn/verify/verifyPatch.ts b/src/ssn/verify/verifyPatch.ts new file mode 100644 index 0000000..181c729 --- /dev/null +++ b/src/ssn/verify/verifyPatch.ts @@ -0,0 +1,28 @@ +import { Product } from '../../interfaces/ISettings'; +import { ISsnFileEntry } from '../../interfaces/ISsnFileEntry'; +import { SsnDiffType } from '../../interfaces/ISsnFileEntry'; + +/** Receives a list of file entries from the .zip file and checks them for correctness */ +export default function verifyPatch(fileEntries: ISsnFileEntry[], product: Product, from: number): void { + //There must be at least a .version file + if (fileEntries.length === 0) { + throw new Error('Expected at least a version file in the '); + } + + //Check that last file is the .version file with diffType 0. + const lastFile = fileEntries[fileEntries.length - 1]; + const validLastFileName = `${product}.version`; + if (lastFile.name !== validLastFileName) { + throw new Error(`Last file must be called "${validLastFileName}" but it was "${lastFile.name}".`); + } + if (lastFile.diffType !== SsnDiffType.NewFile) { + throw new Error(`Last file (.version file) must have diffType 0 but it had diffType ${lastFile.diffType}.`); + } + + //Patches from -1 must not have diff type NewFile + if (from === -1) { + fileEntries.filter((file) => file.diffType !== SsnDiffType.NewFile).forEach((file) => { + throw new Error(`Patches from -1 must be included in full, but this patch had a file "${file.name}" with diff type ${file.diffType}.`); + }); + } +} diff --git a/src/ssn/verify/verifyPatchmanifest.ts b/src/ssn/verify/verifyPatchmanifest.ts index 6ec9678..3bb7cf6 100644 --- a/src/ssn/verify/verifyPatchmanifest.ts +++ b/src/ssn/verify/verifyPatchmanifest.ts @@ -2,7 +2,7 @@ import * as xmlJs from 'xml-js'; import { Product } from '../../interfaces/ISettings'; /** Receives a JSON-converted version of the manifest.xml file, and verifies that all required elements and attributes are present, and nothing more */ -export default function verifyPatchmanifest(manifestFile: xmlJs.Element, product: Product): any { +export default function verifyPatchmanifest(manifestFile: xmlJs.Element, product: Product): void { // if (manifestFile.declaration === undefined || manifestFile.declaration.attributes === undefined || Object.keys(manifestFile.declaration.attributes).length !== 2 || manifestFile.declaration.attributes.version !== '1.0' || manifestFile.declaration.attributes.encoding !== 'utf-8') { throw new Error('Expected declaration with version 1.0 and utf-8 encoding.'); diff --git a/src/ssn/verify/verifySolidpkg.ts b/src/ssn/verify/verifySolidpkg.ts index 1f4dd54..84e2b9e 100644 --- a/src/ssn/verify/verifySolidpkg.ts +++ b/src/ssn/verify/verifySolidpkg.ts @@ -1,7 +1,7 @@ import ISolid from '../../interfaces/ISolidFile'; /** Verifies metafile.solid for correctness. See specification at . */ -export default function verifySolidpkg(file: ISolid, { product, from, to }: {product: string, from: number, to: number}) { +export default function verifySolidpkg(file: ISolid, { product, from, to }: {product: string, from: number, to: number}): void { if (typeof file['creation date'] !== 'number') { throw new Error(`Expected creation date to be a number but it was "${file['creation date']}".`); }