fix(#728): transfer auth

test-b
Rakov 2 years ago
parent 0c5a1aac4f
commit e4cbf54419
  1. 164
      .drone.yml
  2. 66
      Makefile
  3. 2
      package.json
  4. 26
      public/silent-refresh.html
  5. 5
      src/components/AccessTimer/index.tsx
  6. 3
      src/components/Input/styled.tsx
  7. 3
      src/components/SimplePopup/styled.tsx
  8. 59
      src/config/clients/facr.tsx
  9. 65
      src/config/clients/fqtv.tsx
  10. 38
      src/config/clients/india.tsx
  11. 34
      src/config/clients/insports.tsx
  12. 30
      src/config/clients/instat.tsx
  13. 55
      src/config/clients/lff.tsx
  14. 67
      src/config/clients/tunisia.tsx
  15. 13
      src/config/clients/types.tsx
  16. 4
      src/config/env.tsx
  17. 8
      src/config/lexics/authLexics.tsx
  18. 4
      src/config/pages.tsx
  19. 4
      src/config/routes.tsx
  20. 6
      src/features/App/AuthenticatedApp.tsx
  21. 5
      src/features/App/index.tsx
  22. 16
      src/features/AuthServiceApp/components/App/index.tsx
  23. 15
      src/features/AuthServiceApp/components/ChangePassword/hooks.tsx
  24. 5
      src/features/AuthServiceApp/components/ConfirmPopup/index.tsx
  25. 3
      src/features/AuthServiceApp/components/ConfirmPopup/styled.tsx
  26. 5
      src/features/AuthServiceApp/components/Login/hooks.tsx
  27. 4
      src/features/AuthServiceApp/components/Login/index.tsx
  28. 4
      src/features/AuthServiceApp/components/Logo/index.tsx
  29. 5
      src/features/AuthServiceApp/components/Oauth/hooks.tsx
  30. 9
      src/features/AuthServiceApp/components/Oauth/index.tsx
  31. 2
      src/features/AuthServiceApp/components/RecoveryPopup/hooks.tsx
  32. 3
      src/features/AuthServiceApp/components/RecoveryPopup/styled.tsx
  33. 4
      src/features/AuthServiceApp/components/RegisterPopup/styled.tsx
  34. 5
      src/features/AuthServiceApp/components/Registration/hooks.tsx
  35. 8
      src/features/AuthServiceApp/components/Registration/index.tsx
  36. 64
      src/features/AuthServiceApp/config/clients/facr.tsx
  37. 67
      src/features/AuthServiceApp/config/clients/fqtv.tsx
  38. 24
      src/features/AuthServiceApp/config/clients/index.tsx
  39. 42
      src/features/AuthServiceApp/config/clients/india.tsx
  40. 42
      src/features/AuthServiceApp/config/clients/insports.tsx
  41. 41
      src/features/AuthServiceApp/config/clients/instat.tsx
  42. 57
      src/features/AuthServiceApp/config/clients/lff.tsx
  43. 70
      src/features/AuthServiceApp/config/clients/tunisia.tsx
  44. 31
      src/features/AuthServiceApp/config/clients/types.tsx
  45. 6
      src/features/AuthServiceApp/config/pages.tsx
  46. 17
      src/features/AuthServiceApp/config/routes.tsx
  47. 7
      src/features/AuthServiceApp/helpers/getAuthUrl/index.tsx
  48. 2
      src/features/AuthServiceApp/hooks/useAuthFields.tsx
  49. 35
      src/features/AuthServiceApp/index.tsx
  50. 4
      src/features/AuthServiceApp/requests/auth.tsx
  51. 4
      src/features/AuthServiceApp/requests/changePassword.tsx
  52. 6
      src/features/AuthServiceApp/requests/loginCheck.tsx
  53. 4
      src/features/AuthServiceApp/requests/register.tsx
  54. 5
      src/features/AuthServiceApp/requests/resendConfirmation.tsx
  55. 2
      src/features/AuthServiceApp/styled.tsx
  56. 4
      src/features/AuthStore/helpers.tsx
  57. 54
      src/features/AuthStore/hooks/useAuth.tsx
  58. 17
      src/features/Background/index.tsx
  59. 3
      src/features/BuyMatchPopup/components/PackageSelectionStep/index.tsx
  60. 3
      src/features/Menu/index.tsx
  61. 12
      src/features/Theme/index.tsx
  62. 12
      src/features/UserAccount/components/PersonalInfoForm/hooks/useUserInfo.tsx
  63. 5
      src/features/UserAccount/components/PersonalInfoForm/index.tsx
  64. 2
      src/helpers/cookie/index.tsx
  65. 4
      src/index.tsx
  66. 1
      src/react-app-env.d.ts
  67. 4
      src/requests/checkDevice.tsx
  68. 4
      src/requests/getGeoInfo.tsx
  69. 2
      src/utilits/mirage/server.ts

@ -51,47 +51,6 @@ steps:
depends_on:
- make-prod
- name: make-auth
image: node:16-alpine
environment:
REACT_APP_STRIPE_PK:
from_secret: REACT_APP_STRIPE_PK
commands:
- apk add --no-cache make
- make auth-production-build
depends_on:
- npm-install
- name: deploy-S3-auth
image: amazon/aws-cli:latest
environment:
AWS_ACCESS_KEY_ID:
from_secret: AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY:
from_secret: AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION:
from_secret: AWS_DEFAULT_REGION
AWS_MAX_ATTEMPTS: 10
commands:
- aws s3 sync build_auth s3://insports-auth --delete
- aws cloudfront create-invalidation --distribution-id EERIKX9X2SRPJ --paths "/*"
depends_on:
- make-auth
- name: deploy-old-auth-server
image: node:16-alpine
environment:
SSH_KEY_AUTH:
from_secret: SSH_KEY_AUTH
commands:
- apk add --no-cache openssh-client rsync
- eval $(ssh-agent -s)
- echo -n "$SSH_KEY_AUTH" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- ssh-keyscan auth.insports.tv >> ~/.ssh/known_hosts
- rsync -v -r -C build_auth/ ubuntu@auth.insports.tv:/home/ubuntu/ott-auth/src/frontend/
depends_on:
- make-auth
- name: make-india
image: node:16-alpine
@ -669,129 +628,6 @@ steps:
- aws s3 sync build s3://instat-frontend-test-j --delete
- aws cloudfront create-invalidation --distribution-id EC35D25OP7FSL --paths "/*"
---
kind: pipeline
type: docker
name: deploy test-auth
concurrency:
limit: 1
platform:
os: linux
arch: amd64
trigger:
ref:
- refs/heads/test-auth
steps:
- name: npm-install
image: node:16-alpine
environment:
REACT_APP_STRIPE_PK:
from_secret: REACT_APP_STRIPE_PK
commands:
- apk add --no-cache make
- npm install --legacy-peer-deps
- name: make-auth
image: node:16-alpine
environment:
REACT_APP_STRIPE_PK:
from_secret: REACT_APP_STRIPE_PK
commands:
- apk add --no-cache make
- make auth-build
depends_on:
- npm-install
- name: deploy-S3-auth
image: amazon/aws-cli:latest
environment:
AWS_ACCESS_KEY_ID:
from_secret: AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY:
from_secret: AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION:
from_secret: AWS_DEFAULT_REGION
AWS_MAX_ATTEMPTS: 10
commands:
- aws s3 sync build_auth s3://insports-auth-test --delete
- aws cloudfront create-invalidation --distribution-id E10YI3RFOZZDLZ --paths "/*"
depends_on:
- make-auth
---
kind: pipeline
type: docker
name: deploy auth prod
concurrency:
limit: 1
platform:
os: linux
arch: amd64
trigger:
ref:
- refs/heads/auth
steps:
- name: npm-install
image: node:16-alpine
environment:
REACT_APP_STRIPE_PK:
from_secret: REACT_APP_STRIPE_PK
commands:
- apk add --no-cache make
- npm install --legacy-peer-deps
- name: make-auth
image: node:16-alpine
environment:
REACT_APP_STRIPE_PK:
from_secret: REACT_APP_STRIPE_PK
commands:
- apk add --no-cache make
- make auth-production-build
depends_on:
- npm-install
- name: deploy-S3-auth
image: amazon/aws-cli:latest
environment:
AWS_ACCESS_KEY_ID:
from_secret: AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY:
from_secret: AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION:
from_secret: AWS_DEFAULT_REGION
AWS_MAX_ATTEMPTS: 10
commands:
- aws s3 sync build_auth s3://insports-auth --delete
- aws cloudfront create-invalidation --distribution-id EERIKX9X2SRPJ --paths "/*"
depends_on:
- make-auth
- name: deploy-old-auth-server
image: node:16-alpine
environment:
SSH_KEY_AUTH:
from_secret: SSH_KEY_AUTH
commands:
- apk add --no-cache openssh-client rsync
- eval $(ssh-agent -s)
- echo -n "$SSH_KEY_AUTH" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- ssh-keyscan auth.insports.tv >> ~/.ssh/known_hosts
- rsync -v -r -C build_auth/ ubuntu@auth.insports.tv:/home/ubuntu/ott-auth/src/frontend/
depends_on:
- make-auth
---
kind: pipeline
type: docker

@ -2,7 +2,6 @@ install:
npm install
develop:
REACT_APP_TYPE=ott \
REACT_APP_CLIENT=insports \
npm start
@ -10,140 +9,124 @@ clean:
rm -rf build
build: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
npm run build
build-stage: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=preproduction \
REACT_APP_CLIENT=insports \
REACT_APP_STRIPE_PK=pk_live_51J5TEYEDSxVnTgDW5XxhC6ntKZKddXgKHq5HOCDmJTdfSKluMYCdLHOcUA3Miuy8HesxG1eS4c0dQRQpMsEHRrQL00USpu5xIq \
npm run build
build-a: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-a \
npm run build
build-b: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-b \
npm run build
build-c: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-c \
npm run build
build-d: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-d \
npm run build
build-e: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-e \
npm run build
build-f: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-f \
npm run build
build-g: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-g \
npm run build
build-h: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-h \
npm run build
build-i: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-i \
npm run build
build-j: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=insports \
REACT_APP_STAGE=test-j \
npm run build
auth-build:
rm -rf build_auth
# после успешного тестирования удаляем
# auth-build:
# rm -rf build_auth
REACT_APP_TYPE=auth-service \
REACT_APP_ENV=staging \
REACT_APP_GOOGLE_CLIENT_ID=1022673777479-43mqb9lsqkpcr47umuvsoo0eemfpljf5.apps.googleusercontent.com \
REACT_APP_FACEBOOK_CLIENT_ID=798254931203361 \
BUILD_PATH=build_auth \
GENERATE_SOURCEMAP=false \
npx react-scripts build
# REACT_APP_TYPE=auth-service \
# REACT_APP_ENV=staging \
# REACT_APP_GOOGLE_CLIENT_ID=1022673777479-43mqb9lsqkpcr47umuvsoo0eemfpljf5.apps.googleusercontent.com \
# REACT_APP_FACEBOOK_CLIENT_ID=798254931203361 \
# BUILD_PATH=build_auth \
# GENERATE_SOURCEMAP=false \
# npx react-scripts build
npx gzipper --verbose build_auth
# npx gzipper --verbose build_auth
auth-production-build:
rm -rf build_auth
# auth-production-build:
# rm -rf build_auth
REACT_APP_TYPE=auth-service \
REACT_APP_ENV=production \
REACT_APP_GOOGLE_CLIENT_ID=1022673777479-43mqb9lsqkpcr47umuvsoo0eemfpljf5.apps.googleusercontent.com \
REACT_APP_FACEBOOK_CLIENT_ID=798254931203361 \
BUILD_PATH=build_auth \
GENERATE_SOURCEMAP=false \
npx react-scripts build
# REACT_APP_TYPE=auth-service \
# REACT_APP_ENV=production \
# REACT_APP_GOOGLE_CLIENT_ID=1022673777479-43mqb9lsqkpcr47umuvsoo0eemfpljf5.apps.googleusercontent.com \
# REACT_APP_FACEBOOK_CLIENT_ID=798254931203361 \
# BUILD_PATH=build_auth \
# GENERATE_SOURCEMAP=false \
# npx react-scripts build
npx gzipper --verbose build_auth
# npx gzipper --verbose build_auth
facr-build: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=facr \
npm run build
india-build: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=india \
npm run build
tunisia-build: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=tunisia \
npm run build
fqtv-build: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=fqtv \
npm run build
lff-build: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=lff \
npm run build
@ -157,14 +140,12 @@ rustat-build: clean
.PHONY: build
prod: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=production \
REACT_APP_CLIENT=insports \
REACT_APP_STRIPE_PK=pk_live_51J5TEYEDSxVnTgDW5XxhC6ntKZKddXgKHq5HOCDmJTdfSKluMYCdLHOcUA3Miuy8HesxG1eS4c0dQRQpMsEHRrQL00USpu5xIq \
npm run build && cp -r .well-known build
preprod: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=preproduction \
REACT_APP_STAGE=test \
REACT_APP_CLIENT=insports \
@ -173,7 +154,6 @@ preprod: clean
india-prod:
rm -rf build_india && \
REACT_APP_TYPE=ott \
REACT_APP_ENV=production \
REACT_APP_CLIENT=india \
REACT_APP_STRIPE_PK=pk_live_51J5TEYEDSxVnTgDW5XxhC6ntKZKddXgKHq5HOCDmJTdfSKluMYCdLHOcUA3Miuy8HesxG1eS4c0dQRQpMsEHRrQL00USpu5xIq \
@ -182,7 +162,6 @@ india-prod:
facr-prod:
rm -rf build_facr && \
REACT_APP_TYPE=ott \
REACT_APP_ENV=production \
REACT_APP_STRIPE_PK=pk_live_51J5TEYEDSxVnTgDW5XxhC6ntKZKddXgKHq5HOCDmJTdfSKluMYCdLHOcUA3Miuy8HesxG1eS4c0dQRQpMsEHRrQL00USpu5xIq \
REACT_APP_CLIENT=facr \
@ -191,7 +170,6 @@ facr-prod:
lff-prod:
rm -rf build_lff && \
REACT_APP_TYPE=ott \
REACT_APP_ENV=production \
REACT_APP_STRIPE_PK=pk_live_51J5TEYEDSxVnTgDW5XxhC6ntKZKddXgKHq5HOCDmJTdfSKluMYCdLHOcUA3Miuy8HesxG1eS4c0dQRQpMsEHRrQL00USpu5xIq \
REACT_APP_CLIENT=lff \
@ -200,7 +178,6 @@ lff-prod:
diwansport-prod:
rm -rf build_tunisia && \
REACT_APP_TYPE=ott \
REACT_APP_ENV=production \
REACT_APP_STRIPE_PK=pk_live_51J5TEYEDSxVnTgDW5XxhC6ntKZKddXgKHq5HOCDmJTdfSKluMYCdLHOcUA3Miuy8HesxG1eS4c0dQRQpMsEHRrQL00USpu5xIq \
REACT_APP_CLIENT=tunisia \
@ -209,7 +186,6 @@ diwansport-prod:
fqtv-prod:
rm -rf build_fqtv && \
REACT_APP_TYPE=ott \
REACT_APP_ENV=production \
REACT_APP_STRIPE_PK=pk_live_51J5TEYEDSxVnTgDW5XxhC6ntKZKddXgKHq5HOCDmJTdfSKluMYCdLHOcUA3Miuy8HesxG1eS4c0dQRQpMsEHRrQL00USpu5xIq \
REACT_APP_CLIENT=fqtv \

@ -13,8 +13,6 @@
"stylelint": "stylelint \"src/**/*.{ts,tsx}\"",
"storybook": "start-storybook -p 9009 -s public",
"build-storybook": "build-storybook -s public",
"start:auth": "REACT_APP_TYPE=auth-service react-scripts start",
"test:auth": "REACT_APP_TYPE=auth-service react-scripts test",
"facr": "REACT_APP_CLIENT=facr react-scripts start",
"lff": "REACT_APP_CLIENT=lff react-scripts start",
"india": "REACT_APP_CLIENT=india react-scripts start",

@ -11,32 +11,6 @@
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
new Oidc.UserManager().signinSilentCallback()
.then(() => {
const refreshToken = new URLSearchParams(document.location.search).get('refresh_token');
if (refreshToken && /iPad|iPhone|iPod/.test(navigator.userAgent)) {
const getDomain = () => {
if (! '%NODE_ENV%' || '%NODE_ENV%' === 'development') {
return 'localhost';
} else {
return '.insports.tv';
}
};
const parseJwt = (value) => {
const base64Url = value.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map((c) => `%${(`00${c.charCodeAt(0).toString(16)}`).slice(-2)}`).join(''));
return JSON.parse(jsonPayload);
};
const saveRefreshToken = (value) => {
const ref = parseJwt(value);
const expires = `expires=${new Date((ref.exp * 1000)).toUTCString()}`;
document.cookie = `refresh_token=${value};${expires};path=/;domain=${getDomain()};secure;SameSite=None`;
};
saveRefreshToken(refreshToken);
}
})
.catch((err) => {
console.error('OIDC: silent refresh callback error', err);
});

