From 3499ebe9396b8c6c19c8a6ddff5f2541e5639373 Mon Sep 17 00:00:00 2001 From: Jessica Lawshe <5312836+lawshe@users.noreply.github.com> Date: Wed, 6 Dec 2023 07:55:52 -0600 Subject: [PATCH] Merge pull request #15992 from overleaf/ab-group-sso-test-flow-1 [web] Group SSO multi-step modal and test flow GitOrigin-RevId: 343a20ef494276e65b35d1ee070c28d94617ea61 --- services/web/app/src/models/SSOConfig.js | 2 +- .../web/frontend/extracted-translations.json | 24 +++- .../stylesheets/modules/group-settings.less | 135 +++++++++++++++++- services/web/locales/en.json | 39 +++-- .../sso/group-settings-sso.spec.tsx | 76 ++++++++-- .../src/Subscription/GroupSSOHandlerTests.js | 1 - services/web/types/subscription/sso.ts | 2 +- 7 files changed, 238 insertions(+), 41 deletions(-) diff --git a/services/web/app/src/models/SSOConfig.js b/services/web/app/src/models/SSOConfig.js index 53ef70fb6f..5d50d51d02 100644 --- a/services/web/app/src/models/SSOConfig.js +++ b/services/web/app/src/models/SSOConfig.js @@ -5,10 +5,10 @@ const SSOConfigSchema = new Schema( { entryPoint: { type: String, required: true }, certificates: { type: Array, default: [''], required: true }, - signatureAlgorithm: { type: String, required: true }, userIdAttribute: { type: String, required: true }, userFirstNameAttribute: { type: String }, userLastNameAttribute: { type: String }, + validated: { type: Boolean, default: false }, enabled: { type: Boolean, default: false }, }, diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 44649d2ed6..2e1156fa39 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -128,7 +128,6 @@ "category_operators": "", "category_relations": "", "center": "", - "certificate": "", "change": "", "change_currency": "", "change_or_cancel-cancel": "", @@ -286,6 +285,7 @@ "download": "", "download_pdf": "", "download_zip_file": "", + "draft_sso_configuration": "", "drag_here": "", "drag_here_paste_an_image_or": "", "dropbox_checking_sync_status": "", @@ -310,7 +310,6 @@ "each_user_will_have_access_to": "", "easily_manage_your_project_files_everywhere": "", "edit": "", - "edit_configuration": "", "edit_dictionary": "", "edit_dictionary_empty": "", "edit_dictionary_remove": "", @@ -469,6 +468,7 @@ "group_managed_by_group_administrator": "", "group_plan_tooltip": "", "group_plan_with_name_tooltip": "", + "group_sso_configuration_idp_metadata": "", "group_subscription": "", "have_an_extra_backup": "", "have_more_days_to_try": "", @@ -753,6 +753,7 @@ "new_to_latex_look_at": "", "newsletter": "", "newsletter_onboarding_accept": "", + "next": "", "next_payment_of_x_collectected_on_y": "", "no_actions": "", "no_borders": "", @@ -882,6 +883,7 @@ "primarily_work_study_question_nonprofit_ngo": "", "primarily_work_study_question_other": "", "primarily_work_study_question_university_school": "", + "primary_certificate": "", "priority_support": "", "private": "", "problem_talking_to_publishing_service": "", @@ -952,6 +954,7 @@ "recurly_email_update_needed": "", "recurly_email_updated": "", "redirect_to_editor": "", + "redirect_url": "", "reduce_costs_group_licenses": "", "reference_error_relink_hint": "", "reference_managers": "", @@ -1091,6 +1094,7 @@ "session_expired_redirecting_to_login": "", "sessions": "", "set_color": "", + "set_up_sso": "", "settings": "", "setup_another_account_under_a_personal_email_address": "", "share": "", @@ -1120,6 +1124,7 @@ "single_sign_on_sso": "", "skip": "", "something_not_right": "", + "something_went_wrong": "", "something_went_wrong_loading_pdf_viewer": "", "something_went_wrong_processing_the_request": "", "something_went_wrong_rendering_pdf": "", @@ -1136,12 +1141,12 @@ "sso_config_prop_help_certificate": "", "sso_config_prop_help_first_name": "", "sso_config_prop_help_last_name": "", + "sso_config_prop_help_redirect_url": "", "sso_config_prop_help_signature_algorithm": "", - "sso_config_prop_help_user_entry_point": "", "sso_config_prop_help_user_id": "", "sso_configuration": "", - "sso_configuration_created": "", - "sso_configuration_updated": "", + "sso_configuration_not_finalized": "", + "sso_configuration_saved": "", "sso_explanation": "", "sso_is_disabled": "", "sso_is_disabled_explanation_1": "", @@ -1156,6 +1161,9 @@ "sso_link_your_group_uses_sso": "", "sso_logs": "", "sso_not_active": "", + "sso_test_interstitial_info_1": "", + "sso_test_interstitial_info_2": "", + "sso_test_interstitial_title": "", "start_a_free_trial": "", "start_by_adding_your_email": "", "start_free_trial": "", @@ -1215,7 +1223,9 @@ "template_title_taken_from_project_title": "", "templates": "", "terminated": "", + "test": "", "test_configuration": "", + "test_configuration_successful": "", "tex_live_version": "", "thank_you_exclamation": "", "thanks_for_subscribing": "", @@ -1387,6 +1397,7 @@ "user_id_attribute": "", "user_last_name_attribute": "", "user_sessions": "", + "valid_sso_configuration": "", "validation_issue_entry_description": "", "vat": "", "vat_number": "", @@ -1399,10 +1410,12 @@ "view_hub_subtext": "", "view_in_template_gallery": "", "view_invitation": "", + "view_less": "", "view_logs": "", "view_metrics": "", "view_metrics_commons_subtext": "", "view_metrics_group_subtext": "", + "view_more": "", "view_pdf": "", "view_your_invoices": "", "viewing_x": "", @@ -1449,6 +1462,7 @@ "you_are_on_a_paid_plan_contact_support_to_find_out_more": "", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "", "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "", + "you_can_now_enable_sso": "", "you_can_now_log_in_sso": "", "you_dont_have_any_repositories": "", "you_have_added_x_of_group_size_y": "", diff --git a/services/web/frontend/stylesheets/modules/group-settings.less b/services/web/frontend/stylesheets/modules/group-settings.less index 894b4b5c11..41a6089f33 100644 --- a/services/web/frontend/stylesheets/modules/group-settings.less +++ b/services/web/frontend/stylesheets/modules/group-settings.less @@ -110,8 +110,39 @@ h3.group-settings-title { } .sso-config-info { + padding: 12px 0; + + .sso-config-info-header { + display: flex; + justify-content: space-between; + gap: @margin-xs; + padding: 0 @padding-base-horizontal 15px @padding-base-horizontal; + border-bottom: 1px solid @neutral-20; + margin-bottom: 15px; + flex-wrap: wrap; + + .status-label { + font-size: @font-size-small; + border-radius: 4px; + padding: 2px 4px; + margin-top: 4px; + flex-shrink: 0; + + &.status-label-valid { + background-color: @ol-green; + color: @neutral-10; + } + + &.status-label-draft { + background-color: @neutral-20; + color: @neutral-90; + } + } + } + .sso-config-info-section { margin-bottom: @margin-md; + padding: 0 @padding-base-horizontal; } .sso-config-info-label { @@ -124,13 +155,105 @@ h3.group-settings-title { word-break: break-word; } - .sso-config-info-footer { - display: flex; - justify-content: flex-end; - gap: @margin-xs; - } - p { margin-bottom: @margin-xs; } } + +.sso-config-modal-content { + .sso-config-interstitial-title, + .sso-config-test-result-title { + font-family: Lato, sans-serif; + font-size: 20px; + font-weight: bold; + text-align: center; + } + + .sso-config-modal-icon-wrapper { + text-align: center; + margin-top: 8px; + + .sso-config-interstitial-icon, + .sso-config-test-result-icon, + .sso-config-test-error-icon { + font-size: 32px; + width: 80px; + height: 80px; + padding: 24px; + border-radius: 999px; + gap: 8px; + } + + .sso-config-interstitial-icon { + background-color: @neutral-10; + } + + .sso-config-test-result-icon { + background-color: @green-10; + color: @ol-green; + } + + .sso-config-test-error-icon { + background-color: @red-10; + color: @red-50; + } + } + + .sso-config-test-result-title { + font-family: Lato, sans-serif; + font-size: 20px; + font-weight: bold; + text-align: center; + } + + .has-feedback { + .form-control { + padding-right: 0; + } + } +} + +.certificate-wrapper { + display: flex; + &.certificate-full { + flex-wrap: wrap; + } + + .view-more { + flex-grow: 1; + flex-shrink: 0; + } +} + +.certificate { + font-family: Courier, monospace; + + .certificate-truncated & { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: inline-block; + flex-grow: 4; + } + .certificate-full & { + word-break: break-all; + + .break { + flex-basis: 100%; + height: 0; + } + } +} + +.certificate-form-row { + display: flex; + + .certificate-input { + flex-grow: 11; + } + + .certificate-delete { + flex-grow: 1; + flex-shrink: 0; + } +} diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 29b6cf40c4..403984eaf9 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -51,7 +51,7 @@ "activating": "Activating", "activation_token_expired": "Your activation token has expired, you will need to get another one sent to you.", "add": "Add", - "add_additional_certificate": "Add additional certificate", + "add_additional_certificate": "Add another certificate", "add_affiliation": "Add Affiliation", "add_another_address_line": "Add another address line", "add_another_email": "Add another email", @@ -425,6 +425,7 @@ "download": "Download", "download_pdf": "Download PDF", "download_zip_file": "Download .zip file", + "draft_sso_configuration": "Draft SSO configuration", "drag_here": "drag here", "drag_here_paste_an_image_or": "Drag here, paste an image, or ", "drop_files_here_to_upload": "Drop files here to upload", @@ -459,7 +460,6 @@ "ease_of_use": " Ease of Use", "easily_manage_your_project_files_everywhere": "Easily manage your project files, everywhere", "edit": "Edit", - "edit_configuration": "Edit configuration", "edit_dictionary": "Edit Dictionary", "edit_dictionary_empty": "Your custom dictionary is empty.", "edit_dictionary_remove": "Remove from dictionary", @@ -730,6 +730,7 @@ "group_plan_with_name_tooltip": "You are on the __plan__ plan as a member of a group subscription, __groupName__. Click to find out how to make the most of your Overleaf premium features.", "group_plans": "Group Plans", "group_professional": "Group Professional", + "group_sso_configuration_idp_metadata": "The information provided here comes from your Identity Provider (IdP). This is often referred to as its SAML metadata. For some IdPs, you must configure Overleaf as a Service Provider in order to obtain the data required to fill out this form. Please see <0>our documentation0> for more guidance.", "group_standard": "Group Standard", "group_subscription": "Group Subscription", "groups": "Groups", @@ -1145,6 +1146,7 @@ "newsletter_info_title": "Newsletter Preferences", "newsletter_info_unsubscribed": "You are currently <0>unsubscribed0> to the __appName__ newsletter.", "newsletter_onboarding_accept": "Yes, I’d like to get relevant help resources, news, and feature updates.", + "next": "Next", "next_payment_of_x_collectected_on_y": "The next payment of <0>__paymentAmmount__0> will be collected on <1>__collectionDate__1>.", "nl": "Dutch", "no": "Norwegian", @@ -1347,6 +1349,7 @@ "primarily_work_study_question_nonprofit_ngo": "Nonprofit or NGO", "primarily_work_study_question_other": "Other", "primarily_work_study_question_university_school": "University or school", + "primary_certificate": "Primary certificate", "primary_email_check_question": "Is <0>__email__0> still your email address?", "priority_support": "Priority support", "priority_support_info": "Our helpful Support team will prioritise and escalate your support requests where necessary.", @@ -1436,6 +1439,7 @@ "recurly_email_update_needed": "Your billing email address is currently <0>__recurlyEmail__0>. If needed you can update your billing address to <1>__userEmail__1>.", "recurly_email_updated": "Your billing email address was successfully updated", "redirect_to_editor": "Redirect to editor", + "redirect_url": "Redirect URL", "redirecting": "Redirecting", "reduce_costs_group_licenses": "You can cut down on paperwork and reduce costs with our discounted group licenses.", "refer_a_friend": "Refer a friend", @@ -1630,6 +1634,7 @@ "set_color": "set color", "set_new_password": "Set new password", "set_password": "Set Password", + "set_up_sso": "Set up SSO", "settings": "Settings", "setup_another_account_under_a_personal_email_address": "Set up another Overleaf account under a personal email address.", "share": "Share", @@ -1669,6 +1674,7 @@ "sl_gives_you_free_stuff_see_progress_below": "When someone starts using __appName__ after your recommendation we’ll give you some free stuff to say thanks! Check your progress below.", "sl_included_history_of_changes_blurb": "__appName__ includes a history of all of your changes so you can see exactly who changed what, and when. This makes it extremely easy to keep up to date with any progress made by your collaborators and allows you to review recent work.", "something_not_right": "Something’s not right", + "something_went_wrong": "Something went wrong", "something_went_wrong_canceling_your_subscription": "Something went wrong canceling your subscription. Please contact support.", "something_went_wrong_loading_pdf_viewer": "Something went wrong loading the PDF viewer. This might be caused by issues like <0>temporary network problems0> or an <0>outdated web browser0>. Please follow the <1>troubleshooting steps for access, loading and display problems1>. If the issue persists, please <2>let us know2>.", "something_went_wrong_processing_the_request": "Something went wrong processing the request", @@ -1689,14 +1695,14 @@ "sso_account_already_linked": "Account already linked to another __appName__ user", "sso_active": "SSO active", "sso_config_prop_help_certificate": "Base64 encoded certificate without whitespace", - "sso_config_prop_help_first_name": "Property in SAML assertion to use for first name", - "sso_config_prop_help_last_name": "Property in SAML assertion to use for last name", + "sso_config_prop_help_first_name": "The SAML attribute that specifies the user’s first name", + "sso_config_prop_help_last_name": "The SAML attribute that specifies the user’s last name", + "sso_config_prop_help_redirect_url": "The single sign-on redirect URL provided by your IdP (sometimes called the single sign-on service HTTP-redirect location)", "sso_config_prop_help_signature_algorithm": "Base64 encoded certificate without whitespace", - "sso_config_prop_help_user_entry_point": "URL for SAML SSO redirect flow", - "sso_config_prop_help_user_id": "Property in SAML assertion to use for unique id", + "sso_config_prop_help_user_id": "The SAML attribute provided by your IdP that identifies each user", "sso_configuration": "SSO configuration", - "sso_configuration_created": "SSO configuration has been saved", - "sso_configuration_updated": "SSO configuration was updated successfully", + "sso_configuration_not_finalized": "Your configuration has not been finalized.", + "sso_configuration_saved": "SSO configuration has been saved", "sso_explanation": "Set up single sign-on for your group. This sign in method will be optional for group members unless Managed Users is enabled. <0>Learn more about Overleaf Group SSO0>.", "sso_integration": "SSO integration", "sso_integration_info": "Overleaf offers a standard SAML-based Single Sign On integration.", @@ -1714,6 +1720,9 @@ "sso_logs": "SSO Logs", "sso_not_active": "SSO not active", "sso_not_linked": "You have not linked your account to __provider__. Please log in to your account another way and link your __provider__ account via your account settings.", + "sso_test_interstitial_info_1": "<0>Before starting this test0>, please ensure you’ve <1>configured Overleaf as a Service Provider in your IdP1>, and authorized access to the Overleaf service.", + "sso_test_interstitial_info_2": "Clicking <0>Test configuration0> will redirect you to your IdP’s login screen. <1>Read our documentation1> for full details of what happens during the test. And check our <2>SSO troubleshooting advice2> if you get stuck.", + "sso_test_interstitial_title": "Let’s test your SSO configuration", "sso_title": "Single sign-on", "sso_user_denied_access": "Cannot log in because __appName__ was not granted access to your __provider__ account. Please try again.", "standard": "Standard", @@ -1801,7 +1810,9 @@ "templates_page_title": "Templates - Journals, CVs, Presentations, Reports and More", "terminated": "Compilation cancelled", "terms": "Terms", + "test": "Test", "test_configuration": "Test configuration", + "test_configuration_successful": "Test configuration successful", "tex_live_version": "TeX Live version", "thank_you": "Thank you!", "thank_you_email_confirmed": "Thank you, your email is now confirmed", @@ -2016,15 +2027,16 @@ "user_already_added": "User already added", "user_deletion_error": "Sorry, something went wrong deleting your account. Please try again in a minute.", "user_deletion_password_reset_tip": "If you cannot remember your password, or if you are using Single-Sign-On with another provider to sign in (such as Twitter or Google), please <0>reset your password0> and try again.", - "user_first_name_attribute": "User First Name Attribute", - "user_id_attribute": "User ID Attribute", + "user_first_name_attribute": "User first name attribute", + "user_id_attribute": "Unique identifier", "user_is_not_part_of_group": "User is not part of group", - "user_last_name_attribute": "User Last Name Attribute", + "user_last_name_attribute": "User last name attribute", "user_management": "User management", "user_management_info": "Group plan admins have access to an admin panel where users can be added and removed easily. For site-wide plans, users are automatically upgraded when they register or add their email address to Overleaf (domain-based enrollment or SSO).", "user_not_found": "User not found", "user_sessions": "User Sessions", "user_wants_you_to_see_project": "__username__ would like you to join __projectname__", + "valid_sso_configuration": "Valid SSO configuration", "validation_issue_entry_description": "A validation issue which prevented this project from compiling", "vat": "VAT", "vat_number": "VAT Number", @@ -2038,10 +2050,12 @@ "view_hub_subtext": "Access and download subscription statistics and a list of users", "view_in_template_gallery": "View it in the template gallery", "view_invitation": "View Invitation", + "view_less": "View less", "view_logs": "View logs", "view_metrics": "View metrics", "view_metrics_commons_subtext": "Monitor and download usage metrics for your Commons subscription", "view_metrics_group_subtext": "Monitor and download usage metrics for your group subscription", + "view_more": "View more", "view_pdf": "View PDF", "view_source": "View Source", "view_templates": "View templates", @@ -2107,6 +2121,7 @@ "you_are_on_a_paid_plan_contact_support_to_find_out_more": "You’re on an __appName__ Paid plan. <0>Contact support0> to find out more.", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "You are on our <0>__planName__0> plan as a <1>confirmed member1> of <1>__institutionName__1>", "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are on our <0>__planName__0> plan as a <1>member1> of the group subscription <1>__groupName__1> administered by <1>__adminEmail__1>", + "you_can_now_enable_sso": "You can now enable SSO on your Group settings page.", "you_can_now_log_in_sso": "You can now log in through your institution and if eligible you will receive <0>__appName__ Professional features0>.", "you_can_opt_in_and_out_of_overleaf_labs_at_any_time_on_this_page": "You can <0>opt in and out0> of Overleaf Labs at any time on this page", "you_can_opt_in_and_out_of_the_program_at_any_time_on_this_page": "You can <0>opt in and out0> of the program at any time on this page", @@ -2122,7 +2137,7 @@ "you_introed_high_number": " You’ve introduced <0>__numberOfPeople__0> people to __appName__. Good job!", "you_introed_small_number": " You’ve introduced <0>__numberOfPeople__0> person to __appName__. Good job, but can you get some more?", "you_may_be_able_to_fix_issues_to_speed_up_the_compile": "You may be able to fix issues to <0>speed up the compile0>.", - "you_need_to_configure_your_sso_settings": "You need to configure your SSO settings before enabling SSO", + "you_need_to_configure_your_sso_settings": "You need to configure and test your SSO settings before enabling SSO", "you_not_introed_anyone_to_sl": "You’ve not introduced anyone to __appName__ yet. Get sharing!", "you_plus_1": "You + 1", "you_plus_10": "You + 10", diff --git a/services/web/test/frontend/features/group-management/components/sso/group-settings-sso.spec.tsx b/services/web/test/frontend/features/group-management/components/sso/group-settings-sso.spec.tsx index f37a70dbb2..ee21799c46 100644 --- a/services/web/test/frontend/features/group-management/components/sso/group-settings-sso.spec.tsx +++ b/services/web/test/frontend/features/group-management/components/sso/group-settings-sso.spec.tsx @@ -1,9 +1,12 @@ import GroupSettingsSSORoot from '../../../../../../modules/group-settings/frontend/js/components/sso/group-settings-sso-root' +import { SSOConfigurationProvider } from '../../../../../../modules/group-settings/frontend/js/context/sso-configuration-context' function GroupSettingsSSOComponent() { return (