@serve.zone/dcrouter 11.23.4 → 12.0.0

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.
Files changed (119) hide show
  1. package/dist_serve/bundle.js +1 -1
  2. package/dist_ts/00_commitinfo_data.js +2 -2
  3. package/dist_ts/classes.cert-provision-scheduler.d.ts +6 -8
  4. package/dist_ts/classes.cert-provision-scheduler.js +37 -17
  5. package/dist_ts/classes.dcrouter.d.ts +15 -29
  6. package/dist_ts/classes.dcrouter.js +96 -91
  7. package/dist_ts/classes.storage-cert-manager.d.ts +3 -6
  8. package/dist_ts/classes.storage-cert-manager.js +35 -25
  9. package/dist_ts/config/classes.api-token-manager.d.ts +1 -3
  10. package/dist_ts/config/classes.api-token-manager.js +45 -15
  11. package/dist_ts/config/classes.route-config-manager.d.ts +1 -3
  12. package/dist_ts/config/classes.route-config-manager.js +63 -25
  13. package/dist_ts/{cache → db}/classes.cache.cleaner.d.ts +3 -3
  14. package/dist_ts/db/classes.cache.cleaner.js +130 -0
  15. package/dist_ts/{cache → db}/classes.cached.document.js +1 -1
  16. package/dist_ts/db/classes.dcrouter-db.d.ts +70 -0
  17. package/dist_ts/db/classes.dcrouter-db.js +146 -0
  18. package/dist_ts/db/documents/classes.accounting-session.doc.d.ts +32 -0
  19. package/dist_ts/db/documents/classes.accounting-session.doc.js +214 -0
  20. package/dist_ts/db/documents/classes.acme-cert.doc.d.ts +13 -0
  21. package/dist_ts/db/documents/classes.acme-cert.doc.js +109 -0
  22. package/dist_ts/db/documents/classes.api-token.doc.d.ts +18 -0
  23. package/dist_ts/db/documents/classes.api-token.doc.js +127 -0
  24. package/dist_ts/{cache → db}/documents/classes.cached.email.js +3 -3
  25. package/dist_ts/{cache → db}/documents/classes.cached.ip.reputation.js +3 -3
  26. package/dist_ts/db/documents/classes.cert-backoff.doc.d.ts +11 -0
  27. package/dist_ts/db/documents/classes.cert-backoff.doc.js +97 -0
  28. package/dist_ts/db/documents/classes.proxy-cert.doc.d.ts +12 -0
  29. package/dist_ts/db/documents/classes.proxy-cert.doc.js +103 -0
  30. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.d.ts +17 -0
  31. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.js +130 -0
  32. package/dist_ts/db/documents/classes.route-override.doc.d.ts +10 -0
  33. package/dist_ts/db/documents/classes.route-override.doc.js +91 -0
  34. package/dist_ts/db/documents/classes.stored-route.doc.d.ts +12 -0
  35. package/dist_ts/db/documents/classes.stored-route.doc.js +103 -0
  36. package/dist_ts/db/documents/classes.vlan-mappings.doc.d.ts +15 -0
  37. package/dist_ts/db/documents/classes.vlan-mappings.doc.js +77 -0
  38. package/dist_ts/db/documents/classes.vpn-client.doc.d.ts +18 -0
  39. package/dist_ts/db/documents/classes.vpn-client.doc.js +136 -0
  40. package/dist_ts/db/documents/classes.vpn-server-keys.doc.d.ts +10 -0
  41. package/dist_ts/db/documents/classes.vpn-server-keys.doc.js +94 -0
  42. package/dist_ts/db/documents/index.d.ts +13 -0
  43. package/dist_ts/db/documents/index.js +20 -0
  44. package/dist_ts/{cache → db}/index.d.ts +1 -1
  45. package/dist_ts/db/index.js +9 -0
  46. package/dist_ts/opsserver/handlers/certificate.handler.js +66 -66
  47. package/dist_ts/opsserver/handlers/config.handler.js +14 -15
  48. package/dist_ts/paths.d.ts +0 -1
  49. package/dist_ts/paths.js +1 -2
  50. package/dist_ts/radius/classes.accounting.manager.d.ts +4 -12
  51. package/dist_ts/radius/classes.accounting.manager.js +80 -93
  52. package/dist_ts/radius/classes.radius.server.d.ts +1 -3
  53. package/dist_ts/radius/classes.radius.server.js +4 -6
  54. package/dist_ts/radius/classes.vlan.manager.d.ts +3 -7
  55. package/dist_ts/radius/classes.vlan.manager.js +21 -28
  56. package/dist_ts/radius/index.d.ts +1 -1
  57. package/dist_ts/radius/index.js +1 -1
  58. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +3 -5
  59. package/dist_ts/remoteingress/classes.remoteingress-manager.js +41 -21
  60. package/dist_ts/security/classes.ipreputationchecker.d.ts +6 -21
  61. package/dist_ts/security/classes.ipreputationchecker.js +59 -138
  62. package/dist_ts/vpn/classes.vpn-manager.d.ts +4 -22
  63. package/dist_ts/vpn/classes.vpn-manager.js +40 -45
  64. package/dist_ts_oci_container/index.js +4 -4
  65. package/dist_ts_web/00_commitinfo_data.js +2 -2
  66. package/package.json +1 -1
  67. package/readme.storage.md +55 -91
  68. package/ts/00_commitinfo_data.ts +1 -1
  69. package/ts/classes.cert-provision-scheduler.ts +35 -17
  70. package/ts/classes.dcrouter.ts +113 -125
  71. package/ts/classes.storage-cert-manager.ts +34 -22
  72. package/ts/config/classes.api-token-manager.ts +42 -11
  73. package/ts/config/classes.route-config-manager.ts +57 -22
  74. package/ts/{cache → db}/classes.cache.cleaner.ts +6 -6
  75. package/ts/db/classes.dcrouter-db.ts +179 -0
  76. package/ts/db/documents/classes.accounting-session.doc.ts +106 -0
  77. package/ts/db/documents/classes.acme-cert.doc.ts +41 -0
  78. package/ts/db/documents/classes.api-token.doc.ts +56 -0
  79. package/ts/{cache → db}/documents/classes.cached.email.ts +2 -2
  80. package/ts/{cache → db}/documents/classes.cached.ip.reputation.ts +2 -2
  81. package/ts/db/documents/classes.cert-backoff.doc.ts +35 -0
  82. package/ts/db/documents/classes.proxy-cert.doc.ts +38 -0
  83. package/ts/db/documents/classes.remote-ingress-edge.doc.ts +54 -0
  84. package/ts/db/documents/classes.route-override.doc.ts +32 -0
  85. package/ts/db/documents/classes.stored-route.doc.ts +38 -0
  86. package/ts/db/documents/classes.vlan-mappings.doc.ts +32 -0
  87. package/ts/db/documents/classes.vpn-client.doc.ts +57 -0
  88. package/ts/db/documents/classes.vpn-server-keys.doc.ts +31 -0
  89. package/ts/db/documents/index.ts +24 -0
  90. package/ts/{cache → db}/index.ts +6 -2
  91. package/ts/opsserver/handlers/certificate.handler.ts +67 -65
  92. package/ts/opsserver/handlers/config.handler.ts +13 -14
  93. package/ts/paths.ts +0 -1
  94. package/ts/radius/classes.accounting.manager.ts +81 -103
  95. package/ts/radius/classes.radius.server.ts +3 -6
  96. package/ts/radius/classes.vlan.manager.ts +20 -32
  97. package/ts/radius/index.ts +1 -1
  98. package/ts/remoteingress/classes.remoteingress-manager.ts +40 -22
  99. package/ts/security/classes.ipreputationchecker.ts +103 -196
  100. package/ts/vpn/classes.vpn-manager.ts +44 -75
  101. package/ts_web/00_commitinfo_data.ts +1 -1
  102. package/dist_ts/cache/classes.cache.cleaner.js +0 -130
  103. package/dist_ts/cache/classes.cachedb.d.ts +0 -60
  104. package/dist_ts/cache/classes.cachedb.js +0 -126
  105. package/dist_ts/cache/documents/index.d.ts +0 -2
  106. package/dist_ts/cache/documents/index.js +0 -3
  107. package/dist_ts/cache/index.js +0 -7
  108. package/dist_ts/storage/classes.storagemanager.d.ts +0 -83
  109. package/dist_ts/storage/classes.storagemanager.js +0 -348
  110. package/dist_ts/storage/index.d.ts +0 -1
  111. package/dist_ts/storage/index.js +0 -3
  112. package/ts/cache/classes.cachedb.ts +0 -155
  113. package/ts/cache/documents/index.ts +0 -2
  114. package/ts/storage/classes.storagemanager.ts +0 -404
  115. package/ts/storage/index.ts +0 -2
  116. /package/dist_ts/{cache → db}/classes.cached.document.d.ts +0 -0
  117. /package/dist_ts/{cache → db}/documents/classes.cached.email.d.ts +0 -0
  118. /package/dist_ts/{cache → db}/documents/classes.cached.ip.reputation.d.ts +0 -0
  119. /package/ts/{cache → db}/classes.cached.document.ts +0 -0
