Browse Source

Merge pull request #19011 from abpframework/react-native/logout

React native/logout
pull/19012/head
Sinan Öztürk 3 years ago
committed by GitHub
parent
commit
79f054c5b4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      templates/app/react-native/.prettierrc
  2. 5
      templates/app/react-native/Environment.js
  3. 2
      templates/app/react-native/package.json
  4. 28
      templates/app/react-native/src/api/AccountAPI.js
  5. 32
      templates/app/react-native/src/screens/Settings/SettingsScreen.js
  6. 11
      templates/app/react-native/src/store/actions/AppActions.js
  7. 26
      templates/app/react-native/src/store/sagas/AppSaga.js

2
templates/app/react-native/.prettierrc

@ -2,7 +2,7 @@
"trailingComma": "all",
"singleQuote": true,
"jsxSingleQuote": false,
"printWidth": 100,
"printWidth": 80,
"semi": true,
"jsxBracketSameLine": true,
"arrowParens": "avoid"

5
templates/app/react-native/Environment.js

@ -1,6 +1,5 @@
const yourIP = 'Your Local IP Address etc 192.168.1.64'; // See the docs https://docs.abp.io/en/abp/latest/Getting-Started-React-Native?Tiered=No
const port = 44305;
const yourIP = 'localhost'; // See the docs https://docs.abp.io/en/abp/latest/Getting-Started-React-Native?Tiered=No
const port = 44305;
const apiUrl = `http://${yourIP}:${port}`;
const ENV = {
dev: {

2
templates/app/react-native/package.json

@ -24,7 +24,7 @@
"prop-types": "^15.8.1",
"react": "18.1.0",
"react-dom": "18.1.0",
"react-native": "0.70.5",
"react-native": "0.70.8",
"react-native-chart-kit": "^6.11.0",
"react-native-gesture-handler": "~2.8.0",
"react-native-reanimated": "~2.12.0",

28
templates/app/react-native/src/api/AccountAPI.js

@ -4,13 +4,12 @@ import { getEnvVars } from '../../Environment';
const { oAuthConfig } = getEnvVars();
getLoginData = (username, password) => {
const formData = {
grant_type: 'password',
scope: oAuthConfig.scope,
username: username,
password: password,
client_id: oAuthConfig.clientId
client_id: oAuthConfig.clientId,
};
if (oAuthConfig.clientSecret)
@ -19,7 +18,7 @@ getLoginData = (username, password) => {
return Object.entries(formData)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
}
};
export const login = ({ username, password }) =>
api({
@ -27,15 +26,28 @@ export const login = ({ username, password }) =>
url: '/connect/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: getLoginData(username, password),
baseURL: oAuthConfig.issuer
baseURL: oAuthConfig.issuer,
}).then(({ data }) => data);
export const Logout = (
input = { client_id: '', token: '', token_type_hint: '' },
) => {
if (!input.token_type_hint) {
input.token_type_hint = 'access_token';
}
export const Logout = () =>
api({
method: 'GET',
url: '/api/account/logout',
const _data = Object.entries(input)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
return api({
method: 'POST',
url: '/connect/revocat',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: _data,
baseURL: oAuthConfig.issuer,
}).then(({ data }) => data);
};
export const getTenant = tenantName =>
api({

32
templates/app/react-native/src/screens/Settings/SettingsScreen.js

@ -1,17 +1,31 @@
import { Ionicons } from '@expo/vector-icons';
import { useFocusEffect } from '@react-navigation/native';
import i18n from 'i18n-js';
import { Avatar, Button, Divider, FormControl, List, Select, Stack, Text, View } from 'native-base';
import {
Avatar,
Button,
Divider,
FormControl,
List,
Select,
Stack,
Text,
View,
} from 'native-base';
import PropTypes from 'prop-types';
import React, { useCallback, useState } from 'react';
import { getProfileDetail } from '../../api/IdentityAPI';
import AppActions from '../../store/actions/AppActions';
import {
createLanguageSelector,
createLanguagesSelector
createLanguagesSelector,
} from '../../store/selectors/AppSelectors';
import { createTenantSelector } from '../../store/selectors/PersistentStorageSelectors';
import { connectToRedux } from '../../utils/ReduxConnect';
import { store } from '../../store/index';
import { getEnvVars } from '../../../Environment';
const env = getEnvVars();
function SettingsScreen({
navigation,
@ -22,6 +36,7 @@ function SettingsScreen({
tenant = {},
}) {
const [user, setUser] = useState({});
const [token, setToken] = useState(store.getState().persistentStorage.token);
const fetchUser = () => {
getProfileDetail().then(data => {
@ -35,6 +50,17 @@ function SettingsScreen({
}, []),
);
const logout = () => {
const { clientId } = env.oAuthConfig;
const { access_token, refresh_token } = token;
logoutAsync({
client_id: clientId,
token: access_token,
refresh_token: refresh_token,
});
};
return (
<View>
<List px="0" py="0" borderWidth="0">
@ -100,7 +126,7 @@ function SettingsScreen({
bg="danger.500"
style={{ borderRadius: 0 }}
onPress={() => {
logoutAsync();
logout();
}}>
{i18n.t('AbpAccount::Logout')}
</Button>

11
templates/app/react-native/src/store/actions/AppActions.js

@ -2,14 +2,21 @@ import { createAction } from '@reduxjs/toolkit';
const fetchAppConfigAsync = createAction(
'app/fetchAppConfigAsync',
({ callback = () => {}, showLoading = true } = {}) => ({ payload: { callback, showLoading } }),
({ callback = () => {}, showLoading = true } = {}) => ({
payload: { callback, showLoading },
}),
);
const setAppConfig = createAction('app/setAppConfig');
const setLanguageAsync = createAction('app/setLanguageAsync');
const logoutAsync = createAction('app/logoutAsync');
const logoutAsync = createAction(
'app/logoutAsync',
({ client_id = '', token = '', refresh_token = '' } = {}) => ({
payload: { client_id, token, refresh_token },
}),
);
export default {
fetchAppConfigAsync,

26
templates/app/react-native/src/store/sagas/AppSaga.js

@ -6,10 +6,17 @@ import LoadingActions from '../actions/LoadingActions';
import PersistentStorageActions from '../actions/PersistentStorageActions';
function* fetchAppConfig({ payload: { showLoading, callback } }) {
if (showLoading) yield put(LoadingActions.start({ key: 'appConfig', opacity: 1 }));
if (showLoading) {
yield put(LoadingActions.start({ key: 'appConfig', opacity: 1 }));
}
const data = yield call(getApplicationConfiguration);
yield put(AppActions.setAppConfig(data));
yield put(PersistentStorageActions.setLanguage(data.localization.currentCulture.cultureName));
yield put(
PersistentStorageActions.setLanguage(
data.localization.currentCulture.cultureName,
),
);
if (showLoading) yield put(LoadingActions.stop({ key: 'appConfig' }));
callback();
}
@ -19,13 +26,22 @@ function* setLanguage(action) {
yield put(AppActions.fetchAppConfigAsync());
}
function* logout() {
yield call(Logout);
function* logout({ payload: { client_id, token, refresh_token } }) {
const data = { client_id, token };
yield call(Logout, data);
if (!!refresh_token) {
data.token = refresh_token;
data.token_type_hint = 'refresh_token';
yield call(Logout, data);
}
yield put(PersistentStorageActions.setToken({}));
yield put(AppActions.fetchAppConfigAsync());
}
export default function*() {
export default function* () {
yield all([
takeLatest(AppActions.setLanguageAsync.type, setLanguage),
takeLatest(AppActions.fetchAppConfigAsync.type, fetchAppConfig),

Loading…
Cancel
Save