@metric-im/administrate 1.1.1 → 1.1.4
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.
- package/certify.mjs +30 -4
- package/package.json +1 -1
package/certify.mjs
CHANGED
|
@@ -40,6 +40,7 @@ export class Certify {
|
|
|
40
40
|
get SNI() {
|
|
41
41
|
return {SNICallback: async (hostname, cb) => {
|
|
42
42
|
try {
|
|
43
|
+
if (this.pending[hostname]) return(cb('pending'));
|
|
43
44
|
console.log(`SNL get keys for ${hostname}`)
|
|
44
45
|
const siteKeys = await this.getSiteKeys(hostname);
|
|
45
46
|
cb(null, tls.createSecureContext(siteKeys));
|
|
@@ -54,11 +55,15 @@ export class Certify {
|
|
|
54
55
|
|
|
55
56
|
router.get(/^\/\.well-known\/acme-challenge\/([^\/]+)$/,(req,res)=>{
|
|
56
57
|
const token = req.params[0];
|
|
58
|
+
console.log(`ACME challenge request for token: ${token}`);
|
|
59
|
+
console.log(`Available challenges:`, Object.keys(this.challenges));
|
|
57
60
|
if (token in this.challenges) {
|
|
61
|
+
console.log(`✓ Challenge found, responding with authorization`);
|
|
58
62
|
res.writeHead(200);
|
|
59
63
|
res.end(this.challenges[token]);
|
|
60
64
|
return;
|
|
61
65
|
}
|
|
66
|
+
console.log(`✗ Challenge not found, returning 404`);
|
|
62
67
|
// Don't redirect ACME challenges - return 404 instead (says Claude, used to be 302)
|
|
63
68
|
res.writeHead(404);
|
|
64
69
|
res.end('Challenge not found');
|
|
@@ -118,7 +123,7 @@ export class Certify {
|
|
|
118
123
|
return;
|
|
119
124
|
} else {
|
|
120
125
|
if (!this.contactEmail) throw new Error(`cannot request certificate without CONTACT_EMAIL set`);
|
|
121
|
-
this.pending[sitename] =
|
|
126
|
+
this.pending[sitename] = moment();
|
|
122
127
|
|
|
123
128
|
try {
|
|
124
129
|
// Add timeout wrapper for the entire certificate renewal process
|
|
@@ -137,10 +142,28 @@ export class Certify {
|
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
async doRenewCert(sitename) {
|
|
140
|
-
//
|
|
141
|
-
const
|
|
145
|
+
// Prepare CSR options
|
|
146
|
+
const csrOptions = {
|
|
142
147
|
altNames: [sitename],
|
|
143
|
-
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// // letsencrypt will not accept an OU it doesn't certify
|
|
151
|
+
// // Check if domain has an epistery address
|
|
152
|
+
// const domainConfig = this.config.read(sitename);
|
|
153
|
+
// const episteryAddress = domainConfig?.wallet?.address;
|
|
154
|
+
// if (episteryAddress) {
|
|
155
|
+
// // RFC 5280: Use organization (O) field to identify Rootz Corp as binding provider
|
|
156
|
+
// csrOptions.organization = 'Rootz Corp';
|
|
157
|
+
// // RFC 5280: Use organizationUnit (OU) to store epistery identity address
|
|
158
|
+
// // This binds the domain to the epistery address in the certificate
|
|
159
|
+
// // Users can verify at /.well-known/epistery/status (RFC 8615 well-known URI)
|
|
160
|
+
// csrOptions.organizationUnit = `Epistery: ${episteryAddress}`;
|
|
161
|
+
// console.log(`Binding epistery identity ${episteryAddress} to certificate for ${sitename}`);
|
|
162
|
+
// console.log(`Epistery binding verifiable at https://${sitename}/.well-known/epistery/status`);
|
|
163
|
+
// }
|
|
164
|
+
|
|
165
|
+
// create CSR
|
|
166
|
+
const [key, csr] = await Acme.crypto.createCsr(csrOptions);
|
|
144
167
|
|
|
145
168
|
// order certificate with timeout
|
|
146
169
|
const cert = await this.acme.auto({
|
|
@@ -149,9 +172,12 @@ export class Certify {
|
|
|
149
172
|
termsOfServiceAgreed: true,
|
|
150
173
|
challengePriority: ['http-01'],
|
|
151
174
|
challengeCreateFn: (authz, challenge, keyAuthorization) => {
|
|
175
|
+
console.log(`✓ Challenge created - token: ${challenge.token}`);
|
|
176
|
+
console.log(` Challenge URL: http://${sitename}/.well-known/acme-challenge/${challenge.token}`);
|
|
152
177
|
this.challenges[challenge.token] = keyAuthorization;
|
|
153
178
|
},
|
|
154
179
|
challengeRemoveFn: (authz, challenge) => {
|
|
180
|
+
console.log(`✓ Challenge removed - token: ${challenge.token}`);
|
|
155
181
|
delete this.challenges[challenge.token];
|
|
156
182
|
},
|
|
157
183
|
});
|