Fix auth page's init process to account for token expiry
This commit is contained in:
parent
de94602cd2
commit
3920ddf20e
|
@ -20,9 +20,72 @@ const AuthenticateJsx = ({navigation}) => {
|
||||||
const REDIRECT_URI = Linking.makeUrl("authenticate");
|
const REDIRECT_URI = Linking.makeUrl("authenticate");
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
instance: "",
|
instance: "",
|
||||||
authChecked: false,
|
renderLogin: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const init = async () => {
|
||||||
|
const [instancePair, tokenJSONPair, profileJSONPair, appJSONPair] =
|
||||||
|
await AsyncStorage.multiGet([
|
||||||
|
"@user_instance",
|
||||||
|
"@user_token",
|
||||||
|
"@user_profile",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const instance = instancePair[1];
|
||||||
|
const tokenJSON = tokenJSONPair[1];
|
||||||
|
const profileJSON = profileJSONPair[1];
|
||||||
|
|
||||||
|
if (profileJSON == null) {
|
||||||
|
// The user hasn't logged in yet.
|
||||||
|
setState({ ...state, renderLogin: true, });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessToken = JSON.parse(tokenJSON).access_token;
|
||||||
|
|
||||||
|
// Check to see if the credentials are still valid
|
||||||
|
const verifiedUser = await requests.verifyCredentials(
|
||||||
|
instance,
|
||||||
|
accessToken
|
||||||
|
).catch(e => {
|
||||||
|
/* The Pixelfed API returns an HTML page when your access token gets
|
||||||
|
* revoked instead of the JSON error object. Since this causes a lot
|
||||||
|
* of problems, we're going to assume that if the response is HTML,
|
||||||
|
* then the user needs to log in again. See issue #27.
|
||||||
|
*/
|
||||||
|
if (e instanceof SyntaxError) {
|
||||||
|
// Generate faux error API response
|
||||||
|
return { "error": true };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(verifiedUser.error) {
|
||||||
|
// `error` will be undefined if the token is valid
|
||||||
|
// Purge the user's data
|
||||||
|
await AsyncStorage.multiRemove([
|
||||||
|
"@user_instance",
|
||||||
|
"@user_token",
|
||||||
|
"@user_profile",
|
||||||
|
]);
|
||||||
|
|
||||||
|
setState({...state,
|
||||||
|
renderLogin: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// requests.verifyCredentials returns the latest version of the
|
||||||
|
// profile on success, so take this opportunity to update it
|
||||||
|
const newProfile = verifiedUser;
|
||||||
|
await AsyncStorage.setItem(
|
||||||
|
"@user_profile",
|
||||||
|
JSON.stringify(newProfile)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Since nothing went wrong, navigate to the feed.
|
||||||
|
navigation.navigate("Feed");
|
||||||
|
};
|
||||||
|
|
||||||
const _handleUrl = async ({ url }) => {
|
const _handleUrl = async ({ url }) => {
|
||||||
// When the app is foregrounded after authorizing the app from their
|
// When the app is foregrounded after authorizing the app from their
|
||||||
// instance's website...
|
// instance's website...
|
||||||
|
@ -77,16 +140,13 @@ const AuthenticateJsx = ({navigation}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Register the listener for the app getting foregrounded
|
||||||
|
// This is for when the user has navigated back from their web browser
|
||||||
|
// having approved the app
|
||||||
Linking.addEventListener("url", _handleUrl);
|
Linking.addEventListener("url", _handleUrl);
|
||||||
AsyncStorage
|
|
||||||
.getItem("@user_profile")
|
// Start initialization sequence
|
||||||
.then(profile => {
|
init();
|
||||||
if (profile) {
|
|
||||||
navigation.navigate("Feed");
|
|
||||||
} else {
|
|
||||||
setState({...state, authChecked: true});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const _login = async () => {
|
const _login = async () => {
|
||||||
|
@ -132,7 +192,7 @@ const AuthenticateJsx = ({navigation}) => {
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style = { styles.container }>
|
<SafeAreaView style = { styles.container }>
|
||||||
{
|
{
|
||||||
state.authChecked
|
state.renderLogin
|
||||||
? <View style = { styles.innerContainer }>
|
? <View style = { styles.innerContainer }>
|
||||||
<View style = { styles.logo.container }>
|
<View style = { styles.logo.container }>
|
||||||
<Image
|
<Image
|
||||||
|
|
|
@ -96,6 +96,14 @@ export async function _delete(url, token = false) {
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function verifyCredentials(domain, token) {
|
||||||
|
const resp = await get(
|
||||||
|
`https://${domain}/api/v1/accounts/verify_credentials`,
|
||||||
|
token
|
||||||
|
);
|
||||||
|
return resp.json();
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchProfile(domain, id) {
|
export async function fetchProfile(domain, id) {
|
||||||
const resp = await get(`https://${domain}/api/v1/accounts/${id}`);
|
const resp = await get(`https://${domain}/api/v1/accounts/${id}`);
|
||||||
return resp.json();
|
return resp.json();
|
||||||
|
|
Loading…
Reference in New Issue