Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1624 commits
Select commit Hold shift + click to select a range
77d7f24
fix(baselines): remove license gate on authentication methods
github-actions[bot] Oct 9, 2026
8a84d20
fix: add back in empty array
github-actions[bot] Oct 9, 2026
545c287
docs(api): document endpoint status codes and error-signalling helpers
github-actions[bot] Oct 9, 2026
d7c7ecf
feat(msp-apps): add NinjaOne to MSP vendor apps
github-actions[bot] Oct 9, 2026
a7abfb8
feat(branding): add option to turn off the cover image fade
github-actions[bot] Oct 9, 2026
1da5672
Update openapi.json
github-actions[bot] Oct 9, 2026
10c7b75
feat(halo): background auto-map with tenant ID and exact name matching
github-actions[bot] Oct 9, 2026
39f4537
feat(hudu): auto-map tenants via HaloPSA client and exact company name
github-actions[bot] Oct 9, 2026
cef067c
feat(conditional): add list custom variables for CA templates
github-actions[bot] Oct 10, 2026
bde9c62
new GSA deployment standard
github-actions[bot] Oct 10, 2026
2c9a206
Merge pull request #742 from kris6673/feat/teams-files-policy
github-actions[bot] Oct 10, 2026
6ed706f
feat(baselines): manage external meeting bots in the Teams meeting po…
github-actions[bot] Oct 10, 2026
49c4fba
feat(onedrive): allow a custom name when adding a OneDrive shortcut
github-actions[bot] Oct 10, 2026
f5149bc
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 10, 2026
68d2615
fix(exchange): fall back to Get-MessageTraceV2 for GCC message traces
github-actions[bot] Oct 10, 2026
165773c
new baselines for EISCDA
github-actions[bot] Oct 10, 2026
2d81b61
Update openapi.json
github-actions[bot] Oct 11, 2026
30bfd59
perf(baselines): look up engine commands directly and cut exception c…
github-actions[bot] Oct 11, 2026
4118a5f
feat(baselines): filter the fleet overview by baseline and stage
github-actions[bot] Oct 11, 2026
839cb1c
fix(baselines): emit non-package standards from the stage helper
github-actions[bot] Oct 11, 2026
ac32d1c
fix(baselines): stop the unsaved-changes prompt when saving a new bas…
github-actions[bot] Oct 12, 2026
bc0acca
Merge pull request #876 from kris6673/feat/jit-approval-tenant-scope
github-actions[bot] Oct 12, 2026
5d4ead1
Fix push notification permission handling
github-actions[bot] Oct 12, 2026
abf357c
feat(sharepoint): show per-tenant storage table on AllTenants
github-actions[bot] Oct 12, 2026
b0d0ab3
perf(auditlog): cut directory loads and per-record cost in the rules …
github-actions[bot] Oct 12, 2026
fb650c0
perf(auditlog): expand rule exclusions only for rules that cover the …
github-actions[bot] Oct 12, 2026
37d81d6
fix(alerts): filter audit-log coverage ledger server-side
github-actions[bot] Oct 12, 2026
e02b049
chore: bump version to 11.1.0
github-actions[bot] Oct 12, 2026
19ddd36
test(identity): add default table mock for Pester 6 in JIT approval n…
github-actions[bot] Oct 12, 2026
97e4855
chore(frontend): bump sharp, prosemirror-view, source-map-js
github-actions[bot] Oct 12, 2026
fc55f82
fix(baselines): add the Intune Provisioning Client as owner of an exi…
github-actions[bot] Oct 13, 2026
0b55a3b
fix(webhooks): skip already-processed webhook rows and stop overlappi…
github-actions[bot] Oct 13, 2026
54545dc
fix(standards): pass a single template id to the user agent for merge…
github-actions[bot] Oct 13, 2026
0202302
fix(auditlog): use a generic message for the audit search permission …
github-actions[bot] Oct 13, 2026
acd43ad
fix(sso): backfill scopes when the SSO app registration has no Graph …
github-actions[bot] Oct 13, 2026
d21529e
fix(auditlog): evaluate audit rules without enrichment when the direc…
github-actions[bot] Oct 13, 2026
d3bca45
fix(ninjaone): sort secure scores by createdDateTime so the latest sc…
github-actions[bot] Oct 13, 2026
70d315b
CA policy reporting
github-actions[bot] Oct 13, 2026
a4c586c
Update openapi.json
github-actions[bot] Oct 13, 2026
cccb80c
Merge pull request #903 from TecharyJames/feat/macos-laps-retrieval
github-actions[bot] Oct 13, 2026
7d56288
fix(sam-cert): verify the certificate can sign before enabling certif…
github-actions[bot] Oct 13, 2026
4472b9c
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 13, 2026
12f897c
Update openapi.json
github-actions[bot] Oct 13, 2026
a473250
perf(exo): send Exchange Online requests over HTTP/2
github-actions[bot] Oct 14, 2026
708caa2
perf(http): request HTTP/2 on every lane that enables it
github-actions[bot] Oct 14, 2026
69a4ae6
perf(sharepoint): multiplex SharePoint requests over HTTP/2
github-actions[bot] Oct 14, 2026
60faf1a
perf(auditlog): skip records no rule can match and drop the processin…
github-actions[bot] Oct 14, 2026
8a427b7
perf(auditlog): run audit log orchestrations at priority 3
github-actions[bot] Oct 14, 2026
75f2442
fix(auditlog): skip search creation while a previous creation run is …
github-actions[bot] Oct 14, 2026
06ce5a9
Update openapi.json
github-actions[bot] Oct 14, 2026
32aaf7e
Merge pull request #906 from CyberDrain/chore/docs-published-pages-up…
github-actions[bot] Oct 14, 2026
dbd5c76
fix(bec): stop marking quiet investigation runs as abandoned
github-actions[bot] Oct 14, 2026
b90c04c
Update openapi.json
github-actions[bot] Oct 14, 2026
baf196c
feat(bec): log each collector and IP analysis step with its duration
github-actions[bot] Oct 14, 2026
8ed1319
perf(bec): look up at most 20 case addresses with two unpaged sign-in…
github-actions[bot] Oct 14, 2026
a88a5cc
feat(email): test mail flow rules with Test-Message
github-actions[bot] Oct 14, 2026
6a575ed
fix(webhooks): create Graph subscriptions on the current instance URL
github-actions[bot] Oct 14, 2026
53c3a7b
fix(mcp): flag a disabled MCP Server feature during setup
github-actions[bot] Oct 14, 2026
1aa8c11
fix(bec): read sign-in history the sign-in log no longer keeps from t…
github-actions[bot] Oct 14, 2026
d6aad90
fix(bec): sample colleagues from the last 7 days of sign-ins
github-actions[bot] Oct 14, 2026
18327f3
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 14, 2026
dbc44f3
feat(logs): add IP/AppId filters, search, quick ranges, URL state
github-actions[bot] Oct 14, 2026
2fd9e79
fixes noop baselines
github-actions[bot] Oct 14, 2026
0cce494
namespace bug
github-actions[bot] Oct 14, 2026
a65c131
Update openapi.json
github-actions[bot] Oct 14, 2026
13a68ac
fix(intune): refuse templates missing a setting their chosen option r…
github-actions[bot] Oct 14, 2026
362ae86
perf(graph): pace the identity reports at 5 requests per 10 seconds p…
github-actions[bot] Oct 14, 2026
ceef1e9
perf(exo): read calendar permissions 16 batches at a time
github-actions[bot] Oct 14, 2026
5040252
perf(sharepoint): charge permission reads the documented 5 resource u…
github-actions[bot] Oct 14, 2026
16b8e68
Merge pull request #931 from CyberDrain/chore/docs-published-pages-up…
github-actions[bot] Oct 15, 2026
9e3ed40
feat(sharepoint): redrive sharing-link scans while they progress and …
github-actions[bot] Oct 15, 2026
e9956e4
Merge pull request #933 from kris6673/fix/planner-standard-help-text
github-actions[bot] Oct 15, 2026
44cf762
Merge pull request #932 from TecharyJames/fix(jit)-deep-link-approval…
github-actions[bot] Oct 15, 2026
a7e29c9
Merge pull request #914 from kris6673/fix/backend-undefined-vars
github-actions[bot] Oct 15, 2026
54ea8f1
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 15, 2026
75f5945
Merge pull request #915 from kris6673/fix/standards-copy-paste
github-actions[bot] Oct 15, 2026
294e830
Merge pull request #867 from kris6673/fix/intune-include-replace-broa…
github-actions[bot] Oct 15, 2026
4298a52
Merge pull request #908 from kris6673/fix/user-reported-admin-submiss…
github-actions[bot] Oct 15, 2026
7eb67ed
Merge pull request #913 from kris6673/fix/tenantfilter-body-fallback
github-actions[bot] Oct 15, 2026
991ca75
Merge pull request #937 from MartinRain/fix/spo-localized-site-usage
github-actions[bot] Oct 15, 2026
a9babe1
Update openapi.json
github-actions[bot] Oct 15, 2026
a91910c
perf(ninjaone): read only the cache fields the tenant sync uses
github-actions[bot] Oct 15, 2026
28b3f5f
fix(tests): count Global Administrator group members in ZTNA21816
github-actions[bot] Oct 15, 2026
d1f1c15
feat(sharepoint): keep permissions and storage scans in their own tables
github-actions[bot] Oct 15, 2026
4f8dc0e
fix(sharepoint): match the storage report's last refresh line to the …
github-actions[bot] Oct 15, 2026
9aa47cc
Update openapi.json
github-actions[bot] Oct 15, 2026
0ac317e
perf(dbcache): delete orphaned cache rows in batches without per-row …
github-actions[bot] Oct 15, 2026
c706392
perf(ninjaone): cheaper plan-date filter and HTML card helpers in the…
github-actions[bot] Oct 15, 2026
03b511f
perf(sharepoint): run the site caches as their own tasks and fan out …
github-actions[bot] Oct 15, 2026
6185500
add zar and source
github-actions[bot] Oct 15, 2026
96848ed
perf(ninjaone): log user document send reasons and write 8 batches at…
github-actions[bot] Oct 16, 2026
f409dbc
Merge pull request #943 from CyberDrain/chore/docs-published-pages-up…
github-actions[bot] Oct 16, 2026
ce72554
test: fix order-dependent token cache and Warning severity assertions
github-actions[bot] Oct 16, 2026
9d1eb16
fix permissions
github-actions[bot] Oct 16, 2026
ded768e
fixes conditionals.
github-actions[bot] Oct 16, 2026
bc2ff3d
add guid
github-actions[bot] Oct 16, 2026
c7d3bff
perf(ninjaone): round user summary stats and read only user document ids
github-actions[bot] Oct 16, 2026
2c7e1ec
perf(ninjaone): read users and groups once and show dates without times
github-actions[bot] Oct 16, 2026
2d302cb
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 16, 2026
644459a
fix(scheduler): preserve recurring task slots
github-actions[bot] Oct 16, 2026
defebf3
perf(ninjaone): fan large user document syncs out in staged chunks
github-actions[bot] Oct 16, 2026
61a6903
fix(api-clients): never manage the SSO or SAM app as an API client
github-actions[bot] Oct 16, 2026
bcddaba
fix(timezone): only warn when the scheduler rejects a timezone update
github-actions[bot] Oct 16, 2026
9a6cff8
fix: use full generic type names and guard against short ones
github-actions[bot] Oct 16, 2026
c111624
fix(mailbox-cache): keep the previous cache when a batch fails
github-actions[bot] Oct 16, 2026
b92a3ee
Update openapi.json
github-actions[bot] Oct 16, 2026
b3d00f3
feat(auditlog): add app- and user-actor presets for high-risk app cha…
github-actions[bot] Oct 17, 2026
74af364
chore(config): expand RiskyPermissions and VendorTenantList catalogs
github-actions[bot] Oct 17, 2026
feba40a
fix(credentials): spin the refresh icon while status reloads
github-actions[bot] Oct 17, 2026
4eb6dbf
chore: bump version to 11.1.1
github-actions[bot] Oct 17, 2026
dd39737
fix(auditlog): match credentials added when an app registration is cr…
github-actions[bot] Oct 17, 2026
27ebc24
test(bec): derive the catalog merge expectations from RiskyPermission…
github-actions[bot] Oct 17, 2026
52bfdff
test(scheduler): expect a stale delta task to keep its original slot
github-actions[bot] Oct 17, 2026
e6c1ec2
chore: bump version to 11.2.0
github-actions[bot] Oct 17, 2026
769f8ec
fix(auditlog): drop PIM operations that are never in the unified audi…
github-actions[bot] Oct 17, 2026
2a3fe2a
added presets and scripted alerts
github-actions[bot] Oct 17, 2026
264e68d
v up
github-actions[bot] Oct 17, 2026
9455f4b
perf(reports): read one cache type's counts by key per tenant instead…
github-actions[bot] Oct 18, 2026
8cfa581
Merge pull request #958 from CyberDrain/chore/docs-published-pages-up…
github-actions[bot] Oct 18, 2026
b18f35d
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 18, 2026
2e53c04
Remove the Azure App Service build and deployment workflow config
KelvinTegelaar Oct 18, 2026
13bad4a
Add or update the Azure App Service build and deployment workflow config
KelvinTegelaar Oct 18, 2026
dfdc089
Remove the Azure App Service build and deployment workflow config
KelvinTegelaar Oct 18, 2026
67172ab
fix(backend): stop logging temporary passwords on restore
github-actions[bot] Oct 19, 2026
3cae77a
fix(settings): normalize ClientId case in ExecApiClient
github-actions[bot] Oct 19, 2026
b50a709
Update openapi.json
github-actions[bot] Oct 19, 2026
d93285b
perf(tests): read cache counts by key in the tests run and stats timer
github-actions[bot] Oct 19, 2026
58b8aff
test(timers): pin the scheduler timezone mode and jitter invariants
github-actions[bot] Oct 19, 2026
cff985b
chore(deps): update vendored Cronos to 0.13.0
github-actions[bot] Oct 19, 2026
ea0a46f
feat(sharepoint): show the storage report under Teams & SharePoint re…
github-actions[bot] Oct 19, 2026
16e3e45
fix(sharepoint): trim site usage requests and fix the OneDrive getAll…
github-actions[bot] Oct 19, 2026
7e8ac67
fix: correct test add/delete permissions
github-actions[bot] Oct 19, 2026
70fa005
Update openapi.json
github-actions[bot] Oct 19, 2026
1ec8345
minor fix
github-actions[bot] Oct 19, 2026
f6848a5
feat(auth): block app secrets during certificate-only auth
github-actions[bot] Oct 20, 2026
310109e
feat(queue): cancel queues you started and show the queue position
github-actions[bot] Oct 20, 2026
ecdb77a
Update openapi.json
github-actions[bot] Oct 20, 2026
0e04298
Update openapi.json
github-actions[bot] Oct 20, 2026
6be842a
Update openapi.json
github-actions[bot] Oct 20, 2026
c43ed9c
fix(queue): return the bare queue id for a run already in progress
github-actions[bot] Oct 20, 2026
85e2a81
Merge pull request #969 from kris6673/fix/terrl-alert-divide-by-zero
github-actions[bot] Oct 20, 2026
af1e8fa
Merge pull request #945 from kris6673/feat/securescore-points-to-gain
github-actions[bot] Oct 20, 2026
7656399
fix(users): skip licence requests with nothing to add or remove
github-actions[bot] Oct 20, 2026
e64dc8c
fix(users): schedule Exchange group adds for new users
github-actions[bot] Oct 20, 2026
39b9eab
fix(standards): merge GroupTemplate across tiers, batch id lookup
github-actions[bot] Oct 20, 2026
983d651
fix(intune): throw when exclude group name is unresolved
github-actions[bot] Oct 20, 2026
c48b26e
fix(tests): licence-gate and correct identity test grading
github-actions[bot] Oct 20, 2026
5124df2
fix(hudu): sync assets without credentials on retrieval failure
github-actions[bot] Oct 20, 2026
2f3f192
Merge pull request #1001 from CyberDrain/chore/openapi-spec-update-20…
github-actions[bot] Oct 21, 2026
c40d384
fix(cache): clear app protection cache when a tenant has no policies …
github-actions[bot] Oct 21, 2026
654d06f
fix(retention): report which deploy step failed and fail the caller
github-actions[bot] Oct 21, 2026
e91d199
fix(reports): honor report-specific PDF branding presets (#996)
github-actions[bot] Oct 21, 2026
75a5616
refactor(reports): reuse helper preset fallback for BEC evidence PDFs
github-actions[bot] Oct 21, 2026
1f59d98
Update openapi.json
github-actions[bot] Oct 21, 2026
f0a04f1
feat(domains): add tenant-wide domain security assessment report
github-actions[bot] Oct 21, 2026
147d98a
feat(diagnostics): show top caller IPs on the API egress card
github-actions[bot] Oct 21, 2026
56b22b7
Update openapi.json
github-actions[bot] Oct 21, 2026
d570a43
fix(scheduler): cap scheduled task logs and apply retention to genera…
github-actions[bot] Oct 21, 2026
27a5bd2
feat(hudu): rich-text redesign for People, Devices and Magic Dash
github-actions[bot] Oct 21, 2026
75331c1
fix(scheduler): stop re-running split scheduled tasks from a stale pa…
github-actions[bot] Oct 22, 2026
61a976c
fix(alerts): key vulnerability alert items on their CVE and keep snoo…
github-actions[bot] Oct 22, 2026
d2ee8a6
Update openapi.json
github-actions[bot] Oct 22, 2026
cd6ea47
Update openapi.json
github-actions[bot] Oct 22, 2026
9ca3157
feat(baselines): tenant list, bulk triage drawer and paged alignment …
github-actions[bot] Oct 22, 2026
e8ae93c
fix(baselines): readable compliance trend charts
github-actions[bot] Oct 22, 2026
48321f5
fix(hudu): dedupe people/devices via refetch and object id match
github-actions[bot] Oct 22, 2026
fb47dea
fix(offboarding): don't flag skipped groups as errors
github-actions[bot] Oct 22, 2026
48d2144
fix(hudu): preserve partner-moved layout field positions
github-actions[bot] Oct 22, 2026
4abafe2
feat(groups): manage Send As and Send on Behalf on edit group
github-actions[bot] Oct 22, 2026
701303c
feat(endpoint): add on-demand remediation script runs
github-actions[bot] Oct 23, 2026
d99e6e4
feat(endpoint): add device policy status report endpoint
github-actions[bot] Oct 23, 2026
357980a
fix(standards): prefer exact group name match in NudgeMFA targets
github-actions[bot] Oct 23, 2026
1657104
fix(baselines): prefer exact group name match in NudgeMFA targets
github-actions[bot] Oct 23, 2026
c99c301
fix(baselines): ignore Vacation Exclusion groups in CA templates
github-actions[bot] Oct 23, 2026
0fbabfd
Update openapi.json
github-actions[bot] Oct 23, 2026
c6df6ae
fix(baselines): keep template package rows when saving a baseline
github-actions[bot] Oct 23, 2026
92aba52
fix(labels): deploy sensitivity label groups
github-actions[bot] Oct 23, 2026
148af37
fix(dashboard): mark cache collections stale after 48 hours
github-actions[bot] Oct 23, 2026
f0ac44d
fix(baselines): name tenant overrides in the single-baseline run note
github-actions[bot] Oct 23, 2026
76470c5
Update openapi.json
github-actions[bot] Oct 23, 2026
1832f25
feat(ip-list): show IP list entries as Safe or Compromised
github-actions[bot] Oct 23, 2026
c01c81b
fix(bec): refresh the case's run list after an IP review or containme…
github-actions[bot] Oct 23, 2026
ae4421b
perf(alerts): cut vulnerability alert memory on large tenants
github-actions[bot] Oct 23, 2026
6bcca3f
perf(alerts): fold the vulnerability export in a process block instea…
github-actions[bot] Oct 23, 2026
72f57dc
feat(alerts): set minimum run intervals on alerts whose data refreshe…
github-actions[bot] Oct 23, 2026
f111559
Update openapi.json
github-actions[bot] Oct 23, 2026
03b200d
fix(alerts): stop alert reconcile loading every resolved row's item
github-actions[bot] Oct 23, 2026
ccc940a
feat(endpoint): add enrollment configuration report to device policy …
github-actions[bot] Oct 23, 2026
fc3058f
feat(egress): show response encoding per endpoint and caller IP
github-actions[bot] Oct 23, 2026
e303fc6
fix(alerts): read alert history without stored items and resolve by m…
github-actions[bot] Oct 23, 2026
126eb96
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 23, 2026
7a89428
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 23, 2026
01cd88f
feat(bec): add release action to undo BEC containment lockouts
github-actions[bot] Oct 23, 2026
1b97afc
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 23, 2026
4584b73
fix(bec): drop CA policy description, fix enum typo
github-actions[bot] Oct 23, 2026
3aaf58c
fix(alerts): stream alert history and purge it in batches as it is read
github-actions[bot] Oct 23, 2026
0c66f84
fix(onedrive): resolve shortcuts to libraries on the tenant root site
github-actions[bot] Oct 26, 2026
a7cbe5b
feat(baselines): add meeting transcription to Teams global meeting po…
github-actions[bot] Oct 26, 2026
d0c289d
perf(backup): read only hidden scheduled tasks when backing up a tena…
github-actions[bot] Oct 26, 2026
db0cd99
fix(permissions): skip CPV consent and reset for the partner tenant
github-actions[bot] Oct 26, 2026
b110517
fix(conditional): keep a template's authentication strength when savi…
github-actions[bot] Oct 26, 2026
1090f38
fix(cache): clear cached phishing simulation config when the tenant h…
github-actions[bot] Oct 26, 2026
42b7553
docs(variables): document empty list variables and optional per-tenan…
github-actions[bot] Oct 26, 2026
41955ac
fix(auth): give the SSO and API apps their own app management policy
github-actions[bot] Oct 26, 2026
96d34eb
fix(graph): stop Get-GraphRequestList reading a caller's $Rows when t…
github-actions[bot] Oct 27, 2026
c9a19b3
fix(api-clients): accept legacy string Enabled values on API clients
github-actions[bot] Oct 27, 2026
5c74d3b
fix(domains): escape the DNS domain filter and check every row of a d…
github-actions[bot] Oct 27, 2026
7ff26b1
fix(variables): reject custom variable requests without a tenant and …
github-actions[bot] Oct 27, 2026
a4c3990
fix(hudu): refresh the shared relations cache without rewriting it on…
github-actions[bot] Oct 27, 2026
2814dbc
Merge pull request #1052 from kris6673/feat/jit-approver-email
github-actions[bot] Oct 27, 2026
58ab42f
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 27, 2026
5a3e0e0
fix(security): scope template lists, CVE exceptions and refresh token…
github-actions[bot] Oct 27, 2026
46411a4
fix(identity): refuse JIT admin and user default template edits outsi…
github-actions[bot] Oct 27, 2026
14fd0d4
fix(identity): split ListUserPhoto into the caller's own photo and a …
github-actions[bot] Oct 27, 2026
9b9ef12
feat(baselines): report enterprise apps with no sign-in for a set num…
github-actions[bot] Oct 27, 2026
5ecb6de
Update openapi.json
github-actions[bot] Oct 27, 2026
62d4762
fix(baselines): apply authentication method exclude groups to every m…
github-actions[bot] Oct 27, 2026
ac1af24
fix(baselines): stop duplicate Conditional Access named locations and…
github-actions[bot] Oct 27, 2026
b997efb
Merge pull request #1057 from CyberDrain/chore/baseline-standards-jso…
github-actions[bot] Oct 28, 2026
11219ea
fix(tenant): manage excluded groups for every authentication method
github-actions[bot] Oct 28, 2026
c3b477a
fix(intune): keep template references on settings added in the templa…
github-actions[bot] Oct 28, 2026
772eac8
fix(identity): retry adding a new user to a group when the account ha…
github-actions[bot] Oct 28, 2026
a405b75
Update openapi.json
github-actions[bot] Oct 28, 2026
65e029f
Update openapi.json
github-actions[bot] Oct 28, 2026
cd399de
Merge pull request #1059 from Renada-Solutions/fix/tenant-initial-dom…
github-actions[bot] Oct 28, 2026
dfde0f4
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 28, 2026
2be0028
fix(tests): fix the failing backend Pester tests
github-actions[bot] Oct 28, 2026
71f6d7e
Update openapi.json
github-actions[bot] Oct 28, 2026
7f3f543
fix(baselines): show a renamed tenant group's current name so its bas…
github-actions[bot] Oct 28, 2026
cef322a
fix(baselines): drop blank graduation conditions so the baseline edit…
github-actions[bot] Oct 29, 2026
d321395
feat(ninjaone): render the organisation fields with the documentation…
github-actions[bot] Oct 29, 2026
504a5d7
Merge pull request #1064 from CyberDrain/chore/openapi-spec-update-20…
github-actions[bot] Oct 29, 2026
12f112f
Update openapi.json
github-actions[bot] Oct 29, 2026
7d05a4a
Update openapi.json
github-actions[bot] Oct 29, 2026
bf72699
fix(users): queue one Exchange group copy retry scoped to the pending…
github-actions[bot] Oct 29, 2026
fd111a3
fix(baselines): stop CA templates drifting on user names the tenant d…
github-actions[bot] Oct 29, 2026
324d5ac
Update openapi.json
github-actions[bot] Oct 29, 2026
2574b3d
Update openapi.json
github-actions[bot] Oct 29, 2026
bca6ac8
fix(baselines): treat nested license groups as AND in security simula…
github-actions[bot] Oct 29, 2026
b782a8e
fix(ninjaone): prepare credential fields when the settings are saved
github-actions[bot] Oct 29, 2026
3fc3c10
fix(ninjaone): give the tenant summary tables half the row
github-actions[bot] Oct 29, 2026
45c7b2f
feat(config): size HTTP burst workers per host tier
github-actions[bot] Oct 29, 2026
834c731
fix(halo): say why a referenced ticket could not be read before raisi…
github-actions[bot] Oct 29, 2026
d6a1ceb
docs(halo): list the agent settings needed to add results to an exist…
github-actions[bot] Oct 29, 2026
1ce3987
fix(backup): include baselines in CIPP backups
github-actions[bot] Oct 29, 2026
2e2ae09
Merge branch 'dev' of https://github.com/CyberDrain/CIPP into dev
github-actions[bot] Oct 29, 2026
eb67a22
feat(ninjaone): add NinjaOne Ticketing as a PSA target
github-actions[bot] Oct 29, 2026
fc8aa99
Update openapi.json
github-actions[bot] Oct 30, 2026
2da057d
perf(syncro): give Syncro its own HTTP/2 client pool
github-actions[bot] Oct 30, 2026
8e8d929
Merge pull request #1079 from CyberDrain/chore/docs-published-pages-u…
github-actions[bot] Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
349 changes: 349 additions & 0 deletions .build/Add-OpenApiResponseSchemas.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
#Requires -Version 7.0
<#
.SYNOPSIS
Enriches a CIPP openapi.json with typed 200 response schemas derived by static
analysis of the API and frontend repositories.
.DESCRIPTION
The generated CIPP spec types every request body but leaves every 200 response
as the generic StandardResults envelope. This stage fills typed per-endpoint
response schemas for the read surface, using two deterministic sources that are
already checked into the repositories (no live API calls):
1. Captured response shape baselines (CIPP/Tests/Shapes/*.json) - carry real
field types and nesting. Preferred when present.
2. Frontend table column declarations (simpleColumns in CIPP/src pages) -
carry field names only. Used when no baseline exists; fields are typed as
string and marked x-cipp-field-source: frontend so consumers know the type
is a name-only inference, not a verified type.
Endpoints with neither source keep the StandardResults envelope, which is the
correct shape for write/exec operations. Output is deterministic: the same input
repositories always produce a byte-identical spec.
.PARAMETER InputSpec
Path to the source openapi.json. Defaults to the repo-root spec relative to this
script (.build/.. ).
.PARAMETER OutputSpec
Path to write the enriched spec. Defaults to InputSpec (in-place rewrite).
.PARAMETER FrontendRepoPath
Path to a checkout of the CIPP frontend repository. Provides both the shape
baselines (Tests/Shapes) and the page column declarations (src).
.PARAMETER PassThru
Return the enriched spec object instead of only writing it. Used by tests.
.EXAMPLE
./Add-OpenApiResponseSchemas.ps1 -FrontendRepoPath ../CIPP
Rewrites the repo-root openapi.json in place with typed response schemas.
#>
[CmdletBinding()]
param(
[string]$InputSpec = (Join-Path $PSScriptRoot '..' 'openapi.json'),
[string]$OutputSpec,
[string]$FrontendRepoPath,
[switch]$PassThru
)

$ErrorActionPreference = 'Stop'

$script:CippHttpMethods = @('get', 'post', 'put', 'patch', 'delete')

function ConvertFrom-ShapeNode {
<#
.SYNOPSIS
Converts one node of a captured shape tree into an OpenAPI schema fragment.
#>
param($Node)

if ($Node -is [string]) {
switch ($Node) {
'string' { return @{ type = 'string' } }
'number' { return @{ type = 'number' } }
'bool' { return @{ type = 'boolean' } }
'datetime' { return [ordered]@{ type = 'string'; format = 'date-time' } }
# 'null' (captured as null at sample time) and 'truncated' (below the
# capture depth limit) carry no reliable type, so stay permissive.
default { return @{} }
}
}

if ($Node -is [System.Collections.IDictionary]) {
if ($Node['_type'] -eq 'array') {
return [ordered]@{ type = 'array'; items = (ConvertFrom-ShapeNode -Node $Node['_element']) }
}
$properties = [ordered]@{}
foreach ($key in ($Node.Keys | Sort-Object)) {
$properties[[string]$key] = ConvertFrom-ShapeNode -Node $Node[$key]
}
return [ordered]@{ type = 'object'; properties = $properties }
}

return @{}
}

function Get-ShapeBaselineMap {
<#
.SYNOPSIS
Maps endpoint name -> per-record OpenAPI schema, from captured shape baselines.
.DESCRIPTION
Reads only files carrying both _metadata and shape; the sibling
test-results.json and any non-baseline file is skipped. The per-record schema
is the baseline shape itself (the CIPP envelope's Results[] element).
#>
param([string]$ShapesDir)

$map = @{}
if (-not (Test-Path $ShapesDir)) {
Write-Warning "Shapes directory not found: $ShapesDir"
return $map
}

foreach ($file in (Get-ChildItem -Path $ShapesDir -Filter '*.json' | Sort-Object -Property FullName)) {
$doc = Get-Content -LiteralPath $file.FullName -Raw | ConvertFrom-Json -AsHashtable -Depth 100
if (-not ($doc -is [System.Collections.IDictionary] -and $doc.ContainsKey('_metadata') -and $doc.ContainsKey('shape'))) {
continue
}
$endpoint = $doc['_metadata']['endpoint']
if (-not $endpoint) { continue }
$map[$endpoint] = ConvertFrom-ShapeNode -Node $doc['shape']
}
return $map
}

function Get-FrontendColumnMap {
<#
.SYNOPSIS
Maps endpoint name -> sorted unique field names, from page simpleColumns.
.DESCRIPTION
Intent: skips conditional simpleColumns arrays to avoid non-column branch strings; false negatives beat junk fields.
Scans frontend page sources for files that pair an /api/<Endpoint> reference
with a simpleColumns array, and unions the declared column names per endpoint.
Field names are deterministic; their types are not, so callers type them as
string with a provenance marker.
#>
param([string]$SrcDir)

$map = @{}
if (-not (Test-Path $SrcDir)) {
Write-Warning "Frontend src directory not found: $SrcDir"
return $map
}

$endpointPattern = [regex]'/api/([A-Za-z0-9_]+)'
$columnsPattern = [regex]'(?s)\bsimpleColumns\s*(?:=|:)\s*(?:\{\s*)?\[(?<columns>[^\]]*)\]'
$stringPattern = [regex]'"([^"]+)"|''([^'']+)'''

$files = Get-ChildItem -Path $SrcDir -Recurse -File -Include '*.js', '*.jsx'
foreach ($file in $files) {
$text = Get-Content -LiteralPath $file.FullName -Raw
if ([string]::IsNullOrEmpty($text) -or $text -notmatch 'simpleColumns') { continue }

$endpoints = $endpointPattern.Matches($text) | ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
if (-not $endpoints) { continue }

$columns = foreach ($colMatch in $columnsPattern.Matches($text)) {
foreach ($strMatch in $stringPattern.Matches($colMatch.Groups['columns'].Value)) {
$value = if ($strMatch.Groups[1].Success) { $strMatch.Groups[1].Value } else { $strMatch.Groups[2].Value }
if ($value) { $value }
}
}
if (-not $columns) { continue }

foreach ($endpoint in $endpoints) {
if (-not $map.ContainsKey($endpoint)) { $map[$endpoint] = [System.Collections.Generic.HashSet[string]]::new() }
foreach ($column in $columns) { [void]$map[$endpoint].Add($column) }
}
}
return $map
}

function ConvertTo-ColumnRecordSchema {
<#
.SYNOPSIS
Builds a per-record object schema from a set of frontend column names.
#>
param([System.Collections.Generic.HashSet[string]]$Columns)

$properties = [ordered]@{}
foreach ($column in ($Columns | Sort-Object)) {
$properties[$column] = [ordered]@{ type = 'string'; 'x-cipp-field-source' = 'frontend' }
}
return [ordered]@{ type = 'object'; properties = $properties }
}

function ConvertTo-ResponseEnvelopeSchema {
<#
.SYNOPSIS
Wraps a per-record schema in the CIPP { Results: [...], Metadata: {...} } envelope.
#>
param($RecordSchema)

return [ordered]@{
type = 'object'
properties = [ordered]@{
Results = [ordered]@{ type = 'array'; items = $RecordSchema }
Metadata = [ordered]@{ type = 'object' }
}
}
}


function Get-CippOperationId {
<#
.SYNOPSIS
Builds the deterministic operationId for one CIPP path and method.
.DESCRIPTION
Riftwing imports OpenAPI operations by operationId. CIPP upstream does not
currently emit operationIds, so this keeps importer keys stable without
depending on display labels or external data.
#>
param(
[Parameter(Mandatory)][string]$Path,
[Parameter(Mandatory)][string]$Method,
[Parameter(Mandatory)][string[]]$PathMethods
)

$endpointName = $Path -replace '^/api/', ''
if ($PathMethods.Count -eq 1) {
return $endpointName
}

$methodName = [System.Globalization.CultureInfo]::InvariantCulture.TextInfo.ToTitleCase($Method.ToLowerInvariant())
return "$methodName$endpointName"
}

function Add-CippOperationId {
<#
.SYNOPSIS
Injects missing operationIds and fails on duplicate operationIds.
.DESCRIPTION
Existing non-empty operationIds are preserved so this pass can retire itself
when upstream starts emitting operationIds. Duplicate operationIds are fatal
because importers commonly key operations by operationId.
#>
param([Parameter(Mandatory)][System.Collections.IDictionary]$Spec)

if (-not $Spec['paths']) { throw 'Spec has no paths.' }

$operationCount = 0
$injectedCount = 0
$operationIds = @{}

foreach ($pathEntry in $Spec['paths'].GetEnumerator()) {
$pathMethods = @($pathEntry.Value.Keys | Where-Object { $_ -in $script:CippHttpMethods })
foreach ($methodEntry in $pathEntry.Value.GetEnumerator()) {
if ($methodEntry.Key -notin $script:CippHttpMethods) { continue }

$operationCount++
$operation = $methodEntry.Value
$operationId = $operation['operationId']
if ([string]::IsNullOrWhiteSpace([string]$operationId)) {
$operationId = Get-CippOperationId -Path $pathEntry.Key -Method $methodEntry.Key -PathMethods $pathMethods
$operation['operationId'] = $operationId
$injectedCount++
}

if ($operationIds.ContainsKey($operationId)) {
throw "Duplicate operationId found: $operationId"
}
$operationIds[$operationId] = $true
}
}

return [pscustomobject]@{ Operations = $operationCount; Injected = $injectedCount; Unique = $operationIds.Count }
}

function Resolve-SpecResponse {
<#
.SYNOPSIS
Adds typed 200 response schemas to a parsed spec, in place, and returns counts.
.DESCRIPTION
The pure core of this stage: operates on an already-parsed spec hashtable and
the two endpoint maps, with no file or repository access, so it is unit
testable. Only existing 200 responses on get/post/put/patch/delete operations
are touched; everything else (including operations with no matching source) is
left exactly as found.
#>
param(
[Parameter(Mandatory)][System.Collections.IDictionary]$Spec,
[Parameter(Mandatory)][hashtable]$BaselineMap,
[Parameter(Mandatory)][hashtable]$ColumnMap
)

if (-not $Spec['paths']) { throw 'Spec has no paths.' }

$operationCount = 0
$typedCount = 0

foreach ($pathEntry in $Spec['paths'].GetEnumerator()) {
$endpoint = $pathEntry.Key -replace '^/api/', ''

$recordSchema = $null
if ($BaselineMap.ContainsKey($endpoint)) {
$recordSchema = $BaselineMap[$endpoint]
} elseif ($ColumnMap.ContainsKey($endpoint)) {
$recordSchema = ConvertTo-ColumnRecordSchema -Columns $ColumnMap[$endpoint]
}

foreach ($methodEntry in $pathEntry.Value.GetEnumerator()) {
if ($methodEntry.Key -notin $script:CippHttpMethods) { continue }
$operationCount++
if ($null -eq $recordSchema) { continue }

$responses = $methodEntry.Value['responses']
if ($null -eq $responses) { continue }

$okResponse = $responses['200']
if (-not $okResponse) { continue }

$okResponse['content'] = [ordered]@{
'application/json' = [ordered]@{ schema = (ConvertTo-ResponseEnvelopeSchema -RecordSchema $recordSchema) }
}
$typedCount++
}
}

return [pscustomobject]@{
Operations = $operationCount
Typed = $typedCount
}
}

function Add-CippResponseSchema {
<#
.SYNOPSIS
File-level orchestration: read spec + repo sources, enrich, write output.
#>
param(
[Parameter(Mandatory)][string]$InputSpec,
[Parameter(Mandatory)][string]$OutputSpec,
[Parameter(Mandatory)][string]$FrontendRepoPath,
[switch]$PassThru
)

if (-not (Test-Path $InputSpec)) { throw "Input spec not found: $InputSpec" }

$spec = Get-Content -LiteralPath $InputSpec -Raw | ConvertFrom-Json -AsHashtable -Depth 100
$baselineMap = Get-ShapeBaselineMap -ShapesDir (Join-Path $FrontendRepoPath 'Tests' 'Shapes')
$columnMap = Get-FrontendColumnMap -SrcDir (Join-Path $FrontendRepoPath 'src')

$operationIdResult = Add-CippOperationId -Spec $spec
$result = Resolve-SpecResponse -Spec $spec -BaselineMap $baselineMap -ColumnMap $columnMap
Write-Information "Operations: $($result.Operations) | typed responses added: $($result.Typed) | operationIds injected: $($operationIdResult.Injected) | unique operationIds: $($operationIdResult.Unique)" -InformationAction Continue

# Serialization is deterministic for the object this stage builds, but it does not globally canonicalize pre-existing spec keys.
[System.IO.File]::WriteAllText($OutputSpec, ($spec | ConvertTo-Json -Depth 100))

if ($PassThru) { return $spec }
}

# Run orchestration only when invoked as a script, not when dot-sourced for testing.
if ($MyInvocation.InvocationName -ne '.') {
if (-not $FrontendRepoPath) { throw 'FrontendRepoPath is required when running the script.' }
if (-not $OutputSpec) { $OutputSpec = $InputSpec }
Add-CippResponseSchema -InputSpec $InputSpec -OutputSpec $OutputSpec -FrontendRepoPath $FrontendRepoPath -PassThru:$PassThru
}
38 changes: 38 additions & 0 deletions .build/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# OpenAPI enrichment

`Add-OpenApiResponseSchemas.ps1` post-processes the generated CIPP `openapi.json`. It adds deterministic operationIds and typed `200` response schemas where response shape data can be derived from the CIPP frontend repository. It does not replace the upstream OpenAPI generator.

The enriched spec is published on each GitHub Release as the `openapi.enriched.json` release asset.

The PR check and release workflow strictly lint the CI-generated `openapi.enriched.json` with Redocly. The committed `.redocly.lint-ignore.yaml` baseline pins findings that already exist in the generated enriched spec because of upstream `openapi.json` issues. Any new Redocly error or warning that is not in the baseline fails CI.

To regenerate locally, check out the CIPP frontend repository and run:

```powershell
pwsh -NoProfile -File .build/Add-OpenApiResponseSchemas.ps1 `
-FrontendRepoPath <path-to-CIPP-frontend-checkout> `
-InputSpec ./openapi.json -OutputSpec ./openapi.enriched.json
```

If upstream `openapi.json` legitimately changes and the pinned Redocly findings must be refreshed, regenerate the enriched spec first, then regenerate the ignore baseline from that enriched output:

```powershell
pwsh -NoProfile -File .build/Add-OpenApiResponseSchemas.ps1 `
-FrontendRepoPath <path-to-CIPP-frontend-checkout> `
-InputSpec ./openapi.json -OutputSpec ./openapi.enriched.json
npx --yes @redocly/cli@2.35.1 lint ./openapi.enriched.json --generate-ignore-file
```

Do not generate the baseline from the base `openapi.json`. The lint subject is always the generated `openapi.enriched.json`.

## Known limitations

- Only `get`, `post`, `put`, `patch`, and `delete` operations are processed. `head`, `options`, and `trace` are not present in the current spec.
- Paths are assumed to start with `/api/`. All 580 current paths do.
- When a typed `200` response is added, it replaces the existing `200.content`. Today that content is only the generic `StandardResults` envelope.
- Conditional/ternary `simpleColumns` expressions are intentionally not parsed.

## Release workflow notes

- `openapi-enriched-release.yml` builds and uploads from the same tag. On `workflow_dispatch`, the `tag` input is checked out and used as the upload target. On `release: published`, the release tag is checked out and used as the upload target.
- `.github/workflows/` is gitignored in this repository, so the OpenAPI workflow files require `git add -f` when they are intentionally added or updated.
Loading
Loading