studio-engine 0.118.0 → 0.119.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/studio.rb CHANGED
@@ -42,10 +42,12 @@ require "studio/navbar_account_sidebar"
42
42
  require "studio/navbar_identity"
43
43
  require "studio/navbar_wordmark"
44
44
  require "studio/navbar_brand"
45
+ require "studio/loader"
45
46
  require "studio/auth_labels"
46
47
  require "studio/profile_sections"
47
48
  require "studio/profile_image"
48
49
  require "studio/oauth_identity"
50
+ require "studio/google_sign_in"
49
51
  require "studio/newsletter"
50
52
  require "studio/health_report"
51
53
  require "studio/agent_chat"
@@ -185,6 +187,26 @@ module Studio
185
187
  # config.features = %i[web3]
186
188
  mattr_accessor :auth_methods, default: %i[magic_link google]
187
189
 
190
+ # ---- Google sign-in, ready out of the box (Studio::GoogleSignIn) ----------
191
+ # :google in auth_methods draws the button; the engine registers the strategy
192
+ # and a default User.from_omniauth. What is left is the OAuth client, and
193
+ # google_ready? says whether the app has one: GOOGLE_CLIENT_ID and
194
+ # GOOGLE_CLIENT_SECRET both set. While it is false the button opens a modal
195
+ # whose "Request Google setup" mails google_setup_request_to, once per app
196
+ # per day, with the redirect URI to register. docs/GOOGLE_AUTH_SETUP.md.
197
+ def self.google_ready?(env: ENV)
198
+ GoogleSignIn.ready?(env: env)
199
+ end
200
+
201
+ mattr_accessor :google_setup_request_to, default: "team@mcritchie.studio"
202
+
203
+ # The host Google's callback lives on, e.g. "voicebox.mcritchie.studio". It
204
+ # names the redirect URI the setup-request email asks ops to register, and in
205
+ # production it pins OmniAuth's callback host. nil, the default, falls back to
206
+ # ENV["APP_HOST"], then the first plain hostname in config.hosts
207
+ # (Studio::GoogleSignIn.canonical_host). Never read from the request.
208
+ mattr_accessor :google_canonical_host, default: nil
209
+
188
210
  # ---- Capability features --------------------------------------------------
189
211
  # Coarse app-level capability switches an app opts into. Distinct from
190
212
  # auth_methods (which sign-in methods the login views render) — these gate
@@ -283,6 +305,27 @@ module Studio
283
305
  @@navbar_wordmark = NavbarWordmark.normalize(config)
284
306
  end
285
307
 
308
+ # ---- Branded loader ----
309
+ # The loader every page load, long wait and pending button draws: the app's
310
+ # own icon in its own theme colours, no per-app code. A style name, or a Hash
311
+ # with the icon (default: the navbar brand logo, else theme_logos' "Navbar
312
+ # Logo") and, for a signature style, the art file of marked layers. The
313
+ # default is :breathe. Rules: lib/studio/loader.rb; docs/LOADER.md.
314
+ #
315
+ # config.loader = :orbit
316
+ # config.loader = { style: :sparkle, icon: "/brand/icon-dark.svg",
317
+ # art: "/brand/loader-sparkle.svg" }
318
+ mattr_reader :loader, default: Loader.normalize(nil)
319
+
320
+ def self.loader=(config)
321
+ @@loader = Loader.normalize(config)
322
+ end
323
+
324
+ # The icon the loader draws: the configured one, else Loader.default_icon.
325
+ def self.loader_icon
326
+ loader[:icon] || Loader.default_icon
327
+ end
328
+
286
329
  def self.sign_in_label=(label)
287
330
  NavbarIdentity.validate_label!(label)
288
331
  @@sign_in_label = label
@@ -1736,6 +1779,16 @@ module Studio
1736
1779
  get "auth/:provider/callback", to: "omniauth_callbacks#create"
1737
1780
  get "auth/failure", to: "omniauth_callbacks#failure"
1738
1781
 
