-
Notifications
You must be signed in to change notification settings - Fork 0
State Management System
- Introduction
- System Architecture
- Core State Structure
- Local Storage Integration
- State Management Patterns
- Authentication Flow Integration
- UI State Synchronization
- Event Subscription Model
- Error Handling and Edge Cases
- Debugging and Monitoring
- Best Practices
- Troubleshooting Guide
The PostQuantum WebAuthn Platform implements a sophisticated client-side state management system centered around a centralized state object that orchestrates user session context, authentication flows, credential storage, and UI state coordination. This system provides seamless persistence across page reloads while maintaining real-time synchronization between different script modules.
The state management architecture follows a unidirectional data flow pattern where state changes trigger automatic UI updates and coordinate between authentication modules, credential management systems, and user interface components. The system integrates deeply with browser localStorage for persistent storage while providing robust error handling for edge cases like storage quota limits and concurrent modifications.
The state management system operates through several interconnected layers that work together to provide a cohesive user experience:
graph TB
subgraph "State Layer"
State[state.js<br/>Central State Store]
LocalStorage[local-storage.js<br/>Persistence Layer]
Artifacts[credential-artifacts-client.js<br/>Server Sync]
end
subgraph "UI Layer"
Navigation[navigation.js<br/>Tab Management]
UI[ui.js<br/>Modal & Overlay Control]
Status[status.js<br/>Message Display]
end
subgraph "Authentication Layer"
Simple[simple/auth-simple.js<br/>Basic Auth]
Advanced[advanced/auth-advanced.js<br/>Advanced Auth]
Credentials[credential-display.js<br/>Credential Management]
end
subgraph "Main Application"
Main[main.js<br/>Application Bootstrap]
Username[username.js<br/>User Identity]
end
State --> LocalStorage
State --> Artifacts
Navigation --> State
UI --> State
Status --> State
Simple --> State
Advanced --> State
Credentials --> State
Main --> State
Username --> State
LocalStorage --> Artifacts
Diagram sources
- state.js
- local-storage.js
- navigation.js
The central state object serves as the single source of truth for the application, containing essential session context and UI state flags:
classDiagram
class State {
+string currentSubTab
+Array storedCredentials
+string currentJsonMode
+object currentJsonData
+number lastFakeCredLength
+Array generatedExcludeCredentials
+Array generatedAllowCredentials
+TextDecoder utf8Decoder
}
class CredentialRecord {
+string type
+string credentialIdBase64Url
+string storageId
+string email
+string userName
+number signCount
+object properties
+object relyingParty
}
class JsonEditorState {
+string mode
+object data
+boolean isValid
}
State --> CredentialRecord : "manages"
State --> JsonEditorState : "contains"
Diagram sources
- state.js
| Property | Type | Description | Usage |
|---|---|---|---|
currentSubTab |
string | Active sub-navigation tab identifier | Tab switching and UI state |
storedCredentials |
Array | Collection of user credential records | Credential display and management |
currentJsonMode |
string | Current JSON editor mode (view/edit) | Advanced credential configuration |
currentJsonData |
object | Current JSON editor content | Form-to-JSON synchronization |
lastFakeCredLength |
number | Last generated fake credential count | Testing and development |
generatedExcludeCredentials |
Array | Generated exclude credential list | Authentication testing |
generatedAllowCredentials |
Array | Generated allow credential list | Authentication testing |
utf8Decoder |
TextDecoder | UTF-8 decoding utility | Data processing |
Section sources
- state.js
The system provides comprehensive persistence through a sophisticated local storage management layer that handles credential serialization, migration, and synchronization with server-side artifacts.
flowchart TD
A[Unified Storage Key] --> B{Legacy Migration}
B --> |Simple| C[Legacy Simple Storage]
B --> |Advanced| D[Legacy Advanced Storage]
B --> |Unified| E[Modern Storage]
C --> F[Migrate to Unified]
D --> F
F --> G[SHARED_STORAGE_KEY]
G --> H[Credential Partitioning]
H --> I[Simple Credentials]
H --> J[Advanced Credentials]
I --> K[Local Storage]
J --> L[Server Artifacts]
J --> M[Local Storage]
L --> N[Artifact Synchronization]
N --> O[Upload Heavy Data]
N --> P[Download Server Data]
Diagram sources
- local-storage.js
The system maintains backward compatibility through a migration strategy that consolidates legacy storage formats:
| Storage Key | Purpose | Legacy Support |
|---|---|---|
postquantum-webauthn.credentials |
Unified modern storage | Primary |
postquantum-webauthn.simpleCredentials |
Legacy simple credentials | Migration target |
postquantum-webauthn.advancedCredentials |
Legacy advanced credentials | Migration target |
The storage system implements robust serialization with error handling:
sequenceDiagram
participant App as Application
participant LS as Local Storage
participant Parser as JSON Parser
participant Validator as Data Validator
App->>Parser : JSON.stringify(records)
Parser->>LS : window.localStorage.setItem()
LS-->>App : Success/Failure
App->>LS : window.localStorage.getItem()
LS->>Parser : Raw JSON string
Parser->>Validator : Parse and validate
Validator-->>App : Cleaned data array
Note over App,Validator : Error handling for malformed data
Diagram sources
- local-storage.js
Section sources
- local-storage.js
The system employs several key patterns for managing state changes and ensuring consistency across the application.
State updates follow a predictable pattern where changes propagate through the system:
sequenceDiagram
participant User as User Action
participant Handler as Event Handler
participant State as State Store
participant UI as UI Components
participant Storage as Local Storage
User->>Handler : Trigger action
Handler->>State : Update state properties
State->>UI : Notify subscribers
UI->>UI : Re-render affected components
Handler->>Storage : Persist changes
Storage-->>Handler : Confirm persistence
The credential management system demonstrates complex state coordination:
flowchart TD
A[Load Credentials] --> B[Partition Types]
B --> C[Simple Credentials]
B --> D[Advanced Credentials]
C --> E[Local Storage Only]
D --> F[Local + Server Artifacts]
F --> G{Artifact Available?}
G --> |Yes| H[Download Server Data]
G --> |No| I[Use Local Summary]
H --> J[Update State]
I --> J
E --> J
J --> K[Refresh UI Display]
K --> L[Update JSON Editor]
K --> M[Update Allow Credentials]
Diagram sources
- credential-display.js
Section sources
- credential-display.js
The state management system coordinates seamlessly with authentication flows, maintaining session context and propagating state changes throughout the authentication lifecycle.
sequenceDiagram
participant UI as Registration UI
participant State as State Store
participant Auth as Auth Module
participant Storage as Local Storage
participant Server as Server API
UI->>State : Initialize registration state
State->>State : Set session state markers
UI->>Auth : Begin registration
Auth->>Server : Request registration options
Server-->>Auth : Return options with session state
Auth->>State : Store session state
Auth->>Auth : Execute WebAuthn registration
Auth->>Server : Submit registration result
Server-->>Auth : Confirm registration
Auth->>Storage : Save credential locally
Storage->>State : Update stored credentials
State->>UI : Trigger UI refresh
Diagram sources
- auth-simple.js
- auth-advanced.js
Authentication flows maintain state consistency across multiple steps:
| Phase | State Changes | UI Updates | Persistence |
|---|---|---|---|
| Begin Auth | Session state stored | Progress indicators shown | None |
| Select Credentials | Active credential set | Credential list highlighting | None |
| Execute Auth | Assertion result processed | Success/error messages | Sign count updated |
| Complete Auth | Session cleared | Final status displayed | Local storage sync |
Section sources
- auth-simple.js
- auth-advanced.js
The system maintains tight synchronization between state changes and UI updates through a reactive pattern that ensures consistency across all interface components.
stateDiagram-v2
[*] --> Initialization
Initialization --> SimpleTab : switchTab('simple')
Initialization --> AdvancedTab : switchTab('advanced')
SimpleTab --> SimpleSubTab : switchSubTab('registration')
SimpleTab --> SimpleSubTab : switchSubTab('authentication')
AdvancedTab --> AdvancedSubTab : switchSubTab('registration')
AdvancedTab --> AdvancedSubTab : switchSubTab('authentication')
SimpleSubTab --> SimpleTab : Navigation
SimpleSubTab --> AdvancedTab : Tab Switch
AdvancedSubTab --> SimpleTab : Tab Switch
AdvancedSubTab --> AdvancedTab : Navigation
SimpleTab --> [*] : Cleanup
AdvancedTab --> [*] : Cleanup
Diagram sources
- navigation.js
The UI system manages complex modal and overlay states through a z-index coordination system:
flowchart TD
A[Open Modal Request] --> B[Calculate Base Z-Index]
B --> C[Find Highest Existing Modal]
C --> D[Compute Target Z-Index]
D --> E[Apply Z-Index to Modal]
E --> F[Add Open Classes]
F --> G[Update Global Scroll Lock]
H[Close Modal Request] --> I[Remove Open Classes]
I --> J[Reset Z-Index]
J --> K[Cleanup Transitions]
K --> L[Update Global Scroll Lock]
Diagram sources
- ui.js
Section sources
- navigation.js
- ui.js
The state management system implements a publish-subscribe pattern that allows components to react to state changes without tight coupling.
graph LR
subgraph "State Changes"
A[Direct State Update]
B[Async Operations]
C[User Interactions]
end
subgraph "Event System"
D[State Change Events]
E[UI Refresh Triggers]
F[Storage Notifications]
end
subgraph "Subscriber Components"
G[UI Components]
H[Form Handlers]
I[Navigation Controllers]
J[Status Messages]
end
A --> D
B --> D
C --> D
D --> E
D --> F
E --> G
E --> H
E --> I
E --> J
F --> G
F --> H
Components communicate through state changes rather than direct references:
| Component Type | State Dependencies | Update Triggers |
|---|---|---|
| Navigation | currentSubTab |
Tab switches, subtab changes |
| Credential Display | storedCredentials |
Load/save operations |
| JSON Editor |
currentJsonMode, currentJsonData
|
Mode changes, data updates |
| Status Messages | Various | All state changes |
| Forms | Various | Input changes, validation |
Section sources
- navigation.js
- credential-display.js
The system implements comprehensive error handling for various failure scenarios and edge cases.
flowchart TD
A[Storage Operation] --> B{Storage Available?}
B --> |No| C[Graceful Degradation]
B --> |Yes| D[Execute Operation]
D --> E{Operation Successful?}
E --> |No| F[Log Error]
E --> |Yes| G[Continue Operation]
F --> H[Show Warning Message]
H --> I[Fallback Behavior]
C --> J[Inform User]
I --> K[Retry Mechanism]
J --> K
K --> L[User Decision]
| Scenario | Detection Method | Recovery Strategy | User Impact |
|---|---|---|---|
| Storage Quota Exceeded | QuotaExceededError |
Compress data, remove old entries | Reduced functionality |
| Corrupted Storage Data | JSON parse failures | Reset to defaults | Data loss warning |
| Concurrent Modifications | Version conflicts | Merge strategies | Conflict resolution |
| Network Failures | Timeout errors | Retry with exponential backoff | Offline mode |
| Browser Compatibility | Feature detection | Polyfills or alternatives | Limited features |
The system handles stale state through several mechanisms:
sequenceDiagram
participant App as Application
participant State as State Manager
participant Storage as Local Storage
participant Server as Server API
App->>State : Request credential list
State->>Storage : Check local cache
Storage-->>State : Return cached data
State->>Server : Fetch latest data
Server-->>State : Return fresh data
State->>State : Compare versions
State->>State : Resolve conflicts
State-->>App : Return merged data
Section sources
- local-storage.js
- credential-artifacts-client.js
The system provides extensive debugging capabilities and monitoring tools for development and production environments.
flowchart TD
A[Debug Request] --> B[Collect State Snapshot]
B --> C[Gather UI State]
C --> D[Capture Network Activity]
D --> E[Generate Report]
B --> F[Current Subtab]
B --> G[Stored Credentials]
B --> H[JSON Editor State]
C --> I[Modal States]
C --> J[Form Validation]
C --> K[Error Messages]
D --> L[API Requests]
D --> M[Response Times]
D --> N[Error Logs]
E --> O[Debug Console Output]
E --> P[Exportable Report]
The system includes built-in monitoring for key metrics:
| Metric Category | Measurements | Purpose |
|---|---|---|
| Performance | Load times, operation durations | Performance optimization |
| Usage Analytics | Feature adoption, error rates | Product improvement |
| Storage Health | Size limits, corruption detection | Reliability monitoring |
| Network Status | Connectivity, timeout rates | User experience tracking |
Development mode provides enhanced debugging capabilities:
// Example debug configuration
{
enableLogging: true,
verboseErrors: true,
stateSnapshotOnChanges: true,
networkDelaySimulation: false
}Section sources
- main.js
- Single Source of Truth: Maintain one authoritative state object
- Immutable Updates: Create new state objects rather than modifying existing ones
- Predictable Updates: Ensure state changes follow logical sequences
- Minimal State: Store only essential data to reduce complexity
flowchart TD
A[State Update Request] --> B{Should Update?]
B --> |No| C[Skip Update]
B --> |Yes| D[Calculate Diff]
D --> E{Diff Significant?}
E --> |No| F[Optimize Render]
E --> |Yes| G[Full Update]
F --> H[Batch DOM Updates]
G --> H
H --> I[Trigger Reconciliation]
I --> J[Update Affected Components]
The system implements several memory management strategies:
- Lazy Loading: Load credential data only when needed
- Garbage Collection: Clean up unused state references
- Weak References: Use WeakMaps for temporary associations
- Resource Pooling: Reuse expensive objects when possible
State management incorporates security best practices:
- Data Sanitization: Clean user input before storage
- Encryption: Encrypt sensitive credential data
- Access Control: Limit state access to authorized components
- Audit Logging: Track state changes for security analysis
Symptoms: State resets after page reload Causes:
- Storage quota exceeded
- Browser privacy settings blocking localStorage
- CORS restrictions preventing cross-domain access
Solutions:
- Check browser storage quota using
localStorage.length - Verify browser privacy settings allow localStorage
- Test with different browsers/devices
- Implement fallback storage mechanisms
Symptoms: State changes don't reflect in UI Causes:
- Missing event subscriptions
- Incorrect state update patterns
- Component lifecycle issues
Solutions:
- Verify event listeners are properly attached
- Check state update immutability
- Ensure components are mounted before state changes
- Use React DevTools or equivalent debugging tools
Symptoms: Registration/authentication fails silently Causes:
- Network connectivity issues
- Server-side validation failures
- State corruption during async operations
Solutions:
- Enable network monitoring and logging
- Implement retry mechanisms with exponential backoff
- Add comprehensive error handling and user feedback
- Validate state consistency before operations
// Check state health
console.log('State:', state);
console.log('Stored credentials:', state.storedCredentials.length);
console.log('LocalStorage available:', typeof window !== 'undefined' && !!window.localStorage);
// Monitor state changes
window.addEventListener('state:changed', (event) => {
console.log('State updated:', event.detail);
});
// Test storage capacity
try {
const testKey = '__storage_test__';
localStorage.setItem(testKey, 'test');
localStorage.removeItem(testKey);
console.log('Storage available');
} catch (error) {
console.error('Storage unavailable:', error);
}Monitor state management performance using browser developer tools:
- Memory Profiler: Check for memory leaks in state objects
- Performance Timeline: Measure state update timing
- Network Tab: Monitor API requests triggered by state changes
- Console Logging: Track state transitions and error patterns
Section sources
- main.js
- local-storage.js