Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
3670 commits
Select commit Hold shift + click to select a range
c750267
Custom Test Engine converted to a CLM runtime
Zacgoose Jun 22, 2026
f517937
API client RBAC checks before creation
Zacgoose Jun 22, 2026
0a3409a
Update FeatureFlags.json
Zacgoose Jun 22, 2026
a2dec42
Intune Policy sync fixes
Zacgoose Jun 22, 2026
351c7f3
fix: hardcode owner/repo in release notes api
JohnDuprey Jun 22, 2026
a8ac0bd
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
JohnDuprey Jun 22, 2026
9002cca
fix: throw on invalid nextLink url
JohnDuprey Jun 22, 2026
aefefda
chore: bump version to 10.5.4
JohnDuprey Jun 22, 2026
eed85ab
Merge pull request #203 from KelvinTegelaar/dev
pull[bot] Jun 22, 2026
e8cd121
Dev to hotfix (#2106)
JohnDuprey Jun 22, 2026
5549d62
Table cleanup fixes
Zacgoose Jun 23, 2026
ea7661a
Merge pull request #205 from KelvinTegelaar/dev
pull[bot] Jun 23, 2026
eac806c
IP lookup and Audit Log Processing improvements
Zacgoose Jun 24, 2026
a7093da
Merge pull request #206 from KelvinTegelaar/dev
pull[bot] Jun 24, 2026
f690b6d
More reliable RG name resolution
Zacgoose Jun 24, 2026
739d378
90 Day cache cleanup
Zacgoose Jun 24, 2026
b560d15
Move APISpec to config folder
Zacgoose Jun 24, 2026
850f6a2
New Licence Updates
Zacgoose Jun 24, 2026
4d112f5
User Offboarding task validation
Zacgoose Jun 24, 2026
9895ce6
Merge pull request #207 from KelvinTegelaar/dev
pull[bot] Jun 24, 2026
05f5f1f
alert fixes for custom tests
Zacgoose Jun 24, 2026
0c3d4ba
Custom Test Alerting overhaul
Zacgoose Jun 24, 2026
ff0185d
Merge pull request #208 from KelvinTegelaar/dev
pull[bot] Jun 24, 2026
a8143b4
feat(defender): add MTD role, realign iOS sync
kris6673 Jun 25, 2026
63e0b12
Feat/Fix: Add Mobile Threat Defense role and realign iOS sync (#2108)
Zacgoose Jun 25, 2026
7dea7f4
Requirements clarification
Zacgoose Jun 25, 2026
dc3614b
Merge pull request #209 from KelvinTegelaar/dev
pull[bot] Jun 25, 2026
68595cc
feat: incident severity + resolving comment
kris6673 Jun 25, 2026
ac8f243
Language and Region fixes
Zacgoose Jun 25, 2026
6c62d78
Blank value fixes
Zacgoose Jun 25, 2026
dc8b3af
Update Set-CIPPStandardsCompareField.ps1
Zacgoose Jun 25, 2026
e21df9c
Update New-ExoRequest.ps1
Zacgoose Jun 25, 2026
158e973
Update Set-CIPPSAMAdminRoles.ps1
Zacgoose Jun 25, 2026
e6c0c93
Update Set-CIPPSAMAdminRoles.ps1
Zacgoose Jun 25, 2026
67856c4
Update New-ExoRequest.ps1
Zacgoose 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
fe87252
Revert "Update New-ExoRequest.ps1"
Zacgoose Jun 26, 2026
ad7e409
Revert "Update Set-CIPPSAMAdminRoles.ps1"
Zacgoose Jun 26, 2026
3402665
Merge pull request #211 from KelvinTegelaar/dev
pull[bot] Jun 26, 2026
b6b918e
permission repair improvements
Zacgoose Jun 26, 2026
e987ea4
Move NinjaOne Sync from BPA to Reporting DB
Zacgoose Jun 26, 2026
04b3e12
Disable App insights page when not needed
Zacgoose Jun 26, 2026
9deb458
Update Get-NinjaOneFieldMapping.ps1
Zacgoose Jun 26, 2026
428ebd3
Update Set-CIPPDBCacheRiskDetections.ps1
Zacgoose Jun 26, 2026
45b96d6
Fix contact template deployment to align with frontend changes
Zacgoose Jun 26, 2026
ce21a2d
Merge pull request #212 from KelvinTegelaar/dev
pull[bot] Jun 26, 2026
d2e88c5
Start job earlier
Zacgoose Jun 26, 2026
3204da3
Update Get-CIPPStandards.ps1 to fix Custom Quarantine Policy not repo…
Zacgoose Jun 26, 2026
6192717
Fixes for spam filter policy when using custom names
Zacgoose Jun 26, 2026
ee5c30a
feat: enhance device import status handling and logging
kris6673 Jun 26, 2026
a9b3e40
Purview DLP Policy and Standard implementation and fixes
Zacgoose 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
40ca72e
chore: update version to 10.5.5
JohnDuprey Jun 26, 2026
7cafdc6
Merge pull request #214 from KelvinTegelaar/dev
pull[bot] Jun 26, 2026
a511657
Dev to hotfix (#2113)
JohnDuprey Jun 27, 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
9445eed
Permission update fixes
Zacgoose Jun 29, 2026
a9d5c4e
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
5c2dc98
Revert permission repair changes (AsApp grant application + Jun 30 re…
Zacgoose Jul 2, 2026
3d835b5
chore: bump version to 10.5.7
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
c4915b4
Revert partner SP permission lookup and revert to table permissions l…
Zacgoose Jul 3, 2026
0ec258d
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
fb8f193
feat: Copilot instructions for commit messages
Zacgoose Jul 10, 2026
5ae4171
fix: prevent cert provision loop and skip KV 404 retries
JohnDuprey Jul 10, 2026
8e421bf
chore: update ps module from 7.4.0 to 7.8.0
Zacgoose 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
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Binary file added .DS_Store
Binary file not shown.
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.
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FUNCTIONS_WORKER_RUNTIME='powershell'
FUNCTIONS_WORKER_RUNTIME_VERSION='7.4'
AzureWebJobsStorage='DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNoBnZf6KgBVU4=;BlobEndpoint=http://azurite:10000/devstoreaccount1;QueueEndpoint=http://azurite:10001/devstoreaccount1;TableEndpoint=http://azurite:10002/devstoreaccount1;'
DEV_SKIP_BPA_TIMER='true'
DEV_SKIP_DOMAIN_TIMER='true'
FUNCTIONS_EXTENSION_VERSION='4'
NonLocalHostAzurite='true'
Loading
Loading