Skip to content

Commit

Permalink
LetsEncryptDaemon ES6 Class Default Export (#4)
Browse files Browse the repository at this point in the history
class LetsEncryptDaemon is the default export
  • Loading branch information
FirstTimeEZ authored Dec 20, 2024
1 parent 60e69a8 commit db88b66
Show file tree
Hide file tree
Showing 5 changed files with 578 additions and 489 deletions.
58 changes: 50 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,36 @@ Automatically Create and Renew `LetsEncrypt! SSL Certificates`, including `Wildc

### Getting Started

This most recent version of this package is implemented in [`SSL Server`](https://github.com/FirstTimeEZ/server-ssl) and you can use that to understand how it works if the `jsdoc` isn't enough information.
```javascript
import LetsEncryptDaemon from 'lets-encrypt-acme-client';
```

### Wild Card Certificates
#### Simple Usage Example

You can generate `Wild Card Certificates` if you are using a supported `DNS Provider`
Create a `LetsEncryptDaemon` and then start the `Daemon`

```javascript
const daemon = new LetsEncryptDaemon();
await daemon.startLetsEncryptDaemon(...); // You can only start this once, it will configure itself to run again.
daemon.checkChallengesMixin(...); // You must check the HTTP-01 Challenges for each LetsEncryptDaemon
```

#### Complete Example Usage

This most recent version of this package is implemented in [`SSL Server`](https://github.com/FirstTimeEZ/server-ssl)

You can use [`SSL Server`](https://github.com/FirstTimeEZ/server-ssl) to understand how it works if the `jsdoc` isn't enough information.

--------

### Wild Card Certificates

| Supported DNS Providers |
|-------------------------|
| Cloud Flare |

You can generate `Wild Card Certificates` if you are using a supported `DNS Provider`

```
let dnsProvider = {
name: "Cloud Flare",
Expand All @@ -28,11 +48,21 @@ let dnsProvider = {

### LetsEncrypt! Daemon

`LetsEncryptDaemon` is the default exported class

```javascript
const daemon = new LetsEncryptDaemon();
```

### Daemon

The `Daemon` runs periodically to `Create` or `Renew` the `Certificate`

### Jsdoc

```javascript
/**
* Starts the LetsEncrypt! Daemon to Manage the SSL Certificate for the Server
* Starts the LetsEncrypt! Daemon to Manage a SSL Certificate
*
* @param {Array<string>} fqdns - The fully qualified domain names as a SAN (e.g., ["example.com", "www.example.com"]), You must use a `dnsProvider` if you include a wild card
* @param {string} sslPath - The path where your acme account, keys and generated certificate will be stored or loaded from
Expand All @@ -50,7 +80,12 @@ The `Daemon` runs periodically to `Create` or `Renew` the `Certificate`
* @note
* If you start this more than once nothing will happen
*/
export async function startLetsEncryptDaemon(fqdns, sslPath, certificateCallback, optGenerateAnyway = false, optStaging = false, dnsProvider = undefined)
```

#### Usage

```javascript
await daemon.startLetsEncryptDaemon(fqdns, sslPath, certificateCallback, optGenerateAnyway = false, optStaging = false, dnsProvider = undefined)
```

### HTTP Mixin for `HTTP-01`
Expand All @@ -59,17 +94,24 @@ export async function startLetsEncryptDaemon(fqdns, sslPath, certificateCallback

This is not required if you are using a `DNS Provider`

### Jsdoc

```javascript
/**
* Node.js Middleware function to check and respond to ACME HTTP-01 challenges inside the HTTP Server.
* Node.js Middleware function to check and respond to ACME HTTP-01 challenges issued by this LetsEncryptDaemon inside the HTTP Server.
*
* @example
* createServerHTTP(async (req, res) => {
* if (STATE.optLetsEncrypt && await checkChallengesMixin(req, res)) { return; }
* if (STATE.optLetsEncrypt && checkChallengesMixin(req, res)) { return; }
* // normal request redirect etc
* }).listen(80);
*/
export async function checkChallengesMixin(req, res)
```

#### Usage

```javascript
if (daemon.checkChallengesMixin(req, res)) { return; } // Inside the HTTP Server
```

--------
Expand Down
64 changes: 64 additions & 0 deletions ext/ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright © 2024 FirstTimeEZ
* https://github.com/FirstTimeEZ
*
* 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.
*/

/**
* Checks if the given certificate text is valid.
* A valid certificate text starts with "-----BEGIN CERTIFICATE-----"
* and ends with "-----END CERTIFICATE-----" (with or without a newline).
*
* @param {string} certificateText - The certificate text to validate.
* @returns {boolean} True if the certificate text is valid, false otherwise.
*/
export function checkCertificateTextValid(certificateText) {
return certificateText.startsWith("-----BEGIN CERTIFICATE-----") && (certificateText.endsWith("-----END CERTIFICATE-----\n") || certificateText.endsWith("-----END CERTIFICATE-----") || certificateText.endsWith("-----END CERTIFICATE----- "));
}

/**
* Checks if the given private key is valid.
* A valid private key starts with "-----BEGIN PRIVATE KEY-----"
* and ends with "-----END PRIVATE KEY-----" (with or without a newline).
*
* @param {string} privateKey - The private key to validate.
* @returns {boolean} True if the private key is valid, false otherwise.
*/
export function checkPrivateKeyValid(privateKey) {
return privateKey.startsWith("-----BEGIN PRIVATE KEY-----") && (privateKey.endsWith("-----END PRIVATE KEY-----") || privateKey.endsWith("-----END PRIVATE KEY-----\n") || privateKey.endsWith("-----END PRIVATE KEY----- "))
}

/**
* Extracts challenges of a specific type from a list of authorizations.
* Each challenge is marked as unanswered and includes its associated domain
* and wildcard status.
*
* @param {Array} list - The list of authorizations containing challenges.
* @param {string} challengeType - The type of challenge to extract.
* @returns {Array} An array of challenges of the specified type.
*/
export function extractChallengeType(list, challengeType) {
const chals = [];

for (let index = 0; index < list.length; index++) {
const auth = list[index];

for (let i1 = 0; i1 < auth.get.challenges.length; i1++) {
const challenge = auth.get.challenges[i1];
challenge.type == challengeType && (challenge.answered = false, challenge.domain = auth.get.identifier.value, challenge.wildcard = auth.get.wildcard ? auth.get.wildcard : false, chals.push(challenge));
}
}

return chals;
}
Loading

0 comments on commit db88b66

Please sign in to comment.