Skip to content

feat(jit): Add JIT role templates and restricted role access - #101

Open
TecharyJames wants to merge 7 commits into
CyberDrain:devfrom
TecharyJames:jit-role-permissions
Open

feat(jit): Add JIT role templates and restricted role access#101
TecharyJames wants to merge 7 commits into
CyberDrain:devfrom
TecharyJames:jit-role-permissions

Conversation

@TecharyJames

Copy link
Copy Markdown
Contributor

Introduce JIT Role Templates allowing admins to define allow-lists of Entra directory roles that users can see in the JIT roles list.

Backend: new Get-CIPPJITAdminAllowedRoles helper and HTTP entrypoints to Add/Edit/List/Remove templates and ListAllowedRoles; store AllowedRolesTemplate on CustomRoles and enforce restrictions in ExecJITAdmin and ListJITAdmin (fails closed).

Frontend: new pages, table, form, CippJitRoleTemplateApply component, and use-jit-allowed-roles hook to limit UI options.

Docs/summary updated.

Ensures restricted callers can only view/assign permitted roles

Introduce JIT Role Templates allowing admins to define allow-lists of Entra directory roles. Backend: new Get-CIPPJITAdminAllowedRoles helper and HTTP entrypoints to Add/Edit/List/Remove templates and ListAllowedRoles; store AllowedRolesTemplate on CustomRoles and enforce restrictions in ExecJITAdmin and ListJITAdmin (fail-closed semantics). Frontend: new pages, table, form, CippJitRoleTemplateApply component, and use-jit-allowed-roles hook to limit UI options. Docs/summary updated.

Ensures restricted callers can only view/assign permitted roles.
Change Get-CIPPJITAdminAllowedRoles to use restrictive semantics that match CIPP: admin/superadmin remain unrestricted; untemplated custom roles represent the universal set and do not loosen access; if a caller holds any templated custom role the allowed-role list is the intersection of those templates. Fail-closed behavior added (unreadable template/role contributes an empty set). Update documentation pages to describe the new semantics.
@fzmindcore

Copy link
Copy Markdown

Thanks for this James, this is looking exactly like what I requested. Looking forward to seeing this merged!

commit 256f04bc3a74919247eb36ae6f8ea10a361254bf
Merge: e436d19a e9e919d1
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 15:41:07 2026 +0200

    Merge pull request #175 from CyberDrain/dependabot/npm_and_yarn/frontend/dev/apexcharts-6.6.1

    chore(deps): bump apexcharts from 5.16.0 to 6.6.1 in /frontend

commit e436d19a6d21fc7bf1da72c296c40eb45adc4384
Merge: b4e58ace 965c8177
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 15:40:50 2026 +0200

    Merge pull request #174 from CyberDrain/dependabot/npm_and_yarn/frontend/dev/multi-4147e2cc44

    chore(deps): bump @tiptap/pm and @tiptap/core in /frontend

commit b4e58acef57333f4a50b851551e366f7925e1747
Merge: 3518bd2a e2837983
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 15:40:34 2026 +0200

    Merge pull request #191 from TecharyJames/feat-set-custom-font

    feat(standards): add SetDefaultMailboxFont Exchange standard

commit 3518bd2ac1696c3aa66f67900fa4b4ee08cb7072
Author: John Duprey <jwd@johnwduprey.com>
Date:   Fri Aug 7 09:29:48 2026 -0400

    feat(scheduler): add PSA ticket strategy selector

    Adds a 'PSA Ticket Strategy' dropdown to the scheduler form that appears when PSA is selected as a post-execution action. The dropdown offers 'one ticket per affected user' or 'one consolidated ticket per tenant', with the current HaloPSA integration default highlighted. The stored strategy is restored when editing existing tasks.

    Also reformats the file from double-quotes to single-quotes (style normalization).

commit a6f683da2f3da802f8a2e8bf6f8ac26c433a8334
Merge: d57512f1 55d4edc3
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 14:52:24 2026 +0200

    Merge pull request #210 from CyberDrain/preview/new-setup-gate

    feat(setup): gate app behind setup wizard until SAM configured

commit 55d4edc32fdeeb6e9a031fb133961a4405cc85d1
Merge: c285d35c d57512f1
Author: John Duprey <jwd@johnwduprey.com>
Date:   Fri Aug 7 08:46:13 2026 -0400

    Merge remote-tracking branch 'origin/dev' into preview/new-setup-gate

commit d57512f17faab9be0b79fcd6799c5e38613e36e5
Merge: 7bf3b0ba fa70e3a8
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Fri Aug 7 14:40:48 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 7bf3b0babce8006132ad4f031443f91ceb223d1d
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Fri Aug 7 14:40:42 2026 +0200

    feat: add recently added Intune devices  to BEC report

commit fa70e3a82fd676103ecc2baa75f14443456bb350
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 20:38:19 2026 +0800

    fix(auth): throw on auth policy read failure

    Change `Set-CIPPAuthenticationPolicy` to throw when current policy state cannot be read instead of returning a string, so remediation failures are no longer reported as successful writes. Also capture the standard remediation call result with `$null = ...` to prevent output-stream leakage and keep remediation logging aligned with actual PATCH success.

commit 774848c38e84a21fb34ccf9442d56c778ce1b3ac
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 20:35:47 2026 +0800

    fix(standards): default auth method to all_users

    When an authentication method is enabled but no included users/groups resolve, the standard now sets `GroupIds` to `all_users`. This prevents enabled methods from being saved without a target scope and keeps behavior consistent with tenant-wide enforcement.

commit 103fd7f75e3cd9ca03f13833b9f4d0dadfb979bb
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 14:02:22 2026 +0200

    clean on empty for baseline checking.

commit ff9aebc0c82dd848fdf31b906716dbe99a3f07b6
Merge: 42e69740 268a7ad7
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 13:47:25 2026 +0200

    Merge branches 'dev' and 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 42e69740cbe98dbb868a0079640172c8ca2e0206
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 13:29:01 2026 +0200

    baseline deletes

commit 268a7ad7aa781590272fbf491f5522d777a5f5f6
Merge: 2e704636 6b56bbe9
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Fri Aug 7 13:11:12 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 2e704636a39bea67c96f1d5332de74ff5129d183
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Fri Aug 7 13:11:06 2026 +0200

    refactor: update cache name for OneDrive usage reporting

    Changed cacheName from 'Sites' to 'OneDriveUsage' and updated syncData type to 'OneDriveUsage' for improved clarity and consistency in the OneDrive usage report functionality.

commit 6b56bbe9ca7a01feaa5dae423c563d3a8982fa8a
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 19:00:17 2026 +0800

    fix(mcp): improve tool search, serialisation and protocol handling

    - Filter known MCP client IDs from API auth so frontend doesn't report unsaved changes
    - Fix SearchTools tiebreaking to prefer closest-length match over alphabetical
    - Inline input schemas when search returns ≤3 results to save a GetToolInfo round trip
    - Add suggestions when SearchTools finds no matches (prefix stemming)
    - Fix ConvertTo-Json pipeline unrolling that changed JSON shape by row count
    - Refuse JSON-RPC batch requests (removed in MCP 2025-06-18) with 400 instead of mangling ids
    - Return empty string body for JSON-RPC notifications instead of 'null'
    - Echo back only supported protocol versions during initialize handshake
    - Propagate parameter descriptions to MCP input schemas
    - Fall back to first description line when summary equals the endpoint name
    - Log unknown connector tag names with known alternatives
    - Surface near-match suggestions when ExecTool receives an unknown tool name
    - Report truncated names in GetToolInfo when >20 are requested
    - Add OpenAPI spec test: mutation-verb or ReadWrite endpoints must not be GET
    - Add Pester tests for array shape consistency across row counts

commit 8f1fe2a356ff000df98d8c0bb3d1d8291edf9fe4
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 12:26:25 2026 +0200

    updated api docs

commit c2fba95975097ade897295360a55f120169edb77
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 12:01:41 2026 +0200

    make DCR work fully - Automated onboardings are now possible using the MCP

commit e95cb082d37136ad654ff24e4d5e09240dcc0049
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 11:38:13 2026 +0200

    DCR autodiscovery scope

commit 6eb1c2abdee534c252130a79c3108f84a2797827
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 10:57:27 2026 +0200

    spacing?

commit 5bf47b5f33b49ddb11ec07e2c98459343203e534
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 16:21:28 2026 +0800

    fix(api): use NormalizedError so failures show their message

    Get-CippException returns a NormalizedError property, but these call
    sites read NormalizedMessage, which does not exist. Every one produced
    an error string that ended at the colon with nothing after it, e.g.
    "Failed to add app template: ".

commit fd182bd6567c252bdc968e037cb6e5719313bdfe
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 14:55:07 2026 +0800

    fix(openapi): serve spec as static asset

    Move API docs loading from /api/ListOpenApiSpec to /openapi.json, remove the ListOpenApiSpec endpoint, and wire Docker/appsettings so the generated spec is copied and served as a precompressed static file. Update build-openapi to emit a frontend public copy, improve HTTP method inference (POST for mutations, GET for query-capable reads), and refresh tests/spec output to match the new contract and tagging behavior.

commit 7274ce0ee87efe301da2dd77a66e0b54d85a6ea5
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 14:19:41 2026 +0800

    fix: correct pester test pathing

commit 9c45c6aba527341450dcea7ac5d255f7cdf2e17b
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 14:18:39 2026 +0800

    chore: move http files into correct nested folders

commit 26bdfda841c67a764edf1588f740c8b8ecc88e20
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 14:06:43 2026 +0800

    fix(openapi): narrow Graph field claims to proven projections

    The generator was documenting the full Graph entity type for every List endpoint, which was measurably wrong (e.g. ListSharedMailboxAccountEnabled documented 90 fields but returned 8).

    This commit:
    - Distinguishes 'graph' (proven: endpoint selects or reshapes fields) from 'graph-entity' (unproven: pure passthrough) in x-cipp-field-source
    - Uses BackendFields as the field authority when the endpoint reshapes the Graph response itself
    - Adds Get-OutputMemberName to extract Add-Member/Sort-Object/Where-Object -Property spellings and use them to correct field casing without inventing new fields
    - Removes explicit additionalProperties: true from open response records; open-by-omission has the same JSON Schema semantics but avoids the Swagger UI 'additionalProp1' placeholder

commit 6e4c328a28a4418dcdee411c3040d9a38bc79b63
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 14:06:10 2026 +0800

    refactor(email): migrate TenantAllowBlockList to report DB

    Replaces the legacy per-tenant activity trigger orchestration with a shared helper (Get-CIPPTenantAllowBlockListItems) that batches all four list types in a single ExoBulkRequest. Introduces Get-CIPPTenantAllowBlockListReport to serve cached results from the reporting DB. The HTTP endpoint now supports UseReportDB=true and routes AllTenants requests through the report DB by default. The frontend gains a ReportDB toggle via useCippReportDB, AllTenants layout support, and conditional Tenant column. Also fixes Select-Object property-casing bugs in ListMailboxes and ListMailboxCAS.

commit d457da7a8c0ebc706a7d1168f80b774cf93b1ddc
Author: John Duprey <jwd@johnwduprey.com>
Date:   Fri Aug 7 01:46:49 2026 -0400

    fix: eliminate dark-mode flash on initial load

    Replace react-media-hook with a custom useSystemPrefersDark hook that uses useLayoutEffect so the dark/light state is resolved before the browser paints, removing the visible light flash for dark-mode users.

    Add a pre-paint inline script in _document.js that reads localStorage and prefers-color-scheme to immediately set the correct background and hide the stale light SSR prerender until React hydrates.

    Default theme changed from hardcoded 'light' to 'browser' (follows OS preference). Theme toggle now reads the active MUI palette mode instead of the stored value, so it works correctly when the browser default is active.

commit c285d35c2e651bea0c3e279e986bcf841f857ee8
Author: John Duprey <jwd@johnwduprey.com>
Date:   Fri Aug 7 01:15:17 2026 -0400

    feat(keyvault): add CIPP_KV_NAME env override

    Allow explicit Key Vault name via $env:CIPP_KV_NAME for self-hosted or renamed deployments. The override is used verbatim, skipping all name derivation logic.

commit 662a9c8939a53ba375d2cf431f4588d7ac2316c5
Author: John Duprey <jwd@johnwduprey.com>
Date:   Fri Aug 7 01:04:16 2026 -0400

    fix(setup): handle soft-deleted Key Vault secrets on re-setup

    When a CIPP instance is reset, SAM secrets are deleted but remain soft-deleted during the retention window. Re-running setup would hit a 409 conflict because Key Vault reserves the name. This fix recovers the soft-deleted secret and retries the write, polling until Key Vault makes the name live again (up to 60 s).

    Also improves error surfacing in both Set-CippKeyVaultSecret and Invoke-ExecCreateSAMApp so the actual Key Vault/Graph error body is shown rather than just the HTTP status line.

commit 0f48b3971d798ebc3b150f0830606b09d7ef139a
Author: John Duprey <jwd@johnwduprey.com>
Date:   Fri Aug 7 00:46:22 2026 -0400

    feat(setup): add popup-blocked/closed handling and SetupGate stories

    - Fail fast with a clear error when the browser blocks the M365 auth popup
    - Detect popup closure and report popup_closed after a 2s grace period (avoids stuck 'Authenticating...' state on manual close)
    - Add resultReceived guard so a real auth result is never overridden by the closure watcher
    - Clear stale in-memory query cache on SetupGatePage mount, not just localStorage
    - Add Storybook mock for CIPPM365OAuthButton (resolveId plugin in main.mjs)
    - Add comprehensive SetupGatePage stories covering all wizard steps and error paths
    - Add vitest unit tests for the three new popup-flow branches
    - Fix chromium /dev/shm exhaustion in dockerized browser test runs

