diff --git a/ckanext-hdx_dataviz/ckanext/hdx_dataviz/tests/test_dataviz_page_load.py b/ckanext-hdx_dataviz/ckanext/hdx_dataviz/tests/test_dataviz_page_load.py index decb54da89..8e32aa26c8 100644 --- a/ckanext-hdx_dataviz/ckanext/hdx_dataviz/tests/test_dataviz_page_load.py +++ b/ckanext-hdx_dataviz/ckanext/hdx_dataviz/tests/test_dataviz_page_load.py @@ -1,5 +1,4 @@ import pytest -import six import ckan.plugins.toolkit as tk diff --git a/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_custom_org_controller.py b/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_custom_org_controller.py index 092fbd9256..fd8238c830 100644 --- a/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_custom_org_controller.py +++ b/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_custom_org_controller.py @@ -140,7 +140,7 @@ def mock_get_top_line_items(): org_dict = _get_action('organization_update')(context, org_dict) data_access_cls.return_value.get_top_line_items.side_effect = mock_get_top_line_items - req_mock.args = {} + req_mock.args = mock.MagicMock() tk.g.user = sysadmin_user tk.g.userobj = None org_helper_c_mock.user = sysadmin_user diff --git a/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_member_controller.py b/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_member_controller.py index 5e58a487f5..e1bfdcdae6 100644 --- a/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_member_controller.py +++ b/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_controller/test_member_controller.py @@ -138,7 +138,6 @@ def test_members(self, render, app): context = {'model': model, 'session': model.Session, 'user': orgadmin} orgadmin_token = factories.APIToken(user='orgadmin', expires_in=2, unit=60 * 60)['token'] auth = {'Authorization': orgadmin_token} - # test_client = self.get_backwards_compatible_test_client() member_with_name_list = _get_action('member_list')(context, { 'id': 'hdx-test-org', @@ -236,16 +235,17 @@ def _populate_member_names(self, members, member_with_name_list): ret = [next(u[4] for u in member_with_name_list if u[0] == member[0]) for member in members] return ret + @pytest.mark.usefixtures('with_request_context') @mock.patch('ckanext.hdx_users.helpers.mailer._mail_recipient_html') - def test_request_membership(self, _mail_recipient_html): + def test_request_membership(self, _mail_recipient_html, app): test_sysadmin = 'testsysadmin' test_username = 'johndoe1' - test_client = self.get_backwards_compatible_test_client() + test_username_token = factories.APIToken(user=test_username, expires_in=2, unit=60 * 60)['token'] context = {'model': model, 'session': model.Session, 'user': test_sysadmin} # removing one member from organization url = h.url_for('hdx_members.member_delete', id='hdx-test-org') - test_client.post(url, params={'user': 'johndoe1'}, extra_environ={"REMOTE_USER": test_sysadmin}) + app.post(url, params={'user': 'johndoe1'}, extra_environ={"REMOTE_USER": test_sysadmin}) member_list = self._get_action('member_list')(context, { 'id': 'hdx-test-org', @@ -262,9 +262,9 @@ def test_request_membership(self, _mail_recipient_html): # send a membership request url = h.url_for('ytp_request.new') - ret_page = test_client.post(url, params={'organization': 'hdx-test-org', 'role': 'member', 'save': 'save', - 'message': 'add me to your organization'}, - extra_environ={"REMOTE_USER": test_username}) + ret_page = app.post(url, params={'organization': 'hdx-test-org', 'role': 'member', 'save': 'save', + 'message': 'add me to your organization'}, + headers={'Authorization': test_username_token}) member_requests = self._get_action('member_request_list')(context, {'group': 'hdx-test-org'}) assert len(member_requests) == 1, 'Exactly one member request should exist for this org' assert member_requests[0].get('user_name') == test_username @@ -280,16 +280,17 @@ def _populate_member_names(self, members, member_with_name_list): ret = [next(u[4] for u in member_with_name_list if u[0] == member[0]) for member in members] return ret + @pytest.mark.usefixtures('with_request_context') @mock.patch('ckanext.hdx_users.helpers.mailer._mail_recipient_html') - def test_request_membership(self, _mail_recipient_html): + def test_request_membership(self, _mail_recipient_html, app): test_sysadmin = 'testsysadmin' test_username = 'johndoe1' - test_client = self.get_backwards_compatible_test_client() + test_username_token = factories.APIToken(user=test_username, expires_in=2, unit=60 * 60)['token'] context = {'model': model, 'session': model.Session, 'user': test_sysadmin} # removing one member from organization url = h.url_for('hdx_members.member_delete', id='hdx-test-org') - test_client.post(url, params={'user': 'johndoe1'}, extra_environ={"REMOTE_USER": test_sysadmin}) + app.post(url, params={'user': 'johndoe1'}, extra_environ={"REMOTE_USER": test_sysadmin}) member_list = self._get_action('member_list')(context, { 'id': 'hdx-test-org', @@ -306,9 +307,9 @@ def test_request_membership(self, _mail_recipient_html): # send a membership request url = h.url_for('ytp_request.new') - ret_page = test_client.post(url, params={'organization': 'hdx-test-org', 'role': 'editor', 'save': 'save', - 'message': 'add me to your organization'}, - extra_environ={"REMOTE_USER": test_username}) + ret_page = app.post(url, params={'organization': 'hdx-test-org', 'role': 'editor', 'save': 'save', + 'message': 'add me to your organization'}, + headers={'Authorization': test_username_token}) member_requests = self._get_action('member_request_list')(context, {'group': 'hdx-test-org'}) assert len(member_requests) == 1, 'Exactly one member request should exist for this org' assert member_requests[0].get('user_name') == test_username diff --git a/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_pages/test_dataset_search_params.py b/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_pages/test_dataset_search_params.py index 8b5f914037..3623364137 100644 --- a/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_pages/test_dataset_search_params.py +++ b/ckanext-hdx_org_group/ckanext/hdx_org_group/tests/test_pages/test_dataset_search_params.py @@ -46,7 +46,7 @@ def test_search_params(self): end_str = '' search_item = 'name="q"' - count = hdx_test_util.count_string_occurences(page, search_item, + count = hdx_test_util.count_string_occurrences(page, search_item, begin_str, end_str) assert count == 1, 'There should be exactly one input with name q in the form' diff --git a/ckanext-hdx_package/ckanext/hdx_package/helpers/custom_validator.py b/ckanext-hdx_package/ckanext/hdx_package/helpers/custom_validator.py index d237646302..efe14cdf2f 100644 --- a/ckanext-hdx_package/ckanext/hdx_package/helpers/custom_validator.py +++ b/ckanext-hdx_package/ckanext/hdx_package/helpers/custom_validator.py @@ -685,6 +685,26 @@ def hdx_resources_not_allowed_if_requested_data(key, data, errors, context): raise df.Invalid(_('By request - HDX Connect datasets can not store resources')) +def hdx_disable_live_frequency_filestore_resources_only(key, data, errors, context): + """ + Validates that a dataset marked as 'Live' has at least one external resource + """ + if data[key] == '0': # '0' means 'Live' + has_resources = False + has_external_resource = False + + for resource_key, value in data.items(): + if resource_key[0] == 'resources': + has_resources = True + if resource_key[-1] == 'url_type': + if value == 'api': + has_external_resource = True + break + + if has_resources and not has_external_resource: + raise Invalid(_('Live datasets should have at least one external resource')) + + DATASERIES_TITLE_PATTERN = re.compile('^[\w ,-]+$', re.UNICODE) def hdx_dataseries_title_validator(value, context): if value: diff --git a/ckanext-hdx_package/ckanext/hdx_package/plugin.py b/ckanext-hdx_package/ckanext/hdx_package/plugin.py index ae2aa0c980..69a93e2577 100644 --- a/ckanext-hdx_package/ckanext/hdx_package/plugin.py +++ b/ckanext-hdx_package/ckanext/hdx_package/plugin.py @@ -155,7 +155,8 @@ def _modify_package_schema(self, schema): tk.get_validator('not_empty'), tk.get_validator('unicode_safe'), tk.get_validator('hdx_in_update_frequency_values'), - tk.get_converter('convert_to_extras') + tk.get_validator('hdx_disable_live_frequency_filestore_resources_only'), + tk.get_converter('convert_to_extras'), ], 'batch': [tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')], 'maintainer': [tk.get_validator('hdx_find_package_maintainer'), tk.get_validator('not_empty')], @@ -518,6 +519,7 @@ def get_validators(self): 'hdx_add_update_fs_check_info': vd.hdx_add_update_fs_check_info, 'hdx_tag_name_approved_validator': vd.hdx_tag_name_approved_validator, 'hdx_update_last_modified_if_url_changed': vd.hdx_update_last_modified_if_url_changed, + 'hdx_disable_live_frequency_filestore_resources_only': vd.hdx_disable_live_frequency_filestore_resources_only, } def get_auth_functions(self): diff --git a/ckanext-hdx_package/ckanext/hdx_package/tests/test_aws/hdx_s3_test_base.py b/ckanext-hdx_package/ckanext/hdx_package/tests/test_aws/hdx_s3_test_base.py index 6773756f9f..4f5e731f8e 100644 --- a/ckanext-hdx_package/ckanext/hdx_package/tests/test_aws/hdx_s3_test_base.py +++ b/ckanext-hdx_package/ckanext/hdx_package/tests/test_aws/hdx_s3_test_base.py @@ -135,7 +135,7 @@ def _create_package_by_user(cls, pkg_name, user, create_org_and_group=True): "owner_org": "test_owner_org", "groups": [{"name": "test_group1"}], "maintainer": "testsysadmin", - "data_update_frequency": "0", + "data_update_frequency": "-1", "resources": [ { 'package_id': pkg_name, diff --git a/ckanext-hdx_package/ckanext/hdx_package/tests/test_controller/test_contribute_flow.py b/ckanext-hdx_package/ckanext/hdx_package/tests/test_controller/test_contribute_flow.py index 460d2958c9..d760618d3e 100644 --- a/ckanext-hdx_package/ckanext/hdx_package/tests/test_controller/test_contribute_flow.py +++ b/ckanext-hdx_package/ckanext/hdx_package/tests/test_controller/test_contribute_flow.py @@ -124,7 +124,7 @@ def _get_dataset_post_param(dataset_name): 'maintainer': 'testsysadmin', 'license_id': 'cc-by', 'methodology': 'Census', - 'data_update_frequency': 0, + 'data_update_frequency': -1, 'resources__0__position': 0, 'resources__0__url': 'http://yahoo.com', 'resources__0__format': 'link', diff --git a/ckanext-hdx_package/ckanext/hdx_package/tests/test_dataset_special_fields/test_data_update_frequency.py b/ckanext-hdx_package/ckanext/hdx_package/tests/test_dataset_special_fields/test_data_update_frequency.py new file mode 100644 index 0000000000..61bdacf685 --- /dev/null +++ b/ckanext-hdx_package/ckanext/hdx_package/tests/test_dataset_special_fields/test_data_update_frequency.py @@ -0,0 +1,90 @@ +import pytest + +import ckan.tests.factories as factories +import ckan.model as model +import ckan.plugins.toolkit as tk + +import ckanext.hdx_theme.tests.hdx_test_base as hdx_test_base + +from ckanext.hdx_org_group.helpers.static_lists import ORGANIZATION_TYPE_LIST + +config = tk.config +NotAuthorized = tk.NotAuthorized +ValidationError = tk.ValidationError + + +class TestDataUpdateFrequency(hdx_test_base.HdxBaseTest): + NORMAL_USER = 'normal_user' + LIVE_UPDATE_FREQUENCY = '0' + + INTERNAL_RESOURCE = { + 'package_id': 'test_private_dataset_1', + 'url': config.get('ckan.site_url', '') + '/storage/f/test_folder/hdx_test.csv', + 'resource_type': 'file.upload', + 'format': 'CSV', + 'name': 'hdx_test.csv' + } + EXTERNAL_RESOURCE = { + 'package_id': 'test_private_dataset_1', + 'url': 'http://test.ckan.test/test.csv', + 'resource_type': 'api', + 'url_type': 'api', + 'format': 'CSV', + 'name': 'data1.csv', + } + PACKAGE = { + 'package_creator': 'test function', + 'private': False, + 'dataset_date': '01/01/1960-12/31/2012', + 'caveats': 'These are the caveats', + 'license_other': 'TEST OTHER LICENSE', + 'methodology': 'This is a test methodology', + 'dataset_source': 'Test data', + 'license_id': 'hdx-other', + 'notes': 'This is a test dataset', + 'data_update_frequency': LIVE_UPDATE_FREQUENCY, + 'title': 'Test Dataset for Update Frequency', + 'owner_org': 'org_name_4_update_frequency', + 'groups': [{'name': 'roger'}], + } + + @classmethod + def _get_action(cls, action_name): + return tk.get_action(action_name) + + @classmethod + def setup_class(cls): + super(TestDataUpdateFrequency, cls).setup_class() + factories.User(name=cls.NORMAL_USER, email='normal_user@hdx.hdxtest.org') + factories.Organization( + name='org_name_4_update_frequency', + title='ORG NAME FOR UPDATE FREQUENCY', + users=[ + {'name': cls.NORMAL_USER, 'capacity': 'admin'}, + ], + hdx_org_type=ORGANIZATION_TYPE_LIST[0][1], + org_url='https://hdx.hdxtest.org/' + ) + + def test_valid_live_dataset_with_external_resource(self): + context = {'model': model, 'session': model.Session, 'user': self.NORMAL_USER} + + self.PACKAGE['name'] = 'test_dataset_1' + self.PACKAGE['resources'] = [self.INTERNAL_RESOURCE, self.EXTERNAL_RESOURCE] + + dataset_dict = self._get_action('package_create')(context, self.PACKAGE) + assert dataset_dict.get( + 'data_update_frequency') == self.LIVE_UPDATE_FREQUENCY, 'Live dataset should be created successfully with ' \ + 'an external resource' + + def test_invalid_live_dataset_with_only_internal_resources(self): + context = {'model': model, 'session': model.Session, 'user': self.NORMAL_USER} + + self.PACKAGE['name'] = 'test_dataset_2' + self.PACKAGE['resources'] = [self.INTERNAL_RESOURCE] + + try: + self._get_action('package_create')(context, self.PACKAGE) + assert False, 'Validation error should be raised for live datasets without any external resource' + except ValidationError as e: + assert True, 'Live datasets should have at least one external resource' diff --git a/ckanext-hdx_pages/ckanext/hdx_pages/tests/test_controller.py b/ckanext-hdx_pages/ckanext/hdx_pages/tests/test_controller.py index 8fb7cabe80..fcee3f0691 100644 --- a/ckanext-hdx_pages/ckanext/hdx_pages/tests/test_controller.py +++ b/ckanext-hdx_pages/ckanext/hdx_pages/tests/test_controller.py @@ -244,7 +244,7 @@ def test_page_delete(self, app): eldeleted_page = _get_action('page_show')(context_sysadmin, {'id': page_eldeleted.get('name')}) try: url = h.url_for(u'hdx_custom_page.delete_page', id=eldeleted_page.get('id')) - page_delete = app.post(url, extra_environ={"REMOTE_USER": USER}) + page_delete = app.post(url, headers={'Authorization': self._get_token_for_user(USER)}) assert 'Page not found' in page_delete.body, 'page doesn\'t exist' assert '404 Not Found'.lower() in page_delete.status.lower() except logic.NotAuthorized: diff --git a/ckanext-hdx_search/ckanext/hdx_search/controller_logic/search_logic.py b/ckanext-hdx_search/ckanext/hdx_search/controller_logic/search_logic.py index 12d5c50e56..4bb0cc8e36 100644 --- a/ckanext-hdx_search/ckanext/hdx_search/controller_logic/search_logic.py +++ b/ckanext-hdx_search/ckanext/hdx_search/controller_logic/search_logic.py @@ -407,7 +407,7 @@ def _page_number(self): def _params_nopage(self): params_to_skip = ['_show_filters'] # most search operations should reset the page counter: - return [(k, v) for k, v in request.args.items() + return [(k, v) for k, v in request.args.items(multi=True) if k != 'page' and k not in params_to_skip] def _set_search_url_params(self): diff --git a/ckanext-hdx_search/ckanext/hdx_search/tests/conftest.py b/ckanext-hdx_search/ckanext/hdx_search/tests/conftest.py new file mode 100644 index 0000000000..e2ee852355 --- /dev/null +++ b/ckanext-hdx_search/ckanext/hdx_search/tests/conftest.py @@ -0,0 +1 @@ +from ckanext.hdx_theme.tests.conftest import keep_db_tables_on_clean diff --git a/ckanext-hdx_search/ckanext/hdx_search/tests/test_pages/test_pagination.py b/ckanext-hdx_search/ckanext/hdx_search/tests/test_pages/test_pagination.py new file mode 100644 index 0000000000..aa10698555 --- /dev/null +++ b/ckanext-hdx_search/ckanext/hdx_search/tests/test_pages/test_pagination.py @@ -0,0 +1,88 @@ +import pytest +import ckan.tests.factories as factories + +import ckan.plugins.toolkit as tk +import ckan.model as model + +from ckan.types import Context +from ckanext.hdx_org_group.helpers.static_lists import ORGANIZATION_TYPE_LIST +from ckanext.hdx_theme.tests import hdx_test_util + +_url_for = tk.url_for +_get_action = tk.get_action + +STANDARD_USER = 'some_standard_user' +LOCATION_NAME = 'some_location' +ORG_NAME1 = 'some_org1' +ORG_NAME2 = 'some_org2' + + +def _get_dataset_dict(dataset_name, org_name): + return { + "package_creator": "test function", + "private": False, + "dataset_date": "[1960-01-01 TO 2012-12-31]", + "caveats": "These are the caveats", + "license_other": "TEST OTHER LICENSE", + "methodology": "This is a test methodology", + "dataset_source": "Test data", + "license_id": "hdx-other", + "name": dataset_name, + "notes": "This is a test dataset", + "title": "Test Dataset " + dataset_name, + "owner_org": org_name, + "groups": [{"name": LOCATION_NAME}], + "data_update_frequency": "30", + "maintainer": STANDARD_USER, + "resources": [ + { + 'url': 'http://test.ckan.test/test.csv', + 'resource_type': 'api', + 'url_type': 'api', + 'format': 'CSV', + 'name': 'data1.csv', + } + ], + } + + +@pytest.fixture() +def setup_data(): + factories.User(name=STANDARD_USER, email='some_standard_user@hdx.hdxtest.org') + group = factories.Group(name=LOCATION_NAME) + for org_name in [ORG_NAME1, ORG_NAME2]: + factories.Organization( + name=org_name, + title='ORG NAME FOR HDX_REL_URL', + users=[ + {'name': STANDARD_USER, 'capacity': 'editor'}, + ], + hdx_org_type=ORGANIZATION_TYPE_LIST[0][1], + org_url='https://hdx.hdxtest.org/' + ) + + context: Context = {'model': model, 'session': model.Session, 'user': STANDARD_USER} + _get_action('package_create')(context, _get_dataset_dict(dataset_name='dataset1', + org_name=ORG_NAME1)) + _get_action('package_create')(context, _get_dataset_dict(dataset_name='dataset2', + org_name=ORG_NAME2)) + + +@pytest.mark.usefixtures('keep_db_tables_on_clean', 'clean_db', 'clean_index', 'setup_data') +def test_pagination_2_valued_filter(app): + url = _url_for('hdx_dataset.search', organization=[ORG_NAME1, ORG_NAME2], ext_page_size=1) + response = app.get(url) + assert response.status_code == 200 + + page = response.body + + begin_str = '' + search_item1 = f'organization={ORG_NAME1}' + search_item2 = f'organization={ORG_NAME2}' + + count_org1 = hdx_test_util.count_string_occurrences(page, search_item1, begin_str, end_str) + assert count_org1 == 1 + + count_org2 = hdx_test_util.count_string_occurrences(page, search_item2, begin_str, end_str) + assert count_org2 == 1 diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/carousel.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/carousel.js index 79fc5ac10e..fe18a09512 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/carousel.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/carousel.js @@ -49,6 +49,7 @@ options.emulateJSON = true; // Important because your sending formdata options.processData = false; options.contentType = false; + options.headers = hdxUtil.net.getCsrfTokenAsObject(); return Backbone.Model.prototype.sync.call(this, method, model, options); // return Backbone.sync.apply(this, arguments); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/package_links.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/package_links.js index 96b0b66ed0..a43b2fa7db 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/package_links.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/package_links.js @@ -51,6 +51,7 @@ options.emulateJSON = true; // Important because your sending formdata options.processData = false; options.contentType = false; + options.headers = hdxUtil.net.getCsrfTokenAsObject(); return Backbone.Model.prototype.sync.call(this, method, model, options); // return Backbone.sync.apply(this, arguments); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/quick_links.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/quick_links.js index 564dacbffd..f50dc302c9 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/quick_links.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/admin/quick_links.js @@ -50,6 +50,7 @@ options.emulateJSON = true; // Important because your sending formdata options.processData = false; options.contentType = false; + options.headers = hdxUtil.net.getCsrfTokenAsObject(); return Backbone.Model.prototype.sync.call(this, method, model, options); // return Backbone.sync.apply(this, arguments); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/backbone-model-file-upload.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/backbone-model-file-upload.js index a46205f34f..249f93ccf1 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/backbone-model-file-upload.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/backbone-model-file-upload.js @@ -101,6 +101,7 @@ options.data = formData; options.processData = false; options.contentType = false; + options.headers = hdxUtil.net.getCsrfTokenAsObject(); // Handle "progress" events if (!options.xhr) { @@ -173,4 +174,4 @@ // Export out to override Backbone Model Backbone.Model = BackboneModelFileUpload; -})); \ No newline at end of file +})); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/contribute_flow_main.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/contribute_flow_main.js index 0c0fadbd1b..164aa43c07 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/contribute_flow_main.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/contribute_flow/contribute_flow_main.js @@ -63,29 +63,33 @@ formDataArray.push({'name': 'id', 'value': datasetId}); - $.post(validateUrl, formDataArray, - function (data, status, xhr) { - data.error_summary = data.error_summary ? data.error_summary : {}; - - // Resources are not required for metadata-only datasets - if (!data.data.is_requestdata_type && (!resourceDataArray || resourceDataArray.length === 0)) { - data.error_summary['resource-list'] = 'Please add at least 1 resource to the dataset'; - - } - - // Tags are required for metadata-only datasets - if (data.data.is_requestdata_type && data.data.tag_string.length === 0) { - data.errors.tag_string = ['Missing value']; - } - - contributeGlobal.updateValidationUi(data, status, xhr); - // contributeGlobal._managePrivateField(); - deferred.resolve(contributeGlobal.validateSucceeded(data, status)); - moduleLog('Validation finished'); + $.ajax({ + url: validateUrl, + type: 'POST', + data: formDataArray, + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (data, status, xhr) { + data.error_summary = data.error_summary ? data.error_summary : {}; + + // Resources are not required for metadata-only datasets + if (!data.data.is_requestdata_type && (!resourceDataArray || resourceDataArray.length === 0)) { + data.error_summary['resource-list'] = 'Please add at least 1 resource to the dataset'; + } + // Tags are required for metadata-only datasets + if (data.data.is_requestdata_type && data.data.tag_string.length === 0) { + data.errors.tag_string = ['Missing value']; } - ).fail(contributeGlobal.recoverFromServerError); + contributeGlobal.updateValidationUi(data, status, xhr); + // contributeGlobal._managePrivateField(); + deferred.resolve(contributeGlobal.validateSucceeded(data, status)); + moduleLog('Validation finished'); + }, + error: function (xhr, status, error) { + contributeGlobal.recoverFromServerError(); + } + }); }.bind(this) ); @@ -156,12 +160,19 @@ contributeGlobal.controlUserWaitingWidget(true, 'Saving dataset form...'); $.when(analyticsPromise).done(function () { - $.post(requestUrl, formDataArray, - function (data, status, xhr) { - contributeGlobal.updateInnerState(data, status); - deferred.resolve(data, status, xhr); - } - ).fail(contributeGlobal.recoverFromServerError); + $.ajax({ + url: requestUrl, + type: 'POST', + data: formDataArray, + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (data, status, xhr) { + contributeGlobal.updateInnerState(data, status); + deferred.resolve(data, status, xhr); + }, + error: function (xhr, status, error) { + contributeGlobal.recoverFromServerError(); + } + }); }); } } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/country/custom/country-custom.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/country/custom/country-custom.js index d3c0ef02bd..b839ce1644 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/country/custom/country-custom.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/country/custom/country-custom.js @@ -141,6 +141,7 @@ function autoGraph() { type: 'POST', dataType: 'json', url: '/api/3/action/datastore_search_sql', + headers: hdxUtil.net.getCsrfTokenAsObject(), data: urldata, index: sIdx, success: function (data) { @@ -436,6 +437,7 @@ function loadMapData(map, confJson, layers){ type: 'POST', dataType: 'json', url: '/api/3/action/datastore_search_sql', + headers: hdxUtil.net.getCsrfTokenAsObject(), data: urldata, success: function(result){ values = processMapValues(result.result.records, confJson, pcodeColumnName, valueColumnName, descriptionColumnName); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/crisis/ebola/ebola_crisis_page_graph.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/crisis/ebola/ebola_crisis_page_graph.js index 0414eb6a15..f58eef7b40 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/crisis/ebola/ebola_crisis_page_graph.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/crisis/ebola/ebola_crisis_page_graph.js @@ -11,6 +11,7 @@ $.ajax({ type: 'POST', dataType: 'json', url: '/api/3/action/datastore_search_sql', + headers: hdxUtil.net.getCsrfTokenAsObject(), data: data, success: function(data) { var processedData = processData(data.result.records); @@ -55,7 +56,7 @@ function processData(dataIn){ data[data.length-1]['cases'][e['Country']]=e['value']; } else { data[data.length-1]['cases']['other']+=e['value']; - } + } } }); return data; @@ -65,9 +66,9 @@ function generateLineChart(id,data){ data.forEach(function(e){ e.date = new Date(e.date); }); - + var varNames = d3.keys(data[0].deaths).filter(function (key) { return key !== 'total';});; - + var seriesDeathArr = [], series = {}; varNames.forEach(function (name) { series[name] = {name: name, values:[]}; @@ -78,7 +79,7 @@ function generateLineChart(id,data){ series[name].values.push({label: d.date, value: +d.deaths[name]}); }); }); - + var seriesDeathArr = [], series = {}; varNames.forEach(function (name) { series[name] = {name: name, values:[]}; @@ -88,12 +89,12 @@ function generateLineChart(id,data){ varNames.map(function (name) { series[name].values.push({label: d.date, value: +d.deaths[name]}); }); - }); - + }); + var deathColor = d3.scale.ordinal() //.range(["#B71C1C","#E53935","#EF9A9A","#FFEBEE"]); .range(["#f2645a","#F58A83","#F8B1AC","#FBD8D5"]); - + var seriesCaseArr = [], series = {}; varNames.forEach(function (name) { series[name] = {name: name, values:[]}; @@ -103,7 +104,7 @@ function generateLineChart(id,data){ varNames.map(function (name) { series[name].values.push({label: d.date, value: +d.cases[name]}); }); - }); + }); var caseColor = d3.scale.ordinal() //.range(["#1A237E","#3949AB","#7986CB","#E8EAF6"]) @@ -118,10 +119,10 @@ function generateLineChart(id,data){ var y = d3.scale.linear() .range([height, 0]); - - x.domain(d3.extent(data, function(d) { + + x.domain(d3.extent(data, function(d) { return d.date; })); - y.domain([0,d3.max(data, function(d) { return d.cases.total; })]); + y.domain([0,d3.max(data, function(d) { return d.cases.total; })]); var xAxis = d3.svg.axis() .scale(x) @@ -169,7 +170,7 @@ function generateLineChart(id,data){ .x(function (d) { return x(d.label); }) .y0(function (d) { return y(d.y0); }) .y1(function (d) { return y(d.y0 + d.y); }); - + stack(seriesDeathArr); stack(seriesCaseArr); var svg = d3.select(id).append("svg") @@ -360,7 +361,7 @@ function generateLineChart(id,data){ d3.selectAll(".deathPath").transition().duration(500).attr("opacity",0); d3.selectAll(".linelabels").transition().duration(500).attr("opacity",1); d3.selectAll(".areadeathlabels").transition().duration(500).attr("opacity",0); - }); + }); svg.append("path") .datum(data) @@ -379,4 +380,4 @@ function generateLineChart(id,data){ d3.selectAll(".areacaselabels").transition().duration(500).attr("opacity",0); d3.selectAll(".deathline").transition().duration(500).attr("opacity",1); }); -} \ No newline at end of file +} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/hdx-form-validator.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/hdx-form-validator.js index 25c07a5d3b..5135392cb6 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/hdx-form-validator.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/hdx-form-validator.js @@ -105,8 +105,9 @@ this.ckan.module('hdx-form-validator', function ($) { {rule: this.validateLength, args: [1, null]} ], username: [ - {rule: this.validateRegex, args: [/^[a-z0-9_-]+$/]}, - {rule: this.validateLength, args: [2, 100]} + {rule: this.validateLowercaseAlphanumeric}, + {rule: this.validateLength, args: [2, 100]}, + {rule: this.validateCharacters, args: [/^[a-zA-Z0-9_-]+$/]}, ], email: [ {rule: this.validateRegex, args: [/^[^\s@]+@[^\s@]+\.[^\s@]+$/]} @@ -166,12 +167,30 @@ this.ckan.module('hdx-form-validator', function ($) { return [validationErrors.length === 0, validationErrors]; }, - validateRegex: function (field, regex) { var isValid = regex.test(field.val()); return [isValid, isValid ? null : 'invalid-format']; }, + validateLowercaseAlphanumeric: function (field) { + var value = field.val(); + + var isValid = true; + if (/[A-Z]/.test(value)) { + isValid = false; + } + if (!/[a-z0-9]/.test(value)) { + isValid = false; + } + + return [isValid, isValid ? null : 'no-lowercase-alphanumeric']; + }, + + validateCharacters: function (field, regex) { + var isValid = regex.test(field.val()); + return [isValid, isValid ? null : 'invalid-characters']; + }, + validateFieldsMatch: function (field) { var form = field.closest('form'); var matchFieldName = field.data('validation-match'); @@ -295,8 +314,8 @@ this.ckan.module('hdx-form-validator', function ($) { var validationMessages = { 'name': [ {'key': 'invalid-length', 'message': 'Must be between 2 and 100 characters in length'}, - {'key': 'invalid-format', 'message': 'Must use lowercase alphanumeric characters'}, - {'key': null, 'message': 'Can use - (dash) or _ (underscore)'} + {'key': 'no-lowercase-alphanumeric', 'message': 'Must use lowercase alphanumeric characters (a-z, 0-9)'}, + {'key': 'invalid-characters', 'message': 'Only allowed special characters - (dash) or _ (underscore)'}, ], 'password1': [ {'key': 'invalid-length', 'message': 'The password must be a minimum of 10 characters in length'}, diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/qa/qa-package.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/qa/qa-package.js index b5601b6ee1..5336c02211 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/qa/qa-package.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/qa/qa-package.js @@ -15,17 +15,22 @@ function _updateQuarantine(resource, flag) { "_csrf_token": csrf_value }; let promise = new Promise((resolve, reject) => { - $.post('/api/action/hdx_qa_resource_patch', body) - .done((result) => { - if (result.success){ + $.ajax({ + url: '/api/action/hdx_qa_resource_patch', + type: 'POST', + data: body, + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result) { + if (result.success) { resolve(result); } else { reject(result); } - }) - .fail((result) => { + }, + error: function (result) { reject(result); - }); + } + }); }); return promise; } @@ -38,17 +43,22 @@ function _updateBrokenLink(resource, flag) { "_csrf_token": csrf_value }; let promise = new Promise((resolve, reject) => { - $.post('/api/action/hdx_mark_broken_link_in_resource', body) - .done((result) => { - if (result.success){ + $.ajax({ + url: '/api/action/hdx_mark_broken_link_in_resource', + type: 'POST', + data: body, + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result) { + if (result.success) { resolve(result); } else { reject(result); } - }) - .fail((result) => { + }, + error: function (result) { reject(result); - }); + } + }); }); return promise; } @@ -63,17 +73,22 @@ function _updateAllResourcesKeyValue(package,key,value) { }; let promise = new Promise((resolve, reject) => { - $.post('/api/action/hdx_qa_package_revise_resource', body) - .done((result) => { - if (result.success){ + $.ajax({ + url: '/api/action/hdx_qa_package_revise_resource', + type: 'POST', + data: body, + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result) { + if (result.success) { resolve(result); } else { reject(result); } - }) - .fail((result) => { + }, + error: function (result) { reject(result); - }); + } + }); }); return promise; } @@ -187,7 +202,13 @@ function _updateResourceConfirmState(resource, flag, score, piiReportId) { let promise = new Promise((resolve, reject) => { const mixpanelPromise = hdxUtil.analytics.sendQADashboardEvent(resource,flag,score,piiReportId); - const patchPromise = $.post('/api/action/hdx_qa_resource_patch', body); + const patchPromise = $.ajax({ + url: '/api/action/hdx_qa_resource_patch', + type: 'POST', + data: body, + headers: hdxUtil.net.getCsrfTokenAsObject(), + }); + mixpanelPromise.then((mixpanelResults) => { patchPromise .done((result) => { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/requestdata_/modal-form.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/requestdata_/modal-form.js index 479f35717f..c46889dd92 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/requestdata_/modal-form.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/requestdata_/modal-form.js @@ -24,7 +24,15 @@ ckan.module('hdx-modal-form', function($) { } var base_url = ckan.sandbox().client.endpoint; var url = base_url + '/api/' + api_ver + '/action/' + action; - return $.post(url, JSON.stringify(data), "json"); + return $.ajax({ + url: url, + type: 'POST', + contentType: 'application/json', + data: JSON.stringify(data), + dataType: 'json', + headers: hdxUtil.net.getCsrfTokenAsObject(), + }); + } }; @@ -167,6 +175,7 @@ ckan.module('hdx-modal-form', function($) { data: formData, processData: false, contentType: false, + headers: hdxUtil.net.getCsrfTokenAsObject(), type: 'POST' }) .done(function(data) { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/webassets.yml b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/webassets.yml index 1a5f73f4ff..57e7b886d9 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/webassets.yml +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/webassets.yml @@ -392,7 +392,7 @@ onboarding-bulk-user-styles: - onboarding-select-org-styles - onboarding-survey-styles - + onboarding-bulk-user-scripts: extra: preload: @@ -537,6 +537,7 @@ onboarding-select-org-scripts: - hdx_theme/ckan - hdx_theme/onboarding-select-org-styles contents: + - base/hdx-util-lib.js - widget/onboarding/select-organisation.js onboarding-select-org-styles: @@ -1267,7 +1268,7 @@ organization-light-styles: - hdx_theme/dataset-search-styles - hdx_theme/dataset-styles contents: - - search-styles + - search-styles - light/organization/org-light.css organization-members-scripts: @@ -1405,7 +1406,7 @@ contact-contributor-scripts: - hdx_theme/ckan - hdx_theme/contact-contributor-styles contents: - - https://www.google.com/recaptcha/api.js + - https://www.google.com/recaptcha/api.js - widget/membership/contact-contributor.js contact-contributor-styles: diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/faq/faq.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/faq/faq.js index 4897b8bc78..bdc4f057dd 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/faq/faq.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/faq/faq.js @@ -79,7 +79,12 @@ $(document).ready(function(){ var analyticsPromise = hdxUtil.analytics.sendMessagingEvent('faq', 'faq', $this.find('select[name="topic"]').val(), null, false); - var postPromise = $.post('/faq/contact_us', $this.serialize()); + var postPromise = $.ajax({ + url: '/faq/contact_us', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + }); $.when(postPromise, analyticsPromise).then( function (postData, analyticsData) { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/contact-contributor.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/contact-contributor.js index bb8bb4da70..f916c2e739 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/contact-contributor.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/contact-contributor.js @@ -10,7 +10,12 @@ $(document).ready(function(){ var analyticsPromise = hdxUtil.analytics.sendMessagingEvent('dataset', 'contact contributor', $this.find('select[name="topic"]').val(), null, true); - var postPromise = $.post('/membership/contact_contributor', $this.serialize()); + var postPromise = $.ajax({ + url: '/membership/contact_contributor', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + }); $.when(postPromise, analyticsPromise).then( function (postData, analyticsData) { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/group-message.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/group-message.js index cb8b713cf8..9d319beefe 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/group-message.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/membership/group-message.js @@ -18,7 +18,12 @@ $(document).ready(function(){ var analyticsPromise = hdxUtil.analytics.sendMessagingEvent('dataset', 'group message', null, $this.find('select[name="topic"]').val(), true); - var postPromise = $.post('/membership/contact_members', $this.serialize()); + var postPromise = $.ajax({ + url: '/membership/contact_members', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + }); $.when(postPromise, analyticsPromise).then( function (postData, analyticsData) { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/follow.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/follow.js index 8379b88890..4dcb6d8695 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/follow.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/follow.js @@ -49,13 +49,20 @@ $(document).ready(function(){ $('#follow-form-item-loading').hide(); $('#follow-form').on("submit", function(){ $this = $(this); - $.post('/user/follow_details', $this.serialize(), function(result_data){ + $.ajax({ + url: '/user/follow_details', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result_data) { var result = JSON.parse(result_data); - if (result.success){ - closeCurrentWidget($this);showOnboardingWidget('#selectOrgPopup'); + if (result.success) { + closeCurrentWidget($this); + showOnboardingWidget('#selectOrgPopup'); } else { - alert("Can't follow org: " + result.error.message); + alert("Can't follow org: " + result.error.message); } + } }); return false; }); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/invite.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/invite.js index 5fdc1e6ff1..af6ca57505 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/invite.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/invite.js @@ -1,14 +1,22 @@ $(document).ready(function(){ $('#invite-form').on('submit', function(){ $this = $(this); - $.post('/user/invite_friends', $this.serialize(), function(result_data){ - var result = JSON.parse(result_data); - if (result.success){ - closeCurrentWidget($this);showOnboardingWidget('#donePopup'); - } else { - alert("Can't invite friends: " + result.error.message); - } - }); + $.ajax({ + url: '/user/invite_friends', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result_data) { + var result = JSON.parse(result_data); + if (result.success) { + closeCurrentWidget($this); + showOnboardingWidget('#donePopup'); + } else { + alert("Can't invite friends: " + result.error.message); + } + } + }); + return false; }); -}); \ No newline at end of file +}); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/onboarding.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/onboarding.css index 43498c7455..9c59a297ec 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/onboarding.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/onboarding.css @@ -202,7 +202,7 @@ letter-spacing: 0.01em; } .popup.popup-onboarding .footer-hdx-logo { - height: 30px; + height: 26px; } .popup.popup-onboarding .back-button { display: block; diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/recover.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/recover.js index 393f75589b..a84788cc1f 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/recover.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/recover.js @@ -3,16 +3,23 @@ $(document).ready(function(){ $recoverForm.on("submit", function () { $this = $(this); - $.post("/user/reset", $this.serialize(), function (result_data) { + $.ajax({ + url: "/user/reset", + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result_data) { var result = JSON.parse(result_data); if (result.success) { - closeCurrentWidget($this); showOnboardingWidget('#recoverSuccessPopup'); + closeCurrentWidget($this); + showOnboardingWidget('#recoverSuccessPopup'); } else { - var errMsg = $("#recoverPopup").find(".error-message"); - errMsg.text(result.error.message); - $("#field-recover-id").addClass("error"); - errMsg.show(); + var errMsg = $("#recoverPopup").find(".error-message"); + errMsg.text(result.error.message); + $("#field-recover-id").addClass("error"); + errMsg.show(); } + } }); return false; diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/register.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/register.js index 8b8ca5d846..c44d4bbdee 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/register.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/register.js @@ -7,22 +7,28 @@ $(document).ready(function(){ $this = $(this); $iframe = $($(".g-recaptcha").find("iframe:first")); $iframe.css("border", ""); - $.post("/user/register_details", $this.serialize(), function (result_data) { + $.ajax({ + url: "/user/register_details", + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result_data) { var result = JSON.parse(result_data); if (result.success) { - $this.unbind("submit"); - $this.attr("action", "/user/login?came_from=/dataset"); - hdxUtil.analytics.sendUserRegisteredEvent("user register").then(function(){ - $this.submit(); - }); + $this.unbind("submit"); + $this.attr("action", "/user/login?came_from=/dataset"); + hdxUtil.analytics.sendUserRegisteredEvent("user register").then(function () { + $this.submit(); + }); } else { - if (result.error.message == "Captcha is not valid"){ - $iframe.css("border", "1px solid red"); - } else { - alert("Can't register: " + result.error.message); - // grecaptcha.reset(); - } + if (result.error.message == "Captcha is not valid") { + $iframe.css("border", "1px solid red"); + } else { + alert("Can't register: " + result.error.message); + // grecaptcha.reset(); + } } + } }); return false; diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/select-organisation.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/select-organisation.js index 7cc4d5acce..aea76f5587 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/select-organisation.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/select-organisation.js @@ -20,34 +20,45 @@ $(document).ready(function(){ $selectOrgForm.on('submit', function(){ $this = $(this); - $.post('/user/request_membership', $this.serialize(), function(result_data){ + $.ajax({ + url: '/user/request_membership', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result_data) { var result = JSON.parse(result_data); $sel = $($("#select-organisation-form .select2-container.mTop20.required").find("a:first")); $sel.css("border", ""); - if (result.success){ - closeCurrentWidget($this); - let skipNext = false; - if ($this.attr('skipNext') === 'true') { - $this.removeAttr('skipNext'); - skipNext = true; - } - if (!skipNext) { - $selectOrgForm[0].reset(); - showOnboardingWidget('#invitePopup'); - } + if (result.success) { + closeCurrentWidget($this); + let skipNext = false; + if ($this.attr('skipNext') === 'true') { + $this.removeAttr('skipNext'); + skipNext = true; + } + if (!skipNext) { + $selectOrgForm[0].reset(); + showOnboardingWidget('#invitePopup'); + } } else { - alert("Can't join org: " + result.error.message); - $sel.css("border", "1px solid red"); + alert("Can't join org: " + result.error.message); + $sel.css("border", "1px solid red"); } + } }); return false; }); $createOrgForm.on('submit', function(){ $this = $(this); - $.post('/user/request_new_organization', $this.serialize(), function(result_data){ + $.ajax({ + url: '/user/request_new_organization', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result_data) { var result = JSON.parse(result_data); - if (result.success){ + if (result.success) { let skipNext = false; if ($this.attr('skipNext') === 'true') { $this.removeAttr('skipNext'); @@ -55,12 +66,13 @@ $(document).ready(function(){ } $createOrgForm[0].reset(); closeCurrentWidget($this); - if(!skipNext && $('#user_extra').val() === 'True'){ + if (!skipNext && $('#user_extra').val() === 'True') { showOnboardingWidget('#invitePopup'); } } else { - alert("Can't create org: " + result.error.message); + alert("Can't create org: " + result.error.message); } + } }); return false; }); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/signup.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/signup.js index 6035c44c4b..27a433730f 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/signup.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/onboarding/signup.js @@ -12,44 +12,50 @@ $(document).ready(function(){ 'g-recaptcha-response': grecaptcha.getResponse() }; - $.post(url, data, function(result_data){ + $.ajax({ + url: url, + type: 'POST', + data: data, + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (result_data) { var result = JSON.parse(result_data); console.log(result); - if (result.success){ - hdxUtil.analytics.sendUserRegisteredEvent("submit email register").then(function() { - //check for newsletter - we're moving the registration to the backend - // if ($("#signup-send-updates").is(":checked")){ - // console.log("Attempt to register to newsletter!"); - // $.ajax({ - // url: "//unocha.us2.list-manage.com/subscribe/post-json", - // dataType: "jsonp", - // jsonp: "c", - // data: { - // u: "83487eb1105d72ff2427e4bd7", - // id: "6fd988326c", - // EMAIL: email, - // subscribe: "Subscribe", - // _: Date.now() - // }, - // success: function(result){ - // if (result.result == "success") - // console.log("Registered to the newsletter!"); - // else - // console.log("Error:" + JSON.stringify(result)); - // } - // }); - // } + if (result.success) { + hdxUtil.analytics.sendUserRegisteredEvent("submit email register").then(function () { + //check for newsletter - we're moving the registration to the backend + // if ($("#signup-send-updates").is(":checked")){ + // console.log("Attempt to register to newsletter!"); + // $.ajax({ + // url: "//unocha.us2.list-manage.com/subscribe/post-json", + // dataType: "jsonp", + // jsonp: "c", + // data: { + // u: "83487eb1105d72ff2427e4bd7", + // id: "6fd988326c", + // EMAIL: email, + // subscribe: "Subscribe", + // _: Date.now() + // }, + // success: function(result){ + // if (result.result == "success") + // console.log("Registered to the newsletter!"); + // else + // console.log("Error:" + JSON.stringify(result)); + // } + // }); + // } - $("#verifyPopup").find(".verify-email").html(email); - closeCurrentWidget($(".signup-widget:first")); - showOnboardingWidget('#verifyPopup'); - }); + $("#verifyPopup").find(".verify-email").html(email); + closeCurrentWidget($(".signup-widget:first")); + showOnboardingWidget('#verifyPopup'); + }); } else { - var errMsg = $signupForm.find(".error-message"); - errMsg.text(result.error.message); - $("#field-email").addClass("error"); - errMsg.show(); + var errMsg = $signupForm.find(".error-message"); + errMsg.text(result.error.message); + $("#field-email").addClass("error"); + errMsg.show(); } + } }); } grecaptcha.reset(); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/security/popup-security.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/security/popup-security.js index edb3608833..e260ddd1cc 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/security/popup-security.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/security/popup-security.js @@ -9,10 +9,15 @@ $(document).ready(function() { msgContainer.removeClass('alert-success'); msgContainer.removeClass('alert-danger'); - $.post(`/user/configure_mfa/${userName}`, body) - .done((response) => { + $.ajax({ + url: `/user/configure_mfa/${userName}`, + type: 'POST', + headers: hdxUtil.net.getCsrfTokenAsObject(), + contentType: 'application/json', + data: JSON.stringify(body), + success: function (response) { const result = JSON.parse(response); - if (result.success == true){ + if (result.success == true) { msgContainer.html('Code is valid, two-step verification is configured correctly!'); msgContainer.addClass('alert-success'); msgContainer.show(); @@ -25,11 +30,12 @@ $(document).ready(function() { msgContainer.addClass('alert-danger'); msgContainer.show(); } - }) - .fail((result) => { + }, + error: function () { msgContainer.html('Error while attempting test!'); msgContainer.addClass('alert-danger'); - }); + } + }); } function toggleTwoStep(on = false) { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/tags/request-tags.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/tags/request-tags.js index 31eac8b8e5..d2521148b1 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/tags/request-tags.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/widget/tags/request-tags.js @@ -106,7 +106,12 @@ $(document).ready(function () { } } - var postPromise = $.post('/request_tags/suggest', $this.serialize()); + var postPromise = $.ajax({ + url: '/request_tags/suggest', + type: 'POST', + data: $this.serialize(), + headers: hdxUtil.net.getCsrfTokenAsObject(), + }); $.when(postPromise).then( function (postData) { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-combined.png b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-combined.png index e9eef8e783..85c1c3ee57 100644 Binary files a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-combined.png and b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-combined.png differ diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-hdx.png b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-hdx.png index 698d5d67b9..7543bb0bb3 100644 Binary files a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-hdx.png and b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/images/homepage/logo-hdx.png differ diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/widget/onboarding/onboarding.less b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/widget/onboarding/onboarding.less index 100d0b8bae..767ff80428 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/widget/onboarding/onboarding.less +++ b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/widget/onboarding/onboarding.less @@ -181,7 +181,7 @@ } .footer-hdx-logo { - height: 30px; + height: 26px; } .back-button { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/scripts/application.js b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/scripts/application.js index f2a64bd599..79c8a8cda5 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/scripts/application.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/scripts/application.js @@ -1173,6 +1173,7 @@ CKAN.Utils = function($, my) { contentType: 'application/json', url: CKAN.SITE_URL + '/api/3/action/related_' + action, data: data ? JSON.stringify(data) : undefined, + headers: hdxUtil.net.getCsrfTokenAsObject(), error: function(err, txt, w) { // This needs to be far more informative. addAlert('Error: Unable to ' + action + ' related item'); @@ -1301,9 +1302,15 @@ CKAN.Utils = function($, my) { $target.addClass('depressed'); raw_markdown=textarea.val(); preview.html(""+CKAN.Strings.loading+""); - $.post(CKAN.SITE_URL + "/api/util/markdown", { q: raw_markdown }, - function(data) { preview.html(data); } - ); + $.ajax({ + url: CKAN.SITE_URL + "/api/util/markdown", + type: 'POST', + data: {q: raw_markdown}, + headers: hdxUtil.net.getCsrfTokenAsObject(), + success: function (data) { + preview.html(data); + } + }); preview.width(textarea.width()); preview.height(textarea.height()); textarea.hide(); @@ -1438,6 +1445,7 @@ CKAN.Utils = function($, my) { dataType: 'json', processData: false, type: 'POST', + headers: hdxUtil.net.getCsrfTokenAsObject(), success: function(data) { button.setAttribute('data-state', nextState); button.innerHTML = nextString; diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/hapi.py b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/hapi.py index bf4913f289..7318c1df99 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/hapi.py +++ b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/hapi.py @@ -3,7 +3,7 @@ 'HERO_SECTION_DESCRIPTION': '''HDX HAPI is in beta phase, and we are seeking feedback. To share your thoughts or join our slack channel, send an email to hdx@un.org.''', 'DATA_COVERAGE_SECTION_TITLE': '''Data Coverage''', - 'DATA_COVERAGE_SECTION_DESCRIPTION': '''Our initial coverage aligns with the data included in the HDX Data Grids, which places the most important crisis data into six categories and 10 sub-categories. Our beta version of HDX HAPI covers 44 indicators across 25 locations that have a Humanitarian Response Plan. This data has been shared by 9 different contributing organisations.''', + 'DATA_COVERAGE_SECTION_DESCRIPTION': '''Our initial coverage aligns with the data included in the HDX Data Grids, which places the most important crisis data into six categories and 20 sub-categories. Our beta version of HDX HAPI covers 44 indicators across 25 locations that have a Humanitarian Response Plan. This data has been shared by nine different contributing organisations.''', 'DATA_COVERAGE_SECTION_PARAGRAPH': '''Refer to the documentation for the latest coverage. Contact us to request additional indicators in future versions of HDX HAPI.''', 'BE_INSPIRED_SECTION_TITLE': '''Be Inspired''', @@ -12,7 +12,7 @@ 'BE_INSPIRED_CARD_TITLE_POWER_BI': '''Power BI workflow''', 'BE_INSPIRED_CARD_TEXT_POWER_BI': '''A tutorial to demonstrate how easy it is to bring in data.''', 'BE_INSPIRED_CARD_BUTTON_POWER_BI': '''Learn more''', - 'BE_INSPIRED_CARD_BUTTON_LINK_POWER_BI': '''https://docs.google.com/presentation/d/19HfMI9gnKXAMhe0SFZdbbUFesNnTnfeUI9rnshN2kkk/edit?usp=sharing''', + 'BE_INSPIRED_CARD_BUTTON_LINK_POWER_BI': '''https://drive.google.com/file/d/1EQ4UAshvFvpqmoifdBH0mJxKck7xoSGN/view''', 'BE_INSPIRED_CARD_TITLE_API': '''API Sandbox''', 'BE_INSPIRED_CARD_TEXT_API': '''A sandbox environment to help construct queries and get a data response.''', @@ -27,7 +27,7 @@ 'BE_INSPIRED_CARD_TITLE_CHATBOT': '''Chatbot''', 'BE_INSPIRED_CARD_TEXT_CHATBOT': '''An early stage AI chatbot developed with DataKind to ask questions about the data.''', 'BE_INSPIRED_CARD_BUTTON_CHATBOT': '''Learn more''', - 'BE_INSPIRED_CARD_BUTTON_LINK_CHATBOT': '''#''', + 'BE_INSPIRED_CARD_BUTTON_LINK_CHATBOT': '''https://www.datakind.org/our-domains/humanitarian-response/''', 'FAQ_SECTION_TITLE': '''FAQs''', @@ -85,7 +85,7 @@ }, { "category": "Population & Socio-economy", - "subcategory": "Population", + "subcategory": "Baseline Population", "contributor": "United Nations Population Fund (UNFPA) and OCHA offices", "link": "https://hdx-hapi.readthedocs.io/en/latest/data_usage_guides/population_and_socio-economy/#baseline-population" }, diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/signals.py b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/signals.py index 202cbb4157..b8b3b20538 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/signals.py +++ b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/landing_pages/signals.py @@ -3,13 +3,13 @@ 'HERO_SECTION_DESCRIPTION': '''We are seeking feedback. Please contact us at hdx-signals@un.org''', 'DATA_COVERAGE_SECTION_TITLE': '''Data Coverage''', - 'DATA_COVERAGE_SECTION_DESCRIPTION': '''Datasets monitored by HDX signals at the moment are as follows:''', + 'DATA_COVERAGE_SECTION_DESCRIPTION': '''Datasets monitored by HDX Signals at the moment are as follows:''', 'SIGNUP_SECTION_TITLE': '''Sign up''', - 'SIGNUP_SECTION_DESCRIPTION': '''Sign up below to receive HDX Signals emails. To receive the content you are interested in, please make sure you have selected AT LEAST ONE dataset and region or priority humanitarian location from the options below.''', + 'SIGNUP_SECTION_DESCRIPTION': '''Sign up below to receive HDX Signals emails. To receive the content you are interested in, please make sure you have selected AT LEAST ONE dataset and region or priority humanitarian location from the options below. All locations in a region include all locations covered by the datasets, not just priority humanitarian locations listed below.''', 'RESOURCES_SECTION_TITLE': '''Resources''', - 'RESOURCES_SECTION_DESCRIPTION': '''For more information about the datasets monitored by HDX signals as well as information for developers see the following:''', + 'RESOURCES_SECTION_DESCRIPTION': '''For more information about the datasets monitored by HDX Signals as well as information for developers see the following:''', 'RESOURCES_SECTION_PARAGRAPH': '''For more information, please contact us at hdx-signals@un.org.''', 'RESOURCES_CARD_TITLE_MAP': '''Signals Map''', @@ -25,7 +25,7 @@ 'RESOURCES_CARD_TITLE_METHODOLOGY': '''Methodology''', 'RESOURCES_CARD_TEXT_METHODOLOGY': '''Read the HDX Signals methodology''', 'RESOURCES_CARD_BUTTON_METHODOLOGY': '''Learn more''', - 'RESOURCES_CARD_BUTTON_LINK_METHODOLOGY': '''https://github.com/OCHA-DAP/hdx-signals''', + 'RESOURCES_CARD_BUTTON_LINK_METHODOLOGY': '''https://un-ocha-centre-for-humanitarian.gitbook.io/hdx-signals''', 'RESOURCES_CARD_TITLE_REPOSITORY': '''Code Respository''', 'RESOURCES_CARD_TEXT_REPOSITORY': '''Access the HDX Signals code repository''', @@ -61,7 +61,7 @@ { "title": "Market monitoring", "organization": "World Food Programme (WFP)", - "link": "https://data.humdata.org/datasets/global-market-monitor" + "link": "https://data.humdata.org/dataset/global-market-monitor" }, ] diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/__init__.py b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/__init__.py index f014d2a4d0..7c2eca3aae 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/__init__.py +++ b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/__init__.py @@ -1,6 +1,7 @@ from ckanext.hdx_theme.helpers.ui_constants.onboarding.user_info import CONSTANTS as USER_INFO_CONSTANTS from ckanext.hdx_theme.helpers.ui_constants.onboarding.value_proposition import CONSTANTS as VALUE_PROPOSITION_CONSTANTS from ckanext.hdx_theme.helpers.ui_constants.onboarding.verify_email import CONSTANTS as VERIFY_EMAIL_CONSTANTS +from ckanext.hdx_theme.helpers.ui_constants.onboarding.change_email import CONSTANTS as CHANGE_EMAIL_CONSTANTS from ckanext.hdx_theme.helpers.ui_constants.onboarding.account_validated import CONSTANTS as ACCOUNT_VALIDATED_CONSTANTS from ckanext.hdx_theme.helpers.ui_constants.onboarding.request_join_organisation import CONSTANTS as REQUEST_JOIN_ORGANISATION_CONSTANTS from ckanext.hdx_theme.helpers.ui_constants.onboarding.confirm_organisation_choice import CONSTANTS as CONFIRM_ORGANISATION_CHOICE_CONSTANTS @@ -15,6 +16,7 @@ 'USER_INFO': USER_INFO_CONSTANTS, 'VALUE_PROPOSITION': VALUE_PROPOSITION_CONSTANTS, 'VERIFY_EMAIL': VERIFY_EMAIL_CONSTANTS, + 'CHANGE_EMAIL': CHANGE_EMAIL_CONSTANTS, 'ACCOUNT_VALIDATED': ACCOUNT_VALIDATED_CONSTANTS, 'REQUEST_JOIN_ORGANISATION': REQUEST_JOIN_ORGANISATION_CONSTANTS, 'CONFIRM_ORGANISATION_CHOICE': CONFIRM_ORGANISATION_CHOICE_CONSTANTS, diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/change_email.py b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/change_email.py new file mode 100644 index 0000000000..cb4ec111a0 --- /dev/null +++ b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/change_email.py @@ -0,0 +1,18 @@ +from ckanext.hdx_theme.helpers.ui_constants.onboarding.user_info import CONSTANTS as USER_INFO_CONSTANTS + +CONSTANTS = { + 'STEPS_1': USER_INFO_CONSTANTS['STEPS_1'], + 'STEPS_2': USER_INFO_CONSTANTS['STEPS_2'], + 'STEPS_3': USER_INFO_CONSTANTS['STEPS_3'], + + 'PAGE_TITLE': '''Re-enter your email address''', + + 'INPUT_EMAIL_LABEL': '''Enter your email address''', + 'INPUT_EMAIL_PLACEHOLDER': USER_INFO_CONSTANTS['INPUT_EMAIL_PLACEHOLDER'], + 'INPUT_EMAIL_ERROR': USER_INFO_CONSTANTS['INPUT_EMAIL_ERROR'], + 'INPUT_EMAIL2_LABEL': USER_INFO_CONSTANTS['INPUT_EMAIL2_LABEL'], + 'INPUT_EMAIL2_PLACEHOLDER': USER_INFO_CONSTANTS['INPUT_EMAIL2_PLACEHOLDER'], + 'INPUT_EMAIL2_ERROR': USER_INFO_CONSTANTS['INPUT_EMAIL2_ERROR'], + + 'BUTTON_SUBMIT': '''Next''', +} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/verify_email.py b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/verify_email.py index 1ef9bf23f1..7f9a5280dd 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/verify_email.py +++ b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/onboarding/verify_email.py @@ -7,5 +7,7 @@ 'PAGE_TITLE': '''Verify your email address''', 'BODY_MAIN_TEXT': '''We have sent an email to {0} so that you can verify your email address. If you don’t see the email, please check your spam or junk folder.''', - 'BODY_MAIN_TEXT_WITHOUT_EMAIL': '''We have sent an email so that you can verify your email address. If you don’t see the email, please check your spam or junk folder.''' + 'BODY_MAIN_TEXT_WITHOUT_EMAIL': '''We have sent an email so that you can verify your email address. If you don’t see the email, please check your spam or junk folder.''', + + 'CHANGE_EMAIL_TEXT': '''If you need to change your email address, click here''', } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/public/scripts/application.js b/ckanext-hdx_theme/ckanext/hdx_theme/public/scripts/application.js index f2a64bd599..63e3d349f8 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/public/scripts/application.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/public/scripts/application.js @@ -1173,6 +1173,7 @@ CKAN.Utils = function($, my) { contentType: 'application/json', url: CKAN.SITE_URL + '/api/3/action/related_' + action, data: data ? JSON.stringify(data) : undefined, + headers: hdxUtil.net.getCsrfTokenAsObject(), error: function(err, txt, w) { // This needs to be far more informative. addAlert('Error: Unable to ' + action + ' related item'); @@ -1301,9 +1302,15 @@ CKAN.Utils = function($, my) { $target.addClass('depressed'); raw_markdown=textarea.val(); preview.html(""+CKAN.Strings.loading+""); - $.post(CKAN.SITE_URL + "/api/util/markdown", { q: raw_markdown }, - function(data) { preview.html(data); } - ); + $.ajax({ + url: CKAN.SITE_URL + "/api/util/markdown", + type: 'POST', + headers: hdxUtil.net.getCsrfTokenAsObject(), + data: {q: raw_markdown}, + success: function (data) { + preview.html(data); + } + }); preview.width(textarea.width()); preview.height(textarea.height()); textarea.hide(); @@ -1438,6 +1445,7 @@ CKAN.Utils = function($, my) { dataType: 'json', processData: false, type: 'POST', + headers: hdxUtil.net.getCsrfTokenAsObject(), success: function(data) { button.setAttribute('data-state', nextState); button.innerHTML = nextString; diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/admin/all_requests_data.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/admin/all_requests_data.html index fef54eab6d..d79ee18a0d 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/admin/all_requests_data.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/admin/all_requests_data.html @@ -6,7 +6,7 @@ {% asset 'requestdata/main-styles' %} {% asset 'hdx_theme/requestdata-styles' %} {% asset 'hdx_theme/search-styles' %} - + {% asset 'hdx_theme/dataset-search-styles' %} {% endblock %} {% block primary_content_module_margin %}{% endblock %} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reject_request_form.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reject_request_form.html index dd34ce88e3..79ba5591d1 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reject_request_form.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reject_request_form.html @@ -34,6 +34,7 @@ Decline the request
+ {{ h.csrf_input() }}
diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reply_request_form.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reply_request_form.html index d27020bbc1..6d0bb17572 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reply_request_form.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/reply_request_form.html @@ -33,6 +33,7 @@ Reply to this request + {{ h.csrf_input() }}
diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/request_contact.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/request_contact.html index 16cad4ba58..a22dcdbccf 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/request_contact.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/ajax_snippets/request_contact.html @@ -26,6 +26,7 @@ Dataset {{ package_name }} + {{ h.csrf_input() }} {% if pending_request %}
{{ _('You already have a pending request. Please wait for the reply.') }}
{% else %} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/contribute_flow/create_edit.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/contribute_flow/create_edit.html index 9bddfcb749..7ebbaf8dfe 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/contribute_flow/create_edit.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/contribute_flow/create_edit.html @@ -164,6 +164,7 @@ {% endif %} + {{ h.csrf_input() }} {% if data.is_requestdata_type %} {% endif %} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/email/email.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/email/email.html index f1bc0506d6..f45cc3a08f 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/email/email.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/email/email.html @@ -77,7 +77,7 @@ } .hdx-email .hdx-logo img { - width: 136px; + width: 110px; height: auto; display: block; } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/faq_others/faq/search.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/faq_others/faq/search.html index 92b3bbb7fd..8ce55cdec1 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/faq_others/faq/search.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/faq_others/faq/search.html @@ -4,7 +4,7 @@ {% asset 'hdx_theme/faq-scripts' %}
diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/bulk_process.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/bulk_process.html index 936ed7d00d..c90bd84fb5 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/bulk_process.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/bulk_process.html @@ -26,6 +26,7 @@

