@opsimathically/nodenetproccalld 0.0.2 → 0.0.3

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/dist/index.js CHANGED
@@ -35,12 +35,17 @@ var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "
35
35
  var index_exports = {};
36
36
  __export(index_exports, {
37
37
  ApiKeyAuthorizer: () => ApiKeyAuthorizer,
38
+ ClientTlsPackageConfigFileLoader: () => ClientTlsPackageConfigFileLoader,
39
+ ClientTlsPackageGenerator: () => ClientTlsPackageGenerator,
38
40
  ConfigFileLoader: () => ConfigFileLoader,
39
41
  ConfigValidator: () => ConfigValidator,
40
42
  DaemonCli: () => DaemonCli,
41
43
  DaemonProcess: () => DaemonProcess,
44
+ DefaultClientTlsGenerationConfigGenerator: () => DefaultClientTlsGenerationConfigGenerator,
42
45
  DefaultConfigGenerator: () => DefaultConfigGenerator,
46
+ DefaultTlsGenerationConfigGenerator: () => DefaultTlsGenerationConfigGenerator,
43
47
  NetworkProcedureCallDaemon: () => NetworkProcedureCallDaemon,
48
+ TlsGenerationConfigFileLoader: () => TlsGenerationConfigFileLoader,
44
49
  TlsMaterialGenerator: () => TlsMaterialGenerator
45
50
  });
46
51
  module.exports = __toCommonJS(index_exports);