commit 7e56f6b514f893179d7954bde9c41112885a05d5
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 12:19:47 2026 +0800

    fix(openapi): avoid fake response fields

    Stop emitting explicit `additionalProperties: true` in generated object response schemas so Swagger UI no longer invents `additionalProp1` fields in examples. Also add a diagnostic script that compares documented OpenAPI response fields against live `List*` endpoint output to catch casing and schema drift that static inference can miss.

commit 8d9e8d5041d8f0ddd3ddbcabb8b1c64c7c7fbd05
Author: John Duprey <jwd@johnwduprey.com>
Date:   Thu Aug 6 23:40:36 2026 -0400

    feat(setup): gate app behind setup wizard until SAM configured

    Adds a first-run blocking gate driven by a new `initialSetupComplete` flag from `/api/me`. Admins see the setup wizard full-screen; non-admins see a hold page that polls until setup is done.

    - Backend: `Test-CIPPAccess` computes `initialSetupComplete`/`samAppPresent` from env vars with per-worker reload throttle; removes the old alerts-based setup check
    - `Invoke-ExecListAppId`: stop overwriting env vars with null/error strings on failure
    - Frontend: `PrivateRoute` renders `SetupGatePage` or `SetupPendingPage` based on role; removes the old `Layout` alert+dialog approach
    - `OnboardingWizardPage`: accepts `mode`/`samAppPresent`/`completionButton` props to filter options and show an 'Enter CIPP' button on completion
    - `ForcedSsoMigrationDialog`: reads `initialSetupComplete` from `/api/me` directly instead of via prop
    - Tests updated to cover the new gate behaviour

commit 3b456c82fed548d639b462147971ca865995a91a
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 02:08:02 2026 +0200

    app settings updates so we dont have to publish new image again

commit 3155b01e457d72ba87e945ea0010cdb15a9f4748
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 01:33:37 2026 +0200

    PRM updates.

commit 3d60b4025033052224987ca026430077a931ad19
Merge: 4db5419b a5cd5d66
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 01:21:44 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 4db5419ba095680f3d08ab8557ee8de99e93d03d
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 01:21:41 2026 +0200

    new CA drift for baselines

commit a5cd5d66c80df15efd72cc82a728b3aa67af6c8f
Author: John Duprey <jwd@johnwduprey.com>
Date:   Thu Aug 6 18:48:06 2026 -0400

    fix(drift): guard stale-row pruning against partial batch failures

    Graph $batch returns HTTP 200 even when individual sub-requests fail (e.g. 429 throttling), silently dropping policy types from the collection. Previously this caused decided drift rows (Accepted, Denied*, CustomerSpecific) to be pruned and reappear as 'New' on the next run.

    - IntunePoliciesCollected / CAPoliciesCollected are now false when any batch item returns ≥400
    - Standards-type rows are only pruned when their Status is null or 'New'; decided rows are retained across transient key-enumeration drops
    - Template-scoped runs never prune (they cannot see every valid key)
    - Tests refactored to use a shared Get-CIPPAzDataTableEntity mock and extended to cover all new pruning rules

commit 25f2bd4350c480211402afc0ebca0d32140333f8
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 7 00:18:07 2026 +0200

    SMB1001 tag

commit ccaf02ec90bdfb4b8d51da5f6ef83b57c66dca4a
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 23:36:37 2026 +0200

    one more standard

commit 06cb796325c65e360f518a57af80bbf4fc6acda9
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 23:36:20 2026 +0200

    fixes standards helptext, applies to, etc.

commit 09ac354df30b2f654578670e8a47563fcdbd6e9e
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 22:34:04 2026 +0200

    DCR flow

commit 98a3409d5fc77a6e48c2d238c9f0d39cf8ed7489
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 19:29:19 2026 +0000

    GITBOOK-609: Tools Refresh

commit 3f4fc6e99afafefe9ddf196feee7893409e1d10c
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 03:27:17 2026 +0800

    feat(api): add OpenAPI docs and Graph schema

    Add two new CIPP core endpoints to serve the generated OpenAPI spec and resolve Microsoft Graph response schemas from vendored CSDL metadata, with tests for schema resolution and inheritance handling. Update the OpenAPI generator and Docker build flow to consume vendored Graph metadata and improve inferred list response schemas from Graph and Azure Table sources. Also add an in-app Swagger UI documentation tab for the CIPP API integration and keep MCP tool catalog output focused by excluding the raw spec endpoint.

commit c7bb4ef39cd8e5a2aea1785cb17a9d0efc43f15b
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 21:14:45 2026 +0200

    Custom PRM endpoint

commit 6bd768ac449ca6a4aaff162092baf0273bb314d9
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 02:02:46 2026 +0800

    feat(api): describe list responses from the endpoint source

    The spec said what a caller must send but almost nothing about what came back:
    of 386 data endpoints only 98 had a typed record, and the rest were an open
    object. For MCP that is the expensive gap - the model runs a tool and cannot
    predict the shape, so it spends a call finding out.

    Response fields were previously taken only from the frontend's simpleColumns,
    which describe what one page chose to render rather than what the API returns,
    and are absent entirely for endpoints no table renders. The generator now also
    reads the entrypoint: literal Select-Object property lists, calculated
    properties (@{ Name = 'primDomain'; Expression = {...} }) and [PSCustomObject]
    literals all name their fields outright. Both sources are merged and recorded
    separately in x-cipp-field-source, so a surprising field can be traced back.

    Records reached through an alias ($response = $GraphRequest) or a Results
    envelope are followed two hops, and every return path contributes, since an
    endpoint's cached, AllTenants and placeholder branches can each carry a
    different shape.

    Also fixes Test-ResultsEnvelope, which scanned the whole function and so read an
    error branch as the contract: a list endpoint that rejects a bad argument with
    Body = @{ Results = '...' } was documented as an action endpoint returning
    StandardResults. It now ignores branches with a literal 4xx/5xx status. That had
    silently reclassified 10 list endpoints, ListGroups among them.

    Typed records 98 -> 257; list endpoints wrongly typed as actions 32 -> 22.

commit c21c5a8e15857b0e957708c78ad0313b9dee609e
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Thu Aug 6 12:54:29 2026 -0500

    docs: Clean Up Unused Reusable Content from Repo

commit 73cd6a95428850c87b39d0f3ee2d02150f81a7c0
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 01:42:45 2026 +0800

    feat(mcp): add OpenAPI generator and MCP safety improvements

    Adds build/tools/build-openapi.ps1 — a PowerShell AST-based OpenAPI 3.1 generator that replaces regex scanning. Key improvements:

    - Correctly types fields read as `$Field.value` as LabelValue objects instead of plain strings (the root cause of silent null failures)
    - Follows request bodies into downstream helpers (Set-CIPPUser etc.) to recover fields not visible in the entrypoint
    - Adds Get-CippMcpSafePropertyName to rename OData options ($filter → odata_filter) so MCP client schemas stay valid
    - Fixes Invoke-CippMcpApiRequest to unwrap { Results, Metadata } envelopes and reverse parameter aliases on dispatch
    - Adds CI workflow to detect spec drift on PRs
    - Adds openapi-overrides/ for endpoints whose contract cannot be statically derived
    - Regenerates openapi.json from the new generator
    - Adds Pester test suites for the generator, projection, and gateway

commit ff04b418c80a21bb763d503b356a83f4552dece8
Merge: da8185c2 ccf4651f
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 19:34:57 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit da8185c2153bb225f68bd271234f43126acdccd6
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 19:34:54 2026 +0200

    auth mcp stuff

commit ccf4651fff1916e799d340b7acb48fc449034777
Merge: 344308ec 549307f2
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 01:11:28 2026 +0800

    Merge pull request #206 from CyberDrain/maa-drift-fixes

    feat(intune): handle MAA approvals and drift

commit 549307f26ae812c57e5ec2eeebd986ef5e6a906c
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 7 01:10:53 2026 +0800

    feat(intune): handle MAA approvals and drift

    Add end-to-end Intune multi-admin approval support: new approval-requests API and UI page, a scheduled alert for pending approvals, and retry orchestration that resubmits protected writes after approval.

    Refactor Intune assignment handling to keep checks and remediation aligned by introducing shared assignment-target helpers, richer assignment comparison output, App Protection URL/type resolution, and stricter error propagation in policy assignment. Standards now re-check assignments after remediation and report actionable mismatch reasons. Includes broad new Pester coverage for assignment logic, App Protection resolution, and standards/remediation behavior.

commit 344308ecd3b24cad0c9d98199b39d832ad683e27
Merge: 6773c769 9588e48e
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 18:54:30 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 6773c7697914be99f7ed86ea13e4405c9b5463b6
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 18:51:53 2026 +0200

    Multi step MCP usage with tool discovery, allowing old tools to work too

commit 9588e48e00f7517d9fe5a8f33c15e1e15b8243ab
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 16:46:29 2026 +0000

    GITBOOK-608: Location Details

commit e27f1d288928937a5c6e60369d9a7975f4d0ac6c
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 16:33:09 2026 +0000

    GITBOOK-607: Identity Refresh

commit 4f89a99b22419ed7abad90100077dcdaf5b762f9
Merge: 4a362100 6067fbc1
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 6 18:11:32 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 4a3621007311da18d53c67f1ec28ca437ed3d7f8
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 6 18:11:27 2026 +0200

    refactor: update JSON conversion for identifier URIs in API config scripts

    Enhanced the New-CIPPAPIConfig and Repair-CippApiIdentifierUri functions to include JSON conversion with compression for the identifier URIs, improving data handling efficiency.

commit 0bca7b97afe30d59577eb05f7420b71477189061
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 6 18:11:11 2026 +0200

    fix: load SAM cert with OS-specific key storage flags

    Avoid the Exportable fallback that fails on Windows Functions workers without a user profile ("The system cannot find the file specified"), and pick EphemeralKeySet vs MachineKeySet from the host instead of try/catch.

commit 6067fbc1cdb661fbf0b72638daa02f4b5d97a626
Merge: 6cf38f82 9e752584
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 17:46:18 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 6cf38f8253c1d0761f3f4700e8f3d49aab8bc0d9
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 17:46:16 2026 +0200

    fixes in layout

commit 9e752584c8f14c0cc4ef798a5066a69375625a90
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Thu Aug 6 23:35:44 2026 +0800

    refactor(markdown): drop table hyphenation helpers

    Remove `splitLongToken` and `createTableCellHyphenation` from the markdown table utility, along with their dedicated unit tests. This narrows the module and test suite to parsing, normalization, and cell escaping behavior only.

commit 31f22660321beb8aa10bdf59723bf4680ea24c6d
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Thu Aug 6 23:30:38 2026 +0800

    feat(reports): centralise PDF branding into one shared kit

    Every client-facing PDF drew itself: six reports carried six covers, three
    carried their own stylesheet, and four ignored the footer, watermark and cover
    note entirely. A report now supplies its content and nothing else — ReportDocument
    supplies the theme, styles, cover and page furniture.

    Reports are content only. 3,097 lines net removed across the six. None of them
    declares a stylesheet, a theme, a raw <Page>, or names a style; the report builder
    keeps the sheet from context because it renders arbitrary Markdown.

    Branding gained named colour roles. Charts, headings, body, subtitles, footer,
    info cards, data tables, cover text, infographics and the watermark can each be
    set, and each falls back to the brand colour — an install that set only a colour
    renders exactly as before. Presets can be created, renamed, cloned and assigned
    per report type, and a live preview renders the real reports against sample data.

    Fixes found on the way:
    - footer laid out to nothing (absolute box with no stated height)
    - page numbers never painted (inherited lineHeight compounds across relayouts)
    - watermark drawn under content, so chart cards hid it
    - DataTable sized columns with flex, putting every row on its own grid
    - long values overflowed their column; react-pdf's only mid-word break draws a
      hyphen, so they are now broken at a width measured against Helvetica's metrics
    - a global "never hyphenate" registered by one report silently governed all of them

    Page setup keeps only paper and branding. Cover, footer and watermark overrides
    are gone from templates: they let a template contradict the preset it pointed at.
    Stored keys are ignored rather than migrated.

commit 4cfbe0027e2a6d8617146044a27cc7dea22523b0
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 16:43:09 2026 +0200

    add isFetching for loading skeleton

commit f324745a229b1c865e693ffc7e4eefd69c9bc604
Merge: 572edbdc a6f5bef8
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 16:42:49 2026 +0200

    Merge pull request #200 from Jr7468/dev

    feat: Add recent and favorite tenants to the tenant selector

commit a6f5bef84405c09aa06582a380a7976d1853f06f
Merge: 62f33dad 572edbdc
Author: Jr7468 <126574444+Jr7468@users.noreply.github.com>
Date:   Thu Aug 6 15:34:40 2026 +0100

    Merge branch 'dev' into dev

    Signed-off-by: Jr7468 <126574444+Jr7468@users.noreply.github.com>

commit 572edbdcb1a1d2b573a1a47ec842665b8431822a
Merge: 4513e456 aed4abab
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 16:32:13 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 4513e45651baabe5a7368a61126aca26cf23e365
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 16:32:10 2026 +0200

    intune fixes verification baselines

commit aed4abab7e3c87d951c189896672940dc12c157c
Merge: 1fbc0e80 935b5747
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 16:29:27 2026 +0200

    Merge pull request #168 from jspern/feat/top-menu-picker-qol

    feat(tenant-selector): keep current tenant visible in the nav dropdown list

commit 1fbc0e8059a53c13a087e0119826932f104f06c5
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 15:36:24 2026 +0200

    compare fixes for intune and baseline caching for CA policies with hard compares vs soft

