@codyswann/lisa 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cdk/copy-overwrite/jest.cdk.ts +71 -0
- package/cdk/copy-overwrite/jest.config.ts +28 -0
- package/cdk/copy-overwrite/tsconfig.cdk.json +14 -0
- package/cdk/copy-overwrite/tsconfig.eslint.json +2 -1
- package/cdk/copy-overwrite/tsconfig.json +3 -0
- package/cdk/create-only/cdk.json +23 -0
- package/cdk/create-only/tsconfig.local.json +4 -0
- package/expo/copy-overwrite/.claude/skills/owasp-zap/SKILL.md +56 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +5 -10
- package/expo/copy-overwrite/.github/workflows/zap-baseline.yml +107 -0
- package/expo/copy-overwrite/.zap/baseline.conf +36 -0
- package/expo/copy-overwrite/jest.config.ts +28 -0
- package/expo/copy-overwrite/jest.expo.ts +119 -0
- package/expo/copy-overwrite/scripts/zap-baseline.sh +92 -0
- package/expo/copy-overwrite/tsconfig.eslint.json +2 -1
- package/expo/copy-overwrite/tsconfig.expo.json +12 -0
- package/expo/copy-overwrite/tsconfig.json +5 -0
- package/expo/create-only/.github/workflows/ci.yml +8 -0
- package/expo/create-only/tsconfig.local.json +3 -0
- package/expo/package-lisa/package.lisa.json +4 -2
- package/nestjs/copy-overwrite/.github/workflows/zap-baseline.yml +123 -0
- package/nestjs/copy-overwrite/.zap/baseline.conf +39 -0
- package/nestjs/copy-overwrite/jest.config.ts +28 -0
- package/nestjs/copy-overwrite/jest.nestjs.ts +89 -0
- package/nestjs/copy-overwrite/scripts/zap-baseline.sh +99 -0
- package/nestjs/copy-overwrite/tsconfig.build.json +5 -0
- package/nestjs/copy-overwrite/tsconfig.eslint.json +10 -0
- package/nestjs/copy-overwrite/tsconfig.json +5 -0
- package/nestjs/copy-overwrite/tsconfig.nestjs.json +16 -0
- package/nestjs/copy-overwrite/tsconfig.spec.json +7 -0
- package/nestjs/create-only/.github/workflows/ci.yml +8 -0
- package/nestjs/create-only/tsconfig.local.json +6 -0
- package/nestjs/package-lisa/package.lisa.json +2 -1
- package/package.json +1 -1
- package/typescript/copy-overwrite/.claude/commands/security/zap-scan.md +12 -0
- package/typescript/copy-overwrite/.github/workflows/quality.yml +100 -5
- package/typescript/copy-overwrite/jest.base.ts +112 -0
- package/typescript/copy-overwrite/jest.config.ts +34 -0
- package/typescript/copy-overwrite/jest.typescript.ts +72 -0
- package/typescript/copy-overwrite/tsconfig.base.json +15 -0
- package/typescript/copy-overwrite/tsconfig.eslint.json +3 -2
- package/typescript/copy-overwrite/tsconfig.json +5 -0
- package/typescript/copy-overwrite/tsconfig.typescript.json +11 -0
- package/typescript/create-only/jest.config.local.ts +30 -0
- package/typescript/create-only/jest.thresholds.json +8 -0
- package/typescript/create-only/tsconfig.local.json +6 -0
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"fetch:graphql:schema:staging": "./scripts/fetch-graphql-schema.sh staging",
|
|
19
19
|
"fetch:graphql:schema:production": "./scripts/fetch-graphql-schema.sh production",
|
|
20
20
|
"export:web": "expo export --platform web --source-maps",
|
|
21
|
-
"pre-build:eas": "cat .gitignore > .easignore && cat .easignore.extra >> .easignore"
|
|
21
|
+
"pre-build:eas": "cat .gitignore > .easignore && cat .easignore.extra >> .easignore",
|
|
22
|
+
"security:zap": "bash scripts/zap-baseline.sh"
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"@apollo/client": "^3.10.8",
|
|
@@ -117,7 +118,8 @@
|
|
|
117
118
|
"expo-atlas": "^0.4.0",
|
|
118
119
|
"globals": "^16.0.0",
|
|
119
120
|
"jest-environment-jsdom": "^30.2.0",
|
|
120
|
-
"jest-expo": "^54.0.12"
|
|
121
|
+
"jest-expo": "^54.0.12",
|
|
122
|
+
"serve": "^14.2.0"
|
|
121
123
|
},
|
|
122
124
|
"resolutions": {
|
|
123
125
|
"eslint-plugin-react-hooks": "^7.0.0",
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# This file is managed by Lisa.
|
|
2
|
+
# Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
3
|
+
|
|
4
|
+
name: ZAP Baseline Scan (NestJS)
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
workflow_call:
|
|
8
|
+
inputs:
|
|
9
|
+
node_version:
|
|
10
|
+
description: 'Node.js version to use'
|
|
11
|
+
required: false
|
|
12
|
+
default: '22.21.1'
|
|
13
|
+
type: string
|
|
14
|
+
package_manager:
|
|
15
|
+
description: 'Package manager to use (npm, yarn, or bun)'
|
|
16
|
+
required: false
|
|
17
|
+
default: 'bun'
|
|
18
|
+
type: string
|
|
19
|
+
zap_target_url:
|
|
20
|
+
description: 'Override URL for ZAP to scan (default: http://localhost:3000/graphql)'
|
|
21
|
+
required: false
|
|
22
|
+
default: 'http://localhost:3000/graphql'
|
|
23
|
+
type: string
|
|
24
|
+
zap_rules_file:
|
|
25
|
+
description: 'Path to ZAP rules configuration file'
|
|
26
|
+
required: false
|
|
27
|
+
default: '.zap/baseline.conf'
|
|
28
|
+
type: string
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
zap_baseline:
|
|
32
|
+
name: ZAP Baseline Scan
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
timeout-minutes: 20
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout repository
|
|
38
|
+
uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- name: Setup Node.js
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: ${{ inputs.node_version }}
|
|
44
|
+
cache: ${{ inputs.package_manager != 'bun' && inputs.package_manager || '' }}
|
|
45
|
+
|
|
46
|
+
- name: Setup Bun
|
|
47
|
+
if: inputs.package_manager == 'bun'
|
|
48
|
+
uses: oven-sh/setup-bun@v2
|
|
49
|
+
with:
|
|
50
|
+
bun-version: '1.3.8'
|
|
51
|
+
|
|
52
|
+
- name: Install dependencies
|
|
53
|
+
run: |
|
|
54
|
+
if [ "${{ inputs.package_manager }}" = "npm" ]; then
|
|
55
|
+
npm ci
|
|
56
|
+
elif [ "${{ inputs.package_manager }}" = "yarn" ]; then
|
|
57
|
+
yarn install --frozen-lockfile
|
|
58
|
+
elif [ "${{ inputs.package_manager }}" = "bun" ]; then
|
|
59
|
+
bun install --frozen-lockfile
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
- name: Build project
|
|
63
|
+
run: ${{ inputs.package_manager }} run build
|
|
64
|
+
|
|
65
|
+
- name: Start NestJS server
|
|
66
|
+
run: |
|
|
67
|
+
${{ inputs.package_manager }} run start &
|
|
68
|
+
SERVER_PID=$!
|
|
69
|
+
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
|
|
70
|
+
env:
|
|
71
|
+
NODE_ENV: test
|
|
72
|
+
PORT: 3000
|
|
73
|
+
|
|
74
|
+
- name: Wait for server ready
|
|
75
|
+
run: |
|
|
76
|
+
echo "Waiting for NestJS server to be ready..."
|
|
77
|
+
RETRIES=30
|
|
78
|
+
until curl -sf http://localhost:3000/health > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
|
|
79
|
+
echo "Waiting for server... ($RETRIES retries left)"
|
|
80
|
+
RETRIES=$((RETRIES - 1))
|
|
81
|
+
sleep 2
|
|
82
|
+
done
|
|
83
|
+
if [ $RETRIES -eq 0 ]; then
|
|
84
|
+
echo "Server failed to start within timeout"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
echo "Server is ready"
|
|
88
|
+
|
|
89
|
+
- name: Check for ZAP rules file
|
|
90
|
+
id: check_rules
|
|
91
|
+
run: |
|
|
92
|
+
if [ -f "${{ inputs.zap_rules_file }}" ]; then
|
|
93
|
+
echo "has_rules=true" >> $GITHUB_OUTPUT
|
|
94
|
+
else
|
|
95
|
+
echo "has_rules=false" >> $GITHUB_OUTPUT
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
- name: Run ZAP baseline scan
|
|
99
|
+
uses: zaproxy/action-baseline@v0.14.0
|
|
100
|
+
with:
|
|
101
|
+
target: ${{ inputs.zap_target_url }}
|
|
102
|
+
rules_file_name: ${{ steps.check_rules.outputs.has_rules == 'true' && inputs.zap_rules_file || '' }}
|
|
103
|
+
fail_action: true
|
|
104
|
+
allow_issue_writing: false
|
|
105
|
+
artifact_name: 'zap-report-nestjs'
|
|
106
|
+
|
|
107
|
+
- name: Stop NestJS server
|
|
108
|
+
if: always()
|
|
109
|
+
run: |
|
|
110
|
+
if [ -n "$SERVER_PID" ]; then
|
|
111
|
+
kill "$SERVER_PID" 2>/dev/null || true
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
- name: Upload ZAP report
|
|
115
|
+
if: always()
|
|
116
|
+
uses: actions/upload-artifact@v4
|
|
117
|
+
with:
|
|
118
|
+
name: zap-baseline-report-nestjs-${{ github.run_id }}
|
|
119
|
+
path: |
|
|
120
|
+
zap-report.html
|
|
121
|
+
zap-report.json
|
|
122
|
+
zap-report.md
|
|
123
|
+
retention-days: 14
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# OWASP ZAP Baseline Scan Configuration — NestJS GraphQL APIs
|
|
2
|
+
# Format: <rule_id> <action> <description>
|
|
3
|
+
# Actions: IGNORE (skip rule), WARN (report but don't fail), FAIL (fail on finding)
|
|
4
|
+
#
|
|
5
|
+
# Tuned for NestJS APIs behind API Gateway/load balancer in production.
|
|
6
|
+
# Transport-level headers are enforced at infrastructure layer.
|
|
7
|
+
|
|
8
|
+
# CSP header — API responses don't serve HTML; CSP is a browser concern
|
|
9
|
+
10038 WARN (Content Security Policy (CSP) Header Not Set)
|
|
10
|
+
|
|
11
|
+
# X-Content-Type-Options — should be set but is infrastructure-level
|
|
12
|
+
10021 WARN (X-Content-Type-Options Header Missing)
|
|
13
|
+
|
|
14
|
+
# Strict-Transport-Security — enforced at API Gateway/load balancer
|
|
15
|
+
10035 WARN (Strict-Transport-Security Header Not Set)
|
|
16
|
+
|
|
17
|
+
# X-Frame-Options — API responses are not rendered in browsers
|
|
18
|
+
10020 IGNORE (X-Frame-Options Header Not Set)
|
|
19
|
+
|
|
20
|
+
# Permissions-Policy — not applicable to API responses
|
|
21
|
+
10063 IGNORE (Permissions Policy Header Not Set)
|
|
22
|
+
|
|
23
|
+
# Server header disclosure — NestJS/Express may leak version info;
|
|
24
|
+
# should be suppressed in production via Helmet middleware
|
|
25
|
+
10036 WARN (Server Leaks Version Information via "Server" HTTP Response Header Field)
|
|
26
|
+
|
|
27
|
+
# Cookie flags — GraphQL APIs may use session cookies for auth
|
|
28
|
+
10010 FAIL (Cookie No HttpOnly Flag)
|
|
29
|
+
10011 FAIL (Cookie Without Secure Flag)
|
|
30
|
+
10054 WARN (Cookie without SameSite Attribute)
|
|
31
|
+
|
|
32
|
+
# Information disclosure in URL — GraphQL uses POST body, not URL params
|
|
33
|
+
10024 IGNORE (Information Disclosure - Sensitive Information in URL)
|
|
34
|
+
|
|
35
|
+
# Cross-domain JavaScript source — not applicable to API
|
|
36
|
+
10017 IGNORE (Cross-Domain JavaScript Source File Inclusion)
|
|
37
|
+
|
|
38
|
+
# Application error disclosure — NestJS should not leak stack traces
|
|
39
|
+
10023 FAIL (Information Disclosure - Debug Error Messages)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is managed by Lisa.
|
|
3
|
+
* Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Jest Configuration - Main Entry Point (NestJS)
|
|
8
|
+
*
|
|
9
|
+
* Imports the NestJS-specific configuration and project-local customizations.
|
|
10
|
+
* Do not modify this file directly - use jest.config.local.ts for project-specific settings.
|
|
11
|
+
*
|
|
12
|
+
* Inheritance chain:
|
|
13
|
+
* jest.config.ts (this file)
|
|
14
|
+
* └── jest.nestjs.ts
|
|
15
|
+
* └── jest.base.ts
|
|
16
|
+
*
|
|
17
|
+
* @see https://jestjs.io/docs/configuration
|
|
18
|
+
* @module jest.config
|
|
19
|
+
*/
|
|
20
|
+
import { mergeConfigs, mergeThresholds } from "./jest.base.ts";
|
|
21
|
+
import { defaultThresholds, getNestjsJestConfig } from "./jest.nestjs.ts";
|
|
22
|
+
|
|
23
|
+
import localConfig from "./jest.config.local.ts";
|
|
24
|
+
import thresholdsOverrides from "./jest.thresholds.json" with { type: "json" };
|
|
25
|
+
|
|
26
|
+
const thresholds = mergeThresholds(defaultThresholds, thresholdsOverrides);
|
|
27
|
+
|
|
28
|
+
export default mergeConfigs(getNestjsJestConfig({ thresholds }), localConfig);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is managed by Lisa.
|
|
3
|
+
* Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Jest Configuration - NestJS Stack
|
|
8
|
+
*
|
|
9
|
+
* Provides NestJS-specific Jest configuration with extensive coverage
|
|
10
|
+
* exclusions for generated files, DTOs, entities, and modules.
|
|
11
|
+
*
|
|
12
|
+
* Inheritance chain:
|
|
13
|
+
* jest.nestjs.ts (this file)
|
|
14
|
+
* └── jest.base.ts
|
|
15
|
+
*
|
|
16
|
+
* @see https://jestjs.io/docs/configuration
|
|
17
|
+
* @module jest.nestjs
|
|
18
|
+
*/
|
|
19
|
+
import type { Config } from "jest";
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
defaultCoverageExclusions,
|
|
23
|
+
defaultThresholds,
|
|
24
|
+
mergeConfigs,
|
|
25
|
+
mergeThresholds,
|
|
26
|
+
} from "./jest.base.ts";
|
|
27
|
+
|
|
28
|
+
// Re-export base utilities for entry-point configs
|
|
29
|
+
export {
|
|
30
|
+
defaultCoverageExclusions,
|
|
31
|
+
defaultThresholds,
|
|
32
|
+
mergeConfigs,
|
|
33
|
+
mergeThresholds,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Options for configuring the NestJS Jest config factory.
|
|
38
|
+
*/
|
|
39
|
+
interface NestjsJestOptions {
|
|
40
|
+
/** Coverage thresholds (merged defaults + project overrides) */
|
|
41
|
+
readonly thresholds?: Config["coverageThreshold"];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* NestJS-specific patterns excluded from coverage collection.
|
|
46
|
+
* These are generated or boilerplate files that don't benefit from coverage tracking.
|
|
47
|
+
*/
|
|
48
|
+
const nestjsCoverageExclusions: readonly string[] = [
|
|
49
|
+
...defaultCoverageExclusions,
|
|
50
|
+
"!**/*.entity.ts",
|
|
51
|
+
"!**/*.dto.ts",
|
|
52
|
+
"!**/*.input.ts",
|
|
53
|
+
"!**/*.args.ts",
|
|
54
|
+
"!**/*.model.ts",
|
|
55
|
+
"!**/*.module.ts",
|
|
56
|
+
"!**/*.factory.ts",
|
|
57
|
+
"!**/*.enum.ts",
|
|
58
|
+
"!**/*.interface.ts",
|
|
59
|
+
"!**/*.constants.ts",
|
|
60
|
+
"!**/database/migrations/**",
|
|
61
|
+
"!**/database/seeds/**",
|
|
62
|
+
"!**/graphql/**",
|
|
63
|
+
"!**/main.ts",
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Creates a Jest configuration for NestJS projects.
|
|
68
|
+
*
|
|
69
|
+
* @param options - Configuration options for threshold overrides
|
|
70
|
+
* @param options.thresholds - Coverage thresholds (merged defaults + project overrides)
|
|
71
|
+
* @returns Jest config object with ts-jest transform, node environment, and NestJS-specific exclusions
|
|
72
|
+
* @remarks NestJS projects use CommonJS modules and spec.ts test file convention.
|
|
73
|
+
* Coverage excludes entities, DTOs, modules, and other boilerplate files
|
|
74
|
+
* that are better validated through integration tests.
|
|
75
|
+
*/
|
|
76
|
+
export const getNestjsJestConfig = ({
|
|
77
|
+
thresholds = defaultThresholds,
|
|
78
|
+
}: NestjsJestOptions = {}): Config => ({
|
|
79
|
+
testEnvironment: "node",
|
|
80
|
+
rootDir: "src",
|
|
81
|
+
testRegex: ".*\\.spec\\.ts$",
|
|
82
|
+
transform: {
|
|
83
|
+
"^.+\\.ts$": "ts-jest",
|
|
84
|
+
},
|
|
85
|
+
moduleFileExtensions: ["js", "json", "ts"],
|
|
86
|
+
collectCoverageFrom: ["**/*.ts", ...nestjsCoverageExclusions],
|
|
87
|
+
coverageThreshold: thresholds,
|
|
88
|
+
testTimeout: 10000,
|
|
89
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# OWASP ZAP Baseline Scan — NestJS GraphQL API
|
|
3
|
+
# Builds and starts the NestJS server, then runs a ZAP baseline scan via Docker.
|
|
4
|
+
# Outputs an HTML report to zap-report.html in the project root.
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
9
|
+
TARGET_URL="${ZAP_TARGET_URL:-http://host.docker.internal:3000/graphql}"
|
|
10
|
+
ZAP_RULES_FILE="${ZAP_RULES_FILE:-.zap/baseline.conf}"
|
|
11
|
+
REPORT_FILE="zap-report.html"
|
|
12
|
+
|
|
13
|
+
cd "$PROJECT_ROOT"
|
|
14
|
+
|
|
15
|
+
# Verify Docker is available
|
|
16
|
+
if ! command -v docker &> /dev/null; then
|
|
17
|
+
echo "Error: Docker is required but not installed."
|
|
18
|
+
echo "Install Docker from https://docs.docker.com/get-docker/"
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
if ! docker info &> /dev/null 2>&1; then
|
|
23
|
+
echo "Error: Docker daemon is not running."
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Detect package manager
|
|
28
|
+
if [ -f "bun.lockb" ]; then
|
|
29
|
+
PKG_MGR="bun"
|
|
30
|
+
elif [ -f "yarn.lock" ]; then
|
|
31
|
+
PKG_MGR="yarn"
|
|
32
|
+
elif [ -f "pnpm-lock.yaml" ]; then
|
|
33
|
+
PKG_MGR="pnpm"
|
|
34
|
+
else
|
|
35
|
+
PKG_MGR="npm"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
echo "==> Building NestJS project..."
|
|
39
|
+
$PKG_MGR run build
|
|
40
|
+
|
|
41
|
+
echo "==> Starting NestJS server..."
|
|
42
|
+
NODE_ENV=test PORT=3000 $PKG_MGR run start &
|
|
43
|
+
SERVER_PID=$!
|
|
44
|
+
|
|
45
|
+
cleanup() {
|
|
46
|
+
echo "==> Cleaning up..."
|
|
47
|
+
if [ -n "${SERVER_PID:-}" ]; then
|
|
48
|
+
kill "$SERVER_PID" 2>/dev/null || true
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
trap cleanup EXIT
|
|
52
|
+
|
|
53
|
+
echo "==> Waiting for server to be ready..."
|
|
54
|
+
RETRIES=30
|
|
55
|
+
until curl -sf http://localhost:3000/health > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
|
|
56
|
+
RETRIES=$((RETRIES - 1))
|
|
57
|
+
sleep 2
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ $RETRIES -eq 0 ]; then
|
|
61
|
+
echo "Error: Server failed to start within timeout"
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
echo " Server is ready"
|
|
65
|
+
|
|
66
|
+
echo "==> Running OWASP ZAP baseline scan..."
|
|
67
|
+
ZAP_ARGS="-t $TARGET_URL"
|
|
68
|
+
|
|
69
|
+
if [ -f "$ZAP_RULES_FILE" ]; then
|
|
70
|
+
echo " Using rules file: $ZAP_RULES_FILE"
|
|
71
|
+
ZAP_ARGS="$ZAP_ARGS -c /zap/wrk/$(basename "$ZAP_RULES_FILE")"
|
|
72
|
+
MOUNT_RULES="-v $(dirname "$(realpath "$ZAP_RULES_FILE")"):/zap/wrk:ro"
|
|
73
|
+
else
|
|
74
|
+
MOUNT_RULES=""
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
docker run --rm \
|
|
78
|
+
--add-host=host.docker.internal:host-gateway \
|
|
79
|
+
-v "$(pwd)":/zap/wrk/:rw \
|
|
80
|
+
$MOUNT_RULES \
|
|
81
|
+
ghcr.io/zaproxy/zaproxy:stable \
|
|
82
|
+
zap-baseline.py $ZAP_ARGS \
|
|
83
|
+
-r "$REPORT_FILE" \
|
|
84
|
+
-J zap-report.json \
|
|
85
|
+
-w zap-report.md \
|
|
86
|
+
-l WARN || ZAP_EXIT=$?
|
|
87
|
+
|
|
88
|
+
echo ""
|
|
89
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
90
|
+
echo "ZAP report saved to: $REPORT_FILE"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if [ "${ZAP_EXIT:-0}" -ne 0 ]; then
|
|
94
|
+
echo "ZAP found medium+ severity findings (exit code: $ZAP_EXIT)"
|
|
95
|
+
echo "Review $REPORT_FILE for details."
|
|
96
|
+
exit "$ZAP_EXIT"
|
|
97
|
+
else
|
|
98
|
+
echo "ZAP baseline scan passed — no medium+ severity findings."
|
|
99
|
+
fi
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": ".",
|
|
5
|
+
"noEmit": true,
|
|
6
|
+
"allowImportingTsExtensions": true
|
|
7
|
+
},
|
|
8
|
+
"include": ["src/**/*", "test/**/*", "*.config.ts", "eslint.*.ts", "jest.*.ts"],
|
|
9
|
+
"exclude": ["node_modules", ".build"]
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"target": "ES2021",
|
|
6
|
+
"emitDecoratorMetadata": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"outDir": ".build",
|
|
11
|
+
"baseUrl": "./",
|
|
12
|
+
"paths": {
|
|
13
|
+
"@/*": ["./src/*"]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -18,6 +18,14 @@ jobs:
|
|
|
18
18
|
skip_jobs: 'test,test:integration,test:e2e'
|
|
19
19
|
secrets: inherit
|
|
20
20
|
|
|
21
|
+
zap:
|
|
22
|
+
name: 🕷️ ZAP Baseline Scan
|
|
23
|
+
needs: [quality]
|
|
24
|
+
uses: ./.github/workflows/zap-baseline.yml
|
|
25
|
+
with:
|
|
26
|
+
node_version: '22.21.1'
|
|
27
|
+
package_manager: 'bun'
|
|
28
|
+
|
|
21
29
|
create_issue_on_failure:
|
|
22
30
|
name: 📌 Create Issue on Failure
|
|
23
31
|
needs: [quality]
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"fetch:graphql:schema:production": "./scripts/fetch-graphql-schema.sh production",
|
|
27
27
|
"deploy:dev": "sls deploy --stage dev",
|
|
28
28
|
"deploy:staging": "sls deploy --stage staging",
|
|
29
|
-
"deploy:production": "sls deploy --stage production"
|
|
29
|
+
"deploy:production": "sls deploy --stage production",
|
|
30
|
+
"security:zap": "bash scripts/zap-baseline.sh"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
33
|
"@apollo/server": "^5.2.0",
|
package/package.json
CHANGED
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"resolutions": {},
|
|
87
87
|
"name": "@codyswann/lisa",
|
|
88
|
-
"version": "1.
|
|
88
|
+
"version": "1.15.0",
|
|
89
89
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
90
90
|
"main": "dist/index.js",
|
|
91
91
|
"bin": {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Run an OWASP ZAP baseline security scan locally using Docker.
|
|
2
|
+
|
|
3
|
+
Steps:
|
|
4
|
+
1. Check if Docker is installed and running: `docker info`
|
|
5
|
+
2. Check if `scripts/zap-baseline.sh` exists in the project
|
|
6
|
+
3. If it exists, run: `bash scripts/zap-baseline.sh`
|
|
7
|
+
4. If it does not exist, inform the user that this project does not have a ZAP baseline scan configured
|
|
8
|
+
5. After the scan completes, read `zap-report.html` (or `zap-report.md` for text) and summarize:
|
|
9
|
+
- Total number of alerts by risk level (High, Medium, Low, Informational)
|
|
10
|
+
- List each Medium+ finding with its rule ID, name, and recommended fix
|
|
11
|
+
- Categorize findings as "infrastructure-level" (fix at CDN/proxy) vs "application-level" (fix in code)
|
|
12
|
+
6. If the scan failed, explain what failed and suggest concrete remediation steps
|