Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
# These are supported funding model platforms

github: [kelvintegelaar]
92 changes: 92 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: "🐞 Bug report"
description: "Report errors or unexpected behaviors for CIPP and CIPP-API"
title: "[Bug]: "
labels:
- "unconfirmed-by-user"
- "bug"

body:
- type: markdown
attributes:
value: |
**Thank you for taking the time to report a potential bug for CIPP and CIPP-API!**

Please follow the instructions below and provide as much detail as possible to help us understand and reproduce the issue.

- type: checkboxes
id: confirmations
attributes:
label: "Required confirmations before submitting"
description: "Please check all boxes that apply."
options:
- label: "**I can reproduce this issue on the latest released versions** of both CIPP and CIPP-API."
required: true
- label: "**I have searched existing issues** (both open and closed) to avoid duplicates."
required: true
- label: "I am **not** requesting general support; this is an actual bug report."
required: true

# 3) Description / Steps to reproduce
- type: textarea
id: description
attributes:
label: "Issue Description"
description: |
**Describe the issue clearly and provide step-by-step instructions to reproduce it.**
Screenshots can be attached by pasting them here.

Example steps to reproduce:
1. Go to **Settings**
2. Click on a tenant in **Access Check**
3. Click on the green pixel in the bottom-right corner
4. Observe the unexpected behavior
validations:
required: true

# 4) Environment type (Sponsored vs. Non-sponsored)
- type: dropdown
id: environment_type
attributes:
label: "Environment Type"
description: "Select whether you are using currently a paying user of the product, or if you are utilizing the free version"
options:
- "Sponsored (paying) user"
- "Non-sponsored user"
validations:
required: true

# 5) Front End / Back End versions
- type: input
id: front_end_version
attributes:
label: "Front End Version"
description: "Please specify the front end version number (e.g., v1.2.3)."
validations:
required: true

- type: input
id: back_end_version
attributes:
label: "Back End Version"
description: "Please specify the back end version number (e.g., v1.2.3)."
validations:
required: true

# 7) Additional logs or trace (optional)
- type: textarea
id: logs
attributes:
label: "Relevant Logs / Stack Trace"
description: |
If available, please share any relevant logs or stack trace data.
Remove or redact any sensitive info before posting.
render: plaintext
validations:
required: false

# 8) Closing note
- type: markdown
attributes:
value: |
Thank you for your submission! A maintainer will review your report.
Please watch the issue for follow-up questions or status updates.
9 changes: 9 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
blank_issues_enabled: false
contact_links:
- name: Security Reports
url: https://github.com/KelvinTegelaar/CIPP/security/advisories
about: Please report security vulnerabilities here.
- name: Community Discord
url: https://discord.gg/cyberdrain
about: Join our discord community here.

84 changes: 84 additions & 0 deletions .github/ISSUE_TEMPLATE/feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: "✨ Feature request"
description: "Suggest a new feature or improvement"
title: "[Feature Request]: "
labels:
- "enhancement"
- "no-priority"

body:
# Introductory Markdown
- type: markdown
attributes:
value: |
**Thank you for suggesting a new feature or improvement for CIPP**

Before creating a request, please:

