Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
376 commits
Select commit Hold shift + click to select a range
a474464
Merge pull request #160 from KelvinTegelaar/dev
pull[bot] Jun 4, 2026
670c8b6
Merge pull request #161 from KelvinTegelaar/dev
pull[bot] Jun 4, 2026
69cc23e
Merge pull request #162 from KelvinTegelaar/dev
pull[bot] Jun 4, 2026
1e492b4
Merge pull request #163 from KelvinTegelaar/dev
pull[bot] Jun 5, 2026
4ff92ae
Merge pull request #164 from KelvinTegelaar/dev
pull[bot] Jun 5, 2026
6ab2b41
Merge pull request #165 from KelvinTegelaar/dev
pull[bot] Jun 5, 2026
038aba1
Merge pull request #166 from KelvinTegelaar/dev
pull[bot] Jun 5, 2026
c574d67
Merge pull request #167 from KelvinTegelaar/dev
pull[bot] Jun 6, 2026
9185a3e
Merge pull request #168 from KelvinTegelaar/dev
pull[bot] Jun 7, 2026
0d638ca
Merge pull request #169 from KelvinTegelaar/dev
pull[bot] Jun 7, 2026
7d02b0b
Major Update
DamienMatthys Jun 8, 2026
2646da9
Merge pull request #170 from KelvinTegelaar/dev
pull[bot] Jun 8, 2026
2a8bd3b
Merge pull request #171 from KelvinTegelaar/dev
pull[bot] Jun 8, 2026
b68c93f
Update Push-CIPPDBCacheData.ps1
DamienMatthys Jun 8, 2026
4c020dd
Update Set-CIPPDBCacheDefenderCVEs.ps1
DamienMatthys Jun 8, 2026
9f47a50
Merge pull request #173 from KelvinTegelaar/dev
pull[bot] Jun 8, 2026
0c1a4be
Merge pull request #174 from KelvinTegelaar/dev
pull[bot] Jun 9, 2026
c6c31d1
Merge pull request #176 from KelvinTegelaar/dev
pull[bot] Jun 9, 2026
85ef802
Delete Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneCveSyncT…
DamienMatthys Jun 10, 2026
7ae8fcd
Update Push-NinjaOneQueue.ps1
DamienMatthys Jun 10, 2026
7420db6
Update Invoke-NinjaOneTenantSync.ps1
DamienMatthys Jun 10, 2026
4998ffe
Merge branch 'dev' into dev
DamienMatthys Jun 10, 2026
ae604cd
Merge pull request #177 from KelvinTegelaar/dev
pull[bot] Jun 10, 2026
70f9a7b
Merge pull request #178 from KelvinTegelaar/dev
pull[bot] Jun 10, 2026
348d32c
Merge pull request #180 from KelvinTegelaar/dev
pull[bot] Jun 10, 2026
d14a9bb
Merge pull request #181 from KelvinTegelaar/dev
pull[bot] Jun 11, 2026
c945097
Merge pull request #182 from KelvinTegelaar/dev
pull[bot] Jun 11, 2026
9d1e5c0
Merge pull request #183 from KelvinTegelaar/dev
pull[bot] Jun 11, 2026
7f29025
Merge pull request #184 from KelvinTegelaar/dev
pull[bot] Jun 12, 2026
8e3dab3
Merge pull request #185 from KelvinTegelaar/dev
pull[bot] Jun 12, 2026
9af5e4e
Merge pull request #186 from KelvinTegelaar/dev
pull[bot] Jun 12, 2026
5d9c020
Merge pull request #187 from KelvinTegelaar/dev
pull[bot] Jun 13, 2026
49089b8
Merge pull request #188 from KelvinTegelaar/dev
pull[bot] Jun 14, 2026
0bb5570
Merge pull request #189 from KelvinTegelaar/dev
pull[bot] Jun 15, 2026
0983a74
Merge pull request #190 from KelvinTegelaar/dev
pull[bot] Jun 15, 2026
177976b
Merge pull request #191 from KelvinTegelaar/dev
pull[bot] Jun 15, 2026
4fb1ade
feat(mailbox): return SMTP client auth state
kris6673 Jun 15, 2026
b7b9e24
Merge pull request #192 from KelvinTegelaar/dev
pull[bot] Jun 16, 2026
3534f34
Merge pull request #193 from KelvinTegelaar/dev
pull[bot] Jun 16, 2026
8c0334b
Merge pull request #194 from KelvinTegelaar/dev
pull[bot] Jun 17, 2026
353be04
Merge pull request #195 from KelvinTegelaar/dev
pull[bot] Jun 17, 2026
adf8d72
Merge pull request #196 from KelvinTegelaar/dev
pull[bot] Jun 18, 2026
192dad7
Merge pull request #197 from KelvinTegelaar/dev
pull[bot] Jun 18, 2026
8004465
Merge pull request #199 from KelvinTegelaar/dev
pull[bot] Jun 18, 2026
e373cae
Merge pull request #200 from KelvinTegelaar/dev
pull[bot] Jun 19, 2026
f191b86
Merge pull request #201 from KelvinTegelaar/dev
pull[bot] Jun 19, 2026
f44ff88
feat: add allTenants support for shared mailbox enabled report
kris6673 Jun 19, 2026
69394ec
feat: Support room calendar processing options
kris6673 Jun 19, 2026
05096dc
feat: Add default calendar permission handling for rooms
kris6673 Jun 20, 2026
c1099cb
Merge pull request #202 from KelvinTegelaar/dev
pull[bot] Jun 22, 2026
eed85ab
Merge pull request #203 from KelvinTegelaar/dev
pull[bot] Jun 22, 2026
ea7661a
Merge pull request #205 from KelvinTegelaar/dev
pull[bot] Jun 23, 2026
a7093da
Merge pull request #206 from KelvinTegelaar/dev
pull[bot] Jun 24, 2026
9895ce6
Merge pull request #207 from KelvinTegelaar/dev
pull[bot] Jun 24, 2026
ff0185d
Merge pull request #208 from KelvinTegelaar/dev
pull[bot] Jun 24, 2026
dc3614b
Merge pull request #209 from KelvinTegelaar/dev
pull[bot] Jun 25, 2026
68595cc
feat: incident severity + resolving comment
kris6673 Jun 25, 2026
4b08ea3
Merge pull request #210 from KelvinTegelaar/dev
pull[bot] Jun 25, 2026
42087ae
feat: Add message trace retrieval to Push-BECRun function
MWG-Logan Jun 15, 2026
f18525b
feat: configure auth method sub-settings
kris6673 Jun 25, 2026
3402665
Merge pull request #211 from KelvinTegelaar/dev
pull[bot] Jun 26, 2026
ce21a2d
Merge pull request #212 from KelvinTegelaar/dev
pull[bot] Jun 26, 2026
ee5c30a
feat: enhance device import status handling and logging
kris6673 Jun 26, 2026
8adac71
Merge pull request #213 from KelvinTegelaar/dev
pull[bot] Jun 26, 2026
03ae94e
Add typed-response + operationId enrichment for openapi.json
tim-at-rewst Jun 26, 2026
7cafdc6
Merge pull request #214 from KelvinTegelaar/dev
pull[bot] Jun 26, 2026
2a7c7a7
Ignore mail.onmicrosoft domains for DMARC enablement
Zacgoose Jun 27, 2026
a2f29dd
feat: direction-scoped Intune group assignment
kris6673 Jun 27, 2026
dae979b
Fix Check extension alerts repeating on every run (watermark never ad…
matstocks Jun 27, 2026
9a88ec0
feat: add support for ExcludeGroupNames in assignment functions
kris6673 Jun 27, 2026
2f16223
Sensitivity Rule Templating and standard overhaul
Zacgoose Jun 27, 2026
58fe435
Merge pull request #216 from KelvinTegelaar/dev
pull[bot] Jun 27, 2026
d52ec9b
Resolve tenant variables in Win32 Custom App detection script
matstocks Jun 27, 2026
38b18bc
Audit log rework for better resilience
Zacgoose Jun 29, 2026
d358ae5
External Storage Account Backup Replication
Zacgoose Jun 29, 2026
e28e2d8
Merge pull request #217 from KelvinTegelaar/dev
pull[bot] Jun 29, 2026
1b8c0c1
Fixes for CA template editing dropping the package tag
Zacgoose Jun 29, 2026
b995698
Fix CA template list and table side filter when ID/GUID provided
Zacgoose Jun 29, 2026
20eb3d6
Remove standards rows from table when the template is deleted
Zacgoose Jun 29, 2026
bbd52dc
Permission update fixes
Zacgoose Jun 29, 2026
d24f333
fix: token timer secret cleanup
JohnDuprey Jun 29, 2026
d30b2f4
fix: remove execsamsetup, no longer used
JohnDuprey Jun 29, 2026
4e5d152
Merge pull request #218 from KelvinTegelaar/dev
pull[bot] Jun 29, 2026
0b72ea5
Update Compare-CIPPIntuneObject.ps1
Zacgoose Jun 30, 2026
cb3a990
Merge pull request #219 from KelvinTegelaar/dev
pull[bot] Jun 30, 2026
3ce368b
Manual Audit Log Search Fixes
Zacgoose Jun 30, 2026
78b0026
Merge remote-tracking branch 'upstream/dev' into dev
TecharyJames Jun 30, 2026
034366b
Fixes for array value business phone number in templates
Zacgoose Jun 30, 2026
6089106
Fix for adding groups failing for sec groups
Zacgoose Jun 30, 2026
6205e97
fix: modernize and improve logging
kris6673 Jun 30, 2026
7313bd9
Update CIPPSharp
Zacgoose Jun 30, 2026
e718903
fix: rereun detection logic
JohnDuprey Jun 30, 2026
c5a732d
Update Invoke-AddSpamFilter.ps1
Zacgoose Jun 30, 2026
25445c6
Update Oauth standards with conflict information
Zacgoose Jun 30, 2026
e77de98
CIPP Rogue App List
Zacgoose Jun 30, 2026
0dcb4fb
fix: hudu sync
JohnDuprey Jun 30, 2026
7c0da88
feat: add featureflags to stats timer
JohnDuprey Jun 30, 2026
fc8756f
User Offboarding default settings fix
Zacgoose Jun 30, 2026
3c91965
Adds a read-only endpoint that surfaces the currently-active fired al…
TecharyJames Jun 30, 2026
29e8e6c
Fixes for standards where deployment errors were hidden
Zacgoose Jun 30, 2026
eec5f69
Fix Check extension alerts repeating on every run (watermark never ad…
KelvinTegelaar Jun 30, 2026
c6c50d7
Resolve tenant variables in Win32 Custom App detection script (#2116)
KelvinTegelaar Jun 30, 2026
36fd9c0
Fix: Modernize GDAP relationship termination logging (#2117)
KelvinTegelaar Jun 30, 2026
3198c77
Enrich generated openapi.json with typed responses and operationIds (…
KelvinTegelaar Jun 30, 2026
a3c752d
feat: Add message trace retrieval to Push-BECRun function (#2098)
KelvinTegelaar Jun 30, 2026
24e7a06
Feat: Add Intune group assignment enhancements (#2115)
KelvinTegelaar Jun 30, 2026
5994a44
Feat: Add incident severity and resolving comments (#2109)
KelvinTegelaar Jun 30, 2026
0288227
Feat: Support room calendar processing options and default permission…
KelvinTegelaar Jun 30, 2026
e801464
Feat: Add allTenants support for shared mailbox enabled report (#2103)
KelvinTegelaar Jun 30, 2026
25b4110
Feat: CVE exception management page and NinjaOne CVE sync (#2080)
KelvinTegelaar Jun 30, 2026
f965afe
Implements #6214
KelvinTegelaar Jun 30, 2026
67fdcd2
feat: implement clearable fields in user edit API
kris6673 Jun 30, 2026
a0b263c
chore: update version to 10.5.6
JohnDuprey Jun 30, 2026
259770d
fix: revert rerun protection on scheduled tasks
JohnDuprey Jun 30, 2026
d17b33f
fix: add system32,osdrive
JohnDuprey Jul 1, 2026
52ce175
fix: exclude imAddresses from user backup/restore
JohnDuprey Jul 1, 2026
9cf8a3c
Reduce Verbose nop logging
Zacgoose Jul 1, 2026
103078a
JSON escaping fixes for intune policies
Zacgoose Jul 1, 2026
e164701
Bump AzBobbyTables version
Zacgoose Jul 1, 2026
f06ad2f
Table Read Retry
Zacgoose Jul 1, 2026
a79be1c
feat: configure auth method sub-settings (#2110)
KelvinTegelaar Jul 1, 2026
c4c0d3f
Feat: Return SMTP client authentication state in mailbox details (#2097)
KelvinTegelaar Jul 1, 2026
7fa8c1d
Fix: Implement clearable fields in user edit (#2119)
KelvinTegelaar Jul 1, 2026
390b075
Escape square brackets in Intune assignment group name matching
matstocks Jun 30, 2026
614949f
Update payload for log collection endpoint
Zacgoose Jul 1, 2026
aae566d
add executingUser
KelvinTegelaar Jul 1, 2026
a973ec6
Dep bump
Zacgoose Jul 1, 2026
8ff71da
ACSC Essential Eight Test Suite
Zacgoose Jul 1, 2026
5d29976
Role lookup fixes
Zacgoose Jul 1, 2026
7a69da1
Harden app template creation to check app type
Zacgoose Jul 1, 2026
7227962
fix: update sherweb functions to support API client callers
JohnDuprey Jul 1, 2026
915355c
feat: move edituser to reusable set-cippuser function
JohnDuprey Jul 1, 2026
227a74e
feat(halo): link CIPP-generated PSA tickets to the affected user (#2051)
KelvinTegelaar Jul 1, 2026
9767403
Escape square brackets in Intune assignment group name matching (#2120)
KelvinTegelaar Jul 1, 2026
0c524d8
Feat: Enhance device import status handling and logging (#2111)
KelvinTegelaar Jul 1, 2026
ea8259f
add package to exclusions
KelvinTegelaar Jul 1, 2026
76ec0e2
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 1, 2026
b326768
fix(tests): resolve function paths by filename
kris6673 Jul 1, 2026
b6ceba4
refactor(mailbox-perms): share permission helper
kris6673 Jul 1, 2026
877a466
test: add mailbox permission coverage
kris6673 Jul 1, 2026
dab2d8f
feat(tests): add test runner and scaffolder
kris6673 Jul 1, 2026
1b5601e
Fix: resolve test function paths by filename (#2121)
KelvinTegelaar Jul 1, 2026
12fcd01
Refactor: share mailbox permission helper (#2122)
KelvinTegelaar Jul 1, 2026
1a3c6c0
Tests: add mailbox permission coverage (#2123)
KelvinTegelaar Jul 1, 2026
f6115b2
Feat: add Pester test runner and scaffolder (#2124)
KelvinTegelaar Jul 1, 2026
2df5819
MSP App improvements
KelvinTegelaar Jul 1, 2026
0cb0ddc
Feat: Alerts on dashboard (#2118)
KelvinTegelaar Jul 1, 2026
b175790
fix: sync mailbox permission cache after changes
kris6673 Jul 1, 2026
84945c6
feat: filter permission report by user
kris6673 Jul 1, 2026
15c545f
fix: sync cache with resolved UPN, guard filter
kris6673 Jul 2, 2026
81e7900
Correct missing templates from policy compare page and endpoint
Zacgoose Jul 2, 2026
dbc414a
fix logging semantics
Zacgoose Jul 2, 2026
a34a6ed
feat: user filter + cache sync for mailbox permissions (#2125)
KelvinTegelaar Jul 2, 2026
bb1e10d
Add Stale Entra Devices Remediation Action
Zacgoose Jul 2, 2026
913b828
fix: increase template depth in get-cippdrift
JohnDuprey Jul 2, 2026
7c1afbf
Use app permissions to update partner tenant sam app else use delegat…
Zacgoose Jul 2, 2026
396606f
Implement rest api management of teams admin management and update ca…
Zacgoose Jul 2, 2026
23c0c83
Revert permission repair changes (AsApp grant application + Jun 30 re…
Zacgoose Jul 2, 2026
f95046c
feat(bec): surface inbox rule changes in report
kris6673 Jul 2, 2026
4ee9694
chore: bump version to 10.5.7
JohnDuprey Jul 2, 2026
965352f
fix: add caching for hudu relations to reduce api overload
JohnDuprey Jul 2, 2026
50ba47f
feat: add psscriptanalyzer
JohnDuprey Jul 2, 2026
d3a016c
feat: add psscriptanalyzer (#2128)
JohnDuprey Jul 2, 2026
1390e14
updated standards report item
KelvinTegelaar Jul 2, 2026
1f0a3c4
Revert partner SP permission lookup and revert to table permissions l…
Zacgoose Jul 3, 2026
127bdc6
BEC and false network timeout fixes
Zacgoose Jul 3, 2026
4efcd9f
chore: update version to 10.5.8
JohnDuprey Jul 3, 2026
f4861cf
Merge remote-tracking branch 'upstream/dev' into bec-rule-changes
kris6673 Jul 3, 2026
288351f
fix: remove users from mail-enabled security groups during license re…
luimen6 Jul 4, 2026
b378d96
feat: add email aliases and hide-from-GAL to group templates
luimen6 Jul 4, 2026
78c7436
Update Get-CIPPCVEReport.ps1
DamienMatthys Jul 6, 2026
bb94134
Update Invoke-ListCVEManagement.ps1
DamienMatthys Jul 6, 2026
e083b19
Update Invoke-NinjaOneTenantSync.ps1
DamienMatthys Jul 6, 2026
15dc781
feat(bec): surface inbox rule changes in report (#2127)
KelvinTegelaar Jul 6, 2026
d3ea5f7
fix: remove users from mail-enabled security groups during license re…
KelvinTegelaar Jul 6, 2026
36eca35
vacation mode updates
KelvinTegelaar Jul 6, 2026
4c5404c
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 6, 2026
9c1879c
Drop disableResilienceDefaults when not enabled
Zacgoose Jul 6, 2026
e380a7c
feat: enhance sensitivity label handling with advanced settings
JohnDuprey Jul 6, 2026
b1bc57f
feat: enhance drift data handling by pruning stale entries and tracki…
JohnDuprey Jul 7, 2026
61c55e7
Update Invoke-ListCVEManagement.ps1
DamienMatthys Jul 7, 2026
866ede9
Update Get-CIPPCVEReport.ps1
DamienMatthys Jul 7, 2026
2999e36
App registration love
TecharyJames Jul 7, 2026
403082a
Update Invoke-ExecManageAppCredentials.ps1
TecharyJames Jul 7, 2026
158ebf2
Introduce pipeline streaming for graph get request to reduce memory d…
Zacgoose Jul 7, 2026
cb33a14
Harden KV and Offloading name resolutions
Zacgoose Jul 7, 2026
122fbf2
remove copilot feature flag. its timmmeee
KelvinTegelaar Jul 7, 2026
168a110
SSO manual cred input
Zacgoose Jul 7, 2026
bf3f228
fixes manual run jobs with detectedApp data
KelvinTegelaar Jul 7, 2026
9c91d04
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 7, 2026
405c55d
Update Update-CIPPSSORedirectUri.ps1
Zacgoose Jul 7, 2026
9520792
feat: Include SSO migration status in stats timer
JohnDuprey Jul 7, 2026
9c5b576
Last copilot AI improvements reporting.
KelvinTegelaar Jul 7, 2026
ef91c5b
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 7, 2026
c0573d2
feat: Enhance reusable settings template handling in tenant alignment…
JohnDuprey Jul 7, 2026
239cfeb
feat: Refactor target object handling in Get-CippCustomDataAttributes…
JohnDuprey Jul 7, 2026
fea7f9f
shadow ai updates
KelvinTegelaar Jul 7, 2026
5b7cf18
json updates
KelvinTegelaar Jul 7, 2026
fe93fbd
Self fix on read duplicate key values for KeepCopy, keepCopy and keep…
Zacgoose Jul 8, 2026
be7b3a7
Fix for when editing a scheduled and no hidden param is sent from the…
Zacgoose Jul 8, 2026
0a520a2
Feat: App registration enhancements (#2132)
KelvinTegelaar Jul 8, 2026
0dac60d
Fix: Added more properties to CVE management, improved efficiency (#2…
KelvinTegelaar Jul 8, 2026
c902546
Remove legacy formatting for antiphish standard
Zacgoose Jul 8, 2026
ff91091
fix: exclude .None permissions from permission check
JohnDuprey Jul 8, 2026
bc3230e
fix: ensure sorted output for child values and handle comparison erro…
JohnDuprey Jul 8, 2026
660a177
Optionally set company branding for usernameHintText and signInPageTe…
Zacgoose Jul 8, 2026
15cc4b4
feat: enhance role permission handling and introduce Get-CippHttpPerm…
JohnDuprey Jul 8, 2026
23502b9
feat: add functions to format alert cell values and normalize alert d…
JohnDuprey Jul 8, 2026
faa1b84
fix: add member to upn field candidates
JohnDuprey Jul 9, 2026
856a5c3
Feature Flag updates
Zacgoose Jul 9, 2026
4f2dad2
Custom Tests Results Overview page
Zacgoose Jul 9, 2026
aa7e060
sharepoint reports
KelvinTegelaar Jul 9, 2026
70a8722
Add or update the Azure App Service build and deployment workflow config
KelvinTegelaar Jul 9, 2026
e7ed3a2
extra logging
KelvinTegelaar Jul 9, 2026
e106d4d
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 9, 2026
6c86428
oom management
KelvinTegelaar Jul 9, 2026
82ac60e
introducing streaming
KelvinTegelaar Jul 9, 2026
da30ffc
feat: Add SAM cert lifecycle management and endpoint
JohnDuprey Jul 9, 2026
bf76f2b
feat: Support SAM certificate setup exemptions
JohnDuprey Jul 9, 2026
2e636ca
feat: Unify certificate token auth flow
JohnDuprey Jul 9, 2026
98e1a31
fix: Preserve EXO error responses
JohnDuprey Jul 9, 2026
035b862
merge issue
KelvinTegelaar Jul 9, 2026
ce34525
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 9, 2026
5f2a3e3
feat: Enhance SAM certificate handling with preload and cache update …
JohnDuprey Jul 9, 2026
559036d
fix for listening libraries
KelvinTegelaar Jul 9, 2026
beae113
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 9, 2026
94ab1af
fix as app because I forgot
KelvinTegelaar Jul 9, 2026
510236d
fixes cve management issue.
KelvinTegelaar Jul 9, 2026
3ba7744
add license name to offboarding
KelvinTegelaar Jul 9, 2026
2b3ec21
fix: SAM certificate provisioning in authentication load
JohnDuprey Jul 9, 2026
5d3befc
fix: add onprem sync attributes
JohnDuprey Jul 10, 2026
d50b717
feat: Support non-group SharePoint member updates
JohnDuprey Jul 10, 2026
0fe9645
feat: Improve SharePoint site role membership handling
JohnDuprey Jul 10, 2026
d06d7fc
feat: Enhance group member addition and removal logging with group names
JohnDuprey Jul 10, 2026
2bc15bf
feat: Add SiteUrl parameter to Get-CIPPSPOSite and implement single-s…
JohnDuprey Jul 10, 2026
2e8531c
feat: Enhanced SharePoint site management functionality
JohnDuprey Jul 10, 2026
c134795
Fixes for mem cache performance
Zacgoose Jul 10, 2026
c6e67b2
tag update
KelvinTegelaar Jul 10, 2026
101477f
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 10, 2026
7c86a6a
fix for template names when cant be found
KelvinTegelaar Jul 10, 2026
36759b2
fixed in dev
KelvinTegelaar Jul 10, 2026
cad96bb
feat: add email aliases and hide-from-GAL to group templates (#2130)
KelvinTegelaar Jul 10, 2026
3777ac2
rollup multiple versions of same tool
KelvinTegelaar Jul 10, 2026
c59b130
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar Jul 10, 2026
06d0bd8
feat: add functions to manage SharePoint external users and site user…
JohnDuprey Jul 10, 2026
e42d8d3
version up
KelvinTegelaar Jul 10, 2026
8aa4d31
Merge branch 'master' into dev
KelvinTegelaar Jul 10, 2026
f921f04
version up
KelvinTegelaar Jul 10, 2026
11beb6d
Conventional Commits Check for PR titles
Zacgoose Jul 10, 2026
fd23ff2
Dev to release (#2135)
KelvinTegelaar Jul 10, 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
  •  
  •  
  •  
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