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
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.
46 changes: 46 additions & 0 deletions .github/workflows/azure-static-web-apps-ashy-flower-03963d600.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Azure Static Web Apps CI/CD

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

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
steps:
- uses: actions/checkout@v3
with:
submodules: true
lfs: false
- 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_ASHY_FLOWER_03963D600 }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
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: "./client-styled" # App source code path
api_location: "" # Api source code path - optional
output_location: "build" # Built app content directory - optional
###### 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:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FLOWER_03963D600 }}
action: "close"
62 changes: 62 additions & 0 deletions .github/workflows/azure-static-web-apps-white-mud-02f499100.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Azure Static Web Apps CI/CD

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

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:
# 👇 FIXED: Points directly to your active 'ashy-flower' secret token
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FLOWER_03963D600 }}
action: "upload"
###### Repository/Build Configurations ######
app_location: "./client-styled" # 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 }}
# 👇 KEEPING FIX: Forces npm to bypass the peer dependency conflicts cleanly
app_build_command: 'npm install --legacy-peer-deps && npm run build'
###### 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:
# 👇 FIXED: Corrected token name here as well
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FLOWER_03963D600 }}
action: "close"
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
<img src="images/logo4.png" alt="Logo" width="200" >
</a>

<h3 align="center">Storytelling Blog - React Express MySQL Application</h3>
<h3 align="center">Storytelling Blog - React Express MSSQL Application</h3>

<p align="center">
Storytelling is a Full Stack Blog. This stack includes - React, Node, Bootstrap, MySQL Server, Netlify, Heroku and ClearDB.
Storytelling is a Full Stack Blog. This stack includes - React, Node, Bootstrap, Azure SQL Server (MSSQL), Netlify, and Azure App Service.
<br />
<a href="https://github.com/dontrellthedeveloper/react-node-sql-blog"><strong>Explore the docs »</strong></a>
<br />
Expand Down Expand Up @@ -109,7 +109,7 @@
* [![React][React.js]][React-url]
* [![Bootstrap][Bootstrap.com]][Bootstrap-url]
* [![Node][Node.js]][Node-url]
* [![MySQL][MySQL]][MySQL-url]
* [![MSSQL][MSSQL]][MSSQL-url]
* [![Netlify][Netlify]][Netlify-url]
* [![Heroku][Heroku]][Heroku-url]

Expand Down Expand Up @@ -179,7 +179,7 @@ This is an example of how to list things you need to use the software and how to

### Installation

