Skip to content
Open
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
58 changes: 58 additions & 0 deletions .github/workflows/azure-static-web-apps-black-smoke-0e2f99000.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Azure Static Web Apps CI/CD

on:
push:
branches:
- develop
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
- develop

jobs:
build_and_deploy_job:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
runs-on: ubuntu-latest
name: Build and Deploy Job
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
with:
submodules: true
lfs: false
- name: Install OIDC Client from Core Package
run: npm install @actions/core@1.6.0 @actions/http-client
- name: Get Id Token
uses: actions/github-script@v6
id: idtoken
with:
script: |
const coredemo = require('@actions/core')
return await coredemo.getIDToken()
result-encoding: string
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_BLACK_SMOKE_0E2F99000 }}
action: "upload"
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: "./react-client" # App source code path
api_location: "" # Api source code path - optional
output_location: "build" # Built app content directory - optional
github_id_token: ${{ steps.idtoken.outputs.result }}
###### End of Repository/Build Configurations ######

close_pull_request_job:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
name: Close Pull Request Job
steps:
- name: Close Pull Request
id: closepullrequest
uses: Azure/static-web-apps-deploy@v1
with:
action: "close"
123 changes: 123 additions & 0 deletions .github/workflows/sast.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Secure CI/CD Production Pipeline

on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]

jobs:
sast_scan:
name: 1. Vulnerability Assessment (SAST)
runs-on: ubuntu-latest
steps:
- name: Checkout Source Code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Run SonarQube Scan Engine
uses: SonarSource/sonarqube-scan-action@v3
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
with:
args: >
-Dsonar.projectKey=TaskApp-DevSecOps
-Dsonar.projectName=TaskApp
-Dsonar.sources=.

- name: Enforce Custom Quality Gate Status
uses: SonarSource/sonarqube-quality-gate-action@v1.1.0
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

sca_scan:
name: 2. Open-Source Dependency Scan (SCA)
runs-on: ubuntu-latest
needs: sast_scan
steps:
- name: Checkout Source Code
uses: actions/checkout@v4

- name: Snyk - Scan Project Dependencies
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high --file=package.json

container_scan:
name: 3. Container Image Security Scan
runs-on: ubuntu-latest
needs: sca_scan
steps:
- name: Checkout Source Code
uses: actions/checkout@v4

- name: Build Staging Docker Image
run: |
docker build -t taskapp-backend:staging .

- name: Run Trivy Security Vulnerability Scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'taskapp-backend:staging'
format: 'table'
exit-code: '1'
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'

deploy_staging:
name: 4. Staging Environment Deployment
runs-on: ubuntu-latest
needs: container_scan
steps:
- name: Checkout Source Code
uses: actions/checkout@v4

- name: Spin Up Application for Security Probe
run: |
echo "All structural gates passed. Launching staging environment instances..."
echo "Staging deployment active at http://20.187.120.80:9000 (Simulated)"

dast_scan:
name: 5. Dynamic Application Security Testing (DAST)
runs-on: ubuntu-latest
needs: deploy_staging # CRITICAL: Ensures the app is "live" before scanning!
steps:
- name: Checkout Source Code
uses: actions/checkout@v4

- name: Create Report Directory
run: mkdir -p ${{ github.workspace }}/zap

# Step 1 & 2: Pull and Run ZAP Baseline scan against your live frontend target URL
- name: Run ZAP Baseline Scan (Frontend)
run: |
docker run --user root -v ${{ github.workspace }}/zap:/zap/wrk/:rw \
zaproxy/zap-stable zap-baseline.py \
-t http://20.187.120.80:9000 \
-r zap-report.html \
-I

# Step 3: Run ZAP API scan against your backend routing schema definitions
- name: Run ZAP API Scan (Backend)
run: |
docker run --user root -v ${{ github.workspace }}/zap:/zap/wrk/:rw \
zaproxy/zap-stable zap-api-scan.py \
-t http://20.187.120.80:9000/api/openapi.json \
-f openapi \
-r zap-api-report.html \
-I

# Step 4: Publish HTML Security Reports as downloadable pipeline artifacts
- name: Publish ZAP Security Report Artifacts
uses: actions/upload-artifact@v4
if: always() # Guarantees reports publish even if structural security vulnerabilities match
with:
name: zap-security-reports
path: ${{ github.workspace }}/zap/
4 changes: 4 additions & 0 deletions node-express-server/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
npm-debug.log
.git
.env
13 changes: 13 additions & 0 deletions node-express-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Multi-stage build for a smaller, secure image
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only-production
COPY . .

FROM node:18-alpine
WORKDIR /app
COPY --from-builder /app .
EXPOSE 8080
# Note: Based on your screenshot, the main file is server.js
CMD ["node", "server.js"]
16 changes: 11 additions & 5 deletions node-express-server/app/config/db.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
module.exports = {
HOST: "localhost",
USER: "root",
PASSWORD: "123456",
DB: "testdb",
dialect: "mysql",
HOST: "mysql-taskapp-reeha.mysql.database.azure.com", // This is your server building name
USER: "dbuser",
PASSWORD: "Devops@123456789",
DB: "flexibleserverdb", // <-- CHANGE THIS BACK TO Azure's default database room!
dialect: "mysql",
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false
}
},
pool: {
max: 5,
min: 0,
Expand Down
1 change: 1 addition & 0 deletions node-express-server/server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const express = require("express");
const cors = require("cors");


const app = express();

var corsOptions = {
Expand Down
19 changes: 19 additions & 0 deletions react-client/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 1. Build Stage
FROM node:16-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .

# --- CRUCIAL: THESE TWO LINES MUST BE RIGHT HERE (BEFORE THE BUILD RUN) ---
ARG REACT_APP_API_URL
ENV REACT_APP_API_URL=$REACT_APP_API_URL

RUN npm run build

# 2. Production Stage (Nginx)
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
8 changes: 8 additions & 0 deletions react-client/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
5 changes: 3 additions & 2 deletions react-client/src/http-common.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import axios from "axios";

export default axios.create({
baseURL: "http://localhost:8080/api",
// Make sure this points to the BACKEND domain, followed by /api
baseURL: "https://app-taskapp-backend-reeha-fnd0b7b9dqcpazh8.eastasia-01.azurewebsites.net/api",
headers: {
"Content-type": "application/json"
}
});
});