@secfn/core 0.0.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.
- package/README.md +334 -0
- package/dist/access-control/rbac.d.ts +48 -0
- package/dist/access-control/rbac.d.ts.map +1 -0
- package/dist/access-control/rbac.js +203 -0
- package/dist/access-control/rbac.js.map +1 -0
- package/dist/core/secfn.d.ts +28 -0
- package/dist/core/secfn.d.ts.map +1 -0
- package/dist/core/secfn.js +73 -0
- package/dist/core/secfn.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/monitoring/security-monitor.d.ts +46 -0
- package/dist/monitoring/security-monitor.d.ts.map +1 -0
- package/dist/monitoring/security-monitor.js +172 -0
- package/dist/monitoring/security-monitor.js.map +1 -0
- package/dist/rate-limiting/rate-limiter.d.ts +31 -0
- package/dist/rate-limiting/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limiting/rate-limiter.js +140 -0
- package/dist/rate-limiting/rate-limiter.js.map +1 -0
- package/dist/scanning/patterns.d.ts +3 -0
- package/dist/scanning/patterns.d.ts.map +1 -0
- package/dist/scanning/patterns.js +139 -0
- package/dist/scanning/patterns.js.map +1 -0
- package/dist/scanning/scanner.d.ts +36 -0
- package/dist/scanning/scanner.d.ts.map +1 -0
- package/dist/scanning/scanner.js +152 -0
- package/dist/scanning/scanner.js.map +1 -0
- package/dist/secrets/encryption.d.ts +17 -0
- package/dist/secrets/encryption.d.ts.map +1 -0
- package/dist/secrets/encryption.js +47 -0
- package/dist/secrets/encryption.js.map +1 -0
- package/dist/secrets/vault.d.ts +43 -0
- package/dist/secrets/vault.d.ts.map +1 -0
- package/dist/secrets/vault.js +126 -0
- package/dist/secrets/vault.js.map +1 -0
- package/dist/storage/indexeddb-storage.d.ts +37 -0
- package/dist/storage/indexeddb-storage.d.ts.map +1 -0
- package/dist/storage/indexeddb-storage.js +284 -0
- package/dist/storage/indexeddb-storage.js.map +1 -0
- package/dist/types/index.d.ts +189 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/helpers.d.ts +8 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +73 -0
- package/dist/utils/helpers.js.map +1 -0
- package/examples/basic-usage.ts +143 -0
- package/package.json +68 -0
- package/src/access-control/rbac.ts +271 -0
- package/src/core/secfn.ts +90 -0
- package/src/index.ts +27 -0
- package/src/monitoring/security-monitor.ts +245 -0
- package/src/rate-limiting/rate-limiter.ts +181 -0
- package/src/scanning/patterns.ts +140 -0
- package/src/scanning/scanner.ts +199 -0
- package/src/secrets/encryption.ts +74 -0
- package/src/secrets/vault.ts +187 -0
- package/src/storage/indexeddb-storage.ts +355 -0
- package/src/types/index.ts +213 -0
- package/src/utils/helpers.ts +84 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export const DEFAULT_PATTERNS = [
|
|
2
|
+
{
|
|
3
|
+
name: 'AWS Access Key',
|
|
4
|
+
pattern: /AKIA[0-9A-Z]{16}/g,
|
|
5
|
+
entropy: 4.5,
|
|
6
|
+
description: 'AWS Access Key ID',
|
|
7
|
+
severity: 'critical',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: 'AWS Secret Key',
|
|
11
|
+
pattern: /aws[_-]?secret[_-]?access[_-]?key[=:\s]+['"]?([a-zA-Z0-9/+=]{40})['"]?/gi,
|
|
12
|
+
entropy: 5.0,
|
|
13
|
+
description: 'AWS Secret Access Key',
|
|
14
|
+
severity: 'critical',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'Generic API Key',
|
|
18
|
+
pattern: /api[_-]?key[_-]?[=:]\s*['"]?([a-zA-Z0-9]{32,})['"]?/gi,
|
|
19
|
+
entropy: 4.0,
|
|
20
|
+
description: 'Generic API key pattern',
|
|
21
|
+
severity: 'high',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Private Key',
|
|
25
|
+
pattern: /-----BEGIN (RSA|OPENSSH|DSA|EC|PGP) PRIVATE KEY-----/g,
|
|
26
|
+
description: 'Private cryptographic key',
|
|
27
|
+
severity: 'critical',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'JWT Token',
|
|
31
|
+
pattern: /eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g,
|
|
32
|
+
description: 'JSON Web Token',
|
|
33
|
+
severity: 'high',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'GitHub Token',
|
|
37
|
+
pattern: /ghp_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}/g,
|
|
38
|
+
entropy: 4.5,
|
|
39
|
+
description: 'GitHub Personal Access Token',
|
|
40
|
+
severity: 'critical',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'Stripe API Key',
|
|
44
|
+
pattern: /sk_live_[a-zA-Z0-9]{24,}|rk_live_[a-zA-Z0-9]{24,}/g,
|
|
45
|
+
entropy: 4.5,
|
|
46
|
+
description: 'Stripe API Key',
|
|
47
|
+
severity: 'critical',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'Google API Key',
|
|
51
|
+
pattern: /AIza[0-9A-Za-z_-]{35}/g,
|
|
52
|
+
entropy: 4.5,
|
|
53
|
+
description: 'Google API Key',
|
|
54
|
+
severity: 'high',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'Slack Token',
|
|
58
|
+
pattern: /xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24,}/g,
|
|
59
|
+
entropy: 4.5,
|
|
60
|
+
description: 'Slack API Token',
|
|
61
|
+
severity: 'high',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'OpenAI API Key',
|
|
65
|
+
pattern: /sk-[a-zA-Z0-9]{48}/g,
|
|
66
|
+
entropy: 4.5,
|
|
67
|
+
description: 'OpenAI API Key',
|
|
68
|
+
severity: 'critical',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'Anthropic API Key',
|
|
72
|
+
pattern: /sk-ant-[a-zA-Z0-9_-]{95,}/g,
|
|
73
|
+
entropy: 4.5,
|
|
74
|
+
description: 'Anthropic API Key',
|
|
75
|
+
severity: 'critical',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'Database Connection String',
|
|
79
|
+
pattern: /(postgres|mysql|mongodb):\/\/[^\s'"<>]+:[^\s'"<>]+@[^\s'"<>]+/gi,
|
|
80
|
+
description: 'Database connection string with credentials',
|
|
81
|
+
severity: 'critical',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'Password in Code',
|
|
85
|
+
pattern: /(password|passwd|pwd)[=:\s]+['"]([^'"]{8,})['"]/gi,
|
|
86
|
+
entropy: 3.5,
|
|
87
|
+
description: 'Hardcoded password',
|
|
88
|
+
severity: 'high',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'Bearer Token',
|
|
92
|
+
pattern: /Bearer\s+[a-zA-Z0-9_\-\.]{20,}/gi,
|
|
93
|
+
entropy: 4.0,
|
|
94
|
+
description: 'Bearer authentication token',
|
|
95
|
+
severity: 'high',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'NPM Token',
|
|
99
|
+
pattern: /npm_[a-zA-Z0-9]{36}/g,
|
|
100
|
+
entropy: 4.5,
|
|
101
|
+
description: 'NPM Access Token',
|
|
102
|
+
severity: 'high',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'Twilio API Key',
|
|
106
|
+
pattern: /SK[a-f0-9]{32}/g,
|
|
107
|
+
entropy: 4.5,
|
|
108
|
+
description: 'Twilio API Key',
|
|
109
|
+
severity: 'high',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'SendGrid API Key',
|
|
113
|
+
pattern: /SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}/g,
|
|
114
|
+
entropy: 4.5,
|
|
115
|
+
description: 'SendGrid API Key',
|
|
116
|
+
severity: 'high',
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'Mailgun API Key',
|
|
120
|
+
pattern: /key-[a-f0-9]{32}/g,
|
|
121
|
+
entropy: 4.0,
|
|
122
|
+
description: 'Mailgun API Key',
|
|
123
|
+
severity: 'high',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: 'Azure Storage Key',
|
|
127
|
+
pattern: /DefaultEndpointsProtocol=https;AccountName=[^;]+;AccountKey=[^;]+/gi,
|
|
128
|
+
description: 'Azure Storage Connection String',
|
|
129
|
+
severity: 'critical',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'Generic Secret',
|
|
133
|
+
pattern: /(secret|token|api[_-]?key|auth[_-]?token)[=:\s]+['"]([a-zA-Z0-9_\-\/.+=]{20,})['"]/gi,
|
|
134
|
+
entropy: 3.5,
|
|
135
|
+
description: 'Generic secret pattern',
|
|
136
|
+
severity: 'medium',
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/scanning/patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SecretPattern, SecretScanResult } from '../types/index.js';
|
|
2
|
+
import type { IndexedDBStorage } from '../storage/indexeddb-storage.js';
|
|
3
|
+
export interface SecretScannerConfig {
|
|
4
|
+
patterns?: SecretPattern[];
|
|
5
|
+
excludePaths?: string[];
|
|
6
|
+
minEntropy?: number;
|
|
7
|
+
maxFileSize?: number;
|
|
8
|
+
storage?: IndexedDBStorage;
|
|
9
|
+
}
|
|
10
|
+
export interface ScanOptions {
|
|
11
|
+
saveResults?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface GitScanOptions {
|
|
14
|
+
branch?: string;
|
|
15
|
+
commits?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class SecretScanner {
|
|
18
|
+
private patterns;
|
|
19
|
+
private excludePaths;
|
|
20
|
+
private minEntropy;
|
|
21
|
+
private maxFileSize;
|
|
22
|
+
private storage?;
|
|
23
|
+
private git;
|
|
24
|
+
constructor(config?: SecretScannerConfig);
|
|
25
|
+
scanDirectory(dir: string, options?: ScanOptions): Promise<SecretScanResult[]>;
|
|
26
|
+
scanFile(filePath: string): Promise<SecretScanResult[]>;
|
|
27
|
+
scanContent(content: string, filePath: string): SecretScanResult[];
|
|
28
|
+
scanGitHistory(options?: GitScanOptions): Promise<SecretScanResult[]>;
|
|
29
|
+
addPattern(pattern: SecretPattern): void;
|
|
30
|
+
removePattern(name: string): void;
|
|
31
|
+
getPatterns(): SecretPattern[];
|
|
32
|
+
private getLineAndColumn;
|
|
33
|
+
private getContext;
|
|
34
|
+
getScanHistory(limit?: number): Promise<SecretScanResult[]>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/scanning/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAIxE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAC,CAAmB;IACnC,OAAO,CAAC,GAAG,CAAY;gBAEX,MAAM,GAAE,mBAAwB;IAStC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA4BlF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgB7D,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE;IA2C5D,cAAc,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAoC/E,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAIxC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIjC,WAAW,IAAI,aAAa,EAAE;IAI9B,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,UAAU;IAMZ,cAAc,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAM/D"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { glob } from 'glob';
|
|
3
|
+
import simpleGit from 'simple-git';
|
|
4
|
+
import { DEFAULT_PATTERNS } from './patterns.js';
|
|
5
|
+
import { generateId, calculateEntropy, redactSecret } from '../utils/helpers.js';
|
|
6
|
+
export class SecretScanner {
|
|
7
|
+
patterns;
|
|
8
|
+
excludePaths;
|
|
9
|
+
minEntropy;
|
|
10
|
+
maxFileSize;
|
|
11
|
+
storage;
|
|
12
|
+
git;
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
this.patterns = config.patterns || DEFAULT_PATTERNS;
|
|
15
|
+
this.excludePaths = config.excludePaths || ['node_modules/**', 'dist/**', 'build/**', '.git/**'];
|
|
16
|
+
this.minEntropy = config.minEntropy || 3.0;
|
|
17
|
+
this.maxFileSize = config.maxFileSize || 1024 * 1024;
|
|
18
|
+
this.storage = config.storage;
|
|
19
|
+
this.git = simpleGit();
|
|
20
|
+
}
|
|
21
|
+
async scanDirectory(dir, options = {}) {
|
|
22
|
+
const files = await glob('**/*', {
|
|
23
|
+
cwd: dir,
|
|
24
|
+
absolute: true,
|
|
25
|
+
nodir: true,
|
|
26
|
+
ignore: this.excludePaths,
|
|
27
|
+
});
|
|
28
|
+
const results = [];
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
try {
|
|
31
|
+
const fileResults = await this.scanFile(file);
|
|
32
|
+
results.push(...fileResults);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error(`[SecFn] Error scanning file ${file}:`, error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (options.saveResults && this.storage) {
|
|
39
|
+
for (const result of results) {
|
|
40
|
+
await this.storage.saveScanResult(result);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return results;
|
|
44
|
+
}
|
|
45
|
+
async scanFile(filePath) {
|
|
46
|
+
try {
|
|
47
|
+
const content = await readFile(filePath, 'utf-8');
|
|
48
|
+
if (content.length > this.maxFileSize) {
|
|
49
|
+
console.warn(`[SecFn] Skipping large file: ${filePath}`);
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
return this.scanContent(content, filePath);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.error(`[SecFn] Error reading file ${filePath}:`, error);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
scanContent(content, filePath) {
|
|
60
|
+
const results = [];
|
|
61
|
+
const lines = content.split('\n');
|
|
62
|
+
for (const pattern of this.patterns) {
|
|
63
|
+
const matches = content.matchAll(pattern.pattern);
|
|
64
|
+
for (const match of matches) {
|
|
65
|
+
if (!match[0] || !match.index)
|
|
66
|
+
continue;
|
|
67
|
+
const matchedSecret = match[1] || match[0];
|
|
68
|
+
const entropy = calculateEntropy(matchedSecret);
|
|
69
|
+
if (pattern.entropy && entropy < Math.min(pattern.entropy, this.minEntropy)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const { line, column } = this.getLineAndColumn(content, match.index);
|
|
73
|
+
const context = this.getContext(lines, line);
|
|
74
|
+
const result = {
|
|
75
|
+
id: generateId('scan'),
|
|
76
|
+
timestamp: Date.now(),
|
|
77
|
+
file: filePath,
|
|
78
|
+
line,
|
|
79
|
+
column,
|
|
80
|
+
pattern: pattern.name,
|
|
81
|
+
match: matchedSecret,
|
|
82
|
+
redactedMatch: redactSecret(matchedSecret),
|
|
83
|
+
severity: pattern.severity,
|
|
84
|
+
entropy,
|
|
85
|
+
context,
|
|
86
|
+
resolved: false,
|
|
87
|
+
falsePositive: false,
|
|
88
|
+
};
|
|
89
|
+
results.push(result);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
async scanGitHistory(options = {}) {
|
|
95
|
+
const branch = options.branch || 'HEAD';
|
|
96
|
+
const commitCount = options.commits || 100;
|
|
97
|
+
const log = await this.git.log([branch, `-n`, `${commitCount}`]);
|
|
98
|
+
const results = [];
|
|
99
|
+
for (const commit of log.all) {
|
|
100
|
+
try {
|
|
101
|
+
const diff = await this.git.show([commit.hash]);
|
|
102
|
+
const commitResults = this.scanContent(diff, `commit:${commit.hash.substring(0, 7)}`);
|
|
103
|
+
for (const result of commitResults) {
|
|
104
|
+
result.metadata = {
|
|
105
|
+
commit: commit.hash,
|
|
106
|
+
author: commit.author_name,
|
|
107
|
+
date: commit.date,
|
|
108
|
+
message: commit.message,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
results.push(...commitResults);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.error(`[SecFn] Error scanning commit ${commit.hash}:`, error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (this.storage) {
|
|
118
|
+
for (const result of results) {
|
|
119
|
+
await this.storage.saveScanResult(result);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return results;
|
|
123
|
+
}
|
|
124
|
+
addPattern(pattern) {
|
|
125
|
+
this.patterns.push(pattern);
|
|
126
|
+
}
|
|
127
|
+
removePattern(name) {
|
|
128
|
+
this.patterns = this.patterns.filter(p => p.name !== name);
|
|
129
|
+
}
|
|
130
|
+
getPatterns() {
|
|
131
|
+
return [...this.patterns];
|
|
132
|
+
}
|
|
133
|
+
getLineAndColumn(content, index) {
|
|
134
|
+
const beforeMatch = content.substring(0, index);
|
|
135
|
+
const lines = beforeMatch.split('\n');
|
|
136
|
+
const line = lines.length;
|
|
137
|
+
const column = lines[lines.length - 1].length + 1;
|
|
138
|
+
return { line, column };
|
|
139
|
+
}
|
|
140
|
+
getContext(lines, lineNumber, contextLines = 2) {
|
|
141
|
+
const start = Math.max(0, lineNumber - contextLines - 1);
|
|
142
|
+
const end = Math.min(lines.length, lineNumber + contextLines);
|
|
143
|
+
return lines.slice(start, end).join('\n');
|
|
144
|
+
}
|
|
145
|
+
async getScanHistory(limit = 100) {
|
|
146
|
+
if (!this.storage) {
|
|
147
|
+
throw new Error('Storage not configured');
|
|
148
|
+
}
|
|
149
|
+
return await this.storage.getScanHistory(limit);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/scanning/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface EncryptedData {
|
|
2
|
+
iv: string;
|
|
3
|
+
encrypted: string;
|
|
4
|
+
authTag: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class SecretEncryption {
|
|
7
|
+
private algorithm;
|
|
8
|
+
private keyLength;
|
|
9
|
+
private ivLength;
|
|
10
|
+
private salt;
|
|
11
|
+
private iterations;
|
|
12
|
+
encrypt(plaintext: string, masterKey: string): Promise<string>;
|
|
13
|
+
decrypt(ciphertext: string, masterKey: string): Promise<string>;
|
|
14
|
+
private deriveKey;
|
|
15
|
+
isEncrypted(value: string): boolean;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/secrets/encryption.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,UAAU,CAAU;IAEtB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkB9D,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBrE,OAAO,CAAC,SAAS;IAUjB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAapC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes } from 'crypto';
|
|
2
|
+
export class SecretEncryption {
|
|
3
|
+
algorithm = 'aes-256-gcm';
|
|
4
|
+
keyLength = 32;
|
|
5
|
+
ivLength = 16;
|
|
6
|
+
salt = 'secfn-salt-v1';
|
|
7
|
+
iterations = 100000;
|
|
8
|
+
async encrypt(plaintext, masterKey) {
|
|
9
|
+
const key = this.deriveKey(masterKey);
|
|
10
|
+
const iv = randomBytes(this.ivLength);
|
|
11
|
+
const cipher = createCipheriv(this.algorithm, key, iv);
|
|
12
|
+
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
|
13
|
+
encrypted += cipher.final('hex');
|
|
14
|
+
const authTag = cipher.getAuthTag();
|
|
15
|
+
const data = {
|
|
16
|
+
iv: iv.toString('hex'),
|
|
17
|
+
encrypted,
|
|
18
|
+
authTag: authTag.toString('hex'),
|
|
19
|
+
};
|
|
20
|
+
return JSON.stringify(data);
|
|
21
|
+
}
|
|
22
|
+
async decrypt(ciphertext, masterKey) {
|
|
23
|
+
const key = this.deriveKey(masterKey);
|
|
24
|
+
const data = JSON.parse(ciphertext);
|
|
25
|
+
const decipher = createDecipheriv(this.algorithm, key, Buffer.from(data.iv, 'hex'));
|
|
26
|
+
decipher.setAuthTag(Buffer.from(data.authTag, 'hex'));
|
|
27
|
+
let decrypted = decipher.update(data.encrypted, 'hex', 'utf8');
|
|
28
|
+
decrypted += decipher.final('utf8');
|
|
29
|
+
return decrypted;
|
|
30
|
+
}
|
|
31
|
+
deriveKey(masterKey) {
|
|
32
|
+
return pbkdf2Sync(masterKey, this.salt, this.iterations, this.keyLength, 'sha256');
|
|
33
|
+
}
|
|
34
|
+
isEncrypted(value) {
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(value);
|
|
37
|
+
return (typeof parsed === 'object' &&
|
|
38
|
+
'iv' in parsed &&
|
|
39
|
+
'encrypted' in parsed &&
|
|
40
|
+
'authTag' in parsed);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/secrets/encryption.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAQnF,MAAM,OAAO,gBAAgB;IACnB,SAAS,GAAG,aAAa,CAAC;IAC1B,SAAS,GAAG,EAAE,CAAC;IACf,QAAQ,GAAG,EAAE,CAAC;IACd,IAAI,GAAG,eAAe,CAAC;IACvB,UAAU,GAAG,MAAM,CAAC;IAE5B,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,SAAiB;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAQ,CAAC;QAE9D,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACxD,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAEpC,MAAM,IAAI,GAAkB;YAC1B,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YACtB,SAAS;YACT,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;SACjC,CAAC;QAEF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAAkB,EAAE,SAAiB;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,IAAI,GAAkB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAEnD,MAAM,QAAQ,GAAG,gBAAgB,CAC/B,IAAI,CAAC,SAAS,EACd,GAAG,EACH,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CACrB,CAAC;QACT,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QAEtD,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/D,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEpC,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,SAAS,CAAC,SAAiB;QACjC,OAAO,UAAU,CACf,SAAS,EACT,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EACd,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,KAAa;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,IAAI,IAAI,MAAM;gBACd,WAAW,IAAI,MAAM;gBACrB,SAAS,IAAI,MAAM,CACpB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Secret, SecretAccess, Environment } from '../types/index.js';
|
|
2
|
+
import type { IndexedDBStorage } from '../storage/indexeddb-storage.js';
|
|
3
|
+
export interface SecretsVaultConfig {
|
|
4
|
+
storage: IndexedDBStorage;
|
|
5
|
+
encryption: {
|
|
6
|
+
algorithm: 'AES-256-GCM';
|
|
7
|
+
masterKey: string;
|
|
8
|
+
keyDerivation?: 'PBKDF2' | 'scrypt';
|
|
9
|
+
};
|
|
10
|
+
rotation?: {
|
|
11
|
+
checkInterval: number;
|
|
12
|
+
notifyBefore: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface SetSecretOptions {
|
|
16
|
+
tags?: string[];
|
|
17
|
+
environment?: Environment;
|
|
18
|
+
expiresAt?: number;
|
|
19
|
+
rotateEvery?: number;
|
|
20
|
+
createdBy?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class SecretsVault {
|
|
23
|
+
private storage;
|
|
24
|
+
private encryption;
|
|
25
|
+
private masterKey;
|
|
26
|
+
private rotationInterval?;
|
|
27
|
+
constructor(config: SecretsVaultConfig);
|
|
28
|
+
set(key: string, value: string, options?: SetSecretOptions): Promise<string>;
|
|
29
|
+
get(key: string, userId?: string): Promise<string | null>;
|
|
30
|
+
list(filter?: {
|
|
31
|
+
environment?: Environment;
|
|
32
|
+
tags?: string[];
|
|
33
|
+
}): Promise<Array<Omit<Secret, 'value'>>>;
|
|
34
|
+
rotate(key: string, newValue: string, userId?: string): Promise<void>;
|
|
35
|
+
delete(key: string, userId?: string): Promise<void>;
|
|
36
|
+
getAccessLog(key: string, limit?: number): Promise<SecretAccess[]>;
|
|
37
|
+
getSecretsNeedingRotation(beforeMs?: number): Promise<Secret[]>;
|
|
38
|
+
getExpiredSecrets(): Promise<Secret[]>;
|
|
39
|
+
private logAccess;
|
|
40
|
+
private startRotationCheck;
|
|
41
|
+
stop(): void;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=vault.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/secrets/vault.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAIxE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE;QACV,SAAS,EAAE,aAAa,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;KACrC,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAAC,CAAiB;gBAE9B,MAAM,EAAE,kBAAkB;IAUhC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IA+BhF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAoB3D,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,WAAW,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAMpG,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBvE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAYrD,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAU/D,yBAAyB,CAAC,QAAQ,GAAE,MAAgC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAaxF,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAK9B,SAAS;IAYvB,OAAO,CAAC,kBAAkB;IAW1B,IAAI,IAAI,IAAI;CAKb"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { SecretEncryption } from './encryption.js';
|
|
2
|
+
import { generateId, isExpired } from '../utils/helpers.js';
|
|
3
|
+
export class SecretsVault {
|
|
4
|
+
storage;
|
|
5
|
+
encryption;
|
|
6
|
+
masterKey;
|
|
7
|
+
rotationInterval;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.storage = config.storage;
|
|
10
|
+
this.encryption = new SecretEncryption();
|
|
11
|
+
this.masterKey = config.encryption.masterKey;
|
|
12
|
+
if (config.rotation) {
|
|
13
|
+
this.startRotationCheck(config.rotation.checkInterval, config.rotation.notifyBefore);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async set(key, value, options = {}) {
|
|
17
|
+
const existing = await this.storage.getSecretByKey(key);
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
const encryptedValue = await this.encryption.encrypt(value, this.masterKey);
|
|
20
|
+
const secret = {
|
|
21
|
+
id: existing?.id || generateId('secret'),
|
|
22
|
+
key,
|
|
23
|
+
value: encryptedValue,
|
|
24
|
+
encrypted: true,
|
|
25
|
+
version: existing ? existing.version + 1 : 1,
|
|
26
|
+
tags: options.tags || [],
|
|
27
|
+
environment: options.environment,
|
|
28
|
+
expiresAt: options.expiresAt,
|
|
29
|
+
rotateEvery: options.rotateEvery,
|
|
30
|
+
lastRotated: now,
|
|
31
|
+
lastAccessed: undefined,
|
|
32
|
+
accessCount: 0,
|
|
33
|
+
createdBy: options.createdBy || 'system',
|
|
34
|
+
createdAt: existing?.createdAt || now,
|
|
35
|
+
updatedAt: now,
|
|
36
|
+
};
|
|
37
|
+
await this.storage.saveSecret(secret);
|
|
38
|
+
await this.logAccess(secret.id, options.createdBy || 'system', 'write');
|
|
39
|
+
return secret.id;
|
|
40
|
+
}
|
|
41
|
+
async get(key, userId = 'system') {
|
|
42
|
+
const secret = await this.storage.getSecretByKey(key);
|
|
43
|
+
if (!secret)
|
|
44
|
+
return null;
|
|
45
|
+
if (isExpired(secret.expiresAt)) {
|
|
46
|
+
throw new Error(`Secret '${key}' has expired`);
|
|
47
|
+
}
|
|
48
|
+
const decryptedValue = await this.encryption.decrypt(secret.value, this.masterKey);
|
|
49
|
+
secret.lastAccessed = Date.now();
|
|
50
|
+
secret.accessCount += 1;
|
|
51
|
+
await this.storage.saveSecret(secret);
|
|
52
|
+
await this.logAccess(secret.id, userId, 'read');
|
|
53
|
+
return decryptedValue;
|
|
54
|
+
}
|
|
55
|
+
async list(filter) {
|
|
56
|
+
const secrets = await this.storage.listSecrets(filter);
|
|
57
|
+
return secrets.map(({ value, ...rest }) => rest);
|
|
58
|
+
}
|
|
59
|
+
async rotate(key, newValue, userId = 'system') {
|
|
60
|
+
const secret = await this.storage.getSecretByKey(key);
|
|
61
|
+
if (!secret) {
|
|
62
|
+
throw new Error(`Secret '${key}' not found`);
|
|
63
|
+
}
|
|
64
|
+
const encryptedValue = await this.encryption.encrypt(newValue, this.masterKey);
|
|
65
|
+
secret.value = encryptedValue;
|
|
66
|
+
secret.version += 1;
|
|
67
|
+
secret.lastRotated = Date.now();
|
|
68
|
+
secret.updatedAt = Date.now();
|
|
69
|
+
await this.storage.saveSecret(secret);
|
|
70
|
+
await this.logAccess(secret.id, userId, 'rotate');
|
|
71
|
+
}
|
|
72
|
+
async delete(key, userId = 'system') {
|
|
73
|
+
const secret = await this.storage.getSecretByKey(key);
|
|
74
|
+
if (!secret) {
|
|
75
|
+
throw new Error(`Secret '${key}' not found`);
|
|
76
|
+
}
|
|
77
|
+
await this.storage.deleteSecret(secret.id);
|
|
78
|
+
await this.logAccess(secret.id, userId, 'delete');
|
|
79
|
+
}
|
|
80
|
+
async getAccessLog(key, limit = 100) {
|
|
81
|
+
const secret = await this.storage.getSecretByKey(key);
|
|
82
|
+
if (!secret) {
|
|
83
|
+
throw new Error(`Secret '${key}' not found`);
|
|
84
|
+
}
|
|
85
|
+
return await this.storage.getSecretAccessLog(secret.id, limit);
|
|
86
|
+
}
|
|
87
|
+
async getSecretsNeedingRotation(beforeMs = 7 * 24 * 60 * 60 * 1000) {
|
|
88
|
+
const allSecrets = await this.storage.listSecrets();
|
|
89
|
+
const now = Date.now();
|
|
90
|
+
const threshold = now + beforeMs;
|
|
91
|
+
return allSecrets.filter(secret => {
|
|
92
|
+
if (!secret.rotateEvery || !secret.lastRotated)
|
|
93
|
+
return false;
|
|
94
|
+
const nextRotation = secret.lastRotated + secret.rotateEvery;
|
|
95
|
+
return nextRotation <= threshold;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async getExpiredSecrets() {
|
|
99
|
+
const allSecrets = await this.storage.listSecrets();
|
|
100
|
+
return allSecrets.filter(secret => isExpired(secret.expiresAt));
|
|
101
|
+
}
|
|
102
|
+
async logAccess(secretId, userId, action) {
|
|
103
|
+
const accessLog = {
|
|
104
|
+
id: generateId('access'),
|
|
105
|
+
secretId,
|
|
106
|
+
userId,
|
|
107
|
+
action,
|
|
108
|
+
timestamp: Date.now(),
|
|
109
|
+
};
|
|
110
|
+
await this.storage.logSecretAccess(accessLog);
|
|
111
|
+
}
|
|
112
|
+
startRotationCheck(interval, notifyBefore) {
|
|
113
|
+
this.rotationInterval = setInterval(async () => {
|
|
114
|
+
const needsRotation = await this.getSecretsNeedingRotation(notifyBefore);
|
|
115
|
+
if (needsRotation.length > 0) {
|
|
116
|
+
console.warn(`[SecFn] ${needsRotation.length} secret(s) need rotation:`, needsRotation.map(s => s.key));
|
|
117
|
+
}
|
|
118
|
+
}, interval);
|
|
119
|
+
}
|
|
120
|
+
stop() {
|
|
121
|
+
if (this.rotationInterval) {
|
|
122
|
+
clearInterval(this.rotationInterval);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/secrets/vault.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Secret, SecretAccess, Role, UserRole, SecurityEvent, RateLimitEntry, SecretScanResult, EventQuery, SecurityMetrics, TimeRange } from '../types/index.js';
|
|
2
|
+
export declare class IndexedDBStorage {
|
|
3
|
+
private db;
|
|
4
|
+
private dbName;
|
|
5
|
+
constructor(dbName?: string);
|
|
6
|
+
initialize(): Promise<void>;
|
|
7
|
+
private getStore;
|
|
8
|
+
saveSecret(secret: Secret): Promise<void>;
|
|
9
|
+
getSecret(id: string): Promise<Secret | null>;
|
|
10
|
+
getSecretByKey(key: string): Promise<Secret | null>;
|
|
11
|
+
listSecrets(filter?: {
|
|
12
|
+
environment?: string;
|
|
13
|
+
tags?: string[];
|
|
14
|
+
}): Promise<Secret[]>;
|
|
15
|
+
deleteSecret(id: string): Promise<void>;
|
|
16
|
+
logSecretAccess(access: SecretAccess): Promise<void>;
|
|
17
|
+
getSecretAccessLog(secretId: string, limit?: number): Promise<SecretAccess[]>;
|
|
18
|
+
saveRole(role: Role): Promise<void>;
|
|
19
|
+
getRole(id: string): Promise<Role | null>;
|
|
20
|
+
listRoles(): Promise<Role[]>;
|
|
21
|
+
deleteRole(id: string): Promise<void>;
|
|
22
|
+
assignUserRole(userRole: UserRole): Promise<void>;
|
|
23
|
+
getUserRoles(userId: string): Promise<UserRole[]>;
|
|
24
|
+
removeUserRole(userId: string, roleId: string): Promise<void>;
|
|
25
|
+
logSecurityEvent(event: SecurityEvent): Promise<void>;
|
|
26
|
+
queryEvents(query: EventQuery): Promise<SecurityEvent[]>;
|
|
27
|
+
getMetrics(range: TimeRange): Promise<SecurityMetrics>;
|
|
28
|
+
getRateLimitEntry(key: string): Promise<RateLimitEntry | null>;
|
|
29
|
+
setRateLimitEntry(entry: RateLimitEntry): Promise<void>;
|
|
30
|
+
deleteRateLimitEntry(key: string): Promise<void>;
|
|
31
|
+
saveScanResult(result: SecretScanResult): Promise<void>;
|
|
32
|
+
getScanHistory(limit?: number): Promise<SecretScanResult[]>;
|
|
33
|
+
cleanup(retentionMs: number): Promise<void>;
|
|
34
|
+
destroy(): Promise<void>;
|
|
35
|
+
private promisifyRequest;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=indexeddb-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexeddb-storage.d.ts","sourceRoot":"","sources":["../../src/storage/indexeddb-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,SAAS,EACV,MAAM,mBAAmB,CAAC;AAe3B,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAA4B;IACtC,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,SAAU;IAItB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmEjC,OAAO,CAAC,QAAQ;IAMV,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAM7C,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOnD,WAAW,CAAC,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBlF,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvC,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAO1E,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAMzC,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAK5B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrC,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAMjD,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7D,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrD,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IA+CxD,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC;IAwCtD,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAM9D,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvD,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhD,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvD,cAAc,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAMxD,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB3C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9B,OAAO,CAAC,gBAAgB;CAMzB"}
|