commit 62f33dade2a07a053114567da4fd17b0a47c3ea7
Author: Jr7468 <126574444+Jr7468@users.noreply.github.com>
Date:   Thu Aug 6 13:58:28 2026 +0100

    Enhance CippTenantSelector with favorites and grouping

    Refactor tenant selector to include favorites and recent tenants, and improve option grouping.

    Signed-off-by: Jr7468 <126574444+Jr7468@users.noreply.github.com>

commit d807aad9c59e5cf53a9ecbd94069039cb0e59b94
Author: Jr7468 <126574444+Jr7468@users.noreply.github.com>
Date:   Thu Aug 6 13:57:59 2026 +0100

    Add useTenantPreferences hook for tenant management

    Implement a custom hook for managing tenant preferences, including recent and favorite tenants.

    Signed-off-by: Jr7468 <126574444+Jr7468@users.noreply.github.com>

commit e20f47f1d5269210cec4369905a82c3cb62f5ca4
Author: Jr7468 <126574444+Jr7468@users.noreply.github.com>
Date:   Thu Aug 6 13:57:22 2026 +0100

    Add tenant preferences utility functions

    Signed-off-by: Jr7468 <126574444+Jr7468@users.noreply.github.com>

commit 72865e2b6199a905c1947df2742a5602a2b37f94
Merge: 128eacd1 93781432
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 12:47:27 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 128eacd19a0ef78012891f855adb656bd45a7fbd
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 12:47:24 2026 +0200

    improvements to intune standards and caches

commit 93781432c18387893dff519c61a5e6fadd5563b6
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 04:37:52 2026 +0000

    GITBOOK-606: Halo AutoMapping

commit 839d5b11a4949bba1e9c242e218ef5c31bdd6bbe
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 04:17:31 2026 +0000

    GITBOOK-605: Dashboard Refresh

commit aee53d8a8c61f00717e0649d61c1bce263dac26d
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 03:45:27 2026 +0000

    GITBOOK-604: Shared Features Refresh

commit 53bc355c9be80037fa128dcbb291a66ac01385af
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 03:01:40 2026 +0000

    GITBOOK-603: Breadcrumbs Updates

commit 23abe3f4305584eb82ebb8bc65eecac33d3f470a
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 02:44:01 2026 +0000

    GITBOOK-602: Table Behavior Updates

commit 24af9b60c0080b1aa49e9fbf4bee855669779688
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 02:07:51 2026 +0000

    GITBOOK-601: Feature Requests Footer Cleanup

commit 8f134b6a91525155d7dec07dab9e656556d630e4
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Thu Aug 6 01:11:41 2026 +0000

    GITBOOK-600: Tenant Administration Refresh

commit 5e7827aa93f7e666b519e8b93f11cdc8717eccd4
Merge: d1382e8a 08b6d600
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 01:19:57 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit d1382e8a47b43144abdd626cbc6331675c1876f6
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 01:19:55 2026 +0200

    new intune baselines and comparison

commit 08b6d6000c19deaeebcc31b9d8af3ad9b2e63543
Merge: 2c766b94 45856341
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 6 00:49:17 2026 +0200

    Merge pull request #195 from CyberDrain/fix/recommended-roles-doc-links

    fix: update Recommended Roles doc links to maintaining-cipp path

commit 2c766b941e20e1d2f04853c5fb3cd6c9e75d46d9
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 18:19:10 2026 -0400

    feat(identity): use unified RBAC API for roles listing

    Replace the legacy /directoryRoles endpoint with the unified RBAC API (roleManagement/directory) so all role definitions — including unactivated built-in and custom roles — are returned.

    - ListRoles: fetch definitions + assignments separately, resolve principals via getByIds bulk call, group members by role definition
    - ExecRemoveAdminRole: accept roleTemplateId and use directoryRoles(roleTemplateId='...') lookup when provided; add helpful error hint when role is not activated
    - Frontend: pass roleTemplateId in remove action payload; hide remove button for custom roles (no templateId); expose isBuiltIn field in table and off-canvas

commit 2226711cc6ad02cdf6e77976f85a40dddd657dbc
Merge: f2f94716 fe6e1854
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Wed Aug 5 23:49:08 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit f2f947168981c3ef95120545587f17d30d519af0
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Wed Aug 5 23:48:59 2026 +0200

    feat(MEM): add tenant-scoped BitLocker key search page

    Adds /endpoint/MEM/bitlocker-search so recovery key lookups can use the
    selected tenant filter instead of only Universal Search's all-tenant path.

commit fe6e1854f82b673a98a15422d06faf9b50b30116
Merge: a6d3c713 b17044b5
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 23:35:31 2026 +0200

    Merge pull request #196 from samirp91/fix/copilot-imagegeneration-value-inversion-dev-cyberdrain

    fix(standards): correct inverted value labels for CopilotSettings.imageGeneration

commit a6d3c713e81211f2436f72b2c558b89a7fbcd418
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 17:17:48 2026 -0400

    fix(sam): activate missing directory roles on 404

    When a directory role returns 404 during bulk assignment, it means the role template was never activated in the tenant. This change now activates the role from its template and then adds the service principal, instead of silently skipping it.

commit 506113b6924966377f6756af7f79e3ad9daae32b
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 17:12:51 2026 -0400

    fix(stats): detect SSO complete from live EasyAuth config

    When SSO is provisioned at the ARM level during NG migration (outside the setup wizard), no migration table row is written. This causes the stats timer to incorrectly report SSO as incomplete.

    Now checks the live EasyAuth environment variables when the migration row is missing or references a different app ID, reporting SSO as complete — consistent with Invoke-ExecSSOSetup's Status action.

commit b17044b540527786fc9e1e998679ad5af08f4ffe
Author: Samir Patel <p.samir.p@gmail.com>
Date:   Wed Aug 5 17:04:37 2026 -0400

    fix(standards): correct inverted value labels for CopilotSettings.imageGeneration

    microsoft.copilot.imagegeneration's value semantics are inverted from the
    intuitive reading: "1" means Disabled, "0" means Enabled. The standard has
    this backwards ("1" = Enabled, "0" = Disabled), so selecting "Enabled" in
    the UI actually disables Designer image generation for the tenant, and
    vice versa.

    Matches the inversion documented at
    https://michev.info/blog/post/8089/the-sad-state-of-governance-apis-for-copilot-and-agent-365

commit 426c49f2b43fa14d09f534052ab5c6f62597fd81
Merge: 1b21d132 8413830a
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 22:50:49 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 1b21d132e8c1a61c479fd7aa0f5f78a859dce2e5
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 22:50:47 2026 +0200

    cache staleness improvements for CA, schema enhancements, etc.

commit 8413830a83e507ebba6c68b0e85b2a028d3ce871
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 15:52:07 2026 -0400

    perf(tests): fan-out per-tenant queries and add count API

    Replace full-table OData scans with per-partition queries to avoid estate-scale table scans. Add RowStatus, IncludeCounts, and AllowedTenantIds parameters to Get-CIPPTestResultsTenants so the API can return accurate aggregate counts without sending every row. Replace Add-Member loops with ordered hashtable construction for better performance.

    On the frontend, default the AllTenants view to Failed/Investigate rows only with a toggle to show all, and derive tile stats from server-side counts rather than client-side row aggregation.

commit c1498df83467a17cef73780f7d2fce650cd479db
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 15:35:59 2026 -0400

    ci: save PSScriptAnalyzer results to file

    Output PSScriptAnalyzer results to a text file for artifact upload or easier review in CI runs.

commit 458563417905e7459e1d01608fdd72b6a9e3a0b3
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 5 14:29:46 2026 -0500

    fix: update Recommended Roles doc links to maintaining-cipp path

    The Recommended Roles page moved from /setup/installation/ to
    /setup/maintaining-cipp/ in the docs. Updates the GDAP relationship
    page link and the four access-check issue links accordingly.

    Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

commit 4ad0727b3364968ec7464804abbf5d980172ea54
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 21:19:47 2026 +0200

    add standard conflict detection.

commit d0e5d8ea55b98cbbe99b1a1396db4ae67e9c30c6
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 20:53:47 2026 +0200

    new dev modules

commit 808f93385c2856092635b3c7ca473d0f2a8020b4
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 14:24:09 2026 -0400

    docs: add All Tenants view documentation

    Documents the All Tenants estate-wide views for the dashboard (Portfolio, Security Posture, Operations & Triage sections) and the Secure Score page (Tenant Overview and Table Overview tabs), including cache behavior notes.

commit 5368a2c0f5033acfa0d7f2c6a6b7335ba91ebfd8
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 14:12:38 2026 -0400

    feat(dashboard): add AllTenants views for secure score and test results

    Add cross-tenant secure score summary/table and test results views for Identity, Devices, and Custom dashboards when AllTenants is selected.

    - Extract suite-to-pattern map into Get-CippTestSuitePatterns (shared between collection and result labelling)
    - Add SummaryOnly projection to Get-CIPPTestResultsTenants to drop large blob columns on list reads
    - Add Suite label to stored test results via pattern matching
    - Add AllTenantsSecureScore components (summary with trend/leaderboards, table with per-tenant links)
    - Add AllTenantsTestResults component with lazy detail fetch per row
    - Replace 'Not supported' placeholders on secure score pages with real AllTenants views
    - Prevent live Graph calls in use-securescore.js when AllTenants is selected
    - Refactor deriveSecureScoreSummary into a shared export for reuse across dashboard and full-page views

commit e3a82f6d8cec4f66729505d4b46b3da14a3c83ec
Merge: f819554a 4da6c548
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 19:39:46 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit f819554a86628f016cdc43edd4610eae42b5837a
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 19:38:18 2026 +0200

    Naming baselines

commit 4da6c548b58bb4402af4cd58c793edcae5e9e8fe
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 12:38:04 2026 -0400

    feat(dashboard): add navigation links to portfolio tiles

    Replace the off-canvas collection totals on the Tenants tile with direct links to list pages. Portfolio bar tiles (Tenants, Users, Mailboxes, Managed devices) and stat tiles (logs, delegations, deviations) now navigate to their respective pages on click. Also adds a View button to the Mail hygiene card and removes the allTotals off-canvas data that is no longer needed.

commit 98c170f4ca6409f804da8c680fcff5dc0fbd4dff
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 12:11:02 2026 -0400

    fix: respect exclusions and cache TTL in drift/groups

    - Backend: evaluate TenantGroups cache expiry before checking the result cache so TTL is actually enforced instead of serving stale data forever.
    - Frontend: pass `excludedTenants` into `validateDrift` and subtract them from conflict checks, and add `watchForm.excludedTenants` to the effect dependency array so drift validation re-runs when exclusions change.
    fixes #78

commit a72490729c6d04179677d78b000fcd21563084f4
Merge: 3d57b6ff 75aab576
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 17:48:58 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 3d57b6ff9440d9099e9e694f7fe72d46f5f5843d
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 17:48:55 2026 +0200

    more conversions

commit 75aab576144705a94570e44b9f211667d18f0302
Merge: 5cfcd0ce 1020d413
Author: John Duprey <john@cyberdrain.com>
Date:   Wed Aug 5 11:40:51 2026 -0400

    Merge pull request #194 from CyberDrain/preview/new-error-state

    feat(error-pages): add CippErrorState component

commit 5cfcd0ce8fa9646d27908f2e6aa307b7e536d995
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 23:36:16 2026 +0800

    refactor: remove standard telemetry metadata

    Drops the unused metadata block from standard pushes while leaving execution behavior unchanged.

commit c009dbec013a1e587dc01e7d71dd3354fca38666
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 23:28:57 2026 +0800

    Update backend_pester.yml

commit af849c3629817db7610b7d9e05752a7c2bbc2f89
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 11:08:02 2026 -0400

    fix(breaches): add AnyTenant tag and fix formatting

    Add AnyTenant to the Entrypoint functionality tag and fix indentation of the HttpResponseContext return block. This fixes issues where users with tenant restricted roles are unable to perform a HIBP lookup.

commit 0b8447e7c3b78336f07380edd7b886149b667758
Author: Brian Simpson <brian@cyberdrain.com>
Date:   Wed Aug 5 14:19:44 2026 +0000

    GITBOOK-599: CIPP Settings & Advanced Menu Pages Rewrites

commit 782ddb24758285d1c9fd0435d372071cd6bbce78
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 22:16:15 2026 +0800

    ci cache fixes

commit dbc00d971d90d850c8e6455131ab98212b739d6f
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 22:08:40 2026 +0800

    CI check cron triggers

commit b44bde7925c53866afc465747201e177aec4f8fe
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 21:48:44 2026 +0800

    Update frontend_vitest.yml

commit 8143068f1a88ec43d1119f76feffc8eddae242fd
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 21:39:31 2026 +0800

    Update frontend_vitest.yml

commit 9d06aca85f62d84877a925bdccbd4a61d56b1248
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 21:37:45 2026 +0800

    ci: add automated test workflows for backend and frontend

    Add two new GitHub Actions workflows for continuous testing:

    - backend_pester.yml: Runs Pester unit tests on backend PowerShell code
    - frontend_vitest.yml: Runs frontend Vitest unit tests (split into fast unit tests and browser-based storybook tests)

    Both workflows trigger only on path changes and use concurrency controls to cancel previous runs. This ensures code quality checks run automatically on pull requests.

commit fcd9dac079ce382a8779b21c390418f6139be2d0
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Wed Aug 5 13:48:44 2026 +0200

    fix(applications): align Win32 MSP/Choco payloads with Graph detectionRules schema

    File-system detection omitted operator (notConfigured), and templates used returncode / string numerics that Graph rejects on create.

commit c92c91978b9eb077be09c7836c429ef4bd029ace
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 19:00:01 2026 +0800

    fix(standards): strip rawData before replacement

    Remove the template picker rawData snapshot before standards are round-tripped through JSON, and escape replacement values when substituting into serialized settings so quoted text no longer breaks parsing. Added coverage for text replacement, rawData stripping, tag expansion, and Push-CIPPStandard behavior.