1782
+ # "Request Google setup", the button in the Google modal an app shows
1783
+ # while its OAuth client is unset (Studio::GoogleSignIn). Mails the team
1784
+ # once per app per day, and answers 404 once the
1785
+ # button posts; unauthenticated, since the person asking cannot
1786
+ # sign in yet. Drawn whenever the Google button can be.
1787
+ if Studio.auth_method?(:google)
1788
+ post "_studio/google_setup_request", to: "studio/google_setup_requests#create",
1789
+ as: :studio_google_setup_request
1790
+ end
1791
+
1739
1792
  # The daily health report as JSON, for the hub's central 07:00 pull
1740
1793
  # (Studio::HealthReportsController). Drawn in EVERY environment, production
1741
1794
  # included: the controller is the gate, answering 404 until the app names
@@ -63,6 +63,14 @@ Gem::Specification.new do |spec|
63
63
  # allows accepts redis 6. test/lib/gemspec_redis_bound_test.rb pins it.
64
64
  spec.add_dependency "redis", ">= 4.0.1", "< 6"
65
65
  spec.add_dependency "turbo-rails", ">= 1.0"
66
+ # Google sign-in ships ready (Studio::GoogleSignIn). Every app draws the
67
+ # "Sign in with Google" button, so every app carries the strategy: the engine
68
+ # registers google_oauth2 itself unless the host's own initializer already did.
69
+ # Bounds match the consumers' locks (omniauth 2.1, google-oauth2 1.2,
70
+ # rails_csrf_protection 1.0 and 2.0).
71
+ spec.add_dependency "omniauth", ">= 2.1", "< 3"
72
+ spec.add_dependency "omniauth-google-oauth2", ">= 1.1", "< 2"
73
+ spec.add_dependency "omniauth-rails_csrf_protection", ">= 1.0", "< 3"
66
74
  # IP -> location for Studio::Geo. A dependency rather than a host concern
67
75
  # because the point of the geo primitive is that EVERY app has the capacity:
68
76
  # an app that has to add a gem before it can place a visitor does not.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: studio-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.118.0
4
+ version: 0.119.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex McRitchie
@@ -174,6 +174,66 @@ dependencies:
174
174
  - - ">="
175
175
  - !ruby/object:Gem::Version
176
176
  version: '1.0'
177
+ - !ruby/object:Gem::Dependency
178
+ name: omniauth
179
+ requirement: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '2.1'
184
+ - - "<"
185
+ - !ruby/object:Gem::Version
186
+ version: '3'
187
+ type: :runtime
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '2.1'
194
+ - - "<"
195
+ - !ruby/object:Gem::Version
196
+ version: '3'
197
+ - !ruby/object:Gem::Dependency
198
+ name: omniauth-google-oauth2
199
+ requirement: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: '1.1'
204
+ - - "<"
205
+ - !ruby/object:Gem::Version
206
+ version: '2'
207
+ type: :runtime
208
+ prerelease: false
209
+ version_requirements: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: '1.1'
214
+ - - "<"
215
+ - !ruby/object:Gem::Version
216
+ version: '2'
217
+ - !ruby/object:Gem::Dependency
218
+ name: omniauth-rails_csrf_protection
219
+ requirement: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '1.0'
224
+ - - "<"
225
+ - !ruby/object:Gem::Version
226
+ version: '3'
227
+ type: :runtime
228
+ prerelease: false
229
+ version_requirements: !ruby/object:Gem::Requirement
230
+ requirements:
231
+ - - ">="
232
+ - !ruby/object:Gem::Version
233
+ version: '1.0'
234
+ - - "<"
235
+ - !ruby/object:Gem::Version
236
+ version: '3'
177
237
  - !ruby/object:Gem::Dependency
178
238
  name: geocoder
179
239
  requirement: !ruby/object:Gem::Requirement
@@ -400,6 +460,7 @@ files:
400
460
  - app/controllers/studio/component_previews_controller.rb
401
461
  - app/controllers/studio/emails_controller.rb
402
462
  - app/controllers/studio/geo_settings_controller.rb
463
+ - app/controllers/studio/google_setup_requests_controller.rb
403
464
  - app/controllers/studio/health_reports_controller.rb
