diff --git a/app/controllers/bootstrap_controller.rb b/app/controllers/bootstrap_controller.rb new file mode 100644 index 0000000000..dca7007c58 --- /dev/null +++ b/app/controllers/bootstrap_controller.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class BootstrapController < ApplicationController + include ApplicationHelper + include ActionView::Helpers::AssetUrlHelper + + # This endpoint allows us to produce the data required to start up Discourse via JSON API, + # so that you don't have to scrape the HTML for `data-*` payloads + def index + locale = script_asset_path("locales/#{I18n.locale}") + + preload_anonymous_data + if current_user + current_user.sync_notification_channel_position + preload_current_user_data + end + + bootstrap = { + theme_ids: theme_ids, + title: SiteSetting.title, + current_homepage: current_homepage, + locale_script: "#{Discourse.base_url}#{locale}", + setup_data: client_side_setup_data, + preloaded: @preloaded + } + + render_json_dump(bootstrap: bootstrap) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 482b2477d3..f6bda658a3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -356,6 +356,7 @@ module ApplicationHelper end def loading_admin? + return false unless defined?(controller) controller.class.name.split("::").first == "Admin" end diff --git a/config/routes.rb b/config/routes.rb index 69ade71938..e763252bc6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,6 +14,8 @@ Discourse::Application.routes.draw do match "/404", to: "exceptions#not_found", via: [:get, :post] get "/404-body" => "exceptions#not_found_body" + get "/bootstrap" => "bootstrap#index" + post "webhooks/aws" => "webhooks#aws" post "webhooks/mailgun" => "webhooks#mailgun" post "webhooks/mailjet" => "webhooks#mailjet" diff --git a/spec/requests/bootstrap_controller_spec.rb b/spec/requests/bootstrap_controller_spec.rb new file mode 100644 index 0000000000..6495eb4d28 --- /dev/null +++ b/spec/requests/bootstrap_controller_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe BootstrapController do + + it "returns data as anonymous" do + get "/bootstrap.json" + expect(response.status).to eq(200) + + json = response.parsed_body + expect(json).to be_present + + bootstrap = json['bootstrap'] + expect(bootstrap).to be_present + expect(bootstrap['title']).to be_present + expect(bootstrap['setup_data']['base_url']).to eq(Discourse.base_url) + preloaded = bootstrap['preloaded'] + expect(preloaded['site']).to be_present + expect(preloaded['siteSettings']).to be_present + expect(preloaded['currentUser']).to be_blank + expect(preloaded['topicTrackingStates']).to be_blank + end + + it "returns user data when authenticated" do + user = Fabricate(:user) + sign_in(user) + get "/bootstrap.json" + expect(response.status).to eq(200) + + json = response.parsed_body + expect(json).to be_present + + bootstrap = json['bootstrap'] + preloaded = bootstrap['preloaded'] + expect(preloaded['currentUser']).to be_present + expect(preloaded['topicTrackingStates']).to be_present + end + +end