Skip to content

Commit 89a75a9

Browse files
authored
Merge pull request #225 from codeunia-dev/security-fixes-and-improvements
🔒 Critical Security Fixes & Code Quality Improvements
2 parents 43d67eb + ef38cce commit 89a75a9

File tree

13 files changed

+748
-96
lines changed

13 files changed

+748
-96
lines changed

.github/workflows/ci-cd.yml

Lines changed: 202 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: CI/CD Pipeline
1+
name: ci-cd-pipeline
22

33
on:
44
push:
@@ -587,18 +587,213 @@ jobs:
587587
- name: Install dependencies
588588
run: npm ci
589589

590-
- name: Run Lighthouse CI
590+
- name: Install Lighthouse CI
591+
run: npm install -g @lhci/cli@0.12.x
592+
593+
- name: Create Lighthouse configuration for deployed site
594+
run: |
595+
cat > lighthouserc-deployed.js << 'EOF'
596+
module.exports = {
597+
ci: {
598+
collect: {
599+
url: [
600+
'${{ steps.deploy-production.outputs.deployment-url }}/',
601+
'${{ steps.deploy-production.outputs.deployment-url }}/about',
602+
'${{ steps.deploy-production.outputs.deployment-url }}/hackathons',
603+
'${{ steps.deploy-production.outputs.deployment-url }}/leaderboard',
604+
'${{ steps.deploy-production.outputs.deployment-url }}/auth/signin'
605+
],
606+
numberOfRuns: 3,
607+
settings: {
608+
chromeFlags: '--no-sandbox --disable-dev-shm-usage --disable-gpu',
609+
preset: 'desktop'
610+
}
611+
},
612+
assert: {
613+
assertions: {
614+
'categories:performance': ['warn', { minScore: 0.7 }],
615+
'categories:accessibility': ['warn', { minScore: 0.8 }],
616+
'categories:best-practices': ['warn', { minScore: 0.8 }],
617+
'categories:seo': ['warn', { minScore: 0.8 }],
618+
'first-contentful-paint': ['warn', { maxNumericValue: 3000 }],
619+
'largest-contentful-paint': ['warn', { maxNumericValue: 4000 }],
620+
'cumulative-layout-shift': ['warn', { maxNumericValue: 0.2 }],
621+
'total-blocking-time': ['warn', { maxNumericValue: 500 }],
622+
'speed-index': ['warn', { maxNumericValue: 4000 }]
623+
}
624+
},
625+
upload: {
626+
target: 'temporary-public-storage'
627+
}
628+
}
629+
};
630+
EOF
631+
632+
- name: Wait for deployment to be fully ready
633+
run: |
634+
echo "⏳ Waiting for deployment to be fully ready for Lighthouse testing..."
635+
DEPLOYMENT_URL="${{ needs.deploy-production.outputs.deployment-url }}"
636+
637+
# Wait up to 5 minutes for the deployment to be ready
638+
for i in {1..30}; do
639+
echo "Attempt $i/30: Testing deployment readiness..."
640+
if curl -f -s --max-time 10 "$DEPLOYMENT_URL" > /dev/null; then
641+
echo "✅ Deployment is ready for Lighthouse testing"
642+
break
643+
else
644+
echo "⏳ Deployment not ready yet, waiting 10 seconds..."
645+
sleep 10
646+
fi
647+
648+
if [ $i -eq 30 ]; then
649+
echo "❌ Deployment not ready after 5 minutes, but continuing with Lighthouse test"
650+
fi
651+
done
652+
653+
- name: Run Lighthouse CI on deployed site
591654
run: |
592-
npm install -g @lhci/cli@0.12.x
593-
lhci autorun --assert.assertions.categories:performance=warn --assert.assertions.categories:accessibility=warn --assert.assertions.categories:best-practices=warn --assert.assertions.categories:seo=warn --assert.assertions.first-contentful-paint=warn --assert.assertions.largest-contentful-paint=warn --assert.assertions.cumulative-layout-shift=warn --assert.assertions.total-blocking-time=warn --assert.assertions.speed-index=warn
655+
echo "🚀 Starting Lighthouse CI performance testing..."
656+
echo "Testing URL: ${{ steps.deploy-production.outputs.deployment-url }}"
657+
658+
# Run Lighthouse CI with the deployed configuration
659+
lhci autorun --config=lighthouserc-deployed.js
594660
env:
595661
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
596662
LHCI_TOKEN: ${{ secrets.LHCI_TOKEN }}
597663
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
598664

