Class: Everywhere::MobileConfigsController

Inherits:
ActionController::API
  • Object
show all
Defined in:
lib/everywhere/mobile_configs_controller.rb

Overview

Serves the mobile shells' remote path configuration in Rails apps:

GET /everywhere/ios_v1.json      -> MobileConfigsController#show

The route is appended by Everywhere::Engine, so it shows up in rails routes and the app can override it by drawing its own. Inherits ActionController::API on purpose:

* never the app's ApplicationController — its before_actions
(authentication!) would lock the shells out, and
* not ActionController::Base — its `helper :all` resolution reaches
into the host app's helpers, which aren't loadable when the gem is
required during boot. A JSON endpoint needs none of that.

everywhere.yml is re-read on every request: tab changes go live with a deploy — or a plain file save in development, where responses are explicitly uncached so the dev shell's reload polling sees them instantly.

Instance Method Summary collapse

Instance Method Details

#apple_app_site_associationObject

GET /.well-known/apple-app-site-association — the iOS universal-links association file, generated from everywhere.yml. Extension-less and application/json, per Apple. 404 when deep linking isn't configured.



42
43
44
45
46
47
# File 'lib/everywhere/mobile_configs_controller.rb', line 42

def apple_app_site_association
  json = Config.load(::Rails.root.to_s).apple_app_site_association_json
  return head(:not_found) unless json

  render json: json
end

GET /.well-known/assetlinks.json — the Android Digital Asset Links file.



50
51
52
53
54
55
# File 'lib/everywhere/mobile_configs_controller.rb', line 50

def asset_links
  json = Config.load(::Rails.root.to_s).asset_links_json
  return head(:not_found) unless json

  render json: json
end

#jump_leaveObject

GET /everywhere/jump/leave — the way back OUT of a Jump preview. Served unconditionally (unlike the endpoints above): once Jump re-roots onto a previewed app, this page is its only path home, preview session or not.



88
89
90
91
92
# File 'lib/everywhere/mobile_configs_controller.rb', line 88

def jump_leave
  response.headers["cache-control"] = "no-store"
  render html: Everywhere.mobile_jump_leave_html.html_safe,
         layout: false, content_type: "text/html"
end

#jump_manifestObject



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/everywhere/mobile_configs_controller.rb', line 73

def jump_manifest
  return head(:not_found) unless Jump.enabled?

  apply_jump_headers
  return head(:no_content) if request.method == "OPTIONS"

  bearer = request.headers["Authorization"].to_s.delete_prefix("Bearer ").strip
  return head(:forbidden) unless Jump.valid_bearer?(bearer)

  render json: Jump.manifest_hash(Config.load(::Rails.root.to_s))
end

#jump_sessionObject

Jump preview endpoints (spec: platform/docs/jump.md §3). 404 unless every preview is running (EVERYWHERE_JUMP_TOKEN set), so nothing is reachable on a normal deploy. Always cross-origin (the connect page lives on the Jump site), hence the CORS headers + preflight.



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/everywhere/mobile_configs_controller.rb', line 61

def jump_session
  return head(:not_found) unless Jump.enabled?

  apply_jump_headers
  return head(:no_content) if request.method == "OPTIONS"

  result = Jump.exchange(params[:token], params[:device_name])
  return head(:forbidden) unless result

  render json: result, status: :created
end

#resetObject

GET /everywhere/reset?to=/path — the native "reset the app" page. Auth flows redirect the shell here so it rebuilds cleanly before landing on to. Never cached (it must run every time).



97
98
99
100
101
# File 'lib/everywhere/mobile_configs_controller.rb', line 97

def reset
  response.headers["cache-control"] = "no-store"
  render html: Everywhere.mobile_reset_html(params[:to]).html_safe,
         layout: false, content_type: "text/html"
end

#showObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/everywhere/mobile_configs_controller.rb', line 24

def show
  config = Config.load(::Rails.root.to_s)

  # Never cache: the response depends on the session (filter_tabs can hide
  # tabs when signed out), so a shared/public cache could serve one user's
  # tabs to another, and a client cache would serve stale tabs across
  # sign-in/out. The endpoint is a couple of milliseconds — no cache needed.
  response.headers["cache-control"] = "no-store"

  os = params[:platform_v1].delete_suffix("_v1")
  tabs = Everywhere.resolve_tabs(config.tabs_for(os), request)
  tabs = Jump.exit_tabs(config, os, tabs) if Jump.enabled?
  render json: config.path_configuration_hash(os, tabs: tabs)
end