Enable logging out by revoking the access token

This commit is contained in:
Nat 2021-05-04 18:50:41 -03:00
parent 856f215e36
commit 6d0bfa8fd7
1 changed files with 221 additions and 169 deletions

View File

@ -13,6 +13,7 @@ import {
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
import { withoutHTML } from "src/interface/rendering"; import { withoutHTML } from "src/interface/rendering";
import * as requests from "src/requests";
import { ScreenWithBackBarJsx } from "src/components/navigation/navigators"; import { ScreenWithBackBarJsx } from "src/components/navigation/navigators";
@ -46,184 +47,235 @@ const SettingsJsx = (props) => {
// Use Context to get this stuff eventually // Use Context to get this stuff eventually
profile: TEST_PROFILE, profile: TEST_PROFILE,
newProfile: TEST_PROFILE, newProfile: TEST_PROFILE,
loaded: false,
}); });
const fields = state.newProfile.fields; const fields = state.newProfile.fields;
const _handleLogout = async () => {
await requests.postForm(
`https://${state.instance}/oauth/revoke`,
{
client_id: state.appObject.client_id,
client_secret: state.appObject.client_secret,
token: state.token.access_token,
}
);
await AsyncStorage.multiRemove([
"@user_profile",
"@user_notifications",
"@user_instance",
"@user_token",
]);
props.navigation.navigate("Authenticate");
};
useEffect(() => {
AsyncStorage
.multiGet([
"@user_profile",
"@user_instance",
"@user_token",
"@app_object",
])
.then(([profilePair, instancePair, tokenPair, appPair]) =>
[
JSON.parse(profilePair[1]),
instancePair[1],
JSON.parse(tokenPair[1]),
JSON.parse(appPair[1]),
]
)
.then(([profile, instance, token, appObject]) => {
let newProfile = profile;
newProfile.fields = newProfile.fields == null
? []
: newProfile.fields;
setState({...state,
profile: profile,
newProfile: newProfile,
instance: instance,
appObject: appObject,
token: token,
loaded: true,
})
});
}, []);
return ( return (
<ScreenWithBackBarJsx navigation = { props.navigation }> <>
<View style = { styles.avatar.container }> { state.loaded
<Image ? <ScreenWithBackBarJsx navigation = { props.navigation }>
source = { { uri: state.profile.avatar } } <View style = { styles.avatar.container }>
style = { styles.avatar.image }/> <Image
<TouchableOpacity> source = { { uri: state.profile.avatar } }
<Text style = { styles.avatar.change }> style = { styles.avatar.image }/>
Change profile photo <TouchableOpacity>
</Text> <Text style = { styles.avatar.change }>
</TouchableOpacity> Change profile photo
</View> </Text>
<View style = { styles.input.container }> </TouchableOpacity>
<Text style = { styles.label }>Display name</Text> </View>
<TextInput <View style = { styles.input.container }>
style = { styles.bar } <Text style = { styles.label }>Display name</Text>
placeholder = { "Display name" } <TextInput
value = { state.newProfile.display_name } style = { styles.bar }
onChangeText = { placeholder = { "Display name" }
(value) => { value = { state.newProfile.display_name }
setState({...state, onChangeText = {
newProfile: {...state.newProfile, display_name: value} (value) => {
}); setState({...state,
} newProfile: {...state.newProfile, display_name: value}
}/> });
}
}/>
<Text style = { styles.label }>User name</Text> <Text style = { styles.label }>User name</Text>
<TextInput <TextInput
style = { styles.bar } style = { styles.bar }
placeholder = { "User name" } placeholder = { "User name" }
value = { state.newProfile.username } value = { state.newProfile.username }
onChangeText = { onChangeText = {
(value) => { (value) => {
setState({...state, setState({...state,
newProfile: {...state.newProfile, username: value} newProfile: {...state.newProfile, username: value}
}); });
} }
}/> }/>
<Text style = { styles.label }>Bio</Text> <Text style = { styles.label }>Bio</Text>
<TextInput <TextInput
style = { style = {
[ [
styles.bar, styles.bar,
{ height: 100 }, { height: 100 },
] ]
} }
multiline = { true } multiline = { true }
placeholder = { "Bio" } placeholder = { "Bio" }
value = { withoutHTML(state.newProfile.note) } value = { withoutHTML(state.newProfile.note) }
onChangeText = { onChangeText = {
(value) => { (value) => {
setState({...state, setState({...state,
newProfile: {...state.newProfile, note: value} newProfile: {...state.newProfile, note: value}
}); });
} }
}/> }/>
{ {
fields.map((field, i) => fields.map((field, i) =>
<View <View
style = { styles.fields.container } style = { styles.fields.container }
key = { i }> key = { i }>
<TouchableOpacity <TouchableOpacity
onPress = { onPress = {
() => { () => {
let newFields; let newFields;
if (fields.length == 1) { if (fields.length == 1) {
newFields = [{ name: "", value: "" }]; newFields = [{ name: "", value: "" }];
} else { } else {
newFields = state.newProfile.fields; newFields = state.newProfile.fields;
newFields.splice(i, 1); newFields.splice(i, 1);
} }
setState({...state, setState({...state,
newProfile: {...state.newProfile, newProfile: {...state.newProfile,
fields: newFields, fields: newFields,
}, },
}); });
} }
}>
<Image
style = {
[
styles.fields.cross,
fields.length == 1
&& fields[0].name == ""
&& fields[0].value == ""
? { visibility: "hidden" }
: {}
]
}
source = { require("assets/eva-icons/close.png") }/>
</TouchableOpacity>
<View style = { styles.fields.subContainer }>
<Text style = { styles.label }>Name</Text>
<TextInput
style = { [styles.bar, styles.fields.cell] }
placeholder = { "Name" }
value = { withoutHTML(fields[i].name) }
onChangeText = {
(text) => {
let newFields = fields;
newFields[i] = {...newFields[i],
name: text,
};
setState({...state,
newProfile: {...state.newProfile,
fields: newFields,
},
});
}
} />
</View>
<View style = { styles.fields.subContainer }>
<Text style = { styles.label }>Value</Text>
<TextInput
style = { [styles.bar, styles.fields.cell] }
placeholder = { "Value" }
value = { withoutHTML(fields[i].value) }
onChangeText = {
(text) => {
let newFields = fields;
newFields[i] = {...newFields[i],
value: text,
};
setState({...state,
newProfile: {...state.newProfile,
fields: newFields,
},
});
}
} />
</View>
</View>
)
}
<TouchableOpacity
onPress = {
() => {
setState({...state,
newProfile: {...state.newProfile,
fields: state.newProfile.fields.concat({ name: "", value: ""}),
},
});
}
}>
<Image
style = { styles.fields.plus }
source = { require("assets/eva-icons/plus.png") } />
</TouchableOpacity>
<TouchableOpacity style = { styles.button.container }>
<Text style = { styles.button.text }> Save Profile </Text>
</TouchableOpacity>
<TouchableOpacity
style = { styles.button.container }
onPress = { _handleLogout }>
<Text style = {
[ styles.button.text, styles.button.warning ]
}> }>
<Image Log out
style = { </Text>
[ </TouchableOpacity>
styles.fields.cross, </View>
fields.length == 1 </ScreenWithBackBarJsx>
&& fields[0].name == "" : <></>
&& fields[0].value == "" }
? { visibility: "hidden" } </>
: {}
]
}
source = { require("assets/eva-icons/close.png") }/>
</TouchableOpacity>
<View style = { styles.fields.subContainer }>
<Text style = { styles.label }>Name</Text>
<TextInput
style = { [styles.bar, styles.fields.cell] }
placeholder = { "Name" }
value = { withoutHTML(fields[i].name) }
onChangeText = {
(text) => {
let newFields = fields;
newFields[i] = {...newFields[i],
name: text,
};
setState({...state,
newProfile: {...state.newProfile,
fields: newFields,
},
});
}
} />
</View>
<View style = { styles.fields.subContainer }>
<Text style = { styles.label }>Value</Text>
<TextInput
style = { [styles.bar, styles.fields.cell] }
placeholder = { "Value" }
value = { withoutHTML(fields[i].value) }
onChangeText = {
(text) => {
let newFields = fields;
newFields[i] = {...newFields[i],
value: text,
};
setState({...state,
newProfile: {...state.newProfile,
fields: newFields,
},
});
}
} />
</View>
</View>
)
}
<TouchableOpacity
onPress = {
() => {
setState({...state,
newProfile: {...state.newProfile,
fields: state.newProfile.fields.concat({ name: "", value: ""}),
},
});
}
}>
<Image
style = { styles.fields.plus }
source = { require("assets/eva-icons/plus.png") } />
</TouchableOpacity>
<TouchableOpacity style = { styles.button.container }>
<Text style = { styles.button.text }> Save Profile </Text>
</TouchableOpacity>
<TouchableOpacity
style = { styles.button.container }
onPress = {
() => {
AsyncStorage.multiRemove(
["@user_profile", "@user_notifications"]
).then(() => {
props.navigation.navigate("Authenticate");
});
}
}>
<Text style = {
[ styles.button.text, styles.button.warning ]
}>
Log out
</Text>
</TouchableOpacity>
</View>
</ScreenWithBackBarJsx>
); );
}; };