commit e2837983d64be8bbc6ef7e04cb30e6dbf43b7435
Author: James Tarran <jtarran@techary.com>
Date:   Wed Aug 5 11:50:22 2026 +0100

    feat(standards): add SetDefaultMailboxFont Exchange standard

    Adds a new tenant standard that sets the Outlook on the web default
    compose font (name, size, colour) for all user and shared mailboxes
    via Set-MailboxMessageConfiguration.
    - Mailbox list from the CIPP DB cache, with a Get-Mailbox fallback so
      an empty cache reports as unknown instead of compliant
    - Reads current config per mailbox (batched, OperationGuid-correlated)
      and only writes mailboxes that differ, so steady-state runs are
      write-free
    - Report phase feeds alignment/drift with per-mailbox deviations as a
      JSON array, listing only the settings that differ; unreadable
      mailboxes block a compliant verdict
    - Font size validated as the 1-7 scale Exchange stores (3 = 12pt),
      colour as six-digit hex, both in the UI and the standard
    - Applies to OWA/new Outlook only; classic Outlook is documented as
      unaffected

commit 9b9564d2ce339e84992db9ae40bdc47f26e7635b
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 18:42:26 2026 +0800

    fix: enforce boolean flag comparisons in HTTP entrypoints

    Boolean request flags must be compared to $true/$false variables, not strings 'true'/'false', because the OpenAPI generator infers field types from code patterns. String comparisons cause the spec to type them as strings, shipping mistyped MCP tool contracts.

    Normalized booleans also must never be interpolated into strings (e.g., URLs or filters), since $false renders as 'False' when the parameter is absent, silently corrupting the request.

    Fixes:
    - Invoke-ListSites: use -eq $true instead of -eq 'true' (two occurrences)
    - Invoke-ListGroups: fix Graph URL that was passing 'groups//' instead of 'groups?' for list requests, adds explanatory comment

    New test (EntrypointBooleanFlags.Tests.ps1) validates these patterns across all HTTP entrypoints, catching regressions before they ship.

    Tooling: Updated build scripts to properly handle CIPPTests module during dev builds (copy contents to avoid directory nesting) and include it in the watch list.

commit 36d084ef0658631aca8e14a7ba3e5fb79fb096ee
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 12:33:42 2026 +0200

    compares now allow anyof

commit f0812cc13f70272fd15618492841acac7e7b7cd5
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 17:49:30 2026 +0800

    fix(scheduler): add OData injection protection and improve tenant filtering

    - Add ConvertTo-CIPPODataFilterValue for Id, Name, and Type parameters to prevent OData injection attacks
    - Move Type and TenantFilter filtering to query level (storage) instead of client-side for better performance and security
    - Improve tenant resolution to handle both customerId and defaultDomainName formats
    - Build HashSet for allowed tenant identifiers to efficiently check access control
    - Add tenant lookup to correctly resolve and display tenant domain names in results

commit ecd09d3770d015a9057c43c68da9ac0749c7c324
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 17:25:06 2026 +0800

    fix: normalize boolean query parameter handling across endpoints

    Standardize comparison of HTTP query and body parameters against boolean values instead of string literals. Replace `-eq 'true'` with `-eq $true` to prevent type coercion bugs and improve clarity. Extract boolean assignments into descriptive variables with clarifying comments. Add parameter validation to endpoints that require specific parameters. This resolves inconsistent boolean handling patterns across ~40 endpoints and improves code maintainability.

commit 4fae837ee9993f8bd82771ac832dcbf3f42e31f1
Merge: 22da4685 c77183f1
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 11:19:12 2026 +0200

    Merge pull request #185 from kris6673/feature-tag

    chore: Update feature request template to include feature tag

commit 22da4685bec6718859f431b77b70607a2ccd9e4c
Merge: 6d5f0cca 1b78f39c
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 11:18:53 2026 +0200

    Merge pull request #184 from kris6673/feat/intune-bios-password-retrieval

    Feat: Retrieve Intune-managed BIOS passwords

commit 6d5f0cca319529c9eb7e0495381e2e2a1676305e
Merge: dcfabc83 6f896dcf
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 11:17:08 2026 +0200

    Merge pull request #189 from k-grube/fix/storybook-dev-require-context

    test: fix storybook dev server rendering

commit dcfabc8327d6c5234ef2a1742546e3b7120f8a72
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 16:35:12 2026 +0800

    docs(http): add endpoint descriptions

    Add `.DESCRIPTION` metadata to many CIPP HTTP entrypoints so the generated API docs better explain what each endpoint does and how its key parameters behave. No functional behavior changed.

commit 1cc7cc8d170e31144fc1827ac41ab5a811dfd15e
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 16:07:56 2026 +0800

    test(dbc): add auto expanding archive state tests

    Add three test cases for Auto Expanding Archive handling in mailbox caching:
    - Per-mailbox archive state when org setting is unavailable
    - Organization-level setting overriding per-mailbox values
    - Graceful degradation when org config lookup fails

    Also add New-ExoRequest stub and import Get-CIPPAutoExpandingArchiveState helper to support these tests.

commit 051772b842fb9d6006886685ee8f9cacd9968176
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 16:05:43 2026 +0800

    fix(applications): improve path resolution and add exclude group

    - Fixed relative path issues by using $env:CIPPRootPath with Join-Path and -LiteralPath for robust file access
    - Added excludeGroup parameter support in Choco and MSP app deployments
    - Fixed potential object mutation issue in AddMSPApp by parsing template JSON per tenant instead of once globally
    - Added -Raw parameter to Get-Content for safer JSON parsing

commit 45eef74fd2cec51fe45ff819786868c2ebd11c9c
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 15:30:54 2026 +0800

    refactor(sharepoint): migrate to REST API with app-only auth

    Replaces CSOM/SOAP ProcessQuery with SharePoint REST API for site admin operations, using certificate-based app-only authentication instead of delegated (refresh token) auth.

    Benefits:
    - Removes dependency on GDAP holding SharePoint Administrator role in customer tenant
    - Aligns with other SharePoint permission endpoints that already use app-only auth
    - Improves reliability by eliminating 'Attempted to perform an unauthorized operation' failures

    Also:
    - Enhances input validation and normalization for OnedriveAccessUser parameter
    - Improves error messages and logging
    - Removes debug Write-Host output from HTTP endpoint
    - Changes result handling to array format for better multi-user operation rendering
    - Updates documentation comment in Restore-CIPPSPODeletedSite

commit 1020d413574714618dddd4a1336c0ac214c7f910
Author: John Duprey <jwd@johnwduprey.com>
Date:   Wed Aug 5 02:05:06 2026 -0400

    feat(error-pages): add CippErrorState component

    Replace the old CippImageCard-based 401, 404, and 500 pages with a new CippErrorState component that uses palette tokens for proper light/dark mode support.

    - Add CippErrorState component with optional image, collapsible error detail, and primary/secondary actions
    - Add Cippy mascot images for 401, 404, and 500 states
    - Extract clearQueryCacheAndReload into a shared utility
    - Add showBreadcrumb prop to Layout to let error routes opt out of the breadcrumb bar
    - Fix 500 page error boundary reset to fire on routeChangeComplete instead of unmount
    - Add Storybook stories and Vitest unit tests for CippErrorState

commit aa41c3e9ca36c1810157752f87a87eaf3627f74a
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 14:00:41 2026 +0800

    fix(groups): correct Exchange bulk result correlation and group type resolution

    Exchange bulk requests were only checking the final error record, silently hiding failures anywhere earlier in the batch. This meant rejected group membership changes were reported to the operator as succeeded.

    Introduce Resolve-CippExoBulkResult to correlate each result back to its operation by OperationGuid (newly stamped on all Exchange bulk requests). When an error cannot be attributed to a specific operation, all otherwise-unconfirmed operations are reported as failed rather than guessed successful.

    Fix group type routing by looking up what each group actually is from Graph (mailEnabled/securityEnabled/groupTypes) instead of trusting the posted type, which is missing on older template-stored options and stale on groups converted after the option was saved. Only fall back to the posted value when the lookup returned nothing.

    Report groups deliberately skipped during copy (dynamic, AD-synced, public, already-member) so the operator sees which groups were left out and why, rather than silently dropping them.

    Fix the Add User form's template application effect re-firing whenever any watched field changed, overwriting groups the operator had manually added. Gate the effect on whether the template selection has actually changed.

    Add 11 new Pester test suites (1,500+ lines) covering all group membership code paths and error scenarios, and 2 frontend test suites for the form regression and vacation actions.

commit 6f896dcfa25f0597a78c27d4b7272cc744118285
Author: k-grube <grube.kevin@gmail.com>
Date:   Tue Aug 4 17:50:24 2026 -0700

    test: fix storybook dev server rendering

commit c71cecd11f40baf7ce2d195d50eecc411789baab
Author: John Duprey <jwd@johnwduprey.com>
Date:   Tue Aug 4 20:09:29 2026 -0400

    fix(storybook): install playwright chromium in container

    The cipp-storybook container was missing a Chromium browser, causing @storybook/addon-vitest to throw 'Executable doesn't exist' and breaking the component-test widget. Adds a playwright install step before starting the dev server, backed by a named volume to cache the browser across restarts. Updates docs to mention port 6006 and the containerized Storybook workflow.

commit 6e265869e2c8b5dc5b7d29b70f06ef31888a2f8f
Merge: 418bccd7 b0047d42
Author: John Duprey <john@cyberdrain.com>
Date:   Tue Aug 4 19:48:38 2026 -0400

    Merge pull request #171 from CyberDrain/preview/superadmin-nav-reorg

    refactor(advanced): reorganize super-admin into dedicated sections

commit 418bccd7af830ba1b7c67aa0ea8da256732fbe0c
Author: John Duprey <jwd@johnwduprey.com>
Date:   Tue Aug 4 19:48:03 2026 -0400

    feat(build): add Storybook service to docker-compose

    Adds a cipp-storybook service that runs Storybook dev server on port 6006, reusing cipp-frontend's node_modules volume. Adds a healthcheck to cipp-frontend so Storybook waits until yarn install and next dev are ready before starting. Also documents exposed ports in the file header.

commit a6ccafcbe7f288a50d11c46388fdec91c1728095
Author: John Duprey <jwd@johnwduprey.com>
Date:   Tue Aug 4 19:27:46 2026 -0400

    ci: add least-privilege permissions to workflows

    Explicitly scope GITHUB_TOKEN permissions for each workflow to the minimum required, following the principle of least privilege.

commit daf853f00c8f0ef4c82cf7329e0d126a6e6f4d25
Merge: 458d2b95 e7183ea8
Author: John Duprey <john@cyberdrain.com>
Date:   Tue Aug 4 19:19:41 2026 -0400

    Merge pull request #187 from k-grube/test/fix-authshell-breadcrumb-suite

    test: update 3 tests for msw v3, require.context polyfill, auth shell changes

commit 458d2b953a6f36166d1911716f0f075f4e0b5170
Author: John Duprey <jwd@johnwduprey.com>
Date:   Tue Aug 4 18:35:07 2026 -0400

    feat(build): add devmanifests overlay for clean dev loop

    Introduce a `cipp-manifests` seed container that copies tracked .psd1 manifests into a gitignored `.devmanifests/` directory before `cipp-api` starts. Individual manifest files are then bind-mounted over the source tree so DevExpandModuleExports rewrites stay off the working tree. Also adds header comments to docker-compose-all.yml explaining the required `--watch` flag and updates .gitignore and Dockerfile.dockerignore to exclude the new overlay directory.

commit b0047d42087c0ba0261f00b2e6cc7f1d8f12e6ff
Author: John Duprey <jwd@johnwduprey.com>
Date:   Tue Aug 4 18:27:46 2026 -0400

    docs(container-management): rewrite Status & Updates for the new layout

    The page moved from four cards to a status strip, an action row and two
    settings cards; the doc still described the old layout, a Container Status
    card, and a Check Now button that no longer lives where it says.

    Covers the four status tiles and their Build Details / Latest on this
    channel panels, the two conditional notices, the three action buttons, and
    both confirmation dialogs — in particular that a manual check restarts the
    container on the spot when auto-restart is on, which is the one action on
    this page that can surprise you. Also documents the live channel list and
    its refresh button.

    Fixes a stale line of helper text in the Update Checks card that pointed at
    a Maintenance section which no longer exists.

commit 5797b91601fc21d76207952be486dbcfda5c4ffa
Merge: 1bafd7f2 6702cc79
Author: John Duprey <jwd@johnwduprey.com>
Date:   Tue Aug 4 18:26:14 2026 -0400

    Merge branch 'dev' into preview/superadmin-nav-reorg

    Conflicts resolved:

    - CippBreadcrumbNav.jsx — dev replaced the hardcoded tabOptionPaths array
      with a require.context glob, which already picks up the new
      container-management and authentication tabOptions.json files. Took dev's
      version and dropped the now-redundant path additions.
    - authentication/sso.md — took dev's expanded content (including the new
      Refresh Sign-in URLs action) and re-applied the nav-path corrections:
      Super Admin > SSO becomes Authentication > SSO, and the restart pointer
      becomes Container Management > Status & Updates.

    Also repointed the hardcoded SSO_DOCS_URL in ForcedSsoMigrationDialog.jsx
    and CippSSOSettings.jsx (both new on dev) at the moved docs page.

commit 6702cc7986c7ad7f7b23fe91743e65efbe08654e
Author: John Duprey <jwd@johnwduprey.com>
Date:   Tue Aug 4 18:08:50 2026 -0400

    fix: redirect /onboarding to /onboardingv2

    The legacy SAM Setup wizard posted to /api/ExecSAMSetup which no longer exists. Replace the page with a client-side redirect to /onboardingv2 so existing bookmarks and links continue to work.

