Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
48 changes: 48 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
### Quick orientation — cbsecurity (ColdBox module)

This repository is a ColdBox module that provides a request firewall, annotation-driven security, JWT handling, CSRF integration, and security headers.

Keep guidance short and actionable. Prefer small, verifiable edits and reference the real files below.

1) Big picture
- ColdBox module: entrypoint and wiring in `ModuleConfig.cfc` and `models/CBSecurity.cfc`.
- Runtime protection happens in the `cbsecurity.interceptors.Security` interceptor (`interceptors/Security.cfc`) which:
- loads and normalizes rules via `helpers/RulesLoader` (see `models/util/RulesLoader.cfc`),
- delegates validation to a Validator (default: `models/validators/AuthValidator.cfc`) via `ruleValidator()` and `annotationValidator()`,
- processes rule actions (redirect/override/block) and emits interception events (`cbSecurity_onInvalidAuthentication`, etc.).

2) Where to make changes
- Business logic & APIs: `models/` (e.g. `models/jwt/JwtService.cfc`, `models/CBSecurity.cfc`).
- Request enforcement: `interceptors/Security.cfc` (rule matching, IP/HTTP method validation, event overrides).
- Validation strategies: `models/validators/*` — to change how auth/authorization decisions are made.
- Module defaults & wiring: `ModuleConfig.cfc` and `box.json` for dependencies and scripts.

3) Developer workflows (how to run, test, build)
- Install deps and test harness: `box install` at repo root, then `cd test-harness && box install` (or use `box install` from root — `box.json` has `install:dependencies`).
- Run local server for integration/test harness: `box server start server-lucee@5.json` (see `box.json` scripts `start:lucee` / `start:2023`).
- Run tests: this repo uses TestBox. The package `box.json` test runner is configured to `http://localhost:60299/tests/runner.cfm` and `build/Build.cfc` calls `testbox run`. Start the server, then open that URL or run `box testbox run runner=http://localhost:60299/tests/runner.cfm`.
- Useful npm-like tasks are defined in `box.json` under `scripts` (e.g. `box task run taskFile=build/Build.cfc` used by CI). In VSCode use the Task `Run CommandBox Task`.

4) Patterns & conventions to follow
- Validators expose `ruleValidator(rule, controller)` and `annotationValidator(securedValue, controller)`. Return shape: { allow:boolean, type: "authentication"|"authorization", messages:[] }.
- Rules normalized by `RulesLoader` and stored in `properties.firewall.rules.inline`. Rule keys often used: `securelist`, `whitelist`, `httpMethods`, `allowedIPs`, `action`, `redirect`, `overrideEvent`.
- When modifying or adding handlers, prefer ColdBox handler metadata (annotations) for security: see `test-harness/handlers/*` and `handlers/Jwt.cfc` for examples.
- JWT integration relies on `models/jwt/JwtService.cfc` + `models/jwt/storages/*` and `jwt-cfml` dependency; preserve token storage API when changing.

5) Events & integration points
- Interceptor announces: `cbSecurity_onInvalidAuthentication`, `cbSecurity_onInvalidAuthorization`, `cbSecurity_onFirewallBlock` and many JWT lifecycle events (see `ModuleConfig.cfc` interceptorSettings).
- Modules can register rules in their `ModuleConfig.cfc` and are merged into the global rules by `interceptors/Security.cfc` (see `registerModule()` / `postModuleLoad`).

6) Tests & test-harness specifics
- Test harness lives in `test-harness/`. It contains a minimal ColdBox app and TestBox specs (`test-harness/tests/specs/*`). Use it to run integration specs locally.
- Runner: `test-harness/tests/runner.cfm` expects a running CF server on port 60299. Start via `box server start` using one of `server-*.json` files.

7) Small, high-value tasks for AI agents
- Add a focused unit test for a validator method in `test-harness/tests/specs/unit/`.
- When changing behavior in `Security.cfc`, update `test-harness/tests/specs/integration/*` to cover rule matching and invalid action flows.
- Preserve WireBox IDs and signatures when changing services (e.g. `authenticationService@cbauth`, `CacheStorage@cbstorages`).

8) Safety and CI
- CI uses the `build/Build.cfc` and `box.json` scripts. Do not modify CI scripts without updating `box.json` and `build/Build.cfc`.

If anything above is unclear or missing (local server ports, preferred validator override patterns, or CI details), tell me which area to expand and I will iterate.
26 changes: 26 additions & 0 deletions .github/workflows/cron.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Daily Tests

on:
schedule:
- cron: '0 0 * * *' # Runs at 00:00 UTC every day

jobs:
tests:
uses: ./.github/workflows/tests.yml
secrets: inherit

