@revealui/core 0.2.0 → 0.3.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/README.md +137 -30
- package/dist/api/compression.d.ts.map +1 -1
- package/dist/api/payload-optimization.d.ts.map +1 -1
- package/dist/api/rate-limit.d.ts +30 -29
- package/dist/api/rate-limit.d.ts.map +1 -1
- package/dist/api/rate-limit.js +79 -4
- package/dist/api/response-cache.d.ts.map +1 -1
- package/dist/api/response-cache.js +1 -1
- package/dist/api/rest.d.ts.map +1 -1
- package/dist/api/rest.js +5 -4
- package/dist/auth/access.d.ts.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/cache/query-cache.d.ts +12 -10
- package/dist/cache/query-cache.d.ts.map +1 -1
- package/dist/cache/query-cache.js +38 -42
- package/dist/caching/app-cache.d.ts +5 -0
- package/dist/caching/app-cache.d.ts.map +1 -1
- package/dist/caching/app-cache.js +9 -1
- package/dist/caching/cdn-config.d.ts +2 -2
- package/dist/caching/cdn-config.d.ts.map +1 -1
- package/dist/caching/cdn-config.js +5 -15
- package/dist/caching/edge-cache.d.ts +1 -1
- package/dist/caching/edge-cache.d.ts.map +1 -1
- package/dist/caching/edge-cache.js +44 -11
- package/dist/caching/index.d.ts +6 -0
- package/dist/caching/index.d.ts.map +1 -0
- package/dist/caching/index.js +5 -0
- package/dist/caching/service-worker.d.ts +10 -18
- package/dist/caching/service-worker.d.ts.map +1 -1
- package/dist/caching/service-worker.js +5 -4
- package/dist/client/admin/RichText.d.ts +1 -1
- package/dist/client/admin/RichText.d.ts.map +1 -1
- package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
- package/dist/client/admin/components/AdminDashboard.js +178 -205
- package/dist/client/admin/components/CollectionList.d.ts.map +1 -1
- package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
- package/dist/client/admin/components/DocumentForm.js +130 -6
- package/dist/client/admin/components/GlobalForm.d.ts.map +1 -1
- package/dist/client/admin/context/ServerFunctionContext.d.ts +8 -0
- package/dist/client/admin/context/ServerFunctionContext.d.ts.map +1 -0
- package/dist/client/admin/context/ServerFunctionContext.js +15 -0
- package/dist/client/admin/i18n/en.d.ts.map +1 -1
- package/dist/client/admin/index.d.ts +1 -0
- package/dist/client/admin/index.d.ts.map +1 -1
- package/dist/client/admin/index.js +1 -0
- package/dist/client/admin/layout.d.ts +1 -1
- package/dist/client/admin/layout.d.ts.map +1 -1
- package/dist/client/admin/layout.js +3 -2
- package/dist/client/admin/page.d.ts.map +1 -1
- package/dist/client/admin/utils/apiClient.d.ts.map +1 -1
- package/dist/client/admin/utils/apiClient.js +0 -4
- package/dist/client/admin/utils/auth.d.ts +0 -4
- package/dist/client/admin/utils/auth.d.ts.map +1 -1
- package/dist/client/admin/utils/auth.js +0 -6
- package/dist/client/admin/utils/index.d.ts +0 -1
- package/dist/client/admin/utils/index.d.ts.map +1 -1
- package/dist/client/admin/utils/index.js +0 -1
- package/dist/client/admin/utils/serializeConfig.d.ts.map +1 -1
- package/dist/client/hooks.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +0 -2
- package/dist/client/richtext/RichTextEditor.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageNodeComponent.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageNodeComponent.js +0 -1
- package/dist/client/richtext/components/ImageUploadButton.d.ts +2 -0
- package/dist/client/richtext/components/ImageUploadButton.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageUploadButton.js +30 -15
- package/dist/client/richtext/index.d.ts.map +1 -1
- package/dist/client/richtext/nodes/DecoratorBlockNode.d.ts.map +1 -1
- package/dist/client/richtext/nodes/ImageNode.d.ts.map +1 -1
- package/dist/client/richtext/plugins/CollaborationPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/CursorsOverlayPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/FloatingToolbarPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/ImagePlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/ToolbarPlugin.d.ts.map +1 -1
- package/dist/client/ui/index.d.ts.map +1 -1
- package/dist/client/ui/index.js +1 -1
- package/dist/collections/CollectionOperations.d.ts +7 -7
- package/dist/collections/CollectionOperations.d.ts.map +1 -1
- package/dist/collections/CollectionOperations.js +15 -1
- package/dist/collections/hooks.d.ts.map +1 -1
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/collections/operations/create.d.ts +2 -4
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +9 -7
- package/dist/collections/operations/createMany.d.ts +12 -0
- package/dist/collections/operations/createMany.d.ts.map +1 -0
- package/dist/collections/operations/createMany.js +43 -0
- package/dist/collections/operations/delete.d.ts +1 -1
- package/dist/collections/operations/delete.d.ts.map +1 -1
- package/dist/collections/operations/delete.js +31 -2
- package/dist/collections/operations/deleteMany.d.ts +11 -0
- package/dist/collections/operations/deleteMany.d.ts.map +1 -0
- package/dist/collections/operations/deleteMany.js +50 -0
- package/dist/collections/operations/fieldHooks.d.ts +2 -2
- package/dist/collections/operations/fieldHooks.d.ts.map +1 -1
- package/dist/collections/operations/fieldHooks.js +4 -4
- package/dist/collections/operations/find.d.ts +2 -4
- package/dist/collections/operations/find.d.ts.map +1 -1
- package/dist/collections/operations/find.js +115 -8
- package/dist/collections/operations/findById.d.ts +3 -4
- package/dist/collections/operations/findById.d.ts.map +1 -1
- package/dist/collections/operations/findById.js +53 -1
- package/dist/collections/operations/sqlAdapter.d.ts +23 -0
- package/dist/collections/operations/sqlAdapter.d.ts.map +1 -0
- package/dist/collections/operations/sqlAdapter.js +76 -0
- package/dist/collections/operations/update.d.ts +3 -5
- package/dist/collections/operations/update.d.ts.map +1 -1
- package/dist/collections/operations/update.js +103 -11
- package/dist/collections/operations/updateMany.d.ts +11 -0
- package/dist/collections/operations/updateMany.d.ts.map +1 -0
- package/dist/collections/operations/updateMany.js +52 -0
- package/dist/collections/registry.d.ts +12 -0
- package/dist/collections/registry.d.ts.map +1 -0
- package/dist/collections/registry.js +38 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/utils.d.ts +0 -10
- package/dist/config/utils.d.ts.map +1 -1
- package/dist/config/utils.js +18 -17
- package/dist/database/index.d.ts +3 -0
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +1 -5
- package/dist/database/safe-parse.d.ts +26 -0
- package/dist/database/safe-parse.d.ts.map +1 -0
- package/dist/database/safe-parse.js +42 -0
- package/dist/database/ssl-config.d.ts.map +1 -1
- package/dist/database/type-adapter.d.ts.map +1 -1
- package/dist/database/universal-postgres.d.ts.map +1 -1
- package/dist/database/universal-postgres.js +18 -13
- package/dist/dataloader.d.ts.map +1 -1
- package/dist/dataloader.js +16 -2
- package/dist/error-handling/circuit-breaker.d.ts +1 -1
- package/dist/error-handling/circuit-breaker.d.ts.map +1 -1
- package/dist/error-handling/circuit-breaker.js +11 -3
- package/dist/error-handling/error-boundary.d.ts.map +1 -1
- package/dist/error-handling/error-reporter.d.ts +6 -5
- package/dist/error-handling/error-reporter.d.ts.map +1 -1
- package/dist/error-handling/error-reporter.js +26 -41
- package/dist/error-handling/fallback-components.d.ts.map +1 -1
- package/dist/error-handling/fallback-components.js +1 -1
- package/dist/error-handling/index.d.ts +3 -5
- package/dist/error-handling/index.d.ts.map +1 -1
- package/dist/error-handling/index.js +2 -5
- package/dist/error-handling/retry.d.ts.map +1 -1
- package/dist/error-handling/retry.js +13 -8
- package/dist/factories/builders.d.ts.map +1 -1
- package/dist/factories/index.d.ts.map +1 -1
- package/dist/features.d.ts +5 -5
- package/dist/features.d.ts.map +1 -1
- package/dist/features.js +6 -5
- package/dist/fieldTraversal.d.ts.map +1 -1
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/getDefaultValue.d.ts.map +1 -1
- package/dist/fields/getFieldPaths.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/index.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/promise.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/traverseFields.d.ts.map +1 -1
- package/dist/generated/types/cms.d.ts.map +1 -1
- package/dist/generated/types/cms.js +0 -1
- package/dist/generated/types/index.d.ts +0 -3
- package/dist/generated/types/index.d.ts.map +1 -1
- package/dist/generated/types/index.js +0 -7
- package/dist/generated/types/neon.d.ts.map +1 -1
- package/dist/generated/types/neon.js +4 -2
- package/dist/globals/GlobalOperations.d.ts.map +1 -1
- package/dist/globals/GlobalOperations.js +4 -2
- package/dist/globals/index.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -6
- package/dist/instance/RevealUIInstance.d.ts.map +1 -1
- package/dist/instance/RevealUIInstance.js +50 -69
- package/dist/instance/index.d.ts.map +1 -1
- package/dist/instance/logger.d.ts.map +1 -1
- package/dist/instance/methods/create.d.ts.map +1 -1
- package/dist/instance/methods/create.js +4 -4
- package/dist/instance/methods/delete.d.ts.map +1 -1
- package/dist/instance/methods/delete.js +5 -5
- package/dist/instance/methods/find.d.ts.map +1 -1
- package/dist/instance/methods/find.js +0 -3
- package/dist/instance/methods/findById.d.ts.map +1 -1
- package/dist/instance/methods/findById.js +0 -3
- package/dist/instance/methods/hooks.d.ts.map +1 -1
- package/dist/instance/methods/hooks.js +3 -1
- package/dist/instance/methods/update.d.ts.map +1 -1
- package/dist/instance/methods/update.js +4 -4
- package/dist/jobs/index.d.ts +16 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +14 -0
- package/dist/jobs/queue.d.ts +57 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +134 -0
- package/dist/license-encryption.d.ts +21 -0
- package/dist/license-encryption.d.ts.map +1 -0
- package/dist/license-encryption.js +74 -0
- package/dist/license.d.ts +33 -7
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +119 -16
- package/dist/monitoring/alerts.d.ts.map +1 -1
- package/dist/monitoring/cleanup-manager.d.ts.map +1 -1
- package/dist/monitoring/health-monitor.d.ts.map +1 -1
- package/dist/monitoring/index.d.ts.map +1 -1
- package/dist/monitoring/process-registry.d.ts.map +1 -1
- package/dist/monitoring/query-monitor.d.ts.map +1 -1
- package/dist/monitoring/types.d.ts.map +1 -1
- package/dist/monitoring/zombie-detector.d.ts.map +1 -1
- package/dist/monitoring/zombie-detector.js +5 -0
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/utilities.d.ts.map +1 -1
- package/dist/nextjs/withRevealUI.d.ts.map +1 -1
- package/dist/observability/alerts.d.ts.map +1 -1
- package/dist/observability/alerts.js +1 -2
- package/dist/observability/health-check.d.ts +1 -5
- package/dist/observability/health-check.d.ts.map +1 -1
- package/dist/observability/health-check.js +37 -43
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/logger.d.ts.map +1 -1
- package/dist/observability/logger.js +1 -1
- package/dist/observability/metrics.d.ts.map +1 -1
- package/dist/observability/tracing.d.ts.map +1 -1
- package/dist/observability/tracing.js +0 -1
- package/dist/optimization/asset-optimizer.d.ts +6 -2
- package/dist/optimization/asset-optimizer.d.ts.map +1 -1
- package/dist/optimization/asset-optimizer.js +31 -7
- package/dist/optimization/bundle-analyzer.d.ts +1 -1
- package/dist/optimization/bundle-analyzer.d.ts.map +1 -1
- package/dist/optimization/bundle-analyzer.js +29 -5
- package/dist/optimization/code-splitting.d.ts +0 -23
- package/dist/optimization/code-splitting.d.ts.map +1 -1
- package/dist/optimization/code-splitting.js +0 -29
- package/dist/plugins/form-builder.d.ts.map +1 -1
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/nested-docs.d.ts +4 -0
- package/dist/plugins/nested-docs.d.ts.map +1 -1
- package/dist/plugins/nested-docs.js +50 -5
- package/dist/plugins/redirects.d.ts.map +1 -1
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/queryBuilder.d.ts.map +1 -1
- package/dist/queries/queryBuilder.js +15 -5
- package/dist/relationships/analyzer.d.ts.map +1 -1
- package/dist/relationships/analyzer.js +8 -0
- package/dist/relationships/index.d.ts.map +1 -1
- package/dist/relationships/populate-core.d.ts +57 -0
- package/dist/relationships/populate-core.d.ts.map +1 -0
- package/dist/relationships/populate-core.js +116 -0
- package/dist/relationships/populate-helpers.d.ts +5 -51
- package/dist/relationships/populate-helpers.d.ts.map +1 -1
- package/dist/relationships/populate-helpers.js +4 -109
- package/dist/relationships/population.d.ts +1 -9
- package/dist/relationships/population.d.ts.map +1 -1
- package/dist/relationships/population.js +8 -3
- package/dist/revealui.d.ts.map +1 -1
- package/dist/richtext/exports/client/rcc.d.ts.map +1 -1
- package/dist/richtext/exports/client/rcc.js +1 -1
- package/dist/richtext/exports/server/rsc.d.ts +17 -0
- package/dist/richtext/exports/server/rsc.d.ts.map +1 -1
- package/dist/richtext/exports/server/rsc.js +61 -5
- package/dist/richtext/index.d.ts.map +1 -1
- package/dist/richtext/lexical.d.ts.map +1 -1
- package/dist/security/audit.d.ts +1 -1
- package/dist/security/audit.d.ts.map +1 -1
- package/dist/security/audit.js +4 -2
- package/dist/security/auth.d.ts +29 -160
- package/dist/security/auth.d.ts.map +1 -1
- package/dist/security/auth.js +150 -367
- package/dist/security/authorization.d.ts +7 -31
- package/dist/security/authorization.d.ts.map +1 -1
- package/dist/security/authorization.js +72 -14
- package/dist/security/encryption.d.ts +56 -44
- package/dist/security/encryption.d.ts.map +1 -1
- package/dist/security/encryption.js +128 -100
- package/dist/security/gdpr-storage.d.ts +102 -0
- package/dist/security/gdpr-storage.d.ts.map +1 -0
- package/dist/security/gdpr-storage.js +65 -0
- package/dist/security/gdpr.d.ts +57 -37
- package/dist/security/gdpr.d.ts.map +1 -1
- package/dist/security/gdpr.js +155 -94
- package/dist/security/headers.d.ts +4 -2
- package/dist/security/headers.d.ts.map +1 -1
- package/dist/security/headers.js +35 -17
- package/dist/security/index.d.ts +3 -16
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +3 -16
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/renderPage.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -4
- package/dist/storage/vercel-blob.d.ts.map +1 -1
- package/dist/translations/index.d.ts.map +1 -1
- package/dist/types/access.d.ts.map +1 -1
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/cms.d.ts.map +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/extensions.d.ts.map +1 -1
- package/dist/types/frontend.d.ts.map +1 -1
- package/dist/types/generated.d.ts +0 -2
- package/dist/types/generated.d.ts.map +1 -1
- package/dist/types/generated.js +0 -1
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/interfaces/app.d.ts.map +1 -1
- package/dist/types/jobs.d.ts.map +1 -1
- package/dist/types/legacy.d.ts.map +1 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/dist/types/query.d.ts.map +1 -1
- package/dist/types/request.d.ts.map +1 -1
- package/dist/types/richtext.d.ts.map +1 -1
- package/dist/types/runtime.d.ts +59 -1
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/schema.d.ts.map +1 -1
- package/dist/types/user.d.ts.map +1 -1
- package/dist/utils/access-conversion.d.ts.map +1 -1
- package/dist/utils/api-wrapper.d.ts.map +1 -1
- package/dist/utils/api-wrapper.js +1 -1
- package/dist/utils/block-conversion.d.ts.map +1 -1
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/deep-clone.js +0 -1
- package/dist/utils/error-responses.d.ts.map +1 -1
- package/dist/utils/errors.d.ts +36 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +103 -0
- package/dist/utils/field-conversion.d.ts +1 -1
- package/dist/utils/field-conversion.d.ts.map +1 -1
- package/dist/utils/flattenResult.d.ts.map +1 -1
- package/dist/utils/flattenResult.js +0 -1
- package/dist/utils/getBlockSelect.d.ts.map +1 -1
- package/dist/utils/getSelectMode.d.ts.map +1 -1
- package/dist/utils/isValidID.d.ts.map +1 -1
- package/dist/utils/json-parsing.d.ts.map +1 -1
- package/dist/utils/logger-client.d.ts.map +1 -1
- package/dist/utils/logger-server.d.ts.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/request-context.d.ts.map +1 -1
- package/dist/utils/stripUnselectedFields.d.ts.map +1 -1
- package/dist/utils/type-guards.d.ts.map +1 -1
- package/package.json +39 -16
package/dist/security/gdpr.js
CHANGED
|
@@ -3,13 +3,18 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Data privacy, consent management, data export, and right to be forgotten
|
|
5
5
|
*/
|
|
6
|
+
import { createHash, createHmac } from 'node:crypto';
|
|
6
7
|
import { logger } from '../observability/logger.js';
|
|
8
|
+
import { InMemoryBreachStorage } from './gdpr-storage.js';
|
|
7
9
|
/**
|
|
8
10
|
* Consent management system
|
|
9
11
|
*/
|
|
10
12
|
export class ConsentManager {
|
|
11
|
-
|
|
13
|
+
storage;
|
|
12
14
|
consentVersion = '1.0.0';
|
|
15
|
+
constructor(storage) {
|
|
16
|
+
this.storage = storage;
|
|
17
|
+
}
|
|
13
18
|
/**
|
|
14
19
|
* Grant consent
|
|
15
20
|
*/
|
|
@@ -24,25 +29,25 @@ export class ConsentManager {
|
|
|
24
29
|
source,
|
|
25
30
|
version: this.consentVersion,
|
|
26
31
|
};
|
|
27
|
-
this.
|
|
32
|
+
await this.storage.setConsent(userId, type, consent);
|
|
28
33
|
return consent;
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* Revoke consent
|
|
32
37
|
*/
|
|
33
38
|
async revokeConsent(userId, type) {
|
|
34
|
-
const
|
|
35
|
-
const existing = this.consents.get(key);
|
|
39
|
+
const existing = await this.storage.getConsent(userId, type);
|
|
36
40
|
if (existing) {
|
|
37
41
|
existing.granted = false;
|
|
38
42
|
existing.timestamp = new Date().toISOString();
|
|
43
|
+
await this.storage.setConsent(userId, type, existing);
|
|
39
44
|
}
|
|
40
45
|
}
|
|
41
46
|
/**
|
|
42
47
|
* Check if consent is granted
|
|
43
48
|
*/
|
|
44
|
-
hasConsent(userId, type) {
|
|
45
|
-
const consent = this.
|
|
49
|
+
async hasConsent(userId, type) {
|
|
50
|
+
const consent = await this.storage.getConsent(userId, type);
|
|
46
51
|
if (!consent?.granted) {
|
|
47
52
|
return false;
|
|
48
53
|
}
|
|
@@ -55,8 +60,8 @@ export class ConsentManager {
|
|
|
55
60
|
/**
|
|
56
61
|
* Get all consents for user
|
|
57
62
|
*/
|
|
58
|
-
getUserConsents(userId) {
|
|
59
|
-
return
|
|
63
|
+
async getUserConsents(userId) {
|
|
64
|
+
return this.storage.getConsentsByUser(userId);
|
|
60
65
|
}
|
|
61
66
|
/**
|
|
62
67
|
* Update consent version
|
|
@@ -67,8 +72,8 @@ export class ConsentManager {
|
|
|
67
72
|
/**
|
|
68
73
|
* Check if consent needs renewal
|
|
69
74
|
*/
|
|
70
|
-
needsRenewal(userId, type, maxAge) {
|
|
71
|
-
const consent = this.
|
|
75
|
+
async needsRenewal(userId, type, maxAge) {
|
|
76
|
+
const consent = await this.storage.getConsent(userId, type);
|
|
72
77
|
if (!consent?.granted) {
|
|
73
78
|
return true;
|
|
74
79
|
}
|
|
@@ -78,8 +83,8 @@ export class ConsentManager {
|
|
|
78
83
|
/**
|
|
79
84
|
* Get consent statistics
|
|
80
85
|
*/
|
|
81
|
-
getStatistics() {
|
|
82
|
-
const consents =
|
|
86
|
+
async getStatistics() {
|
|
87
|
+
const consents = await this.storage.getAllConsents();
|
|
83
88
|
const now = new Date();
|
|
84
89
|
const granted = consents.filter((c) => c.granted).length;
|
|
85
90
|
const revoked = consents.filter((c) => !c.granted).length;
|
|
@@ -97,6 +102,19 @@ export class ConsentManager {
|
|
|
97
102
|
};
|
|
98
103
|
}
|
|
99
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Escape a value for safe CSV inclusion.
|
|
107
|
+
* Prevents CSV injection by prefixing formula-triggering characters (=, +, -, @, \t, \r)
|
|
108
|
+
* with a single quote, and escapes embedded quotes/commas per RFC 4180.
|
|
109
|
+
*/
|
|
110
|
+
function escapeCsvField(value) {
|
|
111
|
+
// Prefix formula-triggering characters to prevent CSV injection in spreadsheet apps
|
|
112
|
+
let safe = /^[=+\-@\t\r]/.test(value) ? `'${value}` : value;
|
|
113
|
+
// RFC 4180: escape double quotes by doubling them
|
|
114
|
+
safe = safe.replace(/"/g, '""');
|
|
115
|
+
// Always quote the field to handle commas, newlines, and quotes
|
|
116
|
+
return `"${safe}"`;
|
|
117
|
+
}
|
|
100
118
|
/**
|
|
101
119
|
* Data export system
|
|
102
120
|
*/
|
|
@@ -133,12 +151,12 @@ export class DataExportSystem {
|
|
|
133
151
|
// Profile data
|
|
134
152
|
lines.push('Type,Key,Value');
|
|
135
153
|
Object.entries(exportData.data.profile).forEach(([key, value]) => {
|
|
136
|
-
lines.push(`Profile,${key}
|
|
154
|
+
lines.push(`Profile,${escapeCsvField(key)},${escapeCsvField(String(value))}`);
|
|
137
155
|
});
|
|
138
156
|
// Activities
|
|
139
157
|
exportData.data.activities.forEach((activity, index) => {
|
|
140
158
|
Object.entries(activity).forEach(([key, value]) => {
|
|
141
|
-
lines.push(`Activity ${index + 1},${key}
|
|
159
|
+
lines.push(`Activity ${index + 1},${escapeCsvField(key)},${escapeCsvField(String(value))}`);
|
|
142
160
|
});
|
|
143
161
|
});
|
|
144
162
|
return lines.join('\n');
|
|
@@ -155,7 +173,10 @@ export class DataExportSystem {
|
|
|
155
173
|
* Data deletion system (Right to be Forgotten)
|
|
156
174
|
*/
|
|
157
175
|
export class DataDeletionSystem {
|
|
158
|
-
|
|
176
|
+
storage;
|
|
177
|
+
constructor(storage) {
|
|
178
|
+
this.storage = storage;
|
|
179
|
+
}
|
|
159
180
|
/**
|
|
160
181
|
* Request data deletion
|
|
161
182
|
*/
|
|
@@ -168,41 +189,44 @@ export class DataDeletionSystem {
|
|
|
168
189
|
dataCategories,
|
|
169
190
|
reason,
|
|
170
191
|
};
|
|
171
|
-
this.
|
|
192
|
+
await this.storage.setDeletionRequest(request);
|
|
172
193
|
return request;
|
|
173
194
|
}
|
|
174
195
|
/**
|
|
175
196
|
* Process deletion request
|
|
176
197
|
*/
|
|
177
198
|
async processDeletion(requestId, deleteData) {
|
|
178
|
-
const request = this.
|
|
199
|
+
const request = await this.storage.getDeletionRequest(requestId);
|
|
179
200
|
if (!request) {
|
|
180
201
|
throw new Error('Deletion request not found');
|
|
181
202
|
}
|
|
182
203
|
request.status = 'processing';
|
|
204
|
+
await this.storage.setDeletionRequest(request);
|
|
183
205
|
try {
|
|
184
206
|
const result = await deleteData(request.userId, request.dataCategories);
|
|
185
207
|
request.status = 'completed';
|
|
186
208
|
request.processedAt = new Date().toISOString();
|
|
187
209
|
request.deletedData = result.deleted;
|
|
188
210
|
request.retainedData = result.retained;
|
|
211
|
+
await this.storage.setDeletionRequest(request);
|
|
189
212
|
}
|
|
190
213
|
catch (error) {
|
|
191
214
|
request.status = 'failed';
|
|
215
|
+
await this.storage.setDeletionRequest(request);
|
|
192
216
|
throw error;
|
|
193
217
|
}
|
|
194
218
|
}
|
|
195
219
|
/**
|
|
196
220
|
* Get deletion request
|
|
197
221
|
*/
|
|
198
|
-
getRequest(requestId) {
|
|
199
|
-
return this.
|
|
222
|
+
async getRequest(requestId) {
|
|
223
|
+
return this.storage.getDeletionRequest(requestId);
|
|
200
224
|
}
|
|
201
225
|
/**
|
|
202
226
|
* Get user deletion requests
|
|
203
227
|
*/
|
|
204
|
-
getUserRequests(userId) {
|
|
205
|
-
return
|
|
228
|
+
async getUserRequests(userId) {
|
|
229
|
+
return this.storage.getDeletionRequestsByUser(userId);
|
|
206
230
|
}
|
|
207
231
|
/**
|
|
208
232
|
* Check if data can be deleted
|
|
@@ -231,68 +255,70 @@ export class DataDeletionSystem {
|
|
|
231
255
|
/**
|
|
232
256
|
* Data anonymization utilities
|
|
233
257
|
*/
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
sensitiveFields.forEach((field) => {
|
|
275
|
-
if (field in anonymized && typeof anonymized[field] === 'string') {
|
|
276
|
-
anonymized[field] = DataAnonymization.hashValue(anonymized[field]);
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
return anonymized;
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* K-anonymity check
|
|
284
|
-
*/
|
|
285
|
-
static checkKAnonymity(data, quasiIdentifiers, k) {
|
|
286
|
-
// Group by quasi-identifiers
|
|
287
|
-
const groups = new Map();
|
|
288
|
-
data.forEach((item) => {
|
|
289
|
-
const key = quasiIdentifiers.map((field) => String(item[field])).join('|');
|
|
290
|
-
groups.set(key, (groups.get(key) || 0) + 1);
|
|
258
|
+
/**
|
|
259
|
+
* Hash value (irreversible) using SHA-256
|
|
260
|
+
*/
|
|
261
|
+
function hashValue(value) {
|
|
262
|
+
const digest = createHash('sha256').update(value).digest('hex');
|
|
263
|
+
return `hash_${digest}`;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Anonymize user data
|
|
267
|
+
*/
|
|
268
|
+
function anonymizeUser(user) {
|
|
269
|
+
return {
|
|
270
|
+
...user,
|
|
271
|
+
email: hashValue(user.email),
|
|
272
|
+
name: 'Anonymous User',
|
|
273
|
+
phone: undefined,
|
|
274
|
+
address: undefined,
|
|
275
|
+
ip: undefined,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Pseudonymize data (one-way, key-dependent)
|
|
280
|
+
*
|
|
281
|
+
* Uses HMAC-SHA256 — cryptographically bound to the key, resistant to
|
|
282
|
+
* length-extension attacks and GPU brute-force (unlike plain SHA-256).
|
|
283
|
+
*/
|
|
284
|
+
function pseudonymize(value, key) {
|
|
285
|
+
const hmac = createHmac('sha256', key).update(value).digest('hex');
|
|
286
|
+
return `pseudo_${hmac.substring(0, 16)}`;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Anonymize dataset
|
|
290
|
+
*/
|
|
291
|
+
function anonymizeDataset(data, sensitiveFields) {
|
|
292
|
+
return data.map((item) => {
|
|
293
|
+
const anonymized = { ...item };
|
|
294
|
+
sensitiveFields.forEach((field) => {
|
|
295
|
+
if (field in anonymized && typeof anonymized[field] === 'string') {
|
|
296
|
+
anonymized[field] = hashValue(anonymized[field]);
|
|
297
|
+
}
|
|
291
298
|
});
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
299
|
+
return anonymized;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* K-anonymity check
|
|
304
|
+
*/
|
|
305
|
+
function checkKAnonymity(data, quasiIdentifiers, k) {
|
|
306
|
+
// Group by quasi-identifiers
|
|
307
|
+
const groups = new Map();
|
|
308
|
+
data.forEach((item) => {
|
|
309
|
+
const key = quasiIdentifiers.map((field) => String(item[field])).join('|');
|
|
310
|
+
groups.set(key, (groups.get(key) || 0) + 1);
|
|
311
|
+
});
|
|
312
|
+
// Check if all groups have at least k members
|
|
313
|
+
return Array.from(groups.values()).every((count) => count >= k);
|
|
295
314
|
}
|
|
315
|
+
export const DataAnonymization = {
|
|
316
|
+
anonymizeUser,
|
|
317
|
+
pseudonymize,
|
|
318
|
+
hashValue,
|
|
319
|
+
anonymizeDataset,
|
|
320
|
+
checkKAnonymity,
|
|
321
|
+
};
|
|
296
322
|
/**
|
|
297
323
|
* Privacy policy manager
|
|
298
324
|
*/
|
|
@@ -373,7 +399,17 @@ export class CookieConsentManager {
|
|
|
373
399
|
const stored = localStorage.getItem('cookie-consent');
|
|
374
400
|
if (stored) {
|
|
375
401
|
try {
|
|
376
|
-
|
|
402
|
+
const parsed = JSON.parse(stored);
|
|
403
|
+
// Validate shape before assigning — only accept known boolean fields
|
|
404
|
+
// to prevent malicious scripts from injecting arbitrary config.
|
|
405
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
406
|
+
this.config = {
|
|
407
|
+
necessary: true, // always required
|
|
408
|
+
analytics: typeof parsed.analytics === 'boolean' ? parsed.analytics : false,
|
|
409
|
+
marketing: typeof parsed.marketing === 'boolean' ? parsed.marketing : false,
|
|
410
|
+
functional: typeof parsed.functional === 'boolean' ? parsed.functional : true,
|
|
411
|
+
};
|
|
412
|
+
}
|
|
377
413
|
}
|
|
378
414
|
catch {
|
|
379
415
|
// Ignore parse errors
|
|
@@ -397,7 +433,17 @@ export class CookieConsentManager {
|
|
|
397
433
|
}
|
|
398
434
|
}
|
|
399
435
|
export class DataBreachManager {
|
|
400
|
-
|
|
436
|
+
storage;
|
|
437
|
+
constructor(storage) {
|
|
438
|
+
if (storage) {
|
|
439
|
+
this.storage = storage;
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
logger.warn('DataBreachManager: using in-memory storage — breach records will be lost on restart. ' +
|
|
443
|
+
'For production GDPR compliance, pass a database-backed BreachStorage.');
|
|
444
|
+
this.storage = new InMemoryBreachStorage();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
401
447
|
/**
|
|
402
448
|
* Report data breach
|
|
403
449
|
*/
|
|
@@ -408,7 +454,7 @@ export class DataBreachManager {
|
|
|
408
454
|
detectedAt: new Date().toISOString(),
|
|
409
455
|
status: 'detected',
|
|
410
456
|
};
|
|
411
|
-
this.
|
|
457
|
+
await this.storage.setBreach(fullBreach);
|
|
412
458
|
// Auto-notify if critical
|
|
413
459
|
if (fullBreach.severity === 'critical') {
|
|
414
460
|
await this.notifyAuthorities(fullBreach);
|
|
@@ -419,8 +465,10 @@ export class DataBreachManager {
|
|
|
419
465
|
* Notify authorities (required within 72 hours under GDPR)
|
|
420
466
|
*/
|
|
421
467
|
async notifyAuthorities(breach) {
|
|
422
|
-
breach.
|
|
423
|
-
|
|
468
|
+
await this.storage.updateBreach(breach.id, {
|
|
469
|
+
reportedAt: new Date().toISOString(),
|
|
470
|
+
status: 'notified',
|
|
471
|
+
});
|
|
424
472
|
// In production, integrate with data protection authority API
|
|
425
473
|
logger.info('Breach reported to authorities', { breachId: breach.id });
|
|
426
474
|
}
|
|
@@ -428,7 +476,7 @@ export class DataBreachManager {
|
|
|
428
476
|
* Notify affected users
|
|
429
477
|
*/
|
|
430
478
|
async notifyAffectedUsers(breachId, notifyFn) {
|
|
431
|
-
const breach = this.
|
|
479
|
+
const breach = await this.storage.getBreach(breachId);
|
|
432
480
|
if (!breach) {
|
|
433
481
|
throw new Error('Breach not found');
|
|
434
482
|
}
|
|
@@ -449,22 +497,35 @@ export class DataBreachManager {
|
|
|
449
497
|
/**
|
|
450
498
|
* Get breach
|
|
451
499
|
*/
|
|
452
|
-
getBreach(id) {
|
|
453
|
-
return this.
|
|
500
|
+
async getBreach(id) {
|
|
501
|
+
return this.storage.getBreach(id);
|
|
454
502
|
}
|
|
455
503
|
/**
|
|
456
504
|
* Get all breaches
|
|
457
505
|
*/
|
|
458
|
-
getAllBreaches() {
|
|
459
|
-
return
|
|
506
|
+
async getAllBreaches() {
|
|
507
|
+
return this.storage.getAllBreaches();
|
|
460
508
|
}
|
|
461
509
|
}
|
|
462
510
|
/**
|
|
463
|
-
*
|
|
511
|
+
* Factory functions for GDPR subsystems.
|
|
512
|
+
*
|
|
513
|
+
* `ConsentManager` and `DataDeletionSystem` require a `GDPRStorage` implementation.
|
|
514
|
+
* Use `InMemoryGDPRStorage` only in tests — production MUST use a database-backed store.
|
|
515
|
+
*
|
|
516
|
+
* `DataExportSystem`, `PrivacyPolicyManager`, `CookieConsentManager`, and
|
|
517
|
+
* `DataBreachManager` are stateless or client-side only, so singletons are safe.
|
|
464
518
|
*/
|
|
465
|
-
export
|
|
519
|
+
export function createConsentManager(storage) {
|
|
520
|
+
return new ConsentManager(storage);
|
|
521
|
+
}
|
|
522
|
+
export function createDataDeletionSystem(storage) {
|
|
523
|
+
return new DataDeletionSystem(storage);
|
|
524
|
+
}
|
|
466
525
|
export const dataExportSystem = new DataExportSystem();
|
|
467
|
-
export const dataDeletionSystem = new DataDeletionSystem();
|
|
468
526
|
export const privacyPolicyManager = new PrivacyPolicyManager();
|
|
469
527
|
export const cookieConsentManager = new CookieConsentManager();
|
|
528
|
+
export function createDataBreachManager(storage) {
|
|
529
|
+
return new DataBreachManager(storage);
|
|
530
|
+
}
|
|
470
531
|
export const dataBreachManager = new DataBreachManager();
|
|
@@ -163,11 +163,13 @@ export declare const CORSPresets: {
|
|
|
163
163
|
*/
|
|
164
164
|
moderate: (allowedOrigins: string[]) => CORSConfig;
|
|
165
165
|
/**
|
|
166
|
-
* Permissive CORS (all origins)
|
|
166
|
+
* Permissive CORS (all origins) — development only.
|
|
167
|
+
* Logs a warning if used when NODE_ENV === 'production'.
|
|
167
168
|
*/
|
|
168
169
|
permissive: () => CORSConfig;
|
|
169
170
|
/**
|
|
170
|
-
* API CORS (
|
|
171
|
+
* API CORS (public read-only APIs) — credentials disabled.
|
|
172
|
+
* Logs a warning if used when NODE_ENV === 'production'.
|
|
171
173
|
*/
|
|
172
174
|
api: () => CORSConfig;
|
|
173
175
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/security/headers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/security/headers.ts"],"names":[],"mappings":"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"}
|
package/dist/security/headers.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* HTTP security headers and CORS policy management
|
|
5
5
|
*/
|
|
6
|
+
import { defaultLogger } from '../instance/logger.js';
|
|
6
7
|
/**
|
|
7
8
|
* Security headers manager
|
|
8
9
|
*/
|
|
@@ -192,6 +193,11 @@ export class CORSManager {
|
|
|
192
193
|
if (this.isOriginAllowed(origin)) {
|
|
193
194
|
headers['Access-Control-Allow-Origin'] = this.config.origin === '*' ? '*' : origin;
|
|
194
195
|
}
|
|
196
|
+
// Vary: Origin — required when Access-Control-Allow-Origin is not '*' so caches
|
|
197
|
+
// don't serve a response allowed for origin A to origin B.
|
|
198
|
+
if (this.config.origin !== '*') {
|
|
199
|
+
headers.Vary = 'Origin';
|
|
200
|
+
}
|
|
195
201
|
// Access-Control-Allow-Credentials — incompatible with origin: '*' per Fetch spec
|
|
196
202
|
if (this.config.credentials && this.config.origin !== '*') {
|
|
197
203
|
headers['Access-Control-Allow-Credentials'] = 'true';
|
|
@@ -345,26 +351,38 @@ export const CORSPresets = {
|
|
|
345
351
|
maxAge: 86400,
|
|
346
352
|
}),
|
|
347
353
|
/**
|
|
348
|
-
* Permissive CORS (all origins)
|
|
354
|
+
* Permissive CORS (all origins) — development only.
|
|
355
|
+
* Logs a warning if used when NODE_ENV === 'production'.
|
|
349
356
|
*/
|
|
350
|
-
permissive: () =>
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
+
permissive: () => {
|
|
358
|
+
if (process.env.NODE_ENV === 'production') {
|
|
359
|
+
defaultLogger.warn('[SecurityPresets] CORS permissive preset used in production — this allows all origins. Use moderate() with explicit origins instead.');
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
origin: '*',
|
|
363
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
|
364
|
+
allowedHeaders: ['*'],
|
|
365
|
+
credentials: false,
|
|
366
|
+
maxAge: 86400,
|
|
367
|
+
};
|
|
368
|
+
},
|
|
357
369
|
/**
|
|
358
|
-
* API CORS (
|
|
370
|
+
* API CORS (public read-only APIs) — credentials disabled.
|
|
371
|
+
* Logs a warning if used when NODE_ENV === 'production'.
|
|
359
372
|
*/
|
|
360
|
-
api: () =>
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
373
|
+
api: () => {
|
|
374
|
+
if (process.env.NODE_ENV === 'production') {
|
|
375
|
+
defaultLogger.warn('[SecurityPresets] CORS api preset uses origin:"*". For production, pass explicit origins to moderate() instead.');
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
origin: '*',
|
|
379
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
|
|
380
|
+
allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key'],
|
|
381
|
+
exposedHeaders: ['X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-RateLimit-Reset'],
|
|
382
|
+
credentials: false,
|
|
383
|
+
maxAge: 86400,
|
|
384
|
+
};
|
|
385
|
+
},
|
|
368
386
|
};
|
|
369
387
|
/**
|
|
370
388
|
* Security middleware creator
|
package/dist/security/index.d.ts
CHANGED
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Security & Compliance
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive security infrastructure for authentication, authorization,
|
|
5
|
-
* encryption, audit logging, GDPR compliance, and secure headers
|
|
2
|
+
* Security & Compliance — re-exported from @revealui/security
|
|
3
|
+
* New code should import directly from '@revealui/security'.
|
|
6
4
|
*/
|
|
7
|
-
export
|
|
8
|
-
export { AuditReportGenerator, AuditSystem, AuditTrail, audit, createAuditMiddleware, InMemoryAuditStorage, } from './audit';
|
|
9
|
-
export type { AuthConfig, AuthSession, AuthToken, JWTPayload, OAuthConfig, User, } from './auth';
|
|
10
|
-
export { AuthSystem, OAuthClient, OAuthProviders, PasswordHasher, TwoFactorAuth, } from './auth';
|
|
11
|
-
export type { AuthorizationContext, Permission, Policy, PolicyCondition, Role, } from './authorization';
|
|
12
|
-
export { AuthorizationSystem, authorization, CommonRoles, canAccessResource, checkAttributeAccess, createAuthorizationMiddleware, PermissionBuilder, PermissionCache, PolicyBuilder, permissionCache, RequirePermission, RequireRole, } from './authorization';
|
|
13
|
-
export type { EncryptedData, EncryptionConfig, } from './encryption';
|
|
14
|
-
export { DataMasking, EncryptionSystem, EnvelopeEncryption, encryption, FieldEncryption, KeyRotationManager, TokenGenerator, } from './encryption';
|
|
15
|
-
export type { ConsentRecord, ConsentType, CookieConsentConfig, DataBreach, DataCategory, DataDeletionRequest, DataProcessingPurpose, PersonalDataExport, } from './gdpr';
|
|
16
|
-
export { ConsentManager, CookieConsentManager, consentManager, cookieConsentManager, DataAnonymization, DataBreachManager, DataDeletionSystem, DataExportSystem, dataBreachManager, dataDeletionSystem, dataExportSystem, PrivacyPolicyManager, privacyPolicyManager, } from './gdpr';
|
|
17
|
-
export type { CORSConfig, ContentSecurityPolicyConfig, HSTSConfig, PermissionsPolicyConfig, ReferrerPolicyValue, SecurityHeadersConfig, } from './headers';
|
|
18
|
-
export { CORSManager, CORSPresets, createSecurityMiddleware, SecurityHeaders, SecurityPresets, setRateLimitHeaders, } from './headers';
|
|
5
|
+
export * from '@revealui/security';
|
|
19
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,oBAAoB,CAAC"}
|
package/dist/security/index.js
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Security & Compliance
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive security infrastructure for authentication, authorization,
|
|
5
|
-
* encryption, audit logging, GDPR compliance, and secure headers
|
|
2
|
+
* Security & Compliance — re-exported from @revealui/security
|
|
3
|
+
* New code should import directly from '@revealui/security'.
|
|
6
4
|
*/
|
|
7
|
-
|
|
8
|
-
export { AuditReportGenerator, AuditSystem, AuditTrail, audit, createAuditMiddleware, InMemoryAuditStorage, } from './audit';
|
|
9
|
-
// Authentication
|
|
10
|
-
export { AuthSystem, OAuthClient, OAuthProviders, PasswordHasher, TwoFactorAuth, } from './auth';
|
|
11
|
-
// Authorization
|
|
12
|
-
export { AuthorizationSystem, authorization, CommonRoles, canAccessResource, checkAttributeAccess, createAuthorizationMiddleware, PermissionBuilder, PermissionCache, PolicyBuilder, permissionCache, RequirePermission, RequireRole, } from './authorization';
|
|
13
|
-
// Encryption
|
|
14
|
-
export { DataMasking, EncryptionSystem, EnvelopeEncryption, encryption, FieldEncryption, KeyRotationManager, TokenGenerator, } from './encryption';
|
|
15
|
-
// GDPR compliance
|
|
16
|
-
export { ConsentManager, CookieConsentManager, consentManager, cookieConsentManager, DataAnonymization, DataBreachManager, DataDeletionSystem, DataExportSystem, dataBreachManager, dataDeletionSystem, dataExportSystem, PrivacyPolicyManager, privacyPolicyManager, } from './gdpr';
|
|
17
|
-
// Security headers
|
|
18
|
-
export { CORSManager, CORSPresets, createSecurityMiddleware, SecurityHeaders, SecurityPresets, setRateLimitHeaders, } from './headers';
|
|
5
|
+
export * from '@revealui/security';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAEjE,cAAc,6BAA6B,CAAC;AAQ5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderPage.d.ts","sourceRoot":"","sources":["../../src/server/renderPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"renderPage.d.ts","sourceRoot":"","sources":["../../src/server/renderPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAczE;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,CA6CtE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAqB1E"}
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/storage/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel-blob.d.ts","sourceRoot":"","sources":["../../src/storage/vercel-blob.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"vercel-blob.d.ts","sourceRoot":"","sources":["../../src/storage/vercel-blob.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE;QACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,MAAM,CAqFzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/translations/index.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/translations/index.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;KACnD,CAAC;CACH;AAED,MAAM,WAAW,yBAAyB;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACnD;AAED,MAAM,WAAW,IAAI;IACnB,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;CAC3D;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC"}
|