1. Check that you have an active sponsorship, only users that are sponsoring CIPP at the $99,- sponsorship level can create feature requests.
1. Search existing **open and closed** feature requests to avoid duplicates.
2. Note that **repeat feature requests** are permitted if a previous request was closed more than 30 days ago.
3. Consider implementing the feature yourself by reviewing the [development documentation](https://docs.cipp.app/dev-documentation/cipp-dev-guide/setting-up-for-local-development).
4. Feature requests that lack sufficient detail or feasibility may be closed at any time.
5. **This request will auto-close in 14 days** if no meaningful progress or collaboration occurs.
6. If you would like to work on this feature, comment `"I'd like to work on this please!"`
7. Any request that is detrimental to security or the product’s stability will be closed without notice.

# Checkboxes for Confirmations
- type: checkboxes
id: confirmations
attributes:
label: "Please confirm:"
description: "Check all boxes that apply."
options:
- label: "**I have searched existing feature requests** (open and closed) and found no duplicates."
required: true
- label: "**me or my organization is currently an active sponsor of the product at the $99,- level."
required: true

- type: textarea
id: problem-statement
attributes:
label: "Problem Statement"
description: |
**What problem does this feature solve or what gap does it fill?**
Provide a concise explanation. For example:
- "When I need to enable MFA for all users, it takes a lot of time to do it per user. I'd like to enable this for all users in button press"
- "To update a user property for exchange I need to go through 5 portals and 2 systems to be able to make a change."
validations:
required: true

# Field 2: Benefits for MSPs
- type: textarea
id: msp-benefits
attributes:
label: "Benefits for MSPs"
description: |
**How would this feature help MSPs in their day-to-day tasks or overall operations?**
- Does it reduce manual work?
- Does it improve security or scalability?
- Does it offer clarity or automation to commonly repeated tasks?
validations:
required: true

# Field 3: Value or Importance
- type: textarea
id: feature-value
attributes:
label: "Value or Importance"
description: |
**Why is this feature particularly valuable or important to add?**
- If it's critical, explain why.
- If it's optional or nice-to-have, describe how it still adds notable value.
validations:
required: true

# Optional field for PowerShell commands
- type: textarea
id: powershell-commands
attributes:
label: "PowerShell Commands (Optional)"
description: |
If you currently achieve this functionality or a similar workaround using PowerShell, please share your scripts or snippets here.
This information helps contributors understand the existing workflow and aids in development.
validations:
required: false
45 changes: 45 additions & 0 deletions .github/agents/CIPP-Alert-Agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
name: CIPP Frontend Alert Registrar
description: >
Adds new alert entries to src/data/alerts.json in the CIPP frontend.
The agent must never modify any other file or perform any other change.
---

# CIPP Frontend Alert Registrar

## Mission

You are a **frontend alert registrar** responsible for updating the `src/data/alerts.json` file to include new alerts.

Your role is **strictly limited** to adding a new JSON entry describing the alert’s metadata.
You do not touch or inspect any other part of the codebase.

---

## Scope of Work

This agent is used when a new alert must be surfaced to the frontend — for example, after a new backend `Get-CIPPAlert*.ps1` alert has been added.

Tasks include:

- Opening `src/data/alerts.json`
- Appending one new JSON object describing the new alert
- Preserving JSON structure, indentation, and trailing commas exactly as in the existing file
- Validating that the resulting JSON is syntactically correct


## Alert Format

Each alert entry in `src/data/alerts.json` is a JSON object with the following structure:

```json
{
"name": "<alertName>",
"label": "A nice label for the alert",
"requiresInput": true,
"inputType": "switch",
"inputLabel": "Exclude disabled users?",
"inputName": "InactiveLicensedUsersExcludeDisabled",
"recommendedRunInterval": "1d"
}
```
45 changes: 45 additions & 0 deletions .github/agents/CIPP-Frontend-Alert-Agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
name: CIPP Frontend Alert Registrar
description: >
Adds new alert entries to src/data/alerts.json in the CIPP frontend.
The agent must never modify any other file or perform any other change.
---

# CIPP Frontend Alert Registrar

## Mission

You are a **frontend alert registrar** responsible for updating the `src/data/alerts.json` file to include new alerts.

Your role is **strictly limited** to adding a new JSON entry describing the alert’s metadata.
You do not touch or inspect any other part of the codebase.

---

## Scope of Work

This agent is used when a new alert must be surfaced to the frontend — for example, after a new backend `Get-CIPPAlert*.ps1` alert has been added.

Tasks include:

- Opening `src/data/alerts.json`
- Appending one new JSON object describing the new alert
- Preserving JSON structure, indentation, and trailing commas exactly as in the existing file
- Validating that the resulting JSON is syntactically correct


## Alert Format

Each alert entry in `src/data/alerts.json` is a JSON object with the following structure:

```json
{
"name": "<alertName>",
"label": "A nice label for the alert",
"requiresInput": true,
"inputType": "switch",
"inputLabel": "Exclude disabled users?",
"inputName": "InactiveLicensedUsersExcludeDisabled",
"recommendedRunInterval": "1d"
}
```
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
target-branch: "dev"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
target-branch: "dev"
11 changes: 11 additions & 0 deletions .github/pull.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: "1"
rules:
- base: main
upstream: KelvinTegelaar:main
mergeMethod: merge
- base: dev
upstream: KelvinTegelaar:dev
mergeMethod: none
- base: website
upstream: KelvinTegelaar:website
mergeMethod: merge
71 changes: 71 additions & 0 deletions .github/scripts/validate-json.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { readFile, readdir, writeFile, appendFile } from "node:fs/promises";
import path from "node:path";

// Usage: node validate-json.mjs [--strip <prefix>] <dir> [dir...]
// --strip removes a leading path prefix from reported filenames, so a PR checked
// out into a subdirectory still reports repo-relative paths.
const argv = process.argv.slice(2);
let strip = "";
const roots = [];
for (let i = 0; i < argv.length; i++) {
if (argv[i] === "--strip") {
strip = argv[++i] ?? "";
} else {
roots.push(argv[i]);
}
}

async function collect(dir) {
let entries;
try {
entries = await readdir(dir, { withFileTypes: true });
} catch (error) {
if (error.code === "ENOENT") return [];
throw error;
}
const files = [];
for (const entry of entries) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) {
if (entry.name === "node_modules") continue;
files.push(...(await collect(full)));
} else if (entry.name.endsWith(".json")) {
files.push(full);
}
}
return files;
}

const report = (file) => {
const normalised = file.split(path.sep).join("/");
return strip && normalised.startsWith(strip) ? normalised.slice(strip.length) : normalised;
};

const failures = [];
let checked = 0;

for (const root of roots) {
for (const file of await collect(root)) {
checked++;
const contents = await readFile(file, "utf8");
try {
JSON.parse(contents);
} catch (error) {
failures.push({ file: report(file), message: error.message.replace(/\r?\n/g, " ") });
}
}
}

for (const { file, message } of failures) {
// Annotate the PR diff via a GitHub Actions error command.
console.log(`::error file=${file}::${message}`);
}
console.log(`Checked ${checked} JSON file(s), ${failures.length} invalid.`);

// Hand the results to the workflow so it can comment on the PR.
if (process.env.GITHUB_OUTPUT) {
await appendFile(process.env.GITHUB_OUTPUT, `invalid_count=${failures.length}\n`);
}
await writeFile("json-validation-results.json", JSON.stringify(failures, null, 2));

process.exit(failures.length > 0 ? 1 : 0);
12 changes: 12 additions & 0 deletions .github/workflows/Assign_Issue_Volunteer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
name: "Issue volunteer assignment"
on:
issue_comment:
types: [created]
jobs:
volunteer:
runs-on: ubuntu-slim
steps:
- uses: kris6673/issue-volunteer@v0.2.0
with:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
Loading
Loading