notify:
needs: [ tests ]
runs-on: ubuntu-24.04
if: ${{ always() }}
steps:
- name: Slack Notifications
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: boxlang-cron
SLACK_COLOR: ${{ job.status }} # or a specific color like 'green' or '#ff00ff'
SLACK_ICON_EMOJI: ":bell:"
SLACK_MESSAGE: '${{ github.repository }} weekly tests'
SLACK_TITLE: ${{ github.repository }} Tests results
SLACK_USERNAME: CI
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
7 changes: 3 additions & 4 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@ on:
- "main"
- "master"
- "development"
- "releases/v*"
pull_request:
branches:
- "releases/v*"
- development

jobs:
tests:
uses: ./.github/workflows/tests.yml
secrets: inherit

formatCheck:
# Format PR
format_check:
name: Checks Source Code Formatting
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
Expand Down
50 changes: 41 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,26 @@ on:
default: false
type: boolean

# Manual Trigger
workflow_dispatch:
env:
MODULE_ID: cbsecurity
MODULE_ID: ${{ github.event.repository.name }}
JDK: 21
SNAPSHOT: ${{ inputs.snapshot || false }}
BUILD_ID: ${{ github.run_number }}

jobs:
##########################################################################################
# Build & Publish
##########################################################################################
build:
name: Build & Publish
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
permissions:
checks: write
pull-requests: write
contents: write
issues: write
steps:
- name: Checkout Repository
uses: actions/checkout@v4
Expand All @@ -36,6 +45,12 @@ jobs:
with:
forgeboxAPIKey: ${{ secrets.FORGEBOX_TOKEN }}

- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: ${{ env.JDK }}

- name: "Setup Environment Variables For Build Process"
id: current_version
run: |
Expand All @@ -50,7 +65,7 @@ jobs:
fi

- name: Update changelog [unreleased] with latest version
uses: thomaseizinger/keep-a-changelog-new-release@1.3.0
uses: thomaseizinger/keep-a-changelog-new-release@3.1.0
if: env.SNAPSHOT == 'false'
with:
changelogPath: ./changelog.md
Expand All @@ -61,10 +76,10 @@ jobs:
npm install -g markdownlint-cli
markdownlint changelog.md --fix
box install commandbox-docbox
box task run taskfile=build/Build target=run :version=${{ env.VERSION }} :projectName=${{ env.MODULE_ID }} :buildID=${{ github.run_number }} :branch=${{ env.BRANCH }}
box task run taskfile=build/Build target=run :version=${{ env.VERSION }} :projectName=${{ env.MODULE_ID }} :buildID=${{ env.BUILD_ID }} :branch=${{ env.BRANCH }}

- name: Commit Changelog To Master
uses: EndBug/add-and-commit@v9.1.3
- name: Commit Changelog [unreleased] with latest version
uses: EndBug/add-and-commit@v9.1.4
if: env.SNAPSHOT == 'false'
with:
author_name: Github Actions
Expand Down Expand Up @@ -118,7 +133,7 @@ jobs:
box forgebox publish --force

- name: Create Github Release
uses: taiki-e/create-gh-release-action@v1.8.0
uses: taiki-e/create-gh-release-action@v1.8.2
continue-on-error: true
if: env.SNAPSHOT == 'false'
with:
Expand All @@ -127,14 +142,31 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
ref: refs/tags/v${{ env.VERSION }}

- name: Inform Slack
if: ${{ always() }}
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: coding
SLACK_COLOR: ${{ job.status }} # or a specific color like 'green' or '#ff00ff'
SLACK_ICON_EMOJI: ":bell:"
SLACK_MESSAGE: "Module ${{ env.MODULE_ID }} v${{ env.VERSION }} Built with ${{ job.status }}!"
SLACK_TITLE: "ColdBox Module ${{ env.MODULE_ID }}"
SLACK_USERNAME: CI
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}

##########################################################################################
# Prep Next Release
##########################################################################################
prep_next_release:
name: Prep Next Release
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
needs: [ build ]
permissions:
checks: write
pull-requests: write
contents: write
issues: write
steps:
# Checkout development
- name: Checkout Repository
Expand Down Expand Up @@ -165,7 +197,7 @@ jobs:

# Commit it back to development
- name: Commit Version Bump
uses: EndBug/add-and-commit@v9.1.3
uses: EndBug/add-and-commit@v9.1.4
with:
author_name: Github Actions
author_email: info@ortussolutions.com
Expand Down
19 changes: 17 additions & 2 deletions .github/workflows/snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ on:
branches:
- 'development'

workflow_dispatch:

# Unique group name per workflow-branch/tag combo
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
##########################################################################################
# Module Tests
Expand All @@ -18,7 +25,10 @@ jobs:
##########################################################################################
format:
name: Code Auto-Formatting
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
permissions:
contents: write
checks: write
steps:
- uses: actions/checkout@v4

Expand All @@ -28,7 +38,7 @@ jobs:
cmd: run-script format