404
465
  - app/controllers/studio/knowledge_docs_controller.rb
405
466
  - app/controllers/studio/links_controller.rb
@@ -419,6 +480,7 @@ files:
419
480
  - app/helpers/studio/fizz_helper.rb
420
481
  - app/helpers/studio/geo_helper.rb
421
482
  - app/helpers/studio/link_preview_helper.rb
483
+ - app/helpers/studio/loader_helper.rb
422
484
  - app/helpers/studio/public_user_helper.rb
423
485
  - app/helpers/studio/site_footer_helper.rb
424
486
  - app/helpers/studio_email_delivery_helper.rb
@@ -466,6 +528,7 @@ files:
466
528
  - app/javascript/studio/leveling_activity.js
467
529
  - app/javascript/studio/link_preview_card.js
468
530
  - app/javascript/studio/link_sidebar.js
531
+ - app/javascript/studio/loader.js
469
532
  - app/javascript/studio/local_path.js
470
533
  - app/javascript/studio/modal_countdown.js
471
534
  - app/javascript/studio/modal_host.js
@@ -486,12 +549,14 @@ files:
486
549
  - app/jobs/studio/email_delivery_job.rb
487
550
  - app/jobs/studio/health_report_job.rb
488
551
  - app/mailers/application_mailer.rb
552
+ - app/mailers/studio/google_setup_mailer.rb
489
553
  - app/mailers/studio/health_report_mailer.rb
490
554
  - app/mailers/studio/newsletter_mailer.rb
491
555
  - app/mailers/studio/profile_mailer.rb
492
556
  - app/mailers/user_mailer.rb
493
557
  - app/models/concerns/sluggable.rb
494
558
  - app/models/concerns/studio/board/rankable.rb
559
+ - app/models/concerns/studio/omniauth_user.rb
495
560
  - app/models/current.rb
496
561
  - app/models/error_log.rb
497
562
  - app/models/image_cache.rb
@@ -591,6 +656,10 @@ files:
591
656
  - app/views/studio/emails/show.html.erb
592
657
  - app/views/studio/fields/_date_of_birth.html.erb
593
658
  - app/views/studio/geo_settings/edit.html.erb
659
+ - app/views/studio/google_setup_mailer/setup_requested.html.erb
660
+ - app/views/studio/google_setup_mailer/setup_requested.text.erb
661
+ - app/views/studio/google_sign_in/_button.html.erb
662
+ - app/views/studio/google_sign_in/_setup_modal.html.erb
594
663
  - app/views/studio/health_report_mailer/daily.html.erb
595
664
  - app/views/studio/health_report_mailer/daily.text.erb
596
665
  - app/views/studio/knowledge_docs/_access_chips.html.erb
@@ -610,6 +679,8 @@ files:
610
679
  - app/views/studio/knowledge_docs/preview.html.erb
611
680
  - app/views/studio/knowledge_docs/show.html.erb
612
681
  - app/views/studio/links/confirm.html.erb
682
+ - app/views/studio/loader/_loader.html.erb
683
+ - app/views/studio/loader/_overlay.html.erb
613
684
  - app/views/studio/local_emails/index.html.erb
614
685
  - app/views/studio/mailers/_layered_banner.html.erb
615
686
  - app/views/studio/modals/_crop_photo.html.erb
@@ -755,6 +826,7 @@ files:
755
826
  - lib/studio/geo.rb
756
827
  - lib/studio/geo/countries.rb
757
828
  - lib/studio/geo/lookup.rb
829
+ - lib/studio/google_sign_in.rb
758
830
  - lib/studio/health_report.rb
759
831
  - lib/studio/hold_button.rb
760
832
  - lib/studio/host_schema.rb
@@ -772,6 +844,7 @@ files:
772
844
  - lib/studio/link_preview.rb
773
845
  - lib/studio/link_resolution.rb
774
846
  - lib/studio/link_token.rb
847
+ - lib/studio/loader.rb
775
848
  - lib/studio/local_path.rb
776
849
  - lib/studio/log_rotation.rb
777
850
  - lib/studio/mail_sender.rb