599-
- name: Upload performance results
665+
- name: Verify Lighthouse results directory exists
666+
run: |
667+
echo "🔍 Checking Lighthouse results directory..."
668+
if [ -d ".lighthouseci" ]; then
669+
echo "✅ .lighthouseci directory exists"
670+
ls -la .lighthouseci/
671+
echo "📊 Lighthouse results found:"
672+
find .lighthouseci -name "*.json" -o -name "*.html" | head -10
673+
else
674+
echo "❌ .lighthouseci directory not found"
675+
echo "Creating directory for fallback..."
676+
mkdir -p .lighthouseci
677+
echo "{}" > .lighthouseci/manifest.json
678+
fi
679+
680+
- name: Upload Lighthouse performance results
600681
uses: actions/upload-artifact@v4
682+
if: always()
683+
with:
684+
name: lighthouse-performance-results
685+
path: .lighthouseci/
686+
retention-days: 30
687+
if-no-files-found: warn
688+
689+
# Performance Monitoring for Staging
690+
performance-staging:
691+
name: Performance Monitoring (Staging)
692+
runs-on: ubuntu-latest
693+
needs: deploy-staging
694+
if: github.ref == 'refs/heads/develop'
695+
steps:
696+
- name: Checkout code
697+
uses: actions/checkout@v4
698+
699+
- name: Setup Node.js
700+
uses: actions/setup-node@v4
701+
with:
702+
node-version: ${{ env.NODE_VERSION }}
703+
cache: 'npm'
704+
705+
- name: Install dependencies
706+
run: npm ci
707+
708+
- name: Install Lighthouse CI
709+
run: npm install -g @lhci/cli@0.12.x
710+
711+
- name: Create Lighthouse configuration for staging
712+
run: |
713+
cat > lighthouserc-staging.js << 'EOF'
714+
module.exports = {
715+
ci: {
716+
collect: {
717+
url: [
718+
'${{ steps.deploy-staging.outputs.deployment-url }}/',
719+
'${{ steps.deploy-staging.outputs.deployment-url }}/about',
720+
'${{ steps.deploy-staging.outputs.deployment-url }}/hackathons',
721+
'${{ steps.deploy-staging.outputs.deployment-url }}/leaderboard',
722+
'${{ steps.deploy-staging.outputs.deployment-url }}/auth/signin'
723+
],
724+
numberOfRuns: 2,
725+
settings: {
726+
chromeFlags: '--no-sandbox --disable-dev-shm-usage --disable-gpu',
727+
preset: 'desktop'
728+
}
729+
},
730+
assert: {
731+
assertions: {
732+
'categories:performance': ['warn', { minScore: 0.6 }],
733+
'categories:accessibility': ['warn', { minScore: 0.7 }],
734+
'categories:best-practices': ['warn', { minScore: 0.7 }],
735+
'categories:seo': ['warn', { minScore: 0.7 }]
736+
}
737+
},
738+
upload: {
739+
target: 'temporary-public-storage'
740+
}
741+
}
742+
};
743+
EOF
744+
745+
- name: Wait for staging deployment to be ready
746+
run: |
747+
echo "⏳ Waiting for staging deployment to be ready for Lighthouse testing..."
748+
DEPLOYMENT_URL="${{ needs.deploy-staging.outputs.deployment-url }}"
749+
750+
# Wait up to 3 minutes for the staging deployment to be ready
751+
for i in {1..18}; do
752+
echo "Attempt $i/18: Testing staging deployment readiness..."
753+
if curl -f -s --max-time 10 "$DEPLOYMENT_URL" > /dev/null; then
754+
echo "✅ Staging deployment is ready for Lighthouse testing"
755+
break
756+
else
757+
echo "⏳ Staging deployment not ready yet, waiting 10 seconds..."
758+
sleep 10
759+
fi
760+
761+
if [ $i -eq 18 ]; then
762+
echo "❌ Staging deployment not ready after 3 minutes, but continuing with Lighthouse test"
763+
fi
764+
done
765+
- name: Run Lighthouse CI on staging site
766+
run: |
767+
echo "🚀 Starting Lighthouse CI performance testing on staging..."
768+
echo "Testing URL: ${{ steps.deploy-staging.outputs.deployment-url }}"
769+
770+
# Run Lighthouse CI with the staging configuration
771+
lhci autorun --config=lighthouserc-staging.js
772+
env:
773+
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
774+
LHCI_TOKEN: ${{ secrets.LHCI_TOKEN }}
775+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
776+
777+
- name: Verify Lighthouse results directory exists
778+
run: |
779+
echo "🔍 Checking Lighthouse results directory..."
780+
if [ -d ".lighthouseci" ]; then
781+
echo "✅ .lighthouseci directory exists"
782+
ls -la .lighthouseci/
783+
echo "📊 Lighthouse results found:"
784+
find .lighthouseci -name "*.json" -o -name "*.html" | head -10
785+
else
786+
echo "❌ .lighthouseci directory not found"
787+
echo "Creating directory for fallback..."
788+
mkdir -p .lighthouseci
789+
echo "{}" > .lighthouseci/manifest.json
790+
fi
791+
792+
- name: Upload Lighthouse staging results
793+
uses: actions/upload-artifact@v4
794+
if: always()
601795
with:
602-
name: lighthouse-results
796+
name: lighthouse-staging-results
603797
path: .lighthouseci/
604-
retention-days: 30
798+
retention-days: 7
799+
if-no-files-found: warn

