130 lines
4.4 KiB
Rust
130 lines
4.4 KiB
Rust
use graphql_client::reqwest::post_graphql;
|
|
use yew::prelude::*;
|
|
|
|
use crate::components;
|
|
use crate::graphql;
|
|
|
|
pub enum Msg {
|
|
DoneFetching {
|
|
errors: graphql::Errors,
|
|
tokens: Vec<graphql::queries::tokens::tokens::TokensTokens>,
|
|
},
|
|
Revoke(usize),
|
|
RevokeDone(graphql::Errors),
|
|
}
|
|
|
|
#[derive(Properties, PartialEq, Eq)]
|
|
pub struct TokensProps {
|
|
pub token: String,
|
|
}
|
|
|
|
pub struct Tokens {
|
|
fetching: bool,
|
|
errors: graphql::Errors,
|
|
tokens: Option<Vec<graphql::queries::tokens::tokens::TokensTokens>>,
|
|
}
|
|
|
|
impl Component for Tokens {
|
|
type Message = Msg;
|
|
type Properties = TokensProps;
|
|
|
|
fn create(ctx: &Context<Self>) -> Self {
|
|
let client = graphql::client(Some(&ctx.props().token)).unwrap();
|
|
ctx.link().send_future(async move {
|
|
let response = post_graphql::<graphql::queries::tokens::Tokens, _>(
|
|
&client,
|
|
graphql::URL.as_str(),
|
|
graphql::queries::tokens::tokens::Variables,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
Msg::DoneFetching {
|
|
errors: graphql::convert(response.errors),
|
|
tokens: response.data.unwrap().tokens.unwrap(),
|
|
}
|
|
});
|
|
|
|
Self {
|
|
fetching: true,
|
|
errors: None,
|
|
tokens: None,
|
|
}
|
|
}
|
|
|
|
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
match msg {
|
|
Msg::DoneFetching { errors, tokens } => {
|
|
self.fetching = false;
|
|
self.errors = errors;
|
|
self.tokens = Some(tokens);
|
|
true
|
|
}
|
|
Msg::Revoke(id) => {
|
|
self.tokens.as_mut().unwrap().remove(id);
|
|
|
|
let client = graphql::client(Some(&ctx.props().token)).unwrap();
|
|
let token = self.tokens.as_ref().unwrap()[id].id.to_owned();
|
|
ctx.link().send_future(async move {
|
|
let response =
|
|
post_graphql::<graphql::mutations::revoke_token::RevokeToken, _>(
|
|
&client,
|
|
graphql::URL.as_str(),
|
|
graphql::mutations::revoke_token::revoke_token::Variables { token },
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
Msg::RevokeDone(graphql::convert(response.errors))
|
|
});
|
|
|
|
true
|
|
}
|
|
Msg::RevokeDone(errors) => {
|
|
self.errors = errors;
|
|
true
|
|
}
|
|
}
|
|
}
|
|
|
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
html! {
|
|
<fieldset class={classes!("fieldset")}>
|
|
<legend>{ "Tokens" }</legend>
|
|
if self.fetching {
|
|
<components::fetching::Fetching />
|
|
} else {
|
|
<table class={classes!("table")}>
|
|
<thead>
|
|
<tr>
|
|
<th><abbr title="JTI claim of the JWT">{ "ID" }</abbr></th>
|
|
<th><abbr title="IAT claim of the JWT">{ "Issued at" }</abbr></th>
|
|
<th><abbr title="EXP claim of the JWT">{ "Expires at" }</abbr></th>
|
|
<th>{ "Revoke" }</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{
|
|
for self.tokens.as_ref().unwrap().iter().enumerate().map(|(i, t)| html! {
|
|
<tr>
|
|
<th><code>{ &t.id }</code></th>
|
|
<td><code>{ &t.iat }</code></td>
|
|
<td><code>{ &t.exp }</code></td>
|
|
<td>
|
|
<button class={classes!("button")} onclick={ctx.link().callback(move |_| Msg::Revoke(i))}>
|
|
{ "Revoke" }
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
})
|
|
}
|
|
</tbody>
|
|
</table>
|
|
|
|
<components::graphql_errors::GraphQLErrors errors={self.errors.to_owned()} />
|
|
}
|
|
</fieldset>
|
|
}
|
|
}
|
|
}
|