You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-06 06:02:40 +03:00
Simple list of compat sessions
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2605,7 +2605,9 @@ dependencies = [
|
|||||||
"oauth2-types",
|
"oauth2-types",
|
||||||
"serde",
|
"serde",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
"ulid",
|
"ulid",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
@@ -10,7 +10,9 @@ async-graphql = { version = "4.0.16", features = ["chrono", "url"] }
|
|||||||
chrono = "0.4.23"
|
chrono = "0.4.23"
|
||||||
serde = { version = "1.0.147", features = ["derive"] }
|
serde = { version = "1.0.147", features = ["derive"] }
|
||||||
sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "postgres"] }
|
sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "postgres"] }
|
||||||
|
thiserror = "1.0.37"
|
||||||
tokio = { version = "1.21.2", features = ["time"] }
|
tokio = { version = "1.21.2", features = ["time"] }
|
||||||
|
tracing = "0.1.37"
|
||||||
ulid = "1.0.0"
|
ulid = "1.0.0"
|
||||||
url = "2.3.1"
|
url = "2.3.1"
|
||||||
|
|
||||||
|
@@ -22,8 +22,9 @@
|
|||||||
#![warn(clippy::pedantic)]
|
#![warn(clippy::pedantic)]
|
||||||
#![allow(clippy::module_name_repetitions, clippy::missing_errors_doc)]
|
#![allow(clippy::module_name_repetitions, clippy::missing_errors_doc)]
|
||||||
|
|
||||||
use async_graphql::{Context, Description, EmptyMutation, EmptySubscription};
|
use async_graphql::{Context, Description, EmptyMutation, EmptySubscription, ID};
|
||||||
use mas_axum_utils::SessionInfo;
|
use mas_axum_utils::SessionInfo;
|
||||||
|
use model::NodeType;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
use self::model::{BrowserSession, Node, User};
|
use self::model::{BrowserSession, Node, User};
|
||||||
@@ -78,4 +79,34 @@ impl RootQuery {
|
|||||||
|
|
||||||
Ok(session.map(User::from))
|
Ok(session.map(User::from))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetches an object given its ID.
|
||||||
|
async fn node(&self, ctx: &Context<'_>, id: ID) -> Result<Option<Node>, async_graphql::Error> {
|
||||||
|
let (node_type, id) = NodeType::from_id(&id)?;
|
||||||
|
let database = ctx.data::<PgPool>()?;
|
||||||
|
let session_info = ctx.data::<SessionInfo>()?;
|
||||||
|
let mut conn = database.acquire().await?;
|
||||||
|
let session = session_info.load_session(&mut conn).await?;
|
||||||
|
|
||||||
|
let Some(session) = session else { return Ok(None) };
|
||||||
|
|
||||||
|
match node_type {
|
||||||
|
// TODO
|
||||||
|
NodeType::Authentication
|
||||||
|
| NodeType::BrowserSession
|
||||||
|
| NodeType::CompatSession
|
||||||
|
| NodeType::CompatSsoLogin
|
||||||
|
| NodeType::OAuth2Client
|
||||||
|
| NodeType::UserEmail
|
||||||
|
| NodeType::OAuth2Session => Ok(None),
|
||||||
|
|
||||||
|
NodeType::User => {
|
||||||
|
if session.user.data == id {
|
||||||
|
Ok(Some(Box::new(User(session.user)).into()))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ use async_graphql::{Description, Object, ID};
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use mas_storage::PostgresqlBackend;
|
use mas_storage::PostgresqlBackend;
|
||||||
|
|
||||||
use super::User;
|
use super::{NodeType, User};
|
||||||
|
|
||||||
/// A browser session represents a logged in user in a browser.
|
/// A browser session represents a logged in user in a browser.
|
||||||
#[derive(Description)]
|
#[derive(Description)]
|
||||||
@@ -32,7 +32,7 @@ impl From<mas_data_model::BrowserSession<PostgresqlBackend>> for BrowserSession
|
|||||||
impl BrowserSession {
|
impl BrowserSession {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::BrowserSession.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The user logged in this session.
|
/// The user logged in this session.
|
||||||
@@ -60,7 +60,7 @@ pub struct Authentication(pub mas_data_model::Authentication<PostgresqlBackend>)
|
|||||||
impl Authentication {
|
impl Authentication {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::Authentication.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When the object was created.
|
/// When the object was created.
|
||||||
|
@@ -18,7 +18,7 @@ use mas_data_model::CompatSsoLoginState;
|
|||||||
use mas_storage::PostgresqlBackend;
|
use mas_storage::PostgresqlBackend;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use super::User;
|
use super::{NodeType, User};
|
||||||
|
|
||||||
/// A compat session represents a client session which used the legacy Matrix
|
/// A compat session represents a client session which used the legacy Matrix
|
||||||
/// login API.
|
/// login API.
|
||||||
@@ -29,7 +29,7 @@ pub struct CompatSession(pub mas_data_model::CompatSession<PostgresqlBackend>);
|
|||||||
impl CompatSession {
|
impl CompatSession {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::CompatSession.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The user authorized for this session.
|
/// The user authorized for this session.
|
||||||
@@ -62,7 +62,7 @@ pub struct CompatSsoLogin(pub mas_data_model::CompatSsoLogin<PostgresqlBackend>)
|
|||||||
impl CompatSsoLogin {
|
impl CompatSsoLogin {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::CompatSsoLogin.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When the object was created.
|
/// When the object was created.
|
||||||
|
@@ -16,14 +16,7 @@ use async_graphql::connection::OpaqueCursor;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy)]
|
pub use super::NodeType;
|
||||||
#[serde(rename = "snake_case")]
|
|
||||||
pub enum NodeType {
|
|
||||||
UserEmail,
|
|
||||||
BrowserSession,
|
|
||||||
CompatSsoLogin,
|
|
||||||
OAuth2Session,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct NodeCursor(pub NodeType, pub Ulid);
|
pub struct NodeCursor(pub NodeType, pub Ulid);
|
||||||
|
@@ -12,37 +12,25 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use async_graphql::{Interface, ID};
|
use async_graphql::Interface;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
|
||||||
mod browser_sessions;
|
mod browser_sessions;
|
||||||
mod compat_sessions;
|
mod compat_sessions;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
|
mod node;
|
||||||
mod oauth;
|
mod oauth;
|
||||||
mod users;
|
mod users;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
browser_sessions::{Authentication, BrowserSession},
|
browser_sessions::{Authentication, BrowserSession},
|
||||||
compat_sessions::{CompatSession, CompatSsoLogin},
|
compat_sessions::{CompatSession, CompatSsoLogin},
|
||||||
cursor::{Cursor, NodeCursor, NodeType},
|
cursor::{Cursor, NodeCursor},
|
||||||
|
node::{Node, NodeType},
|
||||||
oauth::{OAuth2Client, OAuth2Consent, OAuth2Session},
|
oauth::{OAuth2Client, OAuth2Consent, OAuth2Session},
|
||||||
users::{User, UserEmail},
|
users::{User, UserEmail},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An object with an ID.
|
|
||||||
#[derive(Interface)]
|
|
||||||
#[graphql(field(name = "id", desc = "ID of the object.", type = "ID"))]
|
|
||||||
pub enum Node {
|
|
||||||
Authentication(Box<Authentication>),
|
|
||||||
BrowserSession(Box<BrowserSession>),
|
|
||||||
CompatSession(Box<CompatSession>),
|
|
||||||
CompatSsoLogin(Box<CompatSsoLogin>),
|
|
||||||
OAuth2Client(Box<OAuth2Client>),
|
|
||||||
OAuth2Session(Box<OAuth2Session>),
|
|
||||||
User(Box<User>),
|
|
||||||
UserEmail(Box<UserEmail>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Interface)]
|
#[derive(Interface)]
|
||||||
#[graphql(field(
|
#[graphql(field(
|
||||||
name = "created_at",
|
name = "created_at",
|
||||||
|
107
crates/graphql/src/model/node.rs
Normal file
107
crates/graphql/src/model/node.rs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use async_graphql::{Interface, ID};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use thiserror::Error;
|
||||||
|
use ulid::Ulid;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
Authentication, BrowserSession, CompatSession, CompatSsoLogin, OAuth2Client, OAuth2Session,
|
||||||
|
User, UserEmail,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum NodeType {
|
||||||
|
Authentication,
|
||||||
|
BrowserSession,
|
||||||
|
CompatSession,
|
||||||
|
CompatSsoLogin,
|
||||||
|
OAuth2Client,
|
||||||
|
OAuth2Session,
|
||||||
|
User,
|
||||||
|
UserEmail,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
#[error("invalid id")]
|
||||||
|
pub enum InvalidID {
|
||||||
|
InvalidFormat,
|
||||||
|
InvalidUlid(#[from] ulid::DecodeError),
|
||||||
|
UnknownPrefix,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NodeType {
|
||||||
|
fn to_prefix(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
NodeType::Authentication => "authentication",
|
||||||
|
NodeType::BrowserSession => "browser_session",
|
||||||
|
NodeType::CompatSession => "compat_session",
|
||||||
|
NodeType::CompatSsoLogin => "compat_sso_login",
|
||||||
|
NodeType::OAuth2Client => "oauth2_client",
|
||||||
|
NodeType::OAuth2Session => "oauth2_session",
|
||||||
|
NodeType::User => "user",
|
||||||
|
NodeType::UserEmail => "user_email",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_prefix(prefix: &str) -> Option<Self> {
|
||||||
|
match prefix {
|
||||||
|
"authentication" => Some(NodeType::Authentication),
|
||||||
|
"browser_session" => Some(NodeType::BrowserSession),
|
||||||
|
"compat_session" => Some(NodeType::CompatSession),
|
||||||
|
"compat_sso_login" => Some(NodeType::CompatSsoLogin),
|
||||||
|
"oauth2_client" => Some(NodeType::OAuth2Client),
|
||||||
|
"oauth2_session" => Some(NodeType::OAuth2Session),
|
||||||
|
"user" => Some(NodeType::User),
|
||||||
|
"user_email" => Some(NodeType::UserEmail),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(self, id: impl Into<Ulid>) -> String {
|
||||||
|
let prefix = self.to_prefix();
|
||||||
|
let id = id.into();
|
||||||
|
format!("{prefix}:{id}")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(self, id: impl Into<Ulid>) -> ID {
|
||||||
|
ID(self.serialize(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize(serialized: &str) -> Result<(Self, Ulid), InvalidID> {
|
||||||
|
let (prefix, id) = serialized.split_once(':').ok_or(InvalidID::InvalidFormat)?;
|
||||||
|
let prefix = NodeType::from_prefix(prefix).ok_or(InvalidID::UnknownPrefix)?;
|
||||||
|
let id = id.parse()?;
|
||||||
|
Ok((prefix, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_id(id: &ID) -> Result<(Self, Ulid), InvalidID> {
|
||||||
|
Self::deserialize(&id.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An object with an ID.
|
||||||
|
#[derive(Interface)]
|
||||||
|
#[graphql(field(name = "id", desc = "ID of the object.", type = "ID"))]
|
||||||
|
pub enum Node {
|
||||||
|
Authentication(Box<Authentication>),
|
||||||
|
BrowserSession(Box<BrowserSession>),
|
||||||
|
CompatSession(Box<CompatSession>),
|
||||||
|
CompatSsoLogin(Box<CompatSsoLogin>),
|
||||||
|
OAuth2Client(Box<OAuth2Client>),
|
||||||
|
OAuth2Session(Box<OAuth2Session>),
|
||||||
|
User(Box<User>),
|
||||||
|
UserEmail(Box<UserEmail>),
|
||||||
|
}
|
@@ -19,7 +19,7 @@ use sqlx::PgPool;
|
|||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use super::{BrowserSession, User};
|
use super::{BrowserSession, NodeType, User};
|
||||||
|
|
||||||
/// An OAuth 2.0 session represents a client session which used the OAuth APIs
|
/// An OAuth 2.0 session represents a client session which used the OAuth APIs
|
||||||
/// to login.
|
/// to login.
|
||||||
@@ -30,7 +30,7 @@ pub struct OAuth2Session(pub mas_data_model::Session<PostgresqlBackend>);
|
|||||||
impl OAuth2Session {
|
impl OAuth2Session {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::OAuth2Session.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OAuth 2.0 client used by this session.
|
/// OAuth 2.0 client used by this session.
|
||||||
@@ -62,7 +62,7 @@ pub struct OAuth2Client(pub mas_data_model::Client<PostgresqlBackend>);
|
|||||||
impl OAuth2Client {
|
impl OAuth2Client {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::OAuth2Client.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OAuth 2.0 client ID
|
/// OAuth 2.0 client ID
|
||||||
|
@@ -44,7 +44,7 @@ impl From<mas_data_model::BrowserSession<PostgresqlBackend>> for User {
|
|||||||
impl User {
|
impl User {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::User.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Username chosen by the user.
|
/// Username chosen by the user.
|
||||||
@@ -79,10 +79,10 @@ impl User {
|
|||||||
|after, before, first, last| async move {
|
|after, before, first, last| async move {
|
||||||
let mut conn = database.acquire().await?;
|
let mut conn = database.acquire().await?;
|
||||||
let after_id = after
|
let after_id = after
|
||||||
.map(|x: OpaqueCursor<NodeCursor>| x.extract_for_type(NodeType::UserEmail))
|
.map(|x: OpaqueCursor<NodeCursor>| x.extract_for_type(NodeType::CompatSsoLogin))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
let before_id = before
|
let before_id = before
|
||||||
.map(|x: OpaqueCursor<NodeCursor>| x.extract_for_type(NodeType::UserEmail))
|
.map(|x: OpaqueCursor<NodeCursor>| x.extract_for_type(NodeType::CompatSsoLogin))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let (has_previous_page, has_next_page, edges) =
|
let (has_previous_page, has_next_page, edges) =
|
||||||
@@ -262,7 +262,7 @@ pub struct UserEmail(mas_data_model::UserEmail<PostgresqlBackend>);
|
|||||||
impl UserEmail {
|
impl UserEmail {
|
||||||
/// ID of the object.
|
/// ID of the object.
|
||||||
pub async fn id(&self) -> ID {
|
pub async fn id(&self) -> ID {
|
||||||
ID(self.0.data.to_string())
|
NodeType::UserEmail.id(self.0.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Email address
|
/// Email address
|
||||||
|
@@ -88,10 +88,8 @@ module.exports = {
|
|||||||
rules: {
|
rules: {
|
||||||
"@graphql-eslint/known-fragment-names": "off",
|
"@graphql-eslint/known-fragment-names": "off",
|
||||||
"@graphql-eslint/no-unused-fragments": "off",
|
"@graphql-eslint/no-unused-fragments": "off",
|
||||||
"@graphql-eslint/known-directives": [
|
"@graphql-eslint/unused-arguments": "off",
|
||||||
"error",
|
"@graphql-eslint/known-directives": "off",
|
||||||
{ ignoreClientDirectives: ["connection", "refetchable"] },
|
|
||||||
],
|
|
||||||
// This rule is copied from the 'operations-recommended' config,
|
// This rule is copied from the 'operations-recommended' config,
|
||||||
// but without the 'Query' forbidden suffix on operations,
|
// but without the 'Query' forbidden suffix on operations,
|
||||||
// since it directly clashes with the relay operation naming convention
|
// since it directly clashes with the relay operation naming convention
|
||||||
|
@@ -293,6 +293,10 @@ type RootQuery {
|
|||||||
Get the current logged in user
|
Get the current logged in user
|
||||||
"""
|
"""
|
||||||
currentUser: User
|
currentUser: User
|
||||||
|
"""
|
||||||
|
Fetches an object given its ID.
|
||||||
|
"""
|
||||||
|
node(id: ID!): Node
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@@ -25,12 +25,53 @@ const CompatSsoLogin: React.FC<Props> = ({ login }) => {
|
|||||||
fragment CompatSsoLogin_login on CompatSsoLogin {
|
fragment CompatSsoLogin_login on CompatSsoLogin {
|
||||||
id
|
id
|
||||||
redirectUri
|
redirectUri
|
||||||
|
createdAt
|
||||||
|
session {
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
deviceId
|
||||||
|
finishedAt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
login
|
login
|
||||||
);
|
);
|
||||||
|
|
||||||
return <>{data.redirectUri}</>;
|
let info = null;
|
||||||
|
if (data.session) {
|
||||||
|
info = (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
Started:{" "}
|
||||||
|
<span className="font-mono text-sm">{data.session.createdAt}</span>
|
||||||
|
</div>
|
||||||
|
{data.session.finishedAt ? (
|
||||||
|
<div className="text-alert">
|
||||||
|
Finished:{" "}
|
||||||
|
<span className="font-mono text-sm">{data.session.createdAt}</span>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<div>
|
||||||
|
Device ID:{" "}
|
||||||
|
<span className="font-mono text-sm font-semibold">
|
||||||
|
{data.session.deviceId}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-2 my-1 bg-grey-50 dark:bg-grey-450 rounded">
|
||||||
|
<div>
|
||||||
|
Requested: <span className="font-mono text-sm">{data.createdAt}</span>
|
||||||
|
</div>
|
||||||
|
{info}
|
||||||
|
<div>
|
||||||
|
Redirect URI: <span className="font-semibold">{data.redirectUri}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CompatSsoLogin;
|
export default CompatSsoLogin;
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { graphql, useFragment } from "react-relay";
|
import { graphql, usePaginationFragment } from "react-relay";
|
||||||
import CompatSsoLogin from "./CompatSsoLogin";
|
import CompatSsoLogin from "./CompatSsoLogin";
|
||||||
import { CompatSsoLoginList_user$key } from "./__generated__/CompatSsoLoginList_user.graphql";
|
import { CompatSsoLoginList_user$key } from "./__generated__/CompatSsoLoginList_user.graphql";
|
||||||
|
|
||||||
@@ -21,12 +21,15 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const CompatSsoLoginList: React.FC<Props> = ({ user }) => {
|
const CompatSsoLoginList: React.FC<Props> = ({ user }) => {
|
||||||
const data = useFragment(
|
const { data, loadNext, hasNext } = usePaginationFragment(
|
||||||
graphql`
|
graphql`
|
||||||
fragment CompatSsoLoginList_user on User {
|
fragment CompatSsoLoginList_user on User
|
||||||
compatSsoLogins(first: 10) {
|
@refetchable(queryName: "CompatSsoLoginListQuery") {
|
||||||
|
compatSsoLogins(first: $count, after: $cursor)
|
||||||
|
@connection(key: "CompatSsoLoginList_user_compatSsoLogins") {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
id
|
||||||
...CompatSsoLogin_login
|
...CompatSsoLogin_login
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,10 +40,16 @@ const CompatSsoLoginList: React.FC<Props> = ({ user }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="w-96">
|
||||||
|
<h2 className="text-lg">List of compatibility sessions:</h2>
|
||||||
{data.compatSsoLogins.edges.map((n) => (
|
{data.compatSsoLogins.edges.map((n) => (
|
||||||
<CompatSsoLogin login={n.node} />
|
<CompatSsoLogin login={n.node} key={n.node.id} />
|
||||||
))}
|
))}
|
||||||
|
{hasNext ? (
|
||||||
|
<button className="bg-accent p-2 rounded" onClick={() => loadNext(2)}>
|
||||||
|
Load more
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
265
frontend/src/components/__generated__/CompatSsoLoginListQuery.graphql.ts
generated
Normal file
265
frontend/src/components/__generated__/CompatSsoLoginListQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<3e111db0c30af3251a88326deea5562c>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||||
|
import { FragmentRefs } from "relay-runtime";
|
||||||
|
export type CompatSsoLoginListQuery$variables = {
|
||||||
|
count?: number | null;
|
||||||
|
cursor?: string | null;
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
export type CompatSsoLoginListQuery$data = {
|
||||||
|
readonly node: {
|
||||||
|
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLoginList_user">;
|
||||||
|
} | null;
|
||||||
|
};
|
||||||
|
export type CompatSsoLoginListQuery = {
|
||||||
|
response: CompatSsoLoginListQuery$data;
|
||||||
|
variables: CompatSsoLoginListQuery$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "count"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "cursor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "id"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "id",
|
||||||
|
"variableName": "id"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v2 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "__typename",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
v3 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
v4 = [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "after",
|
||||||
|
"variableName": "cursor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "first",
|
||||||
|
"variableName": "count"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v5 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "createdAt",
|
||||||
|
"storageKey": null
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "CompatSsoLoginListQuery",
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": (v1/*: any*/),
|
||||||
|
"concreteType": null,
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "node",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"args": null,
|
||||||
|
"kind": "FragmentSpread",
|
||||||
|
"name": "CompatSsoLoginList_user"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "RootQuery",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "CompatSsoLoginListQuery",
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": (v1/*: any*/),
|
||||||
|
"concreteType": null,
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "node",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v2/*: any*/),
|
||||||
|
(v3/*: any*/),
|
||||||
|
{
|
||||||
|
"kind": "InlineFragment",
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": (v4/*: any*/),
|
||||||
|
"concreteType": "CompatSsoLoginConnection",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "compatSsoLogins",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "CompatSsoLoginEdge",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "edges",
|
||||||
|
"plural": true,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "CompatSsoLogin",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "node",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v3/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "redirectUri",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
(v5/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "CompatSession",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "session",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v3/*: any*/),
|
||||||
|
(v5/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "deviceId",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "finishedAt",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
(v2/*: any*/)
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "cursor",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "PageInfo",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "pageInfo",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "endCursor",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "hasNextPage",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": (v4/*: any*/),
|
||||||
|
"filters": null,
|
||||||
|
"handle": "connection",
|
||||||
|
"key": "CompatSsoLoginList_user_compatSsoLogins",
|
||||||
|
"kind": "LinkedHandle",
|
||||||
|
"name": "compatSsoLogins"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "User",
|
||||||
|
"abstractKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "45c6342d3a53a3e3b2b18617796cf654",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "CompatSsoLoginListQuery",
|
||||||
|
"operationKind": "query",
|
||||||
|
"text": "query CompatSsoLoginListQuery(\n $count: Int\n $cursor: String\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompatSsoLoginList_user\n id\n }\n}\n\nfragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "cafc795d1bf9643ac6155c017e66c858";
|
||||||
|
|
||||||
|
export default node;
|
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<d3404a632e1928901a9a8ec12357528d>>
|
* @generated SignedSource<<4ace8ea8668e3dc638df21400c690bd8>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -8,16 +8,18 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
import { Fragment, ReaderFragment } from 'relay-runtime';
|
import { ReaderFragment, RefetchableFragment } from 'relay-runtime';
|
||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type CompatSsoLoginList_user$data = {
|
export type CompatSsoLoginList_user$data = {
|
||||||
readonly compatSsoLogins: {
|
readonly compatSsoLogins: {
|
||||||
readonly edges: ReadonlyArray<{
|
readonly edges: ReadonlyArray<{
|
||||||
readonly node: {
|
readonly node: {
|
||||||
|
readonly id: string;
|
||||||
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLogin_login">;
|
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLogin_login">;
|
||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
|
readonly id: string;
|
||||||
readonly " $fragmentType": "CompatSsoLoginList_user";
|
readonly " $fragmentType": "CompatSsoLoginList_user";
|
||||||
};
|
};
|
||||||
export type CompatSsoLoginList_user$key = {
|
export type CompatSsoLoginList_user$key = {
|
||||||
@@ -25,24 +27,64 @@ export type CompatSsoLoginList_user$key = {
|
|||||||
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLoginList_user">;
|
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLoginList_user">;
|
||||||
};
|
};
|
||||||
|
|
||||||
const node: ReaderFragment = {
|
import CompatSsoLoginListQuery_graphql from './CompatSsoLoginListQuery.graphql';
|
||||||
"argumentDefinitions": [],
|
|
||||||
|
const node: ReaderFragment = (function(){
|
||||||
|
var v0 = [
|
||||||
|
"compatSsoLogins"
|
||||||
|
],
|
||||||
|
v1 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
"argumentDefinitions": [
|
||||||
|
{
|
||||||
|
"kind": "RootArgument",
|
||||||
|
"name": "count"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "RootArgument",
|
||||||
|
"name": "cursor"
|
||||||
|
}
|
||||||
|
],
|
||||||
"kind": "Fragment",
|
"kind": "Fragment",
|
||||||
"metadata": null,
|
"metadata": {
|
||||||
|
"connection": [
|
||||||
|
{
|
||||||
|
"count": "count",
|
||||||
|
"cursor": "cursor",
|
||||||
|
"direction": "forward",
|
||||||
|
"path": (v0/*: any*/)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"refetch": {
|
||||||
|
"connection": {
|
||||||
|
"forward": {
|
||||||
|
"count": "count",
|
||||||
|
"cursor": "cursor"
|
||||||
|
},
|
||||||
|
"backward": null,
|
||||||
|
"path": (v0/*: any*/)
|
||||||
|
},
|
||||||
|
"fragmentPathInResult": [
|
||||||
|
"node"
|
||||||
|
],
|
||||||
|
"operation": CompatSsoLoginListQuery_graphql,
|
||||||
|
"identifierField": "id"
|
||||||
|
}
|
||||||
|
},
|
||||||
"name": "CompatSsoLoginList_user",
|
"name": "CompatSsoLoginList_user",
|
||||||
"selections": [
|
"selections": [
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": "compatSsoLogins",
|
||||||
"args": [
|
"args": null,
|
||||||
{
|
|
||||||
"kind": "Literal",
|
|
||||||
"name": "first",
|
|
||||||
"value": 10
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"concreteType": "CompatSsoLoginConnection",
|
"concreteType": "CompatSsoLoginConnection",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "compatSsoLogins",
|
"name": "__CompatSsoLoginList_user_compatSsoLogins_connection",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
{
|
{
|
||||||
@@ -61,25 +103,67 @@ const node: ReaderFragment = {
|
|||||||
"name": "node",
|
"name": "node",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
|
(v1/*: any*/),
|
||||||
{
|
{
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "FragmentSpread",
|
"kind": "FragmentSpread",
|
||||||
"name": "CompatSsoLogin_login"
|
"name": "CompatSsoLogin_login"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "__typename",
|
||||||
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "cursor",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "PageInfo",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "pageInfo",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "endCursor",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "hasNextPage",
|
||||||
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": "compatSsoLogins(first:10)"
|
"storageKey": null
|
||||||
}
|
},
|
||||||
|
(v1/*: any*/)
|
||||||
],
|
],
|
||||||
"type": "User",
|
"type": "User",
|
||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
};
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
(node as any).hash = "b70f4b63784afe8f1f69c78198194cc9";
|
(node as any).hash = "cafc795d1bf9643ac6155c017e66c858";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<bafb31541b97839f32ff9790773ff904>>
|
* @generated SignedSource<<20e2b233e5154ea60632046abc2aa29a>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -11,8 +11,15 @@
|
|||||||
import { Fragment, ReaderFragment } from 'relay-runtime';
|
import { Fragment, ReaderFragment } from 'relay-runtime';
|
||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type CompatSsoLogin_login$data = {
|
export type CompatSsoLogin_login$data = {
|
||||||
|
readonly createdAt: any;
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly redirectUri: any;
|
readonly redirectUri: any;
|
||||||
|
readonly session: {
|
||||||
|
readonly createdAt: any;
|
||||||
|
readonly deviceId: string;
|
||||||
|
readonly finishedAt: any | null;
|
||||||
|
readonly id: string;
|
||||||
|
} | null;
|
||||||
readonly " $fragmentType": "CompatSsoLogin_login";
|
readonly " $fragmentType": "CompatSsoLogin_login";
|
||||||
};
|
};
|
||||||
export type CompatSsoLogin_login$key = {
|
export type CompatSsoLogin_login$key = {
|
||||||
@@ -20,31 +27,69 @@ export type CompatSsoLogin_login$key = {
|
|||||||
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLogin_login">;
|
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLogin_login">;
|
||||||
};
|
};
|
||||||
|
|
||||||
const node: ReaderFragment = {
|
const node: ReaderFragment = (function(){
|
||||||
|
var v0 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
v1 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "createdAt",
|
||||||
|
"storageKey": null
|
||||||
|
};
|
||||||
|
return {
|
||||||
"argumentDefinitions": [],
|
"argumentDefinitions": [],
|
||||||
"kind": "Fragment",
|
"kind": "Fragment",
|
||||||
"metadata": null,
|
"metadata": null,
|
||||||
"name": "CompatSsoLogin_login",
|
"name": "CompatSsoLogin_login",
|
||||||
"selections": [
|
"selections": [
|
||||||
{
|
(v0/*: any*/),
|
||||||
"alias": null,
|
|
||||||
"args": null,
|
|
||||||
"kind": "ScalarField",
|
|
||||||
"name": "id",
|
|
||||||
"storageKey": null
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "redirectUri",
|
"name": "redirectUri",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
|
},
|
||||||
|
(v1/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "CompatSession",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "session",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v0/*: any*/),
|
||||||
|
(v1/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "deviceId",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "finishedAt",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"type": "CompatSsoLogin",
|
"type": "CompatSsoLogin",
|
||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
};
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
(node as any).hash = "e1151a93f1ba4a56332b8aa6129f7bfe";
|
(node as any).hash = "7be3b416b1023cea0de7a87b9738e5d5";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
@@ -20,7 +20,7 @@ import type { HomeQuery } from "./__generated__/HomeQuery.graphql";
|
|||||||
const Home: React.FC = () => {
|
const Home: React.FC = () => {
|
||||||
const data = useLazyLoadQuery<HomeQuery>(
|
const data = useLazyLoadQuery<HomeQuery>(
|
||||||
graphql`
|
graphql`
|
||||||
query HomeQuery {
|
query HomeQuery($count: Int!, $cursor: String) {
|
||||||
currentUser {
|
currentUser {
|
||||||
id
|
id
|
||||||
username
|
username
|
||||||
@@ -29,7 +29,7 @@ const Home: React.FC = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
{}
|
{ count: 2 }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (data.currentUser) {
|
if (data.currentUser) {
|
||||||
|
144
frontend/src/pages/__generated__/HomeQuery.graphql.ts
generated
144
frontend/src/pages/__generated__/HomeQuery.graphql.ts
generated
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<94462aca9c48eae79c22a11003d865c3>>
|
* @generated SignedSource<<874ab84c1095ab907f12b91b55f4bf2c>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type HomeQuery$variables = {};
|
export type HomeQuery$variables = {
|
||||||
|
count: number;
|
||||||
|
cursor?: string | null;
|
||||||
|
};
|
||||||
export type HomeQuery$data = {
|
export type HomeQuery$data = {
|
||||||
readonly currentUser: {
|
readonly currentUser: {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
@@ -24,23 +27,54 @@ export type HomeQuery = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const node: ConcreteRequest = (function(){
|
const node: ConcreteRequest = (function(){
|
||||||
var v0 = {
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "count"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "cursor"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = {
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
v1 = {
|
v2 = {
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "username",
|
"name": "username",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
|
},
|
||||||
|
v3 = [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "after",
|
||||||
|
"variableName": "cursor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "first",
|
||||||
|
"variableName": "count"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v4 = {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "createdAt",
|
||||||
|
"storageKey": null
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
"fragment": {
|
"fragment": {
|
||||||
"argumentDefinitions": [],
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
"kind": "Fragment",
|
"kind": "Fragment",
|
||||||
"metadata": null,
|
"metadata": null,
|
||||||
"name": "HomeQuery",
|
"name": "HomeQuery",
|
||||||
@@ -53,8 +87,8 @@ return {
|
|||||||
"name": "currentUser",
|
"name": "currentUser",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v0/*: any*/),
|
|
||||||
(v1/*: any*/),
|
(v1/*: any*/),
|
||||||
|
(v2/*: any*/),
|
||||||
{
|
{
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "FragmentSpread",
|
"kind": "FragmentSpread",
|
||||||
@@ -69,7 +103,7 @@ return {
|
|||||||
},
|
},
|
||||||
"kind": "Request",
|
"kind": "Request",
|
||||||
"operation": {
|
"operation": {
|
||||||
"argumentDefinitions": [],
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
"kind": "Operation",
|
"kind": "Operation",
|
||||||
"name": "HomeQuery",
|
"name": "HomeQuery",
|
||||||
"selections": [
|
"selections": [
|
||||||
@@ -81,17 +115,11 @@ return {
|
|||||||
"name": "currentUser",
|
"name": "currentUser",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v0/*: any*/),
|
|
||||||
(v1/*: any*/),
|
(v1/*: any*/),
|
||||||
|
(v2/*: any*/),
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": [
|
"args": (v3/*: any*/),
|
||||||
{
|
|
||||||
"kind": "Literal",
|
|
||||||
"name": "first",
|
|
||||||
"value": 10
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"concreteType": "CompatSsoLoginConnection",
|
"concreteType": "CompatSsoLoginConnection",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "compatSsoLogins",
|
"name": "compatSsoLogins",
|
||||||
@@ -113,22 +141,98 @@ return {
|
|||||||
"name": "node",
|
"name": "node",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v0/*: any*/),
|
(v1/*: any*/),
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "redirectUri",
|
"name": "redirectUri",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
|
},
|
||||||
|
(v4/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "CompatSession",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "session",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v1/*: any*/),
|
||||||
|
(v4/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "deviceId",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "finishedAt",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "__typename",
|
||||||
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "cursor",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "PageInfo",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "pageInfo",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "endCursor",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "hasNextPage",
|
||||||
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": "compatSsoLogins(first:10)"
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": (v3/*: any*/),
|
||||||
|
"filters": null,
|
||||||
|
"handle": "connection",
|
||||||
|
"key": "CompatSsoLoginList_user_compatSsoLogins",
|
||||||
|
"kind": "LinkedHandle",
|
||||||
|
"name": "compatSsoLogins"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
@@ -136,16 +240,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "1b4d3469bb6ccc19b8944b1f7fedd9c5",
|
"cacheID": "3543c7ada63831383f66dbeed4b1648e",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "HomeQuery",
|
"name": "HomeQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query HomeQuery {\n currentUser {\n id\n username\n ...CompatSsoLoginList_user\n }\n}\n\nfragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: 10) {\n edges {\n node {\n ...CompatSsoLogin_login\n id\n }\n }\n }\n}\n\nfragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n}\n"
|
"text": "query HomeQuery(\n $count: Int!\n $cursor: String\n) {\n currentUser {\n id\n username\n ...CompatSsoLoginList_user\n }\n}\n\nfragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "a5defd2dc81b62abebfe7a393573d5a8";
|
(node as any).hash = "1cd5ce8ae5a912b3d7ecf0c6e3cd8469";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
Reference in New Issue
Block a user