diff --git a/README.md b/README.md index aa0aeff..b7bfc70 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,32 @@ # CyberSim OS -**Phase 2 MVP: Scenario-Driven Cybersecurity Simulation Platform** +**Phase 2.5: Localization, Corporate Branding, and Immersive Login** -CyberSim OS is an offline-first, browser-native cybersecurity simulation platform designed for ordinary end users. Learners enter a convincing fictional enterprise desktop, perform routine workplace activities, investigate ambiguous events, encounter realistic threats (credential phishing, malicious attachments) and legitimate false flags, receive a multi-axis behavioral after-action assessment, and earn cryptographically verifiable completion certificates (`*.cybercert`). +CyberSim OS is an offline-first, browser-native cybersecurity simulation platform designed for enterprise organizations and end-user learners. Learners enter a convincing fictional enterprise workstation, perform routine workplace activities, investigate ambiguous communications, encounter realistic threats (credential harvesting, malicious attachments) alongside legitimate false flags, receive a multi-axis behavioral after-action assessment, and earn cryptographically verifiable completion certificates (`*.cybercert`). -**Phase 2** transforms CyberSim from a single hard-coded simulation into a **reusable, scenario-driven platform**. Complete experiences are authored through portable declarative JSON scenario packages — no application code changes required. +**Phase 2.5** adds **organizational readiness** through runtime multilingual localization, configuration-driven corporate branding, an immersive workstation login experience, learner first-name personalization, and cross-locale cryptographic verification. --- ## Key Features -- **Scenario-Driven Architecture**: Complete simulations are defined through JSON scenario packages. No code changes needed to create new experiences. -- **Convincing Fictional Desktop**: Original Windows-like theme with draggable/resizable windows, active/inactive focus states, taskbar, Start launcher, simulation clock, and system toast notifications with audio cues. -- **Core Simulated Workplace Applications**: - - **Inlook**: Email client with header inspector (RFC sender vs. friendly name), link hover destination tooltips, phishing report workflow, and reply/delete actions. - - **Navigator**: Web browser supporting intranet directories, policy hubs, and external spoofed credential-harvesting portals. - - **Files**: Virtual filesystem managing Documents, Downloads, and Company Shared folders. - - **Doc Viewer**: Lightweight renderer for spreadsheets (`.xlsx`), policies (`.pdf`), and memos. - - **Security Center**: Endpoint protection dashboard, real-time alert logs, incident report confirmations, and delayed alert triggers. -- **Declarative Event System**: Scenario events with time-based, action-based, and state-based triggers execute through a restricted behavior vocabulary. -- **Data-Driven Scoring**: Scoring categories, rules, and thresholds are defined in the scenario package. The engine evaluates them generically. -- **Delayed Consequences Engine**: Unsafe actions trigger delayed consequence events without giving immediate arcade-like game-over feedback. +- **Immersive CyberSim OS Login**: Fictional enterprise workstation login and dynamic network/workplace selection without requesting passwords or sensitive employee credentials. +- **Runtime Multilingual & Localization (I18n)**: + - CyberSim OS user interface localization with deterministic fallback chain (Selected Locale $\to$ Deployment Default Locale $\to$ English $\to$ `[missing: key]`). + - Working demonstration locales: English (`en`) and Spanish (`es`). + - Independent scenario content localization (`scenarios//locales/.json`). +- **Configuration-Driven Corporate Branding**: + - Customize organization name, short name, logo, desktop wallpaper, accent color, and service desk name via `src/config/deployment.json`. + - Automatic fallback to CyberSim default enterprise theme when branding fields are omitted. + - Preserves simulation safety boundaries (CyberSim identity remains visible). +- **Learner Personalization**: + - First-name input is passed into scenario state (`learner.firstName`). + - Safe template interpolation (`{{learner.firstName}}`, `{{learner.name}}`) in emails, notifications, alerts, web pages, documents, and certificates with strict HTML entity escaping. +- **Scenario-Driven Architecture**: Complete simulations are defined through declarative JSON scenario packages without application source code modification. - **Verifiable Cryptographic Certificates**: - - Web Crypto SHA-256 scenario fingerprinting. + - Canonical Web Crypto SHA-256 scenario fingerprinting unaffected by display translations. - Portable, structured `*.cybercert` JSON credential export. - - Standalone offline certificate validator (`verify.html`). + - Standalone offline certificate validator (`verify.html`) supporting localized verification. - **100% Offline-First & Zero Dependencies**: Runs directly from any static web server, GitHub Pages, or the bundled `launcher.py` with zero npm/node/external CDN requirements. --- @@ -38,7 +40,7 @@ Run the lightweight local launcher to start the server at `http://127.0.0.1:8080 python launcher.py ``` -Your default web browser will open automatically with the default scenario. +Your default web browser will open automatically with the CyberSim OS Login interface. ### Option 2: Static Web Server Serve the `src/` directory with any static HTTP server: @@ -49,137 +51,104 @@ python -m http.server 8000 ``` Open [http://127.0.0.1:8000](http://127.0.0.1:8000) in your browser. -### Loading a Specific Scenario -Use the `?scenario=` query parameter to load a scenario package: +--- -``` -http://127.0.0.1:8080?scenario=scenarios/nexacore-orientation/scenario.json -http://127.0.0.1:8080?scenario=scenarios/quickstart-example/scenario.json -``` +## Deployment Configuration -If no `?scenario=` parameter is specified, the engine loads `scenarios/nexacore-orientation/scenario.json` by default. +Deployments are customized via `src/config/deployment.json`: + +```json +{ + "organization": { + "name": "NexaCore Technologies", + "shortName": "NexaCore", + "logo": "", + "wallpaper": "", + "accentColor": "#2563eb", + "supportName": "NexaCore Service Desk" + }, + "localization": { + "defaultLocale": "en", + "enabledLocales": ["en", "es"] + }, + "scenarios": [ + { + "id": "nexacore-orientation", + "path": "scenarios/nexacore-orientation/scenario.json", + "networkName": "NexaCore Corporate", + "networkDescription": "Corporate Workplace Network", + "networkIcon": "corporate", + "supportedLocales": ["en", "es"] + }, + { + "id": "quickstart-example", + "path": "scenarios/quickstart-example/scenario.json", + "networkName": "Meridian Health Partners", + "networkDescription": "Clinical & Administrative Network", + "networkIcon": "health", + "supportedLocales": ["en", "es"] + } + ] +} +``` --- ## Included Scenarios -| Scenario | Description | -|----------|-------------| -| **NexaCore Orientation** (`nexacore-orientation`) | Full-featured scenario: 5 emails, 3 web pages, 3 documents, 6 scoring categories, credential phishing + malicious attachment threats, 2 false flags. ~15 min. | -| **Meridian Health Quickstart** (`quickstart-example`) | Minimal scenario: 3 emails, 1 web page, 2 documents, 3 scoring categories, 1 credential phishing threat. ~5 min. | +| Scenario | Description | Supported Languages | +|----------|-------------|---------------------| +| **NexaCore Orientation** (`nexacore-orientation`) | Full-featured scenario: 5 emails, 3 web pages, 3 documents, 6 scoring categories, credential phishing + malicious attachment threats, 2 false flags. | English (`en`), Español (`es`) | +| **Meridian Health Quickstart** (`quickstart-example`) | Minimal scenario: 3 emails, 1 web page, 2 documents, 3 scoring categories, 1 credential phishing threat. | English (`en`), Español (`es`) | --- -## Creating a Scenario +## Scenario Localization & Personalization -Scenarios are self-contained JSON packages stored in a directory: +Scenarios declare supported languages in `scenario.json`: -``` -scenarios/my-scenario/ -├── scenario.json # Scenario definition (required) -├── assets/ # Optional images, media -└── README.md # Author notes (optional) +```json +{ + "formatVersion": "1.0", + "id": "my-scenario", + "supportedLocales": ["en", "es"], + "login": { + "networkName": "My Enterprise", + "networkDescription": "Corporate Network", + "networkIcon": "corporate" + } +} ``` -The `scenario.json` file defines everything the learner experiences: -- **People** and **organizations** (contacts, domains, trust boundaries) -- **Messages** (emails with links, attachments, threat indicators) -- **Pages** (simulated websites with forms) -- **Files** (virtual documents, spreadsheets, policies) -- **Events** (time-triggered, action-triggered, state-triggered with delays) -- **Scoring** (categories, rules, conditions, thresholds) -- **Findings** and **feedback** (behavioral evaluation with pedagogical notes) +Scenario translations are placed in `locales/.json` (e.g. `locales/es.json`): -See `docs/scenario-format.md` for the full format reference. - ---- - -## Certificate Verification - -To verify a `*.cybercert` certificate issued by CyberSim OS: - -1. Open `src/verify.html` in your web browser. -2. Drag and drop the `*.cybercert` file into the verification area. -3. The offline verifier recalculates the SHA-256 integrity hash, verifies the scenario fingerprint, and confirms the passing score and learner identity. - ---- - -## Architecture & Directory Structure - -``` -CyberSim-OS/ -├── .labyricorn/ # Labyricorn exhibition & devlog publishing records -├── scenarios/ -│ ├── nexacore-orientation/ # Phase 1 scenario (fully declarative) -│ │ └── scenario.json -│ └── quickstart-example/ # Second example scenario -│ └── scenario.json -├── docs/ -│ └── scenario-format.md # Scenario format reference (TODO) -├── src/ -│ ├── index.html # Main desktop simulation interface -│ ├── verify.html # Standalone offline certificate verifier -│ ├── css/ -│ │ ├── theme-windows.css # Fictional Windows-like enterprise theme tokens -│ │ ├── desktop.css # Window manager, taskbar, start menu, tray, toasts -│ │ ├── components.css # Modals, form inputs, buttons, badges, tabs -│ │ └── apps.css # Inlook, Navigator, Files, DocViewer, SecurityCenter -│ ├── js/ -│ │ ├── main.js # Application bootstrapper & scenario loader -│ │ ├── core/ -│ │ │ ├── window_manager.js# Window lifecycle, stacking, drag, min/max/close -│ │ │ ├── desktop.js # Desktop shell, launcher, clock, simulation controls -│ │ │ └── notifications.js # Toast notifications & Web Audio synth audio chime -│ │ ├── apps/ -│ │ │ ├── inlook.js # Email client with RFC header/link inspection -│ │ │ ├── navigator.js # Simulated browser with data-driven pages & forms -│ │ │ ├── files.js # Virtual filesystem explorer -│ │ │ ├── docviewer.js # Spreadsheet and document viewer -│ │ │ └── security_center.js # Endpoint status & incident report dashboard -│ │ ├── engine/ -│ │ │ ├── event_bus.js # Behavioral telemetry logger -│ │ │ ├── consequence.js # Consequence tracking (Phase 2 thin wrapper) -│ │ │ ├── scenario_state.js# Central mutable scenario state manager -│ │ │ ├── condition_evaluator.js # Declarative condition tree evaluator -│ │ │ ├── event_scheduler.js # Time/action/state-driven event executor -│ │ │ └── action_dispatcher.js # Restricted behavior vocabulary dispatcher -│ │ ├── scenario/ -│ │ │ ├── schema.js # JSON schema validation -│ │ │ ├── loader.js # Scenario package loader & sanitizer -│ │ │ ├── validator.js # Deep reference integrity validation -│ │ │ ├── diagnostics.js # Dev-mode diagnostics overlay -│ │ │ └── fingerprint.js # Web Crypto SHA-256 scenario fingerprinting -│ │ ├── scoring/ -│ │ │ ├── scorer.js # Data-driven behavioral scoring engine -│ │ │ └── aar.js # After-Action Report modal -│ │ └── cert/ -│ │ ├── cert_generator.js# *.cybercert JSON generator & printable certificate -│ │ └── cert_verifier.js # Offline cryptographic certificate verifier -│ └── assets/ # Embedded SVG icons and media -├── launcher.py # Zero-dependency local 127.0.0.1 web server -├── devlog_editor.py # Labyricorn devlog validation & editing tool -└── README.md # Project documentation +```json +{ + "title": "Título en español", + "description": "Descripción en español", + "messages": { + "email_welcome": { + "sender": "Nombre del Remitente", + "subject": "Asunto traducido", + "body": "Hola {{learner.firstName}},\n\n¡Bienvenido a su turno!" + } + } +} ``` --- -## Development Mode +## Automated Tests -Add `?dev=true` to the URL to enable the diagnostics overlay: +Run the headless automated test suite with Node.js: +```bash +node tests/run_tests.js ``` -http://127.0.0.1:8080?scenario=../scenarios/nexacore-orientation/scenario.json&dev=true -``` - -The diagnostics panel shows: -- Scenario validation results (errors, warnings) -- Object counts (people, messages, events, etc.) -- Live event states and scores -- Scenario fingerprint --- -## Validation & Devlog Maintenance +## Devlog Validation Run the validation suite to ensure `.labyricorn/` records and devlog entries adhere to the schema: diff --git a/docs/scenario-format.md b/docs/scenario-format.md index 5c5be86..bcffaa6 100644 --- a/docs/scenario-format.md +++ b/docs/scenario-format.md @@ -53,6 +53,8 @@ For large scenarios, sub-collections can optionally be split across multiple fil | `mode` | `string` | **Yes** | Instruction mode: `"guided"`, `"practice"`, or `"assessment"`. | | `entryEvent` | `string` | **Yes** | ID of the event executed at scenario start. | | `passingScore` | `number` | **Yes** | Minimum score required to pass and earn a certificate (0–100). | +| `supportedLocales` | `array` | No | List of supported language codes (e.g. `["en", "es"]`). | +| `login` | `object` | No | Network login metadata: `{ networkName, networkDescription, networkIcon }`. | | `engine` | `object` | No | Minimum engine version requirements (`{ "minimumVersion": "0.2.0" }`). | | `learner` | `object` | No | Initial persona: `{ name, role, email, department }`. | | `organizations` | `array` | No | List of simulated organizations & trusted domain lists. | @@ -281,3 +283,61 @@ The diagnostics overlay provides: - Event trigger states and scheduled timers - Current category score breakdowns and recorded findings - Scenario SHA-256 fingerprint calculations + +--- + +## 9. Scenario Localization & Personalization + +### 9.1 Declaring Supported Locales & Login Presentation + +Scenarios declare their supported language codes in `scenario.json`: + +```json +{ + "formatVersion": "1.0", + "id": "my-scenario", + "supportedLocales": ["en", "es"], + "login": { + "networkName": "ACME Corporate Network", + "networkDescription": "Simulated Corporate Workplace", + "networkIcon": "corporate" + } +} +``` + +### 9.2 Providing Scenario Translations (`locales/.json`) + +Translations for scenario-specific content are stored within the scenario package under `locales/`: + +``` +scenarios/my-scenario/ +├── scenario.json +└── locales/ + ├── en.json + └── es.json +``` + +The translation catalog can override text properties across messages, pages, files, notifications, alerts, findings, and feedback: + +```json +{ + "title": "Turno Operativo y Concientización", + "messages": { + "email_welcome": { + "sender": "Morgan Chen (Vicepresidente)", + "subject": "Bienvenido al equipo", + "body": "Hola {{learner.firstName}},\n\n¡Bienvenido!" + } + } +} +``` + +### 9.3 Learner Personalization Variables + +The following template variables are available for dynamic interpolation across messages, documents, web pages, notifications, and feedback: + +- `{{learner.firstName}}`: Learner's validated first name entered at login (HTML-escaped). +- `{{learner.name}}`: Learner's full name. +- `{{learner.email}}`: Learner's assigned workplace email address. +- `{{learner.role}}`: Learner's assigned workplace job title. +- `{{company.name}}`: Primary enterprise organization name. diff --git a/src/config/deployment.json b/src/config/deployment.json new file mode 100644 index 0000000..48673a9 --- /dev/null +++ b/src/config/deployment.json @@ -0,0 +1,32 @@ +{ + "organization": { + "name": "NexaCore Technologies", + "shortName": "NexaCore", + "logo": "", + "wallpaper": "", + "accentColor": "#2563eb", + "supportName": "NexaCore Service Desk" + }, + "localization": { + "defaultLocale": "en", + "enabledLocales": ["en", "es"] + }, + "scenarios": [ + { + "id": "nexacore-orientation", + "path": "scenarios/nexacore-orientation/scenario.json", + "networkName": "NexaCore Corporate", + "networkDescription": "Corporate Workplace Network", + "networkIcon": "corporate", + "supportedLocales": ["en", "es"] + }, + { + "id": "quickstart-example", + "path": "scenarios/quickstart-example/scenario.json", + "networkName": "Meridian Health Partners", + "networkDescription": "Clinical & Administrative Network", + "networkIcon": "health", + "supportedLocales": ["en", "es"] + } + ] +} diff --git a/src/css/components.css b/src/css/components.css index d87edfb..e6abb95 100644 --- a/src/css/components.css +++ b/src/css/components.css @@ -225,3 +225,220 @@ margin-bottom: 2px; font-family: var(--font-system); } + +/* Immersive Login Backdrop & Card */ +.cs-login-backdrop { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + background: radial-gradient(circle at 50% 30%, #1e293b 0%, #0f172a 100%); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; + padding: 20px; + font-family: var(--font-system); +} + +.cs-login-card { + background: rgba(30, 41, 59, 0.92); + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: var(--radius-lg); + box-shadow: 0 25px 60px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.05); + backdrop-filter: blur(12px); + max-width: 520px; + width: 100%; + color: #f8fafc; + display: flex; + flex-direction: column; + overflow: hidden; + animation: csFadeIn 0.25s ease-out; +} + +@keyframes csFadeIn { + from { opacity: 0; transform: scale(0.97); } + to { opacity: 1; transform: scale(1); } +} + +.cs-login-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px 16px 24px; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); +} + +.cs-login-org-brand { + display: flex; + align-items: center; + gap: 12px; +} + +.cs-login-icon { + width: 42px; + height: 42px; + border-radius: 10px; + background: var(--color-primary); + display: flex; + align-items: center; + justify-content: center; + color: #ffffff; + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.35); +} + +.cs-login-logo { + max-height: 38px; + max-width: 140px; + object-fit: contain; +} + +.cs-login-org-name { + font-size: 16px; + font-weight: 700; + color: #ffffff; + margin: 0; + line-height: 1.2; +} + +.cs-login-sub { + font-size: 11px; + color: #94a3b8; + margin-top: 2px; +} + +.cs-login-lang-select { + display: flex; + align-items: center; +} + +.cs-select-sm { + padding: 4px 8px; + font-size: 11px; + background: #0f172a; + color: #f8fafc; + border: 1px solid #475569; + border-radius: var(--radius-sm); + cursor: pointer; +} + +.cs-login-body { + padding: 22px 24px; +} + +.cs-login-welcome h2 { + font-size: 18px; + font-weight: 600; + color: #f8fafc; + margin: 0 0 4px 0; +} + +.cs-login-welcome p { + font-size: 12px; + color: #94a3b8; + margin: 0 0 18px 0; + line-height: 1.4; +} + +.cs-login-error { + color: #f87171; + font-size: 11px; + margin-top: 6px; + font-weight: 500; +} + +.cs-network-list { + display: flex; + flex-direction: column; + gap: 8px; + max-height: 200px; + overflow-y: auto; + margin-top: 6px; +} + +.cs-network-card { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 14px; + background: rgba(15, 23, 42, 0.6); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: var(--radius-md); + cursor: pointer; + transition: all 0.15s ease; +} + +.cs-network-card:hover:not(.unsupported) { + background: rgba(37, 99, 235, 0.12); + border-color: rgba(59, 130, 246, 0.4); +} + +.cs-network-card.selected { + background: rgba(37, 99, 235, 0.2); + border-color: #3b82f6; + box-shadow: 0 0 0 1px #3b82f6; +} + +.cs-network-card.unsupported { + opacity: 0.55; + cursor: not-allowed; + background: rgba(15, 23, 42, 0.3); +} + +.cs-network-icon { + flex-shrink: 0; +} + +.cs-network-info { + flex: 1; + min-width: 0; +} + +.cs-network-name { + font-size: 13px; + font-weight: 600; + color: #ffffff; + line-height: 1.2; +} + +.cs-network-desc { + font-size: 11px; + color: #94a3b8; + margin-top: 2px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.cs-network-badge-warn { + display: inline-block; + font-size: 10px; + color: #fbbf24; + margin-top: 3px; +} + +.cs-network-radio { + flex-shrink: 0; +} + +.cs-btn-lg { + padding: 10px 16px; + font-size: 13px; + font-weight: 600; + border-radius: var(--radius-md); +} + +.cs-login-footer { + padding: 12px 24px 16px 24px; + background: rgba(15, 23, 42, 0.4); + border-top: 1px solid rgba(255, 255, 255, 0.06); + text-align: center; +} + +.cs-login-disclaimer { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + font-size: 11px; + color: #cbd5e1; + line-height: 1.3; +} diff --git a/src/index.html b/src/index.html index 52b6792..0f14b79 100644 --- a/src/index.html +++ b/src/index.html @@ -17,8 +17,8 @@
- -
+ +