mirror of
https://github.com/certd/certd.git
synced 2026-05-16 13:17:29 +08:00
refactor(acme-client): 将acme-client改造成ts包并优化项目结构
重构acme-client模块,将原有JavaScript代码迁移至TypeScript 添加类型定义文件(.d.ts)和类型检查 更新构建配置和脚本以支持TypeScript编译 优化项目目录结构和模块导出方式 更新相关依赖和开发工具配置
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* ACME API client
|
||||
*/
|
||||
import * as util from './util.js';
|
||||
|
||||
/**
|
||||
* AcmeApi
|
||||
*
|
||||
* @class
|
||||
* @param {HttpClient} httpClient
|
||||
*/
|
||||
|
||||
class AcmeApi {
|
||||
constructor(httpClient, accountUrl = null) {
|
||||
this.http = httpClient;
|
||||
this.accountUrl = accountUrl;
|
||||
}
|
||||
|
||||
getLocationFromHeader(resp) {
|
||||
let locationUrl = resp.headers.location;
|
||||
const mapping = this.http.urlMapping;
|
||||
if (mapping.mappings) {
|
||||
// eslint-disable-next-line guard-for-in,no-restricted-syntax
|
||||
for (const key in mapping.mappings) {
|
||||
const url = mapping.mappings[key];
|
||||
if (locationUrl.indexOf(url) > -1) {
|
||||
locationUrl = locationUrl.replace(url, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return locationUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get account URL
|
||||
*
|
||||
* @private
|
||||
* @returns {string} Account URL
|
||||
*/
|
||||
|
||||
getAccountUrl() {
|
||||
if (!this.accountUrl) {
|
||||
throw new Error('No account URL found, register account first');
|
||||
}
|
||||
|
||||
return this.accountUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACME API request
|
||||
*
|
||||
* @private
|
||||
* @param {string} url Request URL
|
||||
* @param {object} [payload] Request payload, default: `null`
|
||||
* @param {number[]} [validStatusCodes] Array of valid HTTP response status codes, default: `[]`
|
||||
* @param {object} [opts]
|
||||
* @param {boolean} [opts.includeJwsKid] Include KID instead of JWK in JWS header, default: `true`
|
||||
* @param {boolean} [opts.includeExternalAccountBinding] Include EAB in request, default: `false`
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
async apiRequest(url, payload = null, validStatusCodes = [], { includeJwsKid = true, includeExternalAccountBinding = false } = {}) {
|
||||
const kid = includeJwsKid ? this.getAccountUrl() : null;
|
||||
const resp = await this.http.signedRequest(url, payload, { kid, includeExternalAccountBinding });
|
||||
|
||||
if (validStatusCodes.length && (validStatusCodes.indexOf(resp.status) === -1)) {
|
||||
throw new Error(util.formatResponseError(resp));
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACME API request by resource name helper
|
||||
*
|
||||
* @private
|
||||
* @param {string} resource Request resource name
|
||||
* @param {object} [payload] Request payload, default: `null`
|
||||
* @param {number[]} [validStatusCodes] Array of valid HTTP response status codes, default: `[]`
|
||||
* @param {object} [opts]
|
||||
* @param {boolean} [opts.includeJwsKid] Include KID instead of JWK in JWS header, default: `true`
|
||||
* @param {boolean} [opts.includeExternalAccountBinding] Include EAB in request, default: `false`
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
async apiResourceRequest(resource, payload = null, validStatusCodes = [], { includeJwsKid = true, includeExternalAccountBinding = false } = {}) {
|
||||
const resourceUrl = await this.http.getResourceUrl(resource);
|
||||
return this.apiRequest(resourceUrl, payload, validStatusCodes, { includeJwsKid, includeExternalAccountBinding });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Terms of Service URL if available
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.1
|
||||
*
|
||||
* @returns {Promise<string|null>} ToS URL
|
||||
*/
|
||||
|
||||
async getTermsOfServiceUrl() {
|
||||
return this.http.getMetaField('termsOfService');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new account
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.3
|
||||
*
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
async createAccount(data) {
|
||||
const resp = await this.apiResourceRequest('newAccount', data, [200, 201], {
|
||||
includeJwsKid: false,
|
||||
includeExternalAccountBinding: (data.onlyReturnExisting !== true),
|
||||
});
|
||||
|
||||
/* Set account URL */
|
||||
if (resp.headers.location) {
|
||||
this.accountUrl = this.getLocationFromHeader(resp);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update account
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.2
|
||||
*
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
updateAccount(data) {
|
||||
return this.apiRequest(this.getAccountUrl(), data, [200, 202]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update account key
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.5
|
||||
*
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
updateAccountKey(data) {
|
||||
return this.apiResourceRequest('keyChange', data, [200]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new order
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
|
||||
*
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
createOrder(data) {
|
||||
return this.apiResourceRequest('newOrder', data, [201]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
|
||||
*
|
||||
* @param {string} url Order URL
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
getOrder(url) {
|
||||
return this.apiRequest(url, null, [200]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize order
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
|
||||
*
|
||||
* @param {string} url Finalization URL
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
finalizeOrder(url, data) {
|
||||
return this.apiRequest(url, data, [200]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier authorization
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.5
|
||||
*
|
||||
* @param {string} url Authorization URL
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
getAuthorization(url) {
|
||||
return this.apiRequest(url, null, [200]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update identifier authorization
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2
|
||||
*
|
||||
* @param {string} url Authorization URL
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
updateAuthorization(url, data) {
|
||||
return this.apiRequest(url, data, [200]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete challenge
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.1
|
||||
*
|
||||
* @param {string} url Challenge URL
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
completeChallenge(url, data) {
|
||||
return this.apiRequest(url, data, [200]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke certificate
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.6
|
||||
*
|
||||
* @param {object} data Request payload
|
||||
* @returns {Promise<object>} HTTP response
|
||||
*/
|
||||
|
||||
revokeCert(data) {
|
||||
return this.apiResourceRequest('revokeCert', data, [200]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Export API */
|
||||
export default AcmeApi;
|
||||
Reference in New Issue
Block a user