Browse Source

FEATURE | show blocked ip message

merge-requests/42/head
andrew_bashliy 3 years ago
parent
commit
c1cd9bebb6
  1. 8
      .eslintrc.js
  2. 28
      android/.project
  3. 34
      android/app/.project
  4. 4
      ios/Podfile.lock
  5. 8
      src/api/http.service.ts
  6. 32
      src/modules/auth/hooks/use-authorization.hook.ts
  7. 4
      src/modules/auth/screens/confirm-code.screen.tsx
  8. 12
      src/modules/auth/screens/sign-in.screen.tsx
  9. 10
      src/services/domain/auth.service.ts
  10. 2
      src/shared/components/layouts/auth-layout.component.tsx
  11. 1
      src/shared/enums/exception-keys.enum.ts
  12. 2
      src/shared/helpers/exceptions.helpers.ts
  13. 10
      src/store/shared/reducer.ts
  14. 4
      src/store/shared/selectors.ts
  15. 12
      src/store/shared/types.ts

8
.eslintrc.js

@ -1,5 +1,9 @@ @@ -1,5 +1,9 @@
module.exports = {
root: true,
extends: '@react-native-community',
rules: {},
};
rules: {
semi: 0,
curly: 0,
'no-shadow': 'off',
},
}

28
android/.project

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>taskme</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1630909588189</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

34
android/app/.project

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>app</name>
<comment>Project app created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1630909588124</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

4
ios/Podfile.lock

@ -500,7 +500,7 @@ SPEC CHECKSUMS: @@ -500,7 +500,7 @@ SPEC CHECKSUMS:
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b
FBReactNativeSpec: 09a9b45481cf51e2fc98dd8dc8432607e43e1c52
FBReactNativeSpec: f92e05dd7f112a9a27a69b51545ca9e9c74439ff
Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c
@ -549,4 +549,4 @@ SPEC CHECKSUMS: @@ -549,4 +549,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 10a43cb7dc544fdabb001116ec92f9d67b11e153
COCOAPODS: 1.10.2
COCOAPODS: 1.10.1

8
src/api/http.service.ts

