Module: Everywhere::Config::Auth
- Included in:
- Everywhere::Config
- Defined in:
- lib/everywhere/config/auth.rb
Constant Summary collapse
- DEFAULT_OAUTH_PATHS =
Paths that begin a third-party auth flow, as regex source strings matched against the request path. Declaring
auth:at all opts in, defaulting to OmniAuth's/auth/…convention. ["^/auth/"].freeze
- URL_SCHEME =
The custom URL scheme ASWebAuthenticationSession returns through. Defaults to the iOS bundle id — the convention, and already unique per app. Only the characters RFC 3986 allows in a scheme.
/\A[a-zA-Z][a-zA-Z0-9+.-]*\z/
Instance Method Summary collapse
-
#auth ⇒ Object
Third-party sign-in (Sign in with Apple / Google / GitHub / anything OmniAuth speaks).
-
#auth_cookie?(name) ⇒ Boolean
Cookie names to carry from the auth browser back into the app's web view, filtered by an optional allow/deny list.
- #auth_errors ⇒ Object
- #auth_scheme ⇒ Object
-
#auth_shell_hash ⇒ Object
The auth subset the shell needs: which visits to divert into the auth session, and the scheme to bring the answer back through.
-
#auth_token_ttl ⇒ Object
How long a minted handoff token stays valid.
- #oauth? ⇒ Boolean
-
#oauth_path?(path) ⇒ Boolean
Whether a request path starts a provider flow.
- #oauth_paths ⇒ Object
Instance Method Details
#auth ⇒ Object
Third-party sign-in (Sign in with Apple / Google / GitHub / anything OmniAuth speaks). Providers refuse to run — or run badly — inside an app's web view, so the mobile shell hands these paths to an ASWebAuthenticationSession instead, and the gem bridges the resulting session back into the app (see AuthHandoff).
auth:
oauth_paths: # paths that begin a provider flow
- ^/auth/ # unanchored regexes, like `rules:`
scheme: com.example.app # callback scheme (default: the iOS bundle id)
cookies: # which cookies cross back into the app
except: ["_ga"] # (default: all of them)
The app keeps its own auth: auth: declares nothing about providers,
only which paths the shell must not open in its web view.
21 |
# File 'lib/everywhere/config/auth.rb', line 21 def auth = @data.fetch("auth", nil) || {} |
#auth_cookie?(name) ⇒ Boolean
Cookie names to carry from the auth browser back into the app's web view, filtered by an optional allow/deny list. Everything the flow set is carried by default: the gem can't know which cookie an app's auth library signs its session with.
67 68 69 70 71 72 73 74 75 |
# File 'lib/everywhere/config/auth.rb', line 67 def (name) = auth["cookies"] return true unless .is_a?(Hash) only = Array(["only"]).map(&:to_s) return only.include?(name.to_s) unless only.empty? !Array(["except"]).map(&:to_s).include?(name.to_s) end |
#auth_errors ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/everywhere/config/auth.rb', line 81 def auth_errors return [] unless @data.key?("auth") errors = oauth_paths.filter_map do |pattern| Regexp.new(pattern) nil rescue RegexpError => e "auth.oauth_paths: #{pattern.inspect} is not a valid pattern (#{e.})" end unless auth_scheme.match?(URL_SCHEME) errors << "auth.scheme #{auth_scheme.inspect} is not a URL scheme (letters, digits, +, -, .)" end errors end |
#auth_scheme ⇒ Object
58 59 60 61 |
# File 'lib/everywhere/config/auth.rb', line 58 def auth_scheme explicit = auth["scheme"].to_s.strip explicit.empty? ? bundle_id(target: "ios") : explicit end |
#auth_shell_hash ⇒ Object
The auth subset the shell needs: which visits to divert into the auth
session, and the scheme to bring the answer back through. nil (absent from
everywhere.json) when the app declares no auth: — a shell that can't
divert anything is a shell with no new surface.
101 102 103 104 105 |
# File 'lib/everywhere/config/auth.rb', line 101 def auth_shell_hash return nil unless oauth? { "oauth_paths" => oauth_paths, "scheme" => auth_scheme } end |
#auth_token_ttl ⇒ Object
How long a minted handoff token stays valid. It travels device-locally (browser sheet → shell → web view), so seconds are plenty.
79 |
# File 'lib/everywhere/config/auth.rb', line 79 def auth_token_ttl = [(auth["token_ttl"] || 60).to_i, 5].max |
#oauth? ⇒ Boolean
35 |
# File 'lib/everywhere/config/auth.rb', line 35 def oauth? = !oauth_paths.empty? |
#oauth_path?(path) ⇒ Boolean
Whether a request path starts a provider flow. Both halves of the system ask this — the middleware per request, the shell per visit proposal — so the patterns are compiled the same way on both sides (unanchored regex).
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/everywhere/config/auth.rb', line 40 def oauth_path?(path) # Compiled once per Config, not once per request: the middleware calls # this on every navigation, and the instance it holds lives until # everywhere.yml changes on disk. An unparseable pattern matches nothing # (auth_errors is what reports it). @oauth_regexps ||= oauth_paths.filter_map do |pattern| Regexp.new(pattern) rescue RegexpError nil end @oauth_regexps.any? { |regexp| regexp.match?(path.to_s) } end |
#oauth_paths ⇒ Object
28 29 30 31 32 33 |
# File 'lib/everywhere/config/auth.rb', line 28 def oauth_paths return [] unless @data.key?("auth") paths = Array(auth["oauth_paths"]).map { |p| p.to_s.strip }.reject(&:empty?) paths.empty? ? DEFAULT_OAUTH_PATHS.dup : paths end |