diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ce53b47 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,32 @@ +version: 2 +updates: + # Ruby gems + - package-ecosystem: "bundler" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 10 + labels: + - "dependencies" + + # GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "github-actions" + + # npm (JavaScript/Stimulus) + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 10 + labels: + - "dependencies" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..b8f6472 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,40 @@ +name: "CodeQL" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '0 6 * * 1' # Weekly on Mondays at 6am UTC + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'ruby', 'javascript' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/rubyonrails.yml b/.github/workflows/rubyonrails.yml index 825fcbc..aec798b 100644 --- a/.github/workflows/rubyonrails.yml +++ b/.github/workflows/rubyonrails.yml @@ -19,7 +19,7 @@ jobs: RAILS_ENV: test steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Add or replace dependency steps here - name: Install Ruby and gems uses: ruby/setup-ruby@v1 @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Ruby and gems uses: ruby/setup-ruby@v1 with: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..2e1919c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,34 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| main | :white_check_mark: | + +## Reporting a Vulnerability + +If you discover a security vulnerability in Project Daedalus, please report it responsibly: + +1. **Do not** open a public GitHub issue for security vulnerabilities. +2. Use [GitHub Security Advisories](https://github.com/AgentKush/project_daedalus/security/advisories/new) to report the vulnerability privately. +3. Alternatively, contact the maintainers directly via the [Icarus Modding Discord](https://discord.gg/linkarus-icarus-modding-936621749733302292). + +We will acknowledge receipt within 48 hours and aim to provide a fix or mitigation within 7 days for critical issues. + +## Security Measures + +This project uses the following security tools: + +- **Dependabot** — automatic alerts and PRs for vulnerable dependencies +- **Secret scanning** — detects accidentally committed secrets and API keys +- **Push protection** — blocks pushes that contain secrets +- **CodeQL** — static analysis for common vulnerability patterns in Ruby and JavaScript +- **bundle-audit** — Ruby gem vulnerability scanning in CI + +## Best Practices for Contributors + +- Never commit secrets, API keys, or credentials to the repository +- Firebase credentials belong in Rails encrypted credentials (`rails credentials:edit`), not in code +- Environment variables (e.g., `ADMIN_PASSWORD`) should be set in the deployment environment, not in `.env` files committed to the repo +- Keep dependencies up to date — review Dependabot PRs promptly diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index f5bc6c7..51a1614 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -3,6 +3,7 @@ require "spec_helper" require_relative "support/factory_bot" require_relative "support/chrome" +require_relative "support/firestore" ENV["RAILS_ENV"] ||= "test" require_relative "../config/environment" diff --git a/spec/requests/tools_spec.rb b/spec/requests/tools_spec.rb index 16ef3a9..0c1663e 100644 --- a/spec/requests/tools_spec.rb +++ b/spec/requests/tools_spec.rb @@ -3,9 +3,13 @@ require "rails_helper" RSpec.describe "Tools" do - describe "GET /index" do + before do + allow(Tool).to receive(:all).and_return([build(:tool)]) + end + + describe "GET /tools" do it "returns http success" do - get "/tools/index" + get "/tools" expect(response).to have_http_status(:success) end end diff --git a/spec/support/firestore.rb b/spec/support/firestore.rb new file mode 100644 index 0000000..f1859cc --- /dev/null +++ b/spec/support/firestore.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Stub Firebase credentials globally so tests don't fail when +# credentials are not configured (e.g., in CI environments). +# +# Individual specs should still mock Google::Cloud::Firestore.new +# to return a test double, but this prevents the Firestorable concern +# from raising before the mock can intercept. +RSpec.configure do |config| + config.before do + credentials = Rails.application.credentials + unless credentials.respond_to?(:firebase_keyfile) && credentials.firebase_keyfile.present? + allow(Rails.application.credentials).to receive(:firebase_keyfile).and_return( + { type: "service_account", project_id: "test-project" } + ) + end + end +end