@@ -0,0 +1,54 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { DcRouterDb } from '../classes.dcrouter-db.js';
3
+
4
+ const getDb = () => DcRouterDb.getInstance().getDb();
5
+
6
+ @plugins.smartdata.Collection(() => getDb())
7
+ export class RemoteIngressEdgeDoc extends plugins.smartdata.SmartDataDbDoc<RemoteIngressEdgeDoc, RemoteIngressEdgeDoc> {
8
+ @plugins.smartdata.unI()
9
+ @plugins.smartdata.svDb()
10
+ public id!: string;
11
+
12
+ @plugins.smartdata.svDb()
13
+ public name: string = '';
14
+
15
+ @plugins.smartdata.svDb()
16
+ public secret!: string;
17
+
18
+ @plugins.smartdata.svDb()
19
+ public listenPorts!: number[];
20
+
21
+ @plugins.smartdata.svDb()
22
+ public listenPortsUdp!: number[];
23
+
24
+ @plugins.smartdata.svDb()
25
+ public enabled!: boolean;
26
+
27
+ @plugins.smartdata.svDb()
28
+ public autoDerivePorts!: boolean;
29
+
30
+ @plugins.smartdata.svDb()
31
+ public tags!: string[];
32
+
33
+ @plugins.smartdata.svDb()
34
+ public createdAt!: number;
35
+
36
+ @plugins.smartdata.svDb()
37
+ public updatedAt!: number;
38
+
39
+ constructor() {
40
+ super();
41
+ }
42
+
43
+ public static async findById(id: string): Promise<RemoteIngressEdgeDoc | null> {
44
+ return await RemoteIngressEdgeDoc.getInstance({ id });
45
+ }
46
+
47
+ public static async findAll(): Promise<RemoteIngressEdgeDoc[]> {
48
+ return await RemoteIngressEdgeDoc.getInstances({});
49
+ }
50
+
51
+ public static async findEnabled(): Promise<RemoteIngressEdgeDoc[]> {
52
+ return await RemoteIngressEdgeDoc.getInstances({ enabled: true });
53
+ }
54
+ }
@@ -0,0 +1,32 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { DcRouterDb } from '../classes.dcrouter-db.js';
3
+
4
+ const getDb = () => DcRouterDb.getInstance().getDb();
5
+
6
+ @plugins.smartdata.Collection(() => getDb())
7
+ export class RouteOverrideDoc extends plugins.smartdata.SmartDataDbDoc<RouteOverrideDoc, RouteOverrideDoc> {
8
+ @plugins.smartdata.unI()
9
+ @plugins.smartdata.svDb()
10
+ public routeName!: string;
11
+
12
+ @plugins.smartdata.svDb()
13
+ public enabled!: boolean;
14
+
15
+ @plugins.smartdata.svDb()
16
+ public updatedAt!: number;
17
+
18
+ @plugins.smartdata.svDb()
19
+ public updatedBy!: string;
20
+
21
+ constructor() {
22
+ super();
23
+ }
24
+
25
+ public static async findByRouteName(routeName: string): Promise<RouteOverrideDoc | null> {
26
+ return await RouteOverrideDoc.getInstance({ routeName });
27
+ }
28
+
29
+ public static async findAll(): Promise<RouteOverrideDoc[]> {
30
+ return await RouteOverrideDoc.getInstances({});
31
+ }
32
+ }
@@ -0,0 +1,38 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { DcRouterDb } from '../classes.dcrouter-db.js';
3
+
4
+ const getDb = () => DcRouterDb.getInstance().getDb();
5
+
6
+ @plugins.smartdata.Collection(() => getDb())
7
+ export class StoredRouteDoc extends plugins.smartdata.SmartDataDbDoc<StoredRouteDoc, StoredRouteDoc> {
8
+ @plugins.smartdata.unI()
9
+ @plugins.smartdata.svDb()
10
+ public id!: string;
11
+
12
+ @plugins.smartdata.svDb()
13
+ public route!: plugins.smartproxy.IRouteConfig;
14
+
15
+ @plugins.smartdata.svDb()
16
+ public enabled!: boolean;
17
+
18
+ @plugins.smartdata.svDb()
19
+ public createdAt!: number;
20
+
21
+ @plugins.smartdata.svDb()
22
+ public updatedAt!: number;
23
+
24
+ @plugins.smartdata.svDb()
25
+ public createdBy!: string;
26
+
27
+ constructor() {
28
+ super();
29
+ }
30
+
31
+ public static async findById(id: string): Promise<StoredRouteDoc | null> {
32
+ return await StoredRouteDoc.getInstance({ id });
33
+ }
34
+
35
+ public static async findAll(): Promise<StoredRouteDoc[]> {
36
+ return await StoredRouteDoc.getInstances({});
37
+ }
38
+ }
@@ -0,0 +1,32 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { DcRouterDb } from '../classes.dcrouter-db.js';
3
+
4
+ const getDb = () => DcRouterDb.getInstance().getDb();
5
+
6
+ export interface IMacVlanMapping {
7
+ mac: string;
8
+ vlan: number;
9
+ description?: string;
10
+ enabled: boolean;
11
+ createdAt: number;
12
+ updatedAt: number;
13
+ }
14
+
15
+ @plugins.smartdata.Collection(() => getDb())
16
+ export class VlanMappingsDoc extends plugins.smartdata.SmartDataDbDoc<VlanMappingsDoc, VlanMappingsDoc> {
17
+ @plugins.smartdata.unI()
18
+ @plugins.smartdata.svDb()
19
+ public configId: string = 'vlan-mappings';
20
+
21
+ @plugins.smartdata.svDb()
22
+ public mappings!: IMacVlanMapping[];
23
+
24
+ constructor() {
25
+ super();
26
+ this.mappings = [];
27
+ }
28
+
29
+ public static async load(): Promise<VlanMappingsDoc | null> {
30
+ return await VlanMappingsDoc.getInstance({ configId: 'vlan-mappings' });
31
+ }
32
+ }
@@ -0,0 +1,57 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { DcRouterDb } from '../classes.dcrouter-db.js';
3
+
4
+ const getDb = () => DcRouterDb.getInstance().getDb();
5
+
6
+ @plugins.smartdata.Collection(() => getDb())
7
+ export class VpnClientDoc extends plugins.smartdata.SmartDataDbDoc<VpnClientDoc, VpnClientDoc> {
8
+ @plugins.smartdata.unI()
9
+ @plugins.smartdata.svDb()
10
+ public clientId!: string;
11
+
12
+ @plugins.smartdata.svDb()
13
+ public enabled!: boolean;
14
+
15
+ @plugins.smartdata.svDb()
16
+ public serverDefinedClientTags?: string[];
17
+
18
+ @plugins.smartdata.svDb()
19
+ public description?: string;
20
+
21
+ @plugins.smartdata.svDb()
22
+ public assignedIp?: string;
23
+
24
+ @plugins.smartdata.svDb()
25
+ public noisePublicKey!: string;
26
+
27
+ @plugins.smartdata.svDb()
28
+ public wgPublicKey!: string;
29
+
30
+ @plugins.smartdata.svDb()
31
+ public wgPrivateKey?: string;
32
+
33
+ @plugins.smartdata.svDb()
34
+ public createdAt!: number;
35
+
36
+ @plugins.smartdata.svDb()
37
+ public updatedAt!: number;
38
+
39
+ @plugins.smartdata.svDb()
40
+ public expiresAt?: string;
41
+
42
+ constructor() {
43
+ super();
44
+ }
45
+
46
+ public static async findByClientId(clientId: string): Promise<VpnClientDoc | null> {
47
+ return await VpnClientDoc.getInstance({ clientId });
48
+ }
49
+
50
+ public static async findAll(): Promise<VpnClientDoc[]> {
51
+ return await VpnClientDoc.getInstances({});
52
+ }
53
+
54
+ public static async findEnabled(): Promise<VpnClientDoc[]> {
55
+ return await VpnClientDoc.getInstances({ enabled: true });
56
+ }
57
+ }
@@ -0,0 +1,31 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { DcRouterDb } from '../classes.dcrouter-db.js';
3
+
4
+ const getDb = () => DcRouterDb.getInstance().getDb();
5
+
6
+ @plugins.smartdata.Collection(() => getDb())
7
+ export class VpnServerKeysDoc extends plugins.smartdata.SmartDataDbDoc<VpnServerKeysDoc, VpnServerKeysDoc> {
8
+ @plugins.smartdata.unI()
9
+ @plugins.smartdata.svDb()
10
+ public configId: string = 'vpn-server-keys';
11
+
12
+ @plugins.smartdata.svDb()
13
+ public noisePrivateKey!: string;
14
+
15
+ @plugins.smartdata.svDb()
16
+ public noisePublicKey!: string;
17
+
18
+ @plugins.smartdata.svDb()
19
+ public wgPrivateKey!: string;
20
+
21
+ @plugins.smartdata.svDb()
22
+ public wgPublicKey!: string;
23
+
24
+ constructor() {
25
+ super();
26
+ }
27
+
28
+ public static async load(): Promise<VpnServerKeysDoc | null> {
29
+ return await VpnServerKeysDoc.getInstance({ configId: 'vpn-server-keys' });
30
+ }
31
+ }
@@ -0,0 +1,24 @@
1
+ // Cached/TTL document classes
2
+ export * from './classes.cached.email.js';
3
+ export * from './classes.cached.ip.reputation.js';
4
+
5
+ // Config document classes
6
+ export * from './classes.stored-route.doc.js';
7
+ export * from './classes.route-override.doc.js';
8
+ export * from './classes.api-token.doc.js';
9
+
10
+ // VPN document classes
11
+ export * from './classes.vpn-server-keys.doc.js';
12
+ export * from './classes.vpn-client.doc.js';
13
+
14
+ // Certificate document classes
15
+ export * from './classes.acme-cert.doc.js';
16
+ export * from './classes.proxy-cert.doc.js';
17
+ export * from './classes.cert-backoff.doc.js';
18
+
19
+ // Remote ingress document classes
20
+ export * from './classes.remote-ingress-edge.doc.js';
21
+
22
+ // RADIUS document classes
23
+ export * from './classes.vlan-mappings.doc.js';
24
+ export * from './classes.accounting-session.doc.js';
@@ -1,6 +1,10 @@
1
- // Core cache infrastructure
2
- export * from './classes.cachedb.js';
1
+ // Unified database manager
2
+ export * from './classes.dcrouter-db.js';
3
+
4
+ // TTL base class and constants
3
5
  export * from './classes.cached.document.js';