app/api/admin/audit-logs/route.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { createAuditLogger, AuditLogFilter, AuditActionType } from '@/lib/servic
66
* GET /api/admin/audit-logs
77
* Retrieve audit logs with filtering and pagination
88
*/
9-
async function getAuditLogs(request: NextRequest, _user: AuthenticatedUser) {
9+
async function getAuditLogs(request: NextRequest, user: AuthenticatedUser) {
1010
try {
1111
const { searchParams } = new URL(request.url);
1212

@@ -39,6 +39,9 @@ async function getAuditLogs(request: NextRequest, _user: AuthenticatedUser) {
3939

4040
const auditLogger = createAuditLogger();
4141
const result = await auditLogger.getLogs(filter);
42+
43+
// Log the audit log access for security tracking
44+
console.log(`Admin ${user.id} accessed audit logs with filter:`, filter);
4245

4346
return NextResponse.json({
4447
success: true,

app/api/admin/audit-logs/stats/route.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { createAuditLogger } from '@/lib/services/audit-logger';
66
* GET /api/admin/audit-logs/stats
77
* Get audit log statistics
88
*/
9-
async function getAuditStats(request: NextRequest, _user: AuthenticatedUser) {
9+
async function getAuditStats(request: NextRequest, user: AuthenticatedUser) {
1010
try {
1111
const { searchParams } = new URL(request.url);
1212
const periodDays = searchParams.get('period_days')
@@ -23,6 +23,9 @@ async function getAuditStats(request: NextRequest, _user: AuthenticatedUser) {
2323

2424
const auditLogger = createAuditLogger();
2525
const stats = await auditLogger.getAuditStats(periodDays);
26+
27+
// Log the audit stats access for security tracking
28+
console.log(`Admin ${user.id} accessed audit stats for ${periodDays} days`);
2629

2730
return NextResponse.json({
2831
success: true,

0 commit comments

Comments
 (0)