@nice2dev/ui-security 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,56 @@
1
+ # @nice2dev/ui-security — Changelog
2
+
3
+ ## [0.1.0] — 2025-06-01
4
+
5
+ Initial alpha release — 15 source files.
6
+
7
+ - Security components and utilities
8
+ - **Note**: Zero test coverage — tests needed
9
+
10
+ All notable changes to `@nice2dev/ui-security` will be documented in this file.
11
+
12
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
13
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
14
+
15
+ ---
16
+
17
+ ## [0.1.0] — 2026-06-16
18
+
19
+ ### 🔒 Initial Release
20
+
21
+ First release of `@nice2dev/ui-security` — frontend-first biometric and security components for React.
22
+
23
+ ### Biometric Components
24
+
25
+ - **NiceFingerprintScanner** — camera-based fingerprint scanning with crossing-number minutiae extraction, enroll/verify modes, quality indicator, minutiae overlay
26
+ - **NiceIrisScanner** — Daugman's algorithm for iris segmentation, 256-bit Gabor-like iris codes, Hamming distance matching with rotation compensation, liveness detection
27
+ - **NiceFaceRecognition** — camera face detection with skin-color YCbCr segmentation, 128-dimensional embeddings, cosine similarity matching, photo comparison mode, liveness challenges (blink, smile, head turn)
28
+
29
+ ### Authentication Components
30
+
31
+ - **NicePinKeypad** — numeric PIN entry with configurable length (4–8), scramble mode, lockout after max attempts, SHA-256 hash verification, biometric fallback
32
+ - **NicePatternLock** — Android-style pattern lock with configurable grid (3×3 to 6×6), trail visualization, error animations, touch & mouse support
33
+ - **NicePassphraseInput** — secure passphrase entry with real-time strength meter, show/hide toggle, confirmation mode, copy protection
34
+ - **NiceWebAuthnButton** — FIDO2/Passkey registration and authentication, automatic platform/cross-platform detection, passkey availability check
35
+
36
+ ### Security Management Components
37
+
38
+ - **NiceSecurityAuditLog** — security event log viewer with method/status filters, risk-score colour coding, pagination, JSON export
39
+ - **NiceSessionManager** — active session viewer with device info, trust badges, session revocation
40
+ - **NiceMfaSelector** — multi-factor authentication method picker with grid/list layout, verified state tracking, required-count enforcement
41
+ - **NiceDeviceTrust** — client-side device fingerprinting with trust-score gauge, factor breakdown (GPU, secure context, credential API, etc.)
42
+
43
+ ### Core
44
+
45
+ - **BiometricEngine** — pure-frontend biometric processing engine (~500 lines): fingerprint minutiae extraction, iris code generation, face embedding, liveness detection, device fingerprinting, WebAuthn wrappers, optional backend verification
46
+ - **Type system** — comprehensive TypeScript types: SecurityVerificationStatus, BiometricMethod, BiometricTemplate, FingerprintFeatures, IrisFeatures, FaceFeatures, KeypadConfig, PatternLockConfig, WebAuthnConfig, SecurityAuditEntry, DeviceTrustScore
47
+ - **i18n** — NiceI18nProvider/useNiceTranslation pattern with fallback to English defaults
48
+ - **Theme** — full CSS custom properties system with light/dark mode support (--security-* variables)
49
+
50
+ ### Architecture
51
+
52
+ - All components work **fully frontend** — no backend required
53
+ - Optional backend verification endpoint via `verifyEndpoint` config
54
+ - SHA-256 hash comparison for PIN/pattern/passphrase (never sends plaintext)
55
+ - Camera access via getUserMedia with graceful fallback
56
+ - Zero external dependencies (peer: React ≥ 17)
package/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # @nice2dev/ui-security
2
+
3
+ > Security components for NiceToDev UI — RBAC, audit, token inspection.
4
+
5
+ > **Alpha** — this package is in early development. API may change.
6
+
7
+ ## Features
8
+
9
+ - RBAC (Role-Based Access Control) integration
10
+ - Audit log components
11
+ - Token inspection utilities
12
+ - Designed to work with `@nice2dev/auth` and `@nice2dev/erp-adapter`
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @nice2dev/ui-security
18
+ ```
19
+
20
+ ## Status
21
+
22
+ Early alpha — zero test coverage. Use in production at your own risk.
23
+
24
+ ## License
25
+
26
+ MIT © NiceToDev
@@ -0,0 +1,201 @@
1
+ /**
2
+ * @file Nice2Dev Compliance Utilities
3
+ * @description GDPR, HIPAA, SOC 2, WCAG compliance helpers
4
+ * @packageDocumentation
5
+ */
6
+ export interface GDPRConfig {
7
+ /** Data controller info */
8
+ dataController: {
9
+ name: string;
10
+ email: string;
11
+ address?: string;
12
+ };
13
+ /** Data protection officer */
14
+ dpo?: {
15
+ name: string;
16
+ email: string;
17
+ };
18
+ /** Cookie consent categories */
19
+ cookieCategories: CookieCategory[];
20
+ /** Privacy policy URL */
21
+ privacyPolicyUrl: string;
22
+ /** Cookie policy URL */
23
+ cookiePolicyUrl?: string;
24
+ }
25
+ export interface CookieCategory {
26
+ key: string;
27
+ name: string;
28
+ description: string;
29
+ required: boolean;
30
+ cookies: CookieInfo[];
31
+ }
32
+ export interface CookieInfo {
33
+ name: string;
34
+ purpose: string;
35
+ expiry: string;
36
+ provider: string;
37
+ }
38
+ export interface ConsentPreferences {
39
+ necessary: boolean;
40
+ functional?: boolean;
41
+ analytics?: boolean;
42
+ marketing?: boolean;
43
+ [key: string]: boolean | undefined;
44
+ }
45
+ /**
46
+ * Get stored consent preferences
47
+ */
48
+ export declare function getConsentPreferences(): ConsentPreferences | null;
49
+ /**
50
+ * Save consent preferences
51
+ */
52
+ export declare function saveConsentPreferences(preferences: ConsentPreferences): void;
53
+ /**
54
+ * Check if consent was given for a category
55
+ */
56
+ export declare function hasConsent(category: string): boolean;
57
+ /**
58
+ * Clear all non-essential cookies
59
+ */
60
+ export declare function clearNonEssentialCookies(essentialCookies: string[]): void;
61
+ /**
62
+ * Generate GDPR data export
63
+ */
64
+ export declare function generateDataExport(userId: string, endpoints: {
65
+ profile: string;
66
+ activity: string;
67
+ preferences: string;
68
+ [key: string]: string;
69
+ }, fetchFn?: typeof fetch): Promise<Record<string, unknown>>;
70
+ /**
71
+ * Request data deletion
72
+ */
73
+ export declare function requestDataDeletion(userId: string, endpoint: string, fetchFn?: typeof fetch): Promise<{
74
+ success: boolean;
75
+ confirmationId?: string;
76
+ error?: string;
77
+ }>;
78
+ export interface HIPAAConfig {
79
+ /** Organization name */
80
+ organization: string;
81
+ /** Enable audit logging */
82
+ auditLogging: boolean;
83
+ /** Session timeout in minutes */
84
+ sessionTimeout: number;
85
+ /** Require MFA */
86
+ requireMFA: boolean;
87
+ /** Data encryption requirements */
88
+ encryption: {
89
+ atRest: boolean;
90
+ inTransit: boolean;
91
+ algorithm: string;
92
+ };
93
+ }
94
+ export interface PHIAccessLog {
95
+ id: string;
96
+ userId: string;
97
+ action: 'view' | 'create' | 'update' | 'delete' | 'export' | 'print';
98
+ resourceType: string;
99
+ resourceId: string;
100
+ timestamp: Date;
101
+ ipAddress?: string;
102
+ userAgent?: string;
103
+ reason?: string;
104
+ }
105
+ /**
106
+ * Log PHI access for HIPAA compliance
107
+ */
108
+ export declare function logPHIAccess(log: Omit<PHIAccessLog, 'id' | 'timestamp'>, endpoint?: string): PHIAccessLog;
109
+ /**
110
+ * Create HIPAA-compliant session manager
111
+ */
112
+ export declare function createHIPAASession(config: {
113
+ timeoutMinutes: number;
114
+ onTimeout: () => void;
115
+ onWarning?: (remainingMs: number) => void;
116
+ warningBeforeMs?: number;
117
+ }): {
118
+ resetTimer: () => void;
119
+ destroy: () => void;
120
+ getTimeRemaining: () => number;
121
+ };
122
+ export interface WCAGIssue {
123
+ id: string;
124
+ element: string;
125
+ level: 'A' | 'AA' | 'AAA';
126
+ guideline: string;
127
+ description: string;
128
+ suggestion: string;
129
+ impact: 'critical' | 'serious' | 'moderate' | 'minor';
130
+ }
131
+ /**
132
+ * Check color contrast ratio
133
+ */
134
+ export declare function checkColorContrast(foreground: string, background: string): {
135
+ ratio: number;
136
+ passesAA: boolean;
137
+ passesAAA: boolean;
138
+ passesAALarge: boolean;
139
+ passesAAALarge: boolean;
140
+ };
141
+ /**
142
+ * Check if element has accessible name
143
+ */
144
+ export declare function hasAccessibleName(element: HTMLElement): boolean;
145
+ /**
146
+ * Check heading hierarchy
147
+ */
148
+ export declare function checkHeadingHierarchy(container?: HTMLElement): {
149
+ valid: boolean;
150
+ issues: {
151
+ level: number;
152
+ element: HTMLElement;
153
+ issue: string;
154
+ }[];
155
+ };
156
+ export interface AuditLogEntry {
157
+ id: string;
158
+ timestamp: Date;
159
+ userId: string;
160
+ action: string;
161
+ resource: string;
162
+ resourceId?: string;
163
+ details?: Record<string, unknown>;
164
+ ipAddress?: string;
165
+ userAgent?: string;
166
+ outcome: 'success' | 'failure' | 'error';
167
+ errorMessage?: string;
168
+ }
169
+ export interface AuditLogConfig {
170
+ /** API endpoint for sending logs */
171
+ endpoint: string;
172
+ /** Batch logs before sending */
173
+ batchSize?: number;
174
+ /** Flush interval in ms */
175
+ flushInterval?: number;
176
+ /** Include user agent */
177
+ includeUserAgent?: boolean;
178
+ /** Include IP (requires server-side) */
179
+ includeIP?: boolean;
180
+ }
181
+ /**
182
+ * Create audit logger
183
+ */
184
+ export declare function createAuditLogger(config: AuditLogConfig): {
185
+ log: (entry: Omit<AuditLogEntry, "id" | "timestamp" | "userAgent">) => void;
186
+ flush: () => Promise<void>;
187
+ destroy: () => void;
188
+ };
189
+ export interface SOC2ControlStatus {
190
+ controlId: string;
191
+ name: string;
192
+ category: 'security' | 'availability' | 'processing_integrity' | 'confidentiality' | 'privacy';
193
+ status: 'compliant' | 'non_compliant' | 'not_applicable' | 'in_progress';
194
+ lastAssessed: Date;
195
+ evidence?: string[];
196
+ notes?: string;
197
+ }
198
+ /**
199
+ * Generate SOC 2 readiness checklist
200
+ */
201
+ export declare function getSOC2Checklist(): SOC2ControlStatus[];
@@ -0,0 +1,18 @@
1
+ import { default as React } from 'react';
2
+ import { DeviceTrustScore } from '../core/types';
3
+ export interface NiceDeviceTrustProps {
4
+ /** Pre-computed trust score. If omitted, computed client-side. */
5
+ trustScore?: DeviceTrustScore;
6
+ /** Called when a new score is computed. */
7
+ onScoreComputed?: (score: DeviceTrustScore) => void;
8
+ /** Minimum score threshold to be considered "trusted". Default: 60 */
9
+ trustThreshold?: number;
10
+ /** Show factor breakdown. Default: true */
11
+ showFactors?: boolean;
12
+ /** Show device fingerprint hash. Default: false */
13
+ showFingerprint?: boolean;
14
+ className?: string;
15
+ label?: string;
16
+ }
17
+ export declare const NiceDeviceTrust: React.FC<NiceDeviceTrustProps>;
18
+ export default NiceDeviceTrust;
@@ -0,0 +1,25 @@
1
+ import { default as React } from 'react';
2
+ import { BiometricConfig, BiometricTemplate, VerificationResult, FaceFeatures, SecurityVerificationStatus } from '../core/types';
3
+ export interface NiceFaceRecognitionProps extends BiometricConfig {
4
+ mode: 'enroll' | 'verify' | 'compare';
5
+ enrolledTemplates?: BiometricTemplate[];
6
+ /** Reference photo for 'compare' mode (data URL or image element). */
7
+ referencePhoto?: string | HTMLImageElement;
8
+ onEnroll?: (template: BiometricTemplate, features: FaceFeatures) => void;
9
+ onVerify?: (result: VerificationResult) => void;
10
+ onStatusChange?: (status: SecurityVerificationStatus) => void;
11
+ onError?: (error: Error) => void;
12
+ className?: string;
13
+ size?: 'sm' | 'md' | 'lg';
14
+ label?: string;
15
+ showQuality?: boolean;
16
+ /** Show detected face bounding box. Default: true */
17
+ showBoundingBox?: boolean;
18
+ /** Number of liveness challenges. Default: 1 */
19
+ livenessSteps?: number;
20
+ /** Show reference photo side by side in compare mode. Default: true */
21
+ showReference?: boolean;
22
+ instructionText?: string;
23
+ }
24
+ export declare const NiceFaceRecognition: React.FC<NiceFaceRecognitionProps>;
25
+ export default NiceFaceRecognition;
@@ -0,0 +1,34 @@
1
+ import { default as React } from 'react';
2
+ import { BiometricConfig, BiometricTemplate, VerificationResult, FingerprintFeatures, FingerPosition, SecurityVerificationStatus } from '../core/types';
3
+ export interface NiceFingerprintScannerProps extends BiometricConfig {
4
+ /** 'enroll' to capture new template, 'verify' to match against enrolled. */
5
+ mode: 'enroll' | 'verify';
6
+ /** Previously enrolled templates to match against (verify mode). */
7
+ enrolledTemplates?: BiometricTemplate[];
8
+ /** Which finger to scan. */
9
+ fingerPosition?: FingerPosition;
10
+ /** Called with the new template after enrollment. */
11
+ onEnroll?: (template: BiometricTemplate, features: FingerprintFeatures) => void;
12
+ /** Called with the verification result. */
13
+ onVerify?: (result: VerificationResult) => void;
14
+ /** Called on status change. */
15
+ onStatusChange?: (status: SecurityVerificationStatus) => void;
16
+ /** Called on any error. */
17
+ onError?: (error: Error) => void;
18
+ /** Custom CSS class. */
19
+ className?: string;
20
+ /** Size variant. */
21
+ size?: 'sm' | 'md' | 'lg';
22
+ /** Label for the finger position. */
23
+ label?: string;
24
+ /** Show quality indicator. Default: true */
25
+ showQuality?: boolean;
26
+ /** Show minutiae overlay. Default: false */
27
+ showMinutiae?: boolean;
28
+ /** Instruction text override. */
29
+ instructionText?: string;
30
+ /** Camera facing mode. Default: 'environment' */
31
+ cameraFacing?: 'user' | 'environment';
32
+ }
33
+ export declare const NiceFingerprintScanner: React.FC<NiceFingerprintScannerProps>;
34
+ export default NiceFingerprintScanner;
@@ -0,0 +1,22 @@
1
+ import { default as React } from 'react';
2
+ import { BiometricConfig, BiometricTemplate, VerificationResult, IrisFeatures, EyePosition, SecurityVerificationStatus } from '../core/types';
3
+ export interface NiceIrisScannerProps extends BiometricConfig {
4
+ mode: 'enroll' | 'verify';
5
+ enrolledTemplates?: BiometricTemplate[];
6
+ eye?: EyePosition;
7
+ onEnroll?: (template: BiometricTemplate, features: IrisFeatures) => void;
8
+ onVerify?: (result: VerificationResult) => void;
9
+ onStatusChange?: (status: SecurityVerificationStatus) => void;
10
+ onError?: (error: Error) => void;
11
+ className?: string;
12
+ size?: 'sm' | 'md' | 'lg';
13
+ label?: string;
14
+ showQuality?: boolean;
15
+ /** Show iris segmentation overlay. Default: true */
16
+ showSegmentation?: boolean;
17
+ /** Show guide circle for eye alignment. Default: true */
18
+ showGuide?: boolean;
19
+ instructionText?: string;
20
+ }
21
+ export declare const NiceIrisScanner: React.FC<NiceIrisScannerProps>;
22
+ export default NiceIrisScanner;
@@ -0,0 +1,24 @@
1
+ import { default as React } from 'react';
2
+ import { BiometricMethod } from '../core/types';
3
+ export interface MfaOption {
4
+ method: BiometricMethod;
5
+ label?: string;
6
+ description?: string;
7
+ icon?: React.ReactNode;
8
+ disabled?: boolean;
9
+ /** If the method was already verified in current flow. */
10
+ verified?: boolean;
11
+ }
12
+ export interface NiceMfaSelectorProps {
13
+ options: MfaOption[];
14
+ /** Minimum number of methods that must be verified. Default: 1 */
15
+ requiredCount?: number;
16
+ onSelect?: (method: BiometricMethod) => void;
17
+ /** Called when the required number of methods have been verified. */
18
+ onComplete?: (verifiedMethods: BiometricMethod[]) => void;
19
+ className?: string;
20
+ label?: string;
21
+ layout?: 'grid' | 'list';
22
+ }
23
+ export declare const NiceMfaSelector: React.FC<NiceMfaSelectorProps>;
24
+ export default NiceMfaSelector;
@@ -0,0 +1,22 @@
1
+ import { default as React } from 'react';
2
+ import { SecurityVerificationStatus, VerificationResult } from '../core/types';
3
+ export interface NicePassphraseInputProps {
4
+ mode?: 'set' | 'verify';
5
+ /** SHA-256 hex hash of expected passphrase for verification. */
6
+ expectedHash?: string;
7
+ /** Minimum strength (0-4) required for "set" mode. Default: 2 */
8
+ minStrength?: number;
9
+ /** Minimum character count. Default: 8 */
10
+ minLength?: number;
11
+ onComplete?: (passphrase: string) => void;
12
+ onVerify?: (result: VerificationResult) => void;
13
+ onStatusChange?: (status: SecurityVerificationStatus) => void;
14
+ onError?: (error: Error) => void;
15
+ label?: string;
16
+ placeholder?: string;
17
+ className?: string;
18
+ showStrength?: boolean;
19
+ maxAttempts?: number;
20
+ }
21
+ export declare const NicePassphraseInput: React.FC<NicePassphraseInputProps>;
22
+ export default NicePassphraseInput;
@@ -0,0 +1,19 @@
1
+ import { default as React } from 'react';
2
+ import { PatternLockConfig, SecurityVerificationStatus, VerificationResult } from '../core/types';
3
+ export interface NicePatternLockProps extends Partial<PatternLockConfig> {
4
+ mode?: 'set' | 'verify';
5
+ /** SHA-256 hex of the correct pattern sequence (e.g. "0,1,2,5,8"). */
6
+ expectedHash?: string;
7
+ /** Direct pattern string comparison (less secure). */
8
+ expectedPattern?: string;
9
+ onComplete?: (pattern: number[]) => void;
10
+ onVerify?: (result: VerificationResult) => void;
11
+ onStatusChange?: (status: SecurityVerificationStatus) => void;
12
+ onError?: (error: Error) => void;
13
+ label?: string;
14
+ className?: string;
15
+ /** Canvas dimension in px. Default auto from gridSize. */
16
+ canvasSize?: number;
17
+ }
18
+ export declare const NicePatternLock: React.FC<NicePatternLockProps>;
19
+ export default NicePatternLock;
@@ -0,0 +1,20 @@
1
+ import { default as React } from 'react';
2
+ import { KeypadConfig, SecurityVerificationStatus, VerificationResult } from '../core/types';
3
+ export interface NicePinKeypadProps extends Partial<KeypadConfig> {
4
+ /** Expected PIN hash to verify against (SHA-256 hex of the correct PIN). */
5
+ expectedHash?: string;
6
+ /** Direct PIN string comparison (frontend-only, less secure). */
7
+ expectedPin?: string;
8
+ mode?: 'set' | 'verify';
9
+ onComplete?: (pin: string) => void;
10
+ onVerify?: (result: VerificationResult) => void;
11
+ onStatusChange?: (status: SecurityVerificationStatus) => void;
12
+ onError?: (error: Error) => void;
13
+ /** Show "Use biometrics" fallback button. */
14
+ showBiometricFallback?: boolean;
15
+ onBiometricFallback?: () => void;
16
+ label?: string;
17
+ className?: string;
18
+ }
19
+ export declare const NicePinKeypad: React.FC<NicePinKeypadProps>;
20
+ export default NicePinKeypad;
@@ -0,0 +1,16 @@
1
+ import { default as React } from 'react';
2
+ import { SecurityAuditEntry, BiometricMethod } from '../core/types';
3
+ export interface NiceSecurityAuditLogProps {
4
+ entries: SecurityAuditEntry[];
5
+ /** Max entries per page. Default 20. */
6
+ pageSize?: number;
7
+ /** Enable export button. Default true. */
8
+ showExport?: boolean;
9
+ /** Methods to show in filter dropdown. Default: all. */
10
+ filterMethods?: BiometricMethod[];
11
+ onEntryClick?: (entry: SecurityAuditEntry) => void;
12
+ className?: string;
13
+ label?: string;
14
+ }
15
+ export declare const NiceSecurityAuditLog: React.FC<NiceSecurityAuditLogProps>;
16
+ export default NiceSecurityAuditLog;
@@ -0,0 +1,24 @@
1
+ import { default as React } from 'react';
2
+ export interface SessionInfo {
3
+ id: string;
4
+ device: string;
5
+ browser?: string;
6
+ os?: string;
7
+ ip?: string;
8
+ location?: string;
9
+ lastActive: number;
10
+ current?: boolean;
11
+ trusted?: boolean;
12
+ }
13
+ export interface NiceSessionManagerProps {
14
+ sessions: SessionInfo[];
15
+ onRevoke?: (sessionId: string) => void;
16
+ onRevokeAll?: () => void;
17
+ onTrust?: (sessionId: string, trusted: boolean) => void;
18
+ className?: string;
19
+ label?: string;
20
+ /** Show the "Revoke all other sessions" button. Default: true */
21
+ showRevokeAll?: boolean;
22
+ }
23
+ export declare const NiceSessionManager: React.FC<NiceSessionManagerProps>;
24
+ export default NiceSessionManager;
@@ -0,0 +1,22 @@
1
+ import { default as React } from 'react';
2
+ import { WebAuthnConfig, SecurityVerificationStatus, VerificationResult } from '../core/types';
3
+ export interface NiceWebAuthnButtonProps extends Partial<WebAuthnConfig> {
4
+ mode: 'register' | 'authenticate';
5
+ /** Credential IDs for authentication (base64url strings). */
6
+ credentialIds?: string[];
7
+ /** Server-generated challenge (base64url). If omitted a random one is used. */
8
+ challenge?: string;
9
+ onRegister?: (credential: PublicKeyCredential) => void;
10
+ onAuthenticate?: (assertion: PublicKeyCredential) => void;
11
+ onVerify?: (result: VerificationResult) => void;
12
+ onStatusChange?: (status: SecurityVerificationStatus) => void;
13
+ onError?: (error: Error) => void;
14
+ label?: string;
15
+ className?: string;
16
+ variant?: 'primary' | 'outline' | 'ghost';
17
+ size?: 'sm' | 'md' | 'lg';
18
+ fullWidth?: boolean;
19
+ icon?: React.ReactNode;
20
+ }
21
+ export declare const NiceWebAuthnButton: React.FC<NiceWebAuthnButtonProps>;
22
+ export default NiceWebAuthnButton;