-
Notifications
You must be signed in to change notification settings - Fork 776
Add verify-login compatibility route for 2FA #4331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,12 +2,19 @@ name: Dependency Security Scanner | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| push: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: [main, master, develop] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - master | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - develop | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - codex/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: [main, master, develop] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - master | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - develop | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - codex/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| schedule: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Runs daily at 02:00 UTC (07:30 IST) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - cron: '0 2 * * *' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - cron: "0 2 * * *" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -17,7 +24,6 @@ permissions: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── 1. npm audit ──────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| npm-audit: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: npm Audit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -28,8 +34,9 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Set up Node.js | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version: '20' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache: 'npm' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version: "20" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache: npm | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache-dependency-path: backend/package-lock.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| working-directory: ./backend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -41,88 +48,94 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| npm audit --json > npm-audit-report.json || true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| npm audit --audit-level=high 2>&1 | tee npm-audit-summary.txt || AUDIT_EXIT=$? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "exit_code=${AUDIT_EXIT:-0}" >> $GITHUB_OUTPUT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "exit_code=${AUDIT_EXIT:-0}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Upload npm audit report | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/upload-artifact@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/upload-artifact@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: npm-audit-report | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| npm-audit-report.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| npm-audit-summary.txt | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| backend/npm-audit-report.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| backend/npm-audit-summary.txt | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| retention-days: 30 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Fail on high/critical vulnerabilities | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Fail on high or critical vulnerabilities | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: steps.npm_audit.outputs.exit_code != '0' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| working-directory: ./backend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "::error::High or critical vulnerabilities found. See npm-audit-report artifact." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cat npm-audit-summary.txt | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── 2. Snyk vulnerability scan ────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| snyk: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Snyk Vulnerability Scan | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout repository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: env.SNYK_TOKEN != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Set up Node.js | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: env.SNYK_TOKEN != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version: '20' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache: 'npm' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version: "20" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache: npm | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache-dependency-path: backend/package-lock.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: env.SNYK_TOKEN != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| working-directory: ./backend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: npm install --legacy-peer-deps --prefer-offline | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Run Snyk to check for vulnerabilities | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| working-directory: ./backend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: env.SNYK_TOKEN != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: snyk/actions/node@master | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue-on-error: true # upload SARIF even if vulns found | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue-on-error: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args: > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --file=backend/package.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --severity-threshold=high | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --sarif-file-output=snyk-results.sarif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --json-file-output=snyk-results.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Upload Snyk SARIF to GitHub Security tab | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: env.SNYK_TOKEN != '' && always() && hashFiles('snyk-results.sarif') != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: github/codeql-action/upload-sarif@v3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() && hashFiles('snyk-results.sarif') != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sarif_file: snyk-results.sarif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| category: snyk | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Upload Snyk JSON report | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: env.SNYK_TOKEN != '' && always() && hashFiles('snyk-results.json') != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/upload-artifact@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() && hashFiles('snyk-results.json') != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: snyk-report | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: snyk-results.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| retention-days: 30 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── 3. GitHub Dependency Review (PRs only) ────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Skip Snyk scan when token is unavailable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: env.SNYK_TOKEN == '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: echo "SNYK_TOKEN is not configured for this repository. Skipping Snyk scan." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dependency-review: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: GitHub Dependency Review | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.event_name == 'pull_request' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.event_name == 'pull_request' && !github.event.repository.fork | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major Fork guard condition is ineffective for PRs from forks - if: github.event_name == 'pull_request' && !github.event.repository.fork
+ if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repositoryAlternatively, use
📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout repository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Dependency Review | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Dependency review | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/dependency-review-action@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fail-on-severity: high | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| comment-summary-in-pr: always | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Deny packages with known-bad licenses | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deny-licenses: GPL-2.0, GPL-3.0, AGPL-3.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── 4. OSSAR / OSV Scanner ────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| osv-scan: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: OSV Vulnerability Scan | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -140,66 +153,75 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ./ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Upload OSV SARIF to GitHub Security tab | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() && hashFiles('osv-results.sarif') != '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: github/codeql-action/upload-sarif@v3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sarif_file: osv-results.sarif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| category: osv-scanner | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── 5. Aggregate & notify ─────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| summary: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Security Scan Summary | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| needs: [npm-audit, snyk, osv-scan] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Download all artifacts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/download-artifact@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: scan-results/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Generate summary | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "## 🔐 Dependency Security Scan Summary" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| Scanner | Status |" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "|---------------|--------|" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| npm audit | ${{ needs.npm-audit.result == 'success' && '✅ Passed' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| Snyk | ${{ needs.snyk.result == 'success' && '✅ Passed' || '⚠️ Issues found' }} |" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| OSV Scanner | ${{ needs.osv-scan.result == 'success' && '✅ Passed' || '⚠️ Issues found' }} |" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "_Scan triggered by: \`${{ github.event_name }}\` on \`${{ github.ref_name }}\`_" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "_Run time: $(date -u '+%Y-%m-%d %H:%M UTC')_" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "## Dependency Security Scan Summary" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| Scanner | Status |" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "|---|---|" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| npm audit | ${{ needs.npm-audit.result == 'success' && 'Passed' || 'Failed' }} |" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| Snyk | ${{ needs.snyk.result == 'success' && 'Passed' || needs.snyk.result == 'skipped' && 'Skipped' || 'Issues found' }} |" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "| OSV Scanner | ${{ needs.osv-scan.result == 'success' && 'Passed' || 'Issues found' }} |" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "_Scan triggered by: \`${{ github.event_name }}\` on \`${{ github.ref_name }}\`_" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "_Run time: $(date -u '+%Y-%m-%d %H:%M UTC')_" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
174
to
+185
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Template injection via
🔒 Use an env intermediary - name: Generate summary
+ env:
+ EVENT_NAME: ${{ github.event_name }}
+ REF_NAME: ${{ github.ref_name }}
run: |
echo "## Dependency Security Scan Summary" >> "$GITHUB_STEP_SUMMARY"
...
- echo "_Scan triggered by: \`${{ github.event_name }}\` on \`${{ github.ref_name }}\`_" >> "$GITHUB_STEP_SUMMARY"
+ echo "_Scan triggered by: \`${EVENT_NAME}\` on \`${REF_NAME}\`_" >> "$GITHUB_STEP_SUMMARY"
echo "_Run time: $(date -u '+%Y-%m-%d %H:%M UTC')_" >> "$GITHUB_STEP_SUMMARY"📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.26.1)[error] 182-182: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Post PR comment with summary | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.event_name == 'pull_request' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue-on-error: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/github-script@v7 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| script: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const npmStatus = '${{ needs.npm-audit.result }}' === 'success' ? '✅ Passed' : '❌ Failed'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const snykStatus = '${{ needs.snyk.result }}' === 'success' ? '✅ Passed' : '⚠️ Issues found'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const osvStatus = '${{ needs.osv-scan.result }}' === 'success' ? '✅ Passed' : '⚠️ Issues found'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const body = `## 🔐 Dependency Security Scan Results | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const npmStatus = '${{ needs.npm-audit.result }}' === 'success' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? 'Passed' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : 'Failed'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const snykResult = '${{ needs.snyk.result }}'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const snykStatus = snykResult === 'success' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? 'Passed' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : snykResult === 'skipped' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? 'Skipped' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : 'Issues found'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const osvStatus = '${{ needs.osv-scan.result }}' === 'success' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? 'Passed' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : 'Issues found'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const body = `## Dependency Security Scan Results | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | Scanner | Status | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |---|---| | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | npm audit | ${npmStatus} | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | Snyk | ${snykStatus} | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | OSV Scanner | ${osvStatus} | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > Full reports are available in the [Actions artifacts](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) and the **Security** tab.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > Full reports are available in the [Actions artifacts](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) and the Security tab.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github.rest.issues.createComment({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issue_number: context.issue.number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| owner: context.repo.owner, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo: context.repo.repo, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| body | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| body, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Fail pipeline if critical scan failed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Fail pipeline if npm audit failed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: needs.npm-audit.result == 'failure' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "::error::npm audit detected high/critical vulnerabilities." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "::error::npm audit detected high or critical vulnerabilities." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| import { describe, test } from 'node:test'; | ||
| import assert from 'node:assert/strict'; | ||
| import { ApiError } from '../../middleware/errorHandler.js'; | ||
| import router, { verifyLoginChallenge } from '../twoFactor.js'; | ||
|
|
||
| describe('twoFactor routes', () => { | ||
| test('registers the verify-login compatibility route', () => { | ||
| const verifyLoginRoute = router.stack.find( | ||
| (layer) => layer.route?.path === '/verify-login' && layer.route.methods?.post | ||
| ); | ||
|
|
||
| assert.ok(verifyLoginRoute, 'expected POST /verify-login route to be registered'); | ||
| }); | ||
| }); | ||
|
|
||
| describe('verifyLoginChallenge', () => { | ||
| test('uses TOTP verification by default', async () => { | ||
| const calls = []; | ||
| const req = { | ||
| user: { uid: 'user-123' }, | ||
| body: { token: '123456' }, | ||
| }; | ||
| const res = { | ||
| payload: null, | ||
| json(body) { | ||
| this.payload = body; | ||
| }, | ||
| }; | ||
|
|
||
| await verifyLoginChallenge(req, res, { | ||
| async verifyTotp(uid, token) { | ||
| calls.push(['totp', uid, token]); | ||
| return true; | ||
| }, | ||
| async verifyBackupCode() { | ||
| calls.push(['backup']); | ||
| return true; | ||
| }, | ||
| }); | ||
|
|
||
| assert.deepEqual(calls, [['totp', 'user-123', '123456']]); | ||
| assert.deepEqual(res.payload, { success: true }); | ||
| }); | ||
|
|
||
| test('uses backup-code verification when requested', async () => { | ||
| const calls = []; | ||
| const req = { | ||
| user: { uid: 'user-456' }, | ||
| body: { token: 'ABCD-1234', useBackup: true }, | ||
| }; | ||
| const res = { | ||
| payload: null, | ||
| json(body) { | ||
| this.payload = body; | ||
| }, | ||
| }; | ||
|
|
||
| await verifyLoginChallenge(req, res, { | ||
| async verifyTotp() { | ||
| calls.push(['totp']); | ||
| return true; | ||
| }, | ||
| async verifyBackupCode(uid, code) { | ||
| calls.push(['backup', uid, code]); | ||
| return true; | ||
| }, | ||
| }); | ||
|
|
||
| assert.deepEqual(calls, [['backup', 'user-456', 'ABCD-1234']]); | ||
| assert.deepEqual(res.payload, { success: true }); | ||
| }); | ||
|
|
||
| test('throws the same backup-code error message on invalid backup code', async () => { | ||
| const req = { | ||
| user: { uid: 'user-789' }, | ||
| body: { token: 'BAD-CODE', useBackup: true }, | ||
| }; | ||
| const res = { | ||
| json() { | ||
| assert.fail('res.json should not be called on invalid backup code'); | ||
| }, | ||
| }; | ||
|
|
||
| await assert.rejects( | ||
| verifyLoginChallenge(req, res, { | ||
| async verifyTotp() { | ||
| return true; | ||
| }, | ||
| async verifyBackupCode() { | ||
| return false; | ||
| }, | ||
| }), | ||
| (error) => { | ||
| assert.ok(error instanceof ApiError); | ||
| assert.equal(error.statusCode, 401); | ||
| assert.equal(error.message, 'Invalid backup code'); | ||
| return true; | ||
| } | ||
| ); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Snyk job never reports
skipped; summary will show "Passed" when the token is unset.The
snykjob has no job-levelif, so whenSNYK_TOKENis empty the real steps skip individually but this echo step still runs and the job completes with resultsuccess. Consequentlyneeds.snyk.resultis never'skipped', making the'Skipped'branches in the summary table (Line 179) and PR comment (Lines 197-198) unreachable — the report will read "Passed" even though Snyk never ran. Gate the whole job instead so it is actually skipped.🔧 Skip at the job level so the result is `skipped`
snyk: name: Snyk Vulnerability Scan runs-on: ubuntu-latest + if: ${{ vars.SNYK_ENABLED == 'true' }} # or another job-level gate; secrets can't be read in job-level if env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}Note: secrets cannot be referenced directly in a job-level
if, so route the toggle through a repo/org variable (or a preceding job output) if you want a trueskippedresult.🤖 Prompt for AI Agents