@@ -136,7 +141,7 @@ var _ApiKeyAuthorizer = class _ApiKeyAuthorizer {
136
141
  __name(_ApiKeyAuthorizer, "ApiKeyAuthorizer");
137
142
  var ApiKeyAuthorizer = _ApiKeyAuthorizer;
138
143
 
139
- // src/classes/configfileloader/ConfigFileLoader.class.ts
144
+ // src/classes/clienttlspackageconfigfileloader/ClientTlsPackageConfigFileLoader.class.ts
140
145
  var import_node_fs = __toESM(require("fs"));
141
146
  var import_node_path = __toESM(require("path"));
142
147
 
@@ -1247,8 +1252,408 @@ var JSON5 = {
1247
1252
  var lib = JSON5;
1248
1253
  var dist_default = lib;
1249
1254
 
1250
- // src/classes/configvalidator/ConfigValidator.class.ts
1255
+ // src/classes/clienttlspackageconfigfileloader/ClientTlsPackageConfigFileLoader.class.ts
1251
1256
  var import_zod = require("zod");
1257
+ var client_tls_package_config_schema = import_zod.z.object({
1258
+ ca_key_file: import_zod.z.string().min(1),
1259
+ ca_cert_file: import_zod.z.string().min(1),
1260
+ output_dir: import_zod.z.string().min(1).optional(),
1261
+ overwrite: import_zod.z.boolean().optional(),
1262
+ default_valid_days: import_zod.z.number().int().positive().optional(),
1263
+ clients: import_zod.z.array(import_zod.z.object({
1264
+ client_name: import_zod.z.string().min(1),
1265
+ common_name: import_zod.z.string().min(1).optional(),
1266
+ uri_san: import_zod.z.string().min(1).optional(),
1267
+ package_name: import_zod.z.string().min(1).optional(),
1268
+ valid_days: import_zod.z.number().int().positive().optional()
1269
+ }).strict()).min(1)
1270
+ }).strict();
1271
+ function ParseJson5File(params) {
1272
+ const absolute_file_path = import_node_path.default.resolve(process.cwd(), params.file_path);
1273
+ let file_content;
1274
+ try {
1275
+ file_content = import_node_fs.default.readFileSync(absolute_file_path, "utf8");
1276
+ } catch (error) {
1277
+ const error_message = error instanceof Error ? error.message : String(error);
1278
+ throw new Error(`Unable to read client TLS package config file "${absolute_file_path}": ${error_message}`);
1279
+ }
1280
+ try {
1281
+ return dist_default.parse(file_content);
1282
+ } catch (error) {
1283
+ const error_message = error instanceof Error ? error.message : String(error);
1284
+ throw new Error(`Invalid JSON5 in client TLS package config "${absolute_file_path}": ${error_message}`);
1285
+ }
1286
+ }
1287
+ __name(ParseJson5File, "ParseJson5File");
1288
+ function BuildZodErrorMessage(params) {
1289
+ const lines = params.error.issues.map((issue) => {
1290
+ const issue_path = issue.path.length > 0 ? issue.path.join(".") : "<root>";
1291
+ return `${issue_path}: ${issue.message}`;
1292
+ });
1293
+ return `Invalid client TLS package config file.
1294
+ ${lines.join("\n")}`;
1295
+ }
1296
+ __name(BuildZodErrorMessage, "BuildZodErrorMessage");
1297
+ function ResolvePath(params) {
1298
+ if (import_node_path.default.isAbsolute(params.file_path)) {
1299
+ return params.file_path;
1300
+ }
1301
+ return import_node_path.default.resolve(params.base_dir, params.file_path);
1302
+ }
1303
+ __name(ResolvePath, "ResolvePath");
1304
+ function BuildUriSanFromCommonName(params) {
1305
+ const normalized_common_name = params.common_name.replace(/[^a-zA-Z0-9_.-]/g, "_").toLowerCase();
1306
+ return `spiffe://nodenetproccalld/${normalized_common_name}`;
1307
+ }
1308
+ __name(BuildUriSanFromCommonName, "BuildUriSanFromCommonName");
1309
+ var _ClientTlsPackageConfigFileLoader = class _ClientTlsPackageConfigFileLoader {
1310
+ loadClientTlsPackageOptions(params) {
1311
+ const absolute_config_file_path = import_node_path.default.resolve(process.cwd(), params.client_tls_package_generation_options.config_file_path);
1312
+ const config_dir = import_node_path.default.dirname(absolute_config_file_path);
1313
+ const config_raw = ParseJson5File({
1314
+ file_path: absolute_config_file_path
1315
+ });
1316
+ const parse_result = client_tls_package_config_schema.safeParse(config_raw);
1317
+ if (!parse_result.success) {
1318
+ throw new Error(BuildZodErrorMessage({
1319
+ error: parse_result.error
1320
+ }));
1321
+ }
1322
+ const config_from_file = parse_result.data;
1323
+ const output_dir = ResolvePath({
1324
+ file_path: config_from_file.output_dir ?? "./client_certs",
1325
+ base_dir: config_dir
1326
+ });
1327
+ const overwrite = config_from_file.overwrite ?? false;
1328
+ const default_valid_days = config_from_file.default_valid_days ?? 36500;
1329
+ const clients = this.buildRuntimeClients({
1330
+ clients: config_from_file.clients,
1331
+ default_valid_days
1332
+ });
1333
+ this.assertUniqueClientNames({
1334
+ clients
1335
+ });
1336
+ this.assertUniquePackageNames({
1337
+ clients
1338
+ });
1339
+ return {
1340
+ ca_key_file: ResolvePath({
1341
+ file_path: config_from_file.ca_key_file,
1342
+ base_dir: config_dir
1343
+ }),
1344
+ ca_cert_file: ResolvePath({
1345
+ file_path: config_from_file.ca_cert_file,
1346
+ base_dir: config_dir
1347
+ }),
1348
+ output_dir,
1349
+ overwrite,
1350
+ default_valid_days,
1351
+ clients
1352
+ };
1353
+ }
1354
+ buildRuntimeClients(params) {
1355
+ return params.clients.map((client_definition) => {
1356
+ const common_name = client_definition.common_name ?? client_definition.client_name;
1357
+ const client_uri_san = client_definition.uri_san ?? BuildUriSanFromCommonName({
1358
+ common_name
1359
+ });
1360
+ const package_name = client_definition.package_name ?? client_definition.client_name;
1361
+ const valid_days = client_definition.valid_days ?? params.default_valid_days;
1362
+ return {
1363
+ client_name: client_definition.client_name,
1364
+ common_name,
1365
+ uri_san: client_uri_san,
1366
+ package_name,
1367
+ valid_days
1368
+ };
1369
+ });
1370
+ }
1371
+ assertUniqueClientNames(params) {
1372
+ const seen_client_names = /* @__PURE__ */ new Set();
1373
+ for (const client of params.clients) {
1374
+ if (seen_client_names.has(client.client_name)) {
1375
+ throw new Error(`Duplicate client_name "${client.client_name}" in client TLS package config file.`);
1376
+ }
1377
+ seen_client_names.add(client.client_name);
1378
+ }
1379
+ }
1380
+ assertUniquePackageNames(params) {
1381
+ const seen_package_names = /* @__PURE__ */ new Set();
1382
+ for (const client of params.clients) {
1383
+ if (seen_package_names.has(client.package_name)) {
1384
+ throw new Error(`Duplicate package_name "${client.package_name}" in client TLS package config file.`);
1385
+ }
1386
+ seen_package_names.add(client.package_name);
1387
+ }
1388
+ }
1389
+ };
1390
+ __name(_ClientTlsPackageConfigFileLoader, "ClientTlsPackageConfigFileLoader");
1391
+ var ClientTlsPackageConfigFileLoader = _ClientTlsPackageConfigFileLoader;
1392
+
1393
+ // src/classes/clienttlspackagegenerator/ClientTlsPackageGenerator.class.ts
1394
+ var import_node_child_process = require("child_process");
1395
+ var import_node_fs2 = __toESM(require("fs"));
1396
+ var import_node_path2 = __toESM(require("path"));
1397
+ function WriteTextFile(params) {
1398
+ import_node_fs2.default.writeFileSync(params.file_path, params.content, "utf8");
1399
+ }
1400
+ __name(WriteTextFile, "WriteTextFile");
1401
+ function EnsureReadableFile(params) {
1402
+ if (!import_node_fs2.default.existsSync(params.file_path)) {
1403
+ throw new Error(`${params.label} does not exist: ${params.file_path}`);
1404
+ }
1405
+ const stat_result = import_node_fs2.default.statSync(params.file_path);
1406
+ if (!stat_result.isFile()) {
1407
+ throw new Error(`${params.label} is not a file: ${params.file_path}`);
1408
+ }
1409
+ }
1410
+ __name(EnsureReadableFile, "EnsureReadableFile");
1411
+ var _ClientTlsPackageGenerator = class _ClientTlsPackageGenerator {
1412
+ generateClientTlsPackages(params) {
1413
+ this.assertOpenSslAvailable();
1414
+ this.assertTarAvailable();
1415
+ this.assertCaFiles({
1416
+ runtime_options: params.runtime_options
1417
+ });
1418
+ import_node_fs2.default.mkdirSync(params.runtime_options.output_dir, {
1419
+ recursive: true
1420
+ });
1421
+ const ca_serial_path = import_node_path2.default.join(params.runtime_options.output_dir, "client_ca.cert.srl");
1422
+ if (params.runtime_options.overwrite) {
1423
+ import_node_fs2.default.rmSync(ca_serial_path, {
1424
+ force: true
1425
+ });
1426
+ }
1427
+ const generated_packages = [];
1428
+ for (const client_definition of params.runtime_options.clients) {
1429
+ const client_files = this.buildClientFileMap({
1430
+ output_dir: params.runtime_options.output_dir,
1431
+ client_name: client_definition.client_name,
1432
+ package_name: client_definition.package_name
1433
+ });
1434
+ this.prepareClientOutput({
1435
+ client_files,
1436
+ overwrite: params.runtime_options.overwrite
1437
+ });
1438
+ try {
1439
+ this.generateClientCertificate({
1440
+ client_files,
1441
+ ca_key_file: params.runtime_options.ca_key_file,
1442
+ ca_cert_file: params.runtime_options.ca_cert_file,
1443
+ ca_serial_path,
1444
+ common_name: client_definition.common_name,
1445
+ uri_san: client_definition.uri_san,
1446
+ valid_days: client_definition.valid_days
1447
+ });
1448
+ import_node_fs2.default.rmSync(client_files.client_csr_path, {
1449
+ force: true
1450
+ });
1451
+ import_node_fs2.default.rmSync(client_files.client_ext_path, {
1452
+ force: true
1453
+ });
1454
+ import_node_fs2.default.copyFileSync(params.runtime_options.ca_cert_file, client_files.ca_cert_copy_path);
1455
+ this.writeClientReadme({
1456
+ client_files,
1457
+ client_name: client_definition.client_name
1458
+ });
1459
+ this.createTarPackage({
1460
+ client_files
1461
+ });
1462
+ generated_packages.push({
1463
+ client_name: client_definition.client_name,
1464
+ package_path: client_files.package_path,
1465
+ directory_path: client_files.client_dir,
1466
+ client_cert_path: client_files.client_cert_path,
1467
+ client_key_path: client_files.client_key_path,
1468
+ ca_cert_path: client_files.ca_cert_copy_path
1469
+ });
1470
+ } finally {
1471
+ import_node_fs2.default.rmSync(client_files.client_csr_path, {
1472
+ force: true
1473
+ });
1474
+ import_node_fs2.default.rmSync(client_files.client_ext_path, {
1475
+ force: true
1476
+ });
1477
+ }
1478
+ }
1479
+ import_node_fs2.default.rmSync(ca_serial_path, {
1480
+ force: true
1481
+ });
1482
+ return {
1483
+ output_dir: params.runtime_options.output_dir,
1484
+ packages: generated_packages
1485
+ };
1486
+ }
1487
+ assertOpenSslAvailable() {
1488
+ try {
1489
+ (0, import_node_child_process.execFileSync)("openssl", [
1490
+ "version"
1491
+ ], {
1492
+ stdio: "ignore"
1493
+ });
1494
+ } catch {
1495
+ throw new Error("openssl command is required but was not found. Please install openssl and retry.");
1496
+ }
1497
+ }
1498
+ assertTarAvailable() {
1499
+ try {
1500
+ (0, import_node_child_process.execFileSync)("tar", [
1501
+ "--version"
1502
+ ], {
1503
+ stdio: "ignore"
1504
+ });
1505
+ } catch {
1506
+ throw new Error("tar command is required but was not found. Please install tar and retry.");
1507
+ }
1508
+ }
1509
+ assertCaFiles(params) {
1510
+ EnsureReadableFile({
1511
+ file_path: params.runtime_options.ca_key_file,
1512
+ label: "ca_key_file"
1513
+ });
1514
+ EnsureReadableFile({
1515
+ file_path: params.runtime_options.ca_cert_file,
1516
+ label: "ca_cert_file"
1517
+ });
1518
+ }
1519
+ buildClientFileMap(params) {
1520
+ const client_dir = import_node_path2.default.join(params.output_dir, params.client_name);
1521
+ return {
1522
+ client_dir,
1523
+ client_key_path: import_node_path2.default.join(client_dir, "client.key.pem"),
1524
+ client_csr_path: import_node_path2.default.join(client_dir, "client.csr.pem"),
1525
+ client_cert_path: import_node_path2.default.join(client_dir, "client.cert.pem"),
1526
+ client_ext_path: import_node_path2.default.join(client_dir, "client.ext"),
1527
+ package_path: import_node_path2.default.join(params.output_dir, `${params.package_name}.tar.gz`),
1528
+ ca_cert_copy_path: import_node_path2.default.join(client_dir, "ca.cert.pem")
1529
+ };
1530
+ }
1531
+ prepareClientOutput(params) {
1532
+ if (!params.overwrite) {
1533
+ if (import_node_fs2.default.existsSync(params.client_files.client_dir)) {
1534
+ throw new Error(`Refusing to overwrite existing client directory "${params.client_files.client_dir}". Set overwrite=true in client TLS package config.`);
1535
+ }
1536
+ if (import_node_fs2.default.existsSync(params.client_files.package_path)) {
1537
+ throw new Error(`Refusing to overwrite existing client package "${params.client_files.package_path}". Set overwrite=true in client TLS package config.`);
1538
+ }
1539
+ } else {
1540
+ import_node_fs2.default.rmSync(params.client_files.client_dir, {
1541
+ recursive: true,
1542
+ force: true
1543
+ });
1544
+ import_node_fs2.default.rmSync(params.client_files.package_path, {
1545
+ force: true
1546
+ });
1547
+ }
1548
+ import_node_fs2.default.mkdirSync(params.client_files.client_dir, {
1549
+ recursive: true
1550
+ });
1551
+ }
1552
+ generateClientCertificate(params) {
1553
+ WriteTextFile({
1554
+ file_path: params.client_files.client_ext_path,
1555
+ content: [
1556
+ "extendedKeyUsage=clientAuth",
1557
+ "keyUsage=digitalSignature,keyEncipherment",
1558
+ `subjectAltName=URI:${params.uri_san}`
1559
+ ].join("\n")
1560
+ });
1561
+ this.runOpenSslCommand({
1562
+ args: [
1563
+ "req",
1564
+ "-new",
1565
+ "-newkey",
1566
+ "rsa:4096",
1567
+ "-sha256",
1568
+ "-nodes",
1569
+ "-keyout",
1570
+ params.client_files.client_key_path,
1571
+ "-out",
1572
+ params.client_files.client_csr_path,
1573
+ "-subj",
1574
+ `/CN=${params.common_name}`
1575
+ ]
1576
+ });
1577
+ const ca_sign_args = [
1578
+ "x509",
1579
+ "-req",
1580
+ "-in",
1581
+ params.client_files.client_csr_path,
1582
+ "-CA",
1583
+ params.ca_cert_file,
1584
+ "-CAkey",
1585
+ params.ca_key_file,
1586
+ "-CAserial",
1587
+ params.ca_serial_path,
1588
+ "-out",
1589
+ params.client_files.client_cert_path,
1590
+ "-days",
1591
+ String(params.valid_days),
1592
+ "-sha256",
1593
+ "-extfile",
1594
+ params.client_files.client_ext_path
1595
+ ];
1596
+ if (!import_node_fs2.default.existsSync(params.ca_serial_path)) {
1597
+ const with_create_serial = [
1598
+ ...ca_sign_args
1599
+ ];
1600
+ with_create_serial.splice(10, 0, "-CAcreateserial");
1601
+ this.runOpenSslCommand({
1602
+ args: with_create_serial
1603
+ });
1604
+ } else {
1605
+ this.runOpenSslCommand({
1606
+ args: ca_sign_args
1607
+ });
1608
+ }
1609
+ import_node_fs2.default.chmodSync(params.client_files.client_key_path, 384);
1610
+ import_node_fs2.default.chmodSync(params.client_files.client_cert_path, 420);
1611
+ import_node_fs2.default.chmodSync(params.client_files.client_ext_path, 384);
1612
+ import_node_fs2.default.chmodSync(params.client_files.client_csr_path, 384);
1613
+ }
1614
+ writeClientReadme(params) {
1615
+ const readme_content = [
1616
+ `Client TLS bundle for: ${params.client_name}`,
1617
+ "",
1618
+ "Files:",
1619
+ "- client.key.pem",
1620
+ "- client.cert.pem",
1621
+ "- ca.cert.pem",
1622
+ "",
1623
+ "Use these with NetworkProcedureCallClient tls_mtls fields."
1624
+ ].join("\n");
1625
+ WriteTextFile({
1626
+ file_path: import_node_path2.default.join(params.client_files.client_dir, "README.txt"),
1627
+ content: `${readme_content}
1628
+ `
1629
+ });
1630
+ }
1631
+ createTarPackage(params) {
1632
+ (0, import_node_child_process.execFileSync)("tar", [
1633
+ "-C",
1634
+ params.client_files.client_dir,
1635
+ "-czf",
1636
+ params.client_files.package_path,
1637
+ "."
1638
+ ], {
1639
+ stdio: "ignore"
1640
+ });
1641
+ }
1642
+ runOpenSslCommand(params) {
1643
+ (0, import_node_child_process.execFileSync)("openssl", params.args, {
1644
+ stdio: "ignore"
1645
+ });
1646
+ }
1647
+ };
1648
+ __name(_ClientTlsPackageGenerator, "ClientTlsPackageGenerator");
1649
+ var ClientTlsPackageGenerator = _ClientTlsPackageGenerator;
1650
+
1651
+ // src/classes/configfileloader/ConfigFileLoader.class.ts
1652
+ var import_node_fs3 = __toESM(require("fs"));
1653
+ var import_node_path3 = __toESM(require("path"));
1654
+
1655
+ // src/classes/configvalidator/ConfigValidator.class.ts
1656
+ var import_zod2 = require("zod");
1252
1657
  var privilege_name_list = [
1253
1658
  "invoke_functions",
1254
1659
  "define_functions",
@@ -1264,104 +1669,104 @@ var tls_min_version_list = [
1264
1669
  "TLSv1.2",
1265
1670
  "TLSv1.3"
1266
1671
  ];
1267
- var worker_runtime_options_schema = import_zod.z.object({
1268
- call_timeout_ms: import_zod.z.number().int().positive().optional(),
1269
- control_timeout_ms: import_zod.z.number().int().positive().optional(),
1270
- start_timeout_ms: import_zod.z.number().int().positive().optional(),
1271
- stop_timeout_ms: import_zod.z.number().int().positive().optional(),
1272
- restart_on_failure: import_zod.z.boolean().optional(),
1273
- max_restarts_per_worker: import_zod.z.number().int().nonnegative().optional(),
1274
- max_pending_calls_per_worker: import_zod.z.number().int().positive().optional(),
1275
- restart_base_delay_ms: import_zod.z.number().int().positive().optional(),
1276
- restart_max_delay_ms: import_zod.z.number().int().positive().optional(),
1277
- restart_jitter_ms: import_zod.z.number().int().nonnegative().optional()
1672
+ var worker_runtime_options_schema = import_zod2.z.object({
1673
+ call_timeout_ms: import_zod2.z.number().int().positive().optional(),
1674
+ control_timeout_ms: import_zod2.z.number().int().positive().optional(),
1675
+ start_timeout_ms: import_zod2.z.number().int().positive().optional(),
1676
+ stop_timeout_ms: import_zod2.z.number().int().positive().optional(),
1677
+ restart_on_failure: import_zod2.z.boolean().optional(),
1678
+ max_restarts_per_worker: import_zod2.z.number().int().nonnegative().optional(),
1679
+ max_pending_calls_per_worker: import_zod2.z.number().int().positive().optional(),
1680
+ restart_base_delay_ms: import_zod2.z.number().int().positive().optional(),
1681
+ restart_max_delay_ms: import_zod2.z.number().int().positive().optional(),
1682
+ restart_jitter_ms: import_zod2.z.number().int().nonnegative().optional()
1278
1683
  }).strict();
1279
- var rate_limiter_schema = import_zod.z.object({
1280
- enabled: import_zod.z.boolean().optional(),
1281
- tokens_per_interval: import_zod.z.number().int().positive().optional(),
1282
- interval_ms: import_zod.z.number().int().positive().optional(),
1283
- burst_tokens: import_zod.z.number().int().positive().optional(),
1284
- disconnect_on_limit: import_zod.z.boolean().optional()
1684
+ var rate_limiter_schema = import_zod2.z.object({
1685
+ enabled: import_zod2.z.boolean().optional(),
1686
+ tokens_per_interval: import_zod2.z.number().int().positive().optional(),
1687
+ interval_ms: import_zod2.z.number().int().positive().optional(),
1688
+ burst_tokens: import_zod2.z.number().int().positive().optional(),
1689
+ disconnect_on_limit: import_zod2.z.boolean().optional()
1285
1690
  }).strict();
1286
- var abuse_controls_schema = import_zod.z.object({
1287
- connection_controls: import_zod.z.object({
1288
- max_concurrent_sockets: import_zod.z.number().int().positive().optional(),
1289
- max_concurrent_handshakes: import_zod.z.number().int().positive().optional(),
1290
- max_unauthenticated_sessions: import_zod.z.number().int().positive().optional(),
1291
- global_connection_window_ms: import_zod.z.number().int().positive().optional(),
1292
- global_max_new_connections_per_window: import_zod.z.number().int().positive().optional(),
1293
- per_ip_max_new_connections_per_window: import_zod.z.number().int().positive().optional(),
1294
- tls_handshake_timeout_ms: import_zod.z.number().int().positive().optional(),
1295
- auth_message_timeout_ms: import_zod.z.number().int().positive().optional(),
1296
- max_pre_auth_frame_bytes: import_zod.z.number().int().positive().optional(),
1297
- max_post_auth_frame_bytes: import_zod.z.number().int().positive().optional()
1691
+ var abuse_controls_schema = import_zod2.z.object({
1692
+ connection_controls: import_zod2.z.object({
1693
+ max_concurrent_sockets: import_zod2.z.number().int().positive().optional(),
1694
+ max_concurrent_handshakes: import_zod2.z.number().int().positive().optional(),
1695
+ max_unauthenticated_sessions: import_zod2.z.number().int().positive().optional(),
1696
+ global_connection_window_ms: import_zod2.z.number().int().positive().optional(),
1697
+ global_max_new_connections_per_window: import_zod2.z.number().int().positive().optional(),
1698
+ per_ip_max_new_connections_per_window: import_zod2.z.number().int().positive().optional(),
1699
+ tls_handshake_timeout_ms: import_zod2.z.number().int().positive().optional(),
1700
+ auth_message_timeout_ms: import_zod2.z.number().int().positive().optional(),
1701
+ max_pre_auth_frame_bytes: import_zod2.z.number().int().positive().optional(),
1702
+ max_post_auth_frame_bytes: import_zod2.z.number().int().positive().optional()
1298
1703
  }).strict().optional(),
1299
- auth_controls: import_zod.z.object({
1300
- pending_auth_window_ms: import_zod.z.number().int().positive().optional(),
1301
- max_pending_auth_attempts_per_ip_per_window: import_zod.z.number().int().positive().optional(),
1302
- failed_auth_window_ms: import_zod.z.number().int().positive().optional(),
1303
- max_failed_auth_per_ip_per_window: import_zod.z.number().int().positive().optional(),
1304
- max_failed_auth_per_api_key_per_window: import_zod.z.number().int().positive().optional(),
1305
- block_duration_ms: import_zod.z.number().int().positive().optional(),
1306
- enable_blocklist: import_zod.z.boolean().optional()
1704
+ auth_controls: import_zod2.z.object({
1705
+ pending_auth_window_ms: import_zod2.z.number().int().positive().optional(),
1706
+ max_pending_auth_attempts_per_ip_per_window: import_zod2.z.number().int().positive().optional(),
1707
+ failed_auth_window_ms: import_zod2.z.number().int().positive().optional(),
1708
+ max_failed_auth_per_ip_per_window: import_zod2.z.number().int().positive().optional(),
1709
+ max_failed_auth_per_api_key_per_window: import_zod2.z.number().int().positive().optional(),
1710
+ block_duration_ms: import_zod2.z.number().int().positive().optional(),
1711
+ enable_blocklist: import_zod2.z.boolean().optional()
1307
1712
  }).strict().optional(),
1308
- request_controls: import_zod.z.object({
1309
- max_in_flight_requests_per_connection: import_zod.z.number().int().positive().optional(),
1713
+ request_controls: import_zod2.z.object({
1714
+ max_in_flight_requests_per_connection: import_zod2.z.number().int().positive().optional(),
1310
1715
  per_connection: rate_limiter_schema.optional(),
1311
1716
  per_api_key: rate_limiter_schema.optional(),
1312
1717
  per_ip: rate_limiter_schema.optional()
1313
1718
  }).strict().optional(),
1314
- observability: import_zod.z.object({
1315
- enable_console_log: import_zod.z.boolean().optional()
1719
+ observability: import_zod2.z.object({
1720
+ enable_console_log: import_zod2.z.boolean().optional()
1316
1721
  }).strict().optional()
1317
1722
  }).strict();
1318
- var daemon_server_config_schema = import_zod.z.object({
1319
- information: import_zod.z.object({
1320
- server_name: import_zod.z.string().min(1)
1723
+ var daemon_server_config_schema = import_zod2.z.object({
1724
+ information: import_zod2.z.object({
1725
+ server_name: import_zod2.z.string().min(1)
1321
1726
  }).strict(),
1322
- network: import_zod.z.object({
1323
- bind_addr: import_zod.z.string().min(1),
1324
- tcp_listen_port: import_zod.z.number().int().positive().max(65535)
1727
+ network: import_zod2.z.object({
1728
+ bind_addr: import_zod2.z.string().min(1),
1729
+ tcp_listen_port: import_zod2.z.number().int().positive().max(65535)
1325
1730
  }).strict(),
1326
- tls_mtls: import_zod.z.object({
1327
- key_file: import_zod.z.string().min(1),
1328
- cert_file: import_zod.z.string().min(1),
1329
- ca_file: import_zod.z.string().min(1),
1330
- crl_file: import_zod.z.string().min(1).optional(),
1331
- min_version: import_zod.z.enum(tls_min_version_list).optional(),
1332
- cipher_suites: import_zod.z.string().min(1).optional(),
1333
- handshake_timeout_ms: import_zod.z.number().int().positive().optional(),
1334
- request_timeout_ms: import_zod.z.number().int().positive().optional(),
1335
- max_frame_bytes: import_zod.z.number().int().positive().optional()
1731
+ tls_mtls: import_zod2.z.object({
1732
+ key_file: import_zod2.z.string().min(1),
1733
+ cert_file: import_zod2.z.string().min(1),
1734
+ ca_file: import_zod2.z.string().min(1),
1735
+ crl_file: import_zod2.z.string().min(1).optional(),
1736
+ min_version: import_zod2.z.enum(tls_min_version_list).optional(),
1737
+ cipher_suites: import_zod2.z.string().min(1).optional(),
1738
+ handshake_timeout_ms: import_zod2.z.number().int().positive().optional(),
1739
+ request_timeout_ms: import_zod2.z.number().int().positive().optional(),
1740
+ max_frame_bytes: import_zod2.z.number().int().positive().optional()
1336
1741
  }).strict(),
1337
- workerprocedurecall: import_zod.z.object({
1338
- count: import_zod.z.number().int().positive(),
1742
+ workerprocedurecall: import_zod2.z.object({
1743
+ count: import_zod2.z.number().int().positive(),
1339
1744
  constructor_options: worker_runtime_options_schema.optional(),
1340
1745
  start_options: worker_runtime_options_schema.optional()
1341
1746
  }).strict(),
1342
1747
  abuse_controls: abuse_controls_schema.optional(),
1343
- observability: import_zod.z.object({
1344
- enable_console_log: import_zod.z.boolean().optional(),
1345
- log_worker_events: import_zod.z.boolean().optional(),
1346
- metrics_log_interval_ms: import_zod.z.number().int().positive().optional()
1748
+ observability: import_zod2.z.object({
1749
+ enable_console_log: import_zod2.z.boolean().optional(),
1750
+ log_worker_events: import_zod2.z.boolean().optional(),
1751
+ metrics_log_interval_ms: import_zod2.z.number().int().positive().optional()
1347
1752
  }).strict().optional()
1348
1753
  }).strict();
1349
- var daemon_api_key_config_schema = import_zod.z.object({
1350
- api_keys: import_zod.z.array(import_zod.z.object({
1351
- key_id: import_zod.z.string().min(1),
1352
- api_key: import_zod.z.string().min(1),
1353
- privileges: import_zod.z.array(import_zod.z.enum(privilege_name_list)).min(1),
1354
- enabled: import_zod.z.boolean().optional(),
1355
- identity_constraints: import_zod.z.object({
1356
- remote_address_regex: import_zod.z.string().min(1).optional(),
1357
- tls_peer_subject_regex: import_zod.z.string().min(1).optional(),
1358
- tls_peer_san_regex: import_zod.z.string().min(1).optional(),
1359
- tls_peer_fingerprint256_regex: import_zod.z.string().min(1).optional(),
1360
- tls_peer_serial_number_regex: import_zod.z.string().min(1).optional()
1754
+ var daemon_api_key_config_schema = import_zod2.z.object({
1755
+ api_keys: import_zod2.z.array(import_zod2.z.object({
1756
+ key_id: import_zod2.z.string().min(1),
1757
+ api_key: import_zod2.z.string().min(1),
1758
+ privileges: import_zod2.z.array(import_zod2.z.enum(privilege_name_list)).min(1),
1759
+ enabled: import_zod2.z.boolean().optional(),
1760
+ identity_constraints: import_zod2.z.object({
1761
+ remote_address_regex: import_zod2.z.string().min(1).optional(),
1762
+ tls_peer_subject_regex: import_zod2.z.string().min(1).optional(),
1763
+ tls_peer_san_regex: import_zod2.z.string().min(1).optional(),
1764
+ tls_peer_fingerprint256_regex: import_zod2.z.string().min(1).optional(),
1765
+ tls_peer_serial_number_regex: import_zod2.z.string().min(1).optional()
1361
1766
  }).strict().optional()
1362
1767
  }).strict()).min(1)
1363
1768
  }).strict();
1364
- function BuildZodErrorMessage(params) {
1769
+ function BuildZodErrorMessage2(params) {
1365
1770
  const message_lines = params.error.issues.map((issue) => {
1366
1771
  const issue_path = issue.path.length > 0 ? issue.path.join(".") : "<root>";
1367
1772
  return `${issue_path}: ${issue.message}`;
@@ -1369,7 +1774,7 @@ function BuildZodErrorMessage(params) {
1369
1774
  return `${params.prefix}
1370
1775
  ${message_lines.join("\n")}`;
1371
1776
  }
1372
- __name(BuildZodErrorMessage, "BuildZodErrorMessage");
1777
+ __name(BuildZodErrorMessage2, "BuildZodErrorMessage");
1373
1778
  function CompileRegex(params) {
1374
1779
  try {
1375
1780
  return new RegExp(params.source);
@@ -1383,7 +1788,7 @@ var _ConfigValidator = class _ConfigValidator {
1383
1788
  validateServerConfig(params) {
1384
1789
  const parse_result = daemon_server_config_schema.safeParse(params.server_config_raw);
1385
1790
  if (!parse_result.success) {
1386
- throw new Error(BuildZodErrorMessage({
1791
+ throw new Error(BuildZodErrorMessage2({
1387
1792
  prefix: "Invalid server config.",
1388
1793
  error: parse_result.error
1389
1794
  }));
@@ -1393,7 +1798,7 @@ var _ConfigValidator = class _ConfigValidator {
1393
1798
  validateApiKeysConfig(params) {
1394
1799
  const parse_result = daemon_api_key_config_schema.safeParse(params.api_keys_config_raw);
1395
1800
  if (!parse_result.success) {
1396
- throw new Error(BuildZodErrorMessage({
1801
+ throw new Error(BuildZodErrorMessage2({
1397
1802
  prefix: "Invalid api-keys config.",
1398
1803
  error: parse_result.error
1399
1804
  }));
@@ -1486,20 +1891,20 @@ var ConfigValidator = _ConfigValidator;
1486
1891
  // src/classes/configfileloader/ConfigFileLoader.class.ts
1487
1892
  function ReadUtf8File(params) {
1488
1893
  try {
1489
- return import_node_fs.default.readFileSync(params.file_path, "utf8");
1894
+ return import_node_fs3.default.readFileSync(params.file_path, "utf8");
1490
1895
  } catch (error) {
1491
1896
  const error_message = error instanceof Error ? error.message : String(error);
1492
1897
  throw new Error(`Unable to read file "${params.file_path}": ${error_message}`);
1493
1898
  }
1494
1899
  }
1495
1900
  __name(ReadUtf8File, "ReadUtf8File");
1496
- function ResolvePath(params) {
1497
- if (import_node_path.default.isAbsolute(params.file_path)) {
1901
+ function ResolvePath2(params) {
1902
+ if (import_node_path3.default.isAbsolute(params.file_path)) {
1498
1903
  return params.file_path;
1499
1904
  }
1500
- return import_node_path.default.resolve(params.base_dir, params.file_path);
1905
+ return import_node_path3.default.resolve(params.base_dir, params.file_path);
1501
1906
  }
1502
- __name(ResolvePath, "ResolvePath");
1907
+ __name(ResolvePath2, "ResolvePath");
1503
1908
  function ParseJson5(params) {
1504
1909
  try {
1505
1910
  return dist_default.parse(params.content);
@@ -1515,11 +1920,11 @@ var _ConfigFileLoader = class _ConfigFileLoader {
1515
1920
  this.config_validator = params?.config_validator ?? new ConfigValidator();
1516
1921
  }
1517
1922
  loadDaemonConfig(params) {
1518
- const server_config_path = ResolvePath({
1923
+ const server_config_path = ResolvePath2({
1519
1924
  file_path: params.config_paths.server_config_path,
1520
1925
  base_dir: process.cwd()
1521
1926
  });
1522
- const api_keys_config_path = ResolvePath({
1927
+ const api_keys_config_path = ResolvePath2({
1523
1928
  file_path: params.config_paths.api_keys_config_path,
1524
1929
  base_dir: process.cwd()
1525
1930
  });
@@ -1537,7 +1942,7 @@ var _ConfigFileLoader = class _ConfigFileLoader {
1537
1942
  });
1538
1943
  const runtime_tls_mtls = this.resolveTlsMaterial({
1539
1944
  tls_file_config: server_config.tls_mtls,
1540
- config_file_dir: import_node_path.default.dirname(server_config_path)
1945
+ config_file_dir: import_node_path3.default.dirname(server_config_path)
1541
1946
  });
1542
1947
  const runtime_api_keys = this.config_validator.toRuntimeApiKeysConfig({
1543
1948
  api_keys_config
@@ -1595,7 +2000,7 @@ var _ConfigFileLoader = class _ConfigFileLoader {
1595
2000
  };
1596
2001
  }
1597
2002
  readPemFile(params) {
1598
- const absolute_file_path = ResolvePath({
2003
+ const absolute_file_path = ResolvePath2({
1599
2004
  file_path: params.pem_path,
1600
2005
  base_dir: params.config_file_dir
1601
2006
  });
@@ -1616,11 +2021,13 @@ var ConfigFileLoader = _ConfigFileLoader;
1616
2021
  var default_server_config_path = "./config/server.config.json5";
1617
2022
  var default_api_keys_config_path = "./config/api_keys.config.json5";
1618
2023
  var default_config_output_dir = "./config";
2024
+ var default_tls_config_file_path = "./config/tls_generation.config.json5";
2025
+ var default_client_tls_config_file_path = "./config/client_tls_packages.config.json5";
1619
2026
  var default_tls_output_dir = "./config/certs";
1620
2027
  var default_ca_common_name = "nodenetproccalld-local-ca";
1621
2028
  var default_server_common_name = "localhost";
1622
2029
  var default_client_common_name = "nodenetproccalld-client";
1623
- var default_tls_valid_days = 825;
2030
+ var default_tls_valid_days = 36500;
1624
2031
  var _DaemonCli = class _DaemonCli {
1625
2032
  parseOptions() {
1626
2033
  const options = {
@@ -1632,14 +2039,36 @@ var _DaemonCli = class _DaemonCli {
1632
2039
  output_dir: default_config_output_dir,
1633
2040
  overwrite: false
1634
2041
  },
2042
+ default_tls_config_generation: {
2043
+ enabled: false,
2044
+ output_file_path: default_tls_config_file_path,
2045
+ overwrite: false
2046
+ },
2047
+ default_client_tls_config_generation: {
2048
+ enabled: false,
2049
+ output_file_path: default_client_tls_config_file_path,
2050
+ overwrite: false
2051
+ },
1635
2052
  tls_generation: {
1636
2053
  enabled: false,
2054
+ config_file_path: void 0,
1637
2055
  output_dir: default_tls_output_dir,
1638
2056
  overwrite: false,
1639
2057
  ca_common_name: default_ca_common_name,
1640
2058
  server_common_name: default_server_common_name,
1641
2059
  client_common_name: default_client_common_name,
2060
+ server_dns_sans: [
2061
+ "localhost"
2062
+ ],
2063
+ server_ip_sans: [
2064
+ "127.0.0.1"
2065
+ ],
2066
+ client_uri_san: void 0,
1642
2067
  valid_days: default_tls_valid_days
2068
+ },
2069
+ client_tls_package_generation: {
2070
+ enabled: false,
2071
+ config_file_path: default_client_tls_config_file_path
1643
2072
  }
1644
2073
  };
1645
2074
  const argv = process.argv.slice(2);
@@ -1688,6 +2117,62 @@ var _DaemonCli = class _DaemonCli {
1688
2117
  options.tls_generation.enabled = true;
1689
2118
  continue;
1690
2119
  }
2120
+ if (token2 === "--tls-generation-config") {
2121
+ const next_value = argv[index + 1];
2122
+ if (!next_value) {
2123
+ throw new Error("Missing value for --tls-generation-config");
2124
+ }
2125
+ options.tls_generation.config_file_path = next_value;
2126
+ index += 1;
2127
+ continue;
2128
+ }
2129
+ if (token2 === "--generate-default-tls-config") {
2130
+ options.default_tls_config_generation.enabled = true;
2131
+ continue;
2132
+ }
2133
+ if (token2 === "--default-tls-config-file") {
2134
+ const next_value = argv[index + 1];
2135
+ if (!next_value) {
2136
+ throw new Error("Missing value for --default-tls-config-file");
2137
+ }
2138
+ options.default_tls_config_generation.output_file_path = next_value;
2139
+ index += 1;
2140
+ continue;
2141
+ }
2142
+ if (token2 === "--default-tls-config-overwrite") {
2143
+ options.default_tls_config_generation.overwrite = true;
2144
+ continue;
2145
+ }
2146
+ if (token2 === "--generate-default-client-tls-config") {
2147
+ options.default_client_tls_config_generation.enabled = true;
2148
+ continue;
2149
+ }
2150
+ if (token2 === "--default-client-tls-config-file") {
2151
+ const next_value = argv[index + 1];
2152
+ if (!next_value) {
2153
+ throw new Error("Missing value for --default-client-tls-config-file");
2154
+ }
2155
+ options.default_client_tls_config_generation.output_file_path = next_value;
2156
+ index += 1;
2157
+ continue;
2158
+ }
2159
+ if (token2 === "--default-client-tls-config-overwrite") {
2160
+ options.default_client_tls_config_generation.overwrite = true;
2161
+ continue;
2162
+ }
2163
+ if (token2 === "--generate-client-tls-packages") {
2164
+ options.client_tls_package_generation.enabled = true;
2165
+ continue;
2166
+ }
2167
+ if (token2 === "--client-tls-generation-config") {
2168
+ const next_value = argv[index + 1];
2169
+ if (!next_value) {
2170
+ throw new Error("Missing value for --client-tls-generation-config");
2171
+ }
2172
+ options.client_tls_package_generation.config_file_path = next_value;
2173
+ index += 1;
2174
+ continue;
2175
+ }
1691
2176
  if (token2 === "--tls-output-dir") {
1692
2177
  const next_value = argv[index + 1];
1693
2178
  if (!next_value) {
@@ -1762,7 +2247,28 @@ var _DaemonCli = class _DaemonCli {
1762
2247
  " Output directory for server/api-key config files.",
1763
2248
  " Default: ./config",
1764
2249
  " --default-config-overwrite Overwrite existing default config files.",
2250
+ " --generate-default-tls-config",
2251
+ " Generate a default TLS-generation JSON5 config and exit.",
2252
+ " --default-tls-config-file <path>",
2253
+ " Output path for default TLS-generation config.",
2254
+ " Default: ./config/tls_generation.config.json5",
2255
+ " --default-tls-config-overwrite",
2256
+ " Overwrite existing TLS-generation config file.",
2257
+ " --generate-default-client-tls-config",
2258
+ " Generate a default client TLS package JSON5 config and exit.",
2259
+ " --default-client-tls-config-file <path>",
2260
+ " Output path for default client TLS package config.",
2261
+ " Default: ./config/client_tls_packages.config.json5",
2262
+ " --default-client-tls-config-overwrite",
2263
+ " Overwrite existing client TLS package config file.",
1765
2264
  " --generate-tls-material Generate CA/server/client TLS material and exit.",
2265
+ " --tls-generation-config <path>",
2266
+ " Load TLS-generation options from JSON5 file.",
2267
+ " --generate-client-tls-packages",
2268
+ " Generate client cert/key packages from JSON5 config.",
2269
+ " --client-tls-generation-config <path>",
2270
+ " Path to client TLS package generation JSON5 config.",
2271
+ " Default: ./config/client_tls_packages.config.json5",
1766
2272
  " --tls-output-dir <path> Output directory for generated TLS files.",
1767
2273
  " Default: ./config/certs",
1768
2274
  " --tls-overwrite Overwrite existing TLS files in output dir.",
@@ -1773,7 +2279,7 @@ var _DaemonCli = class _DaemonCli {
1773
2279
  " --tls-client-cn <value> Client certificate common name.",
1774
2280
  " Default: nodenetproccalld-client",
1775
2281
  " --tls-valid-days <number> Certificate validity in days.",
1776
- " Default: 825",
2282
+ " Default: 36500",
1777
2283
  " -h, --help Show this help message."
1778
2284
  ].join("\n");
1779
2285
  console.log(help_text);
@@ -2103,9 +2609,61 @@ var _DaemonProcess = class _DaemonProcess {
2103
2609
  __name(_DaemonProcess, "DaemonProcess");
2104
2610
  var DaemonProcess = _DaemonProcess;
2105
2611
 
2612
+ // src/classes/defaultclienttlsgenerationconfiggenerator/DefaultClientTlsGenerationConfigGenerator.class.ts
2613
+ var import_node_fs4 = __toESM(require("fs"));
2614
+ var import_node_path4 = __toESM(require("path"));
2615
+ var default_client_tls_generation_config_template = `{
2616
+ // Existing CA files used to sign client certificates.
2617
+ // Paths are resolved relative to this config file.
2618
+ ca_key_file: './certs/ca.key.pem',
2619
+ ca_cert_file: './certs/ca.cert.pem',
2620
+
2621
+ // Where client cert bundles will be written.
2622
+ output_dir: './client_certs',
2623
+
2624
+ // Set true to replace existing client bundles.
2625
+ overwrite: false,
2626
+
2627
+ // Default validity period for generated client certs.
2628
+ default_valid_days: 36500,
2629
+
2630
+ clients: [
2631
+ {
2632
+ client_name: 'your_client_name_here',
2633
+ common_name: 'your_client_name_here',
2634
+ uri_san: 'spiffe://nodenetproccalld/your_client_name_here',
2635
+ package_name: 'your_client_name_here_bundle'
2636
+ },
2637
+ {
2638
+ client_name: 'localhost',
2639
+ common_name: 'localhost',
2640
+ uri_san: 'spiffe://nodenetproccalld/localhost',
2641
+ package_name: 'localhost_bundle'
2642
+ }
2643
+ ]
2644
+ }
2645
+ `;
2646
+ var _DefaultClientTlsGenerationConfigGenerator = class _DefaultClientTlsGenerationConfigGenerator {
2647
+ generateDefaultClientTlsGenerationConfig(params) {
2648
+ const output_file_path = import_node_path4.default.resolve(process.cwd(), params.default_client_tls_config_generation_options.output_file_path);
2649
+ if (!params.default_client_tls_config_generation_options.overwrite && import_node_fs4.default.existsSync(output_file_path)) {
2650
+ throw new Error(`Refusing to overwrite existing client TLS config "${output_file_path}". Use --default-client-tls-config-overwrite to replace it.`);
2651
+ }
2652
+ import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(output_file_path), {
2653
+ recursive: true
2654
+ });
2655
+ import_node_fs4.default.writeFileSync(output_file_path, default_client_tls_generation_config_template, "utf8");
2656
+ return {
2657
+ output_file_path
2658
+ };
2659
+ }
2660
+ };
2661
+ __name(_DefaultClientTlsGenerationConfigGenerator, "DefaultClientTlsGenerationConfigGenerator");
2662
+ var DefaultClientTlsGenerationConfigGenerator = _DefaultClientTlsGenerationConfigGenerator;
2663
+
2106
2664
  // src/classes/defaultconfiggenerator/DefaultConfigGenerator.class.ts
2107
- var import_node_fs2 = __toESM(require("fs"));
2108
- var import_node_path2 = __toESM(require("path"));
2665
+ var import_node_fs5 = __toESM(require("fs"));
2666
+ var import_node_path5 = __toESM(require("path"));
2109
2667
  var default_server_config_template = `{
2110
2668
  // Friendly name that clients can use in their own config maps.
2111
2669
  information: {
@@ -2209,28 +2767,28 @@ var default_api_keys_config_template = `{
2209
2767
  }
2210
2768
  `;
2211
2769
  function EnsureParentDirectory(params) {
2212
- import_node_fs2.default.mkdirSync(import_node_path2.default.dirname(params.file_path), {
2770
+ import_node_fs5.default.mkdirSync(import_node_path5.default.dirname(params.file_path), {
2213
2771
  recursive: true
2214
2772
  });
2215
2773
  }
2216
2774
  __name(EnsureParentDirectory, "EnsureParentDirectory");
2217
2775
  function WriteFileIfAllowed(params) {
2218
- if (!params.overwrite && import_node_fs2.default.existsSync(params.file_path)) {
2776
+ if (!params.overwrite && import_node_fs5.default.existsSync(params.file_path)) {
2219
2777
  throw new Error(`Refusing to overwrite existing config "${params.file_path}". Use --default-config-overwrite to replace it.`);
2220
2778
  }
2221
2779
  EnsureParentDirectory({
2222
2780
  file_path: params.file_path
2223
2781
  });
2224
- import_node_fs2.default.writeFileSync(params.file_path, params.content, "utf8");
2782
+ import_node_fs5.default.writeFileSync(params.file_path, params.content, "utf8");
2225
2783
  }
2226
2784
  __name(WriteFileIfAllowed, "WriteFileIfAllowed");
2227
2785
  var _DefaultConfigGenerator = class _DefaultConfigGenerator {
2228
2786
  generateDefaultConfig(params) {
2229
2787
  const options = params.default_config_generation_options;
2230
- const output_dir = import_node_path2.default.resolve(process.cwd(), options.output_dir);
2231
- const server_config_path = import_node_path2.default.join(output_dir, "server.config.json5");
2232
- const api_keys_config_path = import_node_path2.default.join(output_dir, "api_keys.config.json5");
2233
- import_node_fs2.default.mkdirSync(output_dir, {
2788
+ const output_dir = import_node_path5.default.resolve(process.cwd(), options.output_dir);
2789
+ const server_config_path = import_node_path5.default.join(output_dir, "server.config.json5");
2790
+ const api_keys_config_path = import_node_path5.default.join(output_dir, "api_keys.config.json5");
2791
+ import_node_fs5.default.mkdirSync(output_dir, {
2234
2792
  recursive: true
2235
2793
  });
2236
2794
  WriteFileIfAllowed({
@@ -2253,10 +2811,117 @@ var _DefaultConfigGenerator = class _DefaultConfigGenerator {
2253
2811
  __name(_DefaultConfigGenerator, "DefaultConfigGenerator");
2254
2812
  var DefaultConfigGenerator = _DefaultConfigGenerator;
2255
2813
 
2814
+ // src/classes/defaulttlsgenerationconfiggenerator/DefaultTlsGenerationConfigGenerator.class.ts
2815
+ var import_node_fs6 = __toESM(require("fs"));
2816
+ var import_node_path6 = __toESM(require("path"));
2817
+ var default_tls_generation_config_template = `{
2818
+ // Where generated CA/server/client cert + key files should be written.
2819
+ output_dir: './config/certs',
2820
+
2821
+ // Set true to replace existing files in output_dir.
2822
+ overwrite: false,
2823
+
2824
+ // X.509 subject common names.
2825
+ ca_common_name: 'nodenetproccalld-local-ca',
2826
+ server_common_name: 'your_server_name_here',
2827
+ client_common_name: 'nodenetproccalld-client',
2828
+
2829
+ // Server certificate SAN entries used by hostname validation.
2830
+ // Add the DNS names and IPs clients will actually connect to.
2831
+ server_dns_sans: ['your_server_name_here', 'localhost'],
2832
+ server_ip_sans: ['127.0.0.1'],
2833
+
2834
+ // Optional explicit client URI SAN; when omitted, generator derives one from client_common_name.
2835
+ // client_uri_san: 'spiffe://nodenetproccalld/client',
2836
+
2837
+ // Certificate validity period.
2838
+ valid_days: 36500
2839
+ }
2840
+ `;
2841
+ var _DefaultTlsGenerationConfigGenerator = class _DefaultTlsGenerationConfigGenerator {
2842
+ generateDefaultTlsGenerationConfig(params) {
2843
+ const output_file_path = import_node_path6.default.resolve(process.cwd(), params.default_tls_config_generation_options.output_file_path);
2844
+ if (!params.default_tls_config_generation_options.overwrite && import_node_fs6.default.existsSync(output_file_path)) {
2845
+ throw new Error(`Refusing to overwrite existing TLS generation config "${output_file_path}". Use --default-tls-config-overwrite to replace it.`);
2846
+ }
2847
+ import_node_fs6.default.mkdirSync(import_node_path6.default.dirname(output_file_path), {
2848
+ recursive: true
2849
+ });
2850
+ import_node_fs6.default.writeFileSync(output_file_path, default_tls_generation_config_template, "utf8");
2851
+ return {
2852
+ output_file_path
2853
+ };
2854
+ }
2855
+ };
2856
+ __name(_DefaultTlsGenerationConfigGenerator, "DefaultTlsGenerationConfigGenerator");
2857
+ var DefaultTlsGenerationConfigGenerator = _DefaultTlsGenerationConfigGenerator;
2858
+
2859
+ // src/classes/tlsgenerationconfigfileloader/TlsGenerationConfigFileLoader.class.ts
2860
+ var import_node_fs7 = __toESM(require("fs"));
2861
+ var import_node_path7 = __toESM(require("path"));
2862
+ var import_zod3 = require("zod");
2863
+ var tls_generation_config_schema = import_zod3.z.object({
2864
+ output_dir: import_zod3.z.string().min(1).optional(),
2865
+ overwrite: import_zod3.z.boolean().optional(),
2866
+ ca_common_name: import_zod3.z.string().min(1).optional(),
2867
+ server_common_name: import_zod3.z.string().min(1).optional(),
2868
+ client_common_name: import_zod3.z.string().min(1).optional(),
2869
+ server_dns_sans: import_zod3.z.array(import_zod3.z.string().min(1)).optional(),
2870
+ server_ip_sans: import_zod3.z.array(import_zod3.z.string().min(1)).optional(),
2871
+ client_uri_san: import_zod3.z.string().min(1).optional(),
2872
+ valid_days: import_zod3.z.number().int().positive().optional()
2873
+ }).strict();
2874
+ function ParseJson5File2(params) {
2875
+ const absolute_file_path = import_node_path7.default.resolve(process.cwd(), params.file_path);
2876
+ let file_content;
2877
+ try {
2878
+ file_content = import_node_fs7.default.readFileSync(absolute_file_path, "utf8");
2879
+ } catch (error) {
2880
+ const error_message = error instanceof Error ? error.message : String(error);
2881
+ throw new Error(`Unable to read TLS generation config file "${absolute_file_path}": ${error_message}`);
2882
+ }
2883
+ try {
2884
+ return dist_default.parse(file_content);
2885
+ } catch (error) {
2886
+ const error_message = error instanceof Error ? error.message : String(error);
2887
+ throw new Error(`Invalid JSON5 in TLS generation config "${absolute_file_path}": ${error_message}`);
2888
+ }
2889
+ }
2890
+ __name(ParseJson5File2, "ParseJson5File");
2891
+ function BuildZodErrorMessage3(params) {
2892
+ const lines = params.error.issues.map((issue) => {
2893
+ const issue_path = issue.path.length > 0 ? issue.path.join(".") : "<root>";
2894
+ return `${issue_path}: ${issue.message}`;
2895
+ });
2896
+ return `Invalid TLS generation config file.
2897
+ ${lines.join("\n")}`;
2898
+ }
2899
+ __name(BuildZodErrorMessage3, "BuildZodErrorMessage");
2900
+ var _TlsGenerationConfigFileLoader = class _TlsGenerationConfigFileLoader {
2901
+ loadTlsGenerationOptions(params) {
2902
+ const config_raw = ParseJson5File2({
2903
+ file_path: params.config_file_path
2904
+ });
2905
+ const parse_result = tls_generation_config_schema.safeParse(config_raw);
2906
+ if (!parse_result.success) {
2907
+ throw new Error(BuildZodErrorMessage3({
2908
+ error: parse_result.error
2909
+ }));
2910
+ }
2911
+ const config_from_file = parse_result.data;
2912
+ return {
2913
+ ...params.fallback_options,
2914
+ ...config_from_file
2915
+ };
2916
+ }
2917
+ };
2918
+ __name(_TlsGenerationConfigFileLoader, "TlsGenerationConfigFileLoader");
2919
+ var TlsGenerationConfigFileLoader = _TlsGenerationConfigFileLoader;
2920
+
2256
2921
  // src/classes/tlsmaterialgenerator/TlsMaterialGenerator.class.ts
2257
- var import_node_child_process = require("child_process");
2258
- var import_node_fs3 = __toESM(require("fs"));
2259
- var import_node_path3 = __toESM(require("path"));
2922
+ var import_node_child_process2 = require("child_process");
2923
+ var import_node_fs8 = __toESM(require("fs"));
2924
+ var import_node_path8 = __toESM(require("path"));
2260
2925
  function EnsurePositiveInteger(params) {
2261
2926
  if (!Number.isInteger(params.value) || params.value <= 0) {
2262
2927
  throw new Error(`${params.label} must be a positive integer.`);
@@ -2264,15 +2929,35 @@ function EnsurePositiveInteger(params) {
2264
2929
  }
2265
2930
  __name(EnsurePositiveInteger, "EnsurePositiveInteger");
2266
2931
  function MakeDirRecursive(params) {
2267
- import_node_fs3.default.mkdirSync(params.dir_path, {
2932
+ import_node_fs8.default.mkdirSync(params.dir_path, {
2268
2933
  recursive: true
2269
2934
  });
2270
2935
  }
2271
2936
  __name(MakeDirRecursive, "MakeDirRecursive");
2272
- function WriteTextFile(params) {
2273
- import_node_fs3.default.writeFileSync(params.file_path, params.content, "utf8");
2937
+ function WriteTextFile2(params) {
2938
+ import_node_fs8.default.writeFileSync(params.file_path, params.content, "utf8");
2274
2939
  }
2275
- __name(WriteTextFile, "WriteTextFile");
2940
+ __name(WriteTextFile2, "WriteTextFile");
2941
+ function BuildServerSubjectAltNameLine(params) {
2942
+ const san_entries = [];
2943
+ for (const dns_name of params.server_dns_sans) {
2944
+ if (dns_name.trim().length === 0) {
2945
+ continue;
2946
+ }
2947
+ san_entries.push(`DNS:${dns_name.trim()}`);
2948
+ }
2949
+ for (const ip_addr of params.server_ip_sans) {
2950
+ if (ip_addr.trim().length === 0) {
2951
+ continue;
2952
+ }
2953
+ san_entries.push(`IP:${ip_addr.trim()}`);
2954
+ }
2955
+ if (san_entries.length === 0) {
2956
+ throw new Error("TLS generation requires at least one SAN entry. Provide server_dns_sans or server_ip_sans.");
2957
+ }
2958
+ return `subjectAltName=${san_entries.join(",")}`;
2959
+ }
2960
+ __name(BuildServerSubjectAltNameLine, "BuildServerSubjectAltNameLine");
2276
2961
  var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2277
2962
  generateTlsMaterial(params) {
2278
2963
  const options = params.tls_generation_options;
@@ -2280,7 +2965,7 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2280
2965
  value: options.valid_days,
2281
2966
  label: "tls_generation.valid_days"
2282
2967
  });
2283
- const output_dir = import_node_path3.default.resolve(process.cwd(), options.output_dir);
2968
+ const output_dir = import_node_path8.default.resolve(process.cwd(), options.output_dir);
2284
2969
  MakeDirRecursive({
2285
2970
  dir_path: output_dir
2286
2971
  });
@@ -2301,12 +2986,15 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2301
2986
  this.generateServerCertificate({
2302
2987
  tls_files,
2303
2988
  valid_days: options.valid_days,
2304
- server_common_name: options.server_common_name
2989
+ server_common_name: options.server_common_name,
2990
+ server_dns_sans: options.server_dns_sans,
2991
+ server_ip_sans: options.server_ip_sans
2305
2992
  });
2306
2993
  this.generateClientCertificate({
2307
2994
  tls_files,
2308
2995
  valid_days: options.valid_days,
2309
- client_common_name: options.client_common_name
2996
+ client_common_name: options.client_common_name,
2997
+ client_uri_san: options.client_uri_san
2310
2998
  });
2311
2999
  this.cleanupIntermediateFiles({
2312
3000
  tls_files
@@ -2328,7 +3016,7 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2328
3016
  }
2329
3017
  assertOpenSslAvailable() {
2330
3018
  try {
2331
- (0, import_node_child_process.execFileSync)("openssl", [
3019
+ (0, import_node_child_process2.execFileSync)("openssl", [
2332
3020
  "version"
2333
3021
  ], {
2334
3022
  stdio: "ignore"
@@ -2339,17 +3027,17 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2339
3027
  }
2340
3028
  buildTlsFileMap(params) {
2341
3029
  return {
2342
- ca_key_path: import_node_path3.default.join(params.output_dir, "ca.key.pem"),
2343
- ca_cert_path: import_node_path3.default.join(params.output_dir, "ca.cert.pem"),
2344
- server_key_path: import_node_path3.default.join(params.output_dir, "server.key.pem"),
2345
- server_csr_path: import_node_path3.default.join(params.output_dir, "server.csr.pem"),
2346
- server_cert_path: import_node_path3.default.join(params.output_dir, "server.cert.pem"),
2347
- server_ext_path: import_node_path3.default.join(params.output_dir, "server.ext"),
2348
- client_key_path: import_node_path3.default.join(params.output_dir, "client.key.pem"),
2349
- client_csr_path: import_node_path3.default.join(params.output_dir, "client.csr.pem"),
2350
- client_cert_path: import_node_path3.default.join(params.output_dir, "client.cert.pem"),
2351
- client_ext_path: import_node_path3.default.join(params.output_dir, "client.ext"),
2352
- ca_serial_path: import_node_path3.default.join(params.output_dir, "ca.cert.srl")
3030
+ ca_key_path: import_node_path8.default.join(params.output_dir, "ca.key.pem"),
3031
+ ca_cert_path: import_node_path8.default.join(params.output_dir, "ca.cert.pem"),
3032
+ server_key_path: import_node_path8.default.join(params.output_dir, "server.key.pem"),
3033
+ server_csr_path: import_node_path8.default.join(params.output_dir, "server.csr.pem"),
3034
+ server_cert_path: import_node_path8.default.join(params.output_dir, "server.cert.pem"),
3035
+ server_ext_path: import_node_path8.default.join(params.output_dir, "server.ext"),
3036
+ client_key_path: import_node_path8.default.join(params.output_dir, "client.key.pem"),
3037
+ client_csr_path: import_node_path8.default.join(params.output_dir, "client.csr.pem"),
3038
+ client_cert_path: import_node_path8.default.join(params.output_dir, "client.cert.pem"),
3039
+ client_ext_path: import_node_path8.default.join(params.output_dir, "client.ext"),
3040
+ ca_serial_path: import_node_path8.default.join(params.output_dir, "ca.cert.srl")
2353
3041
  };
2354
3042
  }
2355
3043
  assertTargetFilesAreWritable(params) {
@@ -2363,18 +3051,18 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2363
3051
  ];
2364
3052
  if (!params.overwrite) {
2365
3053
  for (const target_path of target_paths) {
2366
- if (import_node_fs3.default.existsSync(target_path)) {
3054
+ if (import_node_fs8.default.existsSync(target_path)) {
2367
3055
  throw new Error(`Refusing to overwrite existing file "${target_path}". Use --tls-overwrite to replace existing material.`);
2368
3056
  }
2369
3057
  }
2370
3058
  return;
2371
3059
  }
2372
3060
  for (const target_path of target_paths) {
2373
- import_node_fs3.default.rmSync(target_path, {
3061
+ import_node_fs8.default.rmSync(target_path, {
2374
3062
  force: true
2375
3063
  });
2376
3064
  }
2377
- import_node_fs3.default.rmSync(params.tls_files.ca_serial_path, {
3065
+ import_node_fs8.default.rmSync(params.tls_files.ca_serial_path, {
2378
3066
  force: true
2379
3067
  });
2380
3068
  }
@@ -2399,10 +3087,13 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2399
3087
  });
2400
3088
  }
2401
3089
  generateServerCertificate(params) {
2402
- WriteTextFile({
3090
+ WriteTextFile2({
2403
3091
  file_path: params.tls_files.server_ext_path,
2404
3092
  content: [
2405
- "subjectAltName=DNS:localhost,IP:127.0.0.1",
3093
+ BuildServerSubjectAltNameLine({
3094
+ server_dns_sans: params.server_dns_sans,
3095
+ server_ip_sans: params.server_ip_sans
3096
+ }),
2406
3097
  "extendedKeyUsage=serverAuth",
2407
3098
  "keyUsage=digitalSignature,keyEncipherment"
2408
3099
  ].join("\n")
@@ -2447,8 +3138,8 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2447
3138
  });
2448
3139
  }
2449
3140
  generateClientCertificate(params) {
2450
- const client_uri = `spiffe://nodenetproccalld/${params.client_common_name.replace(/[^a-zA-Z0-9_.-]/g, "_").toLowerCase()}`;
2451
- WriteTextFile({
3141
+ const client_uri = params.client_uri_san ?? `spiffe://nodenetproccalld/${params.client_common_name.replace(/[^a-zA-Z0-9_.-]/g, "_").toLowerCase()}`;
3142
+ WriteTextFile2({
2452
3143
  file_path: params.tls_files.client_ext_path,
2453
3144
  content: [
2454
3145
  "extendedKeyUsage=clientAuth",
@@ -2495,24 +3186,24 @@ var _TlsMaterialGenerator = class _TlsMaterialGenerator {
2495
3186
  });
2496
3187
  }
2497
3188
  cleanupIntermediateFiles(params) {
2498
- import_node_fs3.default.rmSync(params.tls_files.server_csr_path, {
3189
+ import_node_fs8.default.rmSync(params.tls_files.server_csr_path, {
2499
3190
  force: true
2500
3191
  });
2501
- import_node_fs3.default.rmSync(params.tls_files.client_csr_path, {
3192
+ import_node_fs8.default.rmSync(params.tls_files.client_csr_path, {
2502
3193
  force: true
2503
3194
  });
2504
- import_node_fs3.default.rmSync(params.tls_files.server_ext_path, {
3195
+ import_node_fs8.default.rmSync(params.tls_files.server_ext_path, {
2505
3196
  force: true
2506
3197
  });
2507
- import_node_fs3.default.rmSync(params.tls_files.client_ext_path, {
3198
+ import_node_fs8.default.rmSync(params.tls_files.client_ext_path, {
2508
3199
  force: true
2509
3200
  });
2510
- import_node_fs3.default.rmSync(params.tls_files.ca_serial_path, {
3201
+ import_node_fs8.default.rmSync(params.tls_files.ca_serial_path, {
2511
3202
  force: true
2512
3203
  });
2513
3204
  }
2514
3205
  runOpenSslCommand(params) {
2515
- (0, import_node_child_process.execFileSync)("openssl", params.args, {
3206
+ (0, import_node_child_process2.execFileSync)("openssl", params.args, {
2516
3207
  stdio: "ignore"
2517
3208
  });
2518
3209
  }
@@ -2545,10 +3236,36 @@ async function StartDaemonFromCli() {
2545
3236
  console.log(`API keys config: ${generated_default_config.api_keys_config_path}`);
2546
3237
  return;
2547
3238
  }
3239
+ if (cli_options.default_tls_config_generation.enabled) {
3240
+ const default_tls_generation_config_generator = new DefaultTlsGenerationConfigGenerator();
3241
+ const generated_default_tls_config = default_tls_generation_config_generator.generateDefaultTlsGenerationConfig({
3242
+ default_tls_config_generation_options: cli_options.default_tls_config_generation
3243
+ });
3244
+ console.log("Default TLS-generation config generated successfully.");
3245
+ console.log(`TLS-generation config: ${generated_default_tls_config.output_file_path}`);
3246
+ return;
3247
+ }
3248
+ if (cli_options.default_client_tls_config_generation.enabled) {
3249
+ const default_client_tls_config_generator = new DefaultClientTlsGenerationConfigGenerator();
3250
+ const generated_default_client_tls_config = default_client_tls_config_generator.generateDefaultClientTlsGenerationConfig({
3251
+ default_client_tls_config_generation_options: cli_options.default_client_tls_config_generation
3252
+ });
3253
+ console.log("Default client TLS package config generated successfully.");
3254
+ console.log(`Client TLS package config: ${generated_default_client_tls_config.output_file_path}`);
3255
+ return;
3256
+ }
2548
3257
  if (cli_options.tls_generation.enabled) {
3258
+ let tls_generation_options = cli_options.tls_generation;
3259
+ if (cli_options.tls_generation.config_file_path) {
3260
+ const tls_generation_config_file_loader = new TlsGenerationConfigFileLoader();
3261
+ tls_generation_options = tls_generation_config_file_loader.loadTlsGenerationOptions({
3262
+ config_file_path: cli_options.tls_generation.config_file_path,
3263
+ fallback_options: tls_generation_options
3264
+ });
3265
+ }
2549
3266
  const tls_material_generator = new TlsMaterialGenerator();
2550
3267
  const generated_tls_material = tls_material_generator.generateTlsMaterial({
2551
- tls_generation_options: cli_options.tls_generation
3268
+ tls_generation_options
2552
3269
  });
2553
3270
  console.log("TLS material generated successfully.");
2554
3271
  console.log(`Output directory: ${generated_tls_material.output_dir}`);
@@ -2561,6 +3278,22 @@ async function StartDaemonFromCli() {
2561
3278
  console.log("If using default config, set tls_mtls key_file/cert_file/ca_file in config/server.config.json5 to these files.");
2562
3279
  return;
2563
3280
  }
3281
+ if (cli_options.client_tls_package_generation.enabled) {
3282
+ const client_tls_package_config_file_loader = new ClientTlsPackageConfigFileLoader();
3283
+ const runtime_options = client_tls_package_config_file_loader.loadClientTlsPackageOptions({
3284
+ client_tls_package_generation_options: cli_options.client_tls_package_generation
3285
+ });
3286
+ const client_tls_package_generator = new ClientTlsPackageGenerator();
3287
+ const generated_client_tls_packages = client_tls_package_generator.generateClientTlsPackages({
3288
+ runtime_options
3289
+ });
3290
+ console.log("Client TLS packages generated successfully.");
3291
+ console.log(`Output directory: ${generated_client_tls_packages.output_dir}`);
3292
+ for (const generated_package of generated_client_tls_packages.packages) {
3293
+ console.log(`Client ${generated_package.client_name}: ${generated_package.package_path}`);
3294
+ }
3295
+ return;
3296
+ }
2564
3297
  const daemon_process = new DaemonProcess({
2565
3298
  config_paths: {
2566
3299
  server_config_path: cli_options.server_config_path,
@@ -2580,12 +3313,17 @@ if (require.main === module) {
2580
3313
  // Annotate the CommonJS export names for ESM import in node:
2581
3314
  0 && (module.exports = {
2582
3315
  ApiKeyAuthorizer,
3316
+ ClientTlsPackageConfigFileLoader,
3317
+ ClientTlsPackageGenerator,
2583
3318
  ConfigFileLoader,
2584
3319
  ConfigValidator,
2585
3320
  DaemonCli,
2586
3321
  DaemonProcess,
3322
+ DefaultClientTlsGenerationConfigGenerator,
2587
3323
  DefaultConfigGenerator,
3324
+ DefaultTlsGenerationConfigGenerator,
2588
3325
  NetworkProcedureCallDaemon,
3326
+ TlsGenerationConfigFileLoader,
2589
3327
  TlsMaterialGenerator
2590
3328
  });
2591
3329
  //# sourceMappingURL=index.js.map