From 4bb192879ed61b0b085b3aba5a1d5d373ff72db3 Mon Sep 17 00:00:00 2001
From: Kiril Kartunov
Date: Wed, 29 Jan 2025 09:28:51 +0200
Subject: [PATCH] Revert "[PROD] Security fixes - release"
---
.circleci/config.yml | 59 +-
Dockerfile | 6 +-
.../Account/__snapshots__/index.jsx.snap | 2132 ++++++++++++
.../components/Settings/Account/index.jsx | 32 +
.../Header/__snapshots__/index.jsx.snap | 33 +
.../components/Settings/Header/index.jsx | 17 +
.../Email/__snapshots__/index.jsx.snap | 20 +
.../Settings/Preferences/Email/index.jsx | 11 +
.../Settings/__mocks__/profile-state.json | 593 ++++
.../Settings/__mocks__/props-match.json | 8 +
.../Settings/__mocks__/user-profile.json | 81 +
.../Settings/__snapshots__/index.jsx.snap | 3042 +++++++++++++++++
.../shared/components/Settings/index.jsx | 83 +
.../Sidebar/__snapshots__/Footer.jsx.snap | 2 +-
.../tc-communities/NewsletterSignup.jsx | 72 +
.../__snapshots__/NewsletterSignup.jsx.snap | 47 +
.../community-2/__snapshots__/Learn.jsx.snap | 14 +
.../demo-expert/__snapshots__/Learn.jsx.snap | 14 +
.../taskforce/__snapshots__/Home.jsx.snap | 14 +
.../tc-prod-dev/__snapshots__/Learn.jsx.snap | 14 +
.../utils/__snapshots__/markdown.js.snap | 4 +-
automated-smoke-test/Dockerfile | 32 +
.../config/automation-config-dev.json | 1 +
.../config/automation-config-local.json | 1 +
.../config/automation-config-prod.json | 1 +
automated-smoke-test/test-data/test-data.json | 3 +-
config/default.js | 4 +-
docs/contentful/AppComponent.md | 2 +
...om-inline-components-in-markdown-fields.md | 24 +
docs/pwa/nginx/server.key | 28 +
docs/swagger.yaml | 196 ++
package.json | 7 +-
src/server/index.js | 63 +-
src/server/routes/blog.js | 20 +
src/server/routes/contentful.js | 109 +-
src/server/routes/feeds.js | 1 -
src/server/routes/gSheet.js | 21 +
src/server/routes/mailchimp.js | 34 +
src/server/services/blog.js | 32 +
src/server/services/communities.js | 72 +-
src/server/services/contentful.js | 2 -
src/server/services/gSheet.js | 135 +
src/server/services/mailchimp.js | 111 +
src/server/services/mmLeaderboard.js | 6 +-
src/server/services/recruitCRM.js | 10 +-
src/shared/actions/newsletterArchive.js | 60 +
src/shared/actions/newsletterPreferences.js | 110 +
.../Contentful/AppComponent/index.jsx | 4 +
.../components/Contentful/Article/Article.jsx | 2 +-
.../Contentful/PasswordScreen/index.jsx | 110 +
.../Contentful/PasswordScreen/style.scss | 51 +
src/shared/components/Contentful/Route.jsx | 16 +-
src/shared/components/Gigs/GigApply/index.jsx | 6 +-
.../components/Gigs/GigDetails/index.jsx | 5 +
.../components/NewsletterArchive/index.jsx | 118 +
.../components/NewsletterArchive/style.scss | 114 +
.../components/NewsletterSignup/index.jsx | 193 ++
.../components/NewsletterSignup/style.scss | 108 +
.../ConfirmModal/index.jsx | 139 +
.../ConfirmModal/style.scss | 41 +
.../NewsletterSignupForMembers/index.jsx | 179 +
.../NewsletterSignupForMembers/modal.scss | 51 +
.../NewsletterSignupForMembers/style.scss | 27 +
.../components/Settings/Accordion/index.jsx | 131 +
.../components/Settings/Accordion/styles.scss | 42 +
.../Account/LinkedAccount/AddWebLink.jsx | 234 ++
.../Account/LinkedAccount/ExistingLink.jsx | 286 ++
.../Account/LinkedAccount/ExistingLinks.jsx | 145 +
.../Account/LinkedAccount/LinkAccounts.jsx | 125 +
.../Account/LinkedAccount/SocialIcons.jsx | 20 +
.../Settings/Account/LinkedAccount/index.jsx | 194 ++
.../Settings/Account/LinkedAccount/modal.scss | 114 +
.../Account/LinkedAccount/styles.scss | 907 +++++
.../EmailVerifiResult/AlmostDone/index.jsx | 61 +
.../EmailVerifiResult/AlmostDone/styles.scss | 50 +
.../EmailVerifiResult/Failed/index.jsx | 55 +
.../EmailVerifiResult/Failed/styles.scss | 88 +
.../EmailVerifiResult/Success/index.jsx | 39 +
.../EmailVerifiResult/Success/styles.scss | 46 +
.../MyAccount/EmailVerifiResult/mixins.scss | 68 +
.../Settings/Account/MyAccount/index.jsx | 711 ++++
.../Settings/Account/MyAccount/styles.scss | 795 +++++
.../MyPrimaryRole/FormInputRadio/index.jsx | 43 +
.../MyPrimaryRole/FormInputRadio/styles.scss | 104 +
.../Settings/Account/MyPrimaryRole/index.jsx | 103 +
.../Account/MyPrimaryRole/styles.scss | 254 ++
.../Settings/Account/Security/Modal/index.jsx | 80 +
.../Account/Security/Modal/style.scss | 162 +
.../Security/VerificationListener/index.jsx | 32 +
.../Settings/Account/Security/index.jsx | 430 +++
.../Settings/Account/Security/styles.scss | 300 ++
.../components/Settings/Account/index.jsx | 103 +
.../components/Settings/Account/styles.scss | 76 +
.../components/Settings/ComingSoon/index.jsx | 11 +
.../Settings/ComingSoon/styles.scss | 15 +
.../Settings/ConfirmationModal/index.jsx | 45 +
.../Settings/ConfirmationModal/styles.scss | 191 ++
.../Settings/ConsentComponent/index.jsx | 86 +
.../Settings/ErrorMessage/index.jsx | 30 +
.../Settings/ErrorMessage/styles.scss | 25 +
.../Settings/ErrorWrapper/index.jsx | 45 +
.../Settings/ErrorWrapper/styles.scss | 9 +
.../WorkplaceList/Item/index.jsx | 117 +
.../WorkplaceList/Item/styles.scss | 207 ++
.../WorkExperience/WorkplaceList/index.jsx | 36 +
.../WorkExperience/WorkplaceList/styles.scss | 19 +
.../WorkExperience/index.jsx | 606 ++++
.../WorkExperience/styles.scss | 139 +
.../WorkSkills/Interests/index.jsx | 242 ++
.../WorkSkills/Interests/styles.scss | 113 +
.../WorkSkills/Languages/List/Item/index.jsx | 138 +
.../Languages/List/Item/styles.scss | 211 ++
.../WorkSkills/Languages/List/index.jsx | 41 +
.../WorkSkills/Languages/List/styles.scss | 26 +
.../WorkSkills/Languages/dropdowns.json | 782 +++++
.../WorkSkills/Languages/index.jsx | 482 +++
.../WorkSkills/Languages/styles.scss | 109 +
.../Skills/AddSkillsModal/index.jsx | 140 +
.../Skills/AddSkillsModal/styles.scss | 270 ++
.../WorkSkills/Skills/index.jsx | 444 +++
.../WorkSkills/Skills/styles.scss | 218 ++
.../ExperienceAndSkills/WorkSkills/index.jsx | 35 +
.../WorkSkills/styles.scss | 33 +
.../Settings/ExperienceAndSkills/index.jsx | 121 +
.../Settings/ExperienceAndSkills/styles.scss | 46 +
.../{Form => Settings}/FormField/index.jsx | 0
.../{Form => Settings}/FormField/styles.scss | 0
.../FormInputCheckbox/index.jsx | 0
.../FormInputCheckbox/styles.scss | 0
.../FormInputDatePicker/index.jsx | 0
.../FormInputDatePicker/styles.scss | 0
.../FormInputSelect/index.jsx | 0
.../FormInputSelect/styles.scss | 0
.../FormInputText/index.jsx | 0
.../FormInputText/styles.scss | 0
.../FormInputTextArea/index.jsx | 0
.../FormInputTextArea/styles.scss | 0
.../components/Settings/Header/index.jsx | 31 +
.../components/Settings/Header/styles.scss | 44 +
.../components/Settings/PageRow/index.jsx | 42 +
.../components/Settings/PageRow/styles.scss | 47 +
.../Settings/Payment/EmailDetails/index.jsx | 47 +
.../Settings/Payment/EmailDetails/styles.scss | 43 +
.../Settings/Payment/PaymentInfo/index.jsx | 35 +
.../Settings/Payment/PaymentInfo/styles.scss | 64 +
.../Settings/Payment/PaymentMethod/index.jsx | 158 +
.../Payment/PaymentMethod/styles.scss | 392 +++
.../Payment/PaymentProvider/index.jsx | 221 ++
.../Payment/PaymentProvider/styles.scss | 327 ++
.../components/Settings/Payment/constants.js | 123 +
.../components/Settings/Payment/index.jsx | 63 +
.../components/Settings/Payment/styles.scss | 119 +
.../Settings/Preferences/Email/data.jsx | 20 +
.../Settings/Preferences/Email/index.jsx | 199 ++
.../Settings/Preferences/Email/styles.scss | 102 +
.../Settings/Preferences/List/Item/index.jsx | 80 +
.../Preferences/List/Item/styles.scss | 166 +
.../Settings/Preferences/List/data.jsx | 15 +
.../Settings/Preferences/List/index.jsx | 43 +
.../Preferences/Personalization/index.jsx | 82 +
.../Preferences/Personalization/styles.scss | 15 +
.../components/Settings/Preferences/index.jsx | 113 +
.../Settings/Preferences/styles.scss | 83 +
.../ProfileSettings/AboutYou/index.jsx | 75 +
.../Hobbies/List/Item/index.jsx | 111 +
.../Hobbies/List/Item/styles.scss | 193 ++
.../ProfileSettings/Hobbies/List/index.jsx | 41 +
.../ProfileSettings/Hobbies/List/styles.scss | 30 +
.../ProfileSettings/Hobbies/index.jsx | 127 +
.../ProfileSettings/Hobbies/styles.scss | 324 ++
.../ProfileSettings/ImageInput/index.jsx | 154 +
.../ProfileSettings/ImageInput/styles.scss | 134 +
.../Learning/List/Item/index.jsx | 176 +
.../Learning/List/Item/styles.scss | 211 ++
.../ProfileSettings/Learning/List/index.jsx | 41 +
.../ProfileSettings/Learning/List/styles.scss | 30 +
.../ProfileSettings/Learning/index.jsx | 219 ++
.../ProfileSettings/Learning/styles.scss | 468 +++
.../ProfileSettings/PersonalDetails/index.jsx | 240 ++
.../Settings/ProfileSettings/index.jsx | 1212 +++++++
.../Settings/ProfileSettings/styles.scss | 170 +
.../Settings/SettingsBanner/index.jsx | 90 +
.../Settings/SettingsBanner/styles.scss | 65 +
.../Settings/SideBar/SideItem/index.jsx | 69 +
.../Settings/SideBar/SideItem/styles.scss | 61 +
.../components/Settings/SideBar/index.jsx | 46 +
.../components/Settings/SideBar/styles.scss | 21 +
.../components/Settings/TabSelector/index.jsx | 101 +
.../Settings/TabSelector/styles.scss | 126 +
.../Settings/ToggleableItem/index.jsx | 99 +
.../Settings/ToggleableItem/styles.scss | 52 +
.../Tools/Devices/List/Item/index.jsx | 114 +
.../Tools/Devices/List/Item/styles.scss | 209 ++
.../Settings/Tools/Devices/List/index.jsx | 54 +
.../Settings/Tools/Devices/List/styles.scss | 32 +
.../Settings/Tools/Devices/index.jsx | 615 ++++
.../Settings/Tools/Devices/styles.scss | 110 +
.../ServiceProviders/List/Item/index.jsx | 96 +
.../ServiceProviders/List/Item/styles.scss | 209 ++
.../Tools/ServiceProviders/List/index.jsx | 47 +
.../Tools/ServiceProviders/List/styles.scss | 32 +
.../Tools/ServiceProviders/dropdowns.json | 24 +
.../Settings/Tools/ServiceProviders/index.jsx | 421 +++
.../Tools/ServiceProviders/styles.scss | 117 +
.../Tools/Software/List/Item/index.jsx | 96 +
.../Tools/Software/List/Item/styles.scss | 209 ++
.../Settings/Tools/Software/List/index.jsx | 44 +
.../Settings/Tools/Software/List/styles.scss | 27 +
.../Settings/Tools/Software/dropdowns.json | 24 +
.../Settings/Tools/Software/index.jsx | 427 +++
.../Settings/Tools/Software/styles.scss | 110 +
.../Tools/Subscriptions/List/Item/index.jsx | 92 +
.../Tools/Subscriptions/List/Item/styles.scss | 215 ++
.../Tools/Subscriptions/List/index.jsx | 44 +
.../Tools/Subscriptions/List/styles.scss | 32 +
.../Settings/Tools/Subscriptions/index.jsx | 387 +++
.../Settings/Tools/Subscriptions/styles.scss | 111 +
.../components/Settings/Tools/index.jsx | 139 +
.../components/Settings/Tools/styles.scss | 67 +
.../TopcoderAndYou/Community/Item/index.jsx | 90 +
.../TopcoderAndYou/Community/Item/styles.scss | 177 +
.../TopcoderAndYou/Community/data.jsx | 32 +
.../TopcoderAndYou/Community/index.jsx | 56 +
.../TopcoderAndYou/Community/styles.scss | 60 +
.../TopcoderAndYou/Tracks/Track/index.jsx | 67 +
.../TopcoderAndYou/Tracks/Track/styles.scss | 90 +
.../Settings/TopcoderAndYou/Tracks/index.jsx | 57 +
.../Settings/TopcoderAndYou/Tracks/tracks.jsx | 20 +
.../Settings/TopcoderAndYou/index.jsx | 489 +++
.../Settings/TopcoderAndYou/styles.scss | 100 +
.../Settings/UserConsentModal/index.jsx | 43 +
.../Settings/UserConsentModal/styles.scss | 113 +
src/shared/components/Settings/constants.js | 62 +
src/shared/components/Settings/index.jsx | 166 +
src/shared/components/Settings/style.scss | 470 +++
.../components/TopcoderHeader/Auth/index.jsx | 2 +-
.../components/TopcoderHeader/index.jsx | 11 +-
.../challenge-detail/Specification/index.jsx | 7 +-
.../tc-communities/AccessDenied/index.jsx | 2 +-
.../tc-communities/Footer/index.jsx | 4 +-
.../tc-communities/Header/index.jsx | 6 +-
.../tc-communities/NewsletterSignup/index.jsx | 115 +
.../NewsletterSignup/style.scss | 108 +
.../communities/community-2/Learn/index.jsx | 6 +
.../communities/demo-expert/Home/index.jsx | 7 +
.../communities/demo-expert/Learn/index.jsx | 6 +
.../communities/srmx/Learn/index.jsx | 7 +
.../communities/taskforce/Home/index.jsx | 7 +
.../communities/tc-prod-dev/Home/index.jsx | 7 +
.../communities/tc-prod-dev/Learn/index.jsx | 6 +
.../communities/wipro/Home/index.jsx | 74 +
.../communities/wipro/Learn/index.jsx | 7 +
src/shared/containers/Dashboard/index.jsx | 8 +-
.../containers/EmailSubscribeForm/index.jsx | 222 ++
.../containers/EmailSubscribeForm/style.scss | 98 +
src/shared/containers/NewsletterArchive.jsx | 78 +
.../containers/NewsletterPreferences.jsx | 102 +
.../containers/NewsletterSignupForMembers.jsx | 278 ++
src/shared/containers/Profile.jsx | 42 +-
src/shared/containers/ProfileStats.jsx | 18 +-
src/shared/containers/Settings.jsx | 329 ++
.../SubscribeMailChimpTag/index.jsx | 128 +
.../SubscribeMailChimpTag/style.scss | 62 +
src/shared/containers/Toastr/index.jsx | 8 +-
.../containers/challenge-detail/index.jsx | 2 +-
.../containers/tc-communities/Loader.jsx | 2 +-
.../modal-confirm-reject/index.jsx | 6 +-
.../timeline-events/add-event/index.jsx | 8 +-
src/shared/reducers/index.js | 4 +
src/shared/reducers/newsletterArchive.js | 53 +
src/shared/reducers/newsletterPreferences.js | 70 +
src/shared/routes/Settings/Router.jsx | 6 +
src/shared/routes/Topcoder/Routes.jsx | 5 +
src/shared/routes/Topcoder/Settings.jsx | 32 +
src/shared/utils/markdown.js | 42 +-
src/shared/utils/tc.js | 2 +-
src/shared/utils/url.js | 8 +-
277 files changed, 34574 insertions(+), 354 deletions(-)
create mode 100644 __tests__/shared/components/Settings/Account/__snapshots__/index.jsx.snap
create mode 100644 __tests__/shared/components/Settings/Account/index.jsx
create mode 100644 __tests__/shared/components/Settings/Header/__snapshots__/index.jsx.snap
create mode 100644 __tests__/shared/components/Settings/Header/index.jsx
create mode 100644 __tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap
create mode 100644 __tests__/shared/components/Settings/Preferences/Email/index.jsx
create mode 100644 __tests__/shared/components/Settings/__mocks__/profile-state.json
create mode 100644 __tests__/shared/components/Settings/__mocks__/props-match.json
create mode 100644 __tests__/shared/components/Settings/__mocks__/user-profile.json
create mode 100644 __tests__/shared/components/Settings/__snapshots__/index.jsx.snap
create mode 100644 __tests__/shared/components/Settings/index.jsx
create mode 100644 __tests__/shared/components/tc-communities/NewsletterSignup.jsx
create mode 100644 __tests__/shared/components/tc-communities/__snapshots__/NewsletterSignup.jsx.snap
create mode 100644 automated-smoke-test/Dockerfile
create mode 100644 docs/pwa/nginx/server.key
create mode 100644 docs/swagger.yaml
create mode 100644 src/server/routes/blog.js
create mode 100644 src/server/routes/gSheet.js
create mode 100644 src/server/routes/mailchimp.js
create mode 100644 src/server/services/blog.js
create mode 100644 src/server/services/gSheet.js
create mode 100644 src/server/services/mailchimp.js
create mode 100644 src/shared/actions/newsletterArchive.js
create mode 100644 src/shared/actions/newsletterPreferences.js
create mode 100644 src/shared/components/Contentful/PasswordScreen/index.jsx
create mode 100644 src/shared/components/Contentful/PasswordScreen/style.scss
create mode 100644 src/shared/components/NewsletterArchive/index.jsx
create mode 100644 src/shared/components/NewsletterArchive/style.scss
create mode 100644 src/shared/components/NewsletterSignup/index.jsx
create mode 100644 src/shared/components/NewsletterSignup/style.scss
create mode 100644 src/shared/components/NewsletterSignupForMembers/ConfirmModal/index.jsx
create mode 100644 src/shared/components/NewsletterSignupForMembers/ConfirmModal/style.scss
create mode 100644 src/shared/components/NewsletterSignupForMembers/index.jsx
create mode 100644 src/shared/components/NewsletterSignupForMembers/modal.scss
create mode 100644 src/shared/components/NewsletterSignupForMembers/style.scss
create mode 100644 src/shared/components/Settings/Accordion/index.jsx
create mode 100644 src/shared/components/Settings/Accordion/styles.scss
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/AddWebLink.jsx
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/ExistingLink.jsx
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/ExistingLinks.jsx
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/LinkAccounts.jsx
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/SocialIcons.jsx
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/index.jsx
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/modal.scss
create mode 100644 src/shared/components/Settings/Account/LinkedAccount/styles.scss
create mode 100644 src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/index.jsx
create mode 100644 src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/styles.scss
create mode 100644 src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/index.jsx
create mode 100644 src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/styles.scss
create mode 100644 src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/index.jsx
create mode 100644 src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/styles.scss
create mode 100644 src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/mixins.scss
create mode 100644 src/shared/components/Settings/Account/MyAccount/index.jsx
create mode 100644 src/shared/components/Settings/Account/MyAccount/styles.scss
create mode 100644 src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/index.jsx
create mode 100644 src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/styles.scss
create mode 100644 src/shared/components/Settings/Account/MyPrimaryRole/index.jsx
create mode 100644 src/shared/components/Settings/Account/MyPrimaryRole/styles.scss
create mode 100644 src/shared/components/Settings/Account/Security/Modal/index.jsx
create mode 100644 src/shared/components/Settings/Account/Security/Modal/style.scss
create mode 100644 src/shared/components/Settings/Account/Security/VerificationListener/index.jsx
create mode 100644 src/shared/components/Settings/Account/Security/index.jsx
create mode 100644 src/shared/components/Settings/Account/Security/styles.scss
create mode 100644 src/shared/components/Settings/Account/index.jsx
create mode 100644 src/shared/components/Settings/Account/styles.scss
create mode 100644 src/shared/components/Settings/ComingSoon/index.jsx
create mode 100644 src/shared/components/Settings/ComingSoon/styles.scss
create mode 100644 src/shared/components/Settings/ConfirmationModal/index.jsx
create mode 100644 src/shared/components/Settings/ConfirmationModal/styles.scss
create mode 100644 src/shared/components/Settings/ConsentComponent/index.jsx
create mode 100644 src/shared/components/Settings/ErrorMessage/index.jsx
create mode 100644 src/shared/components/Settings/ErrorMessage/styles.scss
create mode 100644 src/shared/components/Settings/ErrorWrapper/index.jsx
create mode 100644 src/shared/components/Settings/ErrorWrapper/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkExperience/WorkplaceList/Item/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkExperience/WorkplaceList/Item/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkExperience/WorkplaceList/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkExperience/WorkplaceList/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkExperience/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkExperience/styles.scss
create mode 100755 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Interests/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Interests/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Languages/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Languages/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Languages/List/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Languages/List/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Languages/dropdowns.json
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Languages/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Languages/styles.scss
create mode 100755 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Skills/AddSkillsModal/index.jsx
create mode 100755 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Skills/AddSkillsModal/styles.scss
create mode 100755 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Skills/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/Skills/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/WorkSkills/styles.scss
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/index.jsx
create mode 100644 src/shared/components/Settings/ExperienceAndSkills/styles.scss
rename src/shared/components/{Form => Settings}/FormField/index.jsx (100%)
rename src/shared/components/{Form => Settings}/FormField/styles.scss (100%)
rename src/shared/components/{Form => Settings}/FormInputCheckbox/index.jsx (100%)
rename src/shared/components/{Form => Settings}/FormInputCheckbox/styles.scss (100%)
rename src/shared/components/{Form => Settings}/FormInputDatePicker/index.jsx (100%)
rename src/shared/components/{Form => Settings}/FormInputDatePicker/styles.scss (100%)
rename src/shared/components/{Form => Settings}/FormInputSelect/index.jsx (100%)
rename src/shared/components/{Form => Settings}/FormInputSelect/styles.scss (100%)
rename src/shared/components/{Form => Settings}/FormInputText/index.jsx (100%)
rename src/shared/components/{Form => Settings}/FormInputText/styles.scss (100%)
rename src/shared/components/{Form => Settings}/FormInputTextArea/index.jsx (100%)
rename src/shared/components/{Form => Settings}/FormInputTextArea/styles.scss (100%)
create mode 100644 src/shared/components/Settings/Header/index.jsx
create mode 100644 src/shared/components/Settings/Header/styles.scss
create mode 100644 src/shared/components/Settings/PageRow/index.jsx
create mode 100644 src/shared/components/Settings/PageRow/styles.scss
create mode 100644 src/shared/components/Settings/Payment/EmailDetails/index.jsx
create mode 100644 src/shared/components/Settings/Payment/EmailDetails/styles.scss
create mode 100644 src/shared/components/Settings/Payment/PaymentInfo/index.jsx
create mode 100644 src/shared/components/Settings/Payment/PaymentInfo/styles.scss
create mode 100644 src/shared/components/Settings/Payment/PaymentMethod/index.jsx
create mode 100644 src/shared/components/Settings/Payment/PaymentMethod/styles.scss
create mode 100644 src/shared/components/Settings/Payment/PaymentProvider/index.jsx
create mode 100644 src/shared/components/Settings/Payment/PaymentProvider/styles.scss
create mode 100644 src/shared/components/Settings/Payment/constants.js
create mode 100644 src/shared/components/Settings/Payment/index.jsx
create mode 100644 src/shared/components/Settings/Payment/styles.scss
create mode 100644 src/shared/components/Settings/Preferences/Email/data.jsx
create mode 100644 src/shared/components/Settings/Preferences/Email/index.jsx
create mode 100644 src/shared/components/Settings/Preferences/Email/styles.scss
create mode 100644 src/shared/components/Settings/Preferences/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/Preferences/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/Preferences/List/data.jsx
create mode 100644 src/shared/components/Settings/Preferences/List/index.jsx
create mode 100644 src/shared/components/Settings/Preferences/Personalization/index.jsx
create mode 100644 src/shared/components/Settings/Preferences/Personalization/styles.scss
create mode 100644 src/shared/components/Settings/Preferences/index.jsx
create mode 100644 src/shared/components/Settings/Preferences/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/AboutYou/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/Hobbies/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/Hobbies/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/Hobbies/List/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/Hobbies/List/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/Hobbies/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/Hobbies/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/ImageInput/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/ImageInput/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/Learning/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/Learning/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/Learning/List/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/Learning/List/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/Learning/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/Learning/styles.scss
create mode 100644 src/shared/components/Settings/ProfileSettings/PersonalDetails/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/index.jsx
create mode 100644 src/shared/components/Settings/ProfileSettings/styles.scss
create mode 100644 src/shared/components/Settings/SettingsBanner/index.jsx
create mode 100644 src/shared/components/Settings/SettingsBanner/styles.scss
create mode 100644 src/shared/components/Settings/SideBar/SideItem/index.jsx
create mode 100644 src/shared/components/Settings/SideBar/SideItem/styles.scss
create mode 100644 src/shared/components/Settings/SideBar/index.jsx
create mode 100644 src/shared/components/Settings/SideBar/styles.scss
create mode 100644 src/shared/components/Settings/TabSelector/index.jsx
create mode 100644 src/shared/components/Settings/TabSelector/styles.scss
create mode 100644 src/shared/components/Settings/ToggleableItem/index.jsx
create mode 100644 src/shared/components/Settings/ToggleableItem/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Devices/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Devices/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Devices/List/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Devices/List/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Devices/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Devices/styles.scss
create mode 100644 src/shared/components/Settings/Tools/ServiceProviders/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/Tools/ServiceProviders/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/Tools/ServiceProviders/List/index.jsx
create mode 100644 src/shared/components/Settings/Tools/ServiceProviders/List/styles.scss
create mode 100644 src/shared/components/Settings/Tools/ServiceProviders/dropdowns.json
create mode 100644 src/shared/components/Settings/Tools/ServiceProviders/index.jsx
create mode 100644 src/shared/components/Settings/Tools/ServiceProviders/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Software/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Software/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Software/List/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Software/List/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Software/dropdowns.json
create mode 100644 src/shared/components/Settings/Tools/Software/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Software/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Subscriptions/List/Item/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Subscriptions/List/Item/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Subscriptions/List/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Subscriptions/List/styles.scss
create mode 100644 src/shared/components/Settings/Tools/Subscriptions/index.jsx
create mode 100644 src/shared/components/Settings/Tools/Subscriptions/styles.scss
create mode 100644 src/shared/components/Settings/Tools/index.jsx
create mode 100644 src/shared/components/Settings/Tools/styles.scss
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Community/Item/index.jsx
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Community/Item/styles.scss
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Community/data.jsx
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Community/index.jsx
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Community/styles.scss
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Tracks/Track/index.jsx
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Tracks/Track/styles.scss
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Tracks/index.jsx
create mode 100644 src/shared/components/Settings/TopcoderAndYou/Tracks/tracks.jsx
create mode 100644 src/shared/components/Settings/TopcoderAndYou/index.jsx
create mode 100644 src/shared/components/Settings/TopcoderAndYou/styles.scss
create mode 100644 src/shared/components/Settings/UserConsentModal/index.jsx
create mode 100644 src/shared/components/Settings/UserConsentModal/styles.scss
create mode 100644 src/shared/components/Settings/constants.js
create mode 100644 src/shared/components/Settings/index.jsx
create mode 100644 src/shared/components/Settings/style.scss
create mode 100644 src/shared/components/tc-communities/NewsletterSignup/index.jsx
create mode 100644 src/shared/components/tc-communities/NewsletterSignup/style.scss
create mode 100644 src/shared/containers/EmailSubscribeForm/index.jsx
create mode 100644 src/shared/containers/EmailSubscribeForm/style.scss
create mode 100644 src/shared/containers/NewsletterArchive.jsx
create mode 100644 src/shared/containers/NewsletterPreferences.jsx
create mode 100644 src/shared/containers/NewsletterSignupForMembers.jsx
create mode 100644 src/shared/containers/Settings.jsx
create mode 100644 src/shared/containers/SubscribeMailChimpTag/index.jsx
create mode 100644 src/shared/containers/SubscribeMailChimpTag/style.scss
create mode 100644 src/shared/reducers/newsletterArchive.js
create mode 100644 src/shared/reducers/newsletterPreferences.js
create mode 100644 src/shared/routes/Topcoder/Settings.jsx
diff --git a/.circleci/config.yml b/.circleci/config.yml
index b813779aa7..621db64129 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -33,10 +33,10 @@ install_deploysuite: &install_deploysuite
cp ./../buildscript/buildenv.sh .
cp ./../buildscript/awsconfiguration.sh .
restore_cache_settings_for_build: &restore_cache_settings_for_build
- key: docker-node-modules-v4-{{ checksum "package-lock.json" }}
+ key: docker-node-modules-v3-{{ checksum "package-lock.json" }}
save_cache_settings: &save_cache_settings
- key: docker-node-modules-v4-{{ checksum "package-lock.json" }}
+ key: docker-node-modules-v3-{{ checksum "package-lock.json" }}
paths:
- node_modules
@@ -73,7 +73,7 @@ jobs:
command: |
source awsenvconf
source buildenvvar
- ./master_deploy.sh -d ECS -e DEV -t latest -s dev_communityapp_taskvar -i communityapp -p FARGATE
+ ./master_deploy.sh -d ECS -e DEV -t latest -s dev_communityapp_taskvar -i communityapp
# Build & Deploy against testing backend
# "build-test":
@@ -224,7 +224,7 @@ jobs:
command: |
source awsenvconf
source buildenvvar
- ./master_deploy.sh -d ECS -e PROD -t latest -s prod_communityapp_taskvar -i communityapp -p FARGATE
+ ./master_deploy.sh -d ECS -e PROD -t latest -s prod_communityapp_taskvar -i communityapp
curl --request POST \
--url https://circleci.com/api/v2/project/github/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pipeline \
--header "Circle-Token: ${CIRCLE_TOKEN}" \
@@ -260,37 +260,37 @@ jobs:
# path: ./automated-smoke-test/test-results
# Automated Smoke Testing against Production
- # Smoke-Testing-On-Production:
- # <<: *defaults
- # steps:
- # # Initialization.
- # - checkout
- # - setup_remote_docker
- # - run: *install_dependency
- # - run: *install_deploysuite
- # # Restoration of node_modules from cache.
- # - restore_cache: *restore_cache_settings_for_build
- # - run:
- # name: "configuring environment"
- # command: |
- # ./awsconfiguration.sh PROD
- # ./buildenv.sh -e PROD -b prod_communityapp_buildvar,prod_communityapp_deployvar
- # - run:
- # name: "Run automation"
- # no_output_timeout: 20m
- # command: |
- # source awsenvconf
- # source buildenvvar
- # ./automated-smoke-test/smoketest.sh automation-config-prod.json prod
- # - store_artifacts:
- # path: ./automated-smoke-test/test-results
+ Smoke-Testing-On-Production:
+ <<: *defaults
+ steps:
+ # Initialization.
+ - checkout
+ - setup_remote_docker
+ - run: *install_dependency
+ - run: *install_deploysuite
+ # Restoration of node_modules from cache.
+ - restore_cache: *restore_cache_settings_for_build
+ - run:
+ name: "configuring environment"
+ command: |
+ ./awsconfiguration.sh PROD
+ ./buildenv.sh -e PROD -b prod_communityapp_buildvar,prod_communityapp_deployvar
+ - run:
+ name: "Run automation"
+ no_output_timeout: 20m
+ command: |
+ source awsenvconf
+ source buildenvvar
+ ./automated-smoke-test/smoketest.sh automation-config-prod.json prod
+ - store_artifacts:
+ path: ./automated-smoke-test/test-results
# Test job for the cases when we do not need deployment. It just rapidly
# installs (updates) app dependencies, and runs tests (ESLint, Stylelint,
# Jest unit-tests).
test:
docker:
- - image: circleci/node:10.24.1
+ - image: circleci/node:8.11.1
steps:
- checkout
- restore_cache:
@@ -360,7 +360,6 @@ workflows:
- develop
- TOP-1390
- PM-191-2
- - pm-199
# This is alternate dev env for parallel testing
# Deprecate this workflow due to beta env shutdown
# https://topcoder.atlassian.net/browse/CORE-251
diff --git a/Dockerfile b/Dockerfile
index 0e7f8c6e2c..7691feebdc 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,16 +2,12 @@
# and runs it against the specified Topcoder backend (development or
# production) when container is executed.
-FROM node:10.24.1
+FROM node:8.11.2
LABEL app="Community App" version="1.0"
-RUN useradd -m -s /bin/bash appuser
WORKDIR /opt/app
COPY . .
-RUN chown -R appuser:appuser /opt/app
-USER appuser
-
################################################################################
# Receiving of build arguments.
diff --git a/__tests__/shared/components/Settings/Account/__snapshots__/index.jsx.snap b/__tests__/shared/components/Settings/Account/__snapshots__/index.jsx.snap
new file mode 100644
index 0000000000..207666379e
--- /dev/null
+++ b/__tests__/shared/components/Settings/Account/__snapshots__/index.jsx.snap
@@ -0,0 +1,2132 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders account setting page correctly 1`] = `
+
+
+
+
+ Account information & Security
+
+
+
+
+
+
+
+
+ Save Changes
+
+
+
+`;
diff --git a/__tests__/shared/components/Settings/Account/index.jsx b/__tests__/shared/components/Settings/Account/index.jsx
new file mode 100644
index 0000000000..0bd72d407d
--- /dev/null
+++ b/__tests__/shared/components/Settings/Account/index.jsx
@@ -0,0 +1,32 @@
+import React from 'react';
+import Renderer from 'react-test-renderer/shallow';
+
+import Account from 'components/Settings/Account';
+
+import userProfile from '../__mocks__/user-profile.json';
+import profileState from '../__mocks__/profile-state.json';
+
+const rnd = new Renderer();
+
+const settingsUI = {
+ TABS: {
+ ACCOUNT: {
+ MYACCOUNT: 'my account',
+ // LINKEDACCOUNT: 'linked account',
+ },
+ },
+};
+
+it('renders account setting page correctly', () => {
+ rnd.render(( {}}
+ clearIncorrectPassword={() => {}}
+ updateProfile={() => {}}
+ settingsUI={settingsUI}
+ />));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
diff --git a/__tests__/shared/components/Settings/Header/__snapshots__/index.jsx.snap b/__tests__/shared/components/Settings/Header/__snapshots__/index.jsx.snap
new file mode 100644
index 0000000000..bbd94fba03
--- /dev/null
+++ b/__tests__/shared/components/Settings/Header/__snapshots__/index.jsx.snap
@@ -0,0 +1,33 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders setting page header correctly 1`] = `
+
+
+
+ SAVE CHANGES
+
+
+
+`;
diff --git a/__tests__/shared/components/Settings/Header/index.jsx b/__tests__/shared/components/Settings/Header/index.jsx
new file mode 100644
index 0000000000..03de63ce50
--- /dev/null
+++ b/__tests__/shared/components/Settings/Header/index.jsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import Renderer from 'react-test-renderer/shallow';
+
+import Header from 'components/Settings/Header';
+
+import profileState from '../__mocks__/profile-state.json';
+
+const rnd = new Renderer();
+
+it('renders setting page header correctly', () => {
+ rnd.render(( {}}
+ />));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
diff --git a/__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap b/__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap
new file mode 100644
index 0000000000..585e1c49bf
--- /dev/null
+++ b/__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap
@@ -0,0 +1,20 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders email preferences setting page correctly 1`] = `
+
+
+
+`;
diff --git a/__tests__/shared/components/Settings/Preferences/Email/index.jsx b/__tests__/shared/components/Settings/Preferences/Email/index.jsx
new file mode 100644
index 0000000000..f49efaae8d
--- /dev/null
+++ b/__tests__/shared/components/Settings/Preferences/Email/index.jsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import Renderer from 'react-test-renderer/shallow';
+
+import Email from 'components/Settings/Preferences/Email';
+
+const rnd = new Renderer();
+
+it('renders email preferences setting page correctly', () => {
+ rnd.render(());
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
diff --git a/__tests__/shared/components/Settings/__mocks__/profile-state.json b/__tests__/shared/components/Settings/__mocks__/profile-state.json
new file mode 100644
index 0000000000..abd05d4852
--- /dev/null
+++ b/__tests__/shared/components/Settings/__mocks__/profile-state.json
@@ -0,0 +1,593 @@
+{
+ "achievements": [
+ {
+ "date": "2016-09-02T00:00:00.000-04:00",
+ "description": "iOS Developer Challenger Badge"
+ },
+ {
+ "date": "2015-08-05T00:00:00.000-04:00",
+ "description": "Participant Badge"
+ },
+ {
+ "date": "2015-08-05T00:00:00.000-04:00",
+ "description": "iOS Participant Badge"
+ },
+ {
+ "date": "2014-07-01T00:00:00.000-04:00",
+ "description": "Digital Run Top Five"
+ },
+ {
+ "date": "2014-07-01T00:00:00.000-04:00",
+ "description": "Digital Run Winner"
+ },
+ {
+ "date": "2014-02-11T00:00:00.000-05:00",
+ "description": "First Milestone Prize"
+ },
+ {
+ "date": "2013-03-15T00:00:00.000-04:00",
+ "description": "First Forum Post"
+ },
+ {
+ "date": "2013-03-04T00:00:00.000-05:00",
+ "description": "First Passing Submission"
+ },
+ {
+ "date": "2013-02-28T00:00:00.000-05:00",
+ "description": "First Placement"
+ },
+ {
+ "date": "2013-02-28T00:00:00.000-05:00",
+ "description": "First Win"
+ },
+ {
+ "date": "2012-11-09T00:00:00.000-05:00",
+ "description": "One Hundred Forum Posts"
+ },
+ {
+ "date": "2010-10-09T00:00:00.000-04:00",
+ "description": "Five Hundred Forum Posts"
+ },
+ {
+ "date": "2009-04-04T00:00:00.000-04:00",
+ "description": "Twenty Five Placements"
+ },
+ {
+ "date": "2008-07-01T00:00:00.000-04:00",
+ "description": "Twenty Five First Placement Win"
+ },
+ {
+ "date": "2008-06-11T00:00:00.000-04:00",
+ "description": "One Thousand Forum Posts"
+ },
+ {
+ "date": "2008-05-12T00:00:00.000-04:00",
+ "description": "Fifty Passing Submissions"
+ },
+ {
+ "date": "2008-05-03T00:00:00.000-04:00",
+ "description": "Fifty Placements"
+ },
+ {
+ "date": "2008-05-01T00:00:00.000-04:00",
+ "description": "TopCoder Development Coder of the Month for May 2008"
+ },
+ {
+ "date": "2007-03-30T00:00:00.000-04:00",
+ "description": "Fifty First Placement Win"
+ },
+ {
+ "date": "2006-11-03T00:00:00.000-05:00",
+ "description": "One Hundred Passing Submissions"
+ },
+ {
+ "date": "2006-10-28T00:00:00.000-04:00",
+ "description": "One Hundred First Placement Win"
+ },
+ {
+ "date": "2006-10-28T00:00:00.000-04:00",
+ "description": "One hundred Placements"
+ },
+ {
+ "date": "2006-10-28T00:00:00.000-04:00",
+ "description": "SRM Engagement Honor"
+ }
+ ],
+ "copilot": false,
+ "country": "China",
+ "info": null,
+ "loadingError": false,
+ "skills": {
+ "100": {
+ "tagName": ".NET",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "101": {
+ "tagName": "ActionScript",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "109": {
+ "tagName": "Android",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "110": {
+ "tagName": "AngularJS",
+ "hidden": false,
+ "score": 10,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "115": {
+ "tagName": "Apache Kafka",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "USER_ENTERED"
+ ]
+ },
+ "117": {
+ "tagName": "API",
+ "hidden": false,
+ "score": 4,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "127": {
+ "tagName": "Blackberry SDK",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "132": {
+ "tagName": "C#",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "153": {
+ "tagName": "CSS",
+ "hidden": false,
+ "score": 10,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "154": {
+ "tagName": "CSS3",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "USER_ENTERED"
+ ]
+ },
+ "163": {
+ "tagName": "Docker",
+ "hidden": false,
+ "score": 5,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "170": {
+ "tagName": "EJB",
+ "hidden": false,
+ "score": 18,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "171": {
+ "tagName": "Elasticsearch",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "177": {
+ "tagName": "Express",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "182": {
+ "tagName": "Flex",
+ "hidden": false,
+ "score": 3,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "186": {
+ "tagName": "Force.Com Sites",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "211": {
+ "tagName": "Hibernate",
+ "hidden": false,
+ "score": 12,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "212": {
+ "tagName": "HTML",
+ "hidden": false,
+ "score": 6,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "213": {
+ "tagName": "HTML5",
+ "hidden": false,
+ "score": 12,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "214": {
+ "tagName": "HTTP",
+ "hidden": false,
+ "score": 3,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "219": {
+ "tagName": "IBM DB2",
+ "hidden": false,
+ "score": 5,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "229": {
+ "tagName": "IBM Websphere Application Server",
+ "hidden": false,
+ "score": 3,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "232": {
+ "tagName": "IBM WebSphere MQ",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "244": {
+ "tagName": "J2EE",
+ "hidden": false,
+ "score": 15,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "247": {
+ "tagName": "Java",
+ "hidden": false,
+ "score": 123,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "248": {
+ "tagName": "JavaScript",
+ "hidden": false,
+ "score": 20,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "249": {
+ "tagName": "JBoss Seam",
+ "hidden": false,
+ "score": 3,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "250": {
+ "tagName": "JDBC",
+ "hidden": false,
+ "score": 3,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "254": {
+ "tagName": "JPA",
+ "hidden": false,
+ "score": 9,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "255": {
+ "tagName": "jQuery",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "258": {
+ "tagName": "JSF",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "259": {
+ "tagName": "JSON",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "260": {
+ "tagName": "JSP",
+ "hidden": false,
+ "score": 21,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "276": {
+ "tagName": "Maven",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "281": {
+ "tagName": "MongoDB",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "284": {
+ "tagName": "MySql",
+ "hidden": false,
+ "score": 7,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "286": {
+ "tagName": "Node.js",
+ "hidden": false,
+ "score": 18,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "295": {
+ "tagName": "Oracle Database",
+ "hidden": false,
+ "score": 14,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "303": {
+ "tagName": "PHP",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "306": {
+ "tagName": "PostgreSQL",
+ "hidden": false,
+ "score": 8,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "315": {
+ "tagName": "React.js",
+ "hidden": false,
+ "score": 1,
+ "sources": [
+ "USER_ENTERED"
+ ]
+ },
+ "323": {
+ "tagName": "REST",
+ "hidden": false,
+ "score": 5,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "328": {
+ "tagName": "Salesforce",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "337": {
+ "tagName": "Servlet",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "344": {
+ "tagName": "Sharepoint 3.0",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ },
+ "354": {
+ "tagName": "Spring",
+ "hidden": false,
+ "score": 15,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "355": {
+ "tagName": "SQL",
+ "hidden": false,
+ "score": 4,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "356": {
+ "tagName": "SQL Server",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "362": {
+ "tagName": "Struts",
+ "hidden": false,
+ "score": 3,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "387": {
+ "tagName": "Web Services",
+ "hidden": false,
+ "score": 8,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "401": {
+ "tagName": "XML",
+ "hidden": false,
+ "score": 6,
+ "sources": [
+ "CHALLENGE"
+ ]
+ },
+ "402": {
+ "tagName": "XSL",
+ "hidden": false,
+ "score": 2,
+ "sources": [
+ "CHALLENGE",
+ "USER_ENTERED"
+ ]
+ }
+ },
+ "stats": null,
+ "profileForHandle": "tcscoder",
+ "linkedAccounts": [
+ {
+ "userId": "623633",
+ "name": "tcscoder",
+ "email": "tcscoder@gmail.com",
+ "providerType": "github",
+ "provider": null,
+ "context": null,
+ "social": true,
+ "enterprise": false,
+ "emailVerified": false
+ },
+ {
+ "userId": "1233342",
+ "name": "1233342",
+ "email": "",
+ "providerType": "stackoverflow",
+ "provider": null,
+ "context": null,
+ "social": true,
+ "enterprise": false,
+ "emailVerified": false
+ }
+ ],
+ "externalLinks": [
+ {
+ "userId": 22655076,
+ "key": "4c7136cdbbf227274e49c475e7541abf",
+ "handle": "tcscoder",
+ "description": "Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.",
+ "entities": null,
+ "keywords": null,
+ "title": "Google",
+ "images": "https://www.google.com/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png",
+ "source": "embed.ly",
+ "synchronizedAt": 1525560141959,
+ "URL": "https://www.google.com"
+ }
+ ],
+ "externalAccounts": {
+ "userId": 22655076,
+ "handle": "tcscoder",
+ "behance": null,
+ "bitbucket": null,
+ "dribbble": null,
+ "github": null,
+ "linkedin": null,
+ "stackoverflow": null,
+ "twitter": null,
+ "updatedAt": null,
+ "createdAt": null,
+ "createdBy": null,
+ "updatedBy": null
+ },
+ "emailPreferences": {
+ "TOPCODER_NL_DESIGN": true,
+ "TOPCODER_NL_DEV": true,
+ "TOPCODER_NL_GEN": true
+ },
+ "credential": {
+ "activationCode": "SDUUH(HFS",
+ "resetToken": null,
+ "hasPassword": true
+ }
+}
\ No newline at end of file
diff --git a/__tests__/shared/components/Settings/__mocks__/props-match.json b/__tests__/shared/components/Settings/__mocks__/props-match.json
new file mode 100644
index 0000000000..3995d403ea
--- /dev/null
+++ b/__tests__/shared/components/Settings/__mocks__/props-match.json
@@ -0,0 +1,8 @@
+{
+ "isExact": true,
+ "params": {
+ "settingsTab": "profile"
+ },
+ "path": "/settings/:settingsTab(profile|tools|account|preferences)",
+ "url": "/settings/profile"
+}
\ No newline at end of file
diff --git a/__tests__/shared/components/Settings/__mocks__/user-profile.json b/__tests__/shared/components/Settings/__mocks__/user-profile.json
new file mode 100644
index 0000000000..b2dd0838f0
--- /dev/null
+++ b/__tests__/shared/components/Settings/__mocks__/user-profile.json
@@ -0,0 +1,81 @@
+{
+ "maxRating": {
+ "rating": 2162,
+ "track": "DEVELOP",
+ "subTrack": "DEVELOPMENT"
+ },
+ "userId": 22655076,
+ "firstName": "Mike",
+ "lastName": "Smith",
+ "description": "Hello",
+ "otherLangName": "Som",
+ "handle": "tcscoder",
+ "handleLower": "tcscoder",
+ "status": "ACTIVE",
+ "email": "tcscoder@gmail.com",
+ "addresses": [
+ {
+ "streetAddr1": "Street line 1, #432",
+ "streetAddr2": "",
+ "city": "Cheng Du",
+ "zip": "610101",
+ "stateCode": "Sichuan",
+ "type": "HOME",
+ "updatedAt": null,
+ "createdAt": null,
+ "createdBy": "",
+ "updatedBy": ""
+ }
+ ],
+ "homeCountryCode": "CHN",
+ "competitionCountryCode": "CHN",
+ "photoURL": "https://topcoder-prod-media.s3.amazonaws.com/member/profile/tcscoder-1525559661069.png",
+ "tracks": [
+ "DEVELOP"
+ ],
+ "updatedAt": "2018-05-05T22:34Z",
+ "createdAt": "2006-10-06T08:49Z",
+ "createdBy": "22655076",
+ "updatedBy": "22655076",
+ "groups": [
+ {
+ "id": "20000010",
+ "modifiedBy": null,
+ "modifiedAt": null,
+ "createdBy": "8547899",
+ "createdAt": "2017-09-11T13:54:47.000Z",
+ "name": "Blockchain",
+ "description": "Blockchain",
+ "privateGroup": true,
+ "selfRegister": true,
+ "subGroups": null,
+ "parentGroup": null
+ },
+ {
+ "id": "20000013",
+ "modifiedBy": null,
+ "modifiedAt": null,
+ "createdBy": "8547899",
+ "createdAt": "2017-10-19T10:54:47.000Z",
+ "name": "Veterans",
+ "description": "Veterans",
+ "privateGroup": true,
+ "selfRegister": true,
+ "subGroups": null,
+ "parentGroup": null
+ },
+ {
+ "id": "20000015",
+ "modifiedBy": null,
+ "modifiedAt": null,
+ "createdBy": "8547899",
+ "createdAt": "2017-11-06T15:49:35.000Z",
+ "name": "Cognitive",
+ "description": "Cognitive Community",
+ "privateGroup": true,
+ "selfRegister": true,
+ "subGroups": null,
+ "parentGroup": null
+ }
+ ]
+}
\ No newline at end of file
diff --git a/__tests__/shared/components/Settings/__snapshots__/index.jsx.snap b/__tests__/shared/components/Settings/__snapshots__/index.jsx.snap
new file mode 100644
index 0000000000..d73c732fee
--- /dev/null
+++ b/__tests__/shared/components/Settings/__snapshots__/index.jsx.snap
@@ -0,0 +1,3042 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders account setting page correctly 1`] = `
+
+`;
+
+exports[`renders preferences setting page correctly 1`] = `
+
+`;
+
+exports[`renders profile setting page correctly 1`] = `
+
+`;
+
+exports[`renders tools setting page correctly 1`] = `
+
+`;
diff --git a/__tests__/shared/components/Settings/index.jsx b/__tests__/shared/components/Settings/index.jsx
new file mode 100644
index 0000000000..98fcde7a81
--- /dev/null
+++ b/__tests__/shared/components/Settings/index.jsx
@@ -0,0 +1,83 @@
+import React from 'react';
+import Renderer from 'react-test-renderer/shallow';
+
+import Settings from 'components/Settings';
+
+import userProfile from './__mocks__/user-profile.json';
+import profileState from './__mocks__/profile-state.json';
+import propsMatch from './__mocks__/props-match.json';
+
+const rnd = new Renderer();
+
+it('renders profile setting page correctly', () => {
+ rnd.render(( {}}
+ showXlBadge={() => {}}
+ profile={userProfile}
+ profileState={profileState}
+ settingsPageState={{}}
+ lookupData={{}}
+ updateProfile={() => {}}
+ uploadPhoto={() => {}}
+ deletePhoto={() => {}}
+ addSkill={() => {}}
+ hideSkill={() => {}}
+ match={propsMatch}
+ />));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
+
+it('renders account setting page correctly', () => {
+ rnd.render(( {}}
+ showXlBadge={() => {}}
+ profile={userProfile}
+ profileState={profileState}
+ settingsPageState={{}}
+ updatePassword={() => {}}
+ clearIncorrectPassword={() => {}}
+ updateProfile={() => {}}
+ match={propsMatch}
+ />));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
+
+it('renders tools setting page correctly', () => {
+ rnd.render(( {}}
+ showXlBadge={() => {}}
+ profile={userProfile}
+ profileState={profileState}
+ settingsPageState={{}}
+ match={propsMatch}
+ />));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
+
+it('renders preferences setting page correctly', () => {
+ rnd.render(( {}}
+ showXlBadge={() => {}}
+ profile={userProfile}
+ profileState={profileState}
+ settingsPageState={{}}
+ match={propsMatch}
+ />));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
diff --git a/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap b/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap
index d5a3513f5d..88fbc5b716 100644
--- a/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap
+++ b/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap
@@ -69,7 +69,7 @@ exports[`Matches shallow shapshot 1`] = `
className="src-shared-components-challenge-listing-Sidebar-Footer-___style__copyright___ghkHg"
>
Topcoder ©
- 2025
+ 2024
`;
diff --git a/__tests__/shared/components/tc-communities/NewsletterSignup.jsx b/__tests__/shared/components/tc-communities/NewsletterSignup.jsx
new file mode 100644
index 0000000000..4fdbfe1737
--- /dev/null
+++ b/__tests__/shared/components/tc-communities/NewsletterSignup.jsx
@@ -0,0 +1,72 @@
+import React from 'react';
+import Rnd from 'react-test-renderer/shallow';
+import TU from 'react-dom/test-utils';
+import NewsletterSignup from 'components/tc-communities/NewsletterSignup';
+
+const rnd = new Rnd();
+
+test('Snapshot match', () => {
+ rnd.render((
+
+ ));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+
+ rnd.render((
+
+ ));
+ expect(rnd.getRenderOutput()).toMatchSnapshot();
+});
+
+class Wrapper extends React.Component {
+ componentDidMount() {}
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+const instance = TU.renderIntoDocument((
+
+));
+
+describe('handle click', () => {
+ beforeEach(() => jest.clearAllMocks());
+
+ test('onTitleClick', () => {
+ const matches = TU.scryRenderedDOMComponentsWithTag(instance, 'button');
+ expect(matches.length).toBe(1);
+ TU.Simulate.click(matches[0]);
+ });
+});
diff --git a/__tests__/shared/components/tc-communities/__snapshots__/NewsletterSignup.jsx.snap b/__tests__/shared/components/tc-communities/__snapshots__/NewsletterSignup.jsx.snap
new file mode 100644
index 0000000000..dd6ae1c390
--- /dev/null
+++ b/__tests__/shared/components/tc-communities/__snapshots__/NewsletterSignup.jsx.snap
@@ -0,0 +1,47 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Snapshot match 1`] = `
+
+`;
+
+exports[`Snapshot match 2`] = `
+
+`;
diff --git a/__tests__/shared/components/tc-communities/communities/community-2/__snapshots__/Learn.jsx.snap b/__tests__/shared/components/tc-communities/communities/community-2/__snapshots__/Learn.jsx.snap
index 07cfe014b4..922eede706 100644
--- a/__tests__/shared/components/tc-communities/communities/community-2/__snapshots__/Learn.jsx.snap
+++ b/__tests__/shared/components/tc-communities/communities/community-2/__snapshots__/Learn.jsx.snap
@@ -255,5 +255,19 @@ exports[`Match shadow snapshot 1`] = `
title="Useful Links"
/>
+
`;
diff --git a/__tests__/shared/components/tc-communities/communities/demo-expert/__snapshots__/Learn.jsx.snap b/__tests__/shared/components/tc-communities/communities/demo-expert/__snapshots__/Learn.jsx.snap
index 22130a3c9f..442c1cebdf 100644
--- a/__tests__/shared/components/tc-communities/communities/demo-expert/__snapshots__/Learn.jsx.snap
+++ b/__tests__/shared/components/tc-communities/communities/demo-expert/__snapshots__/Learn.jsx.snap
@@ -410,5 +410,19 @@ exports[`Snapshot match 1`] = `
title="Useful Links"
/>
+
`;
diff --git a/__tests__/shared/components/tc-communities/communities/taskforce/__snapshots__/Home.jsx.snap b/__tests__/shared/components/tc-communities/communities/taskforce/__snapshots__/Home.jsx.snap
index efb0463e56..ac2d5bdc21 100644
--- a/__tests__/shared/components/tc-communities/communities/taskforce/__snapshots__/Home.jsx.snap
+++ b/__tests__/shared/components/tc-communities/communities/taskforce/__snapshots__/Home.jsx.snap
@@ -212,5 +212,19 @@ exports[`Match shadow snapshot 1`] = `
}
}
/>
+
`;
diff --git a/__tests__/shared/components/tc-communities/communities/tc-prod-dev/__snapshots__/Learn.jsx.snap b/__tests__/shared/components/tc-communities/communities/tc-prod-dev/__snapshots__/Learn.jsx.snap
index cb16633b29..54022b665c 100644
--- a/__tests__/shared/components/tc-communities/communities/tc-prod-dev/__snapshots__/Learn.jsx.snap
+++ b/__tests__/shared/components/tc-communities/communities/tc-prod-dev/__snapshots__/Learn.jsx.snap
@@ -395,5 +395,19 @@ exports[`Snapshot match 1`] = `
title="Useful Links"
/>
+
`;
diff --git a/__tests__/shared/utils/__snapshots__/markdown.js.snap b/__tests__/shared/utils/__snapshots__/markdown.js.snap
index 5dc7969857..449da8d15c 100644
--- a/__tests__/shared/utils/__snapshots__/markdown.js.snap
+++ b/__tests__/shared/utils/__snapshots__/markdown.js.snap
@@ -1203,7 +1203,7 @@ Array [
A list item with a code block:
- <code>
+ <code goes here>
@@ -1294,7 +1294,7 @@ end tell
ampersands and angle brackets. For example, this:
,
- <div>
+ <div class="footer">
© 2004 Foo Corporation
</div>
diff --git a/automated-smoke-test/Dockerfile b/automated-smoke-test/Dockerfile
new file mode 100644
index 0000000000..b228769e64
--- /dev/null
+++ b/automated-smoke-test/Dockerfile
@@ -0,0 +1,32 @@
+FROM node:10.17.0-stretch
+RUN apt update
+RUN apt install sudo
+RUN sudo apt-get update; sudo apt-get install -y openjdk-8-jre openjdk-8-jre-headless openjdk-8-jdk openjdk-8-jdk-headless;
+RUN curl --silent --show-error --location --fail --retry 3 --output /tmp/google-chrome-stable_current_amd64.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
+ && (sudo dpkg -i /tmp/google-chrome-stable_current_amd64.deb || sudo apt-get -fy install) \
+ && rm -rf /tmp/google-chrome-stable_current_amd64.deb \
+ && sudo sed -i 's|HERE/chrome"|HERE/chrome" --disable-setuid-sandbox --no-sandbox|g' \
+ "/opt/google/chrome/google-chrome" \
+ && google-chrome --version
+RUN export CHROMEDRIVER_RELEASE=$(curl --location --fail --retry 3 http://chromedriver.storage.googleapis.com/LATEST_RELEASE) \
+ && curl --silent --show-error --location --fail --retry 3 --output /tmp/chromedriver_linux64.zip "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_RELEASE/chromedriver_linux64.zip" \
+ && cd /tmp \
+ && unzip chromedriver_linux64.zip \
+ && rm -rf chromedriver_linux64.zip \
+ && sudo mv chromedriver /usr/local/bin/chromedriver \
+ && sudo chmod +x /usr/local/bin/chromedriver \
+ && chromedriver --version
+RUN sudo apt-get install -y libgconf-2-4
+RUN sudo apt-get install -y xvfb
+RUN sudo apt-get install -y jq
+ENV DISPLAY :99
+RUN printf '#!/bin/sh\nXvfb :99 -screen 0 1280x1024x24 &\nexec "$@"\n' > /tmp/entrypoint \
+ && chmod +x /tmp/entrypoint \
+ && sudo mv /tmp/entrypoint /docker-entrypoint.sh
+
+COPY . /automated-smoke-test
+WORKDIR /automated-smoke-test
+RUN npm install
+RUN ./node_modules/.bin/webdriver-manager update --versions.chrome=="$(google-chrome -version)"
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["/bin/sh"]
\ No newline at end of file
diff --git a/automated-smoke-test/config/automation-config-dev.json b/automated-smoke-test/config/automation-config-dev.json
index 9ac9bf711d..4df4b85ad3 100644
--- a/automated-smoke-test/config/automation-config-dev.json
+++ b/automated-smoke-test/config/automation-config-dev.json
@@ -86,6 +86,7 @@
"allNotificationsUrl": "https://community-app.topcoder-dev.com/notifications",
"policiesUrl": "https://community-app.topcoder-dev.com/policy",
"username": "tester1234",
+ "password": "appirio123",
"email": "sathya.jayabal@gmail.com",
"challangesLinks": {
"rssFeedUrl": "http://feeds.topcoder-dev.com/challenges/feed",
diff --git a/automated-smoke-test/config/automation-config-local.json b/automated-smoke-test/config/automation-config-local.json
index c2ca342f56..79f61ba285 100644
--- a/automated-smoke-test/config/automation-config-local.json
+++ b/automated-smoke-test/config/automation-config-local.json
@@ -81,6 +81,7 @@
"allNotificationsUrl": "http://localhost:3000/notifications",
"policiesUrl": "http://localhost:3000/policy",
"username": "Tonyj",
+ "password": "appirio123",
"email": "topcoderconnect@gmail.com",
"challangesLinks": {
"rssFeedUrl": "http://feeds.topcoder.com/challenges/feed",
diff --git a/automated-smoke-test/config/automation-config-prod.json b/automated-smoke-test/config/automation-config-prod.json
index d05c56008c..ed2fc420de 100644
--- a/automated-smoke-test/config/automation-config-prod.json
+++ b/automated-smoke-test/config/automation-config-prod.json
@@ -81,6 +81,7 @@
"allNotificationsUrl": "https://www.topcoder.com/notifications",
"policiesUrl": "https://www.topcoder.com/policy",
"username": "CustomerUser",
+ "password": "appirio123",
"email": "topcoderconnect@gmail.com",
"challangesLinks": {
"rssFeedUrl": "http://feeds.topcoder.com/challenges/feed",
diff --git a/automated-smoke-test/test-data/test-data.json b/automated-smoke-test/test-data/test-data.json
index 98fcf8a0bc..02aa602405 100644
--- a/automated-smoke-test/test-data/test-data.json
+++ b/automated-smoke-test/test-data/test-data.json
@@ -1,6 +1,7 @@
{
"login": {
- "invalidUsername": "gjhhvv"
+ "invalidUsername": "gjhhvv",
+ "invalidPassword": "invalidpassword"
},
"tools": {
"subscription": "Sample A",
diff --git a/config/default.js b/config/default.js
index f5424d3504..e30ec05227 100644
--- a/config/default.js
+++ b/config/default.js
@@ -132,8 +132,8 @@ module.exports = {
INFO: {
DESIGN_CHALLENGES: 'http://help.topcoder.com/hc/en-us/categories/202610437-DESIGN',
DESIGN_CHALLENGE_CHECKPOINTS: 'https://help.topcoder.com/hc/en-us/articles/219240807-Multi-Round-Checkpoint-Design-Challenges',
- DESIGN_CHALLENGE_SUBMISSION: 'https://www.topcoder.com/thrive/articles/Formatting%20Your%20Submission%20for%20Design%20Challenges',
- DESIGN_CHALLENGE_TYPES: 'https://www.topcoder.com/thrive/articles/How%20To%20Compete%20in%20Design',
+ DESIGN_CHALLENGE_SUBMISSION: 'http://help.topcoder.com/hc/en-us/articles/219122667-Formatting-Your-Submission-for-Design-Challenges',
+ DESIGN_CHALLENGE_TYPES: 'http://help.topcoder.com/hc/en-us/articles/217481388-Choosing-a-Design-Challenge',
RELIABILITY_RATINGS_AND_BONUSES: 'https://www.topcoder.com/thrive/articles/Development%20Reliability%20Ratings%20and%20Bonuses',
STOCK_ART_POLICY: 'http://help.topcoder.com/hc/en-us/articles/217481408-Policy-for-Stock-Artwork-in-Design-Submissions',
STUDIO_FONTS_POLICY:
diff --git a/docs/contentful/AppComponent.md b/docs/contentful/AppComponent.md
index a937f7b942..12c3980e17 100644
--- a/docs/contentful/AppComponent.md
+++ b/docs/contentful/AppComponent.md
@@ -46,6 +46,8 @@ Render top spots and list of competitors on specific TCO track.
A block that fetches and renders a job listing page driven by recruitCRM.
+### Type = `EmailSubscribeForm`
+
Generic subscribe for MailChimp tags component.
- **listId** | **String (Required).**
diff --git a/docs/contentful/custom-inline-components-in-markdown-fields.md b/docs/contentful/custom-inline-components-in-markdown-fields.md
index 4961ffe946..da252c165b 100644
--- a/docs/contentful/custom-inline-components-in-markdown-fields.md
+++ b/docs/contentful/custom-inline-components-in-markdown-fields.md
@@ -69,6 +69,22 @@ other types too.
| listId | | ID of MailChimp list to subscribe. |
| interests | empty string | Optional. commas separated string of group ids to which user should be subscribed |
+- #### NewsletterSignupForMembers
+ **Sample use:** ``
+
+ Renders a newsletter signup button that takes user email from his profile
+ information. If the user is not-authenticated, it gets him to the login or
+ registration page, and subscribes him on return. Accepts the following props:
+
+ | Param | Default | Description |
+ | --- | --- | --- |
+ | label | Subscribe for Newsletter | Optional. Custom label to show on the button. |
+ | listId | | ID of MailChimp list to subscribe. |
+ | tags | | ID of MailChimp tags to subscribe. |
+ | buttonTheme | primary-green-md | Theme key(`tc-` is omitted) for the button. See https://community-app.topcoder.com/examples/contentful/contentblock/3k7k1JpnSvIRrJYWs4izYi |
+ | title | Sign up for the Topcoder Newsletter | Modal title |
+ | desc | Do you want to subscribe to this newsletter? | Modal description |
+
- #### VideoModalButton
*Example:* ``
@@ -82,6 +98,14 @@ other types too.
component works only with YouTube videos, and the URL should be similar to
`https://www.youtube.com/embed/mD12LIqdxqk` ().
+- #### NewsletterArchive
+ *Example:* ``
+
+ A list of archive links sorted by descending `sent_date` from a MailChimp's campaign folder. Sould be working under any MarkdownParser component.
+
+ The properties are:
+ - `name` - the unique name of the camplaing foler. It has to be only one name entity. If those duplicate first found will be picked up and rest ignored.
+
## Links
- #### Link
diff --git a/docs/pwa/nginx/server.key b/docs/pwa/nginx/server.key
new file mode 100644
index 0000000000..3e46bd6691
--- /dev/null
+++ b/docs/pwa/nginx/server.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXKekFdnLsjrnq
+4RMF/V6ewrDRwzt9gVJXX8aEemq5wDjrnK1q2SJBrEMQw72T1oIt8TJs+d6HLc0K
+DX3MILdix/r/+ML5bVjTd6HdzqXnbsd9omvZ3a43QKLxGCvqwe0iN8C7106++nik
+3issH6qiQh5p5ERN8gApSyj0/PIu051YCNL8SpsqDiRHtWzZt07ncPFPueINXdRu
+AEb7pod7tIvBnI2kudJx4d2AX+lE7eOhsvCr0eHS3/V03BlprAt3qw7c2ZwLxTYZ
+D/l6NgCoy6AQfq9d7XikTVFx9ZKiuCPVS11PzI6G2pbx5Y6ewHdcfLnPVIDKPfMh
+L3SjmDTNAgMBAAECggEAOLf3kVUUHn/RSrViSmXsF3XDHsiUWhVJG3dH4YxTrfua
+BaIbpNrwSNecJkMzKlGVp365iDimDIRqVIgR7UmCjiuhYvC0lQPaMoSKyum6mjN9
+qwSx4ZCqaC5FxcBVc2EDnc2MpPew7m8gdnWKc+s1E+jSE5/00YdFu5zwgwRa4zSx
+TquwlMGd6AcE1J5YbxYGJRztAl2VKguBJFcSnnFef8xY18GoEO1lt43ef9ijsfL3
+mBccrlLWQmc1CxM8zZ83lD1yW41bcwMhx7XCgRZjhDtNmbyWWJOYoFwojtAxFqG4
+VHFKjY+kNgIWjKZim84GA3tUPS/L832GXYk6SyC6kQKBgQD/HsnCryGTaitjwn+5
+FbPWlBnnGn1hxE36g0u1B3A/mQ3Jut949Dsm9vEoS1gHOQBCc5cE3RXNZ6iZdSDc
+Lf9YzZnchIgjauU9bqkZVI2RSPnNOTjWjXhGtrZxrc4eckRWqbChmYX0qCxokwhb
+leIdmJy7Y0Q6ttVGAHySoC/h7wKBgQDX59mKR1Gm7rKcEqW2aWhz878Xft/OHchh
+THF9EUGHWXOYiKDAPxV6+xg2ZZaPUorMdp588iC3dd0YRn/KSkFlYWIgA8yYkjI7
+Al6pwGgOPw8k2/t1Rxfw2NUJr/19dAqMSyxDZ6W1OsGsdoAIgOMQxx12zENZpX6y
+xcewsWNhAwKBgQC33vbHa/WlC4YONmZbfTrKUp+AouTvC86v2OU9qgjKrYL0e80I
+ne3sHVqeEf915S08t5aGmNlX23f2ciamyjgZRsW324VLEYX7CsCxUvFdXt07fhxq
+9jdTr+g6cmv2IaEDXPXC4qVbOcIX9LC3YYVAk3eSzu6j6pY4B63A99bK3QKBgQDE
+d/mQiGe4BVxJA/sB7Bed9D9+7PhSAu4WBE79pVdBCFhVhHbrmjw8xgN5dKY2U8F0
+X7jHMDovWDTSY0zkUwABdkWppmtmpxrIcdacmDbYR+/K9dd0GDaj91ydTSXaJF94
+3Osxhz7WlNoqy0ak9kwqN1cLhMMA78VEfw/BLRqm6wKBgGUZNlOXQjcAcFjZ12Z4
+3X3tOWjwAPx2D5kT99Jh2BDgzjOci303MDnxI+mb6BQY32mz5+2OlD+bz2qYHVPp
+9+Ir9WNbIl+DCUadRcPuYPAwPSftBEKzH901BBXHnbSkLSWocvLqYxUBjJ64KTh0
+2OTOU4OPRrct2tauUUyPRiBX
+-----END PRIVATE KEY-----
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
new file mode 100644
index 0000000000..19cc61f8d6
--- /dev/null
+++ b/docs/swagger.yaml
@@ -0,0 +1,196 @@
+openapi: 3.0.0
+info:
+ title: Community APP
+ description: Community APP
+ version: 1.0.0
+servers:
+ - url: http://local.topcoder-dev.com:3000
+tags:
+ - name: Profile
+paths:
+ /api/recruit/profile:
+ get:
+ tags:
+ - Profile
+ description: |
+ Get Profile of current user
+
+ **Authorization** All topcoder members are allowed.
+ security:
+ - bearerAuth: []
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/Profile"
+ "401":
+ description: Not authenticated
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/AuthError"
+ "403":
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/AuthError"
+ "404":
+ description: Not Found
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Profile"
+ "500":
+ description: Internal Server Error
+ content:
+ text/plain::
+ schema:
+ type: string
+ post:
+ tags:
+ - Profile
+ description: |
+ Update Profile details of current user
+ **Authorization** All topcoder members are allowed.
+ security:
+ - bearerAuth: []
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ $ref: "#/components/schemas/ProfileUpdate"
+ responses:
+ "204":
+ description: OK
+ "400":
+ description: Bad request
+ content:
+ application/json:
+ schema:
+ oneOf:
+ - $ref: "#/components/schemas/JoiError"
+ - $ref: "#/components/schemas/Error"
+ "401":
+ description: Not authenticated
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/AuthError"
+ "403":
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/AuthError"
+ "404":
+ description: Not Found
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ "500":
+ description: Internal Server Error
+ content:
+ text/plain::
+ schema:
+ type: string
+components:
+ securitySchemes:
+ bearerAuth:
+ type: http
+ scheme: bearer
+ bearerFormat: JWT
+ schemas:
+ Profile:
+ required:
+ - availability
+ properties:
+ phone:
+ type: string
+ description: "The phone number of the user"
+ example: "+1123226666"
+ resume:
+ type: string
+ description: "The resume of the user"
+ availability:
+ type: boolean
+ description: "The availability of the user"
+ default: true
+ example: true
+ skill:
+ type: string
+ description: "The candidate's skills separated via ,"
+ example: "Java,Angular,SQL Server,JavaScript"
+ salaryExpectation:
+ type: integer
+ description: "The candidate expected salary"
+ hasProfile:
+ type: boolean
+ description: "Whether has profile for the user"
+ ProfileUpdate:
+ required:
+ - phone
+ - availability
+ - city
+ - countryName
+ properties:
+ phone:
+ type: string
+ description: "The phone number of the user"
+ example: "(123) 456-7890"
+ city:
+ type: string
+ description: "The member's city"
+ countryName:
+ type: string
+ description: "The member's country"
+ resume:
+ type: string
+ format: binary
+ description: "The resume file of the user"
+ availability:
+ type: boolean
+ description: "The availability of the user"
+ example: true
+ Error:
+ properties:
+ error:
+ type: boolean
+ example: true
+ status:
+ type: integer
+ example: 404
+ url:
+ type: string
+ format: uri
+ errObj:
+ type: object
+ JoiError:
+ required:
+ - message
+ properties:
+ message:
+ type: string
+ AuthError:
+ properties:
+ version:
+ type: string
+ result:
+ type: object
+ properties:
+ success:
+ type: boolean
+ example: false
+ status:
+ type: integer
+ example: 403
+ content:
+ type: object
+ properties:
+ message:
+ type: string
diff --git a/package.json b/package.json
index 3ed6237f7a..45c9302fe6 100644
--- a/package.json
+++ b/package.json
@@ -33,8 +33,8 @@
},
"homepage": "https://github.com/topcoder-platform/community-app#readme",
"engines": {
- "node": "^10.24.1",
- "npm": "^6.14.12"
+ "node": "^8.11.2",
+ "npm": "^5.6.0"
},
"dependencies": {
"@hapi/joi": "^16.1.4",
@@ -172,8 +172,7 @@
"url-parse": "^1.4.1",
"uuid": "^3.3.2",
"valid-url": "^1.0.9",
- "xml2json": "^0.11.2",
- "xss": "^1.0.15"
+ "xml2json": "^0.11.2"
},
"devDependencies": {
"@commitlint/cli": "^8.3.5",
diff --git a/src/server/index.js b/src/server/index.js
index 3ee3671a78..393a72b9a7 100644
--- a/src/server/index.js
+++ b/src/server/index.js
@@ -22,12 +22,14 @@ import { factory as reducerFactory } from 'reducers';
import { redux, server as serverFactory } from 'topcoder-react-utils';
import { getRates as getExchangeRates } from 'services/money';
import { toJson as xmlToJson } from 'utils/xml2json';
-import { promisify } from 'util';
import cdnRouter from './routes/cdn';
+import mailChimpRouter from './routes/mailchimp';
import mockDocuSignFactory from './__mocks__/docu-sign-mock';
import recruitCRMRouter from './routes/recruitCRM';
import mmLeaderboardRouter from './routes/mmLeaderboard';
+import gSheetsRouter from './routes/gSheet';
+import blogRouter from './routes/blog';
import feedsRouter from './routes/feeds';
/* Dome API for topcoder communities */
@@ -40,40 +42,9 @@ global.atob = atob;
const CMS_BASE_URL = `https://app.contentful.com/spaces/${config.SECRET.CONTENTFUL.SPACE_ID}`;
-const getTimestamp = async () => {
- let timestamp;
- try {
- const filePath = path.resolve(__dirname, '../../.build-info');
- if (!filePath.startsWith(path.resolve(__dirname, '../../'))) {
- throw new Error('Invalid file path detected');
- }
-
- const MAX_FILE_SIZE = 10 * 1024; // 10 KB max file size
- const stats = await promisify(fs.stat)(filePath);
- if (stats.size > MAX_FILE_SIZE) {
- throw new Error('File is too large and may cause DoS issues');
- }
-
- const fileContent = await promisify(fs.readFile)(filePath, 'utf-8');
-
- let tsData;
- try {
- tsData = JSON.parse(fileContent);
- } catch (parseErr) {
- throw new Error('Invalid JSON format in file');
- }
-
- if (!tsData || !tsData.timestamp) {
- throw new Error('Timestamp is missing in the JSON file');
- }
-
- timestamp = moment(tsData.timestamp).valueOf();
- } catch (err) {
- console.error('Error:', err.message);
- }
-
- return timestamp;
-};
+let ts = path.resolve(__dirname, '../../.build-info');
+ts = JSON.parse(fs.readFileSync(ts));
+ts = moment(ts.timestamp).valueOf();
const sw = `sw.js${process.env.NODE_ENV === 'production' ? '' : '?debug'}`;
const swScope = '/challenges'; // we are currently only interested in improving challenges pages
@@ -81,7 +52,7 @@ const swScope = '/challenges'; // we are currently only interested in improving
const tcoPattern = new RegExp(/^tco\d{2}\.topcoder(?:-dev)?\.com$/i);
const universalNavUrl = config.UNIVERSAL_NAV_URL;
-const getExtraScripts = ts => [
+const EXTRA_SCRIPTS = [
`