Skip to content

Commit d98ce1e

Browse files
Maxim PlatzerMaxim Platzer
authored andcommitted
fix: restore mTLS auth with client cert
1 parent d806f98 commit d98ce1e

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/lib/server/models.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import endpoints, { endpointSchema, type Endpoint } from "./endpoints/endpoints"
66
import JSON5 from "json5";
77
import { logger } from "$lib/server/logger";
88
import { makeRouterEndpoint } from "$lib/server/router/endpoint";
9+
import { loadClientCertificates } from "$lib/utils/loadClientCerts";
10+
11+
if (config.USE_CLIENT_CERTIFICATE && config.CERT_PATH && config.KEY_PATH) {
12+
loadClientCertificates(config.CERT_PATH, config.KEY_PATH);
13+
}
914

1015
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
1116

src/lib/utils/loadClientCerts.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as fs from "fs";
2+
import { setGlobalDispatcher, Agent } from "undici";
3+
4+
/**
5+
* Load client certificates for mutual TLS authentication. This function must be called before any HTTP requests are made.
6+
* This is a global setting that affects all HTTP requests made by the application using the native fetch API.
7+
*
8+
* @param clientCertPath Path to client certificate
9+
* @param clientKeyPath Path to client key
10+
* @param caCertPath Path to CA certificate [optional]
11+
* @param clientKeyPassword Password for client key [optional]
12+
* @param rejectUnauthorized Reject unauthorized certificates.
13+
* Only use for testing/development, not recommended in production environments [optional]
14+
*
15+
* @returns void
16+
*
17+
* @example
18+
* ```typescript
19+
* loadClientCertificates("cert.pem", "key.pem", "ca.pem", "password", false);
20+
* ```
21+
*
22+
* @see
23+
* [Undici Agent](https://undici.nodejs.org/#/docs/api/Agent)
24+
* @see
25+
* [Undici Dispatcher](https://undici.nodejs.org/#/docs/api/Dispatcher)
26+
* @see
27+
* [NodeJS Native Fetch API](https://nodejs.org/docs/latest-v19.x/api/globals.html#fetch)
28+
*/
29+
export function loadClientCertificates(
30+
clientCertPath: string,
31+
clientKeyPath: string,
32+
caCertPath?: string,
33+
clientKeyPassword?: string,
34+
rejectUnauthorized?: boolean
35+
): void {
36+
const clientCert = fs.readFileSync(clientCertPath);
37+
const clientKey = fs.readFileSync(clientKeyPath);
38+
const caCert = caCertPath ? fs.readFileSync(caCertPath) : undefined;
39+
const agent = new Agent({
40+
connect: {
41+
cert: clientCert,
42+
key: clientKey,
43+
ca: caCert,
44+
passphrase: clientKeyPassword,
45+
rejectUnauthorized,
46+
},
47+
});
48+
49+
setGlobalDispatcher(agent);
50+
}

0 commit comments

Comments
 (0)