commit 8311ceadfefc411214e5db8f90220ab6a0e1af93
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 5 00:01:35 2026 +0200

    updates for baselines

commit e7183ea8cddf2bc27ea1ccc9e9b8006ae51ac7a9
Author: k-grube <grube.kevin@gmail.com>
Date:   Tue Aug 4 14:17:36 2026 -0700

    test: update 3 tests for msw v3, require.context polyfill, auth shell changes

commit 382ce7cedc667c0eaf18034f52cf40a32ef29268
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 4 23:10:15 2026 +0200

    new standards

commit 14b4f46175fae0f468121a143898f5c4e03cbe68
Merge: 74b1a4f4 769ec1d8
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 4 22:17:53 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 74b1a4f4ae9d3c352ce91426c0f44b5558407880
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 4 22:17:49 2026 +0200

    Convert standards

commit 769ec1d868c5a336572f50d6c9da15dd7b97cdab
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 02:07:25 2026 +0800

    fix(settings): persist default test suite setting

    Include `defaultTestSuite` in the settings payload saved from `CippSettingsSideBar` so the selected test suite preference is retained instead of being dropped on save.

commit 0abca90acb02bf4592c30cf21c3d481d50fa447a
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 01:52:49 2026 +0800

    fix(backend): resolve PSScriptAnalyzer warnings

    Fix PSScriptAnalyzer warnings across the backend:

    - Reorder null comparisons to use `$null -eq $var` pattern
    - Rename unapproved verb functions (Process-*, Parse-*, Clean-*, Normalize-*) to approved verb equivalents (ConvertTo-*, ConvertFrom-*, Expand-*)
    - Remove unused `SupportsShouldProcess` from Start-BillingTimer
    - Rename loop variables to avoid shadowing outer scope variables

commit 612b333a468cb516ddae3602269e4f0bfefa02c0
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 01:45:19 2026 +0800

    ci(licenses): add daily license SKU update workflow

    Adds a GitHub Actions workflow that runs daily to refresh Microsoft license SKU data (ConversionTable.csv, M365Licenses.json, ExcludeSkuList.JSON) and opens a PR against dev when anything changes. Reuses an existing open PR branch to avoid stacking one PR per day.

    Also fixes Update-LicenseSKUFiles.ps1 for cross-platform (Linux CI) compatibility by replacing Windows-only path constructs with Join-Path and GetTempPath(), resolving the repo root relative to the script location, and adding guards when expected files are not found.

commit 0308b6e5132cfb69e9fc29372b254b7d82f4b83e
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Tue Aug 4 19:39:17 2026 +0200

    feat(groups): enhance group report with owners and update UI for owner visibility (issue 128)

    Updated the group report to include owners in the data retrieval and added functionality to toggle the display of owners in the UI. The group description was also modified to reflect the inclusion of owners. This improves the overall visibility and management of group data.

commit 0e1bbc78b4ebbc096fd353296e1859d34070df8b
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 5 01:27:32 2026 +0800

    fix(standards): handle default platform policy

    Look up the default Intune platform restrictions policy by its id suffix instead of filtering on an inconsistent Graph type, and log when the default policy cannot be found. Also normalize unset settings to booleans so comparisons, remediation payloads, and BPA reporting do not drift because of `$null` values.

commit c77183f178413e52c17a714eb20429c0f0b134cc
Author: Kristian Kjærgård <31723128+kris6673@users.noreply.github.com>
Date:   Tue Aug 4 19:06:20 2026 +0200

    chore: Change label case in feature request template

    Updated label from 'feature' to 'Feature' in feature request template.

commit dae62b34e90cfdeec45fc0182e7e87e025b0604e
Author: Bobby <31723128+kris6673@users.noreply.github.com>
Date:   Tue Aug 4 19:…
Signed-off-by: James Tarran <jtarran@techary.com>
commit e2cfa2d917d5365f0f241b87440f03bb0f7be6c1
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 14:34:48 2026 +0200

    fix(openapi): sort generator file scans for cross-filesystem determinism

    The table-writer and helper-index scans enumerated files with unsorted
    Get-ChildItem -Recurse, and both merges are order-dependent (first writer
    that states a type wins; first declaration wins). NTFS enumerates sorted
    while ext4 does not, so a spec generated on Windows typed the onboarding
    table's Exception/Logs/Relationship fields as string while the ubuntu
    runner's regeneration left them untyped, failing the -Check drift gate on
    every PR. Sorting on a separator-normalized path makes both platforms
    process writers in the same order; the committed spec is already what the
    sorted scan produces, so only the generator changes.

commit 5b10ea4ae13bb3b2e39dab8a6250e60b6580da61
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 14:11:17 2026 +0200

    remove workflow, fix tests

commit b60a21624070771d02a07e67d239b307c31eae7e
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 14:01:26 2026 +0200

    versions up.

commit f49c6025d3efceffcbde332a13c922d87b42d181
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Fri Aug 21 13:31:45 2026 +0200

    feat(offboarding): enhance Out of Office message handling

    - Introduced logic to resolve Out of Office (OOO) messages only if they are not empty, preventing automatic replies from being set with empty HTML.
    - Updated offboarding job to use the resolved OOO message instead of the raw input.
    - Adjusted tests to verify that OOO messages are correctly passed into job options.
    - Enhanced documentation to clarify the handling of OOO messages and their configuration in user settings.

commit 960f81461c5759a7eb05eb74f6dcc3c8cfe0d5fb
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Fri Aug 21 12:53:31 2026 +0200

    feat(users): add bulk action to require password change at next logon

    Adds ExecRequirePasswordChange so admins can set forceChangePasswordNextSignIn without resetting the password, including multi-select support. Directory-synced accounts are rejected.

commit c6dd7a41e04a9c4dbf4b29443e389782d7e18480
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 21 18:28:20 2026 +0800

    feat(vacation): support standalone alert exclusion

    Add a new `ExecScheduleAuditExclusionVacation` endpoint and wire the vacation wizard to schedule location-based audit alert exclusions independently of Conditional Access. The UI now presents this as its own action, includes confirmation/results handling, updates vacation-mode filtering, and documents the new fifth action.

    Also harden SharePoint sharing-links cache scans by removing the stale PrincipalCount pre-filter path, always using full/incremental delta ground truth, and preserving existing rows when permission batch reads are dropped. Related backend and frontend tests were updated accordingly.

commit e2ccac2194c6f227843b828d1e3581280dfb7fd4
Merge: 97bd9454 1db684e7
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 10:28:06 2026 +0200

    Merge pull request #126 from jspern/refactor/tap-standard

    feat(standards): add TAP lifetime and length configuration

commit 97bd945497e647d1c03f5b55efa61c15a1907a53
Merge: a95df624 ba59db71
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 10:27:41 2026 +0200

    Merge pull request #248 from CyberDrain/dependabot/npm_and_yarn/frontend/dev/tiptap/starter-kit-3.29.2

    chore(deps): bump @tiptap/starter-kit from 3.20.5 to 3.29.2 in /frontend

commit a95df6242ffd096b8fbbd5985b4d9ee861c7c267
Merge: 9a80ce96 e2d19f38
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 10:27:32 2026 +0200

    Merge pull request #249 from CyberDrain/dependabot/npm_and_yarn/frontend/dev/storybook-10.5.7

    chore(deps-dev): bump storybook from 10.3.5 to 10.5.7 in /frontend

commit 9a80ce965c3e226009d79e02394c227ab6b47162
Merge: 0bad5042 449fcd02
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 10:26:22 2026 +0200

    Merge pull request #252 from CyberDrain/dependabot/npm_and_yarn/frontend/dev/react-dropzone-20.0.0

    chore(deps): bump react-dropzone from 15.0.0 to 20.0.0 in /frontend

commit 0bad50426e0b9495531c30f3061c509031af9c0a
Merge: 53815ca6 a79aaf87
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Fri Aug 21 10:16:52 2026 +0200

    Merge pull request #313 from CyberDrain/dependabot/github_actions/dev/github/codeql-action-4.37.7

    chore(deps): bump github/codeql-action from 4.37.6 to 4.37.7

commit 53815ca6f146c9aa5efaf205773b62ef796d3089
Merge: 31a6220f 226751a3
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Thu Aug 20 22:46:15 2026 -0500

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 31a6220fb1cf99ba4a1e29e82c89ff499cb43684
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Thu Aug 20 22:46:04 2026 -0500

    docs: replace embedded API schema with reference to built in integration page

commit 226751a392df475284bc2855ceefb959439864fb
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 21 11:31:42 2026 +0800

    feat(worker-health): surface skipped jobs and add job detail off-canvas

    The job queue stats row now shows the Skipped count (stale queue entries
    whose task was gone by dispatch time - benign, so never flagged red) and
    the status filter gains a Skipped toggle. Each job row gets a More Info
    off-canvas with the fields the table does not show: id, started and
    completed times, and the last error.

    QueuedUtc/StartedUtc/CompletedUtc are registered as absolute-date
    columns, and the absolute-date formatter now returns a rendered string
    instead of a raw Date when the caller accepts nodes - an off-canvas
    containing any absolute-date field crashed React before this.

