diff --git a/.codeclimate.yml b/.codeclimate.yml index 557e5b2f..0365572d 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -19,4 +19,4 @@ exclude_patterns: - vendor/ - "**/vendor/**/*" - app/assets/images/ -- spec/**/* \ No newline at end of file +- spec/**/* diff --git a/.env_login b/.env_dev similarity index 58% rename from .env_login rename to .env_dev index 56b421dd..48146744 100644 --- a/.env_login +++ b/.env_dev @@ -6,3 +6,13 @@ export LOGOUT_REDIRECT_EVAL_URL=http://localhost:3000/ export PHOENIX_URI="http://localhost:4000" export LOGIN_SECRET="f4d3c40a00a8e6ed72fae5204d9ddacd40f087865d40803a6fcfb935591a271838533f06081067dac24c0085c74123e7e1c8b3e0ab562c6645b17eb769854d0d" export JWT_SECRET="fc28c5738ca45162f61126e770a8fbdbd938d0fedcfe8fbb9f851b855b0264866364a9130e96aca8b1977e9f58edf064f1aa435ceccf415ff22fd3c24adba320" + +# static pages on localhost +# export PAGES_DOMAIN="localhost:4001" +# export PAGES_HOST="http://localhost:4001" +# export PAGES_BASE_URL="/" + +# static pages on eval-dev branch +export PAGES_DOMAIN="federalist-2c628203-05c2-48ab-8f87-3eda79380559.sites.pages.cloud.gov" +export PAGES_HOST="https://federalist-2c628203-05c2-48ab-8f87-3eda79380559.sites.pages.cloud.gov" +export PAGES_BASE_URL="/preview/gsa/challenges-and-prizes/eval-dev" \ No newline at end of file diff --git a/.envrc b/.envrc index 4fbb075a..ebe455a6 100644 --- a/.envrc +++ b/.envrc @@ -6,4 +6,4 @@ mkdir -p .nix-bundler export BUNDLE_PATH=./.nix-bundler # Login Env Vars -source .env_login +source .env_dev diff --git a/.simplecov b/.simplecov index 90a22a90..1d3e67c4 100644 --- a/.simplecov +++ b/.simplecov @@ -28,6 +28,7 @@ SimpleCov.start 'rails' do add_filter '/app/jobs/application_job.rb' add_filter '/app/mailers/application_mailer.rb' add_filter '/app/models/application_record.rb' + add_filter '/app/controllers/pages_controller.rb' add_filter '/app/controllers/sandbox_controller.rb' diff --git a/DEVCONFIG.md b/DEVCONFIG.md index c9b2a296..9e03e755 100644 --- a/DEVCONFIG.md +++ b/DEVCONFIG.md @@ -66,7 +66,7 @@ Once direnv is installed and your shell is restarted, clone the project and `cd` ``` ./bin/dev ``` - > _NOTE for login.gov configuration_ -- if you are **not** using direnv/nix to eval `.envrc`, you can run `source .env_login` in your terminal before starting the server or add the env vars in that file to your local environment directly. + > _NOTE for login.gov configuration_ -- if you are **not** using direnv/nix to eval `.envrc`, you can run `source .env_dev` in your terminal before starting the server or add the env vars in that file to your local environment directly. Now you can visit [`localhost:3000`](http://localhost:3000) from your browser. diff --git a/Gemfile b/Gemfile index 1dcb097f..40da774e 100644 --- a/Gemfile +++ b/Gemfile @@ -102,3 +102,5 @@ end gem "factory_bot", "~> 6.5" gem "faker", "~> 3.4" + +gem "rails-reverse-proxy" diff --git a/Gemfile.lock b/Gemfile.lock index 66543f85..5a39e28e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -255,6 +255,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) + rails-reverse-proxy (0.13.0) + actionpack + addressable railties (7.2.2) actionpack (= 7.2.2) activesupport (= 7.2.2) @@ -398,6 +401,7 @@ DEPENDENCIES puma (>= 6.4.3) rails (~> 7.2.1) rails-controller-testing + rails-reverse-proxy rspec-rails rspec_junit_formatter rubocop (>= 1.66.0) diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb new file mode 100644 index 00000000..79cb99e9 --- /dev/null +++ b/app/controllers/pages_controller.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +# Proxy Cloud.gov pages content at the root of the application +class PagesController < ApplicationController + include ReverseProxy::Controller + # We must remove this for proxy of JS assets to be loaded by the browser + protect_from_forgery except: :assets + + # TODO: When launched, the cloud.gov pages need to move off the www.challenge.gov domain + DOMAIN = Rails.configuration.static_site_interop.fetch(:domain) + HOST = Rails.configuration.static_site_interop.fetch(:host) + BASE_URL = Rails.configuration.static_site_interop.fetch(:base_url) + + def index + path = "#{BASE_URL}/#{params[:path]}/" + reverse_proxy(HOST, path:, reset_accept_encoding: true, headers: { host: DOMAIN }) do |config| + config.on_missing do |_code, _response| + redirect_to "/dashboard" + return true + end + + config.on_response do |_code, response| + response.body = rewrite_links(response.body) + end + end + end + + def assets + if params[:ext] == "min" + path = "#{HOST}#{BASE_URL}/assets/#{params[:path]}.#{params[:ext]}.js" + response = Faraday.get(path) + send_data(response.body, type: 'application/javascript') + else + path = "#{BASE_URL}/assets/#{params[:path]}.#{params[:ext]}" + reverse_proxy(HOST, path:, reset_accept_encoding: true, headers: { host: DOMAIN }) + end + end + + def root + path = "#{BASE_URL}/" + reverse_proxy(HOST, path:, reset_accept_encoding: true, headers: { host: DOMAIN }) do |config| + config.on_response do |_code, response| + if response.body.present? + response.body = rewrite_links(response.body) + end + end + end + end + + private + + def rewrite_links(html) + parsed_html = html.gsub(HOST, "/") + if BASE_URL.length > 1 + parsed_html = parsed_html.gsub(BASE_URL, "") + end + # delete the data-public-url attribute from the react app element to send requests through rails proxy + parsed_html = parsed_html.sub(/(