@ -7,6 +7,7 @@ import {
import { T9n } from 'features/T9n'
import { Icon } from 'features/Icon'
import { useAuthStore } from 'features/AuthStore'
import { LogoutAction } from 'features/AuthStore/hooks/useAuth'
import {
AccessTimerContainer,
@ -107,7 +108,7 @@ export const AccessTimer = ({
<T9n t='sign_in_full_game' />
</SignText>
</TimerContainer>
<SignInBtn onClick={() => logout('saveToken')} id='match_register'>
<SignInBtn onClick={() => logout(LogoutAction.SaveToken)} id='match_register'>
<T9n t='sign_in' />
</SignInBtn>
</AccessTimerContainer>
@ -119,7 +120,7 @@ export const AccessTimer = ({
headerName='sec_60'
mainText='continue_watching'
buttonName='sign_in'
onHandle={() => logout('saveToken')}
onHandle={() => logout(LogoutAction.SaveToken)}
icon={<Icon refIcon='ExclamationPoint' />}
/>
)}

@ -2,8 +2,7 @@ import styled, { css } from 'styled-components/macro'
import { devices } from 'config/devices'
import { isMobileDevice } from 'config/userAgent'
import { client } from 'features/AuthServiceApp/config/clients'
import { client } from 'config'
export const Wrapper = styled.div`
background-color: ${({ theme }) => theme.colors.inputs};

@ -1,6 +1,6 @@
import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config'
import { client, isMobileDevice } from 'config'
import { ModalWindow } from 'features/Modal/styled'
import {
@ -10,7 +10,6 @@ import {
HeaderTitle,
} from 'features/AuthServiceApp/components/RegisterPopup/styled'
import { Header as BaseHeader } from 'features/PopupComponents'
import { client } from 'features/AuthServiceApp/config/clients/index'
export const Modal = styled(BaseModal)`

@ -1,4 +1,4 @@
import { css } from 'styled-components/macro'
import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent'
@ -18,11 +18,21 @@ const params = {
_p_version: 'facrtv',
}
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background-color: #00257A;
`
export const facr: ClientConfig = {
auth: {
clientId: ClientIds.Facr,
metaDataUrlParams: `?hash=${randomHash()}`,
},
background: Background,
currencyBadge: {
color: '#333333',
secondColor: 'rgba(255, 255, 255, 0.7)',
@ -31,9 +41,8 @@ export const facr: ClientConfig = {
defaultLanguage: 'cs',
description: 'Live sports streaming platform. All matches playing under the auspices of Czech Republic FA. Access to full matches, various player playlists, and highlights. Free access in the Czech Republic. Available across all devices',
disabledPreferences: false,
host: 'facr.tv',
name: ClientNames.Facr,
privacyLink: '/privacy-policy-and-statement',
privacyLink: '/clients/insports/privacy-policy-and-statement.html',
requests: {
[PROCEDURES.get_matches]: params,
[PROCEDURES.get_team_matches]: params,
@ -43,12 +52,46 @@ export const facr: ClientConfig = {
showSearch: false,
styles: {
background: '',
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
homePageHeader: css`
background: ${(isMobileDevice
? 'linear-gradient(180deg, #00257A 0%, rgba(0, 37, 122, 0) 100%), #000000'
: 'linear-gradient(83.42deg, #00257A 53.04%, rgba(0, 0, 0, 0) 94.83%), #000000'
)};`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
loader: css`
color: #00257A;
`,
logo: 'facr-logo.svg',
logoAuth: css`
background-image: url(/images/facr_auth_logo.png);
height: 163px;
width: 213px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 20px;
width: 130px;
height: 100px;
` : ''}
`,
logoHeight: 6.3,
logoLeft: 1.1,
logoTop: 1.74,
@ -65,12 +108,20 @@ export const facr: ClientConfig = {
width: 48px;
height: 37px;
`,
popupApplyButton: css`
background-color: #00257A;
color: ${({ theme }) => theme.colors.white};
`,
submitButton: css`
background-color: ${({ theme }) => theme.colors.white};
color: #00257A;
`,
userAccountLogo: css`
width: 4.56rem;
height: 3.488rem;
`,
},
termsLink: '/terms-and-conditions?client_id=facr-ott-web',
termsLink: '/clients/facr/terms-and-conditions.html',
title: 'FACR.TV - The home of Czech football streaming',
userAccountLinksDisabled: true,
}

@ -1,14 +1,31 @@
import { css } from 'styled-components/macro'
import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config'
import {
ClientConfig,
ClientIds,
ClientNames,
} from './types'
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background: linear-gradient(0deg, rgba(0, 13, 47, 0.8), rgba(0, 13, 47, 0.8)),
linear-gradient(0deg, #0061DC, #0061DC),
no-repeat center center url(/images/fqtv-background.png);
background-size: 130% 105%;
background-blend-mode: normal, hard-light, normal;
`
export const fqtv: ClientConfig = {
auth: {
clientId: ClientIds.Fqtv,
},
background: Background,
currencyBadge: {
color: '#333333',
secondColor: 'rgba(255, 255, 255, 0.7)',
@ -17,13 +34,25 @@ export const fqtv: ClientConfig = {
defaultLanguage: 'en',
description: 'Queensland’s streamed competitions, including NPL Men, NPL Women and McDonald\'s FQPL Leagues.',
disabledPreferences: true,
host: 'fqtv.com.au',
name: ClientNames.Fqtv,
privacyLink: '/privacy-policy-and-statement?client_id=insports-ott-web',
privacyLink: '/clients/insports/privacy-policy-and-statement.html',
showSearch: true,
showSmartBanner: true,
styles: {
background: '',
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
forgotPasswordInput: css`
border: none;
`,
homePageHeader: css`
background: linear-gradient(0deg, rgba(0, 13, 47, 0.8), rgba(0, 13, 47, 0.8)),
linear-gradient(0deg, #0061DC, #0061DC),
@ -31,7 +60,29 @@ export const fqtv: ClientConfig = {
background-size: 130% 105%;
background-blend-mode: normal, hard-light, normal;
`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
logo: 'fqtv-logo.svg',
logoAuth: css`
background-image: url(/images/fqtv-auth-logo.svg);
background-position: center;
height: 142px;
width: 378px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 200px;
height: 74px;
` : ''}
`,
logoHeight: 2.465,
logoLeft: 0.71,
logoTop: 1,
@ -47,11 +98,17 @@ export const fqtv: ClientConfig = {
width: 86px;
height: 33px;
`,
submitButton: css`
:disabled {
background: #FFFFFF;
color: #00244F;
}
`,
userAccountLogo: css`
width: 6.37rem;
height: 2.465rem;
`,
},
termsLink: '/terms-and-conditions?client_id=insports-ott-web',
termsLink: '/clients/insports/terms-and-conditions.html',
title: 'FQTV is the official home of Football',
}

@ -1,3 +1,6 @@
import { css } from 'styled-components/macro'
import { isMobileDevice } from 'config'
import {
ClientConfig,
ClientIds,
@ -17,9 +20,38 @@ export const india: ClientConfig = {
sign: 'Rupee',
},
disabledHighlights: true,
host: 'india.insports.tv',
name: ClientNames.India,
privacyLink: '/privacy-policy-and-statement?client_id=india-ott-web',
termsLink: '/terms-and-conditions?client_id=india-ott-web',
privacyLink: '/clients/india/privacy-policy-and-statement.html',
styles: {
...insports.styles,
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
logoAuth: css`
background-image: url(/images/insports-logo.svg);
background-position: center;
height: 85px;
width: 275px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 165px;
height: 50px;
@media screen and (orientation: landscape){
width: 92px;
height: 22px;
}
` : ''}
`,
},
termsLink: '/clients/india/terms-and-conditions.html',
userAccountCardsHidden: true,
}

@ -1,5 +1,7 @@
import { css } from 'styled-components/macro'
import { isMobileDevice } from 'config'
import {
ClientConfig,
ClientIds,
@ -18,14 +20,40 @@ export const insports: ClientConfig = {
defaultLanguage: 'en',
description: 'Live sports streaming platform. Football, basketball, ice hockey and more. Access to various player playlists and game highlights. Multiple subscription options. Available across all devices.',
disabledPreferences: true,
host: 'insports.tv',
name: ClientNames.Insports,
privacyLink: '/privacy-policy-and-statement?client_id=insports-ott-web',
privacyLink: '/clients/insports/privacy-policy-and-statement.html',
showSearch: true,
showSmartBanner: true,
styles: {
background: 'background-image: url(/images/Checker.png);',
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
logo: 'insports-logo.svg',
logoAuth: css`
background-image: url(/images/insports-logo.svg);
background-position: center;
height: 85px;
width: 275px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 165px;
height: 50px;
@media screen and (orientation: landscape){
width: 92px;
height: 22px;
}
` : ''}
`,
logoHeight: 2.465,
logoLeft: 1.7,
logoTop: 1.5,
@ -46,6 +74,6 @@ export const insports: ClientConfig = {
height: 2.465rem;
`,
},
termsLink: '/terms-and-conditions?client_id=insports-ott-web',
termsLink: '/clients/insports/terms-and-conditions.html',
title: 'InSports TV - The Home of Sports Streaming',
}

@ -1,4 +1,7 @@
import { css } from 'styled-components/macro'
import { isMobileDevice } from 'config'
import {
ClientConfig,
ClientIds,
@ -17,13 +20,38 @@ export const instat: ClientConfig = {
defaultLanguage: 'en',
description: 'Live sports streaming platform. Football, basketball, ice hockey and more. Access to various player playlists and game highlights. Multiple subscription options. Available across all devices.',
disabledPreferences: true,
host: 'instat.tv',
name: ClientNames.Instat,
privacyLink: '/privacy-policy-and-statement',
showSearch: true,
styles: {
background: 'background-image: url(/images/Checker.png);',
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
logo: 'logo.svg',
logoAuth: css`
background-image: url(/images/logo.svg);
height: 54px;
width: 234px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 78px;
width: 207px;
height: 48px;
@media screen and (orientation: landscape){
width: 92px;
height: 22px;
}
` : ''}
`,
logoHeight: 1.465,
logoLeft: 1.7,
logoTop: 1.5,

@ -1,14 +1,27 @@
import { css } from 'styled-components/macro'
import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config'
import {
ClientConfig,
ClientIds,
ClientNames,
} from './types'
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background: linear-gradient(18.42deg, #242321 8.36%, #242321 42.61%, #DB1C49 86.2%);
`
export const lff: ClientConfig = {
auth: {
clientId: ClientIds.Lff,
},
background: Background,
currencyBadge: {
color: '#333333',
secondColor: 'rgba(255, 255, 255, 0.7)',
@ -18,16 +31,46 @@ export const lff: ClientConfig = {
description: 'Latvijas Futbola federācija (LFF) pašmāju futbola spēļu tiešraižu, apskatu un ierakstu platforma.',
disabledHighlights: true,
disabledPreferences: true,
host: 'tv.lff.lv',
name: ClientNames.Lff,
privacyLink: '/privacy-policy-and-statement',
privacyLink: '/clients/insports/privacy-policy-and-statement.html',
showSearch: true,
styles: {
background: 'background-image: url(/images/Checker.png);',
centerBlock: css`
margin-top: 6.15rem;
${isMobileDevice ? css`
margin-top: 60px;
@media screen and (orientation: landscape) {
width: 290px;
margin-top: 5px;
}
` : ''};
`,
homePageHeader: css`
background: linear-gradient(38.47deg, #242321 26.08%, #DB1C49 95.99%), #000000;
`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white50};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
logo: 'lff_auth_logo.svg',
logoAuth: css`
background-image: url(/images/lff_auth_logo.svg);
height: 220px;
width: 220px;
margin-bottom: 1rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 74px;
height: 74px;
` : ''}
`,
logoHeight: 6,
logoLeft: 1.2,
logoTop: 1.2,
@ -43,12 +86,16 @@ export const lff: ClientConfig = {
width: 42px;
height: 42px;
`,
submitButton: css`
background-color: #DF1C4A;
color: white;
`,
userAccountLogo: css`
width: 80px;
height: 80px;
`,
},
termsLink: '/terms-and-conditions?client_id=lff-ott-web',
termsLink: '/clients/insports/terms-and-conditions.html',
title: 'Latvijas Futbola federācija',
userAccountLinksDisabled: true,
}

@ -1,4 +1,6 @@
import { css } from 'styled-components/macro'
import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config'
import {
ClientConfig,
@ -10,11 +12,23 @@ const randomHash = () => (
(Math.random() ** Math.random()) * 100000000000000
)
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background: linear-gradient(0deg, rgba(2, 46, 48, 0.3),
rgba(2, 46, 48, 0.3)),
radial-gradient(152.89% 271.81% at 0% 96.71%, #2AB7AA 3.27%, #02505C 43.69%, #0B2E4D 100%);
`
export const tunisia: ClientConfig = {
auth: {
clientId: ClientIds.Tunisia,
metaDataUrlParams: `?hash=${randomHash()}`,
},
background: Background,
currencyBadge: {
color: '#333333',
secondColor: 'rgba(255, 255, 255, 0.7)',
@ -25,19 +39,56 @@ export const tunisia: ClientConfig = {
disabledFilters: true,
disabledHighlights: true,
disabledPreferences: true,
host: 'diwansport.net',
name: ClientNames.Tunisia,
privacyLink: '/privacy-policy-and-statement?client_id=insports-ott-web',
privacyLink: '/clients/tunisia/privacy-policy-and-statement.html',
showSearch: true,
styles: {
background: '',
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
forgotPasswordInput: css`
border: none;
`,
homePageHeader: css`
background: radial-gradient(
160.34% 257.27% at -7.45% 162.22%,
#2AB7AA 3.27%,
#02505C 43.69%, #0B2E4D 100%);
`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
loader: css`
color: #0B2E4D;
`,
logo: 'tunis-logo.svg',
logoAuth: css`
background-image: url(/images/tunis_auth_logo.svg);
width: 200px;
height: 178px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
background-image: url(/images/tunis_auth_logo_mobile.svg);
margin-bottom: 20px;
width: 102px;
height: 75px;
` : ''}
`,
logoHeight: 1.922,
logoLeft: 1.1,
logoTop: 1.14,
@ -54,12 +105,20 @@ export const tunisia: ClientConfig = {
width: 100px;
height: 21px;
`,
popupApplyButton: css`
background-color: #0E8F84;
color: ${({ theme }) => theme.colors.white};
`,
submitButton: css`
background-color: ${({ theme }) => theme.colors.white};
color: #0B2E4D;
`,
userAccountLogo: css`
width: 9rem;
height: 1.922rem;
`,
},
termsLink: '/terms-and-conditions?client_id=insports-ott-web',
termsLink: '/clients/tunisia/terms-and-conditions.html',
title: 'Diwan Sport - The home of Tunisian Ligue Professionnelle 1',
userAccountCardsHidden: true,
}

@ -1,4 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FC, ReactNode } from 'react'
import { css } from 'styled-components/macro'
type ProcedureName = string
@ -32,6 +34,7 @@ export type ClientConfig = {
clientId: ClientIds,
metaDataUrlParams?: string,
},
background?: FC<{ children: ReactNode }>,
currencyBadge: {
color: string,
secondColor: string,
@ -42,7 +45,7 @@ export type ClientConfig = {
disabledFilters?: boolean,
disabledHighlights?: boolean,
disabledPreferences?: boolean,
host: string,
isHideSelectLanguages?: boolean,
name: ClientNames,
privacyLink: string,
requests?: Record<ProcedureName, RequestParameters>,
@ -50,8 +53,14 @@ export type ClientConfig = {
showSmartBanner?: boolean,
styles: {
background?: string,
centerBlock?: StyledCss,
forgotPasswordInput?: StyledCss,
homePageHeader?: StyledCss,
input?: StyledCss,
inputGroup?: StyledCss,
loader?: StyledCss,
logo: string,
logoAuth?: StyledCss,
logoHeight?: number,
logoLeft?: number,
logoTop?: number,
@ -61,6 +70,8 @@ export type ClientConfig = {
matchLogoWidth?: number,
matchPageMobileHeaderLogo?: StyledCss,
mobileHeaderLogo?: StyledCss,
popupApplyButton?: StyledCss,
submitButton?: StyledCss,
userAccountLogo?: StyledCss,
},
termsLink: string,

@ -18,5 +18,5 @@ export const stageENV = process.env.REACT_APP_STAGE || 'test'
export const STRIPE_PUBLIC_KEY = process.env.REACT_APP_STRIPE_PK || 'pk_test_51J5TEYEDSxVnTgDWyF63HykCAwKKObIdYCKiCwotte7xvfPw0VhmZiQKzYJIgZ3tCVvQ57JNpGYN7YbxR4JckYUB00HeDWE4YR'
export const GOOGLE_CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID || '1043133237396-kebgih109kro71b5c7c8qphtgjbd2gdk.apps.googleusercontent.com'
export const FACEBOOK_CLIENT_ID = process.env.REACT_APP_FACEBOOK_CLIENT_ID || '798254931203361'
export const GOOGLE_CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID || '1048471272926-14f9okqqo91cmmmakb0ghmlumbv5jm8s.apps.googleusercontent.com'
export const FACEBOOK_CLIENT_ID = process.env.REACT_APP_FACEBOOK_CLIENT_ID || '1724405217985771'

@ -1,7 +1,7 @@
export const lexics = {
export const authLexics = {
accept_cookies: 17203,
accept_privacy: 17202,
and: 17878,
and_auth: 17878,
change_password: 13442,
check_email: 15907,
check_password: 15842,
@ -40,7 +40,7 @@ export const lexics = {
password_changed_success: 17824,
password_new: 15056,
password_repeat: 15057,
privacy_policy_and_statement: 15404,
privacy_policy_and_statement_auth: 15404,
recovery_email: 15833,
register: 13328,
registration_email: 16239,
@ -54,7 +54,7 @@ export const lexics = {
sign_up: 1305,
step_title_login: 13404,
step_title_registration: 1306,
terms_and_conditions: 15738,
terms_and_conditions_auth: 15738,
to_email: 15904,
updated_terms: 15429,
use_new_password: 17825,

@ -1,12 +1,16 @@
export const PAGES = {
about_the_project: 'https://instatsport.com/InStatTV/ott_platform',
authorize: '/authorize',
change_password: '/change_password',
failedPaymee: '/failed-paymee',
highlights: '/highlights',
home: '/',
landing: '/landing',
mailings: '/useraccount/mailings',
match: '/matches',
oauth: '/oauth',
player: '/players',
registration: '/registration',
subscriptions: '/subscriptions',
team: '/teams',
thanksForSubscribe: '/thanks-for-subscription',

@ -52,6 +52,10 @@ const LIKES_API = {
const env = isProduction ? ENV : readSelectedApi() ?? ENV
export const getAuthApiUrl = (path: string) => (
`${AUTH_SERVICE}${path}${window.location.search}`
)
export const VIEWS_API = VIEWS_APIS[env]
export const AUTH_SERVICE = APIS[env].auth
export const AUTH_SERVICE_OLD = APIS[env].auth_old

@ -42,8 +42,9 @@ const PlayerPage = lazy(() => import('features/PlayerPage'))
const TournamentPage = lazy(() => import('features/TournamentPage'))
const SystemSettings = lazy(() => import('features/SystemSettings'))
const Landings = lazy(() => import('features/Landings'))
const HighlightsPage = lazy(() => import('pages/HighlightsPage'))
const ChangePassword = lazy(() => import('features/AuthServiceApp/components/ChangePassword'))
const HighlightsPage = lazy(() => import('pages/HighlightsPage'))
const ThanksPage = lazy(() => import('pages/ThanksPage'))
const Mailings = lazy(() => import('pages/Mailings'))
const FailedPaymeePage = lazy(() => import('pages/FailedPaymeePage'))
@ -76,6 +77,9 @@ export const AuthenticatedApp = () => {
{/* в Switch как прямой children
можно рендерить только Route или Redirect */}
<Switch>
<Route path={PAGES.change_password}>
<ChangePassword />
</Route>
<Route path={PAGES.mailings}>
<Mailings />
</Route>

@ -25,6 +25,7 @@ import { Theme } from 'features/Theme'
import { UnavailableText } from 'components/UnavailableText'
import { ErrorBoundary } from 'components/ErrorBoundary'
import { App } from 'features/AuthServiceApp/components/App'
import { AuthenticatedApp } from './AuthenticatedApp'
import { useAuthStore } from '../AuthStore'
@ -58,7 +59,9 @@ const Main = () => {
<AuthenticatedApp />
</QueryClientProvider>
</ErrorBoundary>
) : null
) : (
<App />
)
}
const date = new Date()

@ -1,15 +1,14 @@
import { lazy } from 'react'
import {
Redirect,
Route,
Switch,
} from 'react-router-dom'
import { useLexicsConfig } from 'features/LexicsStore'
import { PAGES } from '../../config/pages'
import { lexics } from '../../config/lexics'
import { PAGES, isProduction } from 'config'
import { authLexics } from 'config/lexics/authLexics'
import { Main } from './styled'
@ -17,31 +16,28 @@ const Login = lazy(() => import('../Login'))
const Registration = lazy(() => import('../Registration'))
const ChangePassword = lazy(() => import('../ChangePassword'))
const Oauth = lazy(() => import('../Oauth'))
const SystemSettings = lazy(() => import('features/SystemSettings'))
export const App = () => {
useLexicsConfig(lexics)
useLexicsConfig(authLexics)
return (
<Main>
<Switch>
<Route path={PAGES.login}>
<Route path={PAGES.authorize}>
<Login />
</Route>
<Route path={PAGES.oauth}>
<Oauth />
</Route>
<Route path={PAGES.registration}>
<Registration />
</Route>
<Route path={PAGES.change_password}>
<ChangePassword />
</Route>
<Redirect to={PAGES.login} />
</Switch>
{!isProduction && <SystemSettings />}
</Main>
)
}

@ -4,18 +4,16 @@ import {
useState,
} from 'react'
import { useHistory } from 'react-router'
import { useAuthFields } from 'features/AuthServiceApp/hooks/useAuthFields'
import { changePassword } from 'features/AuthServiceApp/requests/changePassword'
import { clients } from 'features/AuthServiceApp/config/clients'
import { useAuthStore } from 'features/AuthStore'
import { LogoutAction } from 'features/AuthStore/hooks/useAuth'
import { useParamsUrl } from '../../hooks/useParamsUrl'
export const useChangePasswordForm = () => {
const { client_id, redirect_uri } = useParamsUrl()
const history = useHistory()
const { client_id } = useParamsUrl()
const { logout } = useAuthStore()
const [error, setError] = useState('')
const [modalOpen, setModalOpen] = useState<boolean>(false)
const [isFetching, setIsFetching] = useState(false)
@ -38,12 +36,9 @@ export const useChangePasswordForm = () => {
setIsFetching(false)
}
}
const host = String(redirect_uri || clients[client_id].host)
const redirectUrl = `/authorize?client_id=${client_id}&redirect_uri=${encodeURIComponent(host)}`
const modalButtonClick = () => {
history.push(redirectUrl)
logout(LogoutAction.LoseRedirectUrl)
}
const onPasswordChange = ({

@ -1,7 +1,6 @@
import { T9n } from 'features/T9n'
import { client } from 'config/clients'
import { AUTH_SERVICE_OLD } from 'config/routes'
import {
ScBody,
@ -43,11 +42,11 @@ export const ConfirmPopup = (props: Props) => {
</ScText>
<ScText>
<T9n t='by_clicking' />
<ScLink href={`${AUTH_SERVICE_OLD}${client.termsLink}`} target='_blank' id='personal_t_k'>
<ScLink href={client.termsLink} target='_blank' id='personal_t_k'>
<T9n t='terms_and_conditions' />
</ScLink>&nbsp;
<T9n t='and' />
<ScLink href={`${AUTH_SERVICE_OLD}${client.privacyLink}`} target='_blank' id='personal_policy'>
<ScLink href={client.privacyLink} target='_blank' id='personal_policy'>
<T9n t='privacy_policy_and_statement' />
</ScLink>
</ScText>

@ -2,6 +2,7 @@ import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent'
import { devices } from 'config/devices'
import { client } from 'config'
import { ModalWindow } from 'features/Modal/styled'
import {
@ -11,8 +12,6 @@ import {
HeaderTitle,
} from 'features/AuthServiceApp/components/RegisterPopup/styled'
import { client } from '../../config/clients/index'
export const Modal = styled(BaseModal)`
${ModalWindow} {
min-height: 220px;

@ -12,10 +12,11 @@ import { redirectToUrl } from 'helpers'
import { useLocalStore } from 'hooks'
import { getAuthApiUrl } from 'config'
import type { Settings } from 'features/AuthStore/helpers'
import { loginCheck } from 'features/AuthServiceApp/requests/auth'
import { resendConfirmation } from 'features/AuthServiceApp/requests/resendConfirmation'
import { getApiUrl } from 'features/AuthServiceApp/config/routes'
import { useAuthFields } from 'features/AuthServiceApp/hooks/useAuthFields'
import { addAccessTokenToUrl } from 'helpers/languageUrlParam'
@ -24,7 +25,7 @@ import { AuthProviders } from '../../config/authProviders'
import { getAuthUrl } from '../../helpers/getAuthUrl'
import { useParamsUrl } from '../../hooks/useParamsUrl'
const url = getApiUrl('/authorize')
const url = getAuthApiUrl('/authorize')
export const useLoginForm = () => {
const urlParams = useParamsUrl()

@ -1,9 +1,9 @@
import { T9n } from 'features/T9n'
import { RecoveryPopup } from 'features/AuthServiceApp/components/RecoveryPopup'
import { RegisterPopup } from 'features/AuthServiceApp/components/RegisterPopup'
import { client } from 'features/AuthServiceApp/config/clients'
import { PAGES } from '../../config/pages'
import { PAGES, client } from 'config'
import { AuthProviders } from '../../config/authProviders'
import { LanguageSelect } from '../LanguageSelect'
import { PasswordInput } from '../PasswordInput'

@ -1,6 +1,6 @@
import styled from 'styled-components/macro'
import { client } from '../../config/clients'
import { client } from 'config'
type Props = {
height?: number,
@ -8,7 +8,7 @@ type Props = {
}
export const Logo = styled.div<Props>`
${client.styles.logo};
${client.styles.logoAuth};
display: block;
background-size: contain;
background-repeat: no-repeat;

@ -9,10 +9,11 @@ import {
} from 'react'
import { isValidEmail } from 'features/AuthServiceApp/helpers/isValidEmail'
import { API_ROOT } from 'features/AuthServiceApp/config/routes'
import { addAccessTokenToUrl } from 'helpers/languageUrlParam'
import { AUTH_SERVICE } from 'config'
export const useOauth = () => {
const [email, setEmail] = useState('')
const [error, setError] = useState('')
@ -25,7 +26,7 @@ export const useOauth = () => {
const authorize = useCallback(async () => {
if (!formRef.current) return
const url = addAccessTokenToUrl(`${API_ROOT}/oauth`)
const url = addAccessTokenToUrl(`${AUTH_SERVICE}/oauth`)
const res = await fetch(url, {
body: new FormData(formRef.current),

@ -9,9 +9,8 @@ import { useLocalStore } from 'hooks'
import type { Settings } from 'features/AuthStore/helpers'
import { getClientSettings } from 'features/AuthStore/helpers'
import { T9n } from 'features/T9n'
import { getAuthApiUrl, PAGES } from 'config'
import { getApiUrl } from 'features/AuthServiceApp/config/routes'
import { PAGES } from '../../config/pages'
import { useOauth } from './hooks'
import {
Header,
@ -29,7 +28,7 @@ import {
} from './styled'
import { ErrorPopup } from '../../../../components/ErrorPopup'
const url = getApiUrl('/oauth')
const url = getAuthApiUrl('/oauth')
const Oauth = () => {
const {
@ -69,7 +68,7 @@ const Oauth = () => {
showEmailField,
} = useOauth()
if (!idToken || !client_id || !redirect_uri) return <Redirect to={PAGES.login} />
if (!idToken || !client_id || !redirect_uri) return <Redirect to={PAGES.authorize} />
if (showEmailField) {
return (
@ -156,7 +155,7 @@ const Oauth = () => {
</Form>
<Text>
Also you can use any{' '}
<StyledLink to={PAGES.login}>other method of authorization</StyledLink>
<StyledLink to={PAGES.authorize}>other method of authorization</StyledLink>
</Text>
</Content>
<ErrorPopup

@ -7,6 +7,7 @@ import {
import { isValidEmail } from 'features/AuthServiceApp/helpers/isValidEmail'
import { loginCheckChangePass } from 'features/AuthServiceApp/requests/loginCheck'
import { PAGES } from 'config'
import { useParamsUrl } from '../../hooks/useParamsUrl'
export const useRecovery = (setIsModalOpen: (value: boolean) => void) => {
@ -53,6 +54,7 @@ export const useRecovery = (setIsModalOpen: (value: boolean) => void) => {
client_id,
email,
lang,
`${window.location.origin}${PAGES.change_password}`,
)
.then(() => {
setIsFetching(false)

@ -2,13 +2,12 @@ import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent'
import { devices } from 'config/devices'
import { client } from 'config'
import { ModalWindow } from 'features/Modal/styled'
import { Modal as BaseModal } from 'features/Modal'
import { Header as BaseHeader } from 'features/PopupComponents'
import { ButtonSolid } from 'features/Common'
import { client } from 'features/AuthServiceApp/config/clients'
import { Input } from 'components/Input'

@ -6,10 +6,10 @@ import { devices } from 'config/devices'
import { ModalWindow } from 'features/Modal/styled'
import { Modal as BaseModal } from 'features/Modal'
import { Header as BaseHeader } from 'features/PopupComponents'
import { client } from 'features/AuthServiceApp/config/clients'
import { ButtonSolid } from 'features/Common'
import { client } from 'config'
export const Modal = styled(BaseModal)`
background-color: rgba(0, 0, 0, 0.7);
padding: 0 60px;

@ -4,9 +4,10 @@ import { useHistory, useLocation } from 'react-router'
import { setAgreements } from 'requests/getAgreements'
import { useAuthFields } from 'features/AuthServiceApp/hooks/useAuthFields'
import { PAGES } from 'config'
import { registerCheck } from '../../requests/register'
import { useParamsUrl } from '../../hooks/useParamsUrl'
import { PAGES } from '../../config/pages'
export const useRegistrationForm = () => {
const history = useHistory()
@ -58,7 +59,7 @@ export const useRegistrationForm = () => {
const handleModalClose = () => {
setIsModalOpen(false)
history.replace(`${PAGES.login}${search}`)
history.replace(`${PAGES.authorize}${search}`)
}
const onTermsChange = () => {

@ -5,10 +5,10 @@ import { useHistory } from 'react-router'
import { T9n } from 'features/T9n'
import { Checkbox } from 'features/Common/Checkbox'
import { RegisterPopup } from 'features/AuthServiceApp/components/RegisterPopup'
import { client } from 'features/AuthServiceApp/config/clients'
import { CompanyInfo } from 'features/CompanyInfo'
import { ClientNames } from 'config/clients/types'
import { client } from 'config'
import { LanguageSelect } from '../LanguageSelect'
import { PasswordInput } from '../PasswordInput'
@ -106,13 +106,13 @@ const Registration = () => {
<Label>
<T9n t='accept_privacy' />
<Link href={client.termsLink} target='_blank'>
<T9n t='terms_and_conditions' />
<T9n t='terms_and_conditions_auth' />
</Link>&nbsp;
{isAvailableToClient && (
<Fragment>
<T9n t='and' />
<T9n t='and_auth' />
<Link href={client.privacyLink} target='_blank'>
<T9n t='privacy_policy_and_statement' />
<T9n t='privacy_policy_and_statement_auth' />
</Link>
</Fragment>
)}

@ -1,64 +0,0 @@
import styled, { css } from 'styled-components/macro'
import { facr as platformFacr } from 'config/clients/facr'
import { isMobileDevice } from 'config/userAgent'
import type { ClientConfig } from './types'
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background-color: #00257A;
`
export const facr: ClientConfig = {
...platformFacr,
background: Background,
styles: {
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
loader: css`
color: #00257A;
`,
logo: css`
background-image: url(/images/facr_auth_logo.png);
height: 163px;
width: 213px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 20px;
width: 130px;
height: 100px;
` : ''}
`,
popupApplyButton: css`
background-color: #00257A;
color: ${({ theme }) => theme.colors.white};
`,
submitButton: css`
background-color: ${({ theme }) => theme.colors.white};
color: #00257A;
`,
},
}

@ -1,67 +0,0 @@
import styled, { css } from 'styled-components/macro'
import { fqtv as platformFqtv } from 'config/clients/fqtv'
import { isMobileDevice } from 'config/userAgent'
import type { ClientConfig } from './types'
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background: linear-gradient(0deg, rgba(0, 13, 47, 0.8), rgba(0, 13, 47, 0.8)),
linear-gradient(0deg, #0061DC, #0061DC),
no-repeat center center url(/images/fqtv-background.png);
background-size: 130% 105%;
background-blend-mode: normal, hard-light, normal;
`
export const fqtv: ClientConfig = {
...platformFqtv,
background: Background,
styles: {
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
forgotPasswordInput: css`
border: none;
`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
logo: css`
background-image: url(/images/fqtv-auth-logo.svg);
background-position: center;
height: 142px;
width: 378px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 200px;
height: 74px;
` : ''}
`,
submitButton: css`
:disabled {
background: #FFFFFF;
color: #00244F;
}
`,
},
}

@ -1,24 +0,0 @@
import { ClientIds } from 'config/clients/types'
import { facr } from './facr'
import { insports } from './insports'
import { instat } from './instat'
import { lff } from './lff'
import { india } from './india'
import { tunisia } from './tunisia'
import { fqtv } from './fqtv'
export const clients = {
[ClientIds.Facr]: facr,
[ClientIds.Fqtv]: fqtv,
[ClientIds.Instat]: instat,
[ClientIds.Lff]: lff,
[ClientIds.Insports]: insports,
[ClientIds.India]: india,
[ClientIds.Tunisia]: tunisia,
}
const params = new URLSearchParams(window.location.search)
const clientId = params.get('client_id') as ClientIds
export const client = clients[clientId] || insports

@ -1,42 +0,0 @@
import { css } from 'styled-components/macro'
import { india as platformIndia } from 'config/clients/india'
import { isMobileDevice } from 'config'
import { Background } from 'features/Background'
import type { ClientConfig } from './types'
export const india: ClientConfig = {
...platformIndia,
background: Background,
styles: {
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
logo: css`
background-image: url(/images/insports-logo.svg);
background-position: center;
height: 85px;
width: 275px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 165px;
height: 50px;
@media screen and (orientation: landscape){
width: 92px;
height: 22px;
}
` : ''}
`,
},
}

@ -1,42 +0,0 @@
import { css } from 'styled-components'
import { insports as platformInsports } from 'config/clients/insports'
import { isMobileDevice } from 'config/userAgent'
import { Background } from 'features/Background'
import type { ClientConfig } from './types'
export const insports: ClientConfig = {
...platformInsports,
background: Background,
styles: {
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
logo: css`
background-image: url(/images/insports-logo.svg);
background-position: center;
height: 85px;
width: 275px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 165px;
height: 50px;
@media screen and (orientation: landscape){
width: 92px;
height: 22px;
}
` : ''}
`,
},
}

@ -1,41 +0,0 @@
import { css } from 'styled-components'
import { instat as platformInstat } from 'config/clients/instat'
import { isMobileDevice } from 'config/userAgent'
import { Background } from 'features/Background'
import type { ClientConfig } from './types'
export const instat: ClientConfig = {
...platformInstat,
background: Background,
styles: {
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
logo: css`
background-image: url(/images/logo.svg);
height: 54px;
width: 234px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
margin-bottom: 78px;
width: 207px;
height: 48px;
@media screen and (orientation: landscape){
width: 92px;
height: 22px;
}
` : ''}
`,
},
}

@ -1,57 +0,0 @@
import styled, { css } from 'styled-components/macro'
import { lff as platformLff } from 'config/clients/lff'
import { isMobileDevice } from 'config/userAgent'
import type { ClientConfig } from './types'
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background: linear-gradient(18.42deg, #242321 8.36%, #242321 42.61%, #DB1C49 86.2%);
`
export const lff: ClientConfig = {
...platformLff,
background: Background,
styles: {
centerBlock: css`
margin-top: 6.15rem;
${isMobileDevice ? css`
margin-top: 60px;
@media screen and (orientation: landscape) {
width: 290px;
margin-top: 5px;
}
` : ''};
`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white50};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
logo: css`
background-image: url(/images/lff_auth_logo.svg);
height: 220px;
width: 220px;
margin-bottom: 1rem;
${isMobileDevice ? css`
margin-bottom: 15px;
width: 74px;
height: 74px;
` : ''}
`,
submitButton: css`
background-color: #DF1C4A;
color: white;
`,
},
}

@ -1,70 +0,0 @@
import styled, { css } from 'styled-components/macro'
import { tunisia as platformTunis } from 'config/clients/tunisia'
import { isMobileDevice } from 'config/userAgent'
import type { ClientConfig } from './types'
const Background = styled.div`
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background: linear-gradient(0deg, rgba(2, 46, 48, 0.3),
rgba(2, 46, 48, 0.3)),
radial-gradient(152.89% 271.81% at 0% 96.71%, #2AB7AA 3.27%, #02505C 43.69%, #0B2E4D 100%);
`
export const tunisia: ClientConfig = {
...platformTunis,
background: Background,
styles: {
centerBlock: css`
margin-top: 9.15rem;
${isMobileDevice ? css`
margin-top: 107px;
@media screen and (orientation: landscape) {
width: 290px;
margin: auto;
}
` : ''};
`,
forgotPasswordInput: css`
border: none;
`,
input: css`
background-color: transparent;
:not(:last-of-type) {
border-color: ${({ theme }) => theme.colors.white};
}
`,
inputGroup: css`
border: 1px solid ${({ theme }) => theme.colors.white};
`,
loader: css`
color: #0B2E4D;
`,
logo: css`
background-image: url(/images/tunis_auth_logo.svg);
width: 200px;
height: 178px;
margin-bottom: 1.82rem;
${isMobileDevice ? css`
background-image: url(/images/tunis_auth_logo_mobile.svg);
margin-bottom: 20px;
width: 102px;
height: 75px;
` : ''}
`,
popupApplyButton: css`
background-color: #0E8F84;
color: ${({ theme }) => theme.colors.white};
`,
submitButton: css`
background-color: ${({ theme }) => theme.colors.white};
color: #0B2E4D;
`,
},
}

@ -1,31 +0,0 @@
import type { ReactNode, FC } from 'react'
import { css } from 'styled-components/macro'
import { ClientIds, ClientNames } from 'config/clients/types'
type StyledCss = ReturnType<typeof css>
export type ClientConfig = {
auth: {
clientId: ClientIds,
},
background: FC<{ children: ReactNode }>,
defaultLanguage: string,
description: string,
host?: string,
isHideSelectLanguages?: boolean,
name: ClientNames,
privacyLink: string,
styles: {
centerBlock?: StyledCss,
forgotPasswordInput?: StyledCss,
input?: StyledCss,
inputGroup?: StyledCss,
loader?: StyledCss,
logo: StyledCss,
popupApplyButton?: StyledCss,
submitButton?: StyledCss,
},
termsLink: string,
title: string,
}

@ -1,6 +0,0 @@
export const PAGES = {
change_password: '/change_password',
login: '/authorize',
oauth: '/oauth',
registration: '/registration',
}

@ -1,17 +0,0 @@
import { ENV, isProduction } from 'config/env'
import { readSelectedApi } from 'helpers/selectedApi'
const APIS = {
preproduction: 'https://api.auth.insports.tv',
production: 'https://api.auth.insports.tv',
staging: 'https://api.auth.test.insports.tv',
}
const env = isProduction ? ENV : readSelectedApi() ?? ENV
export const API_ROOT = APIS[env]
export const getApiUrl = (path: string) => (
`${API_ROOT}${path}${window.location.search}`
)

@ -1,11 +1,14 @@
import { GOOGLE_CLIENT_ID, FACEBOOK_CLIENT_ID } from 'config'
import {
GOOGLE_CLIENT_ID,
FACEBOOK_CLIENT_ID,
PAGES,
} from 'config'
import { getRandomString } from 'helpers'
import type { Settings } from 'features/AuthStore/helpers'
import { AuthProviders } from '../../config/authProviders'
import { PAGES } from '../../config/pages'
const getQueryString = (authProvider: AuthProviders, urlParams: Settings) => {
switch (authProvider) {

@ -7,7 +7,7 @@ import { useState } from 'react'
import { isValidEmail } from 'features/AuthServiceApp/helpers/isValidEmail'
import { isValidPassword } from 'features/AuthServiceApp/helpers/isValidPassword'
import { PAGES } from 'features/AuthServiceApp/config/pages'
import { PAGES } from 'config'
export const useAuthFields = (page: 'login'|'registration') => {
const [email, setEmail] = useState('')

@ -1,35 +0,0 @@
import { BrowserRouter } from 'react-router-dom'
import { getLanguageUrlParam } from 'helpers/languageUrlParam'
import {
setClientTitleAndDescription,
setClientIcons,
} from 'helpers/setClientHeads'
import { GlobalStyles } from 'features/GlobalStyles'
import { LexicsStore } from 'features/LexicsStore'
import { Theme } from 'features/Theme'
import { App } from './components/App'
import { client } from './config/clients'
setClientTitleAndDescription(client.title, client.description)
setClientIcons(client.name)
const Background = client.background
const initialLanguage = getLanguageUrlParam()
const AuthServiceApp = () => (
<BrowserRouter>
<Theme>
<GlobalStyles />
<LexicsStore initialLanguage={initialLanguage}>
<Background>
<App />
</Background>
</LexicsStore>
</Theme>
</BrowserRouter>
)
export default AuthServiceApp

@ -1,4 +1,4 @@
import { getApiUrl } from '../config/routes'
import { getAuthApiUrl } from 'config'
import type { UrlParams } from './register'
@ -31,7 +31,7 @@ export const loginCheck = async ({
password,
urlParams,
}: LoginProps) => {
const url = getApiUrl('/authorize-check')
const url = getAuthApiUrl('/authorize-check')
const init: RequestInit = {
body: new URLSearchParams({

@ -1,6 +1,6 @@
import { ClientIds } from 'config/clients/types'
import { getApiUrl } from '../config/routes'
import { getAuthApiUrl } from 'config'
const errorLexics = {
5: '',
@ -20,7 +20,7 @@ type SuccessResponse = {
}
export const changePassword = async (client_id: ClientIds, password: string) => {
const url = getApiUrl('/change_password')
const url = getAuthApiUrl('/change_password')
const init: RequestInit = {
body: new URLSearchParams({ client_id, password }),
method: 'PUT',

@ -1,6 +1,6 @@
import { ClientIds } from 'config/clients/types'
import { getApiUrl } from '../config/routes'
import { getAuthApiUrl } from 'config'
const errorLexics = {
4: 'error_user_not_found_recovery',
@ -23,13 +23,15 @@ export const loginCheckChangePass = async (
client_id: ClientIds,
email: string,
lang: string,
redirect_uri: string,
) => {
const url = getApiUrl('/change_password')
const url = getAuthApiUrl('/change_password')
const init: RequestInit = {
body: new URLSearchParams({
client_id,
email,
lang,
redirect_uri,
}),
method: 'POST',
}

@ -2,7 +2,7 @@ import type { ClientIds } from 'config/clients/types'
import { checkCookie } from 'helpers/cookie'
import { getApiUrl } from 'features/AuthServiceApp/config/routes'
import { getAuthApiUrl } from 'config'
const errorLexics = {
1: 'error_invalid_email_or_password',
@ -48,7 +48,7 @@ export const registerCheck = async ({
urlParams,
} : RegisterProps) => {
const url = `
${getApiUrl('/registration')}${checkCookie('access_token')
${getAuthApiUrl('/registration')}${checkCookie('access_token')
? `&${checkCookie('access_token')}`
: ''}`
const init: RequestInit = {

@ -1,7 +1,6 @@
import { getAuthApiUrl } from 'config'
import type { ClientIds } from 'config/clients/types'
import { getApiUrl } from 'features/AuthServiceApp/config/routes'
const errorLexics = {
8: 'error_failed_to_send_email',
15: 'error_email_field_required',
@ -41,7 +40,7 @@ export const resendConfirmation = async ({
email,
urlParams,
} : TResendConfirmation) => {
const url = getApiUrl('/repeat_confirm_email')
const url = getAuthApiUrl('/repeat_confirm_email')
const init: RequestInit = {
body: new URLSearchParams({
email,

@ -6,7 +6,7 @@ import { ButtonSolid as BaseButtonSolid } from 'features/Common/Button'
import { T9n } from 'features/T9n'
import { ArrowLoader } from 'features/ArrowLoader'
import { client } from 'features/AuthServiceApp/config/clients'
import { client } from 'config'
export const InputGroup = styled.div`
width: 100%;

@ -6,8 +6,6 @@ import { AUTH_SERVICE } from 'config/routes'
import { ClientIds, ClientNames } from 'config/clients/types'
import { ENV, stageENV } from 'config/env'
import { API_ROOT } from 'features/AuthServiceApp/config/routes'
export interface Settings extends UserManagerSettings {
client_id: ClientIds,
lang?: string,
@ -67,7 +65,7 @@ export const getClientSettings = (): Settings => ({
client_id: client.auth.clientId,
filterProtocolClaims: false,
loadUserInfo: false,
metadataUrl: `${API_ROOT}/.well-known/openid-configuration${client.auth.metaDataUrlParams || ''}`,
metadataUrl: `${AUTH_SERVICE}/.well-known/openid-configuration${client.auth.metaDataUrlParams || ''}`,
redirect_uri: redirectUrl(),
response_mode: 'query',
response_type: 'id_token token',

@ -4,7 +4,7 @@ import {
useMemo,
useEffect,
} from 'react'
import { useHistory } from 'react-router'
import { useHistory, useLocation } from 'react-router'
import type { User } from 'oidc-client'
// @ts-expect-error
@ -14,7 +14,7 @@ import isString from 'lodash/isString'
import isBoolean from 'lodash/isBoolean'
import includes from 'lodash/includes'
import { PAGES, isIOS } from 'config'
import { PAGES } from 'config'
import {
addLanguageUrlParam,
@ -24,7 +24,6 @@ import {
setCookie,
removeCookie,
isMatchPage,
getDomain,
} from 'helpers'
import {
@ -46,7 +45,13 @@ import {
import { userManager } from '../config'
import { needCheckNewDeviсe } from '../helpers'
export enum LogoutAction {
LoseRedirectUrl = 'loseRedirectUrl',
SaveToken = 'saveToken'
}
export const useAuth = () => {
const { pathname } = useLocation()
const { changeLang, lang } = useLexicsStore()
const history = useHistory()
const {
@ -66,29 +71,21 @@ export const useAuth = () => {
})
}
const parseJwt = (value: string) => {
const base64Url = value.split('.')[1]
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map((c) => `%${(`00${c.charCodeAt(0).toString(16)}`).slice(-2)}`).join(''))
return JSON.parse(jsonPayload)
}
const login = useCallback(async () => {
userManager.signinRedirect({ extraQueryParams: { lang } })
}, [lang])
const logout = useCallback((key?: string) => {
const logout = useCallback((key?: LogoutAction) => {
if (key !== LogoutAction.LoseRedirectUrl) {
setPage(history.location.pathname)
}
userManager.clearStaleState()
userManager.createSigninRequest().then(({ url }) => {
const urlWithLang = addLanguageUrlParam(lang, url)
const signOutUrl = `${window.origin}${PAGES.authorize}`
const urlWithLang = addLanguageUrlParam(lang, signOutUrl)
userManager.signoutRedirect({ post_logout_redirect_uri: urlWithLang })
})
removeToken()
if (key !== 'saveToken') {
if (key !== LogoutAction.SaveToken) {
removeCookie('access_token')
removeCookie('refresh_token')
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [lang])
@ -98,6 +95,11 @@ export const useAuth = () => {
saveToken(loadedUser.access_token)
}, [])
const isAuthPage = useMemo(() => pathname === PAGES.authorize
|| pathname === PAGES.registration
|| pathname === PAGES.oauth
|| pathname === PAGES.change_password, [pathname])
const checkUser = useCallback(async () => {
const loadedUser = await userManager.getUser()
@ -111,7 +113,7 @@ export const useAuth = () => {
return Promise.resolve()
}
if (!readToken()) {
if (!readToken() && !isAuthPage) {
const token = await getTemporaryToken()
token && await fetchUserInfo()
return Promise.resolve()
@ -126,6 +128,7 @@ export const useAuth = () => {
}, [
storeUser,
markUserLoaded,
isAuthPage,
])
const [page, setPage] = useLocalStore({
@ -168,21 +171,13 @@ export const useAuth = () => {
}
}
const saveRefreshToken = (value: string) => {
const ref = parseJwt(value)
const expires = `expires=${new Date((ref.exp * 1000)).toUTCString()}`
document.cookie = `refresh_token=${value};${expires};path=/;domain=${getDomain()};secure;SameSite=None`
}
const signinRedirectCallback = useCallback(async (refreshToken: string | null) => {
const signinRedirectCallback = useCallback(() => {
setPage(history.location.pathname)
userManager.signinRedirectCallback()
.then((loadedUser) => {
storeUser(loadedUser)
if (isIOS && refreshToken) saveRefreshToken(refreshToken)
queryParamStorage.clear()
if (page.includes(PAGES.useraccount)) {
history.push(PAGES.home)
@ -206,12 +201,11 @@ export const useAuth = () => {
const searchToken = urlSearch.get('access_token')
const searchRefToken = urlSearch.get('id_token')
const searchExp = urlSearch.get('expires_in')
const refreshToken = urlSearch.get('refresh_token')
const isRedirectedBackFromAuthProvider = Boolean(searchToken && searchRefToken && searchExp)
isRedirectedBackFromAuthProvider
? signinRedirectCallback(refreshToken)
? signinRedirectCallback()
: checkUser()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
@ -315,6 +309,7 @@ export const useAuth = () => {
const auth = useMemo(() => ({
fetchUserInfo,
isAuthPage,
isFromLanding,
isNewDeviceLogin,
landingUrlFrom,
@ -345,6 +340,7 @@ export const useAuth = () => {
setIsFromLanding,
setLandingUrlFrom,
isFromLanding,
isAuthPage,
])
return auth

@ -1,15 +1,28 @@
import { ReactNode } from 'react'
import { useAuthStore } from 'features/AuthStore'
import { client } from 'config'
import { GradientBackground, ImageBackground } from './styled'
type Props = {
children: ReactNode,
}
const ClientBackground = client.background
export const Background = ({ children }: Props) => {
const { isAuthPage } = useAuthStore()
export const Background = ({ children }: Props) => (
return isAuthPage && ClientBackground
? (
<ClientBackground>
{children}
</ClientBackground>
) : (
<ImageBackground>
<GradientBackground>
{children}
</GradientBackground>
</ImageBackground>
)
)
}

@ -25,6 +25,7 @@ import { ArrowLoader } from 'features/ArrowLoader'
import { useAuthStore } from 'features/AuthStore'
import { Arrow } from 'features/HeaderFilters/components/DateFilter/styled'
import type { MatchPackage } from 'features/BuyMatchPopup/types'
import { LogoutAction } from 'features/AuthStore/hooks/useAuth'
import { ClientNames } from 'config/clients/types'
@ -134,7 +135,7 @@ export const PackageSelectionStep = () => {
setLastSelectedPackage(selectedPackage?.id || '')
} else {
setSearch(window.location.search)
logout('saveToken')
logout(LogoutAction.SaveToken)
}
}

@ -12,6 +12,7 @@ import { PAGES } from 'config/pages'
// import { usePreferencesStore } from 'features/PreferencesPopup'
// import { useTournamentPopupStore } from 'features/TournamentsPopup/store'
import { useAuthStore } from 'features/AuthStore'
import { LogoutAction } from 'features/AuthStore/hooks/useAuth'
import { FavoritesMobilePopup } from '../FavoritesMobilePopup'
@ -39,7 +40,7 @@ export const Menu = () => {
} */}
<MenuItem onClick={(e) => {
e.preventDefault()
!user && logout('saveToken')
!user && logout(LogoutAction.SaveToken)
}}
>
<Link

@ -8,8 +8,7 @@ import {
import { ThemeProvider } from 'styled-components'
import { client as clientBase } from 'config/clients'
import { client as clientAuth } from 'features/AuthServiceApp/config/clients'
import { client } from 'config'
import { ClientNames } from 'config/clients/types'
import {
@ -28,13 +27,6 @@ type Props = {
export const Theme = ({ children }: Props) => {
const [theme, setTheme] = useState<CustomTheme>(defaultTheme)
const client = useMemo(() => {
if (process.env.REACT_APP_TYPE === 'auth-service') {
return clientAuth
}
return clientBase
}, [])
// настройка цветовой гаммы зендеска https://developer.zendesk.com/api-reference/widget/settings/#color
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -65,7 +57,7 @@ export const Theme = ({ children }: Props) => {
setTheme(defaultTheme)
break
}
}, [client])
}, [])
useEffect(() => {
switchTheme()

@ -1,11 +1,13 @@
import { useCallback, useMemo } from 'react'
import { useHistory } from 'react-router'
import trim from 'lodash/trim'
import find from 'lodash/find'
import map from 'lodash/map'
import { PAGES } from 'config'
import { formIds } from 'config/form'
import { AUTH_SERVICE_OLD } from 'config/routes'
import { useForm } from 'features/FormStore'
import { useLexicsStore } from 'features/LexicsStore'
@ -15,8 +17,6 @@ import { SaveUserInfo } from 'requests'
import { readToken } from 'helpers/token'
import { client } from 'config/clients'
import { useUserInfoForm } from './useUserInfoForm'
import { useValidateForm } from './useValidateForm'
@ -31,6 +31,7 @@ export type Props = {
}
export const useUserInfo = ({ loader, onSubmit }: Props) => {
const history = useHistory()
const { languageList } = useLexicsStore()
const { userInfo } = useAuthStore()
const {
@ -112,8 +113,9 @@ export const useUserInfo = ({ loader, onSubmit }: Props) => {
}
const resetPassword = useCallback(() => {
window.location.href = `${AUTH_SERVICE_OLD}/change_password?client_id=${client.auth.clientId}&token=${token}`
}, [token])
history.push(`${PAGES.change_password}?token=${token}`)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return {
handleSubmit,

@ -1,6 +1,5 @@
import { client } from 'config/clients'
import { formIds } from 'config/form'
import { AUTH_SERVICE_OLD } from 'config/routes'
import { Combobox } from 'features/Combobox'
import { Input } from 'features/Common'
@ -119,14 +118,14 @@ export const PersonalInfoForm = (props: Props) => {
<PrivacyWrapper>
<PrivacyPolicyLink
target='_blank'
href={`${AUTH_SERVICE_OLD}${client.termsLink}`}
href={client.termsLink}
id='personal_t_k'
>
<T9n t='terms_and_conditions' />
</PrivacyPolicyLink>
<PrivacyPolicyLink
target='_blank'
href={`${AUTH_SERVICE_OLD}${client.privacyLink}`}
href={client.privacyLink}
id='personal_policy'
>
<T9n t='privacy_policy_and_statement' />

@ -29,7 +29,7 @@ export const checkCookie = (name: string) => {
return token[0]
}
export const getDomain = () => (
const getDomain = () => (
process.env.NODE_ENV === 'development'
? 'localhost'
: '.insports.tv'

@ -23,9 +23,7 @@ import * as serviceWorker from './serviceWorker'
// })
// }
export const App = process.env.REACT_APP_TYPE === 'auth-service'
? lazy(() => import('features/AuthServiceApp'))
: lazy(() => import('features/App'))
export const App = lazy(() => import('features/App'))
// если раскоментить, то включится miragejs
// process.env.NODE_ENV === 'development' && makeServer({ environment: 'development' })

@ -6,6 +6,5 @@ declare namespace NodeJS {
REACT_APP_CLIENT: 'instat' | 'facr' | 'lff' | 'insports' | 'india' | 'tunisia' | 'fqtv',
REACT_APP_ENV: 'production' | 'preproduction' | 'staging',
REACT_APP_STAGE: 'staging' | 'test-a' | 'test-b' | 'test-c' | 'test-d' | 'test-e' | 'test-f' | 'test-g' | 'test-h' | 'test-i' | 'test-j' | 'test',
REACT_APP_TYPE: 'auth-service' | 'ott',
}
}

@ -1,4 +1,4 @@
import { API_ROOT } from 'features/AuthServiceApp/config/routes'
import { AUTH_SERVICE } from 'config'
export type FailedResponse = {
error?: string,
@ -10,7 +10,7 @@ export type SuccessResponse = {
}
export const checkDevice = async (token: string) => {
const url = `${API_ROOT}/authorize/check-device?access_token=${token}`
const url = `${AUTH_SERVICE}/authorize/check-device?access_token=${token}`
const config = {
method: 'GET',

@ -1,4 +1,4 @@
import { API_ROOT } from 'features/AuthServiceApp/config/routes'
import { AUTH_SERVICE } from 'config'
import { callApi } from 'helpers'
export type GeoInfoType = {
@ -14,6 +14,6 @@ export const getGeoInfo = async (): Promise<GeoInfoType> => {
return callApi({
config,
url: `${API_ROOT}/geoinfo`,
url: `${AUTH_SERVICE}/geoinfo`,
})
}

@ -6,12 +6,12 @@ import {
import {
ADS_API_URL,
APIS,
API_ROOT,
AUTH_SERVICE,
STATS_API_URL,
URL_AWS,
VIEWS_API,
} from 'config'
import { API_ROOT } from 'features/AuthServiceApp/config/routes'
import { surveys, getAds } from './fixtures'
import { models } from './models'

Loading…
Cancel
Save