commit 53cafd5cc24125a6d582a2697911163b81d8b4d6
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 21 11:14:25 2026 +0800

    fix(core): roll chained orchestrator runs into one queue status

    A logical queue operation can span several orchestrator runs carrying
    the same QueueId suffix: activities re-queue continuation runs (the
    sharing scan's timebox and throttle resumes) and dispatch child
    orchestrations. Get-CIPPQueueData returned one entry per run and
    callers took the first, so a progress tracker read Completed the
    moment the original run's own tasks finished and stopped polling while
    resumed work was still running. Queue and reference lookups now roll
    the whole chain up: task counts sum across runs, and the status stays
    Running while any chained run is active.

commit 9040f665ae8dd2d0ed53ef5f44e26752574a5d3e
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 21 10:55:02 2026 +0800

    feat(container-management): show update history as a data table

    The Status action now returns the 50 most recent version transitions
    instead of 25, and the Update History card renders them in a
    CippDataTable (sortable, searchable, exportable) rather than a property
    list. RecordedAt is registered as a datetime column so it renders as
    relative time like other tables.

commit f532448d867c1881b54ac06e4ec8ac3ee80c18fa
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Thu Aug 20 21:35:11 2026 -0500

    docs(quarantine): document the Files and Teams tabs

    The quarantine route gained child routes for the Files and Teams Messages
    tabs, so the flat page has moved to a section README and each tab now has
    its own page, matching the route path the in-app documentation link is
    built from.

    - move quarantine.md to quarantine/README.md and cover the Email tab
    - add quarantine/files.md and quarantine/teams.md for the reduced action
      set those tabs offer
    - correct the flyout section: it opens from More Info, not a row click,
      and it now lists the URLs and Attachments sections
    - reorder Table Actions to match the row menu, and document Block Sender,
      Download Message, View Message Headers and Submit to Microsoft
    - add the three SUMMARY.md nav entries

    Renaming quarantine.md changes its published URL, so existing links and
    bookmarks to /user-documentation/email/administration/quarantine.md will
    need to follow the new path.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit e4c2877f186e299f1e2f19c4830434d0f7466d67
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Fri Aug 21 10:07:22 2026 +0800

    fix(sharing-links): resume throttled scans

    Add drive-level requeue handling with a persisted RequeueCount so mid-scan throttling resumes from the saved checkpoint instead of restarting or incorrectly completing a drive; stop requeuing after 6 attempts and then fail normally. Also switch principal-mode baseline detection to the dominant PrincipalCount from the first items page (instead of root permissions), preventing inflated root ACL counts from flagging entire libraries; extend resume tests to cover both baseline derivation and throttle requeue/budget behavior.

commit 21081565337c8403ac83e36db6b42fa60f478ee2
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Thu Aug 20 14:59:19 2026 -0500

    docs(groups): document member and owner sub-tables

    The Show Members and Show Owners buttons were replaced by Members and
    Owners columns that open the group's list in a dialog, so the Action
    Buttons section documented two buttons that no longer exist.

    - Rewrite Action Buttons to cover Add Group and Deploy Group Template
    - Add Members and Owners rows to Table Details, and drop the stale
      paragraph about expansion columns and the centrally covered Tenant
      and Cache Timestamp columns
    - Add a Members and Owners section covering both dialogs: their columns,
      row actions with bulk availability, and the Add Members and Add Owners
      buttons

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit cace79c764a28dd4b88aec7a682ab9174229aea4
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Thu Aug 20 14:50:52 2026 -0500

    docs(hudu): list all always-included Magic Dash portal links

    The Settings hint named only Microsoft 365 and Entra as the portal links
    always written to the Magic Dash card. Exchange, Intune, Teams and Azure
    were already always included, and SharePoint was added in 86c7aaf3. Name
    each one as it renders on the card.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 23ff8d1edac55d06851701ffb02520bffd4c6251
Merge: 2ad9c1f5 4725bf4b
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 20 21:48:46 2026 +0200

    Merge pull request #318 from kris6673/quarantine-overhaul

    Feat: Quarantine overhaul with enhanced message details and actions

commit 4725bf4bbe8dc3f9993e171eea0fa1bc11868d2a
Merge: e2a6e577 2ad9c1f5
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 20 21:48:26 2026 +0200

    Merge branch 'dev' into quarantine-overhaul

    Signed-off-by: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>

commit 2ad9c1f50b67d0dbe5a138c19a9e6a98b580dec2
Merge: 791c6971 ba6091cc
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 20 21:45:58 2026 +0200

    Merge pull request #348 from MWG-Logan/feat/investigate-drift-standard

    fix(standards): clarify UserSubmissions drift rule state

commit ba6091ccb76dc76d0af5bff50d6880f1a898a2a8
Author: Logan Cook <2997336+MWG-Logan@users.noreply.github.com>
Date:   Thu Aug 20 14:51:53 2026 -0400

    fix(standards): clarify user submissions drift rule state

    Keep the built-in Outlook report-button state separate from the optional custom destination rule in the comparison payload, and cover enabled, custom-destination, and disabled configurations.

    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

commit 791c69718520e71754d3257b1c43019160007b4f
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 20 19:26:07 2026 +0200

    feat(cipp): enhance group management and UI components

    - Improved `Invoke-EditGroup` function to better handle owner additions and removals with enhanced identity resolution.
    - Updated `CippApiDialog` to integrate CSV field handling and nested value resolution.
    - Introduced `CippDataTableButton` and `CippTableCardButton` components for improved action handling in data tables.
    - Added sub-table functionality in `CippDataTable` for displaying members and owners with dynamic API integration.
    - Refactored `CIPPTableToptoolbar` to support parent row attachment for bulk actions.

    These changes enhance the usability and functionality of group management and data display within the CIPP module.

commit 1d374ecfa9a45cd573d6b509313ac13a38a410ad
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 20 19:25:37 2026 +0200

    feat(cipp): enhance group management functions with new capabilities

    - Added `Add-CIPPGroupOwner` and `Remove-CIPPGroupOwner` functions for managing group ownership.
    - Introduced `Get-CIPPGroupType` function to classify groups based on their type.
    - Updated `Add-CIPPGroupMember` and `Remove-CIPPGroupMember` functions to improve identity resolution and error handling.
    - Implemented `Resolve-CIPPDirectoryId` for resolving directory identities to Graph object IDs.
    - Created `Invoke-ExecGroupMembers` as an entry point for managing group members and owners through a unified API.

    These changes enhance the overall functionality and usability of group management within the CIPP module.

commit 9cba749b9aa4800c3ef49ad52dc44a122cc34742
Merge: bcb443ac 1e5bb200
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 20 17:59:14 2026 +0200

    Merge pull request #344 from jonwbstr/HuduIntegration-switching-magicdash-to-purview-portal

    fix: Update Compliance Portal URL to Purview link

commit bcb443ac12cd722b194d49c9f3452d47bbfb5683
Merge: 4700275e 86c7aaf3
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Thu Aug 20 17:59:03 2026 +0200

    Merge pull request #345 from jonwbstr/HuduIntegration-magicdash-add-link-to-SharePoint-Portal

    feat: Add SharePoint Portal link to Hudu Magic Dash

commit 86c7aaf3bdc714737bb751dfc21c498f31b46e2f
Author: jonwbstr <jon.wbstr@gmail.com>
Date:   Thu Aug 20 11:42:55 2026 -0400

    Add SharePoint Portal link to Hudu Magic Dash

    Signed-off-by: jonwbstr <jon.wbstr@gmail.com>

commit 1e5bb2004ac56cf7d68221dbeb0e2264fef8e40a
Author: jonwbstr <jon.wbstr@gmail.com>
Date:   Thu Aug 20 11:10:52 2026 -0400

    Update Compliance Portal URL to Purview link

    Signed-off-by: jonwbstr <jon.wbstr@gmail.com>

commit 4700275efebe73e2d964977dd35696b9f58d79c8
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Thu Aug 20 08:41:34 2026 -0500

    docs(cipp): document application secret verification on Permissions page

    The permissions check now verifies the SAM application secret as well as
    the application registration's permissions, reporting expiry, imminent
    expiry and an in-memory mismatch on the Permissions Check card. Update
    that section to match, and split the intro to remove an em dash.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 603bcb1e28cfa2b9d1e8099e6f9bbd59d2b96468
Merge: 28e7abff d23afd8f
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 20 14:22:23 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 28e7abff02d489378dad1eae0c3c03b233e2ff6f
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 20 14:22:18 2026 +0200

    fix(gdap): ensure OnboardingUrl is set correctly in GDAP invite function (backfill on badly created invites)

    Updated the Invoke-ListGDAPInvite script to explicitly add the OnboardingUrl property to the InviteRow object. This change addresses the issue where the OnboardingUrl could be null after writing, ensuring that the URL is always correctly formed and available for the onboarding process.

commit d23afd8ffe3069aa427e34f73ef3d43eb1db7ff2
Merge: 78796ea5 9dfab85d
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Thu Aug 20 14:45:26 2026 +0800

    Merge pull request #341 from CyberDrain/chore/license-sku-update-20260820

commit 9dfab85d12f1fe685ec0a60848c55317813a4bcb
Author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Date:   Thu Aug 20 06:09:11 2026 +0000

    chore(licenses): update Microsoft license SKU data

commit 78796ea5ed6bd917ccf06e1e06e8fc9cbc6027aa
Merge: 08235621 0dd8f77f
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 20 00:27:05 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 082356211b410bc1b16fc3d0158ca60e20aec3fa
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Thu Aug 20 00:25:19 2026 +0200

    feat(cipp): implement application secret verification in Test-CIPPAccessPermissions

    Added functionality to verify the application secret stored in Key Vault, including checks for expiration and warning thresholds. This enhancement ensures that the application secret is valid and up-to-date, improving security and reliability in the CIPP access permissions testing process.

commit 715b0bae96e6814860b0cc21acb22a8d1c8b2565
Author: Roel van der Wegen <github@aeternus.tech>
Date:   Wed Aug 19 21:54:19 2026 +0200

    feat(gdap): enhance onboarding URL resolution in GDAP invite functions

    Updated the Invoke-ExecGDAPInvite and Invoke-ListGDAPInvite scripts to improve the generation of onboarding URLs. The new implementation retrieves the hostname dynamically, ensuring that the onboarding URL is correctly formed based on the current environment. This change enhances the user experience by providing accurate links for onboarding processes.

commit 0dd8f77fc9427c7ef5942bf8a9fec56a22b869fb
Merge: e94f951a 2929741d
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 23:59:38 2026 +0800

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit e94f951a84fcc680bbf7c730aa9f0b186313e076
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 23:58:03 2026 +0800

    fix(graph-requests): keep split cache rows in the queue pre-write cleanup

    The pre-write cleanup read in Push-ListGraphRequestQueue projected
    PartitionKey, RowKey and OriginalEntityId - a subset of the split-entity
    markers. Get-AzDataTableLargeEntity then recognised the rows of a split
    entity as parts, could not reassemble them without PartIndex/PartCount,
    and dropped the whole entity, so tenants whose cached blob was split
    across rows were never removed before the rewrite and every refresh
    logged a false 'corrupt table entity' error. Project keys only, so the
    raw physical rows come back and every row reaches the delete; the
    delete already skips part rows it was handed directly.

commit 2929741d323ddd3bb73ce8db794241fc751aee2a
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 10:51:04 2026 -0500

    docs(mobile-layout): correct account menu breakpoints

    PR #316 moved Universal Search and the Light/Dark Mode entry in the
    account popover from mdDown to useIsMobileLayout, so they now appear as
    soon as the navigation collapses rather than only on a phone. Update the
    window-width table and the universal search page to match, and qualify
    the help and support row, which still moves only below 900px.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 14a4a1068b3e3981ea98c726b894cd3719dcb819
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 10:46:02 2026 -0500

    docs(halopsa): correct test ticket scope and drop em dash

    The Create Test Ticket row still described the button as raising a ticket
    using only the ticket type and default priority. New-HaloPSATicket now
    stamps a source on the payload, and the test ticket calls that function
    directly, so the configured request source applies there too.

    Also aligns the Request Source row's closing sentence with the Ticket Type
    row above it ("Halo's default"), and replaces the pre-existing em dash in
    How Alert Tickets Are Raised with a following sentence, so the page passes
    the docs linter clean.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 71e7026d8ffc4b8341d5602b84999980dd0cafd0
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 10:40:00 2026 -0500

    docs(shared-features): document self-service access refresh

    Adds a Refresh My Access page under Menu Bar covering the account
    popover item and the Access Denied page button, the three result
    states, and the 30-second cooldown.

    Also draws the line the paired backend fix creates: a refresh is for a
    change to your own group membership, such as a PIM activation, while
    role group mapping changes made in CIPP now apply immediately and need
    no refresh.

    Documents 8ac85709 and 6ddd24f2.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 1484dcd71ddb40629576e60e9a947d716be75e2b
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 10:28:06 2026 -0500

    docs(report-builder): correct licence rendering in generated reports

    A generated report now names licences from the tenant's own licence data
    with the instance-wide exclusions applied, so excluded and unrecognised
    SKUs no longer fall back to a SKU name or identifier. Separate the
    preview's behaviour from the report's and link the excluded licences
    page.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 01c15ff25dbd0b2ff4eaa2bca615ed708201ec4f
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 10:22:00 2026 -0500

    docs(report-builder): document database block value rendering

    Licence assignments render as product names and Cloud PCs with no
    reported encryption state show as Encrypted (platform-managed), in
    both the builder preview and the generated report.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 5acd4020cbc386525cd2e1a8d45f2e6df861d36b
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 10:05:41 2026 -0500

    docs(identity): document Add Member action on Groups page

    Adds the Add Member row action to the Groups page Table Actions, covering
    the user picker, the CSV bulk path and multi-group selection.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 0752cc3efb90f1cb5130b172ce341dd98c9a0bc3
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 23:00:58 2026 +0800

    docs(alerts): document rogue apps alert sources and CIPP curated list

    The Huntress Rogue Apps alert compares tenants against both the public
    Huntress RogueApps feed and a CIPP-curated list (Config/MaliciousApps.json),
    so it can flag applications that do not appear on the Huntress site. That
    second source was previously undocumented, which caused confusion when
    detections did not match the Huntress list.

    Adds a Rogue Apps docs page covering where the list comes from, what a
    detection means, and the applications on the CIPP curated list; links it
    from the Add Alert page and navigation; and points the in-app alert
    description at the new page.

commit 98d45ca5008074338b6c8cd3b70b3381ec36cfdc
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 09:54:18 2026 -0500

    docs(endpoint): document MDE offboarding and macOS wipe device actions

    Adds the two new Intune device actions to the Devices page Table Actions
    table, in the order they appear in the actions array:

    - Offboard from Defender for Endpoint (76489ea), Windows only, covering
      the Entra device ID match and the cases that report an error instead
    - Wipe Device (7d6a6a9), macOS only, covering the optional Recovery PIN
      and the Intel Mac without T2 caveat

    Also mentions Defender for Endpoint offboarding in the page intro.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 1225d5293ef640d66457a09f71663b07d7d5d7af
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 09:46:48 2026 -0500

    docs(message-encryption): correct IRM field descriptions and align to house style

    Re-grounded the Current Configuration table against Set-IRMConfiguration:

    - Internal Licensing Enabled: in Exchange Online this setting covers
      external recipients as well, and is on by default. The old wording
      implied internal only.
    - External Licensing Enabled: the parameter is on-premises Exchange only,
      so it carries no meaning for a cloud-only tenant. Now says so.
    - Transport Decryption: explain what Disabled, Optional and Mandatory do,
      and that Optional is the default, instead of just listing the values.
    - Purview Message Encryption: describe it as the tenant connecting
      directly to Azure Rights Management.

    Corrected the Actions section: Sender and Recipient are mailbox pickers
    sourced from ListMailboxes, not free-text fields, and the button is
    greyed out rather than hidden. Documented the tenant-switch reset.

    House style: dropped the divider before the closing include, "licenses"
    to "licences" as a noun, converted the HTML table to the markdown
    Action/Description form used elsewhere for non-table pages, and put the
    headings into Title Case to match the corpus.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 325b40a9befce1add1ccc6cd74085df3faa97dc0
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 22:45:36 2026 +0800

    fix(standards): improve spam filter policy resolution

    Replace the legacy name-list policy lookup with a two-pass resolution: prefer an exact name match, then fall back to the built-in default policy (via IsDefault flag or 'Default' name) when the configured name is one of the known portal/cmdlet aliases. Also detect the built-in policy via IsDefault rather than relying solely on the 'Default' name string.

commit 0e93789eb6de365f962cc3e2a5645a45a344e6c3
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 22:44:52 2026 +0800

    fix(standards): guard group template against duplicate creation

    When Graph or Exchange reads failed, the GroupTemplate standard treated the empty result as 'tenant has no groups' and recreated every templated group on each run. Entra permits duplicate displayNames, so each failed read silently produced twins (2→4→6…).

    Adds try/catch guards around both the Graph groups read and the Exchange dynamic distribution group read, logging an error and returning early on failure rather than proceeding with an empty baseline.

    Also adds Pester tests covering the happy path (existing group not recreated, genuinely empty tenant creates group) and the failure paths (Graph failure, Exchange failure, report mode).

commit aa53ad9d455ba6b2396b222a0d3d4556d7e777c9
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 09:37:03 2026 -0500

    docs(offboarding-wizard): document Send As and Send on Behalf grants

    Add the two new mailbox access fields introduced in a0356d8a, correct the
    OneDrive label casing to match the UI, and record that selecting Delete user
    greys out the mailbox access, forwarding and out of office settings.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit b09037d33ac2fe1eee0daaa5f38c05fd2a9eef74
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 09:30:41 2026 -0500

    docs(users): document duplicate username warning on Add User

    Covers the warning added in ca0f6a4c, which appears below the domain
    selector when the username and primary domain match an existing user
    principal name or email alias. Notes that it does not block creation
    and that its absence is not confirmation the address is free.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 8ba85f3273a86c2896a815e30ffcf68c5d185992
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 09:22:53 2026 -0500

    docs(roles): document operations requiring unrestricted tenant access

    Commit 00729896 gates four estate-wide operations behind an unrestricted
    tenant scope: adding a tenant through the Setup Wizard, custom data
    mapping writes, integration tenant and field mapping writes, and tenant
    group management. Adds a central note to the Allowed Tenants step of the
    roles guide, and a hint on each page where the restriction is hit.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 8cdcb627c3bf3f098bb0757ce6b55ac05652d833
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 08:55:56 2026 -0500

    docs(teams-share): update sharing report scan behaviour

    Reflect three sharing-links scan fixes on the Sharing Report page:

    - scanning fans out per library, and an oversized library resumes by
      itself instead of stalling the tenant scan (ef20e301)
    - a library whose permission reads were throttled keeps its existing
      links and is read in full on the next sync (ef20e301)
    - the Preservation Hold Library is not scanned (ef20e301)
    - empty charts read "No data to display" instead of sitting in a
      loading state (0930bded)
    - locked sites now have their links pruned rather than kept, since a
      lock blocks sharing-link redemption, and they return once the lock
      is lifted (94b9e736)

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 47644a1e9c8c1ae0ad985d197f77f0d6d3e0f5e8
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 21:52:21 2026 +0800

    fix(auth): ReadWrite rule grants implied Read permission

    When a role rule grants X.ReadWrite, it now also matches X.Read endpoints in the permission universe. Previously, objects that only declare a .Read endpoint (e.g. Endpoint.Device) would silently lose access when the role was configured with the .ReadWrite variant.

commit 33227aa5772f39f3c43a968c5e883b07888f4bc2
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 08:34:40 2026 -0500

    docs(identity): add guest users to the nav

    Adds the SUMMARY entry for the guest users page, placed between Users
    and Risky Users to mirror the order of the sidebar in the app.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 10b3efac87f2a36a51113b6fda310c5c68874331
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 08:32:31 2026 -0500

    docs(identity): add guest users page

    Documents the guest lifecycle dashboard added in 25dea1b7 and moved onto
    the report cache in 0831a04d7: the six lifecycle statuses and the order
    they resolve in, the summary cards and the status filters they drive,
    the table columns and the two row actions.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 6b53d1099c33e9c502ccbf75e52c237deca409b2
Merge: 06cf2907 afac5679
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 19 15:25:57 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 06cf29072d9dd6d594c807307635942dff4d6b52
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 19 15:25:55 2026 +0200

    device encryption state

commit afac567989b0f68d3fd36eaab95d6afc4114a0cc
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 08:13:00 2026 -0500

    docs(roles): cover a custom role tenant scope that resolves to no tenants

    A custom role can end up scoped to zero tenants, and 98ca5952 makes that
    state deny every tenant's data rather than fall through to unrestricted.
    The evaluation page had no coverage of it, so the symptom reads as CIPP
    showing no data rather than as a scope problem.

    Adds a section naming the three ways a scope empties out (allowed tenants
    all blocked, a tenant group resolving to no members, custom roles since
    deleted) and a matching quick-reference row.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit afeb8ffedd74ac78d8f45f16aeec4bb2a9841dbd
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 08:07:15 2026 -0500

    docs(offboarding): document quarantine release request alert removal

    Add the RemoveQuarantineAlert switch to the offboarding actions table,
    covering what it deletes and what happens when the tenant has no such
    alert.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit d654e282a509a8ff4f0fce3547d4cef82fb3e14f
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 08:02:41 2026 -0500

    docs(alert-configuration): document alert enable and disable actions

    Covers the new Enabled column and the Enable Alert and Disable Alert
    row actions added in 8dc8739, and corrects View Task Details to
    describe its condition as greyed out rather than hidden.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 7d6a6a92eab9b7de1114fb83ba45809f8429a697
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 19 14:57:12 2026 +0200

    add macosx wipe

commit ddc53ecb493528eb01ab3328d1a7df6f4fcad8a9
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 07:54:44 2026 -0500

    docs(shared-features): document the support file generator

    Adds a Generate Support File entry to the speed dial's Options table and a
    section covering the two capture modes, the recording chip, and redaction.
    Also adds the action to the mobile hint's larger-screen list, since it is
    registered on the speed dial only and does not reach the account menu.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 9c221f25472adf279a3807213f45e0dfbf16ab5d
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 07:40:51 2026 -0500

    docs(shared-features): cover GDAP relationships in entity switcher

    Add the GDAP relationship pages to the entity switcher's Where It Appears
    table, along with a note that its entries are named for the customer and a
    warning that the list is partner-level rather than tenant-scoped. Correct
    the caching claim to the five minutes the app actually reuses the list for,
    and cross-link the group, device, app registration, enterprise application
    and relationship pages.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 0d7b4c973a3b8fd9f67522a3288d2f4413446845
Merge: 5059b016 08c22eec
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 20:40:53 2026 +0800

    Merge pull request #330 from CyberDrain/chore/license-sku-update-20260819

commit 5059b016780cd7ce4399be669544515a438becb9
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 07:27:12 2026 -0500

    docs(user-documentation): document version history and hosting details

    The Versions card on Application Settings gained Hosting, App Service SKU,
    Runtime Stack and Last Updated rows plus a Copy for Ticket button, and the
    container management Status & Updates page gained an Update History card.
    Document both, including the Unknown fallbacks and the fact that version
    transitions are only recorded from the next update onward.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 6e344fa3a97c493b116f5c57af947715f09a5ad6
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 07:23:10 2026 -0500

    docs(groups): drop dynamic distribution group from group pages

    The group type was removed from the add group form, the add group
    template form and the deploy templates wizard in 67adec2b, so it no
    longer appears as a selectable type anywhere in the UI.

    Removes the type from the Group Type tables on the add group and add
    group template pages and from the wizard field table on the deploy
    page, narrows the external sender and membership rule settings to the
    types that still offer them, and drops the warning describing which
    fields a dynamic distribution group ignores at creation.

    The stored value is left documented on the group templates list page,
    because the backend still handles the type and templates saved before
    the change keep it.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit b3530b01b030635c5cc95a40c2605eae10d20949
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 07:18:42 2026 -0500

    docs(pwpush): document expiry ranges and test failure reporting

    Follows 07e0415e, which changed behaviour the page described incorrectly.

    - Expiration in Days and Expiration after views now state the accepted
      1-90 and 1-100 ranges, and that an out-of-range value is ignored in
      favour of the Password Pusher default.
    - The branding account selector shows a single explanatory row when no
      accounts can be retrieved, and that row cannot be selected. The
      "Choose branding" step said the list stays empty instead.
    - The Test step now covers failure: the result names the reason rather
      than reporting "PWPush is not enabled" for everything.
    - Removed the five em dashes flagged by lint_docs.py.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 81dd2ae6456d31fa393bee8b1319b686ec77889f
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 07:12:32 2026 -0500

    docs(ca-templates): document custom variables in CA templates

    No page covered custom variables in Conditional Access templates, even
    though a template is only portable across an estate because of them.

    Adds a Custom Variables section to the Create CA Template page: that any
    field accepts a %variablename% token, that substitution runs before CIPP
    matches names in the target tenant (so a variable-named named location,
    authentication strength or authentication context matches the existing
    object instead of being recreated on every deploy), that the whole
    template is substituted at once so a location reference must use the same
    variable text as its display name, and where values are set.

    Also notes that this editor's fields carry no variable autocomplete: the
    builder has no textFieldWithVariables field, so the % list never appears
    and the name has to be typed in full.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 794b474b7d733601b26c7c90c81c064299773390
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 07:07:18 2026 -0500

    docs(identity): document last successful sign-in column

    Commit 47170a68 added `lastSuccessfulSignInDateTime` to the inactive
    users report and changed `lastRefreshedDateTime` to the users cache row
    timestamp rather than request time.

    Update Table Details to match, correct the inactivity rule to the most
    recent of the three sign-in fields, and add a warning that the
    interactive and non-interactive columns record attempts rather than
    successes. Drop the Tenant row, which is covered centrally by
    table-features.md.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit e8d7faee6202703f22345bd10db6bcbb5b3c7dac
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Wed Aug 19 06:56:30 2026 -0500

    docs(user-documentation): drop stale drawer action claims

    The extended-info drawer no longer carries row action buttons, so four
    pages claiming the same actions were available from inside the flyout
    were wrong. On the Devices page the remaining flyout sentence moves into
    Table Details, where the rest of the corpus keeps row-flyout prose.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 08c22eecd115a3a872161c252f9d145dc2dcf7ba
Author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Date:   Wed Aug 19 06:08:54 2026 +0000

    chore(licenses): update Microsoft license SKU data

commit ac32924612b9e200608131ab226db33b7c25f0e9
Merge: 4f2b0557 063722f7
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Wed Aug 19 00:41:41 2026 +0200

    Merge pull request #316 from k-grube/fix/mobile-ui

    Fix(mobile): layout fix 900-1200 viewport, mobile side nav scroll fixes

commit 4f2b055790e59806ae5131dcd7f659d457b9fa98
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Tue Aug 18 17:29:33 2026 -0500

    docs(shared-features): document the entity switcher

    Detail pages now render their title as a switcher that opens a searchable
    list of sibling records, so you can move between users, groups, devices,
    app registrations and enterprise applications without going back to the
    table. Adds the shared page covering it, registers it in the nav, and
    points the View Individual User header paragraph at it.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 063722f70adaea95c153b23f5ad891342b4ccaf2
Merge: 34377cb3 62ca8472
Author: k-grube <grube.kevin@gmail.com>
Date:   Tue Aug 18 15:27:20 2026 -0700

    Merge remote-tracking branch 'upstream/dev' into fix/mobile-ui

commit 62ca847231c23d6dcd3a3c580f4a6ade0d4e5d1a
Merge: d0f916ae 32a4e5e8
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 21:29:45 2026 +0200

    Merge pull request #323 from Renada-Solutions/feat/halo-request-source

    feat(halo): add configurable ticket request source

commit d0f916aec852ee3f506ff15c69ff9fffcdfdd914
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 01:23:17 2026 +0800

    fix(sharepoint): authenticate StorageQuotas reads with the SAM certificate

    The tenant quota endpoint and the quota alert called SPO admin REST
    StorageQuotas() with a delegated client-secret token, which 401s on
    tenants where the service account lacks SharePoint admin rights; the
    endpoint then swallowed the failure into "Not available" and the alert
    silently skipped the tenant. Cert-based app-only auth - the same mode
    the other SPO admin REST callers already use - succeeds on the tenants
    the delegated call failed on.

commit 94b9e73630957cf7d5df623a821f15efc8c87d0a
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 01:11:16 2026 +0800

    fix(sharepoint): treat locked sites as inactive instead of failed in the sharing-links scan

    A NoAccess-locked site (typically an offboarded user's OneDrive) blocks
    all content access including sharing-link redemption, so its links are
    dead while the lock stands. The scan previously completed such sites as
    failed, which protected their cached rows every cycle and logged a
    warning per site per scan. A locked site now completes un-failed
    without scanning, letting finalisation prune its inactive links; an
    unlock later triggers a fresh full scan that re-adds them. Locks
    appearing mid-scan get the same treatment at the drive level.

commit 0930bdedbd1357f86db1b475a4c8735a7147b08a
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 01:06:10 2026 +0800

    fix(sharepoint): show an empty state instead of a permanent skeleton on empty chart cards

    CippChartCard treated an empty series as a loading state, so a chart
    whose data is legitimately empty - e.g. Top External Recipients on a
    tenant with only organization-scope links - rendered a skeleton
    forever. Loading now shows the skeleton; loaded-but-empty shows a
    "No data to display" placeholder.

commit 23fbd3433206b8e6b78a3f56d0fbd5c25715ca8a
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 00:47:56 2026 +0800

    chore(api): update api spec

commit 6ddd24f245b10051b33dc8a5a45ea76fd43823ef
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 00:47:55 2026 +0800

    fix(auth): apply role group mapping changes to user access immediately

    Changing which Entra group maps to a CIPP role only bumped the access
    scope version, which covers what a role can see - not which roles a
    user resolves to. Users kept their previously resolved roles for up to
    15 minutes (the cacheAccessUserRoles TTL) plus the allowedUsers sync
    interval.

    ExecCustomRole now detects an actual mapping change (assign, reassign,
    unmap, or role delete with a mapping) and clears the cached per-user
    resolutions via the new Clear-CippAccessUserCache helper, then runs the
    user sync and invalidates CRAFT's user cache, matching ExecCIPPUsers.
    Permission-only role edits skip the fanout.

    Set-CIPPAccessRole gets the same treatment, and a repair: it always
    threw on its string-typed Group parameter, wrote the mapping under the
    wrong partition key with an invalid -Table argument, and its pre-read
    used '=' instead of 'eq'. It now writes the same shape ExecCustomRole
    does.

commit 8ac85709cd907bbc7194f4570bf76d80ca73cac1
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 00:47:55 2026 +0800

    feat(auth): add self-service access refresh for PIM-activated roles

    Roles resolved from Entra group membership are cached for 15 minutes
    (cacheAccessUserRoles) and mirrored into allowedUsers by a 15-minute
    sync timer, so a role granted through a PIM-activated group could take
    15+ minutes to reach CIPP. ExecRefreshMyAccess lets a signed-in user
    clear their own cached resolution, re-check group membership via Graph,
    and refresh the allowedUsers projection on demand, behind a 30-second
    per-user cooldown.

    The endpoint is Public by necessity - a user whose elevation has not
    landed yet holds no CIPP role at all - and gates itself on the platform
    principal header, refusing app-only API clients.

    Frontend: a Refresh my access item in the account popover that runs
    through the standard confirm dialog with inline results, and a refresh
    affordance with result feedback on the Access Denied page, both
    invalidating the cached /api/me so the UI updates in place.

    Closes #315

commit 3f3247f23d396697b42af465e0624600ca96a742
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Wed Aug 19 00:42:05 2026 +0800

    feat(tests): expose Domain Analyser results to custom tests via the reporting DB

    Snapshot the Domain Analyser results already computed into the Domains
    table into CippReportingDB as type DomainAnalyser during the Graph cache
    collection, so custom tests and reports can read DNS hygiene, email
    authentication state and domain health scores through Get-CIPPTestData
    without needing network access from the test sandbox.

    Rows are keyed by domain so nightly reruns upsert in place, and a tenant
    the analyser has not run for is skipped rather than recorded as an
    authoritative empty set.

    Move the Domain Analyser timer from 05:30 to 01:30 so it completes ahead
    of the 03:00 DB cache run and the 04:00 test run, matching the pattern
    the Intune report-export timer already uses.

    Closes #235

commit 32a4e5e828eafc2905ad6e840a07f7ce7611389d
Author: Jacob Newman <jacob@renada.co.uk>
Date:   Tue Aug 18 17:20:22 2026 +0100

    feat(halo): add configurable ticket request source

    Halo records tickets created over the API as "Manual" unless the payload
    carries a source, so CIPP's tickets are indistinguishable from ones an
    engineer logged by hand when reporting on ticket origin, SLAs or service
    reviews.

    Adds an optional Request Source setting to the HaloPSA integration. Create
    a source in Halo, pick it here, and it is stamped on every ticket CIPP
    raises. Left blank nothing is sent and Halo applies its own default, so
    existing installs behave exactly as before.

    Request sources are lookup type 22 and are instance-wide rather than scoped
    to a ticket type, so they get their own List key instead of joining
    HaloPSAFields, which is re-fetched per dropdown and on every ticket type
    change.

    Source ids include 0 (Email) and negatives (Halo's built-in integration
    sources), and both $null -as [int] and '' -as [int] evaluate to 0, so the
    payload guard checks presence before parsing rather than reusing the
    truthiness/-gt 0 pattern the priority field uses. Tests cover that, the
    unconfigured case and the consolidation path.

commit 30cb11bfd4e4f6dfae1e3cead2ca988102a27e2c
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 17:44:46 2026 +0200

    use actual report.

commit 067ed77464987a5c2b585713a5dea72fb867671a
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 17:38:06 2026 +0200

    translate license shapes and report update.

commit 661a9c5c6a6033c678e0425fa2ed73479cef1607
Merge: dec62136 a4cea972
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 17:29:15 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit dec62136bb2301d60dc11111b92c04cf26d22481
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 17:29:13 2026 +0200

    add users directly from groups menu

commit a4cea9723184cdc11f0f184d423175f230f41677
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 23:26:03 2026 +0800

    feat(support): add manual recording mode to support bundle

    Adds a 'Record Actions' mode to the support bundle dialog that lets users close the dialog, reproduce an issue, and return to stop recording. A persistent chip indicator is shown while recording is active. Also captures request bodies in the network recording and renames internal serialization fields for clarity.

commit 68e0c011f080ac7e598a1e6cd0ad205dc5dfb0b5
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 23:25:57 2026 +0800

    refactor(orchestration): resolve priority fallback directly

    Fold the out-of-range check into the fallback condition instead of forcing
    the explicit value back to $null to re-enter the fallback branch. Same
    resolution order and results; one less indirection to read.

commit 0d164a8d75a1e65ab9d19dd43bcb1d00c2a04e0b
Merge: cd046714 44cfa2f9
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 16:34:27 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit cd046714a4312d60bb389b919dd0f16d0d69f0ee
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 16:34:25 2026 +0200

    add AppleUserInitiatedEnrollmentProfiles

commit 44cfa2f9d2850c651792a9e746878b5e93e93291
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Tue Aug 18 08:51:23 2026 -0500

    docs(mobile): document mobile and narrow-screen behaviour

    Covers the mobile UX work in 19fe49d5, e5ee94bb, c2ba5a96 and d69cbd29 as a
    single shared-features page rather than repeating it per page, since every
    change is in the shared table, layout, theme and dialog components.

    New Shared Features > Mobile Layout page covering the two width thresholds,
    where each menu bar control moves, the card list and its controls, selection
    mode, the switch to the full table, full-screen detail flyouts and back-gesture
    dismissal, the page actions button, the tab picker, breadcrumb collapse,
    clamped notices, dialog and wizard layout, and the PDF handoff.

    Also updates the pages whose behaviour now differs on a phone, adds the new
    "Table view on small screens" preference, and corrects two stale references:
    the tenant selector no longer moves into the navigation menu, and the CIPP
    Users page is no longer titled "CIPP User Management".

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 7904815c3167ca2a3023da4cf290d9354cb1f40d
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Tue Aug 18 08:22:51 2026 -0500

    docs(autopilot): complete group assignment documentation

    Reviewed the enrollment profiles page against the sources changed in
    PR #296 and corrected the gaps:

    - document the missing Identity Group Read fallback, where the group
      picker is replaced by a permission warning
    - Assign to Custom Group(s) lists every Entra ID group type, not just
      security groups
    - Remove Assignment(s) can also remove the all devices assignment
    - correct the Display Name character set to match both validators,
      adding the pipe and backslash and noting hyphens are rejected
    - use <strong> for the UI label in the actions table, drop the italics
      in the field table, and restore the table's uniform row padding

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 0ca554a819a86c2cd6bafe119884e38691629b71
Merge: 76489ea1 0831a04d
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 15:21:38 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit 76489ea1af5ec8ac1f02e8d5fc967cfdd9f908d3
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 15:21:36 2026 +0200

    new MDE offboarding device action

commit 0831a04d7a867ac8bcab61fa5eff04941b0ebe48
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 21:12:59 2026 +0800

    feat(identity): serve guest lifecycle dashboard from the report cache

    The guest users page now reads cached data from the reporting database
    by default, with a toggle back to live Graph and a sync action. The
    Guests cache keeps the full beta property set and sponsors, and now
    merges in signInActivity where the tenant is licensed for it, stamping
    each row with signInLogsCapable so readers can tell a guest who never
    signed in apart from a tenant without sign-in data. ListGuestUsers
    gains a UseReportDB branch via Get-CIPPGuestUsersReport, AllTenants
    support through the cache, and a sponsors column.

commit 2dc0c68a0768b752ecad1d2d2d3e2b357d913567
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 21:04:11 2026 +0800

    fix(orchestration): pass parent run lineage when queueing Craft child runs

    Child orchestrations queued from inside a running activity (e.g. the per-tenant
    DomainAnalyser runs spawned by Push-DomainAnalyserTenant) arrived at Craft with
    no parent run: the bridge's ambient context read is always null on the reused
    pipeline thread, so the parent run finalized and dispatched its PostExecution
    while its children were still running.

    Read RunName from the stamped $global:CraftOperationContext - the same carrier
    the priority default already uses - and pass it explicitly as the new run's
    parent, so Craft holds the parent's finalize until the child completes. Probe
    the bridge method's arity first: an older Craft runtime only exposes the
    6-parameter method, and passing 7 arguments to it would throw instead of
    degrading.

commit f45e502c87855c795df8c4fc4e53a88c7664a647
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Tue Aug 18 07:58:59 2026 -0500

    docs: cover custom role simple mode and role impersonation

    Documents the feature merged in 39767dac, and corrects the permission
    category guidance added for 888e38c5, which only holds for per-category
    roles now that pattern roles expand at evaluation time.

    - roles.md and cipp-roles/add.md: the Simple (patterns) and Advanced
      (per-category) modes, pattern syntax, the built-in role template, the
      live result panel, and the fact that saving in Simple mode replaces
      the category grid.
    - how-cipp-evaluates-roles.md: wildcard roles pick up newly added
      categories on their own, per-category roles do not. New section on
      testing a role with impersonation, including the single-role-in-
      isolation caveat.
    - cipp-roles/README.md: Impersonate Role table action, an impersonation
      section, and why More Info now reads "Effective Permissions (at last
      save)".
    - super-admin/README.md: pointer to impersonation, which is superadmin
      only but lives outside that menu.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 547f533314798bb1a5e74fd5369a8f1f88e58d87
Merge: 89645f91 0aa537d5
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 14:56:17 2026 +0200

    Merge pull request #188 from kris6673/feat/purview-message-encryption

    Feat: Add Purview Message Encryption tools and configuration standard

commit 89645f91f0ad569660923ed1ed0c8ef9919973b7
Author: Brian Simpson <50429915+bmsimp@users.noreply.github.com>
Date:   Tue Aug 18 07:44:07 2026 -0500

    docs: cover GitHub token fallback and release notes defaults

    Documents the behaviour introduced in 4878da5f and c7ec759e.

    - GitHub integration: new "When the Token Stops Working" section covering
      the read fallback to the shared token, writes still failing, and the log
      entry each rejection produces. Test step now describes the failure result
      as well as success.
    - Release notes notification: the dialog opens on the newest feature
      release rather than the running hotfix tag, and a failed refresh serves
      the cached release list instead of erroring.
    - Release notes notification: new section for the phone layout from
      9a0aac50b and 9a668dec2.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 7ba43cd163dfd243789d3642422162dd922c965d
Merge: a0356d8a 3dedce3c
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 14:38:02 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit a0356d8ac5a1478543928e96747b60e3a05bb04d
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 14:38:00 2026 +0200

    added sendas to offboarding wizard

commit 3dedce3ccaf563c0d4d418d3a4ee2053dad0ff66
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 20:33:48 2026 +0800

    fix(queue): read Craft context via variable lookup

    Use `Get-Variable` to fetch `CraftOperationContext` from global scope in orchestrator and queue helpers. This keeps priority detection working on current Craft workers while still degrading cleanly to defaults on older runtimes where the variable is absent.

commit 938c01836357b7b66143e7bba33d13930f8129cc
Merge: ca0f6a4c ba81145e
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 14:17:43 2026 +0200

    Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev

commit ca0f6a4cc26dc07962e6ed1c6c8f967c552c7fc9
Author: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com>
Date:   Tue Aug 18 14:12:33 2026 +0200

    added ability to duplicate name check, and app consent standard changes

commit ba81145ef1be763d4327e60faa92b40680d16c37
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 20:05:49 2026 +0800

    fix(exchange): resolve connector comment variables per target tenant

    Invoke-AddExConnector ran Get-CIPPTextReplacement once before the tenant
    loop with an unassigned $Tenant, so %variable% tokens in the connector
    comment resolved against a null tenant. Move the replacement inside the
    per-tenant loop on a per-tenant copy of the params, so tokens resolve
    against each target tenant and one tenant's resolved values never feed
    the next tenant's replacement.

commit f3a9fe1aa4aa7d42b900b12ea16a11967db55dae
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 20:05:31 2026 +0800

    fix(exchange): seed contact templates from CIPPRootPath instead of relative path

commit e2be9faeb949b63775948752e4fd798234b7a704
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 20:03:13 2026 +0800

    chore(api): update api spec

commit 4616513b25d61af1cf37132556a66bb1820df0c8
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 20:02:56 2026 +0800

    feat(orchestrator): add priority-aware queue scheduling

    Improve queue priority resolution for orchestrations and starter jobs:

    - Start-CIPPOrchestrator now resolves priority via a fallback chain: explicit InputObject.Priority (range-validated) → ambient CraftOperationContext → HTTP-triggered default (P2) → background default (P4)
    - Start-UserTasksOrchestrator explicitly sets P2 for user task orchestrations so they don't queue behind P4 background fan-outs
    - Add-CippQueueMessage gains a Priority parameter, defaults to P2 for HTTP requests and P5 otherwise, with graceful fallback for older Craft runtimes that lack the priority overload

commit 4887e6bd7266b2bf140cf0be9c2cf7e517b912d3
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 20:02:17 2026 +0800

    fix(autocomplete): disambiguate default match

    Adjust single-select default resolution in `CippAutocomplete` to handle duplicate option values safely. The component now only auto-resolves by `value` when there is exactly one match; when multiple options share the same value, it additionally requires a `label` match and otherwise keeps the stored form value to avoid incorrect remapping after option refreshes.

commit 007298969aeda09fe36633cda0f54e4d83097f03
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 19:57:38 2026 +0800

    fix(auth): enforce tenant scope on AnyTenant live and write endpoints

    AnyTenant skips the framework per-tenant check, so each endpoint now
    gates itself: restricted callers resolve the target tenant through the
    scope-narrowed Get-Tenants (or filter rows via
    Select-CippAllowedTenantData), failing closed. Estate-wide config
    writes (extension/custom-data mappings, tenant onboarding, tenant group
    rules) require an unrestricted scope. Covers 26 endpoints, with Pester
    tests for the three gate shapes.

commit 76834eb1ff53bbcea1a7297d875c936ace468f3c
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 19:51:11 2026 +0800

    feat(tools): sharing-links seeding and scan measurement dev scripts

    New-SharingLinksTestData seeds a dedicated document library with many
    small files and organization-scope links (chunked and resumable via
    -StartIndex, Retry-After aware, -Cleanup to remove). The measurement
    script times the scan phases (delta paging, permission batches, the
    real site activity) and projects wall time against the background
    activity budget; the comparison script benchmarks the classic
    delta-plus-permissions collection against the PrincipalCount pre-filter
    and Graph Search discovery on the same drive. All three require a
    dot-sourced Initialize-DevEnvironment session.

commit ef20e301c02e14b84a2b719cb4cc428ffc2fc271
Author: Zacgoose <107489668+Zacgoose@users.noreply.github.com>
Date:   Tue Aug 18 19:51:01 2026 +0800

    fix(sharepoint): marker-based completion and per-drive fan-out for sharing-links scan

    The scan-row pending counter and FailedSites JSON list are replaced with
    insert-only marker rows: the failed-site list overflowed the 64KB table
    property cap at ~315 SharePoint composite site ids, after which every
    counter update failed, the counter never reached zero and finalisation
    never ran. Markers cannot lose completions to write conflicts and have
    no aggregate size cap.

    Site tasks now dispatch one resumable task per drive. Drive tasks
    timebox themselves (1100s under Craft,…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants