Skip to content

Commit a0b54bf

Browse files
committed
base-acme-client.js
- add getNextNonce export - rename `newDirectoryAsync` to `newDirectory` (its still async) - rename `newNonceAsync` to `newNonce` (its still async) - changes to how errors/exceptions are returned - errors have `error.type` of `bac:failed:methodName` - exceptions have `error.type` of `bac:exception:methodName` - inside `error.details` is the message/exception - errors and exceptions from bac have an `error.status` of `777777` or similar
1 parent 5cbdb3d commit a0b54bf

File tree

4 files changed

+23
-68
lines changed

4 files changed

+23
-68
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ Fetch a resource with multiple retry attempts and progressive backoff.
485485
* @param {string|Request} fetchInput - The URL or Request object to fetch
486486
* @param {Object} init - optional fetch init object
487487
* @param {number} [attempts=6] - Maximum number of fetch attempts
488+
* @param {boolean} silent - true to suppress console output on failure attempt
488489
*
489490
* @returns {Promise<Response|undefined>} The response or undefined if all attempts fail
490491
*
@@ -504,7 +505,7 @@ Fetch a resource with multiple retry attempts and progressive backoff.
504505
* // Process successful response
505506
* }
506507
*/
507-
export async function fetchAndRetryUntilOk(fetchInput, init, attempts = 6) { /*...*/ }
508+
export async function fetchAndRetryUntilOk(fetchInput, init, attempts = 6, silent = false) { /*...*/ }
508509
```
509510

510511
</details>

base-acme-client.js

Lines changed: 18 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,7 @@ export async function createAccount(nonce, privateKey, jsonWebKey, acmeDirectory
120120
const response = await fetchAndRetryProtectedUntilOk(payload, protectedHeader, privateKey, acmeDirectory);
121121

122122
if (response) {
123-
if (response.ok) {
124-
return {
125-
answer: { account: await response.json(), location: response.headers.get(NEXT_URL) },
126-
nonce: response.headers.get(REPLAY_NONCE)
127-
};
128-
}
129-
else {
130-
return {
131-
answer: { error: await response.json() },
132-
nonce: await getNextNonce(response.headers, acmeDirectory)
133-
};
134-
}
123+
return await returnAnswer(response, acmeDirectory, 'account');
135124
}
136125

137126
return notCompletedError("createAccount");
@@ -171,18 +160,7 @@ export async function createOrder(kid, nonce, privateKey, identifiers, acmeDirec
171160
const response = await fetchAndRetryProtectedUntilOk(payload, protectedHeader, privateKey, acmeDirectory);
172161

173162
if (response) {
174-
if (response.ok) {
175-
return {
176-
answer: { order: await response.json(), location: response.headers.get(NEXT_URL) },
177-
nonce: response.headers.get(REPLAY_NONCE)
178-
};
179-
}
180-
else {
181-
return {
182-
answer: { error: await response.json() },
183-
nonce: await getNextNonce(response.headers, acmeDirectory)
184-
};
185-
}
163+
return returnAnswer(response, acmeDirectory, 'order');
186164
}
187165

188166
return notCompletedError("createOrder");
@@ -226,18 +204,7 @@ export async function finalizeOrder(commonName, kid, nonce, privateKey, publicKe
226204
const response = await fetchAndRetryProtectedUntilOk(payload, protectedHeader, privateKey, acmeDirectory);
227205

228206
if (response) {
229-
if (response.ok) {
230-
return {
231-
answer: { get: await response.json(), location: response.headers.get(NEXT_URL) },
232-
nonce: response.headers.get(REPLAY_NONCE)
233-
};
234-
}
235-
else {
236-
return {
237-
answer: { error: await response.json() },
238-
nonce: await getNextNonce(response.headers, acmeDirectory)
239-
};
240-
}
207+
return returnAnswer(response, acmeDirectory, 'get');
241208
}
242209

243210
return notCompletedError("finalizeOrder");
@@ -275,18 +242,7 @@ export async function postAsGet(kid, nonce, privateKey, url, acmeDirectory) {
275242
const response = await fetchAndRetryProtectedUntilOk(METHOD_POST_AS_GET, protectedHeader, privateKey, acmeDirectory);
276243

277244
if (response) {
278-
if (response.ok) {
279-
return {
280-
answer: { get: await response.json(), location: response.headers.get(NEXT_URL) },
281-
nonce: response.headers.get(REPLAY_NONCE)
282-
};
283-
}
284-
else {
285-
return {
286-
answer: { error: await response.json() },
287-
nonce: await getNextNonce(response.headers, acmeDirectory)
288-
};
289-
}
245+
return returnAnswer(response, acmeDirectory, 'get');
290246
}
291247

292248
return notCompletedError("postAsGet");
@@ -324,18 +280,7 @@ export async function postAsGetChal(kid, nonce, privateKey, url, acmeDirectory)
324280
const response = await fetchAndRetryProtectedUntilOk(METHOD_POST_AS_GET_CHALLENGE, protectedHeader, privateKey, acmeDirectory);
325281

326282
if (response) {
327-
if (response.ok) {
328-
return {
329-
answer: { get: await response.json(), location: response.headers.get(NEXT_URL) },
330-
nonce: response.headers.get(REPLAY_NONCE)
331-
};
332-
}
333-
else {
334-
return {
335-
answer: { error: await response.json() },
336-
nonce: await getNextNonce(response.headers, acmeDirectory)
337-
};
338-
}
283+
return returnAnswer(response, acmeDirectory, 'get');
339284
}
340285

341286
return notCompletedError("postAsGetChal");
@@ -506,7 +451,7 @@ export async function fetchSuggestedWindow(renewalInfoUrl, aki, serial) {
506451
try {
507452
const url = `${renewalInfoUrl}/${base64urlEncode(hexToBytes(aki))}.${base64urlEncode(hexToBytes(serial))}`;
508453

509-
const response = await fetchAndRetryUntilOk(url);
454+
const response = await fetchAndRetryUntilOk(url, null, 2, true);
510455

511456
if (response && response.ok) {
512457
return { answer: { get: await response.json() } }
@@ -525,7 +470,7 @@ export async function fetchSuggestedWindow(renewalInfoUrl, aki, serial) {
525470
* @param {string|Request} fetchInput - The URL or Request object to fetch
526471
* @param {Object} init - optional fetch init object
527472
* @param {number} [attempts=6] - Maximum number of fetch attempts
528-
*
473+
* @param {boolean} silent - true to suppress console output on failure attempt
529474
* @returns {Promise<Response|undefined>} The response or undefined if all attempts fail
530475
*
531476
* @description
@@ -544,7 +489,7 @@ export async function fetchSuggestedWindow(renewalInfoUrl, aki, serial) {
544489
* // Process successful response
545490
* }
546491
*/
547-
export async function fetchAndRetryUntilOk(fetchInput, init, attempts = 6) {
492+
export async function fetchAndRetryUntilOk(fetchInput, init, attempts = 6, silent = false) {
548493
let a = 1;
549494

550495
while (a <= attempts) {
@@ -560,7 +505,9 @@ export async function fetchAndRetryUntilOk(fetchInput, init, attempts = 6) {
560505
return response;
561506
}
562507

563-
console.error(a - 1, "attempt failed, trying again", fetchInput);
508+
if (!silent) {
509+
console.error(a - 1, "attempt failed, trying again", fetchInput);
510+
}
564511

565512
await new Promise((resolve) => setTimeout(() => { resolve(); }, 650 * a)); // Each failed attempt will delay itself slightly more
566513
} catch (exception) {
@@ -650,6 +597,13 @@ export async function fetchAndRetryProtectedUntilOk(payload, protectedHeader, pr
650597
return undefined;
651598
}
652599

600+
async function returnAnswer(response, acmeDirectory, name) {
601+
return {
602+
answer: { [response.ok ? name : 'error']: await response.json(), location: response.headers.get(NEXT_URL) },
603+
nonce: await getNextNonce(response.headers, acmeDirectory)
604+
};
605+
}
606+
653607
function notCompletedError(error, exception) {
654608
return {
655609
answer:

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "base-acme-client",
33
"author": "FirstTimeEZ",
4-
"version": "22.0.9",
4+
"version": "23.0.1",
55
"description": "Implementation of the Automatic Certificate Management Environment in Javascript (RFC8555)",
66
"main": "base-acme-client.js",
77
"type": "module",

0 commit comments

Comments
 (0)