@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.
- package/dist_serve/bundle.js +705 -548
- package/dist_ts_interfaces/data/index.d.ts +1 -0
- package/dist_ts_interfaces/data/index.js +2 -1
- package/dist_ts_interfaces/data/remoteingress.d.ts +10 -1
- package/dist_ts_interfaces/data/vpn.d.ts +43 -0
- package/dist_ts_interfaces/data/vpn.js +2 -0
- package/dist_ts_interfaces/requests/index.d.ts +1 -0
- package/dist_ts_interfaces/requests/index.js +2 -1
- package/dist_ts_interfaces/requests/vpn.d.ts +135 -0
- package/dist_ts_interfaces/requests/vpn.js +3 -0
- package/package.json +2 -1
- package/readme.md +107 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +126 -0
- package/ts/config/classes.route-config-manager.ts +20 -3
- package/ts/opsserver/classes.opsserver.ts +2 -0
- package/ts/opsserver/handlers/index.ts +2 -1
- package/ts/opsserver/handlers/vpn.handler.ts +257 -0
- package/ts/plugins.ts +2 -1
- package/ts/vpn/classes.vpn-manager.ts +378 -0
- package/ts/vpn/index.ts +1 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +164 -0
- package/ts_web/elements/index.ts +1 -0
- package/ts_web/elements/ops-dashboard.ts +6 -0
- package/ts_web/elements/ops-view-vpn.ts +330 -0
- package/ts_web/readme.md +17 -0
- package/ts_web/router.ts +1 -1
- package/dist_ts/00_commitinfo_data.d.ts +0 -8
- package/dist_ts/00_commitinfo_data.js +0 -9
- package/dist_ts/cache/classes.cache.cleaner.d.ts +0 -47
- package/dist_ts/cache/classes.cache.cleaner.js +0 -130
- package/dist_ts/cache/classes.cached.document.d.ts +0 -76
- package/dist_ts/cache/classes.cached.document.js +0 -100
- package/dist_ts/cache/classes.cachedb.d.ts +0 -60
- package/dist_ts/cache/classes.cachedb.js +0 -126
- package/dist_ts/cache/documents/classes.cached.email.d.ts +0 -125
- package/dist_ts/cache/documents/classes.cached.email.js +0 -337
- package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +0 -119
- package/dist_ts/cache/documents/classes.cached.ip.reputation.js +0 -323
- package/dist_ts/cache/documents/index.d.ts +0 -2
- package/dist_ts/cache/documents/index.js +0 -3
- package/dist_ts/cache/index.d.ts +0 -4
- package/dist_ts/cache/index.js +0 -7
- package/dist_ts/classes.cert-provision-scheduler.d.ts +0 -54
- package/dist_ts/classes.cert-provision-scheduler.js +0 -118
- package/dist_ts/classes.dcrouter.d.ts +0 -356
- package/dist_ts/classes.dcrouter.js +0 -1592
- package/dist_ts/classes.storage-cert-manager.d.ts +0 -18
- package/dist_ts/classes.storage-cert-manager.js +0 -43
- package/dist_ts/config/classes.api-token-manager.d.ts +0 -46
- package/dist_ts/config/classes.api-token-manager.js +0 -150
- package/dist_ts/config/classes.route-config-manager.d.ts +0 -37
- package/dist_ts/config/classes.route-config-manager.js +0 -240
- package/dist_ts/config/index.d.ts +0 -3
- package/dist_ts/config/index.js +0 -5
- package/dist_ts/config/validator.d.ts +0 -104
- package/dist_ts/config/validator.js +0 -152
- package/dist_ts/errors/base.errors.d.ts +0 -224
- package/dist_ts/errors/base.errors.js +0 -320
- package/dist_ts/errors/error-handler.d.ts +0 -98
- package/dist_ts/errors/error-handler.js +0 -282
- package/dist_ts/errors/error.codes.d.ts +0 -115
- package/dist_ts/errors/error.codes.js +0 -136
- package/dist_ts/errors/index.d.ts +0 -54
- package/dist_ts/errors/index.js +0 -136
- package/dist_ts/errors/reputation.errors.d.ts +0 -183
- package/dist_ts/errors/reputation.errors.js +0 -292
- package/dist_ts/http3/http3-route-augmentation.d.ts +0 -50
- package/dist_ts/http3/http3-route-augmentation.js +0 -98
- package/dist_ts/http3/index.d.ts +0 -1
- package/dist_ts/http3/index.js +0 -2
- package/dist_ts/index.d.ts +0 -8
- package/dist_ts/index.js +0 -29
- package/dist_ts/logger.d.ts +0 -21
- package/dist_ts/logger.js +0 -81
- package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
- package/dist_ts/monitoring/classes.metricscache.js +0 -63
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -184
- package/dist_ts/monitoring/classes.metricsmanager.js +0 -744
- package/dist_ts/monitoring/index.d.ts +0 -1
- package/dist_ts/monitoring/index.js +0 -2
- package/dist_ts/opsserver/classes.opsserver.d.ts +0 -37
- package/dist_ts/opsserver/classes.opsserver.js +0 -85
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -31
- package/dist_ts/opsserver/handlers/admin.handler.js +0 -180
- package/dist_ts/opsserver/handlers/api-token.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/api-token.handler.js +0 -62
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -32
- package/dist_ts/opsserver/handlers/certificate.handler.js +0 -421
- package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -7
- package/dist_ts/opsserver/handlers/config.handler.js +0 -192
- package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +0 -30
- package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -227
- package/dist_ts/opsserver/handlers/index.d.ts +0 -11
- package/dist_ts/opsserver/handlers/index.js +0 -12
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -25
- package/dist_ts/opsserver/handlers/logs.handler.js +0 -256
- package/dist_ts/opsserver/handlers/radius.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/radius.handler.js +0 -295
- package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -156
- package/dist_ts/opsserver/handlers/route-management.handler.d.ts +0 -14
- package/dist_ts/opsserver/handlers/route-management.handler.js +0 -117
- package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -9
- package/dist_ts/opsserver/handlers/security.handler.js +0 -233
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -11
- package/dist_ts/opsserver/handlers/stats.handler.js +0 -403
- package/dist_ts/opsserver/helpers/guards.d.ts +0 -27
- package/dist_ts/opsserver/helpers/guards.js +0 -43
- package/dist_ts/opsserver/index.d.ts +0 -1
- package/dist_ts/opsserver/index.js +0 -2
- package/dist_ts/paths.d.ts +0 -26
- package/dist_ts/paths.js +0 -45
- package/dist_ts/plugins.d.ts +0 -80
- package/dist_ts/plugins.js +0 -114
- package/dist_ts/radius/classes.accounting.manager.d.ts +0 -231
- package/dist_ts/radius/classes.accounting.manager.js +0 -462
- package/dist_ts/radius/classes.radius.server.d.ts +0 -171
- package/dist_ts/radius/classes.radius.server.js +0 -386
- package/dist_ts/radius/classes.vlan.manager.d.ts +0 -128
- package/dist_ts/radius/classes.vlan.manager.js +0 -279
- package/dist_ts/radius/index.d.ts +0 -13
- package/dist_ts/radius/index.js +0 -14
- package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +0 -94
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +0 -271
- package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +0 -59
- package/dist_ts/remoteingress/classes.tunnel-manager.js +0 -165
- package/dist_ts/remoteingress/index.d.ts +0 -2
- package/dist_ts/remoteingress/index.js +0 -3
- package/dist_ts/security/classes.contentscanner.d.ts +0 -164
- package/dist_ts/security/classes.contentscanner.js +0 -642
- package/dist_ts/security/classes.ipreputationchecker.d.ts +0 -160
- package/dist_ts/security/classes.ipreputationchecker.js +0 -537
- package/dist_ts/security/classes.securitylogger.d.ts +0 -144
- package/dist_ts/security/classes.securitylogger.js +0 -235
- package/dist_ts/security/index.d.ts +0 -3
- package/dist_ts/security/index.js +0 -4
- package/dist_ts/sms/classes.smsservice.d.ts +0 -15
- package/dist_ts/sms/classes.smsservice.js +0 -72
- package/dist_ts/sms/config/sms.config.d.ts +0 -93
- package/dist_ts/sms/config/sms.config.js +0 -2
- package/dist_ts/sms/config/sms.schema.d.ts +0 -5
- package/dist_ts/sms/config/sms.schema.js +0 -121
- package/dist_ts/sms/index.d.ts +0 -1
- package/dist_ts/sms/index.js +0 -2
- package/dist_ts/storage/classes.storagemanager.d.ts +0 -83
- package/dist_ts/storage/classes.storagemanager.js +0 -348
- package/dist_ts/storage/index.d.ts +0 -1
- package/dist_ts/storage/index.js +0 -3
- package/dist_ts_apiclient/classes.apitoken.d.ts +0 -41
- package/dist_ts_apiclient/classes.apitoken.js +0 -115
- package/dist_ts_apiclient/classes.certificate.d.ts +0 -57
- package/dist_ts_apiclient/classes.certificate.js +0 -69
- package/dist_ts_apiclient/classes.config.d.ts +0 -7
- package/dist_ts_apiclient/classes.config.js +0 -11
- package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +0 -41
- package/dist_ts_apiclient/classes.dcrouterapiclient.js +0 -81
- package/dist_ts_apiclient/classes.email.d.ts +0 -30
- package/dist_ts_apiclient/classes.email.js +0 -52
- package/dist_ts_apiclient/classes.logs.d.ts +0 -21
- package/dist_ts_apiclient/classes.logs.js +0 -14
- package/dist_ts_apiclient/classes.radius.d.ts +0 -59
- package/dist_ts_apiclient/classes.radius.js +0 -95
- package/dist_ts_apiclient/classes.remoteingress.d.ts +0 -54
- package/dist_ts_apiclient/classes.remoteingress.js +0 -136
- package/dist_ts_apiclient/classes.route.d.ts +0 -42
- package/dist_ts_apiclient/classes.route.js +0 -154
- package/dist_ts_apiclient/classes.stats.d.ts +0 -47
- package/dist_ts_apiclient/classes.stats.js +0 -38
- package/dist_ts_apiclient/index.d.ts +0 -10
- package/dist_ts_apiclient/index.js +0 -14
- package/dist_ts_apiclient/plugins.d.ts +0 -3
- package/dist_ts_apiclient/plugins.js +0 -5
- package/dist_ts_web/00_commitinfo_data.d.ts +0 -8
- package/dist_ts_web/00_commitinfo_data.js +0 -9
- package/dist_ts_web/appstate.d.ts +0 -216
- package/dist_ts_web/appstate.js +0 -1064
- package/dist_ts_web/elements/index.d.ts +0 -12
- package/dist_ts_web/elements/index.js +0 -13
- package/dist_ts_web/elements/ops-dashboard.d.ts +0 -23
- package/dist_ts_web/elements/ops-dashboard.js +0 -317
- package/dist_ts_web/elements/ops-view-apitokens.d.ts +0 -13
- package/dist_ts_web/elements/ops-view-apitokens.js +0 -371
- package/dist_ts_web/elements/ops-view-certificates.d.ts +0 -22
- package/dist_ts_web/elements/ops-view-certificates.js +0 -528
- package/dist_ts_web/elements/ops-view-config.d.ts +0 -19
- package/dist_ts_web/elements/ops-view-config.js +0 -339
- package/dist_ts_web/elements/ops-view-emails.d.ts +0 -21
- package/dist_ts_web/elements/ops-view-emails.js +0 -165
- package/dist_ts_web/elements/ops-view-logs.d.ts +0 -13
- package/dist_ts_web/elements/ops-view-logs.js +0 -159
- package/dist_ts_web/elements/ops-view-network.d.ts +0 -71
- package/dist_ts_web/elements/ops-view-network.js +0 -764
- package/dist_ts_web/elements/ops-view-overview.d.ts +0 -22
- package/dist_ts_web/elements/ops-view-overview.js +0 -456
- package/dist_ts_web/elements/ops-view-remoteingress.d.ts +0 -20
- package/dist_ts_web/elements/ops-view-remoteingress.js +0 -494
- package/dist_ts_web/elements/ops-view-routes.d.ts +0 -12
- package/dist_ts_web/elements/ops-view-routes.js +0 -404
- package/dist_ts_web/elements/ops-view-security.d.ts +0 -21
- package/dist_ts_web/elements/ops-view-security.js +0 -574
- package/dist_ts_web/elements/shared/css.d.ts +0 -1
- package/dist_ts_web/elements/shared/css.js +0 -10
- package/dist_ts_web/elements/shared/index.d.ts +0 -2
- package/dist_ts_web/elements/shared/index.js +0 -3
- package/dist_ts_web/elements/shared/ops-sectionheading.d.ts +0 -5
- package/dist_ts_web/elements/shared/ops-sectionheading.js +0 -82
- package/dist_ts_web/index.d.ts +0 -1
- package/dist_ts_web/index.js +0 -10
- package/dist_ts_web/plugins.d.ts +0 -6
- package/dist_ts_web/plugins.js +0 -11
- package/dist_ts_web/router.d.ts +0 -19
- package/dist_ts_web/router.js +0 -91
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Log level for security events
|
|
3
|
-
*/
|
|
4
|
-
export declare enum SecurityLogLevel {
|
|
5
|
-
INFO = "info",
|
|
6
|
-
WARN = "warn",
|
|
7
|
-
ERROR = "error",
|
|
8
|
-
CRITICAL = "critical"
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Security event types for categorization
|
|
12
|
-
*/
|
|
13
|
-
export declare enum SecurityEventType {
|
|
14
|
-
AUTHENTICATION = "authentication",
|
|
15
|
-
ACCESS_CONTROL = "access_control",
|
|
16
|
-
EMAIL_VALIDATION = "email_validation",
|
|
17
|
-
EMAIL_PROCESSING = "email_processing",
|
|
18
|
-
EMAIL_FORWARDING = "email_forwarding",
|
|
19
|
-
EMAIL_DELIVERY = "email_delivery",
|
|
20
|
-
DKIM = "dkim",
|
|
21
|
-
SPF = "spf",
|
|
22
|
-
DMARC = "dmarc",
|
|
23
|
-
RATE_LIMIT = "rate_limit",
|
|
24
|
-
RATE_LIMITING = "rate_limiting",
|
|
25
|
-
SPAM = "spam",
|
|
26
|
-
MALWARE = "malware",
|
|
27
|
-
CONNECTION = "connection",
|
|
28
|
-
DATA_EXPOSURE = "data_exposure",
|
|
29
|
-
CONFIGURATION = "configuration",
|
|
30
|
-
IP_REPUTATION = "ip_reputation",
|
|
31
|
-
REJECTED_CONNECTION = "rejected_connection"
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Security event interface
|
|
35
|
-
*/
|
|
36
|
-
export interface ISecurityEvent {
|
|
37
|
-
timestamp: number;
|
|
38
|
-
level: SecurityLogLevel;
|
|
39
|
-
type: SecurityEventType;
|
|
40
|
-
message: string;
|
|
41
|
-
details?: any;
|
|
42
|
-
ipAddress?: string;
|
|
43
|
-
userId?: string;
|
|
44
|
-
sessionId?: string;
|
|
45
|
-
emailId?: string;
|
|
46
|
-
domain?: string;
|
|
47
|
-
action?: string;
|
|
48
|
-
result?: string;
|
|
49
|
-
success?: boolean;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Security logger for enhanced security monitoring
|
|
53
|
-
*/
|
|
54
|
-
export declare class SecurityLogger {
|
|
55
|
-
private static instance;
|
|
56
|
-
private securityEvents;
|
|
57
|
-
private maxEventHistory;
|
|
58
|
-
private enableNotifications;
|
|
59
|
-
private constructor();
|
|
60
|
-
/**
|
|
61
|
-
* Get singleton instance
|
|
62
|
-
*/
|
|
63
|
-
static getInstance(options?: {
|
|
64
|
-
maxEventHistory?: number;
|
|
65
|
-
enableNotifications?: boolean;
|
|
66
|
-
}): SecurityLogger;
|
|
67
|
-
/**
|
|
68
|
-
* Reset the singleton instance (for shutdown/testing)
|
|
69
|
-
*/
|
|
70
|
-
static resetInstance(): void;
|
|
71
|
-
/**
|
|
72
|
-
* Log a security event
|
|
73
|
-
* @param event The security event to log
|
|
74
|
-
*/
|
|
75
|
-
logEvent(event: Omit<ISecurityEvent, 'timestamp'>): void;
|
|
76
|
-
/**
|
|
77
|
-
* Get recent security events
|
|
78
|
-
* @param limit Maximum number of events to return
|
|
79
|
-
* @param filter Filter for specific event types
|
|
80
|
-
* @returns Recent security events
|
|
81
|
-
*/
|
|
82
|
-
getRecentEvents(limit?: number, filter?: {
|
|
83
|
-
level?: SecurityLogLevel;
|
|
84
|
-
type?: SecurityEventType;
|
|
85
|
-
fromTimestamp?: number;
|
|
86
|
-
toTimestamp?: number;
|
|
87
|
-
}): ISecurityEvent[];
|
|
88
|
-
/**
|
|
89
|
-
* Get events by security level
|
|
90
|
-
* @param level The security level to filter by
|
|
91
|
-
* @param limit Maximum number of events to return
|
|
92
|
-
* @returns Security events matching the level
|
|
93
|
-
*/
|
|
94
|
-
getEventsByLevel(level: SecurityLogLevel, limit?: number): ISecurityEvent[];
|
|
95
|
-
/**
|
|
96
|
-
* Get events by security type
|
|
97
|
-
* @param type The event type to filter by
|
|
98
|
-
* @param limit Maximum number of events to return
|
|
99
|
-
* @returns Security events matching the type
|
|
100
|
-
*/
|
|
101
|
-
getEventsByType(type: SecurityEventType, limit?: number): ISecurityEvent[];
|
|
102
|
-
/**
|
|
103
|
-
* Get security events for a specific IP address
|
|
104
|
-
* @param ipAddress The IP address to filter by
|
|
105
|
-
* @param limit Maximum number of events to return
|
|
106
|
-
* @returns Security events for the IP address
|
|
107
|
-
*/
|
|
108
|
-
getEventsByIP(ipAddress: string, limit?: number): ISecurityEvent[];
|
|
109
|
-
/**
|
|
110
|
-
* Get security events for a specific domain
|
|
111
|
-
* @param domain The domain to filter by
|
|
112
|
-
* @param limit Maximum number of events to return
|
|
113
|
-
* @returns Security events for the domain
|
|
114
|
-
*/
|
|
115
|
-
getEventsByDomain(domain: string, limit?: number): ISecurityEvent[];
|
|
116
|
-
/**
|
|
117
|
-
* Send a notification for critical security events
|
|
118
|
-
* @param event The security event to notify about
|
|
119
|
-
* @private
|
|
120
|
-
*/
|
|
121
|
-
private sendNotification;
|
|
122
|
-
/**
|
|
123
|
-
* Clear event history
|
|
124
|
-
*/
|
|
125
|
-
clearEvents(): void;
|
|
126
|
-
/**
|
|
127
|
-
* Get statistical summary of security events
|
|
128
|
-
* @param timeWindow Optional time window in milliseconds
|
|
129
|
-
* @returns Summary of security events
|
|
130
|
-
*/
|
|
131
|
-
getEventsSummary(timeWindow?: number): {
|
|
132
|
-
total: number;
|
|
133
|
-
byLevel: Record<SecurityLogLevel, number>;
|
|
134
|
-
byType: Record<SecurityEventType, number>;
|
|
135
|
-
topIPs: Array<{
|
|
136
|
-
ip: string;
|
|
137
|
-
count: number;
|
|
138
|
-
}>;
|
|
139
|
-
topDomains: Array<{
|
|
140
|
-
domain: string;
|
|
141
|
-
count: number;
|
|
142
|
-
}>;
|
|
143
|
-
};
|
|
144
|
-
}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import { logger } from '../logger.js';
|
|
3
|
-
/**
|
|
4
|
-
* Log level for security events
|
|
5
|
-
*/
|
|
6
|
-
export var SecurityLogLevel;
|
|
7
|
-
(function (SecurityLogLevel) {
|
|
8
|
-
SecurityLogLevel["INFO"] = "info";
|
|
9
|
-
SecurityLogLevel["WARN"] = "warn";
|
|
10
|
-
SecurityLogLevel["ERROR"] = "error";
|
|
11
|
-
SecurityLogLevel["CRITICAL"] = "critical";
|
|
12
|
-
})(SecurityLogLevel || (SecurityLogLevel = {}));
|
|
13
|
-
/**
|
|
14
|
-
* Security event types for categorization
|
|
15
|
-
*/
|
|
16
|
-
export var SecurityEventType;
|
|
17
|
-
(function (SecurityEventType) {
|
|
18
|
-
SecurityEventType["AUTHENTICATION"] = "authentication";
|
|
19
|
-
SecurityEventType["ACCESS_CONTROL"] = "access_control";
|
|
20
|
-
SecurityEventType["EMAIL_VALIDATION"] = "email_validation";
|
|
21
|
-
SecurityEventType["EMAIL_PROCESSING"] = "email_processing";
|
|
22
|
-
SecurityEventType["EMAIL_FORWARDING"] = "email_forwarding";
|
|
23
|
-
SecurityEventType["EMAIL_DELIVERY"] = "email_delivery";
|
|
24
|
-
SecurityEventType["DKIM"] = "dkim";
|
|
25
|
-
SecurityEventType["SPF"] = "spf";
|
|
26
|
-
SecurityEventType["DMARC"] = "dmarc";
|
|
27
|
-
SecurityEventType["RATE_LIMIT"] = "rate_limit";
|
|
28
|
-
SecurityEventType["RATE_LIMITING"] = "rate_limiting";
|
|
29
|
-
SecurityEventType["SPAM"] = "spam";
|
|
30
|
-
SecurityEventType["MALWARE"] = "malware";
|
|
31
|
-
SecurityEventType["CONNECTION"] = "connection";
|
|
32
|
-
SecurityEventType["DATA_EXPOSURE"] = "data_exposure";
|
|
33
|
-
SecurityEventType["CONFIGURATION"] = "configuration";
|
|
34
|
-
SecurityEventType["IP_REPUTATION"] = "ip_reputation";
|
|
35
|
-
SecurityEventType["REJECTED_CONNECTION"] = "rejected_connection";
|
|
36
|
-
})(SecurityEventType || (SecurityEventType = {}));
|
|
37
|
-
/**
|
|
38
|
-
* Security logger for enhanced security monitoring
|
|
39
|
-
*/
|
|
40
|
-
export class SecurityLogger {
|
|
41
|
-
static instance;
|
|
42
|
-
securityEvents = [];
|
|
43
|
-
maxEventHistory;
|
|
44
|
-
enableNotifications;
|
|
45
|
-
constructor(options) {
|
|
46
|
-
this.maxEventHistory = options?.maxEventHistory || 1000;
|
|
47
|
-
this.enableNotifications = options?.enableNotifications || false;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Get singleton instance
|
|
51
|
-
*/
|
|
52
|
-
static getInstance(options) {
|
|
53
|
-
if (!SecurityLogger.instance) {
|
|
54
|
-
SecurityLogger.instance = new SecurityLogger(options);
|
|
55
|
-
}
|
|
56
|
-
return SecurityLogger.instance;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Reset the singleton instance (for shutdown/testing)
|
|
60
|
-
*/
|
|
61
|
-
static resetInstance() {
|
|
62
|
-
SecurityLogger.instance = undefined;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Log a security event
|
|
66
|
-
* @param event The security event to log
|
|
67
|
-
*/
|
|
68
|
-
logEvent(event) {
|
|
69
|
-
const fullEvent = {
|
|
70
|
-
...event,
|
|
71
|
-
timestamp: Date.now()
|
|
72
|
-
};
|
|
73
|
-
// Store in memory buffer
|
|
74
|
-
this.securityEvents.push(fullEvent);
|
|
75
|
-
// Trim history if needed
|
|
76
|
-
if (this.securityEvents.length > this.maxEventHistory) {
|
|
77
|
-
this.securityEvents.shift();
|
|
78
|
-
}
|
|
79
|
-
// Log to regular logger with appropriate level
|
|
80
|
-
switch (event.level) {
|
|
81
|
-
case SecurityLogLevel.INFO:
|
|
82
|
-
logger.log('info', `[SECURITY:${event.type}] ${event.message}`, event.details);
|
|
83
|
-
break;
|
|
84
|
-
case SecurityLogLevel.WARN:
|
|
85
|
-
logger.log('warn', `[SECURITY:${event.type}] ${event.message}`, event.details);
|
|
86
|
-
break;
|
|
87
|
-
case SecurityLogLevel.ERROR:
|
|
88
|
-
case SecurityLogLevel.CRITICAL:
|
|
89
|
-
logger.log('error', `[SECURITY:${event.type}] ${event.message}`, event.details);
|
|
90
|
-
// Send notification for critical events if enabled
|
|
91
|
-
if (event.level === SecurityLogLevel.CRITICAL && this.enableNotifications) {
|
|
92
|
-
this.sendNotification(fullEvent);
|
|
93
|
-
}
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Get recent security events
|
|
99
|
-
* @param limit Maximum number of events to return
|
|
100
|
-
* @param filter Filter for specific event types
|
|
101
|
-
* @returns Recent security events
|
|
102
|
-
*/
|
|
103
|
-
getRecentEvents(limit = 100, filter) {
|
|
104
|
-
let filteredEvents = this.securityEvents;
|
|
105
|
-
// Apply filters
|
|
106
|
-
if (filter) {
|
|
107
|
-
if (filter.level) {
|
|
108
|
-
filteredEvents = filteredEvents.filter(event => event.level === filter.level);
|
|
109
|
-
}
|
|
110
|
-
if (filter.type) {
|
|
111
|
-
filteredEvents = filteredEvents.filter(event => event.type === filter.type);
|
|
112
|
-
}
|
|
113
|
-
if (filter.fromTimestamp) {
|
|
114
|
-
const fromTs = filter.fromTimestamp;
|
|
115
|
-
filteredEvents = filteredEvents.filter(event => event.timestamp >= fromTs);
|
|
116
|
-
}
|
|
117
|
-
if (filter.toTimestamp) {
|
|
118
|
-
const toTs = filter.toTimestamp;
|
|
119
|
-
filteredEvents = filteredEvents.filter(event => event.timestamp <= toTs);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// Return most recent events up to limit (slice first to avoid mutating source)
|
|
123
|
-
return filteredEvents
|
|
124
|
-
.slice()
|
|
125
|
-
.sort((a, b) => b.timestamp - a.timestamp)
|
|
126
|
-
.slice(0, limit);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Get events by security level
|
|
130
|
-
* @param level The security level to filter by
|
|
131
|
-
* @param limit Maximum number of events to return
|
|
132
|
-
* @returns Security events matching the level
|
|
133
|
-
*/
|
|
134
|
-
getEventsByLevel(level, limit = 100) {
|
|
135
|
-
return this.getRecentEvents(limit, { level });
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Get events by security type
|
|
139
|
-
* @param type The event type to filter by
|
|
140
|
-
* @param limit Maximum number of events to return
|
|
141
|
-
* @returns Security events matching the type
|
|
142
|
-
*/
|
|
143
|
-
getEventsByType(type, limit = 100) {
|
|
144
|
-
return this.getRecentEvents(limit, { type });
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Get security events for a specific IP address
|
|
148
|
-
* @param ipAddress The IP address to filter by
|
|
149
|
-
* @param limit Maximum number of events to return
|
|
150
|
-
* @returns Security events for the IP address
|
|
151
|
-
*/
|
|
152
|
-
getEventsByIP(ipAddress, limit = 100) {
|
|
153
|
-
return this.securityEvents
|
|
154
|
-
.filter(event => event.ipAddress === ipAddress)
|
|
155
|
-
.sort((a, b) => b.timestamp - a.timestamp)
|
|
156
|
-
.slice(0, limit);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Get security events for a specific domain
|
|
160
|
-
* @param domain The domain to filter by
|
|
161
|
-
* @param limit Maximum number of events to return
|
|
162
|
-
* @returns Security events for the domain
|
|
163
|
-
*/
|
|
164
|
-
getEventsByDomain(domain, limit = 100) {
|
|
165
|
-
return this.securityEvents
|
|
166
|
-
.filter(event => event.domain === domain)
|
|
167
|
-
.sort((a, b) => b.timestamp - a.timestamp)
|
|
168
|
-
.slice(0, limit);
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Send a notification for critical security events
|
|
172
|
-
* @param event The security event to notify about
|
|
173
|
-
* @private
|
|
174
|
-
*/
|
|
175
|
-
sendNotification(event) {
|
|
176
|
-
// In a production environment, this would integrate with a notification service
|
|
177
|
-
// For now, we'll just log that we would send a notification
|
|
178
|
-
logger.log('error', `[SECURITY NOTIFICATION] ${event.message}`, {
|
|
179
|
-
...event,
|
|
180
|
-
notificationSent: true
|
|
181
|
-
});
|
|
182
|
-
// Future integration with alerting systems would go here
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Clear event history
|
|
186
|
-
*/
|
|
187
|
-
clearEvents() {
|
|
188
|
-
this.securityEvents = [];
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Get statistical summary of security events
|
|
192
|
-
* @param timeWindow Optional time window in milliseconds
|
|
193
|
-
* @returns Summary of security events
|
|
194
|
-
*/
|
|
195
|
-
getEventsSummary(timeWindow) {
|
|
196
|
-
const cutoff = timeWindow ? Date.now() - timeWindow : 0;
|
|
197
|
-
// Initialize counters
|
|
198
|
-
const byLevel = {};
|
|
199
|
-
for (const level of Object.values(SecurityLogLevel)) {
|
|
200
|
-
byLevel[level] = 0;
|
|
201
|
-
}
|
|
202
|
-
const byType = {};
|
|
203
|
-
for (const type of Object.values(SecurityEventType)) {
|
|
204
|
-
byType[type] = 0;
|
|
205
|
-
}
|
|
206
|
-
const ipCounts = new Map();
|
|
207
|
-
const domainCounts = new Map();
|
|
208
|
-
// Single pass over all events
|
|
209
|
-
let total = 0;
|
|
210
|
-
for (const e of this.securityEvents) {
|
|
211
|
-
if (cutoff && e.timestamp < cutoff)
|
|
212
|
-
continue;
|
|
213
|
-
total++;
|
|
214
|
-
byLevel[e.level]++;
|
|
215
|
-
byType[e.type]++;
|
|
216
|
-
if (e.ipAddress) {
|
|
217
|
-
ipCounts.set(e.ipAddress, (ipCounts.get(e.ipAddress) || 0) + 1);
|
|
218
|
-
}
|
|
219
|
-
if (e.domain) {
|
|
220
|
-
domainCounts.set(e.domain, (domainCounts.get(e.domain) || 0) + 1);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
// Sort and limit top entries
|
|
224
|
-
const topIPs = Array.from(ipCounts.entries())
|
|
225
|
-
.map(([ip, count]) => ({ ip, count }))
|
|
226
|
-
.sort((a, b) => b.count - a.count)
|
|
227
|
-
.slice(0, 10);
|
|
228
|
-
const topDomains = Array.from(domainCounts.entries())
|
|
229
|
-
.map(([domain, count]) => ({ domain, count }))
|
|
230
|
-
.sort((a, b) => b.count - a.count)
|
|
231
|
-
.slice(0, 10);
|
|
232
|
-
return { total, byLevel, byType, topIPs, topDomains };
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zZWN1cml0eWxvZ2dlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3NlY3VyaXR5L2NsYXNzZXMuc2VjdXJpdHlsb2dnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV0Qzs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLGdCQUtYO0FBTEQsV0FBWSxnQkFBZ0I7SUFDMUIsaUNBQWEsQ0FBQTtJQUNiLGlDQUFhLENBQUE7SUFDYixtQ0FBZSxDQUFBO0lBQ2YseUNBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQUxXLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFLM0I7QUFFRDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLGlCQW1CWDtBQW5CRCxXQUFZLGlCQUFpQjtJQUMzQixzREFBaUMsQ0FBQTtJQUNqQyxzREFBaUMsQ0FBQTtJQUNqQywwREFBcUMsQ0FBQTtJQUNyQywwREFBcUMsQ0FBQTtJQUNyQywwREFBcUMsQ0FBQTtJQUNyQyxzREFBaUMsQ0FBQTtJQUNqQyxrQ0FBYSxDQUFBO0lBQ2IsZ0NBQVcsQ0FBQTtJQUNYLG9DQUFlLENBQUE7SUFDZiw4Q0FBeUIsQ0FBQTtJQUN6QixvREFBK0IsQ0FBQTtJQUMvQixrQ0FBYSxDQUFBO0lBQ2Isd0NBQW1CLENBQUE7SUFDbkIsOENBQXlCLENBQUE7SUFDekIsb0RBQStCLENBQUE7SUFDL0Isb0RBQStCLENBQUE7SUFDL0Isb0RBQStCLENBQUE7SUFDL0IsZ0VBQTJDLENBQUE7QUFDN0MsQ0FBQyxFQW5CVyxpQkFBaUIsS0FBakIsaUJBQWlCLFFBbUI1QjtBQXFCRDs7R0FFRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBQ2pCLE1BQU0sQ0FBQyxRQUFRLENBQTZCO0lBQzVDLGNBQWMsR0FBcUIsRUFBRSxDQUFDO0lBQ3RDLGVBQWUs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
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export { SecurityLogger, SecurityLogLevel, SecurityEventType, type ISecurityEvent } from './classes.securitylogger.js';
|
|
2
|
-
export { IPReputationChecker, ReputationThreshold, IPType, type IReputationResult, type IIPReputationOptions } from './classes.ipreputationchecker.js';
|
|
3
|
-
export { ContentScanner, ThreatCategory, type IScanResult, type IContentScannerOptions } from './classes.contentscanner.js';
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { SecurityLogger, SecurityLogLevel, SecurityEventType } from './classes.securitylogger.js';
|
|
2
|
-
export { IPReputationChecker, ReputationThreshold, IPType } from './classes.ipreputationchecker.js';
|
|
3
|
-
export { ContentScanner, ThreatCategory } from './classes.contentscanner.js';
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zZWN1cml0eS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixpQkFBaUIsRUFFbEIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLG1CQUFtQixFQUNuQixNQUFNLEVBR1AsTUFBTSxrQ0FBa0MsQ0FBQztBQUUxQyxPQUFPLEVBQ0wsY0FBYyxFQUNkLGNBQWMsRUFHZixNQUFNLDZCQUE2QixDQUFDIn0=
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import type { ISmsConfig } from './config/sms.config.js';
|
|
3
|
-
export declare class SmsService {
|
|
4
|
-
projectinfo: plugins.projectinfo.ProjectInfo;
|
|
5
|
-
typedrouter: plugins.typedrequest.TypedRouter<import("@api.global/typedrequest-interfaces").ITypedRequest>;
|
|
6
|
-
config: ISmsConfig;
|
|
7
|
-
constructor(options: ISmsConfig);
|
|
8
|
-
/**
|
|
9
|
-
* starts the financeflow instance
|
|
10
|
-
*/
|
|
11
|
-
start(): Promise<void>;
|
|
12
|
-
sendSms(toNumber: number, fromName: string, messageText: string): Promise<void>;
|
|
13
|
-
sendVerificationCode(toNumber: number, fromName: string): Promise<number>;
|
|
14
|
-
stop(): Promise<void>;
|
|
15
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import * as paths from '../paths.js';
|
|
3
|
-
import { logger } from '../logger.js';
|
|
4
|
-
import { smsConfigSchema } from './config/sms.schema.js';
|
|
5
|
-
import { ConfigValidator } from '../config/validator.js';
|
|
6
|
-
export class SmsService {
|
|
7
|
-
projectinfo;
|
|
8
|
-
typedrouter = new plugins.typedrequest.TypedRouter();
|
|
9
|
-
config;
|
|
10
|
-
constructor(options) {
|
|
11
|
-
// Validate and apply defaults to configuration
|
|
12
|
-
const validationResult = ConfigValidator.validate(options, smsConfigSchema);
|
|
13
|
-
if (!validationResult.valid) {
|
|
14
|
-
logger.warn(`SMS service configuration has validation errors: ${validationResult.errors.join(', ')}`);
|
|
15
|
-
}
|
|
16
|
-
// Set configuration with defaults
|
|
17
|
-
this.config = validationResult.config;
|
|
18
|
-
// Add router to platform service
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* starts the financeflow instance
|
|
22
|
-
*/
|
|
23
|
-
async start() {
|
|
24
|
-
logger.log('info', `starting sms service`);
|
|
25
|
-
this.projectinfo = await plugins.projectinfo.ProjectInfo.create(paths.packageDir);
|
|
26
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('sendSms', async (reqData) => {
|
|
27
|
-
await this.sendSms(reqData.toNumber, reqData.fromName, reqData.messageText);
|
|
28
|
-
return {
|
|
29
|
-
status: 'ok',
|
|
30
|
-
};
|
|
31
|
-
}));
|
|
32
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('sendVerificationCode', async (reqData) => {
|
|
33
|
-
const verificationCode = (await this.sendVerificationCode(reqData.toNumber, reqData.fromName)).toString();
|
|
34
|
-
return {
|
|
35
|
-
status: 'ok',
|
|
36
|
-
verificationCode,
|
|
37
|
-
};
|
|
38
|
-
}));
|
|
39
|
-
}
|
|
40
|
-
async sendSms(toNumber, fromName, messageText) {
|
|
41
|
-
// Use default sender if not specified
|
|
42
|
-
const sender = fromName || this.config.defaultSender || 'PlatformService';
|
|
43
|
-
const payload = {
|
|
44
|
-
sender,
|
|
45
|
-
message: messageText,
|
|
46
|
-
recipients: [{ msisdn: toNumber }],
|
|
47
|
-
};
|
|
48
|
-
const resp = await plugins.smartrequest.SmartRequest.create()
|
|
49
|
-
.url('https://gatewayapi.com/rest/mtsms')
|
|
50
|
-
.header('Authorization', `Basic ${Buffer.from(`${this.config.apiGatewayApiToken}:`).toString('base64')}`)
|
|
51
|
-
.header('Content-Type', 'application/json')
|
|
52
|
-
.json(payload)
|
|
53
|
-
.post();
|
|
54
|
-
const json = await resp.json();
|
|
55
|
-
logger.log('info', `sent an sms to ${toNumber} with text '${messageText}'`, {
|
|
56
|
-
eventType: 'sentSms',
|
|
57
|
-
sms: {
|
|
58
|
-
fromName: fromName,
|
|
59
|
-
toNumber: toNumber.toString(),
|
|
60
|
-
messageText: messageText,
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
console.log(JSON.stringify(json, null, 2));
|
|
64
|
-
}
|
|
65
|
-
async sendVerificationCode(toNumber, fromName) {
|
|
66
|
-
let verificationCode = Math.floor(100000 + Math.random() * 900000);
|
|
67
|
-
await this.sendSms(toNumber, fromName, `Your verification code: ${verificationCode}`);
|
|
68
|
-
return verificationCode;
|
|
69
|
-
}
|
|
70
|
-
async stop() { }
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbXNzZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc21zL2NsYXNzZXMuc21zc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBR3RDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFekQsTUFBTSxPQUFPLFVBQVU7SUFDZCxXQUFXLENBQW1DO0lBQzlDLFdBQVcsR0FBRyxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckQsTUFBTSxDQUFhO0lBRTFCLFlBQVksT0FBbUI7UUFDN0IsK0NBQStDO1FBQy9DLE1BQU0sZ0JBQWdCLEdBQUcsZUFBZSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFFNUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0RBQW9ELGdCQUFnQixDQUFDLE1BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3pHLENBQUM7UUFFRCxrQ0FBa0M7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7UUFFdEMsaUNBQWlDO0lBQ25DLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLENB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
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SMS service configuration interface
|
|
3
|
-
*/
|
|
4
|
-
export interface ISmsConfig {
|
|
5
|
-
/**
|
|
6
|
-
* API token for the gateway service
|
|
7
|
-
*/
|
|
8
|
-
apiGatewayApiToken: string;
|
|
9
|
-
/**
|
|
10
|
-
* Default sender ID or phone number
|
|
11
|
-
*/
|
|
12
|
-
defaultSender?: string;
|
|
13
|
-
/**
|
|
14
|
-
* SMS rate limiting
|
|
15
|
-
*/
|
|
16
|
-
rateLimit?: {
|
|
17
|
-
/**
|
|
18
|
-
* Whether rate limiting is enabled
|
|
19
|
-
*/
|
|
20
|
-
enabled?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Maximum requests per period
|
|
23
|
-
*/
|
|
24
|
-
maxPerPeriod?: number;
|
|
25
|
-
/**
|
|
26
|
-
* Period duration in milliseconds
|
|
27
|
-
*/
|
|
28
|
-
periodMs?: number;
|
|
29
|
-
/**
|
|
30
|
-
* Whether to apply rate limit per key
|
|
31
|
-
*/
|
|
32
|
-
perKey?: boolean;
|
|
33
|
-
/**
|
|
34
|
-
* Number of burst tokens
|
|
35
|
-
*/
|
|
36
|
-
burstTokens?: number;
|
|
37
|
-
/**
|
|
38
|
-
* Maximum messages per recipient per day
|
|
39
|
-
*/
|
|
40
|
-
maxPerRecipientPerDay?: number;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* SMS provider configuration
|
|
44
|
-
*/
|
|
45
|
-
provider?: {
|
|
46
|
-
/**
|
|
47
|
-
* Provider type
|
|
48
|
-
*/
|
|
49
|
-
type?: 'gateway' | 'twilio' | 'other';
|
|
50
|
-
/**
|
|
51
|
-
* Provider-specific configuration
|
|
52
|
-
*/
|
|
53
|
-
config?: Record<string, any>;
|
|
54
|
-
/**
|
|
55
|
-
* Fallback provider configuration
|
|
56
|
-
*/
|
|
57
|
-
fallback?: {
|
|
58
|
-
/**
|
|
59
|
-
* Whether to use fallback provider
|
|
60
|
-
*/
|
|
61
|
-
enabled?: boolean;
|
|
62
|
-
/**
|
|
63
|
-
* Provider type
|
|
64
|
-
*/
|
|
65
|
-
type?: 'gateway' | 'twilio' | 'other';
|
|
66
|
-
/**
|
|
67
|
-
* Provider-specific configuration
|
|
68
|
-
*/
|
|
69
|
-
config?: Record<string, any>;
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Verification code settings
|
|
74
|
-
*/
|
|
75
|
-
verification?: {
|
|
76
|
-
/**
|
|
77
|
-
* Code length
|
|
78
|
-
*/
|
|
79
|
-
codeLength?: number;
|
|
80
|
-
/**
|
|
81
|
-
* Code expiration time in seconds
|
|
82
|
-
*/
|
|
83
|
-
expirationSeconds?: number;
|
|
84
|
-
/**
|
|
85
|
-
* Maximum number of attempts
|
|
86
|
-
*/
|
|
87
|
-
maxAttempts?: number;
|
|
88
|
-
/**
|
|
89
|
-
* Cooldown period in seconds
|
|
90
|
-
*/
|
|
91
|
-
cooldownSeconds?: number;
|
|
92
|
-
};
|
|
93
|
-
}
|