@serve.zone/dcrouter 11.12.4 → 11.14.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 (214) hide show
  1. package/dist_serve/bundle.js +705 -548
  2. package/dist_ts_interfaces/data/index.d.ts +1 -0
  3. package/dist_ts_interfaces/data/index.js +2 -1
  4. package/dist_ts_interfaces/data/remoteingress.d.ts +10 -1
  5. package/dist_ts_interfaces/data/vpn.d.ts +43 -0
  6. package/dist_ts_interfaces/data/vpn.js +2 -0
  7. package/dist_ts_interfaces/requests/index.d.ts +1 -0
  8. package/dist_ts_interfaces/requests/index.js +2 -1
  9. package/dist_ts_interfaces/requests/vpn.d.ts +135 -0
  10. package/dist_ts_interfaces/requests/vpn.js +3 -0
  11. package/package.json +2 -1
  12. package/readme.md +107 -3
  13. package/ts/00_commitinfo_data.ts +1 -1
  14. package/ts/classes.dcrouter.ts +126 -0
  15. package/ts/config/classes.route-config-manager.ts +20 -3
  16. package/ts/opsserver/classes.opsserver.ts +2 -0
  17. package/ts/opsserver/handlers/index.ts +2 -1
  18. package/ts/opsserver/handlers/vpn.handler.ts +257 -0
  19. package/ts/plugins.ts +2 -1
  20. package/ts/vpn/classes.vpn-manager.ts +378 -0
  21. package/ts/vpn/index.ts +1 -0
  22. package/ts_web/00_commitinfo_data.ts +1 -1
  23. package/ts_web/appstate.ts +164 -0
  24. package/ts_web/elements/index.ts +1 -0
  25. package/ts_web/elements/ops-dashboard.ts +6 -0
  26. package/ts_web/elements/ops-view-vpn.ts +330 -0
  27. package/ts_web/readme.md +17 -0
  28. package/ts_web/router.ts +1 -1
  29. package/dist_ts/00_commitinfo_data.d.ts +0 -8
  30. package/dist_ts/00_commitinfo_data.js +0 -9
  31. package/dist_ts/cache/classes.cache.cleaner.d.ts +0 -47
  32. package/dist_ts/cache/classes.cache.cleaner.js +0 -130
  33. package/dist_ts/cache/classes.cached.document.d.ts +0 -76
  34. package/dist_ts/cache/classes.cached.document.js +0 -100
  35. package/dist_ts/cache/classes.cachedb.d.ts +0 -60
  36. package/dist_ts/cache/classes.cachedb.js +0 -126
  37. package/dist_ts/cache/documents/classes.cached.email.d.ts +0 -125
  38. package/dist_ts/cache/documents/classes.cached.email.js +0 -337
  39. package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +0 -119
  40. package/dist_ts/cache/documents/classes.cached.ip.reputation.js +0 -323
  41. package/dist_ts/cache/documents/index.d.ts +0 -2
  42. package/dist_ts/cache/documents/index.js +0 -3
  43. package/dist_ts/cache/index.d.ts +0 -4
  44. package/dist_ts/cache/index.js +0 -7
  45. package/dist_ts/classes.cert-provision-scheduler.d.ts +0 -54
  46. package/dist_ts/classes.cert-provision-scheduler.js +0 -118
  47. package/dist_ts/classes.dcrouter.d.ts +0 -356
  48. package/dist_ts/classes.dcrouter.js +0 -1592
  49. package/dist_ts/classes.storage-cert-manager.d.ts +0 -18
  50. package/dist_ts/classes.storage-cert-manager.js +0 -43
  51. package/dist_ts/config/classes.api-token-manager.d.ts +0 -46
  52. package/dist_ts/config/classes.api-token-manager.js +0 -150
  53. package/dist_ts/config/classes.route-config-manager.d.ts +0 -37
  54. package/dist_ts/config/classes.route-config-manager.js +0 -240
  55. package/dist_ts/config/index.d.ts +0 -3
  56. package/dist_ts/config/index.js +0 -5
  57. package/dist_ts/config/validator.d.ts +0 -104
  58. package/dist_ts/config/validator.js +0 -152
  59. package/dist_ts/errors/base.errors.d.ts +0 -224
  60. package/dist_ts/errors/base.errors.js +0 -320
  61. package/dist_ts/errors/error-handler.d.ts +0 -98
  62. package/dist_ts/errors/error-handler.js +0 -282
  63. package/dist_ts/errors/error.codes.d.ts +0 -115
  64. package/dist_ts/errors/error.codes.js +0 -136
  65. package/dist_ts/errors/index.d.ts +0 -54
  66. package/dist_ts/errors/index.js +0 -136
  67. package/dist_ts/errors/reputation.errors.d.ts +0 -183
  68. package/dist_ts/errors/reputation.errors.js +0 -292
  69. package/dist_ts/http3/http3-route-augmentation.d.ts +0 -50
  70. package/dist_ts/http3/http3-route-augmentation.js +0 -98
  71. package/dist_ts/http3/index.d.ts +0 -1
  72. package/dist_ts/http3/index.js +0 -2
  73. package/dist_ts/index.d.ts +0 -8
  74. package/dist_ts/index.js +0 -29
  75. package/dist_ts/logger.d.ts +0 -21
  76. package/dist_ts/logger.js +0 -81
  77. package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
  78. package/dist_ts/monitoring/classes.metricscache.js +0 -63
  79. package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -184
  80. package/dist_ts/monitoring/classes.metricsmanager.js +0 -744
  81. package/dist_ts/monitoring/index.d.ts +0 -1
  82. package/dist_ts/monitoring/index.js +0 -2
  83. package/dist_ts/opsserver/classes.opsserver.d.ts +0 -37
  84. package/dist_ts/opsserver/classes.opsserver.js +0 -85
  85. package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -31
  86. package/dist_ts/opsserver/handlers/admin.handler.js +0 -180
  87. package/dist_ts/opsserver/handlers/api-token.handler.d.ts +0 -6
  88. package/dist_ts/opsserver/handlers/api-token.handler.js +0 -62
  89. package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -32
  90. package/dist_ts/opsserver/handlers/certificate.handler.js +0 -421
  91. package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -7
  92. package/dist_ts/opsserver/handlers/config.handler.js +0 -192
  93. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +0 -30
  94. package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -227
  95. package/dist_ts/opsserver/handlers/index.d.ts +0 -11
  96. package/dist_ts/opsserver/handlers/index.js +0 -12
  97. package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -25
  98. package/dist_ts/opsserver/handlers/logs.handler.js +0 -256
  99. package/dist_ts/opsserver/handlers/radius.handler.d.ts +0 -6
  100. package/dist_ts/opsserver/handlers/radius.handler.js +0 -295
  101. package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -6
  102. package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -156
  103. package/dist_ts/opsserver/handlers/route-management.handler.d.ts +0 -14
  104. package/dist_ts/opsserver/handlers/route-management.handler.js +0 -117
  105. package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -9
  106. package/dist_ts/opsserver/handlers/security.handler.js +0 -233
  107. package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -11
  108. package/dist_ts/opsserver/handlers/stats.handler.js +0 -403
  109. package/dist_ts/opsserver/helpers/guards.d.ts +0 -27
  110. package/dist_ts/opsserver/helpers/guards.js +0 -43
  111. package/dist_ts/opsserver/index.d.ts +0 -1
  112. package/dist_ts/opsserver/index.js +0 -2
  113. package/dist_ts/paths.d.ts +0 -26
  114. package/dist_ts/paths.js +0 -45
  115. package/dist_ts/plugins.d.ts +0 -80
  116. package/dist_ts/plugins.js +0 -114
  117. package/dist_ts/radius/classes.accounting.manager.d.ts +0 -231
  118. package/dist_ts/radius/classes.accounting.manager.js +0 -462
  119. package/dist_ts/radius/classes.radius.server.d.ts +0 -171
  120. package/dist_ts/radius/classes.radius.server.js +0 -386
  121. package/dist_ts/radius/classes.vlan.manager.d.ts +0 -128
  122. package/dist_ts/radius/classes.vlan.manager.js +0 -279
  123. package/dist_ts/radius/index.d.ts +0 -13
  124. package/dist_ts/radius/index.js +0 -14
  125. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +0 -94
  126. package/dist_ts/remoteingress/classes.remoteingress-manager.js +0 -271
  127. package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +0 -59
  128. package/dist_ts/remoteingress/classes.tunnel-manager.js +0 -165
  129. package/dist_ts/remoteingress/index.d.ts +0 -2
  130. package/dist_ts/remoteingress/index.js +0 -3
  131. package/dist_ts/security/classes.contentscanner.d.ts +0 -164
  132. package/dist_ts/security/classes.contentscanner.js +0 -642
  133. package/dist_ts/security/classes.ipreputationchecker.d.ts +0 -160
  134. package/dist_ts/security/classes.ipreputationchecker.js +0 -537
  135. package/dist_ts/security/classes.securitylogger.d.ts +0 -144
  136. package/dist_ts/security/classes.securitylogger.js +0 -235
  137. package/dist_ts/security/index.d.ts +0 -3
  138. package/dist_ts/security/index.js +0 -4
  139. package/dist_ts/sms/classes.smsservice.d.ts +0 -15
  140. package/dist_ts/sms/classes.smsservice.js +0 -72
  141. package/dist_ts/sms/config/sms.config.d.ts +0 -93
  142. package/dist_ts/sms/config/sms.config.js +0 -2
  143. package/dist_ts/sms/config/sms.schema.d.ts +0 -5
  144. package/dist_ts/sms/config/sms.schema.js +0 -121
  145. package/dist_ts/sms/index.d.ts +0 -1
  146. package/dist_ts/sms/index.js +0 -2
  147. package/dist_ts/storage/classes.storagemanager.d.ts +0 -83
  148. package/dist_ts/storage/classes.storagemanager.js +0 -348
  149. package/dist_ts/storage/index.d.ts +0 -1
  150. package/dist_ts/storage/index.js +0 -3
  151. package/dist_ts_apiclient/classes.apitoken.d.ts +0 -41
  152. package/dist_ts_apiclient/classes.apitoken.js +0 -115
  153. package/dist_ts_apiclient/classes.certificate.d.ts +0 -57
  154. package/dist_ts_apiclient/classes.certificate.js +0 -69
  155. package/dist_ts_apiclient/classes.config.d.ts +0 -7
  156. package/dist_ts_apiclient/classes.config.js +0 -11
  157. package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +0 -41
  158. package/dist_ts_apiclient/classes.dcrouterapiclient.js +0 -81
  159. package/dist_ts_apiclient/classes.email.d.ts +0 -30
  160. package/dist_ts_apiclient/classes.email.js +0 -52
  161. package/dist_ts_apiclient/classes.logs.d.ts +0 -21
  162. package/dist_ts_apiclient/classes.logs.js +0 -14
  163. package/dist_ts_apiclient/classes.radius.d.ts +0 -59
  164. package/dist_ts_apiclient/classes.radius.js +0 -95
  165. package/dist_ts_apiclient/classes.remoteingress.d.ts +0 -54
  166. package/dist_ts_apiclient/classes.remoteingress.js +0 -136
  167. package/dist_ts_apiclient/classes.route.d.ts +0 -42
  168. package/dist_ts_apiclient/classes.route.js +0 -154
  169. package/dist_ts_apiclient/classes.stats.d.ts +0 -47
  170. package/dist_ts_apiclient/classes.stats.js +0 -38
  171. package/dist_ts_apiclient/index.d.ts +0 -10
  172. package/dist_ts_apiclient/index.js +0 -14
  173. package/dist_ts_apiclient/plugins.d.ts +0 -3
  174. package/dist_ts_apiclient/plugins.js +0 -5
  175. package/dist_ts_web/00_commitinfo_data.d.ts +0 -8
  176. package/dist_ts_web/00_commitinfo_data.js +0 -9
  177. package/dist_ts_web/appstate.d.ts +0 -216
  178. package/dist_ts_web/appstate.js +0 -1064
  179. package/dist_ts_web/elements/index.d.ts +0 -12
  180. package/dist_ts_web/elements/index.js +0 -13
  181. package/dist_ts_web/elements/ops-dashboard.d.ts +0 -23
  182. package/dist_ts_web/elements/ops-dashboard.js +0 -317
  183. package/dist_ts_web/elements/ops-view-apitokens.d.ts +0 -13
  184. package/dist_ts_web/elements/ops-view-apitokens.js +0 -371
  185. package/dist_ts_web/elements/ops-view-certificates.d.ts +0 -22
  186. package/dist_ts_web/elements/ops-view-certificates.js +0 -528
  187. package/dist_ts_web/elements/ops-view-config.d.ts +0 -19
  188. package/dist_ts_web/elements/ops-view-config.js +0 -339
  189. package/dist_ts_web/elements/ops-view-emails.d.ts +0 -21
  190. package/dist_ts_web/elements/ops-view-emails.js +0 -165
  191. package/dist_ts_web/elements/ops-view-logs.d.ts +0 -13
  192. package/dist_ts_web/elements/ops-view-logs.js +0 -159
  193. package/dist_ts_web/elements/ops-view-network.d.ts +0 -71
  194. package/dist_ts_web/elements/ops-view-network.js +0 -764
  195. package/dist_ts_web/elements/ops-view-overview.d.ts +0 -22
  196. package/dist_ts_web/elements/ops-view-overview.js +0 -456
  197. package/dist_ts_web/elements/ops-view-remoteingress.d.ts +0 -20
  198. package/dist_ts_web/elements/ops-view-remoteingress.js +0 -494
  199. package/dist_ts_web/elements/ops-view-routes.d.ts +0 -12
  200. package/dist_ts_web/elements/ops-view-routes.js +0 -404
  201. package/dist_ts_web/elements/ops-view-security.d.ts +0 -21
  202. package/dist_ts_web/elements/ops-view-security.js +0 -574
  203. package/dist_ts_web/elements/shared/css.d.ts +0 -1
  204. package/dist_ts_web/elements/shared/css.js +0 -10
  205. package/dist_ts_web/elements/shared/index.d.ts +0 -2
  206. package/dist_ts_web/elements/shared/index.js +0 -3
  207. package/dist_ts_web/elements/shared/ops-sectionheading.d.ts +0 -5
  208. package/dist_ts_web/elements/shared/ops-sectionheading.js +0 -82
  209. package/dist_ts_web/index.d.ts +0 -1
  210. package/dist_ts_web/index.js +0 -10
  211. package/dist_ts_web/plugins.d.ts +0 -6
  212. package/dist_ts_web/plugins.js +0 -11
  213. package/dist_ts_web/router.d.ts +0 -19
  214. package/dist_ts_web/router.js +0 -91
