@freshguard/freshguard-core 0.13.2 → 0.15.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/CHANGELOG.md +15 -1
- package/README.md +74 -1
- package/SKILL.md +229 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +74 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/connectors/azure-sql.d.ts +121 -0
- package/dist/connectors/azure-sql.d.ts.map +1 -0
- package/dist/connectors/azure-sql.js +489 -0
- package/dist/connectors/azure-sql.js.map +1 -0
- package/dist/connectors/base-connector.d.ts +139 -0
- package/dist/connectors/base-connector.d.ts.map +1 -1
- package/dist/connectors/base-connector.js +160 -3
- package/dist/connectors/base-connector.js.map +1 -1
- package/dist/connectors/bigquery.d.ts +100 -0
- package/dist/connectors/bigquery.d.ts.map +1 -1
- package/dist/connectors/bigquery.js +143 -2
- package/dist/connectors/bigquery.js.map +1 -1
- package/dist/connectors/duckdb.d.ts +96 -0
- package/dist/connectors/duckdb.d.ts.map +1 -1
- package/dist/connectors/duckdb.js +144 -7
- package/dist/connectors/duckdb.js.map +1 -1
- package/dist/connectors/index.d.ts +28 -0
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +28 -0
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/mssql.d.ts +119 -0
- package/dist/connectors/mssql.d.ts.map +1 -0
- package/dist/connectors/mssql.js +483 -0
- package/dist/connectors/mssql.js.map +1 -0
- package/dist/connectors/mysql.d.ts +85 -0
- package/dist/connectors/mysql.d.ts.map +1 -1
- package/dist/connectors/mysql.js +118 -3
- package/dist/connectors/mysql.js.map +1 -1
- package/dist/connectors/postgres.d.ts +85 -0
- package/dist/connectors/postgres.d.ts.map +1 -1
- package/dist/connectors/postgres.js +113 -6
- package/dist/connectors/postgres.js.map +1 -1
- package/dist/connectors/redshift.d.ts +90 -0
- package/dist/connectors/redshift.d.ts.map +1 -1
- package/dist/connectors/redshift.js +131 -7
- package/dist/connectors/redshift.js.map +1 -1
- package/dist/connectors/snowflake.d.ts +108 -0
- package/dist/connectors/snowflake.d.ts.map +1 -1
- package/dist/connectors/snowflake.js +137 -3
- package/dist/connectors/snowflake.js.map +1 -1
- package/dist/connectors/synapse.d.ts +123 -0
- package/dist/connectors/synapse.d.ts.map +1 -0
- package/dist/connectors/synapse.js +495 -0
- package/dist/connectors/synapse.js.map +1 -0
- package/dist/db/index.d.ts +25 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +23 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrate.d.ts +23 -0
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +38 -0
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/schema.d.ts +11 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +70 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/errors/debug-factory.d.ts +38 -0
- package/dist/errors/debug-factory.d.ts.map +1 -1
- package/dist/errors/debug-factory.js +40 -0
- package/dist/errors/debug-factory.js.map +1 -1
- package/dist/errors/index.d.ts +59 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +110 -7
- package/dist/errors/index.js.map +1 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata/duckdb-storage.d.ts +3 -0
- package/dist/metadata/duckdb-storage.d.ts.map +1 -1
- package/dist/metadata/duckdb-storage.js +6 -0
- package/dist/metadata/duckdb-storage.js.map +1 -1
- package/dist/metadata/factory.d.ts +30 -0
- package/dist/metadata/factory.d.ts.map +1 -1
- package/dist/metadata/factory.js +31 -0
- package/dist/metadata/factory.js.map +1 -1
- package/dist/metadata/index.d.ts +26 -0
- package/dist/metadata/index.d.ts.map +1 -1
- package/dist/metadata/index.js +26 -0
- package/dist/metadata/index.js.map +1 -1
- package/dist/metadata/interface.d.ts +33 -0
- package/dist/metadata/interface.d.ts.map +1 -1
- package/dist/metadata/interface.js +3 -0
- package/dist/metadata/interface.js.map +1 -1
- package/dist/metadata/postgresql-storage.d.ts +3 -0
- package/dist/metadata/postgresql-storage.d.ts.map +1 -1
- package/dist/metadata/postgresql-storage.js +12 -2
- package/dist/metadata/postgresql-storage.js.map +1 -1
- package/dist/metadata/schema-config.d.ts +53 -0
- package/dist/metadata/schema-config.d.ts.map +1 -1
- package/dist/metadata/schema-config.js +64 -0
- package/dist/metadata/schema-config.js.map +1 -1
- package/dist/metadata/types.d.ts +3 -0
- package/dist/metadata/types.d.ts.map +1 -1
- package/dist/metadata/types.js +3 -0
- package/dist/metadata/types.js.map +1 -1
- package/dist/monitor/baseline-calculator.d.ts +56 -0
- package/dist/monitor/baseline-calculator.d.ts.map +1 -1
- package/dist/monitor/baseline-calculator.js +72 -0
- package/dist/monitor/baseline-calculator.js.map +1 -1
- package/dist/monitor/baseline-config.d.ts +77 -0
- package/dist/monitor/baseline-config.d.ts.map +1 -1
- package/dist/monitor/baseline-config.js +79 -1
- package/dist/monitor/baseline-config.js.map +1 -1
- package/dist/monitor/freshness.d.ts +40 -0
- package/dist/monitor/freshness.d.ts.map +1 -1
- package/dist/monitor/freshness.js +82 -3
- package/dist/monitor/freshness.js.map +1 -1
- package/dist/monitor/index.d.ts +29 -0
- package/dist/monitor/index.d.ts.map +1 -1
- package/dist/monitor/index.js +29 -0
- package/dist/monitor/index.js.map +1 -1
- package/dist/monitor/schema-baseline.d.ts +45 -0
- package/dist/monitor/schema-baseline.d.ts.map +1 -1
- package/dist/monitor/schema-baseline.js +63 -5
- package/dist/monitor/schema-baseline.js.map +1 -1
- package/dist/monitor/schema-changes.d.ts +45 -0
- package/dist/monitor/schema-changes.d.ts.map +1 -1
- package/dist/monitor/schema-changes.js +85 -0
- package/dist/monitor/schema-changes.js.map +1 -1
- package/dist/monitor/volume.d.ts +43 -0
- package/dist/monitor/volume.d.ts.map +1 -1
- package/dist/monitor/volume.js +89 -0
- package/dist/monitor/volume.js.map +1 -1
- package/dist/observability/logger.d.ts +91 -0
- package/dist/observability/logger.d.ts.map +1 -1
- package/dist/observability/logger.js +108 -0
- package/dist/observability/logger.js.map +1 -1
- package/dist/observability/metrics.d.ts +140 -0
- package/dist/observability/metrics.d.ts.map +1 -1
- package/dist/observability/metrics.js +184 -7
- package/dist/observability/metrics.js.map +1 -1
- package/dist/resilience/circuit-breaker.d.ts +112 -2
- package/dist/resilience/circuit-breaker.d.ts.map +1 -1
- package/dist/resilience/circuit-breaker.js +140 -6
- package/dist/resilience/circuit-breaker.js.map +1 -1
- package/dist/resilience/index.d.ts +9 -0
- package/dist/resilience/index.d.ts.map +1 -1
- package/dist/resilience/index.js +13 -0
- package/dist/resilience/index.js.map +1 -1
- package/dist/resilience/retry-policy.d.ts +105 -0
- package/dist/resilience/retry-policy.d.ts.map +1 -1
- package/dist/resilience/retry-policy.js +158 -7
- package/dist/resilience/retry-policy.js.map +1 -1
- package/dist/resilience/timeout-manager.d.ts +137 -0
- package/dist/resilience/timeout-manager.d.ts.map +1 -1
- package/dist/resilience/timeout-manager.js +151 -4
- package/dist/resilience/timeout-manager.js.map +1 -1
- package/dist/security/query-analyzer.d.ts +124 -0
- package/dist/security/query-analyzer.d.ts.map +1 -1
- package/dist/security/query-analyzer.js +150 -9
- package/dist/security/query-analyzer.js.map +1 -1
- package/dist/security/schema-cache.d.ts +152 -0
- package/dist/security/schema-cache.d.ts.map +1 -1
- package/dist/security/schema-cache.js +144 -12
- package/dist/security/schema-cache.js.map +1 -1
- package/dist/types/connector.d.ts +68 -1
- package/dist/types/connector.d.ts.map +1 -1
- package/dist/types/connector.js +38 -15
- package/dist/types/connector.js.map +1 -1
- package/dist/types/driver-results.d.ts +28 -0
- package/dist/types/driver-results.d.ts.map +1 -1
- package/dist/types/driver-results.js +12 -0
- package/dist/types/driver-results.js.map +1 -1
- package/dist/types.d.ts +113 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/dist/validation/index.d.ts +8 -0
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +12 -0
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/runtime-validator.d.ts +98 -0
- package/dist/validation/runtime-validator.d.ts.map +1 -1
- package/dist/validation/runtime-validator.js +114 -1
- package/dist/validation/runtime-validator.js.map +1 -1
- package/dist/validation/sanitizers.d.ts +59 -0
- package/dist/validation/sanitizers.d.ts.map +1 -1
- package/dist/validation/sanitizers.js +104 -20
- package/dist/validation/sanitizers.js.map +1 -1
- package/dist/validation/schemas.d.ts +73 -0
- package/dist/validation/schemas.d.ts.map +1 -1
- package/dist/validation/schemas.js +132 -5
- package/dist/validation/schemas.js.map +1 -1
- package/dist/validators/index.d.ts +54 -0
- package/dist/validators/index.d.ts.map +1 -1
- package/dist/validators/index.js +93 -2
- package/dist/validators/index.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure Microsoft SQL Server connector for FreshGuard Core
|
|
3
|
+
* Extends BaseConnector with security built-in
|
|
4
|
+
*
|
|
5
|
+
* @module @freshguard/freshguard-core/connectors/mssql
|
|
6
|
+
*/
|
|
7
|
+
import { BaseConnector } from './base-connector.js';
|
|
8
|
+
import type { ConnectorConfig, TableSchema, SecurityConfig } from '../types/connector.js';
|
|
9
|
+
import { type QueryResultRow } from '../types/driver-results.js';
|
|
10
|
+
import type { SourceCredentials } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Secure SQL Server connector
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - SQL injection prevention
|
|
16
|
+
* - Connection timeouts
|
|
17
|
+
* - SSL enforcement
|
|
18
|
+
* - Read-only query patterns
|
|
19
|
+
* - Secure error handling
|
|
20
|
+
* - Connection pooling via mssql
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { MSSQLConnector } from '@freshguard/freshguard-core';
|
|
25
|
+
*
|
|
26
|
+
* const connector = new MSSQLConnector({
|
|
27
|
+
* host: 'sql-server.example.com', port: 1433,
|
|
28
|
+
* database: 'analytics',
|
|
29
|
+
* username: 'readonly',
|
|
30
|
+
* password: process.env.MSSQL_PASSWORD!,
|
|
31
|
+
* ssl: true,
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class MSSQLConnector extends BaseConnector {
|
|
36
|
+
private pool;
|
|
37
|
+
private connected;
|
|
38
|
+
/**
|
|
39
|
+
* @param config - Database connection settings (host, port, database, credentials)
|
|
40
|
+
* @param securityConfig - Optional overrides for query timeouts, max rows, SSL, and blocked keywords
|
|
41
|
+
*/
|
|
42
|
+
constructor(config: ConnectorConfig, securityConfig?: Partial<SecurityConfig>);
|
|
43
|
+
/**
|
|
44
|
+
* Connect to SQL Server database with security validation
|
|
45
|
+
*/
|
|
46
|
+
private connect;
|
|
47
|
+
/**
|
|
48
|
+
* Execute a validated SQL query with security measures
|
|
49
|
+
*/
|
|
50
|
+
protected executeQuery(sql: string): Promise<QueryResultRow[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Execute a parameterized SQL query using prepared statements
|
|
53
|
+
*/
|
|
54
|
+
protected executeParameterizedQuery(sql: string, parameters?: unknown[]): Promise<QueryResultRow[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Test database connection with security validation
|
|
57
|
+
*/
|
|
58
|
+
testConnection(debugConfig?: import('../types.js').DebugConfig): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Helper method to merge debug configuration
|
|
61
|
+
*/
|
|
62
|
+
private mergeDebugConfig;
|
|
63
|
+
/**
|
|
64
|
+
* Generate connection suggestions based on error
|
|
65
|
+
*/
|
|
66
|
+
private generateConnectionSuggestion;
|
|
67
|
+
/**
|
|
68
|
+
* List all tables in the database
|
|
69
|
+
*/
|
|
70
|
+
listTables(): Promise<string[]>;
|
|
71
|
+
/**
|
|
72
|
+
* Get table schema information securely
|
|
73
|
+
*/
|
|
74
|
+
getTableSchema(table: string): Promise<TableSchema>;
|
|
75
|
+
/**
|
|
76
|
+
* Get last modified timestamp using SQL Server-specific methods
|
|
77
|
+
*/
|
|
78
|
+
getLastModified(table: string): Promise<Date | null>;
|
|
79
|
+
/**
|
|
80
|
+
* Close the database connection
|
|
81
|
+
*/
|
|
82
|
+
close(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Map SQL Server data types to standard types
|
|
85
|
+
*/
|
|
86
|
+
private mapMSSQLType;
|
|
87
|
+
/**
|
|
88
|
+
* Override escapeIdentifier for SQL Server bracket notation
|
|
89
|
+
*/
|
|
90
|
+
protected escapeIdentifier(identifier: string): string;
|
|
91
|
+
/**
|
|
92
|
+
* Legacy connect method for backward compatibility
|
|
93
|
+
* @deprecated Use constructor with ConnectorConfig instead
|
|
94
|
+
*/
|
|
95
|
+
connectLegacy(credentials: SourceCredentials): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Legacy test connection method for backward compatibility
|
|
98
|
+
* @deprecated Use testConnection() instead
|
|
99
|
+
*/
|
|
100
|
+
testConnectionLegacy(): Promise<{
|
|
101
|
+
success: boolean;
|
|
102
|
+
tableCount?: number;
|
|
103
|
+
error?: string;
|
|
104
|
+
}>;
|
|
105
|
+
/**
|
|
106
|
+
* Legacy get table metadata method for backward compatibility
|
|
107
|
+
* @deprecated Use getRowCount() and getMaxTimestamp() instead
|
|
108
|
+
*/
|
|
109
|
+
getTableMetadata(tableName: string, timestampColumn?: string): Promise<{
|
|
110
|
+
rowCount: number;
|
|
111
|
+
lastUpdate?: Date;
|
|
112
|
+
}>;
|
|
113
|
+
/**
|
|
114
|
+
* Legacy query method for backward compatibility
|
|
115
|
+
* @deprecated Direct SQL queries are not allowed for security reasons
|
|
116
|
+
*/
|
|
117
|
+
query<T = unknown>(_sql: string): Promise<T[]>;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=mssql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mssql.d.ts","sourceRoot":"","sources":["../../src/connectors/mssql.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC1F,OAAO,EAAE,KAAK,cAAc,EAAa,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,cAAe,SAAQ,aAAa;IAC/C,OAAO,CAAC,IAAI,CAAqC;IACjD,OAAO,CAAC,SAAS,CAAS;IAE1B;;;OAGG;gBACS,MAAM,EAAE,eAAe,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAM7E;;OAEG;YACW,OAAO;IAwCrB;;OAEG;cACa,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAIpE;;OAEG;cACa,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAoD7G;;OAEG;IACG,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,aAAa,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAgEvF;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAkCpC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IA2BrC;;OAEG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA+CzD;;OAEG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAsC1D;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAmDpB;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAmBtD;;;OAGG;IACG,aAAa,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlE;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA2BhG;;;OAGG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,eAAe,SAAe,GAC7B,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC;IAqBnD;;;OAGG;IAEG,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;CAKrD"}
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure Microsoft SQL Server connector for FreshGuard Core
|
|
3
|
+
* Extends BaseConnector with security built-in
|
|
4
|
+
*
|
|
5
|
+
* @module @freshguard/freshguard-core/connectors/mssql
|
|
6
|
+
*/
|
|
7
|
+
import * as mssql from 'mssql';
|
|
8
|
+
import { BaseConnector } from './base-connector.js';
|
|
9
|
+
import { rowString } from '../types/driver-results.js';
|
|
10
|
+
import { ConnectionError, TimeoutError, QueryError, ErrorHandler } from '../errors/index.js';
|
|
11
|
+
import { validateConnectorConfig } from '../validators/index.js';
|
|
12
|
+
/**
|
|
13
|
+
* Secure SQL Server connector
|
|
14
|
+
*
|
|
15
|
+
* Features:
|
|
16
|
+
* - SQL injection prevention
|
|
17
|
+
* - Connection timeouts
|
|
18
|
+
* - SSL enforcement
|
|
19
|
+
* - Read-only query patterns
|
|
20
|
+
* - Secure error handling
|
|
21
|
+
* - Connection pooling via mssql
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* import { MSSQLConnector } from '@freshguard/freshguard-core';
|
|
26
|
+
*
|
|
27
|
+
* const connector = new MSSQLConnector({
|
|
28
|
+
* host: 'sql-server.example.com', port: 1433,
|
|
29
|
+
* database: 'analytics',
|
|
30
|
+
* username: 'readonly',
|
|
31
|
+
* password: process.env.MSSQL_PASSWORD!,
|
|
32
|
+
* ssl: true,
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export class MSSQLConnector extends BaseConnector {
|
|
37
|
+
pool = null;
|
|
38
|
+
connected = false;
|
|
39
|
+
/**
|
|
40
|
+
* @param config - Database connection settings (host, port, database, credentials)
|
|
41
|
+
* @param securityConfig - Optional overrides for query timeouts, max rows, SSL, and blocked keywords
|
|
42
|
+
*/
|
|
43
|
+
constructor(config, securityConfig) {
|
|
44
|
+
// Validate configuration before proceeding
|
|
45
|
+
validateConnectorConfig(config);
|
|
46
|
+
super(config, securityConfig);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Connect to SQL Server database with security validation
|
|
50
|
+
*/
|
|
51
|
+
async connect() {
|
|
52
|
+
if (this.connected && this.pool) {
|
|
53
|
+
return; // Already connected
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const poolConfig = {
|
|
57
|
+
server: this.config.host,
|
|
58
|
+
port: this.config.port ?? 1433,
|
|
59
|
+
database: this.config.database,
|
|
60
|
+
user: this.config.username,
|
|
61
|
+
password: this.config.password,
|
|
62
|
+
options: {
|
|
63
|
+
encrypt: this.requireSSL || this.config.ssl !== false,
|
|
64
|
+
trustServerCertificate: false,
|
|
65
|
+
connectTimeout: this.connectionTimeout,
|
|
66
|
+
requestTimeout: this.queryTimeout,
|
|
67
|
+
appName: this.config.applicationName ?? 'freshguard-core'
|
|
68
|
+
},
|
|
69
|
+
pool: {
|
|
70
|
+
max: 1, // Single connection for monitoring
|
|
71
|
+
min: 0,
|
|
72
|
+
idleTimeoutMillis: 30000
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
this.pool = new mssql.ConnectionPool(poolConfig);
|
|
76
|
+
await this.pool.connect();
|
|
77
|
+
this.connected = true;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
throw new ConnectionError('Failed to connect to SQL Server', this.config.host, this.config.port, error instanceof Error ? error : undefined);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Execute a validated SQL query with security measures
|
|
85
|
+
*/
|
|
86
|
+
async executeQuery(sql) {
|
|
87
|
+
return this.executeParameterizedQuery(sql, []);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Execute a parameterized SQL query using prepared statements
|
|
91
|
+
*/
|
|
92
|
+
async executeParameterizedQuery(sql, parameters = []) {
|
|
93
|
+
await this.connect();
|
|
94
|
+
if (!this.pool) {
|
|
95
|
+
throw new ConnectionError('Database connection not available');
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const result = await this.executeWithTimeout(async () => {
|
|
99
|
+
if (!this.pool)
|
|
100
|
+
throw new ConnectionError('Database connection not available');
|
|
101
|
+
const request = this.pool.request();
|
|
102
|
+
// Bind positional parameters as @p1, @p2, etc.
|
|
103
|
+
for (let i = 0; i < parameters.length; i++) {
|
|
104
|
+
request.input(`p${i + 1}`, parameters[i]);
|
|
105
|
+
}
|
|
106
|
+
// Replace $N placeholders with @pN for MSSQL
|
|
107
|
+
let mssqlSql = sql;
|
|
108
|
+
for (let i = parameters.length; i >= 1; i--) {
|
|
109
|
+
mssqlSql = mssqlSql.replace(new RegExp(`\\$${i}`, 'g'), `@p${i}`);
|
|
110
|
+
}
|
|
111
|
+
// Also replace ? placeholders with @pN
|
|
112
|
+
let paramIndex = 0;
|
|
113
|
+
mssqlSql = mssqlSql.replace(/\?/g, () => `@p${++paramIndex}`);
|
|
114
|
+
const res = await request.query(mssqlSql);
|
|
115
|
+
return (res.recordset ?? []);
|
|
116
|
+
}, this.queryTimeout);
|
|
117
|
+
// Validate result size for security
|
|
118
|
+
this.validateResultSize(result);
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error instanceof TimeoutError) {
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
// Sanitize and re-throw as QueryError
|
|
126
|
+
throw new QueryError(ErrorHandler.getUserMessage(error), 'query_execution', undefined, error instanceof Error ? error : undefined);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Test database connection with security validation
|
|
131
|
+
*/
|
|
132
|
+
async testConnection(debugConfig) {
|
|
133
|
+
const mergedDebugConfig = this.mergeDebugConfig(debugConfig);
|
|
134
|
+
const debugId = `mssql-test-${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 5)}`;
|
|
135
|
+
const startTime = performance.now();
|
|
136
|
+
try {
|
|
137
|
+
this.logDebugInfo(mergedDebugConfig, debugId, 'Starting connection test', {
|
|
138
|
+
host: this.config.host,
|
|
139
|
+
port: this.config.port,
|
|
140
|
+
database: this.config.database,
|
|
141
|
+
ssl: this.config.ssl
|
|
142
|
+
});
|
|
143
|
+
await this.connect();
|
|
144
|
+
if (!this.pool) {
|
|
145
|
+
this.logDebugError(mergedDebugConfig, debugId, 'Connection test', {
|
|
146
|
+
error: 'Connection not available after connect',
|
|
147
|
+
duration: performance.now() - startTime
|
|
148
|
+
});
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// Test with a simple, safe query (skip validation for connection test)
|
|
152
|
+
const sql = 'SELECT 1 AS test';
|
|
153
|
+
await this.executeWithTimeout(async () => {
|
|
154
|
+
if (!this.pool)
|
|
155
|
+
throw new ConnectionError('Database connection not available');
|
|
156
|
+
const request = this.pool.request();
|
|
157
|
+
return request.query(sql);
|
|
158
|
+
}, this.connectionTimeout);
|
|
159
|
+
const duration = performance.now() - startTime;
|
|
160
|
+
if (mergedDebugConfig?.enabled) {
|
|
161
|
+
console.log(`[DEBUG-${debugId}] Connection test completed:`, {
|
|
162
|
+
success: true,
|
|
163
|
+
duration,
|
|
164
|
+
host: this.config.host,
|
|
165
|
+
database: this.config.database
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
const duration = performance.now() - startTime;
|
|
172
|
+
this.logDebugError(mergedDebugConfig, debugId, 'Connection test', {
|
|
173
|
+
host: this.config.host,
|
|
174
|
+
port: this.config.port,
|
|
175
|
+
database: this.config.database,
|
|
176
|
+
error: mergedDebugConfig?.exposeRawErrors && error instanceof Error ? error.message : 'Connection failed',
|
|
177
|
+
duration,
|
|
178
|
+
suggestion: this.generateConnectionSuggestion(error)
|
|
179
|
+
});
|
|
180
|
+
// Don't throw - this method should return boolean
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Helper method to merge debug configuration
|
|
186
|
+
*/
|
|
187
|
+
mergeDebugConfig(debugConfig) {
|
|
188
|
+
return {
|
|
189
|
+
enabled: debugConfig?.enabled ?? (process.env.NODE_ENV === 'development'),
|
|
190
|
+
exposeQueries: debugConfig?.exposeQueries ?? true,
|
|
191
|
+
exposeRawErrors: debugConfig?.exposeRawErrors ?? true,
|
|
192
|
+
logLevel: debugConfig?.logLevel ?? 'debug'
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Generate connection suggestions based on error
|
|
197
|
+
*/
|
|
198
|
+
generateConnectionSuggestion(error) {
|
|
199
|
+
if (!(error instanceof Error)) {
|
|
200
|
+
return 'Check database connection configuration';
|
|
201
|
+
}
|
|
202
|
+
const message = error.message.toLowerCase();
|
|
203
|
+
if (message.includes('connect econnrefused') || message.includes('connection refused')) {
|
|
204
|
+
return `SQL Server at ${this.config.host}:${this.config.port} is not accepting connections. Verify the server is running and TCP/IP protocol is enabled in SQL Server Configuration Manager.`;
|
|
205
|
+
}
|
|
206
|
+
if (message.includes('timeout') || message.includes('connect timeout')) {
|
|
207
|
+
return `Connection timeout to ${this.config.host}:${this.config.port}. Check network connectivity, firewall rules, and server responsiveness.`;
|
|
208
|
+
}
|
|
209
|
+
if (message.includes('login failed') || message.includes('authentication failed')) {
|
|
210
|
+
return `Authentication failed for database '${this.config.database}'. Verify username, password, and that SQL Server authentication is enabled.`;
|
|
211
|
+
}
|
|
212
|
+
if (message.includes('cannot open database') || message.includes('database') && message.includes('not exist')) {
|
|
213
|
+
return `Database '${this.config.database}' not found on server. Check database name and create if necessary.`;
|
|
214
|
+
}
|
|
215
|
+
if (message.includes('ssl') || message.includes('tls') || message.includes('encrypt')) {
|
|
216
|
+
return `SSL/TLS connection issue. Check SSL configuration and server certificate settings.`;
|
|
217
|
+
}
|
|
218
|
+
if (message.includes('named pipes') || message.includes('named instance')) {
|
|
219
|
+
return `Connection issue with named instance. Ensure SQL Server Browser service is running and use hostname\\instance format.`;
|
|
220
|
+
}
|
|
221
|
+
return `Connection failed to ${this.config.host}:${this.config.port}. Check host, port, credentials, and network connectivity.`;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* List all tables in the database
|
|
225
|
+
*/
|
|
226
|
+
async listTables() {
|
|
227
|
+
const sql = `
|
|
228
|
+
SELECT TABLE_NAME as table_name
|
|
229
|
+
FROM INFORMATION_SCHEMA.TABLES
|
|
230
|
+
WHERE TABLE_TYPE = 'BASE TABLE'
|
|
231
|
+
AND TABLE_SCHEMA = 'dbo'
|
|
232
|
+
ORDER BY TABLE_NAME
|
|
233
|
+
`;
|
|
234
|
+
await this.validateQuery(sql);
|
|
235
|
+
try {
|
|
236
|
+
const result = await this.executeQuery(sql);
|
|
237
|
+
return result
|
|
238
|
+
.slice(0, this.maxRows)
|
|
239
|
+
.map((row) => rowString(row.table_name ?? row.TABLE_NAME ?? row.tablename))
|
|
240
|
+
.filter(Boolean);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
throw new QueryError('Failed to list tables', 'table_listing', undefined, error instanceof Error ? error : undefined);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get table schema information securely
|
|
248
|
+
*/
|
|
249
|
+
async getTableSchema(table) {
|
|
250
|
+
// Validate table name (identifiers cannot be parameterized)
|
|
251
|
+
this.escapeIdentifier(table);
|
|
252
|
+
const sql = `
|
|
253
|
+
SELECT
|
|
254
|
+
COLUMN_NAME as column_name,
|
|
255
|
+
DATA_TYPE as data_type,
|
|
256
|
+
IS_NULLABLE as is_nullable
|
|
257
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
|
258
|
+
WHERE TABLE_SCHEMA = 'dbo'
|
|
259
|
+
AND TABLE_NAME = '${table}'
|
|
260
|
+
ORDER BY ORDINAL_POSITION
|
|
261
|
+
`;
|
|
262
|
+
await this.validateQuery(sql);
|
|
263
|
+
try {
|
|
264
|
+
const result = await this.executeQuery(sql);
|
|
265
|
+
const limited = result.slice(0, this.maxRows);
|
|
266
|
+
if (limited.length === 0) {
|
|
267
|
+
throw QueryError.tableNotFound(table);
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
table,
|
|
271
|
+
columns: limited.map(row => ({
|
|
272
|
+
name: rowString(row.column_name ?? row.COLUMN_NAME),
|
|
273
|
+
type: this.mapMSSQLType(rowString(row.data_type ?? row.DATA_TYPE)),
|
|
274
|
+
nullable: (row.is_nullable ?? row.IS_NULLABLE) === 'YES'
|
|
275
|
+
}))
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
if (error instanceof QueryError) {
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
throw new QueryError('Failed to get table schema', 'schema_query', table, error instanceof Error ? error : undefined);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Get last modified timestamp using SQL Server-specific methods
|
|
287
|
+
*/
|
|
288
|
+
async getLastModified(table) {
|
|
289
|
+
// Try common timestamp columns
|
|
290
|
+
const timestampColumns = ['updated_at', 'modified_at', 'last_modified', 'timestamp'];
|
|
291
|
+
for (const column of timestampColumns) {
|
|
292
|
+
try {
|
|
293
|
+
const result = await this.getMaxTimestamp(table, column);
|
|
294
|
+
if (result) {
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// Column doesn't exist, try next one
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Fallback: use SQL Server DMV for index usage stats
|
|
304
|
+
try {
|
|
305
|
+
const sql = `
|
|
306
|
+
SELECT MAX(last_user_update) as last_modified
|
|
307
|
+
FROM sys.dm_db_index_usage_stats
|
|
308
|
+
WHERE database_id = DB_ID()
|
|
309
|
+
AND object_id = OBJECT_ID('dbo.${this.escapeIdentifier(table).replace(/\[|\]/g, '')}')
|
|
310
|
+
`;
|
|
311
|
+
await this.validateQuery(sql);
|
|
312
|
+
const result = await this.executeQuery(sql);
|
|
313
|
+
if (result.length > 0 && result[0]?.last_modified) {
|
|
314
|
+
return new Date(rowString(result[0].last_modified));
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// DMV query failed, return null
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Close the database connection
|
|
324
|
+
*/
|
|
325
|
+
async close() {
|
|
326
|
+
if (this.pool) {
|
|
327
|
+
try {
|
|
328
|
+
await this.pool.close();
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
// Log error but don't throw - closing should be safe
|
|
332
|
+
console.warn('Warning: Error closing SQL Server connection:', ErrorHandler.getUserMessage(error));
|
|
333
|
+
}
|
|
334
|
+
finally {
|
|
335
|
+
this.pool = null;
|
|
336
|
+
this.connected = false;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Map SQL Server data types to standard types
|
|
342
|
+
*/
|
|
343
|
+
mapMSSQLType(mssqlType) {
|
|
344
|
+
const typeMap = {
|
|
345
|
+
// Numeric types
|
|
346
|
+
'tinyint': 'integer',
|
|
347
|
+
'smallint': 'integer',
|
|
348
|
+
'int': 'integer',
|
|
349
|
+
'integer': 'integer',
|
|
350
|
+
'bigint': 'bigint',
|
|
351
|
+
'decimal': 'decimal',
|
|
352
|
+
'numeric': 'decimal',
|
|
353
|
+
'money': 'decimal',
|
|
354
|
+
'smallmoney': 'decimal',
|
|
355
|
+
'float': 'float',
|
|
356
|
+
'real': 'float',
|
|
357
|
+
'bit': 'boolean',
|
|
358
|
+
// String types
|
|
359
|
+
'char': 'text',
|
|
360
|
+
'varchar': 'text',
|
|
361
|
+
'text': 'text',
|
|
362
|
+
'nchar': 'text',
|
|
363
|
+
'nvarchar': 'text',
|
|
364
|
+
'ntext': 'text',
|
|
365
|
+
// Date/time types
|
|
366
|
+
'date': 'date',
|
|
367
|
+
'time': 'time',
|
|
368
|
+
'datetime': 'timestamp',
|
|
369
|
+
'datetime2': 'timestamp',
|
|
370
|
+
'smalldatetime': 'timestamp',
|
|
371
|
+
'datetimeoffset': 'timestamptz',
|
|
372
|
+
// Binary types
|
|
373
|
+
'binary': 'text',
|
|
374
|
+
'varbinary': 'text',
|
|
375
|
+
'image': 'text',
|
|
376
|
+
// Special types
|
|
377
|
+
'uniqueidentifier': 'text',
|
|
378
|
+
'xml': 'text',
|
|
379
|
+
'sql_variant': 'text',
|
|
380
|
+
'hierarchyid': 'text',
|
|
381
|
+
'geometry': 'text',
|
|
382
|
+
'geography': 'text',
|
|
383
|
+
'timestamp': 'text', // SQL Server timestamp is a rowversion, not a date
|
|
384
|
+
'rowversion': 'text'
|
|
385
|
+
};
|
|
386
|
+
return typeMap[mssqlType.toLowerCase()] ?? 'unknown';
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Override escapeIdentifier for SQL Server bracket notation
|
|
390
|
+
*/
|
|
391
|
+
escapeIdentifier(identifier) {
|
|
392
|
+
// Only allow alphanumeric, underscore, and dot (for schema.table)
|
|
393
|
+
if (!/^[a-zA-Z0-9_.]+$/.test(identifier)) {
|
|
394
|
+
throw new Error(`Invalid identifier: ${identifier}`);
|
|
395
|
+
}
|
|
396
|
+
// Additional length check
|
|
397
|
+
if (identifier.length > 256) {
|
|
398
|
+
throw new Error('Identifier too long');
|
|
399
|
+
}
|
|
400
|
+
// Return with brackets for SQL Server
|
|
401
|
+
return `[${identifier}]`;
|
|
402
|
+
}
|
|
403
|
+
// ==============================================
|
|
404
|
+
// Legacy API compatibility methods
|
|
405
|
+
// ==============================================
|
|
406
|
+
/**
|
|
407
|
+
* Legacy connect method for backward compatibility
|
|
408
|
+
* @deprecated Use constructor with ConnectorConfig instead
|
|
409
|
+
*/
|
|
410
|
+
async connectLegacy(credentials) {
|
|
411
|
+
console.warn('Warning: connectLegacy is deprecated. Use constructor with ConnectorConfig instead.');
|
|
412
|
+
// Convert legacy credentials to new format
|
|
413
|
+
const config = {
|
|
414
|
+
host: credentials.host ?? '',
|
|
415
|
+
port: credentials.port ?? 1433,
|
|
416
|
+
database: credentials.database ?? '',
|
|
417
|
+
username: credentials.username ?? '',
|
|
418
|
+
password: credentials.password ?? '',
|
|
419
|
+
ssl: credentials.sslMode !== 'disable'
|
|
420
|
+
};
|
|
421
|
+
// Validate and reconnect
|
|
422
|
+
validateConnectorConfig(config);
|
|
423
|
+
this.config = { ...this.config, ...config };
|
|
424
|
+
await this.connect();
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Legacy test connection method for backward compatibility
|
|
428
|
+
* @deprecated Use testConnection() instead
|
|
429
|
+
*/
|
|
430
|
+
async testConnectionLegacy() {
|
|
431
|
+
console.warn('Warning: testConnectionLegacy is deprecated. Use testConnection() instead.');
|
|
432
|
+
try {
|
|
433
|
+
const success = await this.testConnection();
|
|
434
|
+
if (success) {
|
|
435
|
+
// Get table count for legacy compatibility
|
|
436
|
+
const tables = await this.listTables();
|
|
437
|
+
return {
|
|
438
|
+
success: true,
|
|
439
|
+
tableCount: tables.length
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
return {
|
|
444
|
+
success: false,
|
|
445
|
+
error: 'Connection test failed'
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
return {
|
|
451
|
+
success: false,
|
|
452
|
+
error: ErrorHandler.getUserMessage(error)
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Legacy get table metadata method for backward compatibility
|
|
458
|
+
* @deprecated Use getRowCount() and getMaxTimestamp() instead
|
|
459
|
+
*/
|
|
460
|
+
async getTableMetadata(tableName, timestampColumn = 'updated_at') {
|
|
461
|
+
console.warn('Warning: getTableMetadata is deprecated. Use getRowCount() and getMaxTimestamp() instead.');
|
|
462
|
+
try {
|
|
463
|
+
const rowCount = await this.getRowCount(tableName);
|
|
464
|
+
const lastUpdate = await this.getMaxTimestamp(tableName, timestampColumn);
|
|
465
|
+
return {
|
|
466
|
+
rowCount,
|
|
467
|
+
lastUpdate: lastUpdate ?? undefined
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
catch (error) {
|
|
471
|
+
throw new QueryError('Failed to get table metadata', 'metadata_query', tableName, error instanceof Error ? error : undefined);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Legacy query method for backward compatibility
|
|
476
|
+
* @deprecated Direct SQL queries are not allowed for security reasons
|
|
477
|
+
*/
|
|
478
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- deprecated stub that always throws
|
|
479
|
+
async query(_sql) {
|
|
480
|
+
throw new Error('Direct SQL queries are not allowed for security reasons. Use specific methods like getRowCount(), getMaxTimestamp(), etc.');
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
//# sourceMappingURL=mssql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mssql.js","sourceRoot":"","sources":["../../src/connectors/mssql.ts"],"names":[],"mappings":"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"}
|