diff options
Diffstat (limited to 'app')
21 files changed, 213 insertions, 23 deletions
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index cb70837f9e9..37b0215f6f9 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -561,3 +561,6 @@ export const getDateInPast = (date, daysInPast) => { dateClone.setTime(dateClone.getTime() - daysInPast * 24 * 60 * 60 * 1000), ).toISOString(); }; + +export const beginOfDayTime = 'T00:00:00Z'; +export const endOfDayTime = 'T23:59:59Z'; diff --git a/app/assets/javascripts/pages/registrations/new/index.js b/app/assets/javascripts/pages/registrations/new/index.js new file mode 100644 index 00000000000..a33d11f3613 --- /dev/null +++ b/app/assets/javascripts/pages/registrations/new/index.js @@ -0,0 +1,9 @@ +import LengthValidator from '~/pages/sessions/new/length_validator'; +import UsernameValidator from '~/pages/sessions/new/username_validator'; +import NoEmojiValidator from '~/emoji/no_emoji_validator'; + +document.addEventListener('DOMContentLoaded', () => { + new UsernameValidator(); // eslint-disable-line no-new + new LengthValidator(); // eslint-disable-line no-new + new NoEmojiValidator(); // eslint-disable-line no-new +}); diff --git a/app/assets/stylesheets/pages/experimental_separate_sign_up.scss b/app/assets/stylesheets/pages/experimental_separate_sign_up.scss new file mode 100644 index 00000000000..8b1ec1ced35 --- /dev/null +++ b/app/assets/stylesheets/pages/experimental_separate_sign_up.scss @@ -0,0 +1,51 @@ +.signup-page { + .page-wrap { + background-color: $gray-light; + } + + .gitlab-logo { + width: 80px; + height: 80px; + } + + .signup-box-container { + max-width: 900px; + + &.navless-container { + // overriding .devise-layout-html.navless-container to support the sticky footer + // without having a header on size xs + @include media-breakpoint-down(xs) { + padding: 65px $gl-padding; // height of footer + padding-top: $gl-padding; + } + } + } + + .signup-heading h2 { + font-weight: $gl-font-weight-bold; + + @include media-breakpoint-down(md) { + font-size: $gl-font-size-large; + } + } + + .signup-box { + background-color: $white-light; + box-shadow: 0 0 0 1px $border-color; + border-radius: $border-radius; + } + + .form-control { + &:active, + &:focus { + background-color: $white-light; + } + } + + .devise-errors { + h2 { + font-size: $gl-font-size; + color: $red-700; + } + } +} diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index d8aabecc036..7488a5b16a2 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -215,6 +215,12 @@ body { // offset height of fixed header + 1 to avoid scroll height: calc(100% - 51px); + + // offset without the header + &.navless { + height: calc(100% - 11px); + } + margin: 0; padding: 0; diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index 99840e40af1..d88ec06a18b 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -5,23 +5,21 @@ class HealthController < ActionController::Base include RequiresWhitelistedMonitoringClient def readiness - results = checks.flat_map(&:readiness) - success = results.all?(&:success) - - # disable static error pages at the gitlab-workhorse level, we want to see this error response even in production - headers["X-GitLab-Custom-Error"] = 1 unless success - - response = results.map { |result| [result.name, result.payload] }.to_h - render json: response, status: success ? :ok : :service_unavailable + render_probe(::Gitlab::HealthChecks::Probes::Readiness) end def liveness - render json: { status: 'ok' }, status: :ok + render_probe(::Gitlab::HealthChecks::Probes::Liveness) end private - def checks - ::Gitlab::HealthChecks::CHECKS + def render_probe(probe_class) + result = probe_class.new.execute + + # disable static error pages at the gitlab-workhorse level, we want to see this error response even in production + headers["X-GitLab-Custom-Error"] = 1 unless result.success? + + render json: result.json, status: result.http_status end end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 2e4c6a801b0..3a2975e92d6 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -6,13 +6,19 @@ class RegistrationsController < Devise::RegistrationsController include RecaptchaExperimentHelper include InvisibleCaptcha + layout :choose_layout + prepend_before_action :check_captcha, only: :create before_action :whitelist_query_limiting, only: [:destroy] before_action :ensure_terms_accepted, if: -> { action_name == 'create' && Gitlab::CurrentSettings.current_application_settings.enforce_terms? } def new - redirect_to(new_user_session_path) + if helpers.use_experimental_separate_sign_up_flow? + @resource = build_resource + else + redirect_to new_user_session_path(anchor: 'register-pane') + end end def create @@ -144,6 +150,16 @@ class RegistrationsController < Devise::RegistrationsController def stored_location_or_dashboard(user) stored_location_for(user) || dashboard_projects_path end + + # Part of an experiment to build a new sign up flow. Will be resolved + # with https://gitlab.com/gitlab-org/growth/engineering/issues/64 + def choose_layout + if helpers.use_experimental_separate_sign_up_flow? + 'devise_experimental_separate_sign_up_flow' + else + 'devise' + end + end end RegistrationsController.prepend_if_ee('EE::RegistrationsController') diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index af98a611b8b..2a5a3b9eac6 100644 --- a/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb @@ -4,4 +4,8 @@ module SessionsHelper def unconfirmed_email? flash[:alert] == t(:unconfirmed, scope: [:devise, :failure]) end + + def use_experimental_separate_sign_up_flow? + ::Gitlab.dev_env_or_com? && Feature.enabled?(:experimental_separate_sign_up_flow) + end end diff --git a/app/models/concerns/group_api_compatibility.rb b/app/models/concerns/group_api_compatibility.rb new file mode 100644 index 00000000000..f02aa2035e5 --- /dev/null +++ b/app/models/concerns/group_api_compatibility.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Add methods used by the groups API +module GroupAPICompatibility + extend ActiveSupport::Concern + + def project_creation_level_str + ::Gitlab::Access.project_creation_string_options.key(project_creation_level) + end + + def project_creation_level_str=(value) + write_attribute(:project_creation_level, ::Gitlab::Access.project_creation_string_options.fetch(value)) + end + + def subgroup_creation_level_str + ::Gitlab::Access.subgroup_creation_string_options.key(subgroup_creation_level) + end + + def subgroup_creation_level_str=(value) + write_attribute(:subgroup_creation_level, ::Gitlab::Access.subgroup_creation_string_options.fetch(value)) + end +end diff --git a/app/models/group.rb b/app/models/group.rb index 1b62db04ab7..5df9d97dcb6 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -14,6 +14,7 @@ class Group < Namespace include TokenAuthenticatable include WithUploads include Gitlab::Utils::StrongMemoize + include GroupAPICompatibility ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10 diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 0e6059f8715..7c0220a705a 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -256,7 +256,7 @@ class Namespace < ApplicationRecord end def has_parent? - parent.present? + parent_id.present? || parent.present? end def root_ancestor diff --git a/app/models/project_services/data_fields.rb b/app/models/project_services/data_fields.rb index 46136556ade..cffb493d569 100644 --- a/app/models/project_services/data_fields.rb +++ b/app/models/project_services/data_fields.rb @@ -5,7 +5,7 @@ module DataFields class_methods do # Provide convenient accessor methods for data fields. - # TODO: Simplify as part of https://gitlab.com/gitlab-org/gitlab-foss/issues/63084 + # TODO: Simplify as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 def data_field(*args) args.each do |arg| self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb index 278677edcdf..9e1393196ff 100644 --- a/app/models/project_services/issue_tracker_service.rb +++ b/app/models/project_services/issue_tracker_service.rb @@ -4,7 +4,7 @@ class IssueTrackerService < Service validate :one_issue_tracker, if: :activated?, on: :manual_change # TODO: we can probably just delegate as part of - # https://gitlab.com/gitlab-org/gitlab-foss/issues/63084 + # https://gitlab.com/gitlab-org/gitlab/issues/29404 data_field :project_url, :issues_url, :new_issue_url default_value_for :category, 'issue_tracker' @@ -25,7 +25,7 @@ class IssueTrackerService < Service end end - # this will be removed as part of https://gitlab.com/gitlab-org/gitlab-foss/issues/63084 + # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 def title if title_attribute = read_attribute(:title) title_attribute @@ -36,7 +36,7 @@ class IssueTrackerService < Service end end - # this will be removed as part of https://gitlab.com/gitlab-org/gitlab-foss/issues/63084 + # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 def description if description_attribute = read_attribute(:description) description_attribute @@ -49,7 +49,7 @@ class IssueTrackerService < Service def handle_properties # this has been moved from initialize_properties and should be improved - # as part of https://gitlab.com/gitlab-org/gitlab-foss/issues/63084 + # as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 return unless properties @legacy_properties_data = properties.dup diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index cfdf55b5155..6ebec17e703 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -19,7 +19,7 @@ class JiraService < IssueTrackerService # for more information check: https://gitlab.com/gitlab-org/gitlab-foss/issues/49936. # TODO: we can probably just delegate as part of - # https://gitlab.com/gitlab-org/gitlab-foss/issues/63084 + # https://gitlab.com/gitlab-org/gitlab/issues/29404 data_field :username, :password, :url, :api_url, :jira_issue_transition_id before_update :reset_password diff --git a/app/views/admin/application_settings/_influx.html.haml b/app/views/admin/application_settings/_influx.html.haml index 98c7a9659c3..300b01c6777 100644 --- a/app/views/admin/application_settings/_influx.html.haml +++ b/app/views/admin/application_settings/_influx.html.haml @@ -7,7 +7,7 @@ in running SQL queries. These settings require a = link_to 'restart', help_page_path('administration/restart_gitlab') to take effect. - = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/introduction') + = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/index') .form-group .form-check = f.check_box :metrics_enabled, class: 'form-check-input' diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 42cfbbf84f2..dfdf7429dc5 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -1,4 +1,7 @@ - page_title "Sign up" -= render 'devise/shared/signup_box' +- if use_experimental_separate_sign_up_flow? + = render 'devise/shared/experimental_separate_sign_up_flow_box' +- else + = render 'devise/shared/signup_box' = render 'devise/shared/sign_in_link' diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 30ed7ed6b29..17e5da501f5 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -4,7 +4,8 @@ - if form_based_providers.any? = render 'devise/shared/tabs_ldap' - else - = render 'devise/shared/tabs_normal' + - unless use_experimental_separate_sign_up_flow? + = render 'devise/shared/tabs_normal' .tab-content - if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled? = render 'devise/shared/signin_box' diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml new file mode 100644 index 00000000000..f92c29da5e6 --- /dev/null +++ b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml @@ -0,0 +1,34 @@ +- max_name_length = 128 +- max_username_length = 255 +.signup-box.p-3.mb-2 + .signup-body + = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f| + .devise-errors.mt-0 + = render "devise/shared/error_messages", resource: resource + = invisible_captcha + .name.form-group + = f.label :name, _('Full name'), class: 'label-bold' + = f.text_field :name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_name_length, :max_length_message => s_("SignUp|Name is too long (maximum is %{max_length} characters).") % { max_length: max_name_length }, :qa_selector => 'new_user_name_field' }, required: true, title: _("This field is required.") + .username.form-group + = f.label :username, class: 'label-bold' + = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.") + %p.validation-error.gl-field-error-ignore.field-validation.mt-1.hide.cred= _('Username is already taken.') + %p.validation-success.gl-field-error-ignore.field-validation.mt-1.hide.cgreen= _('Username is available.') + %p.validation-pending.gl-field-error-ignore.field-validation.mt-1.hide= _('Checking username availability...') + .form-group + = f.label :email, class: 'label-bold' + = f.email_field :email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.") + .form-group.append-bottom-20#password-strength + = f.label :password, class: 'label-bold' + = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length } + %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length } + - if Gitlab::CurrentSettings.current_application_settings.enforce_terms? + .form-group + = check_box_tag :terms_opt_in, '1', false, required: true, data: { qa_selector: 'new_user_accept_terms_checkbox' } + = label_tag :terms_opt_in do + - terms_link = link_to s_("I accept the|Terms of Service and Privacy Policy"), terms_path, target: "_blank" + - accept_terms_label = _("I accept the %{terms_link}") % { terms_link: terms_link } + = accept_terms_label.html_safe + = render_if_exists 'devise/shared/email_opted_in', f: f + .submit-container.mt-3 + = f.submit _("Register"), class: "btn-register btn btn-block btn-success mb-0 p-2", data: { qa_selector: 'new_user_register_button' } diff --git a/app/views/devise/shared/_sign_in_link.html.haml b/app/views/devise/shared/_sign_in_link.html.haml index 77ef103cc47..9a7d8a0a160 100644 --- a/app/views/devise/shared/_sign_in_link.html.haml +++ b/app/views/devise/shared/_sign_in_link.html.haml @@ -1,4 +1,4 @@ -%p +%p.text-center %span.light Already have login and password? = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes') diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml index f8f36a8bfff..deaceccbfc7 100644 --- a/app/views/devise/shared/_signin_box.html.haml +++ b/app/views/devise/shared/_signin_box.html.haml @@ -22,3 +22,8 @@ .login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' } .login-body = render 'devise/sessions/new_base' + +- if use_experimental_separate_sign_up_flow? + %p.light.mt-2 + = _("Don't have an account yet?") + = link_to _("Register now"), new_registration_path(:user) diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 68abfd3f61f..1efd8647a67 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -1,5 +1,17 @@ - page_description brand_title unless page_description +-# Needs a redirect on the client side since it's using an anchor to distuingish +-# between sign in and registration. We need to inline the JS to not render +-# anything from this page beforehand. +-# Part of an experiment to build a new sign up flow. Will be removed again with +-# https://gitlab.com/gitlab-org/growth/engineering/issues/64 +- if use_experimental_separate_sign_up_flow? && current_path?("sessions#new") + = javascript_tag nonce: true do + :plain + if (window.location.hash === '#register-pane') { + window.location.replace("/users/sign_up") + } + - site_name = "GitLab" %head{ prefix: "og: http://ogp.me/ns#" } %meta{ charset: "utf-8" } diff --git a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml new file mode 100644 index 00000000000..b10145b62af --- /dev/null +++ b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml @@ -0,0 +1,25 @@ +!!! 5 +%html.devise-layout-html.navless{ class: system_message_class } + = render "layouts/head" + %body.ui-indigo.signup-page.application.navless{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } } + = header_message + = render "layouts/init_client_detection_flags" + .page-wrap + .container.signup-box-container.navless-container.mt-0 + = render "layouts/broadcast" + .content + = render "layouts/flash" + .row.mb-3 + .col-sm-8.offset-sm-2.col-md-6.offset-md-3.new-session-forms-container + = render_if_exists 'layouts/devise_help_text' + .text-center.signup-heading.mt-3.mb-3 + = image_tag(image_url('logo.svg'), class: 'gitlab-logo', alt: 'GitLab Logo') + %h2= _('Register for GitLab.com') + = yield + %hr.footer-fixed + .footer-container + .container + .footer-links + = link_to _("Help"), help_path + = link_to _("About GitLab"), "https://about.gitlab.com/" + = footer_message |