...@@ -752,7 +752,9 @@ production: &base ...@@ -752,7 +752,9 @@ production: &base
# Path to a file containing a CA certificate # Path to a file containing a CA certificate
ca_file: '/etc/ssl/certs/CA.pem' ca_file: '/etc/ssl/certs/CA.pem'
# Port where the client side certificate is requested by the webserver (NGINX/Apache) # Host and port where the client side certificate is requested by the
# webserver (NGINX/Apache)
# client_certificate_required_host: smartcard.gitlab.example.com
# client_certificate_required_port: 3444 # client_certificate_required_port: 3444
# Browser session with smartcard sign-in is required for Git access # Browser session with smartcard sign-in is required for Git access
... ...
......
...@@ -77,6 +77,7 @@ end ...@@ -77,6 +77,7 @@ end
Gitlab.ee do Gitlab.ee do
Settings['smartcard'] ||= Settingslogic.new({}) Settings['smartcard'] ||= Settingslogic.new({})
Settings.smartcard['enabled'] = false if Settings.smartcard['enabled'].nil? Settings.smartcard['enabled'] = false if Settings.smartcard['enabled'].nil?
Settings.smartcard['client_certificate_required_host'] = Settings.gitlab['host'] if Settings.smartcard['client_certificate_required_host'].nil?
Settings.smartcard['client_certificate_required_port'] = 3444 if Settings.smartcard['client_certificate_required_port'].nil? Settings.smartcard['client_certificate_required_port'] = 3444 if Settings.smartcard['client_certificate_required_port'].nil?
Settings.smartcard['required_for_git_access'] = false if Settings.smartcard['required_for_git_access'].nil? Settings.smartcard['required_for_git_access'] = false if Settings.smartcard['required_for_git_access'].nil?
Settings.smartcard['san_extensions'] = false if Settings.smartcard['san_extensions'].nil? Settings.smartcard['san_extensions'] = false if Settings.smartcard['san_extensions'].nil?
... ...
......
...@@ -2,36 +2,41 @@ ...@@ -2,36 +2,41 @@
cd "$(dirname "$0")/.." cd "$(dirname "$0")/.."
echo "=> Linting documents at path $(pwd) as $(whoami)..." echo "=> Linting documents at path $(pwd) as $(whoami)..."
echo
ERRORCODE=0
# Use long options (e.g. --header instead of -H) for curl examples in documentation. # Use long options (e.g. --header instead of -H) for curl examples in documentation.
echo '=> Checking for cURL short options...' echo '=> Checking for cURL short options...'
echo
grep --extended-regexp --recursive --color=auto 'curl (.+ )?-[^- ].*' doc/ >/dev/null 2>&1 grep --extended-regexp --recursive --color=auto 'curl (.+ )?-[^- ].*' doc/ >/dev/null 2>&1
if [ $? -eq 0 ] if [ $? -eq 0 ]
then then
echo '✖ ERROR: Short options for curl should not be used in documentation! echo '✖ ERROR: Short options for curl should not be used in documentation!
Use long options (e.g., --header instead of -H):' >&2 Use long options (e.g., --header instead of -H):' >&2
grep --extended-regexp --recursive --color=auto 'curl (.+ )?-[^- ].*' doc/ grep --extended-regexp --recursive --color=auto 'curl (.+ )?-[^- ].*' doc/
exit 1 ((ERRORCODE++))
fi fi
# Ensure that the CHANGELOG.md does not contain duplicate versions # Ensure that the CHANGELOG.md does not contain duplicate versions
DUPLICATE_CHANGELOG_VERSIONS=$(grep --extended-regexp '^## .+' CHANGELOG.md | sed -E 's| \(.+\)||' | sort -r | uniq -d) DUPLICATE_CHANGELOG_VERSIONS=$(grep --extended-regexp '^## .+' CHANGELOG.md | sed -E 's| \(.+\)||' | sort -r | uniq -d)
echo '=> Checking for CHANGELOG.md duplicate entries...' echo '=> Checking for CHANGELOG.md duplicate entries...'
echo
if [ "${DUPLICATE_CHANGELOG_VERSIONS}" != "" ] if [ "${DUPLICATE_CHANGELOG_VERSIONS}" != "" ]
then then
echo '✖ ERROR: Duplicate versions in CHANGELOG.md:' >&2 echo '✖ ERROR: Duplicate versions in CHANGELOG.md:' >&2
echo "${DUPLICATE_CHANGELOG_VERSIONS}" >&2 echo "${DUPLICATE_CHANGELOG_VERSIONS}" >&2
exit 1 ((ERRORCODE++))
fi fi
# Make sure no files in doc/ are executable # Make sure no files in doc/ are executable
EXEC_PERM_COUNT=$(find doc/ -type f -perm 755 | wc -l) EXEC_PERM_COUNT=$(find doc/ -type f -perm 755 | wc -l)
echo "=> Checking $(pwd)/doc for executable permissions..." echo "=> Checking $(pwd)/doc for executable permissions..."
echo
if [ "${EXEC_PERM_COUNT}" -ne 0 ] if [ "${EXEC_PERM_COUNT}" -ne 0 ]
then then
echo '✖ ERROR: Executable permissions should not be used in documentation! Use `chmod 644` to the files in question:' >&2 echo '✖ ERROR: Executable permissions should not be used in documentation! Use `chmod 644` to the files in question:' >&2
find doc/ -type f -perm 755 find doc/ -type f -perm 755
exit 1 ((ERRORCODE++))
fi fi
# Do not use 'README.md', instead use 'index.md' # Do not use 'README.md', instead use 'index.md'
...@@ -39,13 +44,14 @@ fi ...@@ -39,13 +44,14 @@ fi
NUMBER_READMES=46 NUMBER_READMES=46
FIND_READMES=$(find doc/ -name "README.md" | wc -l) FIND_READMES=$(find doc/ -name "README.md" | wc -l)
echo '=> Checking for new README.md files...' echo '=> Checking for new README.md files...'
echo
if [ ${FIND_READMES} -ne $NUMBER_READMES ] if [ ${FIND_READMES} -ne $NUMBER_READMES ]
then then
echo echo
echo ' ✖ ERROR: New README.md file(s) detected, prefer index.md over README.md.' >&2 echo ' ✖ ERROR: New README.md file(s) detected, prefer index.md over README.md.' >&2
echo ' https://docs.gitlab.com/ee/development/documentation/styleguide.html#work-with-directories-and-files' echo ' https://docs.gitlab.com/ee/development/documentation/styleguide.html#work-with-directories-and-files'
echo echo
exit 1 ((ERRORCODE++))
fi fi
MD_DOC_PATH=${MD_DOC_PATH:-doc} MD_DOC_PATH=${MD_DOC_PATH:-doc}
...@@ -64,7 +70,7 @@ function run_locally_or_in_docker() { ...@@ -64,7 +70,7 @@ function run_locally_or_in_docker() {
echo echo
echo " ✖ ERROR: '${cmd}' not found. Install '${cmd}' or Docker to proceed." >&2 echo " ✖ ERROR: '${cmd}' not found. Install '${cmd}' or Docker to proceed." >&2
echo echo
exit 1 ((ERRORCODE++))
fi fi
if [ $? -ne 0 ] if [ $? -ne 0 ]
...@@ -72,15 +78,22 @@ function run_locally_or_in_docker() { ...@@ -72,15 +78,22 @@ function run_locally_or_in_docker() {
echo echo
echo " ✖ ERROR: '${cmd}' failed with errors." >&2 echo " ✖ ERROR: '${cmd}' failed with errors." >&2
echo echo
exit 1 ((ERRORCODE++))
fi fi
} }
echo '=> Linting markdown style...' echo '=> Linting markdown style...'
echo
run_locally_or_in_docker 'markdownlint' "--config .markdownlint.json ${MD_DOC_PATH}" run_locally_or_in_docker 'markdownlint' "--config .markdownlint.json ${MD_DOC_PATH}"
echo '=> Linting prose...' echo '=> Linting prose...'
run_locally_or_in_docker 'vale' "--minAlertLevel error ${MD_DOC_PATH}" run_locally_or_in_docker 'vale' "--minAlertLevel error ${MD_DOC_PATH}"
if [ $ERRORCODE -ne 0 ]
then
echo "✖ ${ERRORCODE} lint test(s) failed. Review the log carefully to see full listing."
exit 1
else
echo "✔ Linting passed" echo "✔ Linting passed"
exit 0 exit 0
fi
...@@ -28,9 +28,9 @@ HOOK_DATA = <<~HOOK ...@@ -28,9 +28,9 @@ HOOK_DATA = <<~HOOK
if [ -e "$harness" ] if [ -e "$harness" ]
then then
if [[ ("$url" != *"dev.gitlab.org"*) && ("$url" != *"gitlab-org/security/"*) ]] if [["$url" != *"gitlab-org/security/"*]]
then then
echo "Pushing to remotes other than dev.gitlab.org and gitlab.com/gitlab-org/security has been disabled!" echo "Pushing to remotes other than gitlab.com/gitlab-org/security has been disabled!"
echo "Run scripts/security-harness to disable this check." echo "Run scripts/security-harness to disable this check."
echo echo
...@@ -58,7 +58,7 @@ def toggle ...@@ -58,7 +58,7 @@ def toggle
else else
FileUtils.touch(harness_path) FileUtils.touch(harness_path)
puts "#{SHELL_GREEN}Security harness installed -- you will only be able to push to dev.gitlab.org or gitlab.com/gitlab-org/security!#{SHELL_CLEAR}" puts "#{SHELL_GREEN}Security harness installed -- you will only be able to push to gitlab.com/gitlab-org/security!#{SHELL_CLEAR}"
end end
end end
... ...
......
# frozen_string_literal: true
require 'spec_helper'
describe 'IDE Clientside Preview CSP' do
let_it_be(:user) { create(:user) }
shared_context 'disable feature' do
before do
allow_next_instance_of(ApplicationSetting) do |instance|
allow(instance).to receive(:web_ide_clientside_preview_enabled?).and_return(false)
end
end
end
it_behaves_like 'setting CSP', 'frame-src' do
let(:whitelisted_url) { 'https://sandbox.gitlab-static.test' }
let(:extended_controller_class) { IdeController }
subject do
visit ide_path
response_headers['Content-Security-Policy']
end
before do
allow_next_instance_of(ApplicationSetting) do |instance|
allow(instance).to receive(:web_ide_clientside_preview_enabled?).and_return(true)
allow(instance).to receive(:web_ide_clientside_preview_bundler_url).and_return(whitelisted_url)
end
sign_in(user)
end
end
end
...@@ -11,7 +11,7 @@ describe 'Static Object External Storage Content Security Policy' do ...@@ -11,7 +11,7 @@ describe 'Static Object External Storage Content Security Policy' do
end end
end end
it_behaves_like 'setting CSP connect-src' do it_behaves_like 'setting CSP', 'connect-src' do
let_it_be(:whitelisted_url) { 'https://static-objects.test' } let_it_be(:whitelisted_url) { 'https://static-objects.test' }
let_it_be(:extended_controller_class) { IdeController } let_it_be(:extended_controller_class) { IdeController }
... ...
......
...@@ -12,7 +12,7 @@ describe 'Sourcegraph Content Security Policy' do ...@@ -12,7 +12,7 @@ describe 'Sourcegraph Content Security Policy' do
end end
end end
it_behaves_like 'setting CSP connect-src' do it_behaves_like 'setting CSP', 'connect-src' do
let_it_be(:whitelisted_url) { 'https://sourcegraph.test' } let_it_be(:whitelisted_url) { 'https://sourcegraph.test' }
let_it_be(:extended_controller_class) { Projects::BlobController } let_it_be(:extended_controller_class) { Projects::BlobController }
... ...
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Popover from '~/blob/suggest_gitlab_ci_yml/components/popover.vue'; import Popover from '~/blob/suggest_gitlab_ci_yml/components/popover.vue';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import * as utils from '~/lib/utils/common_utils'; import * as utils from '~/lib/utils/common_utils';
jest.mock('~/lib/utils/common_utils', () => ({ jest.mock('~/lib/utils/common_utils', () => ({
...@@ -11,6 +12,8 @@ jest.mock('~/lib/utils/common_utils', () => ({ ...@@ -11,6 +12,8 @@ jest.mock('~/lib/utils/common_utils', () => ({
const target = 'gitlab-ci-yml-selector'; const target = 'gitlab-ci-yml-selector';
const dismissKey = 'suggest_gitlab_ci_yml_99'; const dismissKey = 'suggest_gitlab_ci_yml_99';
const defaultTrackLabel = 'suggest_gitlab_ci_yml'; const defaultTrackLabel = 'suggest_gitlab_ci_yml';
const commitTrackLabel = 'suggest_commit_first_project_gitlab_ci_yml';
const humanAccess = 'owner';
describe('Suggest gitlab-ci.yml Popover', () => { describe('Suggest gitlab-ci.yml Popover', () => {
let wrapper; let wrapper;
...@@ -21,6 +24,7 @@ describe('Suggest gitlab-ci.yml Popover', () => { ...@@ -21,6 +24,7 @@ describe('Suggest gitlab-ci.yml Popover', () => {
target, target,
trackLabel, trackLabel,
dismissKey, dismissKey,
humanAccess,
}, },
}); });
} }
...@@ -50,15 +54,43 @@ describe('Suggest gitlab-ci.yml Popover', () => { ...@@ -50,15 +54,43 @@ describe('Suggest gitlab-ci.yml Popover', () => {
expect(wrapper.vm.popoverDismissed).toEqual(true); expect(wrapper.vm.popoverDismissed).toEqual(true);
}); });
beforeEach(() => { afterEach(() => {
Cookies.remove(dismissKey); Cookies.remove(dismissKey);
}); });
}); });
describe('tracking', () => {
let trackingSpy;
beforeEach(() => {
createWrapper(commitTrackLabel);
trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
});
afterEach(() => {
unmockTracking();
});
it('sends a tracking event with the expected properties for the popover being viewed', () => {
const expectedCategory = undefined;
const expectedAction = undefined;
const expectedLabel = 'suggest_commit_first_project_gitlab_ci_yml';
const expectedProperty = 'owner';
document.body.dataset.page = 'projects:blob:new';
wrapper.vm.trackOnShow();
expect(trackingSpy).toHaveBeenCalledWith(expectedCategory, expectedAction, {
label: expectedLabel,
property: expectedProperty,
});
});
});
describe('when the popover is mounted with the trackLabel of the Confirm button popover at the bottom of the page', () => { describe('when the popover is mounted with the trackLabel of the Confirm button popover at the bottom of the page', () => {
it('calls scrollToElement so that the Confirm button and popover will be in sight', () => { it('calls scrollToElement so that the Confirm button and popover will be in sight', () => {
const scrollToElementSpy = jest.spyOn(utils, 'scrollToElement'); const scrollToElementSpy = jest.spyOn(utils, 'scrollToElement');
const commitTrackLabel = 'suggest_commit_first_project_gitlab_ci_yml';
createWrapper(commitTrackLabel); createWrapper(commitTrackLabel);
... ...
......
...@@ -16,6 +16,17 @@ const dummyPackageJson = () => ({ ...@@ -16,6 +16,17 @@ const dummyPackageJson = () => ({
main: 'index.js', main: 'index.js',
}), }),
}); });
const expectedSandpackOptions = () => ({
files: {},
entry: '/index.js',
showOpenInCodeSandbox: true,
});
const expectedSandpackSettings = () => ({
fileResolver: {
isFile: expect.any(Function),
readFile: expect.any(Function),
},
});
describe('IDE clientside preview', () => { describe('IDE clientside preview', () => {
let wrapper; let wrapper;
...@@ -84,6 +95,46 @@ describe('IDE clientside preview', () => { ...@@ -84,6 +95,46 @@ describe('IDE clientside preview', () => {
return waitForCalls(); return waitForCalls();
}); });
it('creates sandpack manager', () => {
expect(smooshpack.Manager).toHaveBeenCalledWith(
'#ide-preview',
expectedSandpackOptions(),
expectedSandpackSettings(),
);
});
it('pings usage', () => {
expect(storeClientsideActions.pingUsage).toHaveBeenCalledTimes(1);
});
});
describe('with codesandboxBundlerUrl', () => {
const TEST_BUNDLER_URL = 'https://test.gitlab-static.test';
beforeEach(() => {
createComponent({
getters: { packageJson: dummyPackageJson },
state: { codesandboxBundlerUrl: TEST_BUNDLER_URL },
});
return waitForCalls();
});
it('creates sandpack manager with bundlerURL', () => {
expect(smooshpack.Manager).toHaveBeenCalledWith('#ide-preview', expectedSandpackOptions(), {
...expectedSandpackSettings(),
bundlerURL: TEST_BUNDLER_URL,
});
});
});
describe('with codesandboxBundlerURL', () => {
beforeEach(() => {
createComponent({ getters: { packageJson: dummyPackageJson } });
return waitForCalls();
});
it('creates sandpack manager', () => { it('creates sandpack manager', () => {
expect(smooshpack.Manager).toHaveBeenCalledWith( expect(smooshpack.Manager).toHaveBeenCalledWith(
'#ide-preview', '#ide-preview',
...@@ -100,10 +151,6 @@ describe('IDE clientside preview', () => { ...@@ -100,10 +151,6 @@ describe('IDE clientside preview', () => {
}, },
); );
}); });
it('pings usage', () => {
expect(storeClientsideActions.pingUsage).toHaveBeenCalledTimes(1);
});
}); });
describe('computed', () => { describe('computed', () => {
... ...
......
...@@ -480,8 +480,8 @@ describe WikiPage do ...@@ -480,8 +480,8 @@ describe WikiPage do
let(:untitled_page) { described_class.new(wiki) } let(:untitled_page) { described_class.new(wiki) }
let(:directory_page) do let(:directory_page) do
create_page('parent/child', 'test content') create_page('parent directory/child page', 'test content')
wiki.find_page('parent/child') wiki.find_page('parent directory/child page')
end end
where(:page, :title, :changed) do where(:page, :title, :changed) do
...@@ -494,15 +494,25 @@ describe WikiPage do ...@@ -494,15 +494,25 @@ describe WikiPage do
:existing_page | nil | false :existing_page | nil | false
:existing_page | 'test page' | false :existing_page | 'test page' | false
:existing_page | 'test-page' | false
:existing_page | '/test page' | false :existing_page | '/test page' | false
:existing_page | '/test-page' | false
:existing_page | ' test page ' | true
:existing_page | 'new title' | true :existing_page | 'new title' | true
:existing_page | 'new-title' | true
:directory_page | nil | false :directory_page | nil | false
:directory_page | 'parent/child' | false :directory_page | 'parent directory/child page' | false
:directory_page | 'child' | false :directory_page | 'parent-directory/child page' | false
:directory_page | '/child' | true :directory_page | 'parent-directory/child-page' | false
:directory_page | 'parent/other' | true :directory_page | 'child page' | false
:directory_page | 'other/child' | true :directory_page | 'child-page' | false
:directory_page | '/child page' | true
:directory_page | 'parent directory/other' | true
:directory_page | 'parent-directory/other' | true
:directory_page | 'parent-directory / child-page' | true
:directory_page | 'other directory/child page' | true
:directory_page | 'other-directory/child page' | true
end end
with_them do with_them do
... ...
......
# frozen_string_literal: true # frozen_string_literal: true
RSpec.shared_examples 'setting CSP connect-src' do RSpec.shared_examples 'setting CSP' do |rule_name|
let_it_be(:default_csp_values) { "'self' https://some-cdn.test" } let_it_be(:default_csp_values) { "'self' https://some-cdn.test" }
shared_context 'csp config' do |csp_rule| shared_context 'csp config' do |csp_rule|
...@@ -10,7 +10,7 @@ RSpec.shared_examples 'setting CSP connect-src' do ...@@ -10,7 +10,7 @@ RSpec.shared_examples 'setting CSP connect-src' do
end end
expect_next_instance_of(extended_controller_class) do |controller| expect_next_instance_of(extended_controller_class) do |controller|
expect(controller).to receive(:current_content_security_policy).and_return(csp) expect(controller).to receive(:current_content_security_policy).at_least(:once).and_return(csp)
end end
end end
end end
...@@ -23,55 +23,55 @@ RSpec.shared_examples 'setting CSP connect-src' do ...@@ -23,55 +23,55 @@ RSpec.shared_examples 'setting CSP connect-src' do
end end
end end
describe 'when a CSP config exists for connect-src' do describe "when a CSP config exists for #{rule_name}" do
include_context 'csp config', :connect_src include_context 'csp config', rule_name.parameterize.underscore.to_sym
context 'when feature is enabled' do context 'when feature is enabled' do
it 'appends to connect-src' do it "appends to #{rule_name}" do
is_expected.to eql("connect-src #{default_csp_values} #{whitelisted_url}") is_expected.to eql("#{rule_name} #{default_csp_values} #{whitelisted_url}")
end end
end end
context 'when feature is disabled' do context 'when feature is disabled' do
include_context 'disable feature' include_context 'disable feature'
it 'keeps original connect-src' do it "keeps original #{rule_name}" do
is_expected.to eql("connect-src #{default_csp_values}") is_expected.to eql("#{rule_name} #{default_csp_values}")
end end
end end
end end
describe 'when a CSP config exists for default-src but not connect-src' do describe "when a CSP config exists for default-src but not #{rule_name}" do
include_context 'csp config', :default_src include_context 'csp config', :default_src
context 'when feature is enabled' do context 'when feature is enabled' do
it 'uses default-src values in connect-src' do it "uses default-src values in #{rule_name}" do
is_expected.to eql("default-src #{default_csp_values}; connect-src #{default_csp_values} #{whitelisted_url}") is_expected.to eql("default-src #{default_csp_values}; #{rule_name} #{default_csp_values} #{whitelisted_url}")
end end
end end
context 'when feature is disabled' do context 'when feature is disabled' do
include_context 'disable feature' include_context 'disable feature'
it 'does not add connect-src' do it "does not add #{rule_name}" do
is_expected.to eql("default-src #{default_csp_values}") is_expected.to eql("default-src #{default_csp_values}")
end end
end end
end end
describe 'when a CSP config exists for font-src but not connect-src' do describe "when a CSP config exists for font-src but not #{rule_name}" do
include_context 'csp config', :font_src include_context 'csp config', :font_src
context 'when feature is enabled' do context 'when feature is enabled' do
it 'uses default-src values in connect-src' do it "uses default-src values in #{rule_name}" do
is_expected.to eql("font-src #{default_csp_values}; connect-src #{whitelisted_url}") is_expected.to eql("font-src #{default_csp_values}; #{rule_name} #{whitelisted_url}")
end end
end end
context 'when feature is disabled' do context 'when feature is disabled' do
include_context 'disable feature' include_context 'disable feature'
it 'does not add connect-src' do it "does not add #{rule_name}" do
is_expected.to eql("font-src #{default_csp_values}") is_expected.to eql("font-src #{default_csp_values}")
end end
end end
... ...
......
...@@ -2779,10 +2779,10 @@ code-point-at@^1.0.0: ...@@ -2779,10 +2779,10 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codesandbox-api@^0.0.20: codesandbox-api@0.0.23:
version "0.0.20" version "0.0.23"
resolved "https://registry.yarnpkg.com/codesandbox-api/-/codesandbox-api-0.0.20.tgz#174bcd76c9f31521175c6bceabc37da6b1fbc30b" resolved "https://registry.yarnpkg.com/codesandbox-api/-/codesandbox-api-0.0.23.tgz#bf650a21b5f3c2369e03f0c19d10b4e2ba255b4f"
integrity sha512-jhxZzAmjCKBZad8QWMeueiQVFE87igK6F2DBOEVFFJO6jgTXT8qjuzGYepr+B8bjgo/icN7bc/2xmEMBA63s2w== integrity sha512-fFGBkIghDkQILh7iHYlpZU5sfWncCDb92FQSFE4rR3VBcTfUsD5VZgpQi+JjZQuwWIdfl4cOhcIFrUYwshUezA==
codesandbox-import-util-types@^1.2.11: codesandbox-import-util-types@^1.2.11:
version "1.2.11" version "1.2.11"
...@@ -10334,12 +10334,12 @@ slugify@^1.3.1: ...@@ -10334,12 +10334,12 @@ slugify@^1.3.1:
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.1.tgz#f572127e8535329fbc6c1edb74ab856b61ad7de2" resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.1.tgz#f572127e8535329fbc6c1edb74ab856b61ad7de2"
integrity sha512-6BwyhjF5tG5P8s+0DPNyJmBSBePG6iMyhjvIW5zGdA3tFik9PtK+yNkZgTeiroCRGZYgkHftFA62tGVK1EI9Kw== integrity sha512-6BwyhjF5tG5P8s+0DPNyJmBSBePG6iMyhjvIW5zGdA3tFik9PtK+yNkZgTeiroCRGZYgkHftFA62tGVK1EI9Kw==
smooshpack@^0.0.54: smooshpack@^0.0.62:
version "0.0.54" version "0.0.62"
resolved "https://registry.yarnpkg.com/smooshpack/-/smooshpack-0.0.54.tgz#9044358b85052d348b801f385678c8a0c76f2bb6" resolved "https://registry.yarnpkg.com/smooshpack/-/smooshpack-0.0.62.tgz#cb31b9f808f73de3146b050f84d044eb353b5503"
integrity sha512-yIwEWb17hqoW5IaWyzO6O6nxY89I5UdRoGIZy5hihoqXP9OYcoMbBTxKwS57MeXSKdNA2rtk86rlCcOgAYIgrA== integrity sha512-lFuJV2f504/U78sifWy0V2FyoE/8mTgOXM4DL918ncNxAxbtu236XSCLAH3SQwXZWn0JdmRnWs/XU4+sIUVVmQ==
dependencies: dependencies:
codesandbox-api "^0.0.20" codesandbox-api "0.0.23"
codesandbox-import-utils "^1.2.3" codesandbox-import-utils "^1.2.3"
lodash.isequal "^4.5.0" lodash.isequal "^4.5.0"
... ...
......