Comparing version 1.0.0 to 1.1.0
@@ -9,4 +9,2 @@ export declare class ValueError extends Error { | ||
} | ||
export declare class UnsignedMetadataError extends RepositoryError { | ||
} | ||
export declare class BadVersionError extends RepositoryError { | ||
@@ -18,8 +16,2 @@ } | ||
} | ||
export declare class LengthOrHashMismatchError extends RepositoryError { | ||
} | ||
export declare class CryptoError extends Error { | ||
} | ||
export declare class UnsupportedAlgorithmError extends CryptoError { | ||
} | ||
export declare class DownloadError extends Error { | ||
@@ -26,0 +18,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DownloadHTTPError = exports.DownloadLengthMismatchError = exports.DownloadError = exports.UnsupportedAlgorithmError = exports.CryptoError = exports.LengthOrHashMismatchError = exports.ExpiredMetadataError = exports.EqualVersionError = exports.BadVersionError = exports.UnsignedMetadataError = exports.RepositoryError = exports.PersistError = exports.RuntimeError = exports.ValueError = void 0; | ||
exports.DownloadHTTPError = exports.DownloadLengthMismatchError = exports.DownloadError = exports.ExpiredMetadataError = exports.EqualVersionError = exports.BadVersionError = exports.RepositoryError = exports.PersistError = exports.RuntimeError = exports.ValueError = void 0; | ||
// An error about insufficient values | ||
@@ -20,6 +20,2 @@ class ValueError extends Error { | ||
exports.RepositoryError = RepositoryError; | ||
// An error about metadata object with insufficient threshold of signatures. | ||
class UnsignedMetadataError extends RepositoryError { | ||
} | ||
exports.UnsignedMetadataError = UnsignedMetadataError; | ||
// An error for metadata that contains an invalid version number. | ||
@@ -37,12 +33,2 @@ class BadVersionError extends RepositoryError { | ||
exports.ExpiredMetadataError = ExpiredMetadataError; | ||
// An error while checking the length and hash values of an object. | ||
class LengthOrHashMismatchError extends RepositoryError { | ||
} | ||
exports.LengthOrHashMismatchError = LengthOrHashMismatchError; | ||
class CryptoError extends Error { | ||
} | ||
exports.CryptoError = CryptoError; | ||
class UnsupportedAlgorithmError extends CryptoError { | ||
} | ||
exports.UnsupportedAlgorithmError = UnsupportedAlgorithmError; | ||
//----- Download Errors ------------------------------------------------------- | ||
@@ -49,0 +35,0 @@ // An error occurred while attempting to download a file. |
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
type DownloadFileHandler<T> = (file: string) => Promise<T>; | ||
export declare abstract class BaseFetcher { | ||
export interface Fetcher { | ||
downloadFile<T>(url: string, maxLength: number, handler: DownloadFileHandler<T>): Promise<T>; | ||
downloadBytes(url: string, maxLength: number): Promise<Buffer>; | ||
} | ||
export declare abstract class BaseFetcher implements Fetcher { | ||
abstract fetch(url: string): Promise<NodeJS.ReadableStream>; | ||
@@ -13,3 +17,3 @@ downloadFile<T>(url: string, maxLength: number, handler: DownloadFileHandler<T>): Promise<T>; | ||
} | ||
export declare class Fetcher extends BaseFetcher { | ||
export declare class DefaultFetcher extends BaseFetcher { | ||
private timeout?; | ||
@@ -16,0 +20,0 @@ private retries?; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Fetcher = exports.BaseFetcher = void 0; | ||
exports.DefaultFetcher = exports.BaseFetcher = void 0; | ||
const fs_1 = __importDefault(require("fs")); | ||
@@ -55,3 +55,3 @@ const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); | ||
exports.BaseFetcher = BaseFetcher; | ||
class Fetcher extends BaseFetcher { | ||
class DefaultFetcher extends BaseFetcher { | ||
constructor(options = {}) { | ||
@@ -73,3 +73,3 @@ super(); | ||
} | ||
exports.Fetcher = Fetcher; | ||
exports.DefaultFetcher = DefaultFetcher; | ||
const writeBufferToStream = async (stream, buffer) => { | ||
@@ -76,0 +76,0 @@ return new Promise((resolve, reject) => { |
@@ -1,3 +0,2 @@ | ||
export { BaseFetcher } from './fetcher'; | ||
export { TargetFile } from './models/file'; | ||
export { BaseFetcher, Fetcher } from './fetcher'; | ||
export { Updater } from './updater'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Updater = exports.TargetFile = exports.BaseFetcher = void 0; | ||
exports.Updater = exports.BaseFetcher = void 0; | ||
var fetcher_1 = require("./fetcher"); | ||
Object.defineProperty(exports, "BaseFetcher", { enumerable: true, get: function () { return fetcher_1.BaseFetcher; } }); | ||
var file_1 = require("./models/file"); | ||
Object.defineProperty(exports, "TargetFile", { enumerable: true, get: function () { return file_1.TargetFile; } }); | ||
var updater_1 = require("./updater"); | ||
Object.defineProperty(exports, "Updater", { enumerable: true, get: function () { return updater_1.Updater; } }); |
/// <reference types="node" /> | ||
import { Metadata, Root, Snapshot, Targets, Timestamp } from './models'; | ||
import { Metadata, Root, Snapshot, Targets, Timestamp } from '@tufjs/models'; | ||
export declare class TrustedMetadataStore { | ||
@@ -4,0 +4,0 @@ private trustedSet; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TrustedMetadataStore = void 0; | ||
const models_1 = require("@tufjs/models"); | ||
const error_1 = require("./error"); | ||
const models_1 = require("./models"); | ||
const types_1 = require("./utils/types"); | ||
class TrustedMetadataStore { | ||
@@ -35,8 +34,8 @@ constructor(rootData) { | ||
const data = JSON.parse(bytesBuffer.toString('utf8')); | ||
const newRoot = models_1.Metadata.fromJSON(types_1.MetadataKind.Root, data); | ||
if (newRoot.signed.type != types_1.MetadataKind.Root) { | ||
const newRoot = models_1.Metadata.fromJSON(models_1.MetadataKind.Root, data); | ||
if (newRoot.signed.type != models_1.MetadataKind.Root) { | ||
throw new error_1.RepositoryError(`Expected 'root', got ${newRoot.signed.type}`); | ||
} | ||
// Client workflow 5.4: check for arbitrary software attack | ||
this.root.verifyDelegate(types_1.MetadataKind.Root, newRoot); | ||
this.root.verifyDelegate(models_1.MetadataKind.Root, newRoot); | ||
// Client workflow 5.5: check for rollback attack | ||
@@ -47,3 +46,3 @@ if (newRoot.signed.version != this.root.signed.version + 1) { | ||
// Check that new root is signed by self | ||
newRoot.verifyDelegate(types_1.MetadataKind.Root, newRoot); | ||
newRoot.verifyDelegate(models_1.MetadataKind.Root, newRoot); | ||
// Client workflow 5.7: set new root as trusted root | ||
@@ -61,8 +60,8 @@ this.trustedSet.root = newRoot; | ||
const data = JSON.parse(bytesBuffer.toString('utf8')); | ||
const newTimestamp = models_1.Metadata.fromJSON(types_1.MetadataKind.Timestamp, data); | ||
if (newTimestamp.signed.type != types_1.MetadataKind.Timestamp) { | ||
const newTimestamp = models_1.Metadata.fromJSON(models_1.MetadataKind.Timestamp, data); | ||
if (newTimestamp.signed.type != models_1.MetadataKind.Timestamp) { | ||
throw new error_1.RepositoryError(`Expected 'timestamp', got ${newTimestamp.signed.type}`); | ||
} | ||
// Client workflow 5.4.2: check for arbitrary software attack | ||
this.root.verifyDelegate(types_1.MetadataKind.Timestamp, newTimestamp); | ||
this.root.verifyDelegate(models_1.MetadataKind.Timestamp, newTimestamp); | ||
if (this.timestamp) { | ||
@@ -110,8 +109,8 @@ // Prevent rolling back timestamp version | ||
const data = JSON.parse(bytesBuffer.toString('utf8')); | ||
const newSnapshot = models_1.Metadata.fromJSON(types_1.MetadataKind.Snapshot, data); | ||
if (newSnapshot.signed.type != types_1.MetadataKind.Snapshot) { | ||
const newSnapshot = models_1.Metadata.fromJSON(models_1.MetadataKind.Snapshot, data); | ||
if (newSnapshot.signed.type != models_1.MetadataKind.Snapshot) { | ||
throw new error_1.RepositoryError(`Expected 'snapshot', got ${newSnapshot.signed.type}`); | ||
} | ||
// Client workflow 5.5.3: check for arbitrary software attack | ||
this.root.verifyDelegate(types_1.MetadataKind.Snapshot, newSnapshot); | ||
this.root.verifyDelegate(models_1.MetadataKind.Snapshot, newSnapshot); | ||
// version check against meta version (5.5.4) is deferred to allow old | ||
@@ -156,4 +155,4 @@ // snapshot to be used in rollback protection | ||
const data = JSON.parse(bytesBuffer.toString('utf8')); | ||
const newDelegate = models_1.Metadata.fromJSON(types_1.MetadataKind.Targets, data); | ||
if (newDelegate.signed.type != types_1.MetadataKind.Targets) { | ||
const newDelegate = models_1.Metadata.fromJSON(models_1.MetadataKind.Targets, data); | ||
if (newDelegate.signed.type != models_1.MetadataKind.Targets) { | ||
throw new error_1.RepositoryError(`Expected 'targets', got ${newDelegate.signed.type}`); | ||
@@ -178,7 +177,7 @@ } | ||
const data = JSON.parse(bytesBuffer.toString('utf8')); | ||
const root = models_1.Metadata.fromJSON(types_1.MetadataKind.Root, data); | ||
if (root.signed.type != types_1.MetadataKind.Root) { | ||
const root = models_1.Metadata.fromJSON(models_1.MetadataKind.Root, data); | ||
if (root.signed.type != models_1.MetadataKind.Root) { | ||
throw new error_1.RepositoryError(`Expected 'root', got ${root.signed.type}`); | ||
} | ||
root.verifyDelegate(types_1.MetadataKind.Root, root); | ||
root.verifyDelegate(models_1.MetadataKind.Root, root); | ||
this.trustedSet['root'] = root; | ||
@@ -185,0 +184,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import { BaseFetcher } from './fetcher'; | ||
import { TargetFile } from './models/file'; | ||
import { Config } from './utils/config'; | ||
import { TargetFile } from '@tufjs/models'; | ||
import { Config } from './config'; | ||
import { Fetcher } from './fetcher'; | ||
export interface UpdaterOptions { | ||
@@ -9,3 +9,3 @@ metadataDir: string; | ||
targetBaseUrl?: string; | ||
fetcher?: BaseFetcher; | ||
fetcher?: Fetcher; | ||
config?: Partial<Config>; | ||
@@ -12,0 +12,0 @@ } |
@@ -27,9 +27,9 @@ "use strict"; | ||
exports.Updater = void 0; | ||
const models_1 = require("@tufjs/models"); | ||
const fs = __importStar(require("fs")); | ||
const path = __importStar(require("path")); | ||
const config_1 = require("./config"); | ||
const error_1 = require("./error"); | ||
const fetcher_1 = require("./fetcher"); | ||
const store_1 = require("./store"); | ||
const config_1 = require("./utils/config"); | ||
const types_1 = require("./utils/types"); | ||
class Updater { | ||
@@ -42,3 +42,3 @@ constructor(options) { | ||
this.targetBaseUrl = targetBaseUrl; | ||
const data = this.loadLocalMetadata(types_1.MetadataKind.Root); | ||
const data = this.loadLocalMetadata(models_1.MetadataKind.Root); | ||
this.trustedSet = new store_1.TrustedMetadataStore(data); | ||
@@ -48,3 +48,3 @@ this.config = { ...config_1.defaultConfig, ...config }; | ||
fetcher || | ||
new fetcher_1.Fetcher({ | ||
new fetcher_1.DefaultFetcher({ | ||
timeout: this.config.fetchTimeout, | ||
@@ -58,3 +58,3 @@ retries: this.config.fetchRetries, | ||
await this.loadSnapshot(); | ||
await this.loadTargets(types_1.MetadataKind.Targets, types_1.MetadataKind.Root); | ||
await this.loadTargets(models_1.MetadataKind.Targets, models_1.MetadataKind.Root); | ||
} | ||
@@ -130,3 +130,3 @@ // Returns the TargetFile instance with information for the given target path. | ||
// Client workflow 5.3.8: persist root metadata file | ||
this.persistMetadata(types_1.MetadataKind.Root, bytesData); | ||
this.persistMetadata(models_1.MetadataKind.Root, bytesData); | ||
} | ||
@@ -143,3 +143,3 @@ catch (error) { | ||
try { | ||
const data = this.loadLocalMetadata(types_1.MetadataKind.Timestamp); | ||
const data = this.loadLocalMetadata(models_1.MetadataKind.Timestamp); | ||
this.trustedSet.updateTimestamp(data); | ||
@@ -168,3 +168,3 @@ } | ||
// Client workflow 5.4.5: persist timestamp metadata | ||
this.persistMetadata(types_1.MetadataKind.Timestamp, bytesData); | ||
this.persistMetadata(models_1.MetadataKind.Timestamp, bytesData); | ||
} | ||
@@ -176,3 +176,3 @@ // Load local and remote snapshot metadata. | ||
try { | ||
const data = this.loadLocalMetadata(types_1.MetadataKind.Snapshot); | ||
const data = this.loadLocalMetadata(models_1.MetadataKind.Snapshot); | ||
this.trustedSet.updateSnapshot(data, true); | ||
@@ -196,3 +196,3 @@ } | ||
// Client workflow 5.5.7: persist snapshot metadata file | ||
this.persistMetadata(types_1.MetadataKind.Snapshot, bytesData); | ||
this.persistMetadata(models_1.MetadataKind.Snapshot, bytesData); | ||
} | ||
@@ -248,4 +248,4 @@ catch (error) { | ||
{ | ||
roleName: types_1.MetadataKind.Targets, | ||
parentRoleName: types_1.MetadataKind.Root, | ||
roleName: models_1.MetadataKind.Targets, | ||
parentRoleName: models_1.MetadataKind.Root, | ||
}, | ||
@@ -252,0 +252,0 @@ ]; |
{ | ||
"name": "tuf-js", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "JavaScript implementation of The Update Framework (TUF)", | ||
@@ -8,13 +8,9 @@ "main": "dist/index.js", | ||
"scripts": { | ||
"build": "tsc", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"test:ci": "jest --maxWorkers=2 --coverage", | ||
"lint": "eslint --fix --ext .ts src/**", | ||
"lint:check": "eslint --max-warnings 0 --ext .ts src/**", | ||
"format": "prettier --write \"src/**/*\"" | ||
"build": "tsc --build", | ||
"clean": "rm -rf dist", | ||
"test": "jest" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/github/tuf-js.git" | ||
"url": "git+https://github.com/theupdateframework/tuf-js.git" | ||
}, | ||
@@ -25,3 +21,5 @@ "files": [ | ||
"keywords": [ | ||
"tuf" | ||
"tuf", | ||
"security", | ||
"update" | ||
], | ||
@@ -31,27 +29,15 @@ "author": "bdehamer@github.com", | ||
"bugs": { | ||
"url": "https://github.com/github/tuf-js/issues" | ||
"url": "https://github.com/theupdateframework/tuf-js/issues" | ||
}, | ||
"homepage": "https://github.com/github/tuf-js#readme", | ||
"homepage": "https://github.com/theupdateframework/tuf-js/packages/client#readme", | ||
"devDependencies": { | ||
"@tsconfig/node14": "^1.0.3", | ||
"@types/jest": "^28.1.8", | ||
"@types/lodash.isequal": "^4.5.6", | ||
"@tufjs/repo-mock": "1.0.0", | ||
"@types/make-fetch-happen": "^10.0.1", | ||
"@types/minimatch": "^5.1.2", | ||
"@types/node": "^18.11.10", | ||
"@typescript-eslint/eslint-plugin": "^5.45.0", | ||
"@typescript-eslint/parser": "^5.45.0", | ||
"eslint": "^8.28.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-prettier": "^4.2.1", | ||
"http-server": "^14.1.1", | ||
"jest": "^28.1.3", | ||
"@types/node": "^18.14.1", | ||
"nock": "^13.2.9", | ||
"prettier": "^2.8.0", | ||
"ts-jest": "^28.0.8", | ||
"typescript": "^4.9.3" | ||
"typescript": "^4.9.5" | ||
}, | ||
"dependencies": { | ||
"make-fetch-happen": "^11.0.1", | ||
"minimatch": "^6.1.0" | ||
"@tufjs/models": "1.0.0" | ||
}, | ||
@@ -58,0 +44,0 @@ "engines": { |
@@ -1,52 +0,3 @@ | ||
# <img src="https://cdn.rawgit.com/theupdateframework/artwork/3a649fa6/tuf-logo.svg" height="100" valign="middle" alt="TUF"/> A Framework for Securing Software Update Systems | ||
# tuf-js | ||
--- | ||
[The Update Framework (TUF)](https://theupdateframework.io/) is a framework for | ||
secure content delivery and updates. It protects against various types of | ||
supply chain attacks and provides resilience to compromise. This repository is written in Typescript. It is intended to conform to | ||
version 1.0 of the [TUF | ||
specification](https://theupdateframework.github.io/specification/latest/). | ||
## About The Update Framework | ||
The Update Framework (TUF) design helps developers maintain the security of a | ||
software update system, even against attackers that compromise the repository | ||
or signing keys. | ||
TUF provides a flexible | ||
[specification](https://github.com/theupdateframework/specification/blob/master/tuf-spec.md) | ||
defining functionality that developers can use in any software update system or | ||
re-implement to fit their needs. | ||
TUF is hosted by the [Linux Foundation](https://www.linuxfoundation.org/) as | ||
part of the [Cloud Native Computing Foundation](https://www.cncf.io/) (CNCF) | ||
and its design is [used in production](https://theupdateframework.io/adoptions/) | ||
by various tech companies and open source organizations. A variant of TUF | ||
called [Uptane](https://uptane.github.io/) is used to secure over-the-air | ||
updates in automobiles. | ||
Please see [TUF's website](https://theupdateframework.com/) for more information about TUF! | ||
## Documentation | ||
- [Introduction to TUF's Design](https://theupdateframework.io/overview/) | ||
- [The TUF Specification](https://theupdateframework.github.io/specification/latest/) | ||
- [Developer documentation](https://theupdateframework.readthedocs.io/), including | ||
[API reference](https://theupdateframework.readthedocs.io/en/latest/api/api-reference.html) | ||
- [Usage examples](https://github.com/github/tuf-js/tree/main/examples/client-example) | ||
## Requirements | ||
* node: ^14.17.0 || ^16.13.0 || >=18.0.0 | ||
## License | ||
This project is licensed under the terms of the MIT open source license. Please refer to [MIT](./LICENSE.md) for the full terms. | ||
## Code of Conduct | ||
Please note that this project is released with a [Contributor Code of Conduct](./CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. | ||
## Maintainers | ||
`tuf-js` is maintained by [@ejahnGithub](https://github.com/ejahnGithub) and [@bdehamer](https://github.com/bdehamer) on the Package Security team at GitHub. | ||
JavaScript TUF client implementation. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
5
0
37561
17
803
4
1
+ Added@tufjs/models@1.0.0
+ Added@tufjs/models@1.0.0(transitive)
- Removedminimatch@^6.1.0