@@ -1,386 +0,0 @@
1
- import * as plugins from '../plugins.js';
2
- import { logger } from '../logger.js';
3
- import { VlanManager } from './classes.vlan.manager.js';
4
- import { AccountingManager } from './classes.accounting.manager.js';
5
- /**
6
- * RADIUS Server wrapper that provides:
7
- * - MAC Authentication Bypass (MAB) for network devices
8
- * - VLAN assignment based on MAC address
9
- * - Accounting for session tracking and billing
10
- * - Integration with SmartProxy routing
11
- */
12
- export class RadiusServer {
13
- radiusServer;
14
- vlanManager;
15
- accountingManager;
16
- config;
17
- storageManager;
18
- clientSecrets = new Map();
19
- running = false;
20
- // Statistics
21
- stats = {
22
- authRequests: 0,
23
- authAccepts: 0,
24
- authRejects: 0,
25
- accountingRequests: 0,
26
- startTime: 0,
27
- };
28
- constructor(config, storageManager) {
29
- this.config = {
30
- authPort: config.authPort ?? 1812,
31
- acctPort: config.acctPort ?? 1813,
32
- bindAddress: config.bindAddress ?? '0.0.0.0',
33
- ...config,
34
- };
35
- this.storageManager = storageManager;
36
- // Initialize VLAN manager
37
- this.vlanManager = new VlanManager(config.vlanAssignment, storageManager);
38
- // Initialize accounting manager
39
- this.accountingManager = new AccountingManager(config.accounting, storageManager);
40
- }
41
- /**
42
- * Start the RADIUS server
43
- */
44
- async start() {
45
- if (this.running) {
46
- logger.log('warn', 'RADIUS server is already running');
47
- return;
48
- }
49
- logger.log('info', `Starting RADIUS server on ${this.config.bindAddress}:${this.config.authPort} (auth) and ${this.config.acctPort} (acct)`);
50
- // Initialize managers
51
- await this.vlanManager.initialize();
52
- await this.accountingManager.initialize();
53
- // Import static VLAN mappings if provided
54
- if (this.config.vlanAssignment?.mappings) {
55
- await this.vlanManager.importMappings(this.config.vlanAssignment.mappings);
56
- }
57
- // Build client secrets map
58
- this.buildClientSecretsMap();
59
- // Create the RADIUS server
60
- this.radiusServer = new plugins.smartradius.RadiusServer({
61
- authPort: this.config.authPort,
62
- acctPort: this.config.acctPort,
63
- bindAddress: this.config.bindAddress,
64
- defaultSecret: this.getDefaultSecret(),
65
- authenticationHandler: this.handleAuthentication.bind(this),
66
- accountingHandler: this.handleAccounting.bind(this),
67
- });
68
- // Configure per-client secrets
69
- for (const [ip, secret] of this.clientSecrets) {
70
- this.radiusServer.setClientSecret(ip, secret);
71
- }
72
- // Start the server
73
- await this.radiusServer.start();
74
- this.running = true;
75
- this.stats.startTime = Date.now();
76
- logger.log('info', `RADIUS server started with ${this.config.clients.length} configured clients`);
77
- }
78
- /**
79
- * Stop the RADIUS server
80
- */
81
- async stop() {
82
- if (!this.running) {
83
- return;
84
- }
85
- logger.log('info', 'Stopping RADIUS server...');
86
- if (this.radiusServer) {
87
- await this.radiusServer.stop();
88
- this.radiusServer = undefined;
89
- }
90
- this.accountingManager.stop();
91
- this.running = false;
92
- logger.log('info', 'RADIUS server stopped');
93
- }
94
- /**
95
- * Handle authentication request
96
- */
97
- async handleAuthentication(request) {
98
- this.stats.authRequests++;
99
- const authData = {
100
- username: request.attributes?.UserName || '',
101
- password: request.attributes?.UserPassword,
102
- nasIpAddress: request.attributes?.NasIpAddress || request.source?.address || '',
103
- nasPort: request.attributes?.NasPort,
104
- nasPortType: request.attributes?.NasPortType,
105
- nasIdentifier: request.attributes?.NasIdentifier,
106
- calledStationId: request.attributes?.CalledStationId,
107
- callingStationId: request.attributes?.CallingStationId,
108
- serviceType: request.attributes?.ServiceType,
109
- };
110
- logger.log('debug', `RADIUS Auth Request: user=${authData.username}, NAS=${authData.nasIpAddress}`);
111
- // Perform MAC Authentication Bypass (MAB)
112
- // In MAB, the username is typically the MAC address
113
- const result = await this.performMabAuthentication(authData);
114
- if (result.success) {
115
- this.stats.authAccepts++;
116
- logger.log('info', `RADIUS Auth Accept: user=${authData.username}, VLAN=${result.vlanId}`);
117
- // Build response with VLAN attributes
118
- const response = {
119
- code: plugins.smartradius.ERadiusCode.AccessAccept,
120
- replyMessage: result.replyMessage,
121
- };
122
- // Add VLAN attributes if assigned
123
- if (result.vlanId !== undefined) {
124
- response.tunnelType = 13; // VLAN
125
- response.tunnelMediumType = 6; // IEEE 802
126
- response.tunnelPrivateGroupId = String(result.vlanId);
127
- }
128
- // Add session timeout if specified
129
- if (result.sessionTimeout) {
130
- response.sessionTimeout = result.sessionTimeout;
131
- }
132
- // Add idle timeout if specified
133
- if (result.idleTimeout) {
134
- response.idleTimeout = result.idleTimeout;
135
- }
136
- // Add framed IP if specified
137
- if (result.framedIpAddress) {
138
- response.framedIpAddress = result.framedIpAddress;
139
- }
140
- return response;
141
- }
142
- else {
143
- this.stats.authRejects++;
144
- logger.log('warn', `RADIUS Auth Reject: user=${authData.username}, reason=${result.rejectReason}`);
145
- return {
146
- code: plugins.smartradius.ERadiusCode.AccessReject,
147
- replyMessage: result.rejectReason || 'Access Denied',
148
- };
149
- }
150
- }
151
- /**
152
- * Handle accounting request
153
- */
154
- async handleAccounting(request) {
155
- this.stats.accountingRequests++;
156
- if (!this.config.accounting?.enabled) {
157
- // Still respond even if not tracking
158
- return { code: plugins.smartradius.ERadiusCode.AccountingResponse };
159
- }
160
- const statusType = request.attributes?.AcctStatusType;
161
- const sessionId = request.attributes?.AcctSessionId || '';
162
- const accountingData = {
163
- sessionId,
164
- username: request.attributes?.UserName || '',
165
- macAddress: request.attributes?.CallingStationId,
166
- nasIpAddress: request.attributes?.NasIpAddress || request.source?.address || '',
167
- nasPort: request.attributes?.NasPort,
168
- nasPortType: request.attributes?.NasPortType,
169
- nasIdentifier: request.attributes?.NasIdentifier,
170
- calledStationId: request.attributes?.CalledStationId,
171
- callingStationId: request.attributes?.CallingStationId,
172
- inputOctets: request.attributes?.AcctInputOctets,
173
- outputOctets: request.attributes?.AcctOutputOctets,
174
- inputPackets: request.attributes?.AcctInputPackets,
175
- outputPackets: request.attributes?.AcctOutputPackets,
176
- sessionTime: request.attributes?.AcctSessionTime,
177
- terminateCause: request.attributes?.AcctTerminateCause,
178
- serviceType: request.attributes?.ServiceType,
179
- };
180
- try {
181
- switch (statusType) {
182
- case plugins.smartradius.EAcctStatusType.Start:
183
- logger.log('debug', `RADIUS Acct Start: session=${sessionId}, user=${accountingData.username}`);
184
- await this.accountingManager.handleAccountingStart(accountingData);
185
- break;
186
- case plugins.smartradius.EAcctStatusType.Stop:
187
- logger.log('debug', `RADIUS Acct Stop: session=${sessionId}`);
188
- await this.accountingManager.handleAccountingStop(accountingData);
189
- break;
190
- case plugins.smartradius.EAcctStatusType.InterimUpdate:
191
- logger.log('debug', `RADIUS Acct Interim: session=${sessionId}`);
192
- await this.accountingManager.handleAccountingUpdate(accountingData);
193
- break;
194
- default:
195
- logger.log('debug', `RADIUS Acct Unknown status type: ${statusType}`);
196
- }
197
- }
198
- catch (error) {
199
- logger.log('error', `RADIUS accounting error: ${error.message}`);
200
- }
201
- return { code: plugins.smartradius.ERadiusCode.AccountingResponse };
202
- }
203
- /**
204
- * Perform MAC Authentication Bypass
205
- */
206
- async performMabAuthentication(data) {
207
- // Extract MAC address from username or CallingStationId
208
- const macAddress = this.extractMacAddress(data);
209
- if (!macAddress) {
210
- return {
211
- success: false,
212
- rejectReason: 'No MAC address found',
213
- };
214
- }
215
- // Look up VLAN assignment
216
- const vlanResult = this.vlanManager.assignVlan(macAddress);
217
- if (!vlanResult.assigned) {
218
- return {
219
- success: false,
220
- rejectReason: 'Unknown MAC address',
221
- };
222
- }
223
- // Build successful result
224
- const result = {
225
- success: true,
226
- vlanId: vlanResult.vlan,
227
- replyMessage: vlanResult.isDefault
228
- ? `Assigned to default VLAN ${vlanResult.vlan}`
229
- : `Assigned to VLAN ${vlanResult.vlan}`,
230
- };
231
- // Apply any additional settings from the matched rule
232
- if (vlanResult.matchedRule) {
233
- // Future: Add session timeout, idle timeout, etc. from rule
234
- }
235
- return result;
236
- }
237
- /**
238
- * Extract MAC address from authentication data
239
- */
240
- extractMacAddress(data) {
241
- // Try CallingStationId first (most common for MAB)
242
- if (data.callingStationId) {
243
- return this.normalizeMac(data.callingStationId);
244
- }
245
- // Try username (often MAC address in MAB)
246
- if (data.username && this.looksLikeMac(data.username)) {
247
- return this.normalizeMac(data.username);
248
- }
249
- return null;
250
- }
251
- /**
252
- * Check if a string looks like a MAC address
253
- */
254
- looksLikeMac(value) {
255
- // Remove common separators and check length
256
- const cleaned = value.replace(/[-:. ]/g, '');
257
- return /^[0-9a-fA-F]{12}$/.test(cleaned);
258
- }
259
- /**
260
- * Normalize MAC address format
261
- */
262
- normalizeMac(mac) {
263
- return this.vlanManager.normalizeMac(mac);
264
- }
265
- /**
266
- * Build client secrets map from configuration
267
- */
268
- buildClientSecretsMap() {
269
- this.clientSecrets.clear();
270
- for (const client of this.config.clients) {
271
- if (!client.enabled) {
272
- continue;
273
- }
274
- // Handle CIDR ranges
275
- if (client.ipRange.includes('/')) {
276
- // For CIDR ranges, we'll use the network address as key
277
- // In practice, smartradius may handle this differently
278
- const [network] = client.ipRange.split('/');
279
- this.clientSecrets.set(network, client.secret);
280
- }
281
- else {
282
- this.clientSecrets.set(client.ipRange, client.secret);
283
- }
284
- }
285
- }
286
- /**
287
- * Get default secret for unknown clients
288
- */
289
- getDefaultSecret() {
290
- // Use first enabled client's secret as default, or a random one
291
- for (const client of this.config.clients) {
292
- if (client.enabled) {
293
- return client.secret;
294
- }
295
- }
296
- return plugins.crypto.randomBytes(16).toString('hex');
297
- }
298
- /**
299
- * Add a RADIUS client
300
- */
301
- async addClient(client) {
302
- // Check if client already exists
303
- const existingIndex = this.config.clients.findIndex(c => c.name === client.name);
304
- if (existingIndex >= 0) {
305
- this.config.clients[existingIndex] = client;
306
- }
307
- else {
308
- this.config.clients.push(client);
309
- }
310
- // Update client secrets if running
311
- if (this.running && this.radiusServer && client.enabled) {
312
- if (client.ipRange.includes('/')) {
313
- const [network] = client.ipRange.split('/');
314
- this.radiusServer.setClientSecret(network, client.secret);
315
- this.clientSecrets.set(network, client.secret);
316
- }
317
- else {
318
- this.radiusServer.setClientSecret(client.ipRange, client.secret);
319
- this.clientSecrets.set(client.ipRange, client.secret);
320
- }
321
- }
322
- logger.log('info', `RADIUS client ${client.enabled ? 'added' : 'disabled'}: ${client.name} (${client.ipRange})`);
323
- }
324
- /**
325
- * Remove a RADIUS client
326
- */
327
- removeClient(name) {
328
- const index = this.config.clients.findIndex(c => c.name === name);
329
- if (index >= 0) {
330
- const client = this.config.clients[index];
331
- this.config.clients.splice(index, 1);
332
- // Remove from secrets map
333
- if (client.ipRange.includes('/')) {
334
- const [network] = client.ipRange.split('/');
335
- this.clientSecrets.delete(network);
336
- }
337
- else {
338
- this.clientSecrets.delete(client.ipRange);
339
- }
340
- logger.log('info', `RADIUS client removed: ${name}`);
341
- return true;
342
- }
343
- return false;
344
- }
345
- /**
346
- * Get configured clients
347
- */
348
- getClients() {
349
- return [...this.config.clients];
350
- }
351
- /**
352
- * Get VLAN manager for direct access to VLAN operations
353
- */
354
- getVlanManager() {
355
- return this.vlanManager;
356
- }
357
- /**
358
- * Get accounting manager for direct access to accounting operations
359
- */
360
- getAccountingManager() {
361
- return this.accountingManager;
362
- }
363
- /**
364
- * Get server statistics
365
- */
366
- getStats() {
367
- return {
368
- running: this.running,
369
- uptime: this.running ? Date.now() - this.stats.startTime : 0,
370
- authRequests: this.stats.authRequests,
371
- authAccepts: this.stats.authAccepts,
372
- authRejects: this.stats.authRejects,
373
- accountingRequests: this.stats.accountingRequests,
374
- activeSessions: this.accountingManager.getStats().activeSessions,
375
- vlanMappings: this.vlanManager.getStats().totalMappings,
376
- clients: this.config.clients.filter(c => c.enabled).length,
377
- };
378
- }
379
- /**
380
- * Check if server is running
381
- */
382
- isRunning() {
383
- return this.running;
384
- }
385
- }
386
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5yYWRpdXMuc2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcmFkaXVzL2NsYXNzZXMucmFkaXVzLnNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXRDLE9BQU8sRUFBRSxXQUFXLEVBQWlELE1BQU0sMkJBQTJCLENBQUM7QUFDdkcsT0FBTyxFQUFFLGlCQUFpQixFQUEwRCxNQUFNLGlDQUFpQyxDQUFDO0FBOEU1SDs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUNmLFlBQVksQ0FBb0M7SUFDaEQsV0FBVyxDQUFjO0lBQ3pCLGlCQUFpQixDQUFvQjtJQUNyQyxNQUFNLENBQXNCO0lBQzVCLGNBQWMsQ0FBa0I7SUFDaEMsYUFBYSxHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQy9DLE9BQU8sR0FBWSxLQUFLLENBQUM7SUFFakMsYUFBYTtJQUNMLEtBQUssR0FBRztRQUNkLFlBQVksRUFBRSxDQUFDO1FBQ2YsV0FBVyxFQUFFLENBQUM7UUFDZCxXQUFXLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixFQUFFLENBQUM7UUFDckIsU0FBUyxFQUFFLENBQUM7S0FDYixDQUFDO0lBRUYsWUFBWSxNQUEyQixFQUFFLGNBQStCO1FBQ3RFLElBQUksQ0FBQyxNQUFNLEdBQUc7WUFDWixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsSUFBSSxJQUFJO1lBQ2pDLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxJQUFJLElBQUk7WUFDakMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLElBQUksU0FBUztZQUM1QyxHQUFHLE1BQU07U0FDVixDQUFDO1FBQ0YsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFFckMsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxX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
@@ -1,128 +0,0 @@
1
- import type { StorageManager } from '../storage/index.js';
2
- /**
3
- * MAC address to VLAN mapping
4
- */
5
- export interface IMacVlanMapping {
6
- /** MAC address (full) or OUI pattern (e.g., "00:11:22" for vendor prefix) */
7
- mac: string;
8
- /** VLAN ID to assign */
9
- vlan: number;
10
- /** Optional description */
11
- description?: string;
12
- /** Whether this mapping is enabled */
13
- enabled: boolean;
14
- /** Creation timestamp */
15
- createdAt: number;
16
- /** Last update timestamp */
17
- updatedAt: number;
18
- }
19
- /**
20
- * VLAN assignment result
21
- */
22
- export interface IVlanAssignmentResult {
23
- /** Whether a VLAN was successfully assigned */
24
- assigned: boolean;
25
- /** The assigned VLAN ID (or default if not matched) */
26
- vlan: number;
27
- /** The matching rule (if any) */
28
- matchedRule?: IMacVlanMapping;
29
- /** Whether default VLAN was used */
30
- isDefault: boolean;
31
- }
32
- /**
33
- * VlanManager configuration
34
- */
35
- export interface IVlanManagerConfig {
36
- /** Default VLAN for unknown MACs */
37
- defaultVlan?: number;
38
- /** Whether to allow unknown MACs (assign default VLAN) or reject */
39
- allowUnknownMacs?: boolean;
40
- /** Storage key prefix for persistence */
41
- storagePrefix?: string;
42
- }
43
- /**
44
- * Manages MAC address to VLAN mappings with support for:
45
- * - Exact MAC address matching
46
- * - OUI (vendor prefix) pattern matching
47
- * - Wildcard patterns
48
- * - Default VLAN for unknown devices
49
- */
50
- export declare class VlanManager {
51
- private mappings;
52
- private config;
53
- private storageManager?;
54
- private normalizedMacCache;
55
- constructor(config?: IVlanManagerConfig, storageManager?: StorageManager);
56
- /**
57
- * Initialize the VLAN manager and load persisted mappings
58
- */
59
- initialize(): Promise<void>;
60
- /**
61
- * Normalize a MAC address to lowercase with colons
62
- * Accepts formats: 00:11:22:33:44:55, 00-11-22-33-44-55, 001122334455
63
- */
64
- normalizeMac(mac: string): string;
65
- /**
66
- * Check if a MAC address matches a pattern
67
- * Supports:
68
- * - Exact match: "00:11:22:33:44:55"
69
- * - OUI match: "00:11:22" (matches any device with this vendor prefix)
70
- * - Wildcard: "*" (matches all)
71
- */
72
- macMatchesPattern(mac: string, pattern: string): boolean;
73
- /**
74
- * Add or update a MAC to VLAN mapping
75
- */
76
- addMapping(mapping: Omit<IMacVlanMapping, 'createdAt' | 'updatedAt'>): Promise<IMacVlanMapping>;
77
- /**
78
- * Remove a MAC to VLAN mapping
79
- */
80
- removeMapping(mac: string): Promise<boolean>;
81
- /**
82
- * Get a specific mapping by MAC
83
- */
84
- getMapping(mac: string): IMacVlanMapping | undefined;
85
- /**
86
- * Get all mappings
87
- */
88
- getAllMappings(): IMacVlanMapping[];
89
- /**
90
- * Determine VLAN assignment for a MAC address
91
- * Returns the most specific matching rule (exact > OUI > wildcard > default)
92
- */
93
- assignVlan(mac: string): IVlanAssignmentResult;
94
- /**
95
- * Bulk import mappings
96
- */
97
- importMappings(mappings: Array<Omit<IMacVlanMapping, 'createdAt' | 'updatedAt'>>): Promise<number>;
98
- /**
99
- * Export all mappings
100
- */
101
- exportMappings(): IMacVlanMapping[];
102
- /**
103
- * Update configuration
104
- */
105
- updateConfig(config: Partial<IVlanManagerConfig>): void;
106
- /**
107
- * Get current configuration
108
- */
109
- getConfig(): Required<IVlanManagerConfig>;
110
- /**
111
- * Get statistics
112
- */
113
- getStats(): {
114
- totalMappings: number;
115
- enabledMappings: number;
116
- exactMatches: number;
117
- ouiPatterns: number;
118
- wildcardPatterns: number;
119
- };
120
- /**
121
- * Load mappings from storage
122
- */
123
- private loadMappings;
124
- /**
125
- * Save mappings to storage
126
- */
127
- private saveMappings;
128
- }