diff --git a/.circleci/config.yml b/.circleci/config.yml index 1e58d6ae06..04ea6facaf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -230,7 +230,8 @@ workflows: filters: branches: only: - - hot-fix + - develop-auth0-sync + - develop # This is alternate dev env for parallel testing - "build-test": context : org-global @@ -260,7 +261,6 @@ workflows: branches: only: - develop - - listing-develop-sync # Production builds are exectuted # when PR is merged to the master # Don't change anything in this configuration diff --git a/__tests__/client/client.jsx b/__tests__/client/client.jsx index cf90a63944..84e6e19b26 100644 --- a/__tests__/client/client.jsx +++ b/__tests__/client/client.jsx @@ -106,7 +106,7 @@ const mockTcAccounts = { decodeToken: () => ({ exp: Date.now() }), getFreshToken: () => Promise.resolve(tokenV3), }; -jest.setMock('tc-accounts', mockTcAccounts); +jest.setMock('@topcoder-platform/tc-auth-lib', mockTcAccounts); /* Mock auth actions */ /* diff --git a/__tests__/shared/components/Header/__snapshots__/index.jsx.snap b/__tests__/shared/components/Header/__snapshots__/index.jsx.snap index e82f28e5b7..06761c8d88 100644 --- a/__tests__/shared/components/Header/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/Header/__snapshots__/index.jsx.snap @@ -165,8 +165,8 @@ exports[`Default render 1`] = ` auth={null} authURLs={ Object { - "href": "https://accounts.topcoder-dev.com/member/registration?utm_source=community-app-main", - "location": "https://accounts.topcoder-dev.com/member?retUrl=%S&utm_source=community-app-main", + "href": "https://accounts-auth0.topcoder-dev.com?utm_source=community-app-main", + "location": "https://accounts-auth0.topcoder-dev.com?retUrl=%S&utm_source=community-app-main", } } loggedIn={true} diff --git a/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap b/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap index 387a544a65..c7007eef45 100644 --- a/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap +++ b/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap @@ -316,7 +316,7 @@ exports[`Matches shallow shapshot 1`] = ` className="src-shared-components-TopcoderFooter-___style__link___3-nzm" > Join Community diff --git a/__tests__/shared/components/tc-communities/Footer.jsx b/__tests__/shared/components/tc-communities/Footer.jsx index 4145cb1dfe..4af4808c33 100644 --- a/__tests__/shared/components/tc-communities/Footer.jsx +++ b/__tests__/shared/components/tc-communities/Footer.jsx @@ -41,8 +41,8 @@ test('render properly', () => { )); @@ -63,8 +63,8 @@ test('render properly', () => { url: 'leaderboard', }]} communityId="wipro" - registerUrl="https://accounts.topcoder-dev.com/member/registration" - loginUrl="https://accounts.topcoder-dev.com/member" + registerUrl="https://accounts-auth0.topcoder-dev.com/member/registration" + loginUrl="https://accounts-auth0.topcoder-dev.com/member" isAuthorized={false} theme={{ container: 'container', diff --git a/__tests__/shared/components/tc-communities/__snapshots__/AccessDenied.jsx.snap b/__tests__/shared/components/tc-communities/__snapshots__/AccessDenied.jsx.snap index 407702adeb..389cd6e649 100644 --- a/__tests__/shared/components/tc-communities/__snapshots__/AccessDenied.jsx.snap +++ b/__tests__/shared/components/tc-communities/__snapshots__/AccessDenied.jsx.snap @@ -20,7 +20,7 @@ exports[`Matches shallow shapshot 1`] = ` > Log In Here diff --git a/__tests__/shared/reducers/auth.js b/__tests__/shared/reducers/auth.js index 5427774916..85ae05645f 100644 --- a/__tests__/shared/reducers/auth.js +++ b/__tests__/shared/reducers/auth.js @@ -24,7 +24,7 @@ const mockActions = { _.merge(actions, mockActions); -jest.setMock('tc-accounts', { +jest.setMock('@topcoder-platform/tc-auth-lib', { decodeToken: () => 'User object', isTokenExpired: () => false, }); diff --git a/__tests__/shared/reducers/challenge.js b/__tests__/shared/reducers/challenge.js index dab9dd39c0..2d4e112a9d 100644 --- a/__tests__/shared/reducers/challenge.js +++ b/__tests__/shared/reducers/challenge.js @@ -11,7 +11,7 @@ import { mock, actions } from 'topcoder-react-lib'; const { mockAction } = mock; -jest.setMock('tc-accounts', { +jest.setMock('@topcoder-platform/tc-auth-lib', { decodeToken: () => 'User object', isTokenExpired: () => false, }); diff --git a/bin/www b/bin/www index 0ed62f7ba6..ef2d8722eb 100644 --- a/bin/www +++ b/bin/www @@ -5,7 +5,7 @@ /* Enables Babel for the server-side code (with exception of this very file). */ require('babel-register')({ ignore: [ - /node_modules\/(?!appirio-tech.*|topcoder|tc-)/, + /node_modules\/(?!appirio-tech.*|topcoder|tc-|@topcoder)/, /node_modules\/topcoder-react-utils/, ], }); diff --git a/config/default.js b/config/default.js index ccf981f212..7f4b987e90 100644 --- a/config/default.js +++ b/config/default.js @@ -78,16 +78,6 @@ module.exports = { }, }, - /* Amount of time [seconds] before expiration of authentication tokens, - * when the frontend will automatically trigger their refreshment. Once - * ready, it will either write to the Redux store fresh token, or will - * remove auth tokens from the store. - * NOTE: With the current implementation of accounts-app this value must be - * smaller than 60 seconds (earlier than 60 seconds before expiration of an - * auth token, a call to the getFreshToken() method returns the old token, - * due to caching). */ - REAUTH_TIME: 55, - /* API key for Segment.io. For development environment the value is set inside * development.json, for production environment it is set via CircleCI * variables. */ @@ -104,7 +94,7 @@ module.exports = { * platform. */ URL: { /* Connector URL of the TC accounts App. */ - ACCOUNTS_APP_CONNECTOR: 'https://accounts.topcoder-dev.com/connector.html', + ACCOUNTS_APP_CONNECTOR: 'https://accounts-auth0.topcoder-dev.com', /* The remote address where the app is deployed. */ APP: 'https://community-app.topcoder-dev.com', @@ -114,7 +104,7 @@ module.exports = { COMMUNITY_APP: 'https://community-app.topcoder-dev.com', ARENA: 'https://arena.topcoder-dev.com', - AUTH: 'http://accounts.topcoder-dev.com', + AUTH: 'https://accounts-auth0.topcoder-dev.com', BASE: 'https://www.topcoder-dev.com', HOME: '/my-dashboard', BLOG: 'https://www.topcoder-dev.com/blog', @@ -129,6 +119,8 @@ module.exports = { BLOCKCHAIN: 'https://blockchain.topcoder-dev.com', COGNITIVE: 'https://cognitive.topcoder-dev.com', ZURICH: 'https://community-app.topcoder-dev.com/__community__/zurich', + COMCAST: 'https://community-app.topcoder-dev.com/__community__/comcast', + CS: 'https://community-app.topcoder-dev.com/__community__/cs', }, /* Dedicated section to group together links to various articles in @@ -152,6 +144,7 @@ module.exports = { STUDIO: 'https://studio.topcoder-dev.com', TCO: 'https://www.topcoder.com/tco', TCO17: 'https://tco17.topcoder.com/', + TCO19: 'https://community-app.topcoder-dev.com/__community__/tco19', TOPGEAR: 'https://dev-topgear.wipro.com', @@ -384,8 +377,8 @@ module.exports = { ], HEADER_MENU_THEME: 'light', HEADER_AUTH_URLS: { - href: 'https://accounts.topcoder-dev.com/member/registration?utm_source=community-app-main', - location: 'https://accounts.topcoder-dev.com/member?retUrl=%S&utm_source=community-app-main', + href: 'https://accounts-auth0.topcoder-dev.com?utm_source=community-app-main', + location: 'https://accounts-auth0.topcoder-dev.com?retUrl=%S&utm_source=community-app-main', }, ACCOUNT_MENU: [ { diff --git a/config/jest/default.js b/config/jest/default.js index 8af45e1d4c..9fb5d0bfd6 100644 --- a/config/jest/default.js +++ b/config/jest/default.js @@ -1,7 +1,7 @@ const config = require('topcoder-react-utils/config/jest/default'); const nodeConfig = require('config'); -config.transformIgnorePatterns[0] = '/node_modules/(?!appirio-tech|topcoder|tc-)'; +config.transformIgnorePatterns[0] = '/node_modules/(?!appirio-tech|topcoder|tc-|@topcoder)'; // config.testMatch[0] = '**/__tests__/shared/containers/challenge-listing/FilterPanel.jsx'; // Include the directories whose tests has been written to minimize coverage time diff --git a/config/production.js b/config/production.js index 405c90e93b..44f89c1ef9 100644 --- a/config/production.js +++ b/config/production.js @@ -26,7 +26,7 @@ module.exports = { * as a more verbose name for the param. */ COMMUNITY_APP: 'https://community-app.topcoder.com', - AUTH: 'https://accounts.topcoder.com', + AUTH: 'https://accounts-auth0.topcoder.com', BASE: 'https://www.topcoder.com', HOME: '/my-dashboard', COMMUNITY: 'https://community.topcoder.com', @@ -39,8 +39,9 @@ module.exports = { IOS: 'https://ios.topcoder.com', /* Connector URL of the TC accounts App. */ - ACCOUNTS_APP_CONNECTOR: 'https://accounts.topcoder.com/connector.html', + ACCOUNTS_APP_CONNECTOR: 'https://accounts-auth0.topcoder.com/', TCO17: 'https://tco17.topcoder.com/', + TCO19: 'https://tco19.topcoder.com/', TOPGEAR: 'https://topgear-app.wipro.com', @@ -50,6 +51,8 @@ module.exports = { BLOCKCHAIN: 'https://blockchain.topcoder.com', COGNITIVE: 'https://cognitive.topcoder.com', ZURICH: 'https://zurich.topcoder.com', + COMCAST: 'https://comcast.topcoder.com', + CS: 'https://cs.topcoder.com', }, EMAIL_VERIFY_URL: 'http://www.topcoder.com/settings/account/changeEmail', }, @@ -184,8 +187,8 @@ module.exports = { ], HEADER_MENU_THEME: 'light', HEADER_AUTH_URLS: { - href: 'https://accounts.topcoder.com/member/registration?utm_source=community-app-main', - location: 'https://accounts.topcoder.com/member?retUrl=%S&utm_source=community-app-main', + href: 'https://accounts-auth0.topcoder.com?utm_source=community-app-main', + location: 'https://accounts-auth0.topcoder.com?retUrl=%S&utm_source=community-app-main', }, ACCOUNT_MENU: [ { diff --git a/config/webpack/development.js b/config/webpack/development.js index a7b910a4d3..bc853989aa 100644 --- a/config/webpack/development.js +++ b/config/webpack/development.js @@ -17,7 +17,7 @@ const standardDevelopmentConfig = configFactory({ const jsxRule = standardDevelopmentConfig.module.rules.find(rule => rule.loader === 'babel-loader'); jsxRule.exclude = [ - /node_modules[\\/](?!appirio-tech.*|topcoder|tc-)/, + /node_modules[\\/](?!appirio-tech.*|topcoder|tc-|@topcoder)/, /src[\\/]assets[\\/]fonts/, /src[\\/]assets[\\/]images[\\/]dashboard/, ]; diff --git a/config/webpack/production.js b/config/webpack/production.js index 4023147b4d..ab95dbac37 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -24,7 +24,7 @@ const standardDevelopmentConfig = configFactory({ const jsxRule = standardDevelopmentConfig.module.rules.find(rule => rule.loader === 'babel-loader'); jsxRule.exclude = [ - /node_modules[\\/](?!appirio-tech.*|topcoder|tc-)/, + /node_modules[\\/](?!appirio-tech.*|topcoder|tc-|@topcoder)/, /src[\\/]assets[\\/]fonts/, /src[\\/]assets[\\/]images[\\/]dashboard/, ]; diff --git a/package.json b/package.json index eb006f35d7..113c861e6d 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ }, "dependencies": { "@hapi/joi": "^16.1.4", + "@topcoder-platform/tc-auth-lib": "topcoder-platform/tc-auth-lib#1.0.1", "aos": "^2.3.4", "atob": "^2.1.1", "babel-register": "^6.26.0", @@ -137,10 +138,9 @@ "showdown": "^1.8.6", "slick-carousel": "^1.8.1", "supertest": "^3.1.0", - "tc-accounts": "git+https://github.com/appirio-tech/accounts-app.git#dev", "tc-core-library-js": "github:appirio-tech/tc-core-library-js#v2.6.3", "tc-ui": "^1.0.12", - "topcoder-react-lib": "1.0.8", + "topcoder-react-lib": "1.1.0", "topcoder-react-ui-kit": "2.0.1", "topcoder-react-utils": "0.7.8", "turndown": "^4.0.2", diff --git a/src/client/index.jsx b/src/client/index.jsx index c5ad157536..b44745e76e 100644 --- a/src/client/index.jsx +++ b/src/client/index.jsx @@ -11,7 +11,7 @@ import { configureConnector, decodeToken, getFreshToken, -} from 'tc-accounts'; +} from '@topcoder-platform/tc-auth-lib'; import { actions, logger, errors } from 'topcoder-react-lib'; import { client, redux } from 'topcoder-react-utils'; @@ -113,10 +113,9 @@ function authenticate(store) { if (tctV2) time = decodeToken(tctV2).exp; if (userV3) time = Math.min(time, userV3.exp); if (time < Number.MAX_VALUE) { - time = 1000 * (time - window.CONFIG.REAUTH_TIME); - time = Math.max(0, time - Date.now()); + time = Math.max(1000, (time * 1000) - Date.now()); logger.log('Reauth scheduled in', time / 1000, 'seconds'); - setTimeout(() => authenticate(store), time); + setTimeout(() => authenticate(store), time + 1000); } }); } diff --git a/src/shared/actions/challenge-listing/index.js b/src/shared/actions/challenge-listing/index.js index 62d5db8c49..3592af19f9 100644 --- a/src/shared/actions/challenge-listing/index.js +++ b/src/shared/actions/challenge-listing/index.js @@ -4,7 +4,7 @@ import _ from 'lodash'; import { createActions } from 'redux-actions'; -import { decodeToken } from 'tc-accounts'; +import { decodeToken } from '@topcoder-platform/tc-auth-lib'; import 'isomorphic-fetch'; import { processSRM } from 'utils/tc'; import { errors, services } from 'topcoder-react-lib'; diff --git a/src/shared/components/TopcoderFooter/index.jsx b/src/shared/components/TopcoderFooter/index.jsx index 1910102404..7d7b2909cd 100644 --- a/src/shared/components/TopcoderFooter/index.jsx +++ b/src/shared/components/TopcoderFooter/index.jsx @@ -1,8 +1,9 @@ +import cookies from 'browser-cookies'; import moment from 'moment'; import PT from 'prop-types'; import React from 'react'; -import { config } from 'topcoder-react-utils'; +import { config, isomorphy } from 'topcoder-react-utils'; import FacebookIcon from './icons/icon-fb.svg'; import YouTubeIcon from './icons/icon-youtube.svg'; @@ -33,6 +34,9 @@ Link.propTypes = { export default function TopcoderFooter() { const base = config.URL.BASE; + const authUrl = config.URL.AUTH; + const retUrl = isomorphy.isClientSide() ? encodeURIComponent(window.location.href) : ''; + const loggedIn = isomorphy.isClientSide() && cookies.get('tcjwt') !== null; const currentYear = moment().year(); return (
@@ -90,7 +94,9 @@ export default function TopcoderFooter() {
    Admins Contact Us - Join Community + {!loggedIn + && Join Community + } About Community Changelog Talk to Sales diff --git a/src/shared/components/challenge-detail/MySubmissions/index.jsx b/src/shared/components/challenge-detail/MySubmissions/index.jsx index 8687914a85..824b29d0d6 100644 --- a/src/shared/components/challenge-detail/MySubmissions/index.jsx +++ b/src/shared/components/challenge-detail/MySubmissions/index.jsx @@ -7,7 +7,7 @@ import PT from 'prop-types'; import _ from 'lodash'; import { goToLogin } from 'utils/tc'; import LoadingIndicator from 'components/LoadingIndicator'; -import { isTokenExpired } from 'tc-accounts'; +import { isTokenExpired } from '@topcoder-platform/tc-auth-lib'; import SubmissionsList from './SubmissionsList'; import SubmissionsDetail from './SubmissionsDetail'; diff --git a/src/shared/components/challenge-detail/Submissions/index.jsx b/src/shared/components/challenge-detail/Submissions/index.jsx index bf0beda012..380e3cf9ac 100644 --- a/src/shared/components/challenge-detail/Submissions/index.jsx +++ b/src/shared/components/challenge-detail/Submissions/index.jsx @@ -11,7 +11,7 @@ import _ from 'lodash'; import { connect } from 'react-redux'; import { config } from 'topcoder-react-utils'; import { submission as submissionUtils } from 'topcoder-react-lib'; -import { isTokenExpired } from 'tc-accounts'; +import { isTokenExpired } from '@topcoder-platform/tc-auth-lib'; import cn from 'classnames'; import { PrimaryButton } from 'topcoder-react-ui-kit'; diff --git a/src/shared/components/tc-communities/Header/index.jsx b/src/shared/components/tc-communities/Header/index.jsx index c610f947e6..4c15cac657 100644 --- a/src/shared/components/tc-communities/Header/index.jsx +++ b/src/shared/components/tc-communities/Header/index.jsx @@ -12,7 +12,12 @@ import DesktopSubMenu from 'components/TopcoderHeader/desktop/SubMenu'; import React from 'react'; import PT from 'prop-types'; import { Avatar, PrimaryButton, Button } from 'topcoder-react-ui-kit'; -import { config, Link, NavLink } from 'topcoder-react-utils'; +import { + config, + Link, + NavLink, + isomorphy, +} from 'topcoder-react-utils'; import { getRatingColor } from 'utils/tc'; import Dropdown from 'components/tc-communities/Dropdown'; import { themr } from 'react-css-super-themr'; @@ -47,10 +52,13 @@ function Header(props) { onMobileToggleClick, profile, theme, - logoutRedirect, meta, } = props; + let { + logoutRedirect, + } = props; + const BASE_URL = config.URL.BASE; const AUTH_URL = config.URL.AUTH; const normalizedProfile = profile && _.clone(profile); @@ -59,6 +67,10 @@ function Header(props) { meta.competitorsGroupIds, ) : []; + if (_.isEmpty(logoutRedirect) && isomorphy.isClientSide()) { + logoutRedirect = window.location.href; + } + let userSubMenu; if (profile) { userSubMenu = { @@ -81,7 +93,7 @@ function Header(props) { icon: , // TODO: In addition to hitting ${AUTH_URL}/logout, which logs out // from the accounts-app, we should wipe out auth cookies! - link: `${AUTH_URL}/logout?retUrl=${logoutRedirect}`, + link: `${AUTH_URL}?logout=true&retUrl=${encodeURIComponent(logoutRedirect)}`, title: 'Log Out', }], }; diff --git a/src/shared/containers/Dashboard/index.jsx b/src/shared/containers/Dashboard/index.jsx index 552fa5cd59..4ecc310a2b 100644 --- a/src/shared/containers/Dashboard/index.jsx +++ b/src/shared/containers/Dashboard/index.jsx @@ -25,7 +25,7 @@ import { updateChallengeType } from 'utils/challenge'; import challengeListingActions from 'actions/challenge-listing'; import communityActions from 'actions/tc-communities'; -import { isTokenExpired, decodeToken } from 'tc-accounts'; +import { isTokenExpired, decodeToken } from '@topcoder-platform/tc-auth-lib'; import { config, isomorphy } from 'topcoder-react-utils'; import './styles.scss'; diff --git a/src/shared/containers/EmailVerification/index.jsx b/src/shared/containers/EmailVerification/index.jsx index 66bc337c4b..e425db7c5a 100644 --- a/src/shared/containers/EmailVerification/index.jsx +++ b/src/shared/containers/EmailVerification/index.jsx @@ -8,7 +8,7 @@ import PT from 'prop-types'; import {connect} from "react-redux"; import { actions } from "topcoder-react-lib"; import { Redirect } from 'react-router'; -import {isTokenExpired} from "tc-accounts"; +import {isTokenExpired} from '@topcoder-platform/tc-auth-lib'; import * as queryString from 'query-string'; import LoadingIndicator from 'components/LoadingIndicator'; import Error404 from 'components/Error404'; diff --git a/src/shared/containers/Settings.jsx b/src/shared/containers/Settings.jsx index 40009cef92..dcbaf86ad0 100644 --- a/src/shared/containers/Settings.jsx +++ b/src/shared/containers/Settings.jsx @@ -6,7 +6,7 @@ import React from 'react'; import PT from 'prop-types'; import { connect } from 'react-redux'; -import { isTokenExpired } from 'tc-accounts'; +import { isTokenExpired } from '@topcoder-platform/tc-auth-lib'; import { goToLogin } from 'utils/tc'; import { actions } from 'topcoder-react-lib'; diff --git a/src/shared/containers/challenge-detail/index.jsx b/src/shared/containers/challenge-detail/index.jsx index 1dc074aee0..3c2efdf568 100644 --- a/src/shared/containers/challenge-detail/index.jsx +++ b/src/shared/containers/challenge-detail/index.jsx @@ -38,6 +38,7 @@ import { COMPETITION_TRACKS, COMPETITION_TRACKS_V3, SUBTRACKS, + CHALLENGE_STATUS, } from 'utils/tc'; import { config, MetaTags } from 'topcoder-react-utils'; import { actions } from 'topcoder-react-lib'; @@ -406,7 +407,7 @@ class ChallengeDetailPageContainer extends React.Component { } - const submissionEnded = status === 'COMPLETED' + const submissionEnded = status === CHALLENGE_STATUS.COMPLETED || (!_.some(phases, { name: 'Submission', isOpen: true }) && !_.some(phases, { name: 'Checkpoint Submission', isOpen: true })); @@ -849,9 +850,9 @@ const mapDispatchToProps = (dispatch) => { dispatch(a.fetchCheckpointsDone(tokens.tokenV2, ch.legacyId)); } else dispatch(a.dropCheckpoints()); } else dispatch(a.dropCheckpoints()); - if (ch.status === 'COMPLETED') { - dispatch(a.loadResultsInit(challengeId)); - dispatch(a.loadResultsDone(tokens, challengeId, ch.track.toLowerCase())); + if (ch.status === CHALLENGE_STATUS.COMPLETED) { + dispatch(a.loadResultsInit(ch.legacyId)); + dispatch(a.loadResultsDone(tokens, ch.legacyId, ch.track.toLowerCase())); } else dispatch(a.dropResults()); return res; }); diff --git a/src/shared/reducers/tc-communities/index.js b/src/shared/reducers/tc-communities/index.js index b915416d12..5ab21acf3d 100644 --- a/src/shared/reducers/tc-communities/index.js +++ b/src/shared/reducers/tc-communities/index.js @@ -8,7 +8,7 @@ import _ from 'lodash'; import actions from 'actions/tc-communities'; import { logger, services, errors } from 'topcoder-react-lib'; import { handleActions } from 'redux-actions'; -import { decodeToken } from 'tc-accounts'; +import { decodeToken } from '@topcoder-platform/tc-auth-lib'; import { getAuthTokens } from 'utils/tc'; import { STATE as JOIN_COMMUNITY } from 'components/tc-communities/JoinCommunity'; import { getCommunityId } from 'server/services/communities'; diff --git a/src/shared/routes/Communities/Blockchain/Routes.jsx b/src/shared/routes/Communities/Blockchain/Routes.jsx index bcf49f27bf..6ede568403 100644 --- a/src/shared/routes/Communities/Blockchain/Routes.jsx +++ b/src/shared/routes/Communities/Blockchain/Routes.jsx @@ -57,6 +57,7 @@ export default function Blockchain({ base, member, meta }) { baseUrl={base} hideJoinNow pageId={match.params.pageId || 'home'} + logoutRedirect={config.URL.COMMUNITIES.BLOCKCHAIN} />