Block emojis from user name

- Use JS regex for emoji validation
- Add test for blocking emojis in full name
- Fix existing tests for user status that failed locally
This commit is contained in:
Martin Wortschack 2019-02-01 17:24:11 +01:00
parent c243b154ab
commit 845c8d0b5c
7 changed files with 73 additions and 22 deletions

View File

@ -1,6 +1,7 @@
import $ from 'jquery';
import createFlash from '~/flash';
import GfmAutoComplete from '~/gfm_auto_complete';
import emojiRegex from 'emoji-regex';
import EmojiMenu from './emoji_menu';
const defaultStatusEmoji = 'speech_balloon';
@ -42,6 +43,17 @@ document.addEventListener('DOMContentLoaded', () => {
const emojiAutocomplete = new GfmAutoComplete();
emojiAutocomplete.setup($(statusMessageField), { emojis: true });
const userNameInput = document.getElementById('user_name');
userNameInput.addEventListener('input', () => {
const EMOJI_REGEX = emojiRegex();
if (EMOJI_REGEX.test(userNameInput.value)) {
// set field to invalid so it gets detected by GlFieldErrors
userNameInput.setCustomValidity('Invalid field');
} else {
userNameInput.setCustomValidity('');
}
});
import(/* webpackChunkName: 'emoji' */ '~/emoji')
.then(Emoji => {
const emojiMenu = new EmojiMenu(

View File

@ -2,7 +2,7 @@
- @content_class = "limit-container-width" unless fluid_layout
- gravatar_link = link_to Gitlab.config.gravatar.host, 'https://' + Gitlab.config.gravatar.host
= bootstrap_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user prepend-top-default js-quick-submit' }, authenticity_token: true do |f|
= bootstrap_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user prepend-top-default js-quick-submit gl-show-field-errors' }, authenticity_token: true do |f|
= form_errors(@user)
.row
@ -77,10 +77,10 @@
.col-lg-8
.row
- if @user.read_only_attribute?(:name)
= f.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9' },
= f.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name' },
help: s_("Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you") % { provider_label: attribute_provider_label(:name) }
- else
= f.text_field :name, label: 'Full name', required: true, wrapper: { class: 'col-md-9' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
= f.text_field :name, label: 'Full name', required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
= f.text_field :id, readonly: true, label: 'User ID', wrapper: { class: 'col-md-3' }
- if @user.read_only_attribute?(:email)

View File

@ -0,0 +1,5 @@
---
title: Block emojis and symbol characters from users full names
merge_request: 24523
author:
type: other

View File

@ -5399,6 +5399,9 @@ msgstr ""
msgid "Profiles|Username successfully changed"
msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
msgid "Profiles|What's your status?"
msgstr ""

View File

@ -61,6 +61,7 @@
"document-register-element": "1.3.0",
"dropzone": "^4.2.0",
"echarts": "^4.2.0-rc.2",
"emoji-regex": "^7.0.3",
"emoji-unicode-version": "^0.2.1",
"exports-loader": "^0.7.0",
"file-loader": "^3.0.1",

View File

@ -10,6 +10,7 @@ describe 'User edit profile' do
def submit_settings
click_button 'Update profile settings'
wait_for_requests if respond_to?(:wait_for_requests)
end
it 'changes user profile' do
@ -35,6 +36,17 @@ describe 'User edit profile' do
expect(page).to have_content('Profile was successfully updated')
end
it 'shows an error if the full name contains an emoji', :js do
simulate_input('#user_name', 'Martin 😀')
submit_settings
page.within('.qa-full-name') do
expect(page).to have_css '.gl-field-error-outline'
expect(find('.gl-field-error')).not_to have_selector('.hidden')
expect(find('.gl-field-error')).to have_content('Using emojis in names seems fun, but please try to set a status message instead')
end
end
context 'user avatar' do
before do
attach_file(:user_avatar, Rails.root.join('spec', 'fixtures', 'banana_sample.gif'))
@ -61,6 +73,11 @@ describe 'User edit profile' do
end
context 'user status', :js do
def visit_user
visit user_path(user)
wait_for_requests
end
def select_emoji(emoji_name, is_modal = false)
emoji_menu_class = is_modal ? '.js-modal-status-emoji-menu' : '.js-status-emoji-menu'
toggle_button = find('.js-toggle-emoji-menu')
@ -71,18 +88,16 @@ describe 'User edit profile' do
context 'profile edit form' do
it 'shows the user status form' do
visit(profile_path)
expect(page).to have_content('Current status')
end
it 'adds emoji to user status' do
emoji = 'biohazard'
visit(profile_path)
select_emoji(emoji)
submit_settings
visit user_path(user)
visit_user
within('.cover-status') do
expect(page).to have_emoji(emoji)
end
@ -90,11 +105,11 @@ describe 'User edit profile' do
it 'adds message to user status' do
message = 'I have something to say'
visit(profile_path)
fill_in 'js-status-message-field', with: message
submit_settings
visit user_path(user)
visit_user
within('.cover-status') do
expect(page).to have_emoji('speech_balloon')
expect(page).to have_content message
@ -104,12 +119,12 @@ describe 'User edit profile' do
it 'adds message and emoji to user status' do
emoji = 'tanabata_tree'
message = 'Playing outside'
visit(profile_path)
select_emoji(emoji)
fill_in 'js-status-message-field', with: message
submit_settings
visit user_path(user)
visit_user
within('.cover-status') do
expect(page).to have_emoji(emoji)
expect(page).to have_content message
@ -119,7 +134,8 @@ describe 'User edit profile' do
it 'clears the user status' do
user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread')
visit user_path(user)
visit_user
within('.cover-status') do
expect(page).to have_emoji(user_status.emoji)
expect(page).to have_content user_status.message
@ -129,15 +145,13 @@ describe 'User edit profile' do
click_button 'js-clear-user-status-button'
submit_settings
wait_for_requests
visit_user
visit user_path(user)
expect(page).not_to have_selector '.cover-status'
end
it 'displays a default emoji if only message is entered' do
message = 'a status without emoji'
visit(profile_path)
fill_in 'js-status-message-field', with: message
within('.js-toggle-emoji-menu') do
@ -162,6 +176,7 @@ describe 'User edit profile' do
page.within "#set-user-status-modal" do
click_button 'Set status'
end
wait_for_requests
end
before do
@ -202,7 +217,8 @@ describe 'User edit profile' do
select_emoji(emoji, true)
set_user_status_in_modal
visit user_path(user)
visit_user
within('.cover-status') do
expect(page).to have_emoji(emoji)
end
@ -225,7 +241,8 @@ describe 'User edit profile' do
find('.js-status-message-field').native.send_keys(message)
set_user_status_in_modal
visit user_path(user)
visit_user
within('.cover-status') do
expect(page).to have_emoji('speech_balloon')
expect(page).to have_content message
@ -240,7 +257,8 @@ describe 'User edit profile' do
find('.js-status-message-field').native.send_keys(message)
set_user_status_in_modal
visit user_path(user)
visit_user
within('.cover-status') do
expect(page).to have_emoji(emoji)
expect(page).to have_content message
@ -250,7 +268,9 @@ describe 'User edit profile' do
it 'clears the user status with the "X" button' do
user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread')
visit user_path(user)
visit_user
wait_for_requests
within('.cover-status') do
expect(page).to have_emoji(user_status.emoji)
expect(page).to have_content user_status.message
@ -265,14 +285,18 @@ describe 'User edit profile' do
find('.js-clear-user-status-button').click
set_user_status_in_modal
visit user_path(user)
visit_user
wait_for_requests
expect(page).not_to have_selector '.cover-status'
end
it 'clears the user status with the "Remove status" button' do
user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread')
visit user_path(user)
visit_user
wait_for_requests
within('.cover-status') do
expect(page).to have_emoji(user_status.emoji)
expect(page).to have_content user_status.message
@ -288,7 +312,8 @@ describe 'User edit profile' do
click_button 'Remove status'
end
visit user_path(user)
visit_user
expect(page).not_to have_selector '.cover-status'
end

View File

@ -3395,6 +3395,11 @@ elliptic@^6.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.0"
emoji-regex@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
emoji-unicode-version@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/emoji-unicode-version/-/emoji-unicode-version-0.2.1.tgz#0ebf3666b5414097971d34994e299fce75cdbafc"