From 262e927fa3c68e2a2bf3f9adcffecd7a9807941c Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Thu, 9 May 2024 15:33:42 -0700 Subject: [PATCH] deps: @sigstore/sign@2.3.1 --- DEPENDENCIES.md | 3 + .../@sigstore/sign/dist/external/error.js | 44 +++------ .../@sigstore/sign/dist/external/fetch.js | 99 +++++++++++++++++++ .../@sigstore/sign/dist/external/fulcio.js | 30 ++---- .../@sigstore/sign/dist/external/rekor.js | 77 ++++----------- .../@sigstore/sign/dist/external/tsa.js | 27 ++--- node_modules/@sigstore/sign/package.json | 11 ++- package-lock.json | 10 +- 8 files changed, 171 insertions(+), 130 deletions(-) create mode 100644 node_modules/@sigstore/sign/dist/external/fetch.js diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index e9b9f575c7cb7..3445abb1f4396 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -533,6 +533,7 @@ graph LR; npm-->remark; npm-->rimraf; npm-->semver; + npm-->sigstore-sign["@sigstore/sign"]; npm-->sigstore-tuf["@sigstore/tuf"]; npm-->spawk; npm-->spdx-expression-parse; @@ -737,6 +738,8 @@ graph LR; sigstore-->sigstore-verify["@sigstore/verify"]; sigstore-bundle-->sigstore-protobuf-specs["@sigstore/protobuf-specs"]; sigstore-sign-->make-fetch-happen; + sigstore-sign-->proc-log; + sigstore-sign-->promise-retry; sigstore-sign-->sigstore-bundle["@sigstore/bundle"]; sigstore-sign-->sigstore-core["@sigstore/core"]; sigstore-sign-->sigstore-protobuf-specs["@sigstore/protobuf-specs"]; diff --git a/node_modules/@sigstore/sign/dist/external/error.js b/node_modules/@sigstore/sign/dist/external/error.js index 0dad92ea69414..a6a65adebb176 100644 --- a/node_modules/@sigstore/sign/dist/external/error.js +++ b/node_modules/@sigstore/sign/dist/external/error.js @@ -1,6 +1,21 @@ "use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ Object.defineProperty(exports, "__esModule", { value: true }); -exports.checkStatus = exports.HTTPError = void 0; +exports.HTTPError = void 0; class HTTPError extends Error { constructor({ status, message, location, }) { super(`(${status}) ${message}`); @@ -9,30 +24,3 @@ class HTTPError extends Error { } } exports.HTTPError = HTTPError; -const checkStatus = async (response) => { - if (response.ok) { - return response; - } - else { - let message = response.statusText; - const location = response.headers?.get('Location') || undefined; - const contentType = response.headers?.get('Content-Type'); - // If response type is JSON, try to parse the body for a message - if (contentType?.includes('application/json')) { - try { - await response.json().then((body) => { - message = body.message; - }); - } - catch (e) { - // ignore - } - } - throw new HTTPError({ - status: response.status, - message: message, - location: location, - }); - } -}; -exports.checkStatus = checkStatus; diff --git a/node_modules/@sigstore/sign/dist/external/fetch.js b/node_modules/@sigstore/sign/dist/external/fetch.js new file mode 100644 index 0000000000000..b2d81bde7be16 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/external/fetch.js @@ -0,0 +1,99 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fetchWithRetry = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const http2_1 = require("http2"); +const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); +const proc_log_1 = require("proc-log"); +const promise_retry_1 = __importDefault(require("promise-retry")); +const util_1 = require("../util"); +const error_1 = require("./error"); +const { HTTP2_HEADER_LOCATION, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_USER_AGENT, HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_REQUEST_TIMEOUT, } = http2_1.constants; +async function fetchWithRetry(url, options) { + return (0, promise_retry_1.default)(async (retry, attemptNum) => { + const method = options.method || 'POST'; + const headers = { + [HTTP2_HEADER_USER_AGENT]: util_1.ua.getUserAgent(), + ...options.headers, + }; + const response = await (0, make_fetch_happen_1.default)(url, { + method, + headers, + body: options.body, + timeout: options.timeout, + retry: false, // We're handling retries ourselves + }).catch((reason) => { + proc_log_1.log.http('fetch', `${method} ${url} attempt ${attemptNum} failed with ${reason}`); + return retry(reason); + }); + if (response.ok) { + return response; + } + else { + const error = await errorFromResponse(response); + proc_log_1.log.http('fetch', `${method} ${url} attempt ${attemptNum} failed with ${response.status}`); + if (retryable(response.status)) { + return retry(error); + } + else { + throw error; + } + } + }, retryOpts(options.retry)); +} +exports.fetchWithRetry = fetchWithRetry; +// Translate a Response into an HTTPError instance. This will attempt to parse +// the response body for a message, but will default to the statusText if none +// is found. +const errorFromResponse = async (response) => { + let message = response.statusText; + const location = response.headers?.get(HTTP2_HEADER_LOCATION) || undefined; + const contentType = response.headers?.get(HTTP2_HEADER_CONTENT_TYPE); + // If response type is JSON, try to parse the body for a message + if (contentType?.includes('application/json')) { + try { + const body = await response.json(); + message = body.message || message; + } + catch (e) { + // ignore + } + } + return new error_1.HTTPError({ + status: response.status, + message: message, + location: location, + }); +}; +// Determine if a status code is retryable. This includes 5xx errors, 408, and +// 429. +const retryable = (status) => [HTTP_STATUS_REQUEST_TIMEOUT, HTTP_STATUS_TOO_MANY_REQUESTS].includes(status) || status >= HTTP_STATUS_INTERNAL_SERVER_ERROR; +// Normalize the retry options to the format expected by promise-retry +const retryOpts = (retry) => { + if (typeof retry === 'boolean') { + return { retries: retry ? 1 : 0 }; + } + else if (typeof retry === 'number') { + return { retries: retry }; + } + else { + return { retries: 0, ...retry }; + } +}; diff --git a/node_modules/@sigstore/sign/dist/external/fulcio.js b/node_modules/@sigstore/sign/dist/external/fulcio.js index f00b62e147cd7..de6a1ad9f9e79 100644 --- a/node_modules/@sigstore/sign/dist/external/fulcio.js +++ b/node_modules/@sigstore/sign/dist/external/fulcio.js @@ -1,7 +1,4 @@ "use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", { value: true }); exports.Fulcio = void 0; /* @@ -19,33 +16,26 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); -const util_1 = require("../util"); -const error_1 = require("./error"); +const fetch_1 = require("./fetch"); /** * Fulcio API client. */ class Fulcio { constructor(options) { - this.fetch = make_fetch_happen_1.default.defaults({ - retry: options.retry, - timeout: options.timeout, + this.options = options; + } + async createSigningCertificate(request) { + const { baseURL, retry, timeout } = this.options; + const url = `${baseURL}/api/v2/signingCert`; + const response = await (0, fetch_1.fetchWithRetry)(url, { headers: { 'Content-Type': 'application/json', - 'User-Agent': util_1.ua.getUserAgent(), }, - }); - this.baseUrl = options.baseURL; - } - async createSigningCertificate(request) { - const url = `${this.baseUrl}/api/v2/signingCert`; - const response = await this.fetch(url, { - method: 'POST', body: JSON.stringify(request), + timeout, + retry, }); - await (0, error_1.checkStatus)(response); - const data = await response.json(); - return data; + return response.json(); } } exports.Fulcio = Fulcio; diff --git a/node_modules/@sigstore/sign/dist/external/rekor.js b/node_modules/@sigstore/sign/dist/external/rekor.js index 6f6cb96cc9c5c..bb59a126e032f 100644 --- a/node_modules/@sigstore/sign/dist/external/rekor.js +++ b/node_modules/@sigstore/sign/dist/external/rekor.js @@ -1,7 +1,4 @@ "use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", { value: true }); exports.Rekor = void 0; /* @@ -19,23 +16,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); -const util_1 = require("../util"); -const error_1 = require("./error"); +const fetch_1 = require("./fetch"); /** * Rekor API client. */ class Rekor { constructor(options) { - this.fetch = make_fetch_happen_1.default.defaults({ - retry: options.retry, - timeout: options.timeout, - headers: { - Accept: 'application/json', - 'User-Agent': util_1.ua.getUserAgent(), - }, - }); - this.baseUrl = options.baseURL; + this.options = options; } /** * Create a new entry in the Rekor log. @@ -43,13 +30,17 @@ class Rekor { * @returns {Promise} The created entry */ async createEntry(propsedEntry) { - const url = `${this.baseUrl}/api/v1/log/entries`; - const response = await this.fetch(url, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, + const { baseURL, timeout, retry } = this.options; + const url = `${baseURL}/api/v1/log/entries`; + const response = await (0, fetch_1.fetchWithRetry)(url, { + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, body: JSON.stringify(propsedEntry), + timeout, + retry, }); - await (0, error_1.checkStatus)(response); const data = await response.json(); return entryFromResponse(data); } @@ -59,44 +50,18 @@ class Rekor { * @returns {Promise} The retrieved entry */ async getEntry(uuid) { - const url = `${this.baseUrl}/api/v1/log/entries/${uuid}`; - const response = await this.fetch(url); - await (0, error_1.checkStatus)(response); - const data = await response.json(); - return entryFromResponse(data); - } - /** - * Search the Rekor log index for entries matching the given query. - * @param opts {SearchIndex} Options to search the Rekor log - * @returns {Promise} UUIDs of matching entries - */ - async searchIndex(opts) { - const url = `${this.baseUrl}/api/v1/index/retrieve`; - const response = await this.fetch(url, { - method: 'POST', - body: JSON.stringify(opts), - headers: { 'Content-Type': 'application/json' }, + const { baseURL, timeout, retry } = this.options; + const url = `${baseURL}/api/v1/log/entries/${uuid}`; + const response = await (0, fetch_1.fetchWithRetry)(url, { + method: 'GET', + headers: { + Accept: 'application/json', + }, + timeout, + retry, }); - await (0, error_1.checkStatus)(response); const data = await response.json(); - return data; - } - /** - * Search the Rekor logs for matching the given query. - * @param opts {SearchLogQuery} Query to search the Rekor log - * @returns {Promise} List of matching entries - */ - async searchLog(opts) { - const url = `${this.baseUrl}/api/v1/log/entries/retrieve`; - const response = await this.fetch(url, { - method: 'POST', - body: JSON.stringify(opts), - headers: { 'Content-Type': 'application/json' }, - }); - await (0, error_1.checkStatus)(response); - const rawData = await response.json(); - const data = rawData.map((d) => entryFromResponse(d)); - return data; + return entryFromResponse(data); } } exports.Rekor = Rekor; diff --git a/node_modules/@sigstore/sign/dist/external/tsa.js b/node_modules/@sigstore/sign/dist/external/tsa.js index 252c14f2d32d8..a948ba9cca2c7 100644 --- a/node_modules/@sigstore/sign/dist/external/tsa.js +++ b/node_modules/@sigstore/sign/dist/external/tsa.js @@ -1,7 +1,4 @@ "use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", { value: true }); exports.TimestampAuthority = void 0; /* @@ -19,28 +16,22 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); -const util_1 = require("../util"); -const error_1 = require("./error"); +const fetch_1 = require("./fetch"); class TimestampAuthority { constructor(options) { - this.fetch = make_fetch_happen_1.default.defaults({ - retry: options.retry, - timeout: options.timeout, + this.options = options; + } + async createTimestamp(request) { + const { baseURL, timeout, retry } = this.options; + const url = `${baseURL}/api/v1/timestamp`; + const response = await (0, fetch_1.fetchWithRetry)(url, { headers: { 'Content-Type': 'application/json', - 'User-Agent': util_1.ua.getUserAgent(), }, - }); - this.baseUrl = options.baseURL; - } - async createTimestamp(request) { - const url = `${this.baseUrl}/api/v1/timestamp`; - const response = await this.fetch(url, { - method: 'POST', body: JSON.stringify(request), + timeout, + retry, }); - await (0, error_1.checkStatus)(response); return response.buffer(); } } diff --git a/node_modules/@sigstore/sign/package.json b/node_modules/@sigstore/sign/package.json index 09eea0a39e877..47d8fed2e6ab3 100644 --- a/node_modules/@sigstore/sign/package.json +++ b/node_modules/@sigstore/sign/package.json @@ -1,6 +1,6 @@ { "name": "@sigstore/sign", - "version": "2.3.0", + "version": "2.3.1", "description": "Sigstore signing library", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -27,15 +27,18 @@ }, "devDependencies": { "@sigstore/jest": "^0.0.0", - "@sigstore/mock": "^0.7.0", + "@sigstore/mock": "^0.7.3", "@sigstore/rekor-types": "^2.0.0", - "@types/make-fetch-happen": "^10.0.4" + "@types/make-fetch-happen": "^10.0.4", + "@types/promise-retry": "^1.1.6" }, "dependencies": { "@sigstore/bundle": "^2.3.0", "@sigstore/core": "^1.0.0", "@sigstore/protobuf-specs": "^0.3.1", - "make-fetch-happen": "^13.0.0" + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/package-lock.json b/package-lock.json index c91ff5d22ce3d..e227122e41c66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2010,15 +2010,17 @@ } }, "node_modules/@sigstore/sign": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.0.tgz", - "integrity": "sha512-tsAyV6FC3R3pHmKS880IXcDJuiFJiKITO1jxR1qbplcsBkZLBmjrEw5GbC7ikD6f5RU1hr7WnmxB/2kKc1qUWQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.1.tgz", + "integrity": "sha512-YZ71wKIOweC8ViUeZXboz0iPLqMkskxuoeN/D1CEpAyZvEepbX9oRMIoO6a/DxUqO1VEaqmcmmqzSiqtOsvSmw==", "inBundle": true, "dependencies": { "@sigstore/bundle": "^2.3.0", "@sigstore/core": "^1.0.0", "@sigstore/protobuf-specs": "^0.3.1", - "make-fetch-happen": "^13.0.0" + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" }, "engines": { "node": "^16.14.0 || >=18.0.0"