@ -4,6 +4,8 @@ import { config } from '@/config' @@ -4,6 +4,8 @@ import { config } from '@/config'
import { GlobalContainerService } from '@/services/system'
import Storage from 'react-native-expire-storage'
import { AuthService } from '@/services/domain'
import { SetIsForbidden } from '@/store/shared'
import { simpleDispatch } from '@/store/store-helpers'
const store = () => GlobalContainerService.get('store')
@ -40,10 +42,14 @@ const request = async <T>(func: Function): Promise<AxiosResponse<T>> => { @@ -40,10 +42,14 @@ const request = async <T>(func: Function): Promise<AxiosResponse<T>> => {
let response = await func()
return response as any as AxiosResponse
} catch (e: any) {
if (e.response.status === 401) {
console.log('CAUGHT IN REQ', e.response?.data.statusCode)
if (e.response?.data?.statusCode === 401) {
await AuthService.refreshSession()
return (await func()) as any as AxiosResponse
}
if (e.response?.data?.statusCode === 403) {
simpleDispatch(new SetIsForbidden({ isForbidden: true }))
}
throw e
}
}

32
src/modules/auth/hooks/use-authorization.hook.ts

@ -1,12 +1,24 @@ @@ -1,12 +1,24 @@
import { AuthService } from '@/services/domain'
import { useState } from 'react'
import { ExceptionKeys, getMessageByExceptionKey } from '@/shared'
import { selectIsForbidden } from '@/store/shared'
import { useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
export const useAuthorization = () => {
const [isSent, setIsSent] = useState(false)
const [isConfirmed, setIsConfirmed] = useState(false)
const [error, setError] = useState<any>(null)
const [error, setError] = useState<string>(null)
const isForbidden = useSelector(selectIsForbidden)
const clearError = () => setError(false)
const clearError = () => setError(null)
const setFirbiddenError = () => {
setError(getMessageByExceptionKey(ExceptionKeys.Forbidden))
}
useEffect(() => {
if (isForbidden) setFirbiddenError()
}, [isForbidden])
const sendCode = async (phoneNumber: string) => {
try {
@ -15,7 +27,13 @@ export const useAuthorization = () => { @@ -15,7 +27,13 @@ export const useAuthorization = () => {
setIsSent(true)
clearError()
} catch (e: any) {
setError(e.response?.data)
console.log('ERROR', e.message)
if (e.response?.data.statusCode === 403) {
setFirbiddenError()
return
}
setError(getMessageByExceptionKey(e.response?.data?.key))
}
}
@ -25,7 +43,11 @@ export const useAuthorization = () => { @@ -25,7 +43,11 @@ export const useAuthorization = () => {
setIsConfirmed(true)
clearError()
} catch (e: any) {
setError(e.response?.data)
if (e.response?.data.statusCode === 403) {
setFirbiddenError()
return
}
setError(getMessageByExceptionKey(e.response?.data?.key))
}
}

4
src/modules/auth/screens/confirm-code.screen.tsx

@ -3,7 +3,6 @@ import { @@ -3,7 +3,6 @@ import {
$size,
AuthLayout,
Button,
getMessageByExceptionKey,
getTheme,
ImageComponent,
NavigationModuleKey,
@ -79,13 +78,14 @@ export const ConfirmCode = () => { @@ -79,13 +78,14 @@ export const ConfirmCode = () => {
name: 'lock-1',
color: getTheme().iconComponent.$primaryColor,
}}
error={getMessageByExceptionKey(error?.key)}
error={error}
/>
<Button
title="Підтвердити"
onPress={() => {
confirmLogin(confirmCode)
}}
style={{ marginBottom: 80 }}
/>
</View>
</View>

12
src/modules/auth/screens/sign-in.screen.tsx

@ -4,13 +4,7 @@ import { StyleSheet, Text, View } from 'react-native' @@ -4,13 +4,7 @@ import { StyleSheet, Text, View } from 'react-native'
import { AuthLayout, Button } from '$components'
import { ImageComponent } from '../../../shared/components/elements/image.component'
import { FormPhone } from '../../../shared/components/forms/form-phone.component'
import {
$size,
getMessageByExceptionKey,
getTheme,
IRouteParams,
RouteKey,
} from '@/shared'
import { $size, getTheme, IRouteParams, RouteKey } from '@/shared'
import { useAuthorization } from '../hooks'
interface IProps extends IRouteParams {}
@ -21,7 +15,7 @@ export const SignInScreen = ({ navigation }: IProps) => { @@ -21,7 +15,7 @@ export const SignInScreen = ({ navigation }: IProps) => {
useEffect(() => {
if (isSent) navigation.navigate(RouteKey.ConfirmCode)
}, [isSent])
}, [isSent, navigation])
return (
<AuthLayout>
@ -41,7 +35,7 @@ export const SignInScreen = ({ navigation }: IProps) => { @@ -41,7 +35,7 @@ export const SignInScreen = ({ navigation }: IProps) => {
name={'phoneNumber'}
onChange={v => setPhoneNumber(v)}
value={phoneNumber}
error={getMessageByExceptionKey(error?.key)}
error={error}
/>
<Button
title="Підтвердити"

10
src/services/domain/auth.service.ts

@ -2,9 +2,9 @@ import { Platform } from 'react-native' @@ -2,9 +2,9 @@ import { Platform } from 'react-native'
import { requestConfirmationCode, finishLogin, sendRefreshToken } from '@/api'
import { SaveTokens } from '@/store/auth'
import { simpleDispatch } from '@/store/store-helpers'
import { NavigationService, NetworkService, StorageService } from '../system'
import { NavigationService, StorageService } from '../system'
import { ITokenPair, NavigationModuleKey, StorageKey } from '@/shared'
import { AccountService } from '.'
import { AccountService } from './account.service'
let phoneNumber: string
@ -41,10 +41,16 @@ const autoAuth = async () => { @@ -41,10 +41,16 @@ const autoAuth = async () => {
} catch (e) {
console.log('ACCOUNT LOADING ERROR', e)
await dropTokens()
NavigationService.setModule(NavigationModuleKey.Auth)
}
}
const dropTokens = async () => {
await StorageService.set(StorageKey.AccessToken, '')
await StorageService.set(StorageKey.RefreshToken, '')
}
const refreshSession = async (refreshToken?: string) => {
let token = refreshToken
if (!token) {

2
src/shared/components/layouts/auth-layout.component.tsx

@ -8,7 +8,7 @@ interface IProps { @@ -8,7 +8,7 @@ interface IProps {
export const AuthLayout = (props: IProps) => {
return (
<ScreenLayout needScroll={false}>
<ScreenLayout needScroll={true}>
<View style={styles.wrapper}>{props.children}</View>
</ScreenLayout>
)

1
src/shared/enums/exception-keys.enum.ts

@ -3,4 +3,5 @@ export enum ExceptionKeys { @@ -3,4 +3,5 @@ export enum ExceptionKeys {
InvalidCredentials = 'invalid_credentials',
WrongCode = 'wrong_code',
NotFound = 'not_found',
Forbidden = 'forbidden_resource',
}

2
src/shared/helpers/exceptions.helpers.ts

@ -3,6 +3,8 @@ import { ExceptionKeys } from '../enums' @@ -3,6 +3,8 @@ import { ExceptionKeys } from '../enums'
const exceptionsDictionary = {
[ExceptionKeys.WrongCode]: 'Неправильний код',
[ExceptionKeys.InvalidCredentials]: 'Невірно введено дані',
[ExceptionKeys.Forbidden]:
'Вашу IP-адресу заблоковано. Для розблокування зверніться до адміністратора',
}
export const getMessageByExceptionKey = (key: ExceptionKeys) => {

10
src/store/shared/reducer.ts

@ -4,10 +4,12 @@ import { NavigationModuleKey } from '@/shared/enums' @@ -4,10 +4,12 @@ import { NavigationModuleKey } from '@/shared/enums'
export interface ISharedState {
activeNavigationModule: NavigationModuleKey
isForbidden: ConstrainBoolean
}
const initialState: ISharedState = {
activeNavigationModule: NavigationModuleKey.Loading,
isForbidden: false,
}
export const sharedReducer = createReducer<ISharedState, TAuthActions>(
@ -20,9 +22,17 @@ export const sharedReducer = createReducer<ISharedState, TAuthActions>( @@ -20,9 +22,17 @@ export const sharedReducer = createReducer<ISharedState, TAuthActions>(
}
},
SET_IS_FORBIDDEN: (state, action) => {
return {
...state,
isForbidden: action.payload.isForbidden,
}
},
RESET: () => {
return {
activeNavigationModule: NavigationModuleKey.Auth,
isForbidden: false,
}
},
},

4
src/store/shared/selectors.ts

@ -1,7 +1,9 @@ @@ -1,7 +1,9 @@
import { RootState } from '..'
export const selectActiveNavigationModule = (store: RootState) => {
return store.shared.activeNavigationModule
}
export const selectIsForbidden = (store: RootState) => {
return store.shared.isForbidden
}

12
src/store/shared/types.ts

@ -10,8 +10,18 @@ export class SetNavigationModule implements Action { @@ -10,8 +10,18 @@ export class SetNavigationModule implements Action {
) {}
}
export class SetIsForbidden implements Action {
readonly type = 'SET_IS_FORBIDDEN'
constructor(
public readonly payload: {
isForbidden: boolean
},
) {}
}
export class Reset {
readonly type = 'RESET'
}
export type TAuthActions = SetNavigationModule | Reset
export type TAuthActions = SetNavigationModule | SetIsForbidden | Reset

Loading…
Cancel
Save