studio-engine 0.13.1 → 0.14.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/app/views/sessions/new.html.erb +49 -25
- data/lib/studio/version.rb +1 -1
- data/lib/studio.rb +22 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8540d767e024bc8314d5471788d3f430e79a1e17c2dc49ba5c28a61f84f74646
|
|
4
|
+
data.tar.gz: ba45685b2e743504e7c60a59f35a6a41074d72b8ef1c60460f3f6b65d34d65f6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6dabad0d6e3946fb10b990a4b525cd3e03c248eabfebf1408cd790cfaba678df19fe115d7928d8eac247ada917cf9479e7857afe08418d9e9944b0ac7a5ed975
|
|
7
|
+
data.tar.gz: fbd613547387db6bd201d0f03d66685accffcba10adaa8f68349b3fbe785ea275e5c4c6a3f0dff2d15bdc7884294fa995066c7b20830319e54831219bdf6c10c
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html) — `MAJOR.MINOR.PATCH`. Consumer Rails apps install the released RubyGems package with `gem "studio-engine", "~> 0.6"`; bumping the gem version and updating consumer lockfiles is a release.
|
|
4
4
|
|
|
5
|
+
## 0.14.0 — 2026-07-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Passwordless engine login** — the stock `sessions/new` sign-in view now
|
|
10
|
+
renders its method set from `auth_methods`, so a host app configured for
|
|
11
|
+
passwordless sign-in gets the correct engine-shipped view with no local
|
|
12
|
+
override. Fixes a 500 in the passwordless path where the view assumed a
|
|
13
|
+
password field.
|
|
14
|
+
|
|
5
15
|
## 0.13.1 — 2026-07-19
|
|
6
16
|
|
|
7
17
|
### Changed
|
|
@@ -35,36 +35,60 @@
|
|
|
35
35
|
<%= render "sessions/sso_continue" if defined?(sso_user_available?) && sso_user_available? %>
|
|
36
36
|
<% end %>
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
<%# The primary email form renders from the app's configured auth_methods: a PASSWORD
|
|
39
|
+
form only when passwords are available (Studio.password_login_available? — enabled AND
|
|
40
|
+
the User supports `authenticate`), otherwise the passwordless MAGIC-LINK request form.
|
|
41
|
+
The old hardcoded password field 500'd on every passwordless app's only sign-in path. %>
|
|
42
|
+
<% if Studio.password_login_available? %>
|
|
43
|
+
<%= form_tag login_path, method: :post do %>
|
|
44
|
+
<div class="mb-5">
|
|
45
|
+
<label for="email" class="block text-sm text-secondary mb-2 font-medium">Email</label>
|
|
46
|
+
<input type="email" name="email" id="email" value="<%= params[:email] %>" <%= 'autofocus' unless has_sso %>
|
|
47
|
+
x-ref="emailField"
|
|
48
|
+
class="input-field"
|
|
49
|
+
placeholder="you@example.com">
|
|
50
|
+
</div>
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
<div class="mb-6">
|
|
53
|
+
<label for="password" class="block text-sm text-secondary mb-2 font-medium">Password</label>
|
|
54
|
+
<input type="password" name="password" id="password"
|
|
55
|
+
class="input-field"
|
|
56
|
+
placeholder="Your password">
|
|
57
|
+
</div>
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
<button type="submit" class="btn btn-primary btn-lg w-full">
|
|
60
|
+
Log In
|
|
61
|
+
</button>
|
|
62
|
+
<% end %>
|
|
63
|
+
<% elsif Studio.auth_method?(:magic_link) %>
|
|
64
|
+
<%= form_tag magic_link_request_path, method: :post do %>
|
|
65
|
+
<div class="mb-5">
|
|
66
|
+
<label for="email" class="block text-sm text-secondary mb-2 font-medium">Email</label>
|
|
67
|
+
<input type="email" name="email" id="email" value="<%= params[:email] %>" <%= 'autofocus' unless has_sso %>
|
|
68
|
+
x-ref="emailField"
|
|
69
|
+
class="input-field"
|
|
70
|
+
placeholder="you@example.com">
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<button type="submit" class="btn btn-primary btn-lg w-full">
|
|
74
|
+
Send sign-in link
|
|
75
|
+
</button>
|
|
76
|
+
<% end %>
|
|
57
77
|
<% end %>
|
|
58
78
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
<% if Studio.auth_method?(:google) %>
|
|
80
|
+
<% if Studio.password_login_available? || Studio.auth_method?(:magic_link) %>
|
|
81
|
+
<div class="relative my-6">
|
|
82
|
+
<div class="absolute inset-0 flex items-center"><div class="w-full border-t border-subtle"></div></div>
|
|
83
|
+
<div class="relative flex justify-center text-sm"><span class="bg-surface px-3 text-secondary">or</span></div>
|
|
84
|
+
</div>
|
|
85
|
+
<% end %>
|
|
63
86
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
87
|
+
<%= button_to "/auth/google_oauth2", method: :post, data: { turbo: false },
|
|
88
|
+
class: "btn btn-google btn-lg w-full gap-3" do %>
|
|
89
|
+
<%= render "components/google_logo" %>
|
|
90
|
+
Sign in with Google
|
|
91
|
+
<% end %>
|
|
68
92
|
<% end %>
|
|
69
93
|
|
|
70
94
|
<p class="text-center text-secondary text-sm mt-6">
|
data/lib/studio/version.rb
CHANGED
data/lib/studio.rb
CHANGED
|
@@ -152,6 +152,28 @@ module Studio
|
|
|
152
152
|
auth_methods.include?(method.to_sym)
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
+
# True when the engine login should render a PASSWORD field/form: passwords are enabled
|
|
156
|
+
# (`:password` in auth_methods) AND the host User model actually supports them (responds to
|
|
157
|
+
# `authenticate` — i.e. `has_secure_password`). Both are required, and the second is the
|
|
158
|
+
# belt-and-suspenders: without it, a passwordless app (User with no `authenticate`) rendered
|
|
159
|
+
# the hardcoded password field and 500'd on submit via `user.authenticate` — the whole fleet
|
|
160
|
+
# having moved off passwords, this made the engine default wrong for every consumer. The User
|
|
161
|
+
# check is defensive of a mis-set auth_methods; the contract validation normally guarantees it
|
|
162
|
+
# (validate_user_contract! requires PASSWORD_USER_INSTANCE_METHODS iff auth_method?(:password)).
|
|
163
|
+
def self.password_login_available?
|
|
164
|
+
auth_method?(:password) && user_supports_password?
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Does the host User model respond to `authenticate` (has_secure_password)? Safe when no User
|
|
168
|
+
# is defined (an engine-only boot / a test with no host model) — answers false rather than raise.
|
|
169
|
+
def self.user_supports_password?
|
|
170
|
+
return false unless defined?(::User) && ::User.respond_to?(:instance_methods)
|
|
171
|
+
|
|
172
|
+
PASSWORD_USER_INSTANCE_METHODS.all? { |m| ::User.instance_methods.include?(m) }
|
|
173
|
+
rescue StandardError
|
|
174
|
+
false
|
|
175
|
+
end
|
|
176
|
+
|
|
155
177
|
# True when the emailed/inbox magic-link URL is the short /l/<token> — i.e.
|
|
156
178
|
# magic links are Studio::Link rows AND this app draws the /l routes. False =
|
|
157
179
|
# the legacy /magic_link/<token> path: the :signed store, OR an app on the
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: studio-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex McRitchie
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|