ultimate-jekyll-manager 1.9.27 → 1.9.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -129,30 +129,32 @@ async function getHttpsConfig() {
129
129
  // Check if mkcert certificates exist
130
130
  const certPath = path.join(rootPathProject, '.temp');
131
131
 
132
- // Look for any mkcert generated files (handles localhost+2.pem format)
133
- const certFiles = jetpack.find(certPath, { matching: 'localhost*.pem' }) || [];
132
+ // Look for any mkcert generated files. NOTE: mkcert names files after the FIRST
133
+ // SAN host (development.<brand>+N.pem, not localhost*.pem) match *.pem, the
134
+ // same pattern generateMkcertCertificates() finds after generating.
135
+ const certFiles = jetpack.find(certPath, { matching: '*.pem' }) || [];
134
136
  const keyFile = certFiles.find(f => f.includes('-key.pem'));
135
137
  const certFile = certFiles.find(f => !f.includes('-key.pem'));
136
138
 
137
139
  if (keyFile && certFile) {
138
- logger.log('Using mkcert certificates from .temp/');
139
- logger.log(`Certificate: ${certFile}`);
140
- logger.log(`Key: ${keyFile}`);
140
+ const problem = checkCertProblem(certFile);
141
141
 
142
- // Read certificate to check validity
143
- try {
144
- const certContent = jetpack.read(certFile);
145
- if (certContent && certContent.includes('BEGIN CERTIFICATE')) {
146
- logger.log('✅ Certificate appears valid');
147
- }
148
- } catch (e) {
149
- logger.log('⚠️ Could not read certificate');
142
+ if (!problem) {
143
+ logger.log('Using mkcert certificates from .temp/');
144
+ logger.log(`Certificate: ${certFile}`);
145
+ logger.log(`Key: ${keyFile}`);
146
+
147
+ return {
148
+ key: keyFile,
149
+ cert: certFile
150
+ };
150
151
  }
151
152
 
152
- return {
153
- key: keyFile,
154
- cert: certFile
155
- };
153
+ // Stale certs (expired, or issued by a DIFFERENT machine's mkcert CA — e.g.
154
+ // .temp copied over from another Mac) make browsers reject https://localhost:4000
155
+ // outright. Wipe and regenerate against THIS machine's trusted CA.
156
+ logger.log(`Existing certificates are not usable (${problem}) — regenerating...`);
157
+ certFiles.forEach((file) => jetpack.remove(file));
156
158
  }
157
159
 
158
160
  // Try to generate mkcert certificates
@@ -170,6 +172,41 @@ async function getHttpsConfig() {
170
172
  return true;
171
173
  }
172
174
 
175
+ // Returns a reason string when the existing cert must be regenerated, or null
176
+ // when it's usable: unexpired AND signed by this machine's trusted mkcert root CA.
177
+ function checkCertProblem(certFile) {
178
+ const { X509Certificate } = require('crypto');
179
+ const { execSync } = require('child_process');
180
+
181
+ let cert;
182
+ try {
183
+ cert = new X509Certificate(jetpack.read(certFile));
184
+ } catch (e) {
185
+ return 'unreadable certificate';
186
+ }
187
+
188
+ if (new Date(cert.validTo) <= new Date()) {
189
+ return `expired ${cert.validTo}`;
190
+ }
191
+
192
+ // Verify the signature chains to the CURRENT mkcert root CA. If mkcert (or its
193
+ // root) isn't available we can't verify — keep the existing certs rather than
194
+ // breaking the self-signed fallback path.
195
+ try {
196
+ const caRoot = execSync('mkcert -CAROOT', { encoding: 'utf8' }).trim();
197
+ const ca = new X509Certificate(jetpack.read(path.join(caRoot, 'rootCA.pem')));
198
+
199
+ if (!cert.verify(ca.publicKey)) {
200
+ const issuerCN = cert.issuer.split('\n').find((line) => line.startsWith('CN=')) || cert.issuer;
201
+ return `issued by a different CA (${issuerCN})`;
202
+ }
203
+ } catch (e) {
204
+ return null;
205
+ }
206
+
207
+ return null;
208
+ }
209
+
173
210
  // Generate mkcert certificates
174
211
  async function generateMkcertCertificates(certPath) {
175
212
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-jekyll-manager",
3
- "version": "1.9.27",
3
+ "version": "1.9.28",
4
4
  "description": "Ultimate Jekyll dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -116,7 +116,7 @@
116
116
  "prettier": "^3.9.4",
117
117
  "sass": "^1.101.0",
118
118
  "spellchecker": "^3.7.1",
119
- "web-manager": "^4.3.2",
119
+ "web-manager": "^4.3.4",
120
120
  "webpack": "^5.108.3",
121
121
  "wonderful-fetch": "^2.0.5",
122
122
  "wonderful-version": "^1.3.2",