6
+
7
+ // Cache cleaner
4
8
  export * from './classes.cache.cleaner.js';
5
9
 
6
10
  // Document classes
@@ -1,6 +1,7 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import type { OpsServer } from '../classes.opsserver.js';
3
3
  import * as interfaces from '../../../ts_interfaces/index.js';
4
+ import { AcmeCertDoc, ProxyCertDoc } from '../../db/index.js';
4
5
 
5
6
  export class CertificateHandler {
6
7
  constructor(private opsServerRef: OpsServer) {
@@ -187,30 +188,28 @@ export class CertificateHandler {
187
188
  }
188
189
  }
189
190
 
190
- // Check persisted cert data from StorageManager
191
+ // Check persisted cert data from smartdata document classes
191
192
  if (status === 'unknown') {
192
193
  const cleanDomain = domain.replace(/^\*\.?/, '');
193
- let certData = await dcRouter.storageManager.getJSON(`/certs/${cleanDomain}`);
194
- if (!certData) {
195
- // Also check certStore path (proxy-certs)
196
- certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${domain}`);
197
- }
198
- if (certData?.validUntil) {
199
- expiryDate = new Date(certData.validUntil).toISOString();
200
- if (certData.created) {
201
- issuedAt = new Date(certData.created).toISOString();
194
+ const acmeDoc = await AcmeCertDoc.findByDomain(cleanDomain);
195
+ const proxyDoc = !acmeDoc ? await ProxyCertDoc.findByDomain(domain) : null;
196
+
197
+ if (acmeDoc?.validUntil) {
198
+ expiryDate = new Date(acmeDoc.validUntil).toISOString();
199
+ if (acmeDoc.created) {
200
+ issuedAt = new Date(acmeDoc.created).toISOString();
202
201
  }
203
202
  issuer = 'smartacme-dns-01';
204
- } else if (certData?.publicKey) {
203
+ } else if (proxyDoc?.publicKey) {
205
204
  // certStore has the cert — parse PEM for expiry
206
205
  try {
207
- const x509 = new plugins.crypto.X509Certificate(certData.publicKey);
206
+ const x509 = new plugins.crypto.X509Certificate(proxyDoc.publicKey);
208
207
  expiryDate = new Date(x509.validTo).toISOString();
209
208
  issuedAt = new Date(x509.validFrom).toISOString();
210
209
  } catch { /* PEM parsing failed */ }
211
210
  status = 'valid';
212
211
  issuer = 'cert-store';
213
- } else if (certData) {
212
+ } else if (acmeDoc || proxyDoc) {
214
213
  status = 'valid';
215
214
  issuer = 'cert-store';
216
215
  }
@@ -366,18 +365,17 @@ export class CertificateHandler {
366
365
  const dcRouter = this.opsServerRef.dcRouterRef;
367
366
  const cleanDomain = domain.replace(/^\*\.?/, '');
368
367
 
369
- // Delete from all known storage paths
370
- const paths = [
371
- `/proxy-certs/${domain}`,
372
- `/proxy-certs/${cleanDomain}`,
373
- `/certs/${cleanDomain}`,
374
- ];
368
+ // Delete from smartdata document classes
369
+ const acmeDoc = await AcmeCertDoc.findByDomain(cleanDomain);
370
+ if (acmeDoc) {
371
+ await acmeDoc.delete();
372
+ }
375
373
 
376
- for (const path of paths) {
377
- try {
378
- await dcRouter.storageManager.delete(path);
379
- } catch {
380
- // Path may not exist — ignore
374
+ // Try both original domain and clean domain for proxy certs
375
+ for (const d of [domain, cleanDomain]) {
376
+ const proxyDoc = await ProxyCertDoc.findByDomain(d);
377
+ if (proxyDoc) {
378
+ await proxyDoc.delete();
381
379
  }
382
380
  }
383
381
 
@@ -408,43 +406,41 @@ export class CertificateHandler {
408
406
  };
409
407
  message?: string;
410
408
  }> {
411
- const dcRouter = this.opsServerRef.dcRouterRef;
412
409
  const cleanDomain = domain.replace(/^\*\.?/, '');
413
410
 
414
- // Try SmartAcme /certs/ path first (has full ICert fields)
415
- let certData = await dcRouter.storageManager.getJSON(`/certs/${cleanDomain}`);
416
- if (certData && certData.publicKey && certData.privateKey) {
411
+ // Try AcmeCertDoc first (has full ICert fields)
412
+ const acmeDoc = await AcmeCertDoc.findByDomain(cleanDomain);
413
+ if (acmeDoc && acmeDoc.publicKey && acmeDoc.privateKey) {
417
414
  return {
418
415
  success: true,
419
416
  cert: {
420
- id: certData.id || plugins.crypto.randomUUID(),
421
- domainName: certData.domainName || domain,
422
- created: certData.created || Date.now(),
423
- validUntil: certData.validUntil || 0,
424
- privateKey: certData.privateKey,
425
- publicKey: certData.publicKey,
426
- csr: certData.csr || '',
417
+ id: acmeDoc.id || plugins.crypto.randomUUID(),
418
+ domainName: acmeDoc.domainName || domain,
419
+ created: acmeDoc.created || Date.now(),
420
+ validUntil: acmeDoc.validUntil || 0,
421
+ privateKey: acmeDoc.privateKey,
422
+ publicKey: acmeDoc.publicKey,
423
+ csr: acmeDoc.csr || '',
427
424
  },
428
425
  };
429
426
  }
430
427
 
431
- // Fallback: try /proxy-certs/ with original domain
432
- certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${domain}`);
433
- if (!certData || !certData.publicKey) {
434
- // Try with clean domain
435
- certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${cleanDomain}`);
428
+ // Fallback: try ProxyCertDoc with original domain, then clean domain
429
+ let proxyDoc = await ProxyCertDoc.findByDomain(domain);
430
+ if (!proxyDoc || !proxyDoc.publicKey) {
431
+ proxyDoc = await ProxyCertDoc.findByDomain(cleanDomain);
436
432
  }
437
433
 
438
- if (certData && certData.publicKey && certData.privateKey) {
434
+ if (proxyDoc && proxyDoc.publicKey && proxyDoc.privateKey) {
439
435
  return {
440
436
  success: true,
441
437
  cert: {
442
438
  id: plugins.crypto.randomUUID(),
443
439
  domainName: domain,
444
- created: certData.validFrom || Date.now(),
445
- validUntil: certData.validUntil || 0,
446
- privateKey: certData.privateKey,
447
- publicKey: certData.publicKey,
440
+ created: proxyDoc.validFrom || Date.now(),
441
+ validUntil: proxyDoc.validUntil || 0,
442
+ privateKey: proxyDoc.privateKey,
443
+ publicKey: proxyDoc.publicKey,
448
444
  csr: '',
449
445
  },
450
446
  };
@@ -476,26 +472,32 @@ export class CertificateHandler {
476
472
  const dcRouter = this.opsServerRef.dcRouterRef;
477
473
  const cleanDomain = cert.domainName.replace(/^\*\.?/, '');
478
474
 
479
- // Save to /certs/ (SmartAcme-compatible path)
480
- await dcRouter.storageManager.setJSON(`/certs/${cleanDomain}`, {
481
- id: cert.id,
482
- domainName: cert.domainName,
483
- created: cert.created,
484
- validUntil: cert.validUntil,
485
- privateKey: cert.privateKey,
486
- publicKey: cert.publicKey,
487
- csr: cert.csr || '',
488
- });
489
-
490
- // Also save to /proxy-certs/ (proxy-cert format)
491
- await dcRouter.storageManager.setJSON(`/proxy-certs/${cert.domainName}`, {
492
- domain: cert.domainName,
493
- publicKey: cert.publicKey,
494
- privateKey: cert.privateKey,
495
- ca: undefined,
496
- validUntil: cert.validUntil,
497
- validFrom: cert.created,
498
- });
475
+ // Save to AcmeCertDoc (SmartAcme-compatible)
476
+ let acmeDoc = await AcmeCertDoc.findByDomain(cleanDomain);
477
+ if (!acmeDoc) {
478
+ acmeDoc = new AcmeCertDoc();
479
+ acmeDoc.domainName = cleanDomain;
480
+ }
481
+ acmeDoc.id = cert.id;
482
+ acmeDoc.created = cert.created;
483
+ acmeDoc.validUntil = cert.validUntil;
484
+ acmeDoc.privateKey = cert.privateKey;
485
+ acmeDoc.publicKey = cert.publicKey;
486
+ acmeDoc.csr = cert.csr || '';
487
+ await acmeDoc.save();
488
+
489
+ // Also save to ProxyCertDoc (proxy-cert format)
490
+ let proxyDoc = await ProxyCertDoc.findByDomain(cert.domainName);
491
+ if (!proxyDoc) {
492
+ proxyDoc = new ProxyCertDoc();
493
+ proxyDoc.domain = cert.domainName;
494
+ }
495
+ proxyDoc.publicKey = cert.publicKey;
496
+ proxyDoc.privateKey = cert.privateKey;
497
+ proxyDoc.ca = '';
498
+ proxyDoc.validUntil = cert.validUntil;
499
+ proxyDoc.validFrom = cert.created;
500
+ await proxyDoc.save();
499
501
 
500
502
  // Update in-memory status map
501
503
  dcRouter.certificateStatusMap.set(cert.domainName, {
@@ -33,11 +33,9 @@ export class ConfigHandler {
33
33
  const resolvedPaths = dcRouter.resolvedPaths;
34
34
 
35
35
  // --- System ---
36
- const storageBackend: 'filesystem' | 'custom' | 'memory' = opts.storage?.readFunction
36
+ const storageBackend: 'filesystem' | 'custom' | 'memory' = opts.dbConfig?.mongoDbUrl
37
37
  ? 'custom'
38
- : opts.storage?.fsPath
39
- ? 'filesystem'
40
- : 'memory';
38
+ : 'filesystem';
41
39
 
42
40
  // Resolve proxy IPs: fall back to SmartProxy's runtime proxyIPs if not in opts
43
41
  let proxyIps = opts.proxyIps || [];
@@ -55,7 +53,7 @@ export class ConfigHandler {
55
53
  proxyIps,
56
54
  uptime: Math.floor(process.uptime()),
57
55
  storageBackend,
58
- storagePath: opts.storage?.fsPath || null,
56
+ storagePath: opts.dbConfig?.storagePath || resolvedPaths.defaultTsmDbPath,
59
57
  };
60
58
 
61
59
  // --- SmartProxy ---
@@ -151,15 +149,15 @@ export class ConfigHandler {
151
149
  keyPath: opts.tls?.keyPath || null,
152
150
  };
153
151
 
154
- // --- Cache ---
155
- const cacheConfig = opts.cacheConfig;
152
+ // --- Database ---
153
+ const dbConfig = opts.dbConfig;
156
154
  const cache: interfaces.requests.IConfigData['cache'] = {
157
- enabled: cacheConfig?.enabled !== false,
158
- storagePath: cacheConfig?.storagePath || resolvedPaths.defaultTsmDbPath,
159
- dbName: cacheConfig?.dbName || 'dcrouter',
160
- defaultTTLDays: cacheConfig?.defaultTTLDays || 30,
161
- cleanupIntervalHours: cacheConfig?.cleanupIntervalHours || 1,
162
- ttlConfig: cacheConfig?.ttlConfig ? { ...cacheConfig.ttlConfig } as Record<string, number> : {},
155
+ enabled: dbConfig?.enabled !== false,
156
+ storagePath: dbConfig?.storagePath || resolvedPaths.defaultTsmDbPath,
157
+ dbName: dbConfig?.dbName || 'dcrouter',
158
+ defaultTTLDays: 30,
159
+ cleanupIntervalHours: dbConfig?.cleanupIntervalHours || 1,
160
+ ttlConfig: {},
163
161
  };
164
162
 
165
163
  // --- RADIUS ---
@@ -185,7 +183,8 @@ export class ConfigHandler {
185
183
  tlsMode = 'custom';
186
184
  } else if (riCfg?.hubDomain) {
187
185
  try {
188
- const stored = await dcRouter.storageManager.getJSON(`/proxy-certs/${riCfg.hubDomain}`);
186
+ const { ProxyCertDoc } = await import('../../db/index.js');
187
+ const stored = await ProxyCertDoc.findByDomain(riCfg.hubDomain);
189
188
  if (stored?.publicKey && stored?.privateKey) {
190
189
  tlsMode = 'acme';
191
190
  }
package/ts/paths.ts CHANGED
@@ -34,7 +34,6 @@ export function resolvePaths(baseDir?: string) {
34
34
  dcrouterHomeDir: root,
35
35
  dataDir: resolvedDataDir,
36
36
  defaultTsmDbPath: plugins.path.join(root, 'tsmdb'),
37
- defaultStoragePath: plugins.path.join(root, 'storage'),
38
37
  dnsRecordsDir: plugins.path.join(resolvedDataDir, 'dns'),
39
38
  };
40
39
  }