-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 25b4b66
Showing
50 changed files
with
5,712 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
{ | ||
"extends": [ | ||
"airbnb-base", | ||
"plugin:@typescript-eslint/recommended", | ||
"plugin:jsdoc/recommended", | ||
"plugin:n/recommended", | ||
"plugin:unicorn/recommended" | ||
], | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"ecmaFeatures": { | ||
"impliedStrict": true | ||
}, | ||
"ecmaVersion": 2020, | ||
"sourceType": "module", | ||
"project": "./tsconfig.json" | ||
}, | ||
"plugins": [ | ||
"@typescript-eslint", | ||
"jsdoc", | ||
"unicorn" | ||
], | ||
"root": true, | ||
"rules": { | ||
"object-curly-newline": ["error", { | ||
"ObjectExpression": { "multiline": true, "consistent": true }, | ||
"ObjectPattern": { "multiline": true, "consistent": true }, | ||
"ImportDeclaration": { "multiline": true, "consistent": true }, | ||
"ExportDeclaration": { "multiline": true, "consistent": true } | ||
}], | ||
"no-param-reassign": 0, | ||
"no-continue": 0, | ||
"no-restricted-syntax": 0, | ||
"require-await": 0, | ||
"no-return-await": 0, | ||
"eslint-comments/no-use": 0, | ||
"filenames/match-regex": 0, | ||
"prettier/prettier": 0, | ||
"i18n-text/no-en": 0, | ||
"import/no-namespace": 0, | ||
"no-unused-vars": 0, | ||
"import/namespace": 0, | ||
"no-constructor-return": 0, | ||
"default-case-last": 0, | ||
"no-undef": 0, | ||
"import/named": 0, | ||
"no-empty": ["error", {"allowEmptyCatch": true}], | ||
"no-promise-executor-return": 0, | ||
"@typescript-eslint/ban-ts-comment": ["warn", { | ||
"ts-ignore": "allow-with-description" | ||
}], | ||
"@typescript-eslint/explicit-module-boundary-types": 0, | ||
"@typescript-eslint/require-await": "error", | ||
"no-void": "off", | ||
"@typescript-eslint/no-floating-promises": "error", | ||
"@typescript-eslint/return-await": ["error", "always"], | ||
|
||
"import/no-unresolved": "off", | ||
"import/extensions": ["error", "always", { | ||
"js": "always", | ||
"mjs": "never" | ||
}], | ||
"import/no-useless-path-segments": ["error", { | ||
"noUselessIndex": false | ||
}], | ||
"import/order": ["error", { | ||
"alphabetize": { | ||
"caseInsensitive": false, | ||
"order": "asc" | ||
}, | ||
"groups": [ | ||
"builtin", | ||
"external", | ||
"parent", | ||
"sibling", | ||
"index" | ||
], | ||
"newlines-between": "always", | ||
"pathGroups": [{ | ||
"group": "external", | ||
"pattern": "@dataprocs/**", | ||
"position": "after" | ||
}], | ||
"pathGroupsExcludedImportTypes": ["builtin"] | ||
}], | ||
"import/prefer-default-export": 0, | ||
"unicorn/switch-case-braces": 0, | ||
"unicorn/no-useless-undefined": 0, | ||
"unicorn/no-array-for-each": 0, | ||
"unicorn/prefer-spread": 0, | ||
"unicorn/no-null": 0, | ||
"unicorn/filename-case": 0, | ||
"unicorn/prefer-dom-node-append": 0, | ||
"unicorn/prevent-abbreviations": 0, | ||
"unicorn/explicit-length-check": 0, | ||
"unicorn/catch-error-name": 0, | ||
"unicorn/prefer-dom-node-dataset": 0, | ||
"unicorn/no-array-reduce": 0, | ||
"unicorn/no-this-assignment": 0, | ||
"unicorn/prefer-ternary": ["error", "only-single-line"], | ||
"unicorn/no-empty-file": 0, | ||
"unicorn/prefer-query-selector": 0, | ||
"unicorn/prefer-dom-node-remove": 0, | ||
"unicorn/no-for-loop": 0, | ||
"jsdoc/newline-after-description": [ | ||
"warn", | ||
"never" | ||
], | ||
"jsdoc/no-undefined-types": 0, | ||
"jsdoc/require-param-description": 0, | ||
"jsdoc/require-property-description": 0, | ||
"jsdoc/require-returns": 0, | ||
"jsdoc/require-returns-description": 0, | ||
"jsdoc/valid-types": 0, | ||
"max-len": ["error", 120, 2, { | ||
"ignoreComments": true, | ||
"ignoreRegExpLiterals": true, | ||
"ignoreStrings": true, | ||
"ignoreTemplateLiterals": true, | ||
"ignoreUrls": true | ||
}], | ||
"consistent-return": "warn", | ||
"no-console": ["error", { | ||
"allow": [ | ||
"warn", | ||
"error", | ||
"time", | ||
"timeEnd" | ||
] | ||
}], | ||
"no-plusplus": ["off"], | ||
"node/no-unsupported-features/es-syntax": ["off", { | ||
"ignores": [], | ||
"version": ">=14.0.0" | ||
}], | ||
"prefer-destructuring": ["error", { | ||
"AssignmentExpression": { | ||
"array": false, | ||
"object": false | ||
}, | ||
"VariableDeclarator": { | ||
"array": false, | ||
"object": true | ||
} | ||
}, { | ||
"enforceForRenamedProperties": false | ||
}], | ||
"sort-imports": ["error", { | ||
"ignoreDeclarationSort": true | ||
}], | ||
"spaced-comment": ["error", "always", { | ||
"block": { | ||
"balanced": true, | ||
"exceptions": ["-", "+"], | ||
"markers": ["=", "!", ":", "::"] | ||
}, | ||
"line": { | ||
"exceptions": ["-", "+"], | ||
"markers": ["=", "!", "/"] | ||
} | ||
}] | ||
}, | ||
"settings": { | ||
"jsdoc": { | ||
"preferredTypes": { | ||
"array": "Array", | ||
"object": "Object", | ||
"object.": "Object<>", | ||
"object<>": "Object<>", | ||
"symbol": "Symbol" | ||
}, | ||
"tagNamePreference": { | ||
"augment": "extends", | ||
"constant": "const", | ||
"property": "prop", | ||
"returns": "return" | ||
} | ||
} | ||
}, | ||
"overrides": [ | ||
{ | ||
"files": [ "*.cjs"], | ||
"rules": { | ||
"import/no-nodejs-modules": 0, | ||
"@typescript-eslint/no-var-requires": 0 | ||
} | ||
} | ||
] | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "Debug AVA", | ||
"request": "launch", | ||
"runtimeArgs": [ | ||
"run-script", | ||
"debug-test" | ||
], | ||
"runtimeExecutable": "npm", | ||
"skipFiles": [ | ||
"<node_internals>/**" | ||
], | ||
"type": "pwa-node" | ||
}, | ||
{ | ||
"type": "node", | ||
"request": "launch", | ||
"name": "Debug AVA test file", | ||
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/ava", | ||
"runtimeArgs": [ | ||
"--serial", | ||
"${file}" | ||
], | ||
"outputCapture": "std", | ||
"skipFiles": [ | ||
"<node_internals>/**/*.js" | ||
] | ||
}, | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"javascript.preferences.importModuleSpecifier": "relative", | ||
"javascript.preferences.importModuleSpecifierEnding": "js", | ||
"javascript.preferences.quoteStyle": "single" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# acmejs | ||
|
||
Zero-dependency ACME Client | ||
|
||
# Compatiblity | ||
|
||
Uses: | ||
|
||
| Feature | Chrome | Firefox | Safari | NodeJS | Deno | | ||
| -------------------------------------------------------------------------------------------------- | -----: | ------: | -----: | -----: | ---: | | ||
| [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) | 37 | 34 | 11 | 15.0.0 | 1.17 | | ||
| [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch) | 42 | 39 | 10.1 | 18.0.0 | 1.0 | | ||
| [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/EventTarget)* | 64 | 59 | 14 | 15.0.0 | 1.0 | | ||
| [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)† | 67 | 68 | 14 | 10.4.0 | 1.0 | | ||
| | | | | | | | ||
| Supported | 67 | 68 | 14 | 18.0.0 | 1.17 | | ||
|
||
*Used by helper functions | ||
†Used by helper ASN1 operations | ||
|
||
*Compatibility may be extended via polyfills (not included)* | ||
|
||
# Libraries | ||
|
||
* [ACMEClient](./lib/ACMEAgent.js) | ||
* [JOSE Functions](./lib/jose.js) | ||
* [JWA Functions](./lib/jwa.js) | ||
* [JWE Functions](./lib/jwe.js) (incomplete) | ||
* [JWK Functions](./lib/jwk.js) | ||
* [JWS Functions](./lib/jws.js) | ||
* [KeyStore](./lib/KeyStore.js) | ||
|
||
# Helpers | ||
|
||
* [JWK Import Functions](./helpers/jwkImporter.js) | ||
* [name.com DNS API](./lib/nameDotCom.js) | ||
* [Quick Certificate Order](./lib/quickOrder.js) | ||
|
||
# Utilities | ||
|
||
* [ASN1 Encoder/Decoder](./utils/asn1.js) | ||
* [Base64 Encoder/Decoder](./utils/base64.js) | ||
* [Bit Functions](./utils/bit.js) | ||
* [SubtleCrypto NodeJS Wrapper](./utils/crypto.js) | ||
* [DNS Resolver](./utils/dns.js) | ||
* [PKCS1, PKCS8, PKCS10 Functions](./utils/pkcs8.js) | ||
* [UTF-8 Decoder](./utils/utf8.js) | ||
|
||
# Usage | ||
|
||
|
||
# Quick Order with name.com (defaults to Lets Encrypt ACME); | ||
|
||
````js | ||
import { buildEventTarget } from '@shortfuse/acmejs/helpers/nameDotCom.js'; | ||
import { getWildcardCertificate } from '@shortfuse/acmejs/helpers/quickOrder.js'; | ||
|
||
// as JWK | ||
const ACCOUNT_PRIVATE_KEY = { | ||
alg: 'ES256', | ||
kty: 'EC', | ||
crv: 'P-256', | ||
x: 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU', | ||
y: 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0', | ||
d: 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI', | ||
}; | ||
|
||
// as PEM | ||
const CSR_PRIVATE_KEY = ` | ||
-----BEGIN PRIVATE KEY----- | ||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDD0tPV/du2vftjvXj1t/gXTK39 | ||
sNBVrOAEb/jKzXae+Xa0H+3LhZaQIQNMfACiBSgIfZUvEGb+7TqXWQpoLoFR/R7MvGWcSk98JyrV | ||
tveD8ZmZYyItSY7m2hcasqAFiKyOouV5vzyRe87/lEyzzBpF3bQQ4IDaQu+K9Hj5fKuU6rrOeOhs | ||
dnJc+VdDQLScHxvMoLZ9Vtt+oK9J4/tOLwr4CG8khDlBURcBY6gPcLo3dPU09SW+6ctX2cX4mkXx | ||
6O/0mmdTmacr/vu50KdRMleFeZYOWPAEhhMfywybTuzBiPVIZVP8WFCSKNMbfi1S9A9PdBqnebww | ||
HhX3/hsEBt2BAgMBAAECggEABEI1P6nf6Zs7mJlyBDv+Pfl5rjL2cOqLy6TovvZVblMkCPpJyFuN | ||
IPDK2tK2i897ZaXfhPDBIKmllM2Hq6jZQKB110OAnTPDg0JxzMiIHPs32S1d/KilHjGff4Hjd4NX | ||
p1l1Dp8BUPOllorR2TYm2x6dcCGFw9lhTr8O03Qp4hjn84VjGIWADYCk83mgS4nRsnHkdiqYnWx1 | ||
AjKlY51yEK6RcrDMi0Th2RXrrINoC35sVv+APt2rkoMGi52RwTEseA1KZGFrxjq61ReJif6p2VXE | ||
cvHeX6CWLx014LGk43z6Q28P6HgeEVEfIjyqCUea5Du/mYb/QsRSCosXLxBqwQKBgQD1+fdC9ZiM | ||
rVI+km7Nx2CKBn8rJrDmUh5SbXn2MYJdrUd8bYNnZkCgKMgxVXsvJrbmVOrby2txOiqudZkk5mD3 | ||
E5O/QZWPWQLgRu8ueYNpobAX9NRgNfZ7rZD+81vh5MfZiXfuZOuzv29iZhU0oqyZ9y75eHkLdrer | ||
NkwYOe5aUQKBgQDLzapDi1NxkBgsj9iiO4KUa7jvD4JjRqFy4Zhj/jbQvlvM0F/uFp7sxVcHGx4r | ||
11C+6iCbhX4u+Zuu0HGjT4d+hNXmgGyxR8fIUVxOlOtDkVJa5sOBZK73/9/MBeKusdmJPRhalZQf | ||
MUJRWIoEVDMhfg3tW/rBj5RYAtP2dTVUMQKBgDs8yr52dRmT+BWXoFWwaWB0NhYHSFz/c8v4D4Ip | ||
5DJ5M5kUqquxJWksySGQa40sbqnD05fBQovPLU48hfgr/zghn9hUjBcsoZOvoZR4sRw0UztBvA+7 | ||
jzOz1hKAOyWIulR6Vca0yUrNlJ6G5R56+sRNkiOETupi2dLCzcqb0PoxAoGAZyNHvTLvIZN4iGSr | ||
jz5qkM4LIwBIThFadxbv1fq6pt0O/BGf2o+cEdq0diYlGK64cEVwBwSBnSg4vzlBqRIAUejLjwED | ||
AJyA4EE8Y5A9l04dzV7nJb5cRak6CrgXxay/mBJRFtaHxVlaZGxYPGSYE6UFS0+3EOmmevvDZQBf | ||
4qECgYEA0ZF6Vavz28+8wLO6SP3w8NmpHk7K9tGEvUfQ30SgDx4G7qPIgfPrbB4OP/E0qCfsIImi | ||
3sCPpjvUMQdVVZyPOIMuB+rV3ZOxkrzxEUOrpOpR48FZbL7RN90yRQsAsrp9e4iv8QwB3VxLe7X0 | ||
TDqqnRyqrc/osGzuS2ZcHOKmCU8= | ||
-----END PRIVATE KEY----- | ||
`; | ||
|
||
const NAME_DOT_COM_USERNAME = 'foo'; | ||
const NAME_DOT_COM_TOKEN = 'bar'; | ||
|
||
const certificate = await getWildcardCertificate({ | ||
tosAgreed: true, | ||
domain: 'foo.com', | ||
jwk: ACCOUNT_PRIVATE_KEY, | ||
email: '[email protected]', | ||
eventTarget: buildEventTarget(NAME_DOT_COM_USERNAME, NAME_DOT_COM_TOKEN), | ||
csr: { | ||
countryName: 'US', | ||
localityName: 'New York', | ||
organizationName: 'Foo Products', | ||
organizationalUnitName: 'IT', | ||
stateOrProvinceName: 'NY', | ||
jwk: CSR_PRIVATE_KEY, | ||
}, | ||
}); | ||
|
||
await store('foo-com.crt', certificate); | ||
```` | ||
|
||
See [quickOrder.js](./helpers/quickOrder.js) source code for a working example. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* @see https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.2 | ||
* @typedef {Object} Account | ||
* @prop {'valid'|'deactivated'|'revoked'} status The status of this account. | ||
* The value "deactivated" should be used to indicate client-initiated | ||
* deactivation whereas "revoked" should be used to indicate server- | ||
* initiated deactivation. See Section 7.1.6. | ||
* @prop {string[]} [contact] An array of URLs that the | ||
* server can use to contact the client for issues related to this | ||
* account. For example, the server may wish to notify the client | ||
* about server-initiated revocation or certificate expiration. For | ||
* information on supported URL schemes, see Section 7.3. | ||
* @prop {boolean} [termsOfServiceAgreed] Including this field in a `newAccount` | ||
* request, with a value of true, indicates the client's agreement with the | ||
* terms of service. This field cannot be updated by the client. | ||
* @prop {JWSJSONSerialization} [externalAccountBinding] Including this field in a | ||
* newAccount request indicates approval by the holder of an existing | ||
* non-ACME account to bind that account to this ACME account. This | ||
* field is not updateable by the client (see Section 7.3.4). | ||
* @prop {string} orders A URL from which a list of orders | ||
* submitted by this account can be fetched via a POST-as-GET | ||
* request, as described in Section 7.1.2.1. | ||
*/ | ||
|
||
/** | ||
* @see https://datatracker.ietf.org/doc/html/rfc8555#section-7.3 | ||
* @typedef {Object} AccountNewRequestFields | ||
* @prop {boolean} [onlyReturnExisting] If this field is present | ||
* with the value "true", then the server MUST NOT create a new | ||
* account if one does not already exist. This allows a client to | ||
* look up an account URL based on an account key (see | ||
* Section 7.3.1). | ||
*/ | ||
|
||
/** | ||
* @see https://datatracker.ietf.org/doc/html/rfc8555#section-7.3 | ||
* @typedef {Pick<Account, 'contact'|'termsOfServiceAgreed'|'externalAccountBinding'> & AccountNewRequestFields} AccountNewRequest | ||
*/ | ||
|
||
/** @typedef {Pick<Account, 'status'|'contact'>} AccountRequest */ |
Oops, something went wrong.