From 68610431e7590e7652ef2cef88883899d9b1718c Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Fri, 22 May 2026 15:52:45 +0200 Subject: [PATCH 01/14] Update the XWiki auth screen Remove outdated code, since now we can use the parent OAuth. --- .../oauth_clients/create_contract.rb | 4 +- .../oauth_client_form_component.html.erb | 36 ++++++++++- .../forms/oauth_client_form_component.rb | 5 +- .../oauth_client_info_component.html.erb | 8 ++- .../oauth_clients/xwiki_create_contract.rb | 38 ----------- .../wikis/admin/oauth_clients_controller.rb | 7 ++- .../wikis/app/models/wikis/xwiki_provider.rb | 1 + .../providers/xwiki/oauth_configuration.rb | 4 +- .../adapters/providers/xwiki/queries/user.rb | 2 +- .../wikis/oauth_clients/create_service.rb | 2 +- modules/wikis/config/locales/en.yml | 6 +- .../x_wiki_create_contract_spec.rb | 63 ------------------- .../xwiki/oauth_configuration_spec.rb | 4 +- .../providers/xwiki/queries/user_spec.rb | 16 ++--- 14 files changed, 70 insertions(+), 126 deletions(-) delete mode 100644 modules/wikis/app/contracts/wikis/oauth_clients/xwiki_create_contract.rb delete mode 100644 modules/wikis/spec/contracts/wikis/oauth_clients/x_wiki_create_contract_spec.rb diff --git a/app/contracts/oauth_clients/create_contract.rb b/app/contracts/oauth_clients/create_contract.rb index 83df00f53977..398a9a21f634 100644 --- a/app/contracts/oauth_clients/create_contract.rb +++ b/app/contracts/oauth_clients/create_contract.rb @@ -36,11 +36,9 @@ class CreateContract < ::ModelContract validates :client_id, presence: true, length: { maximum: 255 } attribute :client_secret, writable: true - validates :client_secret, presence: true, if: :client_secret_required? + validates :client_secret, presence: true validates :client_secret, length: { maximum: 255 } - def client_secret_required? = true - attribute :integration_type, writable: true validates :integration_type, presence: true diff --git a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb index 1c71a51c859b..24a94406e53c 100644 --- a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb @@ -20,8 +20,9 @@ name: "oauth_client[client_id]", label: t(".client_id"), visually_hide_label: false, + readonly: false, value: resolved_oauth_client.client_id, - readonly: true + required: true ) input_group.with_trailing_action_clipboard_copy_button( value: resolved_oauth_client.client_id, @@ -30,6 +31,39 @@ end end + oauth_client_row.with_row(mb: 3) do + render(Primer::OpenProject::InputGroup.new(input_width: :large)) do |input_group| + input_group.with_text_input( + name: "oauth_client[client_secret]", + label: t(".client_secret"), + visually_hide_label: false, + readonly: false, + value: resolved_oauth_client.client_secret, + required: true + ) + input_group.with_trailing_action_clipboard_copy_button( + value: resolved_oauth_client.client_secret, + aria: { label: t("button_copy_to_clipboard") } + ) + end + end + + oauth_client_row.with_row(mb: 3) do + render(Primer::OpenProject::InputGroup.new(input_width: :large)) do |input_group| + input_group.with_text_input( + name: "oauth_client[redirect_uri]", + label: t(".redirect_uri"), + visually_hide_label: false, + value: resolved_oauth_client.redirect_uri + ) + input_group.with_trailing_action_clipboard_copy_button( + value: resolved_oauth_client.redirect_uri, + aria: { label: t("button_copy_to_clipboard") } + ) + input_group.with_caption { t(".redirect_uri_caption") } + end + end + oauth_client_row.with_row do render( Wikis::Admin::SubmitOrCancelForm.new( diff --git a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb index 37c7b8bbb721..d7a0d233a821 100644 --- a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb +++ b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb @@ -51,7 +51,10 @@ def cancel_button_path def resolved_oauth_client oauth_client || wiki_provider.oauth_client || - wiki_provider.build_oauth_client(client_id: Wikis::XWikiProvider.generate_client_id) + wiki_provider.build_oauth_client( + client_id: Wikis::XWikiProvider.generate_client_id, + client_secret: Wikis::XWikiProvider.generate_client_secret + ) end end end diff --git a/modules/wikis/app/components/wikis/admin/oauth_client_info_component.html.erb b/modules/wikis/app/components/wikis/admin/oauth_client_info_component.html.erb index 801914d20694..ad152a7620a0 100644 --- a/modules/wikis/app/components/wikis/admin/oauth_client_info_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/oauth_client_info_component.html.erb @@ -10,8 +10,12 @@ end end - grid.with_area(:description, tag: :div, color: :subtle) do - render(Primer::Beta::Text.new) { t("wikis.admin.wiki_providers.#{wiki_provider}.oauth.provider_oauth_description") } + grid.with_area(:description, classes: "wb-break-word", tag: :div, color: :subtle) do + if oauth_client.present? + render(Primer::Beta::Text.new) { "#{t('.label_oauth_client_id')}: #{oauth_client.client_id}" } + else + render(Primer::Beta::Text.new) { t("wikis.admin.wiki_providers.#{wiki_provider}.oauth.provider_oauth_description") } + end end if wiki_provider.persisted? diff --git a/modules/wikis/app/contracts/wikis/oauth_clients/xwiki_create_contract.rb b/modules/wikis/app/contracts/wikis/oauth_clients/xwiki_create_contract.rb deleted file mode 100644 index df7d5fdc57dc..000000000000 --- a/modules/wikis/app/contracts/wikis/oauth_clients/xwiki_create_contract.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -module Wikis - module OAuthClients - # XWiki uses a public OAuth client (RFC 6749 §2.1) — no client_secret is issued. - class XWikiCreateContract < ::OAuthClients::CreateContract - def client_secret_required? = false - end - end -end diff --git a/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb b/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb index 96c4ff9efa64..d8f2431a4dfa 100644 --- a/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb +++ b/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb @@ -42,7 +42,10 @@ class OAuthClientsController < ApplicationController menu_item :wiki_providers def new - oauth_client = OAuthClient.new(client_id: Wikis::XWikiProvider.generate_client_id) + oauth_client = OAuthClient.new( + client_id: Wikis::XWikiProvider.generate_client_id, + client_secret: Wikis::XWikiProvider.generate_client_secret + ) update_via_turbo_stream( component: Wikis::Admin::Forms::OAuthClientFormComponent.new(@wiki_provider, @@ -92,7 +95,7 @@ def save_oauth_client end def oauth_client_params - params.expect(oauth_client: [:client_id]) + params.expect(oauth_client: [:client_id, :client_secret]) end def find_wiki_provider diff --git a/modules/wikis/app/models/wikis/xwiki_provider.rb b/modules/wikis/app/models/wikis/xwiki_provider.rb index 47f535987edd..6151824237c4 100644 --- a/modules/wikis/app/models/wikis/xwiki_provider.rb +++ b/modules/wikis/app/models/wikis/xwiki_provider.rb @@ -46,6 +46,7 @@ class XWikiProvider < Provider class << self def registry_prefix = "xwiki" def generate_client_id = SecureRandom.uuid + def generate_client_secret = SecureRandom.hex(32) end def configured? diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/oauth_configuration.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/oauth_configuration.rb index 32228586974f..01b14a753a64 100644 --- a/modules/wikis/app/services/wikis/adapters/providers/xwiki/oauth_configuration.rb +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/oauth_configuration.rb @@ -35,8 +35,6 @@ module XWiki # OAuth2 configuration for XWiki's OIDC Provider extension. # # Deviations from a standard OAuth2 confidential client: - # - Public client: no client_secret; token_endpoint_auth_method is :none. - # - No pre-registration: XWiki accepts any client_id/redirect_uri; consent is stored on first auth. # - No refresh tokens: tokens are long-lived; re-auth via ensure_connection if revoked. # - No expires_in: tokens do not expire; expires_in is stored as nil. # @@ -69,9 +67,9 @@ def authorization_uri(state: nil) def basic_rack_oauth_client uri = provider_uri - # XWiki is a public client — no secret is used. Rack::OAuth2::Client.new( identifier: @oauth_client.client_id, + secret: @oauth_client.client_secret, redirect_uri: @oauth_client.redirect_uri, scheme: uri.scheme, host: uri.host, diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/user.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/user.rb index 4c7a28b9a02f..a49fbb3296f9 100644 --- a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/user.rb +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/user.rb @@ -35,7 +35,7 @@ module XWiki module Queries class User < BaseQuery def call(auth_strategy:) - url = "#{provider.url.chomp('/')}/rest/" + url = "#{provider.url.chomp('/')}/rest/wikis/xwiki/user" Adapters::Authentication[auth_strategy].call do |http| handle_response(http.get(url)) end diff --git a/modules/wikis/app/services/wikis/oauth_clients/create_service.rb b/modules/wikis/app/services/wikis/oauth_clients/create_service.rb index 65c3dfaaade8..41b062391764 100644 --- a/modules/wikis/app/services/wikis/oauth_clients/create_service.rb +++ b/modules/wikis/app/services/wikis/oauth_clients/create_service.rb @@ -32,7 +32,7 @@ module Wikis module OAuthClients class CreateService < ::OAuthClients::CreateService def initialize(**) - super(contract_class: Wikis::OAuthClients::XWikiCreateContract, **) + super(contract_class: ::OAuthClients::CreateContract, **) end def attributes_service_class diff --git a/modules/wikis/config/locales/en.yml b/modules/wikis/config/locales/en.yml index 6584f37749b2..52740cdc9895 100644 --- a/modules/wikis/config/locales/en.yml +++ b/modules/wikis/config/locales/en.yml @@ -81,6 +81,9 @@ en: application_secret: Application secret oauth_client_form_component: client_id: Client ID + client_secret: Client secret + redirect_uri: Redirect URI + redirect_uri_caption: Copy this value into the Redirect URI field of your XWiki OIDC client registration. health_status: show: actions: @@ -97,6 +100,7 @@ en: replace_oauth_application: Replace OpenProject OAuth application oauth_client_info_component: confirm_replace_oauth_client: This action will reset the current XWiki OAuth credentials. All users will need to reauthorize against XWiki. Are you sure you want to proceed? + label_oauth_client_id: OAuth Client ID label_pending: Pending replace_oauth_client: Replace XWiki OAuth application side_panel: @@ -131,7 +135,7 @@ en: oauth: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth application. Copy the credentials below into your XWiki instance. provider_oauth: XWiki OAuth - provider_oauth_description: Allow OpenProject to access XWiki data using OAuth. A client ID is automatically generated to identify OpenProject to XWiki — no manual configuration is needed on the XWiki side. + provider_oauth_description: Allow OpenProject to access XWiki data using OAuth. A client ID and client secret have been pre-generated for you — copy them along with the redirect URI into your XWiki OIDC client registration. You can change the client ID and secret if needed. openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. diff --git a/modules/wikis/spec/contracts/wikis/oauth_clients/x_wiki_create_contract_spec.rb b/modules/wikis/spec/contracts/wikis/oauth_clients/x_wiki_create_contract_spec.rb deleted file mode 100644 index 8b9f8065e2b7..000000000000 --- a/modules/wikis/spec/contracts/wikis/oauth_clients/x_wiki_create_contract_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -require "spec_helper" -require_module_spec_helper -require "contracts/shared/model_contract_shared_context" - -RSpec.describe Wikis::OAuthClients::XWikiCreateContract do - include_context "ModelContract shared context" - - let(:current_user) { create(:admin) } - let(:client_id) { SecureRandom.uuid } - let(:client_secret) { nil } - let(:integration) { create(:xwiki_provider) } - let(:oauth_client) { build(:oauth_client, client_id:, client_secret:, integration:) } - - let(:contract) { described_class.new(oauth_client, current_user) } - - describe "client_secret" do - context "when absent (nil)" do - include_examples "contract is valid" - end - - context "when empty string" do - let(:client_secret) { "" } - - include_examples "contract is valid" - end - - context "when too long" do - let(:client_secret) { "X" * 257 } - - include_examples "contract is invalid", client_secret: :too_long - end - end -end diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb index 0676df3b9997..b86ef19a008c 100644 --- a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Wikis::Adapters::Providers::XWiki::OAuthConfiguration do let(:wiki_provider) { build_stubbed(:xwiki_provider, url: "https://xwiki.example.com/xwiki") } - let(:oauth_client) { build_stubbed(:oauth_client, client_id: "xwiki-uuid", integration: wiki_provider) } + let(:oauth_client) { build_stubbed(:oauth_client, client_id: "xwiki-uuid", client_secret: "xwiki-secret", integration: wiki_provider) } before do allow(wiki_provider).to receive(:oauth_client).and_return(oauth_client) @@ -90,7 +90,7 @@ it "configures the rack client with correct attributes" do expect(rack_client).to have_attributes( identifier: "xwiki-uuid", - secret: nil, + secret: "xwiki-secret", token_endpoint: "/xwiki/oidc/token", authorization_endpoint: "/xwiki/oidc/authorization" ) diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/user_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/user_spec.rb index d02794d64e40..b36acd3ec67b 100644 --- a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/user_spec.rb +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/user_spec.rb @@ -35,7 +35,7 @@ let(:user) { build_stubbed(:user) } let(:oauth_client) { build_stubbed(:oauth_client) } let(:wiki_provider) { build_stubbed(:xwiki_provider, url: "https://xwiki.local/") } - let(:rest_url) { "https://xwiki.local/rest/" } + let(:user_url) { "https://xwiki.local/rest/wikis/xwiki/user" } let(:auth_strategy) { Wikis::Adapters::Input::AuthStrategy.build(key: :bearer_token, user:, provider: wiki_provider).value! } subject(:query) { described_class.new(model: wiki_provider) } @@ -51,9 +51,9 @@ end describe "#call" do - context "when the request succeeds with xwiki-user header" do + context "when the request succeeds with an xwiki-user header" do before do - stub_request(:get, rest_url) + stub_request(:get, user_url) .with(headers: { "Authorization" => "Bearer some-token" }) .to_return(status: 200, body: "", headers: { "xwiki-user" => "XWiki.admin" }) end @@ -65,10 +65,10 @@ end end - context "when the token is absent or invalid (XWiki returns 200 without xwiki-user header)" do + context "when the response is missing the xwiki-user header" do before do - stub_request(:get, rest_url) - .to_return(status: 200, body: "", headers: {}) + stub_request(:get, user_url) + .to_return(status: 200, body: "") end it "returns Failure with :unauthorized code" do @@ -80,7 +80,7 @@ context "when XWiki returns a non-2xx status" do before do - stub_request(:get, rest_url).to_return(status: 500, body: "Internal Server Error") + stub_request(:get, user_url).to_return(status: 401, body: "Unauthorized") end it "returns Failure with :request_failed code" do @@ -91,7 +91,7 @@ end context "when a network error occurs" do - before { stub_request(:get, rest_url).to_timeout } + before { stub_request(:get, user_url).to_timeout } it "returns Failure with :connection_error code" do result = query.call(auth_strategy:) From 063428ddc6df5d4286e67df5a34af1d55929c858 Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Fri, 22 May 2026 16:44:49 +0200 Subject: [PATCH 02/14] Fix rubocop issues --- .../app/controllers/wikis/admin/oauth_clients_controller.rb | 2 +- .../adapters/providers/xwiki/oauth_configuration_spec.rb | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb b/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb index d8f2431a4dfa..40613992e4e2 100644 --- a/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb +++ b/modules/wikis/app/controllers/wikis/admin/oauth_clients_controller.rb @@ -95,7 +95,7 @@ def save_oauth_client end def oauth_client_params - params.expect(oauth_client: [:client_id, :client_secret]) + params.expect(oauth_client: %i[client_id client_secret]) end def find_wiki_provider diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb index b86ef19a008c..1fa212d3fcdb 100644 --- a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/oauth_configuration_spec.rb @@ -32,7 +32,9 @@ RSpec.describe Wikis::Adapters::Providers::XWiki::OAuthConfiguration do let(:wiki_provider) { build_stubbed(:xwiki_provider, url: "https://xwiki.example.com/xwiki") } - let(:oauth_client) { build_stubbed(:oauth_client, client_id: "xwiki-uuid", client_secret: "xwiki-secret", integration: wiki_provider) } + let(:oauth_client) do + build_stubbed(:oauth_client, client_id: "xwiki-uuid", client_secret: "xwiki-secret", integration: wiki_provider) + end before do allow(wiki_provider).to receive(:oauth_client).and_return(oauth_client) From bfabc6dbf3324bb729c626429b2d776954638020 Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Fri, 22 May 2026 16:59:38 +0200 Subject: [PATCH 03/14] Fix specs plus a hack how to overcome the error for the `with_trailing_action_clipboard_copy_button` in case if user will delete the data --- .../wikis/admin/forms/oauth_client_form_component.html.erb | 4 ++-- .../wikis/admin/oauth_client_info_component_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb index 24a94406e53c..4b9058150eda 100644 --- a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb @@ -25,7 +25,7 @@ required: true ) input_group.with_trailing_action_clipboard_copy_button( - value: resolved_oauth_client.client_id, + value: resolved_oauth_client.client_id.to_s, aria: { label: t("button_copy_to_clipboard") } ) end @@ -42,7 +42,7 @@ required: true ) input_group.with_trailing_action_clipboard_copy_button( - value: resolved_oauth_client.client_secret, + value: resolved_oauth_client.client_secret.to_s, aria: { label: t("button_copy_to_clipboard") } ) end diff --git a/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb b/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb index ce923d80de79..c5ab272567a8 100644 --- a/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb +++ b/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb @@ -63,9 +63,9 @@ expect(page).to have_text(I18n.t(:label_completed)) end - it "renders the description" do + it "renders the oauth client id" do render_inline(described_class.new(wiki_provider)) - expect(page).to have_text(I18n.t("wikis.admin.wiki_providers.xwiki.oauth.provider_oauth_description")) + expect(page).to have_text("#{I18n.t('wikis.admin.oauth_client_info_component.label_oauth_client_id')}: #{oauth_client.client_id}") end it "renders a sync icon button with a confirm dialog" do From c11bb5c2e3d8c9774fab49951cbd3a2353c8dc0e Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Fri, 22 May 2026 17:09:59 +0200 Subject: [PATCH 04/14] Add validation for client and secret Remove copy button as it doesn't work with validation errors --- .../oauth_client_form_component.html.erb | 46 ++++++++----------- .../forms/oauth_client_form_component.rb | 4 ++ 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb index 4b9058150eda..2f06f1418985 100644 --- a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.html.erb @@ -15,37 +15,27 @@ end oauth_client_row.with_row(mb: 3) do - render(Primer::OpenProject::InputGroup.new(input_width: :large)) do |input_group| - input_group.with_text_input( - name: "oauth_client[client_id]", - label: t(".client_id"), - visually_hide_label: false, - readonly: false, - value: resolved_oauth_client.client_id, - required: true - ) - input_group.with_trailing_action_clipboard_copy_button( - value: resolved_oauth_client.client_id.to_s, - aria: { label: t("button_copy_to_clipboard") } - ) - end + render(Primer::Alpha::TextField.new( + name: "oauth_client[client_id]", + label: t(".client_id"), + visually_hide_label: false, + value: resolved_oauth_client.client_id, + input_width: :large, + required: true, + validation_message: validation_message_for(:client_id) + )) end oauth_client_row.with_row(mb: 3) do - render(Primer::OpenProject::InputGroup.new(input_width: :large)) do |input_group| - input_group.with_text_input( - name: "oauth_client[client_secret]", - label: t(".client_secret"), - visually_hide_label: false, - readonly: false, - value: resolved_oauth_client.client_secret, - required: true - ) - input_group.with_trailing_action_clipboard_copy_button( - value: resolved_oauth_client.client_secret.to_s, - aria: { label: t("button_copy_to_clipboard") } - ) - end + render(Primer::Alpha::TextField.new( + name: "oauth_client[client_secret]", + label: t(".client_secret"), + visually_hide_label: false, + value: resolved_oauth_client.client_secret, + input_width: :large, + required: true, + validation_message: validation_message_for(:client_secret) + )) end oauth_client_row.with_row(mb: 3) do diff --git a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb index d7a0d233a821..54137492bc47 100644 --- a/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb +++ b/modules/wikis/app/components/wikis/admin/forms/oauth_client_form_component.rb @@ -56,5 +56,9 @@ def resolved_oauth_client client_secret: Wikis::XWikiProvider.generate_client_secret ) end + + def validation_message_for(attribute) + resolved_oauth_client.errors.messages_for(attribute).to_sentence.presence + end end end From 37b4ff550417fc33b5fc0bf755d440ac0acccf40 Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Fri, 22 May 2026 17:25:56 +0200 Subject: [PATCH 05/14] Update oauth_client_info_component_spec.rb --- .../wikis/admin/oauth_client_info_component_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb b/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb index c5ab272567a8..05831fddd7c9 100644 --- a/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb +++ b/modules/wikis/spec/components/wikis/admin/oauth_client_info_component_spec.rb @@ -65,7 +65,9 @@ it "renders the oauth client id" do render_inline(described_class.new(wiki_provider)) - expect(page).to have_text("#{I18n.t('wikis.admin.oauth_client_info_component.label_oauth_client_id')}: #{oauth_client.client_id}") + expect(page).to have_text( + "#{I18n.t('wikis.admin.oauth_client_info_component.label_oauth_client_id')}: #{oauth_client.client_id}" + ) end it "renders a sync icon button with a confirm dialog" do From b1c152cf5b6b1b5dc58ae625ebfec24be3ff57dc Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Tue, 26 May 2026 15:56:07 +0200 Subject: [PATCH 06/14] Move health check down Add the provider type to the name of the provider --- .../app/views/wikis/admin/wiki_providers/edit.html.erb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb b/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb index 8c9a161588be..b8afd7cbb115 100644 --- a/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb +++ b/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb @@ -32,7 +32,12 @@ See COPYRIGHT and LICENSE files for more details. <% html_title t(:label_administration), t(:project_module_wiki_platforms), page_title %> <%= render(Primer::OpenProject::PageHeader.new) do |header| %> - <% header.with_title { page_title } %> + <% header.with_title do %> + <%= page_title %> + <%= render(Primer::Beta::Text.new(tag: :span, font_weight: :light, color: :muted)) do %> + (<%= t("wikis.provider_types.#{@wiki_provider}.name") %>) + <% end %> + <% end %> <% header.with_breadcrumbs( @@ -90,7 +95,7 @@ See COPYRIGHT and LICENSE files for more details. render(Wikis::Admin::WikiProviderViewComponent.new(@wiki_provider, wizard: @wizard)) end - page.with_sidebar(col_placement: :end, row_placement: :start) do + page.with_sidebar(col_placement: :end, row_placement: :end) do render(Wikis::Admin::SidePanelComponent.new(@wiki_provider)) end end From aec0ebbb4c3db4e927fcbd141e552604a64ebb08 Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Tue, 26 May 2026 16:14:21 +0200 Subject: [PATCH 07/14] Add xwiki admin URL --- .../forms/oauth_application_form_component.html.erb | 12 +++++++----- .../admin/forms/oauth_application_form_component.rb | 6 ++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.html.erb b/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.html.erb index be3f3e4d80d6..400cd63dd16a 100644 --- a/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.html.erb @@ -1,12 +1,14 @@ <%= component_wrapper do flex_layout(flex_items: :center) do |credentials_row| - credentials_row.with_row do - render(Primer::Beta::Text.new(font_weight: :bold)) { t("wikis.admin.wiki_providers.oauth.openproject_oauth") } - end - credentials_row.with_row(mb: 3) do - render(Primer::Beta::Text.new(color: :subtle)) { t("wikis.admin.wiki_providers.#{wiki_provider}.oauth.openproject_oauth_description") } + render(Primer::Alpha::Banner.new(icon: :alert, scheme: :warning)) do + helpers.link_translate( + "wikis.instructions.xwiki.oauth_application_details_html", + links: { xwiki_admin_link: xwiki_admin_url }, + external: true + ) + end end credentials_row.with_row(mb: 3) do diff --git a/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.rb b/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.rb index 55ab8108c73a..b0b3c39b101c 100644 --- a/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.rb +++ b/modules/wikis/app/components/wikis/admin/forms/oauth_application_form_component.rb @@ -30,6 +30,8 @@ module Wikis::Admin::Forms class OAuthApplicationFormComponent < Wikis::Admin::WikiProviderComponent + OPENPROJECT_PLUGIN_ADMIN_PATH = "/bin/admin/XWiki/XWikiPreferences?editor=globaladmin§ion=OpenProject" + def self.wrapper_key = :wiki_provider_oauth_application_section delegate :oauth_application, to: :wiki_provider @@ -43,5 +45,9 @@ def done_button_path url_helpers.edit_admin_settings_wiki_provider_path(wiki_provider) end end + + def xwiki_admin_url + "#{wiki_provider.url.to_s.chomp('/')}#{OPENPROJECT_PLUGIN_ADMIN_PATH}" + end end end From 5fb46c599d50f1dcd6f6bfca4fbcfb786d5aadce Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Tue, 26 May 2026 16:17:13 +0200 Subject: [PATCH 08/14] Update translations and wiki provider oauth section --- .../admin/general_info_component.html.erb | 7 ++++-- .../oauth_application_info_component.html.erb | 6 ++++- modules/wikis/config/locales/en.yml | 23 +++++++++++++------ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb index ef908a10b825..065bca5f49bc 100644 --- a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb @@ -7,8 +7,11 @@ end grid.with_area(:description, tag: :div, color: :subtle, test_selector: "wiki-provider-description") do - concat(render(Primer::Beta::Text.new) { "#{wiki_provider.name} - " }) - concat(render(Primer::Beta::Link.new(href: wiki_provider.url, target: "_blank", underline: true)) { wiki_provider.url }) + concat(render(Primer::Beta::Text.new) { "#{t("wikis.provider_types.#{wiki_provider}.name")} - #{wiki_provider.name} - #{wiki_provider.url}" }) + if wiki_provider.url.present? + concat(render(Primer::Beta::Text.new) { " - " }) + concat(helpers.static_link_to(href: wiki_provider.url, label: t("wikis.buttons.open_wiki"), underline: true)) + end end grid.with_area(:"icon-button", tag: :div, color: :muted) do diff --git a/modules/wikis/app/components/wikis/admin/oauth_application_info_component.html.erb b/modules/wikis/app/components/wikis/admin/oauth_application_info_component.html.erb index 9ef7e1cd6d40..b8209c20a807 100644 --- a/modules/wikis/app/components/wikis/admin/oauth_application_info_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/oauth_application_info_component.html.erb @@ -11,7 +11,11 @@ end grid.with_area(:description, tag: :div, color: :subtle) do - render(Primer::Beta::Text.new) { t("wikis.admin.wiki_providers.#{wiki_provider}.oauth.openproject_oauth_description") } + if oauth_application.present? + render(Primer::Beta::Text.new) { "#{t(".label_oauth_client_id")}: #{oauth_application.uid}" } + else + render(Primer::Beta::Text.new) { t("wikis.admin.wiki_providers.#{wiki_provider}.oauth.openproject_oauth_description") } + end end if wiki_provider.persisted? diff --git a/modules/wikis/config/locales/en.yml b/modules/wikis/config/locales/en.yml index 52740cdc9895..206ef0c93201 100644 --- a/modules/wikis/config/locales/en.yml +++ b/modules/wikis/config/locales/en.yml @@ -35,8 +35,16 @@ en: buttons: connect_account: Connect %{provider} account done_continue: Done, continue + open_wiki: Open wiki save_and_continue: Save and continue wiki_page: Wiki page + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + provider_types: + xwiki: + name: XWiki delete_relation_page_link_confirmation_dialog: title: Delete related wiki page link heading: Delete related wiki page link? @@ -77,11 +85,11 @@ en: general_info_form_component: xwiki_instance_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. oauth_application_form_component: - application_id: Application ID - application_secret: Application secret + application_id: OpenProject OAuth Application ID + application_secret: OpenProject OAuth Application secret oauth_client_form_component: - client_id: Client ID - client_secret: Client secret + client_id: Wiki OAuth Client ID + client_secret: Wiki OAuth Client secret redirect_uri: Redirect URI redirect_uri_caption: Copy this value into the Redirect URI field of your XWiki OIDC client registration. health_status: @@ -96,6 +104,7 @@ en: title: Health Report oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? + label_oauth_client_id: OAuth Client label_pending: Pending replace_oauth_application: Replace OpenProject OAuth application oauth_client_info_component: @@ -127,14 +136,14 @@ en: oauth: openproject_oauth: OpenProject OAuth sections: - general_information: Basic details + general_information: General information oauth_configuration: OAuth configuration url_caption: Please add the host address of your wiki platform including the https://. It should not be longer than 255 characters. - xwiki_instance: XWiki Instance + xwiki_instance: Wiki Provider xwiki: oauth: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth application. Copy the credentials below into your XWiki instance. - provider_oauth: XWiki OAuth + provider_oauth: Wiki OAuth provider_oauth_description: Allow OpenProject to access XWiki data using OAuth. A client ID and client secret have been pre-generated for you — copy them along with the redirect URI into your XWiki OIDC client registration. You can change the client ID and secret if needed. openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth From 0746125ab2b1f111c7ce188eb48012af65ea4627 Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Tue, 26 May 2026 16:26:18 +0200 Subject: [PATCH 09/14] Update oauth_application_info_component_spec.rb --- .../wikis/admin/oauth_application_info_component_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/wikis/spec/components/wikis/admin/oauth_application_info_component_spec.rb b/modules/wikis/spec/components/wikis/admin/oauth_application_info_component_spec.rb index f10b22afbe7d..4c9413d8ab1b 100644 --- a/modules/wikis/spec/components/wikis/admin/oauth_application_info_component_spec.rb +++ b/modules/wikis/spec/components/wikis/admin/oauth_application_info_component_spec.rb @@ -65,9 +65,11 @@ expect(page).to have_text(I18n.t(:label_completed)) end - it "renders the description" do + it "renders the oauth application id" do render_inline(described_class.new(wiki_provider)) - expect(page).to have_text(I18n.t("wikis.admin.wiki_providers.xwiki.oauth.openproject_oauth_description")) + expect(page).to have_text( + "#{I18n.t('wikis.admin.oauth_application_info_component.label_oauth_client_id')}: #{oauth_application.uid}" + ) end it "renders a sync button with a confirm dialog" do From 8bd54b731a86e950874b3d2eb51d3a2f43d8617e Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Wed, 27 May 2026 09:46:28 +0200 Subject: [PATCH 10/14] Update modules/wikis/app/models/wikis/xwiki_provider.rb Co-authored-by: Jan Sandbrink --- modules/wikis/app/models/wikis/xwiki_provider.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/wikis/app/models/wikis/xwiki_provider.rb b/modules/wikis/app/models/wikis/xwiki_provider.rb index 6151824237c4..5937021f5076 100644 --- a/modules/wikis/app/models/wikis/xwiki_provider.rb +++ b/modules/wikis/app/models/wikis/xwiki_provider.rb @@ -45,7 +45,7 @@ class XWikiProvider < Provider class << self def registry_prefix = "xwiki" - def generate_client_id = SecureRandom.uuid + def generate_client_id = "openproject-#{SecureRandom.hex(8)}" def generate_client_secret = SecureRandom.hex(32) end From 8509eb896f349ef6ad768c94965a25ca1d9f3fe4 Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Wed, 27 May 2026 09:46:54 +0200 Subject: [PATCH 11/14] Update modules/wikis/config/locales/en.yml Co-authored-by: Jan Sandbrink --- modules/wikis/config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/wikis/config/locales/en.yml b/modules/wikis/config/locales/en.yml index a2a9a8c4829f..aff1d079e806 100644 --- a/modules/wikis/config/locales/en.yml +++ b/modules/wikis/config/locales/en.yml @@ -109,7 +109,7 @@ en: title: Health Report oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? - label_oauth_client_id: OAuth Client + label_oauth_client_id: OAuth Client ID label_pending: Pending replace_oauth_application: Replace OpenProject OAuth application oauth_client_info_component: From 90e236ca2a20a7953c0709e7a9423f1a2926360c Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Wed, 27 May 2026 15:04:44 +0200 Subject: [PATCH 12/14] Rename translation key for wikis from `instance` to `provider` --- .../wikis/admin/forms/general_info_form_component.html.erb | 4 ++-- .../components/wikis/admin/general_info_component.html.erb | 2 +- .../wikis/app/views/wikis/admin/wiki_providers/new.html.erb | 6 +++--- modules/wikis/config/locales/en.yml | 5 ++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb b/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb index 7f74304d01a1..fc0cf9c1157f 100644 --- a/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb @@ -2,12 +2,12 @@ component_wrapper do flex_layout(mb: 3) do |general_info_row| general_info_row.with_row do - render(Primer::Beta::Text.new(font_weight: :bold)) { t("wikis.admin.wiki_providers.xwiki_instance") } + render(Primer::Beta::Text.new(font_weight: :bold)) { Wikis::Provider.model_name.human } end general_info_row.with_row do render(Primer::Beta::Text.new(color: :subtle, test_selector: "wiki-provider-configuration-instructions")) do - t(".xwiki_instance_description") + t(".provider_description") end end diff --git a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb index 065bca5f49bc..8d65586ef29c 100644 --- a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb @@ -2,7 +2,7 @@ component_wrapper do grid_layout("op-storage-view--row", tag: :div, align_items: :center) do |grid| grid.with_area(:item, tag: :div, mr: 3) do - concat(render(Primer::Beta::Text.new(font_weight: :bold, mr: 1)) { t("wikis.admin.wiki_providers.xwiki_instance") }) + concat(render(Primer::Beta::Text.new(font_weight: :bold, mr: 1)) { Wikis::Provider.model_name.human }) concat(render(Primer::Beta::Label.new(scheme: :success, test_selector: "wiki-provider-general-info-status")) { t(:label_completed) }) end diff --git a/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb b/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb index 10ae6e7a8d29..9128d2f50de7 100644 --- a/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb +++ b/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb @@ -27,17 +27,17 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<% html_title t(:label_administration), t(:project_module_wiki_platforms), t("wikis.admin.wiki_providers.label_new_xwiki_instance") %> +<% html_title t(:label_administration), t(:project_module_wiki_platforms), t("wikis.admin.wiki_providers.label_new_provider") %> <%= render(Primer::OpenProject::PageHeader.new) do |header| %> <% header.with_title(test_selector: "wiki-provider-new-page-header--title") do %> - <%= t("wikis.admin.wiki_providers.label_new_xwiki_instance") %> + <%= t("wikis.admin.wiki_providers.label_new_provider") %> <% end %> <% header.with_breadcrumbs([ { href: admin_index_path, text: t(:label_administration) }, { href: admin_settings_wiki_providers_path, text: t(:project_module_wiki_platforms) }, - t("wikis.admin.wiki_providers.label_new_xwiki_instance") + t("wikis.admin.wiki_providers.label_new_provider") ]) %> <% header.with_description(test_selector: "wiki-provider-new-page-header--description") do %> diff --git a/modules/wikis/config/locales/en.yml b/modules/wikis/config/locales/en.yml index aff1d079e806..ecdd28f9b102 100644 --- a/modules/wikis/config/locales/en.yml +++ b/modules/wikis/config/locales/en.yml @@ -88,7 +88,7 @@ en: inline wiki page link will no longer be accessible. This action is irreversible. forms: general_info_form_component: - xwiki_instance_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. + provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. oauth_application_form_component: application_id: OpenProject OAuth Application ID application_secret: OpenProject OAuth Application secret @@ -133,7 +133,7 @@ en: index_description: Add an external wiki service to link work packages to existing wiki pages or create new ones directly from OpenProject. label_add_new: Add new wiki provider label_edit: Edit XWiki provider - label_new_xwiki_instance: New XWiki provider + label_new_provider: New XWiki provider label_wiki_platform: Wiki provider name_caption: Give your storage a name so that users can differentiate between multiple wiki platforms. name_placeholder: XWiki knowledge base @@ -144,7 +144,6 @@ en: general_information: General information oauth_configuration: OAuth configuration url_caption: Please add the host address of your wiki platform including the https://. It should not be longer than 255 characters. - xwiki_instance: Wiki Provider xwiki: oauth: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth application. Copy the credentials below into your XWiki instance. From 871fa551357f6dea3f181469478434c7a625f91b Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Wed, 27 May 2026 15:15:16 +0200 Subject: [PATCH 13/14] Use instance to get the provider name instead of hardcode --- .../wikis/admin/forms/general_info_form_component.html.erb | 2 +- .../app/components/wikis/admin/general_info_component.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb b/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb index fc0cf9c1157f..15e003f43d19 100644 --- a/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb @@ -2,7 +2,7 @@ component_wrapper do flex_layout(mb: 3) do |general_info_row| general_info_row.with_row do - render(Primer::Beta::Text.new(font_weight: :bold)) { Wikis::Provider.model_name.human } + render(Primer::Beta::Text.new(font_weight: :bold)) { wiki_provider.class.model_name.human } end general_info_row.with_row do diff --git a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb index 8d65586ef29c..cc30023b8846 100644 --- a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb @@ -2,7 +2,7 @@ component_wrapper do grid_layout("op-storage-view--row", tag: :div, align_items: :center) do |grid| grid.with_area(:item, tag: :div, mr: 3) do - concat(render(Primer::Beta::Text.new(font_weight: :bold, mr: 1)) { Wikis::Provider.model_name.human }) + concat(render(Primer::Beta::Text.new(font_weight: :bold, mr: 1)) { wiki_provider.class.model_name.human }) concat(render(Primer::Beta::Label.new(scheme: :success, test_selector: "wiki-provider-general-info-status")) { t(:label_completed) }) end From 21842f3dddd15391eaeabd0a5ea99a2105074c02 Mon Sep 17 00:00:00 2001 From: Yauheni Suhakou Date: Wed, 27 May 2026 15:38:36 +0200 Subject: [PATCH 14/14] Move back singular translations --- .../wikis/admin/forms/general_info_form_component.html.erb | 2 +- .../app/components/wikis/admin/general_info_component.html.erb | 2 +- .../wikis/admin/wiki_provider_list_component.html.erb | 2 +- .../wikis/app/views/wikis/admin/wiki_providers/index.html.erb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb b/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb index 15e003f43d19..3bb7990e3274 100644 --- a/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/forms/general_info_form_component.html.erb @@ -2,7 +2,7 @@ component_wrapper do flex_layout(mb: 3) do |general_info_row| general_info_row.with_row do - render(Primer::Beta::Text.new(font_weight: :bold)) { wiki_provider.class.model_name.human } + render(Primer::Beta::Text.new(font_weight: :bold)) { t("wikis.provider_types.#{wiki_provider}.name") } end general_info_row.with_row do diff --git a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb index cc30023b8846..fb6ff7086ba5 100644 --- a/modules/wikis/app/components/wikis/admin/general_info_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/general_info_component.html.erb @@ -2,7 +2,7 @@ component_wrapper do grid_layout("op-storage-view--row", tag: :div, align_items: :center) do |grid| grid.with_area(:item, tag: :div, mr: 3) do - concat(render(Primer::Beta::Text.new(font_weight: :bold, mr: 1)) { wiki_provider.class.model_name.human }) + concat(render(Primer::Beta::Text.new(font_weight: :bold, mr: 1)) { t("wikis.provider_types.#{wiki_provider}.name") }) concat(render(Primer::Beta::Label.new(scheme: :success, test_selector: "wiki-provider-general-info-status")) { t(:label_completed) }) end diff --git a/modules/wikis/app/components/wikis/admin/wiki_provider_list_component.html.erb b/modules/wikis/app/components/wikis/admin/wiki_provider_list_component.html.erb index 1c52774b0259..fa23c31dca97 100644 --- a/modules/wikis/app/components/wikis/admin/wiki_provider_list_component.html.erb +++ b/modules/wikis/app/components/wikis/admin/wiki_provider_list_component.html.erb @@ -29,7 +29,7 @@ end grid.with_area(:provider, tag: :div, color: :subtle, mr: 3, hide: :sm) do - render(Primer::Beta::Text.new(color: :subtle)) { wiki_provider.model_name.human } + render(Primer::Beta::Text.new(color: :subtle)) { t("wikis.provider_types.#{wiki_provider}.name") } end grid.with_area(:time, tag: :div, color: :subtle, hide: :sm) do diff --git a/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb b/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb index bfec99652b7b..fb08ec6d2e51 100644 --- a/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb +++ b/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb @@ -50,7 +50,7 @@ See COPYRIGHT and LICENSE files for more details. test_selector: "wiki-providers-create-new-button" } ) do |menu| menu.with_item( - label: I18n.t("activerecord.models.wikis/xwiki_provider"), + label: I18n.t("wikis.provider_types.xwiki.name"), href: new_admin_settings_wiki_provider_path ) end