secure-ui-components 0.1.0-beta.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/LICENSE +21 -0
- package/README.md +310 -0
- package/dist/components/secure-datetime/secure-datetime.css +263 -0
- package/dist/components/secure-datetime/secure-datetime.d.ts +124 -0
- package/dist/components/secure-datetime/secure-datetime.d.ts.map +1 -0
- package/dist/components/secure-datetime/secure-datetime.js +610 -0
- package/dist/components/secure-datetime/secure-datetime.js.map +1 -0
- package/dist/components/secure-file-upload/secure-file-upload.css +334 -0
- package/dist/components/secure-file-upload/secure-file-upload.d.ts +150 -0
- package/dist/components/secure-file-upload/secure-file-upload.d.ts.map +1 -0
- package/dist/components/secure-file-upload/secure-file-upload.js +911 -0
- package/dist/components/secure-file-upload/secure-file-upload.js.map +1 -0
- package/dist/components/secure-form/secure-form.css +62 -0
- package/dist/components/secure-form/secure-form.d.ts +128 -0
- package/dist/components/secure-form/secure-form.d.ts.map +1 -0
- package/dist/components/secure-form/secure-form.js +697 -0
- package/dist/components/secure-form/secure-form.js.map +1 -0
- package/dist/components/secure-input/secure-input.css +168 -0
- package/dist/components/secure-input/secure-input.d.ts +114 -0
- package/dist/components/secure-input/secure-input.d.ts.map +1 -0
- package/dist/components/secure-input/secure-input.js +785 -0
- package/dist/components/secure-input/secure-input.js.map +1 -0
- package/dist/components/secure-select/secure-select.css +195 -0
- package/dist/components/secure-select/secure-select.d.ts +149 -0
- package/dist/components/secure-select/secure-select.d.ts.map +1 -0
- package/dist/components/secure-select/secure-select.js +634 -0
- package/dist/components/secure-select/secure-select.js.map +1 -0
- package/dist/components/secure-submit-button/secure-submit-button.css +135 -0
- package/dist/components/secure-submit-button/secure-submit-button.d.ts +61 -0
- package/dist/components/secure-submit-button/secure-submit-button.d.ts.map +1 -0
- package/dist/components/secure-submit-button/secure-submit-button.js +399 -0
- package/dist/components/secure-submit-button/secure-submit-button.js.map +1 -0
- package/dist/components/secure-table/secure-table.css +341 -0
- package/dist/components/secure-table/secure-table.d.ts +64 -0
- package/dist/components/secure-table/secure-table.d.ts.map +1 -0
- package/dist/components/secure-table/secure-table.js +567 -0
- package/dist/components/secure-table/secure-table.js.map +1 -0
- package/dist/components/secure-textarea/secure-textarea.css +153 -0
- package/dist/components/secure-textarea/secure-textarea.d.ts +111 -0
- package/dist/components/secure-textarea/secure-textarea.d.ts.map +1 -0
- package/dist/components/secure-textarea/secure-textarea.js +477 -0
- package/dist/components/secure-textarea/secure-textarea.js.map +1 -0
- package/dist/core/base-component.d.ts +134 -0
- package/dist/core/base-component.d.ts.map +1 -0
- package/dist/core/base-component.js +303 -0
- package/dist/core/base-component.js.map +1 -0
- package/dist/core/base.css +37 -0
- package/dist/core/security-config.d.ts +89 -0
- package/dist/core/security-config.d.ts.map +1 -0
- package/dist/core/security-config.js +273 -0
- package/dist/core/security-config.js.map +1 -0
- package/dist/core/types.d.ts +212 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +7 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/package.json +89 -0
- package/dist/styles/tokens.css +257 -0
- package/package.json +118 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Base Component Class for Secure-UI
|
|
3
|
+
*
|
|
4
|
+
* This module provides the foundational class that all Secure-UI web components
|
|
5
|
+
* extend. It implements core security features, progressive enhancement,
|
|
6
|
+
* and standardized lifecycle management.
|
|
7
|
+
*
|
|
8
|
+
* Security Features:
|
|
9
|
+
* - Closed Shadow DOM (prevents external JavaScript access)
|
|
10
|
+
* - Automatic XSS sanitization
|
|
11
|
+
* - Security tier enforcement
|
|
12
|
+
* - Audit logging infrastructure
|
|
13
|
+
* - Rate limiting support
|
|
14
|
+
* - Progressive enhancement (works without JS)
|
|
15
|
+
*
|
|
16
|
+
* @module base-component
|
|
17
|
+
* @license MIT
|
|
18
|
+
*/
|
|
19
|
+
import { SecurityTier, getTierConfig, isValidTier, } from './security-config.js';
|
|
20
|
+
/**
|
|
21
|
+
* Base class for all Secure-UI components
|
|
22
|
+
*
|
|
23
|
+
* All components in the Secure-UI library should extend this class to inherit
|
|
24
|
+
* core security functionality and standardized behavior.
|
|
25
|
+
*
|
|
26
|
+
* Security Architecture:
|
|
27
|
+
* - Closed Shadow DOM prevents external tampering
|
|
28
|
+
* - All attributes are sanitized on read
|
|
29
|
+
* - Security tier is immutable after initial set
|
|
30
|
+
* - Default tier is CRITICAL (fail secure)
|
|
31
|
+
*/
|
|
32
|
+
export class SecureBaseComponent extends HTMLElement {
|
|
33
|
+
#securityTier = SecurityTier.CRITICAL;
|
|
34
|
+
#config;
|
|
35
|
+
#shadow;
|
|
36
|
+
#auditLog = [];
|
|
37
|
+
#rateLimitState = {
|
|
38
|
+
attempts: 0,
|
|
39
|
+
windowStart: Date.now()
|
|
40
|
+
};
|
|
41
|
+
#initialized = false;
|
|
42
|
+
/**
|
|
43
|
+
* Constructor
|
|
44
|
+
*
|
|
45
|
+
* Security Note: Creates a CLOSED shadow DOM to prevent external JavaScript
|
|
46
|
+
* from accessing or modifying the component's internal DOM.
|
|
47
|
+
*/
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
this.#shadow = this.attachShadow({ mode: 'closed' });
|
|
51
|
+
this.#config = getTierConfig(this.#securityTier);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Observed attributes - must be overridden by child classes
|
|
55
|
+
*/
|
|
56
|
+
static get observedAttributes() {
|
|
57
|
+
return ['security-tier', 'disabled', 'readonly'];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Called when element is added to DOM
|
|
61
|
+
*/
|
|
62
|
+
connectedCallback() {
|
|
63
|
+
if (!this.#initialized) {
|
|
64
|
+
this.#initialize();
|
|
65
|
+
this.#initialized = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
#initialize() {
|
|
69
|
+
this.initializeSecurity();
|
|
70
|
+
this.#render();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Initialize security tier, config, and audit logging without triggering render.
|
|
74
|
+
*
|
|
75
|
+
* Components that manage their own rendering (e.g. secure-table) can call this
|
|
76
|
+
* from their connectedCallback instead of super.connectedCallback() to get
|
|
77
|
+
* security initialization without the base render lifecycle.
|
|
78
|
+
* @protected
|
|
79
|
+
*/
|
|
80
|
+
initializeSecurity() {
|
|
81
|
+
const tierAttr = this.getAttribute('security-tier');
|
|
82
|
+
if (tierAttr && isValidTier(tierAttr)) {
|
|
83
|
+
this.#securityTier = tierAttr;
|
|
84
|
+
}
|
|
85
|
+
this.#config = getTierConfig(this.#securityTier);
|
|
86
|
+
this.#audit('component_initialized', {
|
|
87
|
+
tier: this.#securityTier,
|
|
88
|
+
timestamp: new Date().toISOString()
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Called when an observed attribute changes
|
|
93
|
+
*
|
|
94
|
+
* Security Note: security-tier attribute is immutable after initialization
|
|
95
|
+
* to prevent privilege escalation.
|
|
96
|
+
*/
|
|
97
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
98
|
+
if (name === 'security-tier' && this.#initialized) {
|
|
99
|
+
console.warn(`Security tier cannot be changed after initialization. ` +
|
|
100
|
+
`Attempted change from "${oldValue}" to "${newValue}" blocked.`);
|
|
101
|
+
if (oldValue !== null) {
|
|
102
|
+
this.setAttribute('security-tier', oldValue);
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (this.#initialized) {
|
|
107
|
+
this.handleAttributeChange(name, oldValue, newValue);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Handle attribute changes - to be overridden by child classes
|
|
112
|
+
*/
|
|
113
|
+
handleAttributeChange(_name, _oldValue, _newValue) {
|
|
114
|
+
// Child classes should override this method
|
|
115
|
+
}
|
|
116
|
+
#render() {
|
|
117
|
+
this.#shadow.innerHTML = '';
|
|
118
|
+
// Base styles via <link> — loads from 'self', fully CSP-safe.
|
|
119
|
+
// Using adoptedStyleSheets + replaceSync(inlineString) triggers CSP violations
|
|
120
|
+
// when style-src lacks 'unsafe-inline'. A <link> element loading from 'self'
|
|
121
|
+
// is always permitted.
|
|
122
|
+
const baseLink = document.createElement('link');
|
|
123
|
+
baseLink.rel = 'stylesheet';
|
|
124
|
+
baseLink.href = new URL('./base.css', import.meta.url).href;
|
|
125
|
+
this.#shadow.appendChild(baseLink);
|
|
126
|
+
const content = this.render();
|
|
127
|
+
if (content) {
|
|
128
|
+
this.#shadow.appendChild(content);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Returns the URL of the shared base stylesheet.
|
|
133
|
+
* Components that manage their own rendering (e.g. secure-table) can use
|
|
134
|
+
* this to inject the base <link> themselves.
|
|
135
|
+
* @protected
|
|
136
|
+
*/
|
|
137
|
+
getBaseStylesheetUrl() {
|
|
138
|
+
return new URL('./base.css', import.meta.url).href;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Inject a component stylesheet into the shadow root via <link>.
|
|
142
|
+
* Accepts a URL (use import.meta.url to derive it, e.g.
|
|
143
|
+
* new URL('./my-component.css', import.meta.url).href
|
|
144
|
+
* ). Loading from 'self' satisfies strict CSP without unsafe-inline.
|
|
145
|
+
* @protected
|
|
146
|
+
*/
|
|
147
|
+
addComponentStyles(cssUrl) {
|
|
148
|
+
const link = document.createElement('link');
|
|
149
|
+
link.rel = 'stylesheet';
|
|
150
|
+
link.href = cssUrl;
|
|
151
|
+
this.#shadow.appendChild(link);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Sanitize a string value to prevent XSS
|
|
155
|
+
*/
|
|
156
|
+
sanitizeValue(value) {
|
|
157
|
+
if (typeof value !== 'string') {
|
|
158
|
+
return '';
|
|
159
|
+
}
|
|
160
|
+
const div = document.createElement('div');
|
|
161
|
+
div.textContent = value;
|
|
162
|
+
return div.innerHTML;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Validate input against tier-specific rules
|
|
166
|
+
*/
|
|
167
|
+
validateInput(value, options = {}) {
|
|
168
|
+
const errors = [];
|
|
169
|
+
const config = this.#config;
|
|
170
|
+
if (config.validation.required && (!value || value.trim().length === 0)) {
|
|
171
|
+
errors.push('This field is required');
|
|
172
|
+
}
|
|
173
|
+
const maxLength = options.maxLength || config.validation.maxLength;
|
|
174
|
+
if (value && value.length > maxLength) {
|
|
175
|
+
errors.push(`Value exceeds maximum length of ${maxLength}`);
|
|
176
|
+
}
|
|
177
|
+
const minLength = options.minLength || 0;
|
|
178
|
+
if (value && value.length < minLength) {
|
|
179
|
+
errors.push(`Value must be at least ${minLength} characters`);
|
|
180
|
+
}
|
|
181
|
+
const pattern = options.pattern || config.validation.pattern;
|
|
182
|
+
if (pattern && value && !pattern.test(value)) {
|
|
183
|
+
errors.push('Value does not match required format');
|
|
184
|
+
}
|
|
185
|
+
if (config.validation.strict && errors.length > 0) {
|
|
186
|
+
this.#audit('validation_failed', {
|
|
187
|
+
errors,
|
|
188
|
+
valueLength: value ? value.length : 0
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
valid: errors.length === 0,
|
|
193
|
+
errors
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check rate limit for this component
|
|
198
|
+
*/
|
|
199
|
+
checkRateLimit() {
|
|
200
|
+
if (!this.#config.rateLimit.enabled) {
|
|
201
|
+
return { allowed: true, retryAfter: 0 };
|
|
202
|
+
}
|
|
203
|
+
const now = Date.now();
|
|
204
|
+
const windowMs = this.#config.rateLimit.windowMs;
|
|
205
|
+
if (now - this.#rateLimitState.windowStart > windowMs) {
|
|
206
|
+
this.#rateLimitState.attempts = 0;
|
|
207
|
+
this.#rateLimitState.windowStart = now;
|
|
208
|
+
}
|
|
209
|
+
if (this.#rateLimitState.attempts >= this.#config.rateLimit.maxAttempts) {
|
|
210
|
+
const retryAfter = windowMs - (now - this.#rateLimitState.windowStart);
|
|
211
|
+
this.#audit('rate_limit_exceeded', {
|
|
212
|
+
attempts: this.#rateLimitState.attempts,
|
|
213
|
+
retryAfter
|
|
214
|
+
});
|
|
215
|
+
return { allowed: false, retryAfter };
|
|
216
|
+
}
|
|
217
|
+
this.#rateLimitState.attempts++;
|
|
218
|
+
return { allowed: true, retryAfter: 0 };
|
|
219
|
+
}
|
|
220
|
+
#audit(event, data = {}) {
|
|
221
|
+
const config = this.#config.audit;
|
|
222
|
+
const shouldLog = (event.includes('access') && config.logAccess) ||
|
|
223
|
+
(event.includes('change') && config.logChanges) ||
|
|
224
|
+
(event.includes('submit') && config.logSubmission) ||
|
|
225
|
+
event.includes('initialized') ||
|
|
226
|
+
event.includes('rate_limit') ||
|
|
227
|
+
event.includes('validation');
|
|
228
|
+
if (!shouldLog) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const logEntry = {
|
|
232
|
+
event,
|
|
233
|
+
tier: this.#securityTier,
|
|
234
|
+
timestamp: new Date().toISOString(),
|
|
235
|
+
...data
|
|
236
|
+
};
|
|
237
|
+
if (config.includeMetadata) {
|
|
238
|
+
logEntry.userAgent = navigator.userAgent;
|
|
239
|
+
logEntry.language = navigator.language;
|
|
240
|
+
}
|
|
241
|
+
this.#auditLog.push(logEntry);
|
|
242
|
+
this.dispatchEvent(new CustomEvent('secure-audit', {
|
|
243
|
+
detail: logEntry,
|
|
244
|
+
bubbles: true,
|
|
245
|
+
composed: true
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get the shadow root (protected access for child classes)
|
|
250
|
+
*/
|
|
251
|
+
get shadowRoot() {
|
|
252
|
+
return this.#shadow;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get the current security tier
|
|
256
|
+
*/
|
|
257
|
+
get securityTier() {
|
|
258
|
+
return this.#securityTier;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get the tier configuration
|
|
262
|
+
*/
|
|
263
|
+
get config() {
|
|
264
|
+
return this.#config;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get all audit log entries
|
|
268
|
+
*/
|
|
269
|
+
getAuditLog() {
|
|
270
|
+
return [...this.#auditLog];
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Clear the local audit log
|
|
274
|
+
*/
|
|
275
|
+
clearAuditLog() {
|
|
276
|
+
this.#auditLog = [];
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Trigger an audit event from child classes
|
|
280
|
+
*/
|
|
281
|
+
audit(event, data) {
|
|
282
|
+
this.#audit(event, data);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Force re-render of the component
|
|
286
|
+
*/
|
|
287
|
+
rerender() {
|
|
288
|
+
this.#render();
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Clean up when component is removed from DOM
|
|
292
|
+
*/
|
|
293
|
+
disconnectedCallback() {
|
|
294
|
+
this.#rateLimitState = { attempts: 0, windowStart: Date.now() };
|
|
295
|
+
if (this.#config.audit.logAccess) {
|
|
296
|
+
this.#audit('component_disconnected', {
|
|
297
|
+
timestamp: new Date().toISOString()
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
export default SecureBaseComponent;
|
|
303
|
+
//# sourceMappingURL=base-component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-component.js","sourceRoot":"","sources":["../../src/core/base-component.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Shadow DOM styles shared by all Secure-UI components.
|
|
3
|
+
* Loaded via <link rel="stylesheet"> to satisfy strict CSP (style-src 'self').
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
:host {
|
|
7
|
+
display: block;
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
10
|
+
font-size: 14px;
|
|
11
|
+
line-height: 1.5;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:host([hidden]) {
|
|
15
|
+
display: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
* {
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.hidden {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.security-badge {
|
|
27
|
+
display: inline-block;
|
|
28
|
+
padding: var(--secure-ui-badge-padding, 2px 6px);
|
|
29
|
+
margin-left: var(--secure-ui-space-2, 0.5rem);
|
|
30
|
+
font-size: var(--secure-ui-badge-font-size, 0.6875rem); /* 11px — below normal text threshold, verify contrast */
|
|
31
|
+
font-weight: var(--secure-ui-font-weight-semibold, 600);
|
|
32
|
+
border-radius: var(--secure-ui-badge-border-radius, 0.25rem);
|
|
33
|
+
text-transform: uppercase;
|
|
34
|
+
background-color: var(--secure-ui-color-bg-tertiary);
|
|
35
|
+
color: var(--secure-ui-color-text-secondary);
|
|
36
|
+
border: var(--secure-ui-border-width-thin, 1px) solid var(--secure-ui-color-border);
|
|
37
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Security Configuration and Tier Definitions
|
|
3
|
+
*
|
|
4
|
+
* This module defines the four security tiers that govern all component behavior
|
|
5
|
+
* in the Secure-UI library. Each tier represents a different level of data sensitivity
|
|
6
|
+
* and applies corresponding security controls.
|
|
7
|
+
*
|
|
8
|
+
* Security Philosophy:
|
|
9
|
+
* - Defense in depth: Multiple layers of protection at each tier
|
|
10
|
+
* - Fail secure: Default to highest security when tier is ambiguous
|
|
11
|
+
* - Progressive enhancement: All tiers work without JavaScript
|
|
12
|
+
* - Zero trust: Always validate, never assume data is safe
|
|
13
|
+
*
|
|
14
|
+
* @module security-config
|
|
15
|
+
* @license MIT
|
|
16
|
+
*/
|
|
17
|
+
import type { SecurityTierValue, TierConfig, CSPDirectives, SecurityHeaders } from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Security tier enumeration
|
|
20
|
+
* These constants should be used throughout the library to reference security levels
|
|
21
|
+
*/
|
|
22
|
+
export declare const SecurityTier: Readonly<{
|
|
23
|
+
/** PUBLIC: Non-sensitive data (e.g., search queries, public comments) */
|
|
24
|
+
PUBLIC: "public";
|
|
25
|
+
/** AUTHENTICATED: User-specific but non-sensitive data (e.g., display names, preferences) */
|
|
26
|
+
AUTHENTICATED: "authenticated";
|
|
27
|
+
/** SENSITIVE: Personally identifiable information (e.g., email, phone, address) */
|
|
28
|
+
SENSITIVE: "sensitive";
|
|
29
|
+
/** CRITICAL: High-risk data (e.g., passwords, SSN, payment info) */
|
|
30
|
+
CRITICAL: "critical";
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Default configuration for each security tier
|
|
34
|
+
*
|
|
35
|
+
* Security Note: These defaults implement defense-in-depth by progressively
|
|
36
|
+
* adding security controls at each tier. When in doubt, components should
|
|
37
|
+
* default to CRITICAL tier behavior.
|
|
38
|
+
*/
|
|
39
|
+
export declare const TIER_CONFIG: Readonly<Record<SecurityTierValue, TierConfig>>;
|
|
40
|
+
/**
|
|
41
|
+
* Get configuration for a specific security tier
|
|
42
|
+
*
|
|
43
|
+
* Security Note: If an invalid tier is provided, this function fails secure
|
|
44
|
+
* by returning the CRITICAL tier configuration.
|
|
45
|
+
*/
|
|
46
|
+
export declare function getTierConfig(tier: string): TierConfig;
|
|
47
|
+
/**
|
|
48
|
+
* Validate that a tier value is valid
|
|
49
|
+
*/
|
|
50
|
+
export declare function isValidTier(tier: string): tier is SecurityTierValue;
|
|
51
|
+
/**
|
|
52
|
+
* Compare two security tiers
|
|
53
|
+
*
|
|
54
|
+
* @returns -1 if tier1 < tier2, 0 if equal, 1 if tier1 > tier2
|
|
55
|
+
*/
|
|
56
|
+
export declare function compareTiers(tier1: string, tier2: string): number;
|
|
57
|
+
/**
|
|
58
|
+
* Get the more secure of two tiers
|
|
59
|
+
*/
|
|
60
|
+
export declare function getMoreSecureTier(tier1: string, tier2: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Content Security Policy recommendations for each tier
|
|
63
|
+
*/
|
|
64
|
+
export declare const CSP_RECOMMENDATIONS: Readonly<Record<SecurityTierValue, Readonly<CSPDirectives>>>;
|
|
65
|
+
/**
|
|
66
|
+
* Default security headers recommendations
|
|
67
|
+
*/
|
|
68
|
+
export declare const SECURITY_HEADERS: Readonly<SecurityHeaders>;
|
|
69
|
+
declare const _default: {
|
|
70
|
+
SecurityTier: Readonly<{
|
|
71
|
+
/** PUBLIC: Non-sensitive data (e.g., search queries, public comments) */
|
|
72
|
+
PUBLIC: "public";
|
|
73
|
+
/** AUTHENTICATED: User-specific but non-sensitive data (e.g., display names, preferences) */
|
|
74
|
+
AUTHENTICATED: "authenticated";
|
|
75
|
+
/** SENSITIVE: Personally identifiable information (e.g., email, phone, address) */
|
|
76
|
+
SENSITIVE: "sensitive";
|
|
77
|
+
/** CRITICAL: High-risk data (e.g., passwords, SSN, payment info) */
|
|
78
|
+
CRITICAL: "critical";
|
|
79
|
+
}>;
|
|
80
|
+
TIER_CONFIG: Readonly<Record<SecurityTierValue, TierConfig>>;
|
|
81
|
+
getTierConfig: typeof getTierConfig;
|
|
82
|
+
isValidTier: typeof isValidTier;
|
|
83
|
+
compareTiers: typeof compareTiers;
|
|
84
|
+
getMoreSecureTier: typeof getMoreSecureTier;
|
|
85
|
+
CSP_RECOMMENDATIONS: Readonly<Record<SecurityTierValue, Readonly<CSPDirectives>>>;
|
|
86
|
+
SECURITY_HEADERS: Readonly<SecurityHeaders>;
|
|
87
|
+
};
|
|
88
|
+
export default _default;
|
|
89
|
+
//# sourceMappingURL=security-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-config.d.ts","sourceRoot":"","sources":["../../src/core/security-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,yEAAyE;;IAGzE,6FAA6F;;IAG7F,mFAAmF;;IAGnF,oEAAoE;;EAEpE,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAoJtE,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAOtD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,iBAAiB,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAiC3F,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAMrD,CAAC;;;QAlQD,yEAAyE;;QAGzE,6FAA6F;;QAG7F,mFAAmF;;QAGnF,oEAAoE;;;;;;;;;;;AA2PtE,wBASE"}
|