{% block form %} {% if c.page.item_count %}
+ {{ h.csrf_input() }} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/members.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/members.html index 184d5cbece..44a59bf509 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/members.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/members.html @@ -198,6 +198,7 @@
+ {{ h.csrf_input() }}
Add / invite colleagues to this organisation
diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/snippets/add_member.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/snippets/add_member.html index 3cc3240cd8..83a124cf8f 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/snippets/add_member.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/organization/snippets/add_member.html @@ -9,6 +9,7 @@ {% asset 'hdx_theme/hdx-autocomplete' %} + {{ h.csrf_input() }}
@@ -99,6 +100,7 @@

{{ _('Datasets in this showcase') }}

{% if c.showcase_pkgs %} + {{ h.csrf_input() }}
diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/showcase/new_package_form.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/showcase/new_package_form.html index 78a82be33d..990bc3f9c6 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/showcase/new_package_form.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/showcase/new_package_form.html @@ -1,8 +1,12 @@ {% import 'macros/form.html' as form %} {% set action = c.form_action or '' %} -{% set form_style = c.form_style or c.action %} +{#{% set form_style = c.form_style or c.action %}#} +{% set form_style = g.view %} +{% set showcase_read_route = 'showcase_blueprint.read' %} +{% set showcase_delete_route = 'showcase_blueprint.delete' %} + {{ h.csrf_input() }} {# pkg_name used in 3 stage edit #} @@ -16,8 +20,8 @@ {% endblock %} {% block package_basic_fields_url %} - {% set prefix = h.url_for('showcase_blueprint.read', id='') %} - {% set domain = h.url_for('showcase_blueprint.read', id='', qualified=true) %} + {% set prefix = h.url_for(showcase_read_route, id='') %} + {% set domain = h.url_for(showcase_read_route, id='', qualified=true) %} {% set domain = domain|replace("http://", "")|replace("https://", "") %} {% set attrs = {'data-module': 'slug-preview-slug', 'data-module-prefix': domain, 'data-module-placeholder': ''} %} @@ -96,7 +100,7 @@ {% block delete_button %} {% if form_style == 'edit' and h.check_access('ckanext_showcase_delete', {'id': data.id}) and not data.state == 'deleted' %} {% set locale = h.dump_json({'content': _('Are you sure you want to delete this showcase?')}) %} - {% block delete_button_text %}{{ _('Delete') }}{% endblock %} + {% block delete_button_text %}{{ _('Delete') }}{% endblock %} {% endif %} {% endblock %} {% block save_button %} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/snippets/confirmation_post.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/snippets/confirmation_post.html index 506ff50f75..2591cb2fb3 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/snippets/confirmation_post.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/snippets/confirmation_post.html @@ -12,6 +12,7 @@