diff --git a/app/controllers/oidc_accounts_controller.rb b/app/controllers/oidc_accounts_controller.rb
index 6e22a1c93..4e7c9275f 100644
--- a/app/controllers/oidc_accounts_controller.rb
+++ b/app/controllers/oidc_accounts_controller.rb
@@ -102,10 +102,12 @@ class OidcAccountsController < ApplicationController
# Security: JIT users should NOT have password_digest set to prevent
# chained authentication attacks where SSO users gain local login access
# via password reset.
+ # Allow user to edit first_name and last_name from the form, but email comes from OIDC
+ user_params = params.fetch(:user, {}).permit(:first_name, :last_name)
@user = User.new(
email: email,
- first_name: @pending_auth["first_name"],
- last_name: @pending_auth["last_name"],
+ first_name: user_params[:first_name].presence || @pending_auth["first_name"],
+ last_name: user_params[:last_name].presence || @pending_auth["last_name"],
skip_password_validation: true
)
diff --git a/app/views/oidc_accounts/new_user.html.erb b/app/views/oidc_accounts/new_user.html.erb
new file mode 100644
index 000000000..4656d4dba
--- /dev/null
+++ b/app/views/oidc_accounts/new_user.html.erb
@@ -0,0 +1,37 @@
+<%
+ header_title t("oidc_accounts.new_user.title")
+%>
+
+
+
<%= t("oidc_accounts.new_user.heading") %>
+
+ <%= t("oidc_accounts.new_user.description", provider: @pending_auth["provider"]) %>
+
+
+
+<%= styled_form_with model: @user, url: create_user_oidc_account_path, class: "space-y-4", data: { turbo: false } do |form| %>
+
+
<%= t("oidc_accounts.new_user.email_label") %>
+
<%= @pending_auth["email"] %>
+
+
+ <%= form.text_field :first_name,
+ label: t("oidc_accounts.new_user.first_name_label"),
+ placeholder: t("oidc_accounts.new_user.first_name_placeholder"),
+ autofocus: true %>
+
+ <%= form.text_field :last_name,
+ label: t("oidc_accounts.new_user.last_name_label"),
+ placeholder: t("oidc_accounts.new_user.last_name_placeholder") %>
+
+ <%= form.submit t("oidc_accounts.new_user.submit") %>
+<% end %>
+
+
+ <%= render DS::Link.new(
+ text: t("oidc_accounts.new_user.cancel"),
+ href: new_session_path,
+ variant: :default,
+ class: "font-medium text-sm text-primary hover:underline transition"
+ ) %>
+
diff --git a/config/locales/views/oidc_accounts/en.yml b/config/locales/views/oidc_accounts/en.yml
index d39572b2a..618baf7e2 100644
--- a/config/locales/views/oidc_accounts/en.yml
+++ b/config/locales/views/oidc_accounts/en.yml
@@ -3,3 +3,14 @@ en:
oidc_accounts:
link:
account_creation_disabled: New account creation via single sign-on is disabled. Please contact an administrator to create your account.
+ new_user:
+ title: Complete Your Account
+ heading: Create Your Account
+ description: Please confirm your details to complete account creation with your %{provider} identity.
+ email_label: Email (from SSO provider)
+ first_name_label: First Name
+ first_name_placeholder: Enter your first name
+ last_name_label: Last Name
+ last_name_placeholder: Enter your last name
+ submit: Create Account
+ cancel: Cancel
diff --git a/test/controllers/oidc_accounts_controller_test.rb b/test/controllers/oidc_accounts_controller_test.rb
index 9cb283960..a26975176 100644
--- a/test/controllers/oidc_accounts_controller_test.rb
+++ b/test/controllers/oidc_accounts_controller_test.rb
@@ -98,6 +98,18 @@ class OidcAccountsControllerTest < ActionController::TestCase
}
end
+ test "should show new_user page when pending auth exists" do
+ session[:pending_oidc_auth] = new_user_auth
+ get :new_user
+ assert_response :success
+ end
+
+ test "should redirect new_user to login when no pending auth" do
+ get :new_user
+ assert_redirected_to new_session_path
+ assert_equal "No pending OIDC authentication found", flash[:alert]
+ end
+
test "should show create account option for new user" do
session[:pending_oidc_auth] = new_user_auth
@@ -175,6 +187,34 @@ class OidcAccountsControllerTest < ActionController::TestCase
assert_equal new_user_auth["uid"], oidc_identity.uid
end
+ test "create_user uses form params for name when provided" do
+ session[:pending_oidc_auth] = new_user_auth
+
+ assert_difference [ "User.count", "OidcIdentity.count" ], 1 do
+ post :create_user, params: {
+ user: { first_name: "Custom", last_name: "Name" }
+ }
+ end
+
+ assert_redirected_to root_path
+
+ new_user = User.find_by(email: new_user_auth["email"])
+ assert_equal "Custom", new_user.first_name
+ assert_equal "Name", new_user.last_name
+ end
+
+ test "create_user falls back to OIDC data when form params are blank" do
+ session[:pending_oidc_auth] = new_user_auth
+
+ post :create_user, params: {
+ user: { first_name: "", last_name: "" }
+ }
+
+ new_user = User.find_by(email: new_user_auth["email"])
+ assert_equal new_user_auth["first_name"], new_user.first_name
+ assert_equal new_user_auth["last_name"], new_user.last_name
+ end
+
test "should create session after OIDC registration" do
session[:pending_oidc_auth] = new_user_auth