- name: Commit Format Changes
uses: stefanzweifel/git-auto-commit-action@v4
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: Apply cfformat changes

Expand All @@ -39,5 +49,10 @@ jobs:
uses: ./.github/workflows/release.yml
needs: [ tests, format ]
secrets: inherit
permissions:
checks: write
pull-requests: write
contents: write
issues: write
with:
snapshot: true
38 changes: 21 additions & 17 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,39 @@ on:
jobs:
tests:
name: Tests
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
env:
DB_USER: root
DB_PASSWORD: root
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
cfengine: [ "lucee@5", "adobe@2018", "adobe@2021", "adobe@2023" ]
coldboxVersion: [ "^6.0.0", "^7.0.0" ]
cfengine: [ "boxlang-cfml@1", "lucee@5", "lucee@6", "adobe@2023", "adobe@2025" ]
coldboxVersion: [ "^7.0.0", "^8.0.0" ]
experimental: [ false ]
# Here we tests all engines against ColdBox@BE
# Experimental: ColdBox BE vs All Engines
include:
- coldboxVersion: "be"
cfengine: "lucee@5"
cfengine: "lucee@6"
experimental: true
- coldboxVersion: "be"
cfengine: "adobe@2018"
cfengine: "adobe@2023"
experimental: true
- coldboxVersion: "be"
cfengine: "adobe@2021"
cfengine: "boxlang-cfml@1"
experimental: true
- coldboxVersion: "be"
cfengine: "adobe@2023"
# BoxLang PRIME with ColdBox 8
- coldboxVersion: "8"
cfengine: "boxlang-cfml@1"
experimental: true
# BoxLang CFML BE with ColdBox 8
- coldboxVersion: "8"
cfengine: "boxlang-cfml@be"
experimental: true
steps:
- name: Checkout Repository
uses: actions/checkout@v4


- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "11"
uses: actions/checkout@v5

- name: Setup Database and Fixtures
run: |
Expand All @@ -54,6 +52,12 @@ jobs:
# Import Database
mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} < test-harness/tests/resources/cbsecurity.sql

- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "21"

- name: Setup Environment For Testing Process
run: |
# Setup .env
Expand Down
2 changes: 1 addition & 1 deletion .markdownlint.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"no-multiple-blanks": {
"maximum": 2
},
"no-duplicate-heading" : false,
"no-duplicate-header" : {
"siblings_only" : true
},
"no-duplicate-heading" : false,
"no-inline-html" : false
}
15 changes: 4 additions & 11 deletions box.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name":"ColdBox Security",
"version":"3.4.3",
"version":"3.5.0",
"location":"https://downloads.ortussolutions.com/ortussolutions/coldbox-modules/cbsecurity/@build.version@/cbsecurity-@build.version@.zip",
"author":"Ortus Solutions.com <info@ortussolutions.com>",
"slug":"cbsecurity",
Expand Down Expand Up @@ -28,10 +28,9 @@
"cbcsrf":"^3.0.0"
},
"devDependencies":{
"commandbox-boxlang":"*",
"commandbox-cfformat":"*",
"commandbox-docbox":"*",
"commandbox-dotenv":"*",
"commandbox-cfconfig":"*"
"commandbox-docbox":"*"
},
"ignore":[
"**/.*",
Expand All @@ -48,18 +47,12 @@
"format":"cfformat run handlers/,interceptors/,models/,test-harness/tests/specs,ModuleConfig.cfc --overwrite",
"format:watch":"cfformat watch handlers/,interceptors/,models/,test-harness/tests/specs,ModuleConfig.cfc ./.cfformat.json",
"format:check":"cfformat check handlers/,interceptors/,models/,test-harness/tests/specs,ModuleConfig.cfc",
"install:dependencies":"install && cd test-harness && install",
"install:dependencies":"install --force && cd test-harness && install --force",
"start:lucee":"server start serverConfigFile=server-lucee@5.json",
"start:2018":"server start serverConfigFile=server-adobe@2018.json",
"start:2021":"server start serverConfigFile=server-adobe@2021.json",
"start:2023":"server start serverConfigFile=server-adobe@2023.json",
"stop:lucee":"server stop serverConfigFile=server-lucee@5.json",
"stop:2018":"server stop serverConfigFile=server-adobe@2018.json",
"stop:2021":"server stop serverConfigFile=server-adobe@2021.json",
"stop:2023":"server stop serverConfigFile=server-adobe@2023.json",
"logs:lucee":"server log serverConfigFile=server-lucee@5.json --follow",
"logs:2018":"server log serverConfigFile=server-adobe@2018.json --follow",
"logs:2021":"server log serverConfigFile=server-adobe@2021.json --follow",
"logs:2023":"server log serverConfigFile=server-adobe@2023.json --follow"
},
"installPaths":{
Expand Down
Loading
Loading