1. Create a SQL server database. Try using MySQL Workbench.
1. Create a SQL server database. Try using Azure Data Studio or SQL Server Management Studio (SSMS).
5. Clone the repo
```sh
git clone https://github.com/dontrellthedeveloper/react-node-sql-blog.git
Expand Down Expand Up @@ -338,8 +338,8 @@ Project Link: [https://github.com/dontrellthedeveloper/react-node-sql-blog](http
[GoogleLogin-url]: https://console.cloud.google.com


[MySQL]: https://img.shields.io/badge/mySQL-4479A1?style=for-the-badge&logo=mysql&logoColor=white
[MySQL-url]: https://redux.js.org/
[MSSQL]: https://img.shields.io/badge/Microsoft%20SQL%20Server-CC292B?style=for-the-badge&logo=microsoft%20sql%20server&logoColor=white
[MSSQL-url]: https://www.microsoft.com/en-us/sql-server/

[Heroku]: https://img.shields.io/badge/heroku-430098?style=for-the-badge&logo=heroku&logoColor=FFCA28
[Heroku-url]: https://firebase.google.com/
Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
npm-debug.log
.env
.git
.idea
*.md
Dockerfile
.dockerignore
File renamed without changes.
26 changes: 26 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Stage 1: Build stage
FROM node:18-alpine AS builder

WORKDIR /app

COPY package*.json ./
# Force a clean install layer execution
RUN npm ci --only=production

# Stage 2: Production stage
FROM node:18-alpine
WORKDIR /app

# Copy files directly to ensure the latest local changes write fresh blocks
COPY . .

# Explicitly pull production modules from the isolated builder setup
COPY --from=builder /app/node_modules ./node_modules

# Expose port 3001 to align with your Azure load-balancer settings
EXPOSE 3001

# Set environment string properties to completely bypass local file drift
ENV NODE_ENV=production

CMD ["node", "index.js"]
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
14 changes: 14 additions & 0 deletions backend/config/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"development": {
"use_env_variable": "DB_CONNECTION_STRING",
"dialect": "mssql"
},
"test": {
"use_env_variable": "DB_CONNECTION_STRING",
"dialect": "mssql"
},
"production": {
"use_env_variable": "DB_CONNECTION_STRING",
"dialect": "mssql"
}
}
30 changes: 30 additions & 0 deletions backend/db/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- 1. Create the Users Table
CREATE TABLE Users (
id INT IDENTITY(1,1) PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
createdAt DATETIME2 DEFAULT GETDATE()
);

-- 2. Create the Posts Table
CREATE TABLE Posts (
id INT IDENTITY(1,1) PRIMARY KEY,
title VARCHAR(255) NOT NULL,
postText TEXT NOT NULL,
username VARCHAR(255) NOT NULL,
UserId INT NOT NULL,
createdAt DATETIME2 DEFAULT GETDATE(),
updatedAt DATETIME2 DEFAULT GETDATE(),
CONSTRAINT FK_UserPost FOREIGN KEY (UserId) REFERENCES Users(id) ON DELETE CASCADE
);

-- 3. Create the Comments Table (Optional but standard for this repo)
CREATE TABLE Comments (
id INT IDENTITY(1,1) PRIMARY KEY,
commentBody TEXT NOT NULL,
username VARCHAR(255) NOT NULL,
PostId INT NOT NULL,
createdAt DATETIME2 DEFAULT GETDATE(),
updatedAt DATETIME2 DEFAULT GETDATE(),
CONSTRAINT FK_PostComment FOREIGN KEY (PostId) REFERENCES Posts(id) ON DELETE CASCADE
);
56 changes: 56 additions & 0 deletions backend/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const express = require("express");
const app = express();
const cors = require("cors");
const sql = require("mssql");
require("dotenv").config();

// Middleware Setup
app.use(cors());
app.use(express.json());
app.use("/Images", express.static("./Images"));

// Routers
const postRouter = require("./routes/Posts");
app.use("/posts", postRouter);
const commentsRouter = require("./routes/Comments");
app.use("/comments", commentsRouter);
const usersRouter = require("./routes/Users");
app.use("/auth", usersRouter);
const likesRouter = require("./routes/Likes");
app.use("/likes", likesRouter);

// Secure Azure SQL Connection Pool configuration
const dbConfig = {
server: process.env.DB_HOST,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
port: 1433,
options: {
encrypt: true,
trustServerCertificate: false
},
pool: { max: 10, min: 0, idleTimeoutMillis: 30000 }
};


// Create a globally accessible connection lifecycle pool
async function initializeServer() {
try {
// Creating a global pool attaches connection context natively to sql.query calls
await sql.connect(dbConfig);
console.log("Successfully authenticated and connected to Azure SQL Database Pool!");

const PORT = process.env.PORT || 3001;
// The Express server is called ONLY AFTER the DB pool has successfully resolved
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
} catch (err) {
console.error("Critical database pool connection error:", err);
setTimeout(initializeServer, 5000);
}
}

// Start Server and Database Pool concurrently
initializeServer();
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
28 changes: 20 additions & 8 deletions server/models/index.js → backend/models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,28 @@ const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
require('dotenv').config();

const db = {};

let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
// Synchronized with Azure MSSQL configurations from your DevSecOps setup
const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASSWORD,
{
host: process.env.DB_HOST,
dialect: 'mssql',
port: 1433,
dialectOptions: {
options: {
encrypt: true, // for Azure compliance
trustServerCertificate: false
}
},
logging: false
}
);

fs
.readdirSync(__dirname)
Expand Down
Loading