@tachles/starter 1.1.0 → 1.1.1

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.
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Security Configuration Guide
3
+ *
4
+ * This file documents the security configuration options.
5
+ * These are the default values and should not be modified unless you understand the implications.
6
+ *
7
+ * To customize security settings, you would need to fork the project and modify
8
+ * src/utils/security.ts
9
+ */
10
+ export interface SecurityConfigOptions {
11
+ /**
12
+ * Maximum number of packages that can be installed in one operation
13
+ * Default: 50
14
+ *
15
+ * Higher values may allow DoS through excessive installations.
16
+ * Lower values may break legitimate large templates.
17
+ */
18
+ MAX_PACKAGES_PER_OPERATION: number;
19
+ /**
20
+ * Maximum number of commands that can be executed in one recipe
21
+ * Default: 20
22
+ *
23
+ * Higher values may allow command flooding.
24
+ * Lower values may break complex setup templates.
25
+ */
26
+ MAX_COMMANDS_PER_RECIPE: number;
27
+ /**
28
+ * Timeout for individual commands in milliseconds
29
+ * Default: 1800000 (30 minutes)
30
+ *
31
+ * Higher values may allow indefinitely hanging processes.
32
+ * Lower values may break legitimate long-running operations (database migrations, etc.)
33
+ */
34
+ COMMAND_TIMEOUT_MS: number;
35
+ /**
36
+ * Maximum package name length (npm standard)
37
+ * Default: 214
38
+ *
39
+ * Should match npm's limit unless you have a specific reason to change it.
40
+ */
41
+ MAX_PACKAGE_NAME_LENGTH: number;
42
+ /**
43
+ * Maximum command string length
44
+ * Default: 1000
45
+ *
46
+ * Extremely long commands are suspicious and may indicate abuse.
47
+ */
48
+ MAX_COMMAND_LENGTH: number;
49
+ }
50
+ /**
51
+ * Rate Limiter Configuration
52
+ */
53
+ export interface RateLimiterOptions {
54
+ /**
55
+ * Time window in milliseconds
56
+ * Default: 60000 (1 minute)
57
+ */
58
+ windowMs: number;
59
+ /**
60
+ * Maximum requests per window
61
+ * Default: 20
62
+ */
63
+ maxRequests: number;
64
+ }
65
+ /**
66
+ * Example: Strict Security Profile
67
+ *
68
+ * For high-security environments, use these settings:
69
+ */
70
+ export declare const STRICT_SECURITY: SecurityConfigOptions;
71
+ /**
72
+ * Example: Permissive Security Profile
73
+ *
74
+ * For testing/development, you might use:
75
+ * WARNING: Do not use in production!
76
+ */
77
+ export declare const PERMISSIVE_SECURITY: SecurityConfigOptions;
78
+ /**
79
+ * Default Security Profile (Recommended)
80
+ */
81
+ export declare const DEFAULT_SECURITY: SecurityConfigOptions;
82
+ /**
83
+ * Environment-based Configuration
84
+ *
85
+ * You can override security settings via environment variables:
86
+ *
87
+ * TACHLES_MAX_PACKAGES=30
88
+ * TACHLES_MAX_COMMANDS=15
89
+ * TACHLES_COMMAND_TIMEOUT=600000
90
+ *
91
+ * Note: This feature is not currently implemented but could be added.
92
+ */
93
+ //# sourceMappingURL=security-config-guide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-config-guide.d.ts","sourceRoot":"","sources":["../../src/utils/security-config-guide.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,0BAA0B,EAAE,MAAM,CAAC;IAEnC;;;;;;OAMG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;;;;;OAMG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;;;;OAKG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,qBAM7B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,qBAMjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,qBAM9B,CAAC;AAEF;;;;;;;;;;GAUG"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Security Configuration Guide
3
+ *
4
+ * This file documents the security configuration options.
5
+ * These are the default values and should not be modified unless you understand the implications.
6
+ *
7
+ * To customize security settings, you would need to fork the project and modify
8
+ * src/utils/security.ts
9
+ */
10
+ /**
11
+ * Example: Strict Security Profile
12
+ *
13
+ * For high-security environments, use these settings:
14
+ */
15
+ export const STRICT_SECURITY = {
16
+ MAX_PACKAGES_PER_OPERATION: 20,
17
+ MAX_COMMANDS_PER_RECIPE: 10,
18
+ COMMAND_TIMEOUT_MS: 10 * 60 * 1000, // 10 minutes
19
+ MAX_PACKAGE_NAME_LENGTH: 214,
20
+ MAX_COMMAND_LENGTH: 500,
21
+ };
22
+ /**
23
+ * Example: Permissive Security Profile
24
+ *
25
+ * For testing/development, you might use:
26
+ * WARNING: Do not use in production!
27
+ */
28
+ export const PERMISSIVE_SECURITY = {
29
+ MAX_PACKAGES_PER_OPERATION: 100,
30
+ MAX_COMMANDS_PER_RECIPE: 50,
31
+ COMMAND_TIMEOUT_MS: 60 * 60 * 1000, // 60 minutes
32
+ MAX_PACKAGE_NAME_LENGTH: 214,
33
+ MAX_COMMAND_LENGTH: 2000,
34
+ };
35
+ /**
36
+ * Default Security Profile (Recommended)
37
+ */
38
+ export const DEFAULT_SECURITY = {
39
+ MAX_PACKAGES_PER_OPERATION: 50,
40
+ MAX_COMMANDS_PER_RECIPE: 20,
41
+ COMMAND_TIMEOUT_MS: 30 * 60 * 1000, // 30 minutes
42
+ MAX_PACKAGE_NAME_LENGTH: 214,
43
+ MAX_COMMAND_LENGTH: 1000,
44
+ };
45
+ /**
46
+ * Environment-based Configuration
47
+ *
48
+ * You can override security settings via environment variables:
49
+ *
50
+ * TACHLES_MAX_PACKAGES=30
51
+ * TACHLES_MAX_COMMANDS=15
52
+ * TACHLES_COMMAND_TIMEOUT=600000
53
+ *
54
+ * Note: This feature is not currently implemented but could be added.
55
+ */
56
+ //# sourceMappingURL=security-config-guide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-config-guide.js","sourceRoot":"","sources":["../../src/utils/security-config-guide.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAA0B;IACpD,0BAA0B,EAAE,EAAE;IAC9B,uBAAuB,EAAE,EAAE;IAC3B,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACjD,uBAAuB,EAAE,GAAG;IAC5B,kBAAkB,EAAE,GAAG;CACxB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA0B;IACxD,0BAA0B,EAAE,GAAG;IAC/B,uBAAuB,EAAE,EAAE;IAC3B,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACjD,uBAAuB,EAAE,GAAG;IAC5B,kBAAkB,EAAE,IAAI;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA0B;IACrD,0BAA0B,EAAE,EAAE;IAC9B,uBAAuB,EAAE,EAAE;IAC3B,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACjD,uBAAuB,EAAE,GAAG;IAC5B,kBAAkB,EAAE,IAAI;CACzB,CAAC;AAEF;;;;;;;;;;GAUG"}
@@ -0,0 +1,83 @@
1
+ import { Package, Command } from '../api/types.js';
2
+ export declare const SECURITY_CONFIG: {
3
+ MAX_PACKAGES_PER_OPERATION: number;
4
+ MAX_COMMANDS_PER_RECIPE: number;
5
+ COMMAND_TIMEOUT_MS: number;
6
+ BLOCKED_PACKAGE_PATTERNS: RegExp[];
7
+ BLOCKED_COMMAND_PATTERNS: RegExp[];
8
+ ALLOWED_PACKAGE_SCOPES: string[];
9
+ MAX_PACKAGE_NAME_LENGTH: number;
10
+ MAX_COMMAND_LENGTH: number;
11
+ };
12
+ export declare class SecurityValidator {
13
+ /**
14
+ * Validate a package name for security concerns
15
+ */
16
+ static validatePackage(pkg: Package): {
17
+ valid: boolean;
18
+ reason?: string;
19
+ };
20
+ /**
21
+ * Validate a command for security concerns
22
+ */
23
+ static validateCommand(cmd: Command): {
24
+ valid: boolean;
25
+ reason?: string;
26
+ };
27
+ /**
28
+ * Validate batch of packages
29
+ */
30
+ static validatePackageBatch(packages: Package[]): {
31
+ valid: boolean;
32
+ errors: string[];
33
+ };
34
+ /**
35
+ * Validate batch of commands
36
+ */
37
+ static validateCommandBatch(commands: Command[]): {
38
+ valid: boolean;
39
+ errors: string[];
40
+ };
41
+ /**
42
+ * Check if a version string is valid
43
+ */
44
+ private static isValidVersion;
45
+ /**
46
+ * Sanitize a command string (escape dangerous characters)
47
+ */
48
+ static sanitizeCommandString(cmd: string): string;
49
+ /**
50
+ * Check if package is from a trusted scope
51
+ */
52
+ static isTrustedScope(packageName: string): boolean;
53
+ /**
54
+ * Log security validation result
55
+ */
56
+ static logValidationError(context: string, errors: string[]): void;
57
+ }
58
+ /**
59
+ * Rate limiter to prevent abuse
60
+ */
61
+ export declare class RateLimiter {
62
+ private requests;
63
+ private readonly windowMs;
64
+ private readonly maxRequests;
65
+ constructor(windowMs?: number, maxRequests?: number);
66
+ /**
67
+ * Check if request is allowed
68
+ */
69
+ isAllowed(key: string): boolean;
70
+ /**
71
+ * Get remaining requests in current window
72
+ */
73
+ getRemaining(key: string): number;
74
+ /**
75
+ * Reset rate limit for a key
76
+ */
77
+ reset(key: string): void;
78
+ /**
79
+ * Clear all rate limits (for testing)
80
+ */
81
+ clear(): void;
82
+ }
83
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAInD,eAAO,MAAM,eAAe;;;;;;;;;CAuD3B,CAAC;AAEF,qBAAa,iBAAiB;IAC5B;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAmCzE;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAkDzE;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG;QAChD,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB;IAwBD;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG;QAChD,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB;IAwBD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAW7B;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAajD;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAOnD;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;CAQnE;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,QAAQ,GAAE,MAAc,EAAE,WAAW,GAAE,MAAW;IAK9D;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAmB/B;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAUjC;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,268 @@
1
+ import chalk from 'chalk';
2
+ // Security configuration
3
+ export const SECURITY_CONFIG = {
4
+ // Maximum number of packages that can be installed in one operation
5
+ MAX_PACKAGES_PER_OPERATION: 50,
6
+ // Maximum number of commands that can be executed
7
+ MAX_COMMANDS_PER_RECIPE: 20,
8
+ // Timeout for individual commands (30 minutes)
9
+ COMMAND_TIMEOUT_MS: 30 * 60 * 1000,
10
+ // Blocked package patterns (malicious or suspicious)
11
+ BLOCKED_PACKAGE_PATTERNS: [
12
+ /^[._]/, // Packages starting with . or _
13
+ /[\s;|&`$(){}[\]<>]/, // Packages with shell metacharacters
14
+ /rm\s+-rf/i, // Dangerous rm commands
15
+ /\/etc\//i, // System directory access
16
+ /\.\.\/\.\.\//, // Directory traversal
17
+ ],
18
+ // Blocked command patterns
19
+ BLOCKED_COMMAND_PATTERNS: [
20
+ /rm\s+-rf\s+[/~]/i, // Dangerous rm commands
21
+ /curl.*\|\s*(bash|sh)/i, // Piping curl to shell
22
+ /wget.*\|\s*(bash|sh)/i, // Piping wget to shell
23
+ /eval\s+/i, // Eval commands
24
+ /exec\s+/i, // Exec commands
25
+ /(nc|netcat).*-e/i, // Netcat reverse shells
26
+ /\/etc\/(passwd|shadow)/i, // System file access
27
+ /sudo\s+/i, // Sudo commands
28
+ /chmod\s+[0-7]*7[0-7]*/i, // Making files executable for all
29
+ />\s*\/dev\/[a-z]+/i, // Writing to devices
30
+ /mkfs\./i, // Formatting filesystems
31
+ /dd\s+if=/i, // Direct disk access
32
+ /:(){ :|:&};:/, // Fork bomb
33
+ ],
34
+ // Allowed package scopes (npm organizations)
35
+ ALLOWED_PACKAGE_SCOPES: [
36
+ '@types',
37
+ '@babel',
38
+ '@testing-library',
39
+ '@prisma',
40
+ '@vercel',
41
+ '@next',
42
+ '@tanstack',
43
+ '@radix-ui',
44
+ '@hookform',
45
+ // Add more trusted scopes as needed
46
+ ],
47
+ // Maximum package name length
48
+ MAX_PACKAGE_NAME_LENGTH: 214,
49
+ // Maximum command length
50
+ MAX_COMMAND_LENGTH: 1000,
51
+ };
52
+ export class SecurityValidator {
53
+ /**
54
+ * Validate a package name for security concerns
55
+ */
56
+ static validatePackage(pkg) {
57
+ // Check package name length
58
+ if (pkg.name.length > SECURITY_CONFIG.MAX_PACKAGE_NAME_LENGTH) {
59
+ return {
60
+ valid: false,
61
+ reason: `Package name too long: ${pkg.name.substring(0, 50)}...`,
62
+ };
63
+ }
64
+ // Check for empty package name
65
+ if (!pkg.name || pkg.name.trim() === '') {
66
+ return { valid: false, reason: 'Empty package name' };
67
+ }
68
+ // Check against blocked patterns
69
+ for (const pattern of SECURITY_CONFIG.BLOCKED_PACKAGE_PATTERNS) {
70
+ if (pattern.test(pkg.name)) {
71
+ return {
72
+ valid: false,
73
+ reason: `Package name contains suspicious pattern: ${pkg.name}`,
74
+ };
75
+ }
76
+ }
77
+ // Validate version format
78
+ if (!this.isValidVersion(pkg.version)) {
79
+ return {
80
+ valid: false,
81
+ reason: `Invalid version format: ${pkg.version}`,
82
+ };
83
+ }
84
+ return { valid: true };
85
+ }
86
+ /**
87
+ * Validate a command for security concerns
88
+ */
89
+ static validateCommand(cmd) {
90
+ const commandString = cmd.customCommand ||
91
+ `${cmd.packageName || ''} ${cmd.commandArgs || ''}`.trim();
92
+ // Check command length
93
+ if (commandString.length > SECURITY_CONFIG.MAX_COMMAND_LENGTH) {
94
+ return {
95
+ valid: false,
96
+ reason: 'Command exceeds maximum length',
97
+ };
98
+ }
99
+ // Check for empty command
100
+ if (!commandString || commandString.trim() === '') {
101
+ return { valid: false, reason: 'Empty command' };
102
+ }
103
+ // Check against blocked patterns
104
+ for (const pattern of SECURITY_CONFIG.BLOCKED_COMMAND_PATTERNS) {
105
+ if (pattern.test(commandString)) {
106
+ return {
107
+ valid: false,
108
+ reason: `Command contains dangerous pattern: ${commandString.substring(0, 100)}`,
109
+ };
110
+ }
111
+ }
112
+ // Validate runner
113
+ const validRunners = ['npx', 'npm', 'yarn', 'pnpm', 'custom'];
114
+ if (cmd.runner && !validRunners.includes(cmd.runner)) {
115
+ return {
116
+ valid: false,
117
+ reason: `Invalid command runner: ${cmd.runner}`,
118
+ };
119
+ }
120
+ // Additional checks for custom commands
121
+ if (cmd.runner === 'custom' && cmd.customCommand) {
122
+ // Prevent command chaining
123
+ if (/[;&|]/.test(cmd.customCommand)) {
124
+ return {
125
+ valid: false,
126
+ reason: 'Custom commands cannot contain command chaining operators (;, &, |)',
127
+ };
128
+ }
129
+ }
130
+ return { valid: true };
131
+ }
132
+ /**
133
+ * Validate batch of packages
134
+ */
135
+ static validatePackageBatch(packages) {
136
+ const errors = [];
137
+ // Check batch size
138
+ if (packages.length > SECURITY_CONFIG.MAX_PACKAGES_PER_OPERATION) {
139
+ errors.push(`Too many packages in one operation (max: ${SECURITY_CONFIG.MAX_PACKAGES_PER_OPERATION})`);
140
+ }
141
+ // Validate each package
142
+ for (const pkg of packages) {
143
+ const result = this.validatePackage(pkg);
144
+ if (!result.valid) {
145
+ errors.push(result.reason);
146
+ }
147
+ }
148
+ return {
149
+ valid: errors.length === 0,
150
+ errors,
151
+ };
152
+ }
153
+ /**
154
+ * Validate batch of commands
155
+ */
156
+ static validateCommandBatch(commands) {
157
+ const errors = [];
158
+ // Check batch size
159
+ if (commands.length > SECURITY_CONFIG.MAX_COMMANDS_PER_RECIPE) {
160
+ errors.push(`Too many commands in recipe (max: ${SECURITY_CONFIG.MAX_COMMANDS_PER_RECIPE})`);
161
+ }
162
+ // Validate each command
163
+ for (const cmd of commands) {
164
+ const result = this.validateCommand(cmd);
165
+ if (!result.valid) {
166
+ errors.push(result.reason);
167
+ }
168
+ }
169
+ return {
170
+ valid: errors.length === 0,
171
+ errors,
172
+ };
173
+ }
174
+ /**
175
+ * Check if a version string is valid
176
+ */
177
+ static isValidVersion(version) {
178
+ if (!version)
179
+ return false;
180
+ // Allow 'latest' or valid semver patterns
181
+ if (version === 'latest' || version === '*')
182
+ return true;
183
+ // Allow version ranges: ^1.0.0, ~1.0.0, >=1.0.0, 1.x, 1.0.0-beta.1, etc.
184
+ const semverPattern = /^([\^~>=<]+)?\d+(\.\d+)?(\.\d+)?(-[\w.]+)?(\+[\w.]+)?$|^\d+\.x$/;
185
+ return semverPattern.test(version);
186
+ }
187
+ /**
188
+ * Sanitize a command string (escape dangerous characters)
189
+ */
190
+ static sanitizeCommandString(cmd) {
191
+ // Remove any null bytes
192
+ let sanitized = cmd.replace(/\0/g, '');
193
+ // Remove newlines and carriage returns
194
+ sanitized = sanitized.replace(/[\r\n]/g, ' ');
195
+ // Trim and normalize whitespace
196
+ sanitized = sanitized.trim().replace(/\s+/g, ' ');
197
+ return sanitized;
198
+ }
199
+ /**
200
+ * Check if package is from a trusted scope
201
+ */
202
+ static isTrustedScope(packageName) {
203
+ if (!packageName.startsWith('@'))
204
+ return false;
205
+ const scope = packageName.split('/')[0];
206
+ return SECURITY_CONFIG.ALLOWED_PACKAGE_SCOPES.includes(scope);
207
+ }
208
+ /**
209
+ * Log security validation result
210
+ */
211
+ static logValidationError(context, errors) {
212
+ console.error(chalk.red(`\n🚨 Security Validation Failed: ${context}\n`));
213
+ errors.forEach((error, index) => {
214
+ console.error(chalk.red(` ${index + 1}. ${error}`));
215
+ });
216
+ console.error(chalk.yellow('\n⚠️ This recipe contains potentially unsafe operations.'));
217
+ console.error(chalk.yellow(' Please review the template source before proceeding.\n'));
218
+ }
219
+ }
220
+ /**
221
+ * Rate limiter to prevent abuse
222
+ */
223
+ export class RateLimiter {
224
+ requests = new Map();
225
+ windowMs;
226
+ maxRequests;
227
+ constructor(windowMs = 60000, maxRequests = 10) {
228
+ this.windowMs = windowMs;
229
+ this.maxRequests = maxRequests;
230
+ }
231
+ /**
232
+ * Check if request is allowed
233
+ */
234
+ isAllowed(key) {
235
+ const now = Date.now();
236
+ const requests = this.requests.get(key) || [];
237
+ // Filter out old requests
238
+ const recentRequests = requests.filter((timestamp) => now - timestamp < this.windowMs);
239
+ if (recentRequests.length >= this.maxRequests) {
240
+ return false;
241
+ }
242
+ recentRequests.push(now);
243
+ this.requests.set(key, recentRequests);
244
+ return true;
245
+ }
246
+ /**
247
+ * Get remaining requests in current window
248
+ */
249
+ getRemaining(key) {
250
+ const now = Date.now();
251
+ const requests = this.requests.get(key) || [];
252
+ const recentRequests = requests.filter((timestamp) => now - timestamp < this.windowMs);
253
+ return Math.max(0, this.maxRequests - recentRequests.length);
254
+ }
255
+ /**
256
+ * Reset rate limit for a key
257
+ */
258
+ reset(key) {
259
+ this.requests.delete(key);
260
+ }
261
+ /**
262
+ * Clear all rate limits (for testing)
263
+ */
264
+ clear() {
265
+ this.requests.clear();
266
+ }
267
+ }
268
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=security.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.test.d.ts","sourceRoot":"","sources":["../../src/utils/security.test.ts"],"names":[],"mappings":""}