You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-07 17:03:01 +03:00
Lint GraphQL schema and operations with eslint
This commit is contained in:
44
.github/workflows/ci.yaml
vendored
44
.github/workflows/ci.yaml
vendored
@@ -52,9 +52,35 @@ jobs:
|
|||||||
files: crates/policy/policies/coverage.json
|
files: crates/policy/policies/coverage.json
|
||||||
flags: policies
|
flags: policies
|
||||||
|
|
||||||
|
frontend-lint:
|
||||||
|
name: Check frontend style
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout the code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: frontend/package-lock.json
|
||||||
|
|
||||||
|
- name: Install Node dependencies
|
||||||
|
working-directory: ./frontend
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
working-directory: ./frontend
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
|
|
||||||
rustfmt:
|
rustfmt:
|
||||||
name: Check style
|
name: Check Rust style
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -85,7 +111,7 @@ jobs:
|
|||||||
- name: Checkout the code
|
- name: Checkout the code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install toolchain
|
- name: Install Rust toolchain
|
||||||
run: |
|
run: |
|
||||||
rustup toolchain install stable
|
rustup toolchain install stable
|
||||||
rustup default stable
|
rustup default stable
|
||||||
@@ -93,8 +119,19 @@ jobs:
|
|||||||
- name: Setup Rust cache
|
- name: Setup Rust cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
|
- name: Install Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: frontend/package-lock.json
|
||||||
|
|
||||||
|
- name: Install Node dependencies
|
||||||
|
working-directory: ./frontend
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
- name: Update the schemas
|
- name: Update the schemas
|
||||||
run: sh ./misc/update-schemas.sh
|
run: sh ./misc/update.sh
|
||||||
|
|
||||||
- name: Check that the workspace is clean
|
- name: Check that the workspace is clean
|
||||||
run: |
|
run: |
|
||||||
@@ -396,6 +433,7 @@ jobs:
|
|||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
needs:
|
needs:
|
||||||
- opa-lint
|
- opa-lint
|
||||||
|
- frontend-lint
|
||||||
- rustfmt
|
- rustfmt
|
||||||
- clippy
|
- clippy
|
||||||
- check-schema
|
- check-schema
|
||||||
|
@@ -1,398 +0,0 @@
|
|||||||
"""
|
|
||||||
An authentication records when a user enter their credential in a browser
|
|
||||||
session.
|
|
||||||
"""
|
|
||||||
type Authentication implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
When the object was created.
|
|
||||||
"""
|
|
||||||
createdAt: DateTime!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
A browser session represents a logged in user in a browser.
|
|
||||||
"""
|
|
||||||
type BrowserSession implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
The user logged in this session.
|
|
||||||
"""
|
|
||||||
user: User!
|
|
||||||
"""
|
|
||||||
The most recent authentication of this session.
|
|
||||||
"""
|
|
||||||
lastAuthentication: Authentication
|
|
||||||
"""
|
|
||||||
When the object was created.
|
|
||||||
"""
|
|
||||||
createdAt: DateTime!
|
|
||||||
}
|
|
||||||
|
|
||||||
type BrowserSessionConnection {
|
|
||||||
"""
|
|
||||||
Information to aid in pagination.
|
|
||||||
"""
|
|
||||||
pageInfo: PageInfo!
|
|
||||||
"""
|
|
||||||
A list of edges.
|
|
||||||
"""
|
|
||||||
edges: [BrowserSessionEdge!]!
|
|
||||||
"""
|
|
||||||
A list of nodes.
|
|
||||||
"""
|
|
||||||
nodes: [BrowserSession!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
An edge in a connection.
|
|
||||||
"""
|
|
||||||
type BrowserSessionEdge {
|
|
||||||
"""
|
|
||||||
A cursor for use in pagination
|
|
||||||
"""
|
|
||||||
cursor: String!
|
|
||||||
"""
|
|
||||||
The item at the end of the edge
|
|
||||||
"""
|
|
||||||
node: BrowserSession!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
A compat session represents a client session which used the legacy Matrix
|
|
||||||
login API.
|
|
||||||
"""
|
|
||||||
type CompatSession implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
The user authorized for this session.
|
|
||||||
"""
|
|
||||||
user: User!
|
|
||||||
"""
|
|
||||||
The Matrix Device ID of this session.
|
|
||||||
"""
|
|
||||||
deviceId: String!
|
|
||||||
"""
|
|
||||||
When the object was created.
|
|
||||||
"""
|
|
||||||
createdAt: DateTime!
|
|
||||||
"""
|
|
||||||
When the session ended.
|
|
||||||
"""
|
|
||||||
finishedAt: DateTime
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
A compat SSO login represents a login done through the legacy Matrix login
|
|
||||||
API, via the `m.login.sso` login method.
|
|
||||||
"""
|
|
||||||
type CompatSsoLogin implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
When the object was created.
|
|
||||||
"""
|
|
||||||
createdAt: DateTime!
|
|
||||||
"""
|
|
||||||
The redirect URI used during the login.
|
|
||||||
"""
|
|
||||||
redirectUri: Url!
|
|
||||||
"""
|
|
||||||
When the login was fulfilled, and the user was redirected back to the
|
|
||||||
client.
|
|
||||||
"""
|
|
||||||
fulfilledAt: DateTime
|
|
||||||
"""
|
|
||||||
When the client exchanged the login token sent during the redirection.
|
|
||||||
"""
|
|
||||||
exchangedAt: DateTime
|
|
||||||
"""
|
|
||||||
The compat session which was started by this login.
|
|
||||||
"""
|
|
||||||
session: CompatSession
|
|
||||||
}
|
|
||||||
|
|
||||||
type CompatSsoLoginConnection {
|
|
||||||
"""
|
|
||||||
Information to aid in pagination.
|
|
||||||
"""
|
|
||||||
pageInfo: PageInfo!
|
|
||||||
"""
|
|
||||||
A list of edges.
|
|
||||||
"""
|
|
||||||
edges: [CompatSsoLoginEdge!]!
|
|
||||||
"""
|
|
||||||
A list of nodes.
|
|
||||||
"""
|
|
||||||
nodes: [CompatSsoLogin!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
An edge in a connection.
|
|
||||||
"""
|
|
||||||
type CompatSsoLoginEdge {
|
|
||||||
"""
|
|
||||||
A cursor for use in pagination
|
|
||||||
"""
|
|
||||||
cursor: String!
|
|
||||||
"""
|
|
||||||
The item at the end of the edge
|
|
||||||
"""
|
|
||||||
node: CompatSsoLogin!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
Implement the DateTime<Utc> scalar
|
|
||||||
|
|
||||||
The input/output is a string in RFC3339 format.
|
|
||||||
"""
|
|
||||||
scalar DateTime
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
interface Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
An OAuth 2.0 client
|
|
||||||
"""
|
|
||||||
type Oauth2Client implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
OAuth 2.0 client ID
|
|
||||||
"""
|
|
||||||
clientId: String!
|
|
||||||
"""
|
|
||||||
Client name advertised by the client.
|
|
||||||
"""
|
|
||||||
clientName: String
|
|
||||||
"""
|
|
||||||
Client URI advertised by the client.
|
|
||||||
"""
|
|
||||||
clientUri: Url
|
|
||||||
"""
|
|
||||||
Terms of services URI advertised by the client.
|
|
||||||
"""
|
|
||||||
tosUri: Url
|
|
||||||
"""
|
|
||||||
Privacy policy URI advertised by the client.
|
|
||||||
"""
|
|
||||||
policyUri: Url
|
|
||||||
"""
|
|
||||||
List of redirect URIs used for authorization grants by the client.
|
|
||||||
"""
|
|
||||||
redirectUris: [Url!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
An OAuth 2.0 session represents a client session which used the OAuth APIs
|
|
||||||
to login.
|
|
||||||
"""
|
|
||||||
type Oauth2Session implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
OAuth 2.0 client used by this session.
|
|
||||||
"""
|
|
||||||
client: Oauth2Client!
|
|
||||||
"""
|
|
||||||
Scope granted for this session.
|
|
||||||
"""
|
|
||||||
scope: String!
|
|
||||||
"""
|
|
||||||
The browser session which started this OAuth 2.0 session.
|
|
||||||
"""
|
|
||||||
browserSession: BrowserSession!
|
|
||||||
"""
|
|
||||||
User authorized for this session.
|
|
||||||
"""
|
|
||||||
user: User!
|
|
||||||
}
|
|
||||||
|
|
||||||
type Oauth2SessionConnection {
|
|
||||||
"""
|
|
||||||
Information to aid in pagination.
|
|
||||||
"""
|
|
||||||
pageInfo: PageInfo!
|
|
||||||
"""
|
|
||||||
A list of edges.
|
|
||||||
"""
|
|
||||||
edges: [Oauth2SessionEdge!]!
|
|
||||||
"""
|
|
||||||
A list of nodes.
|
|
||||||
"""
|
|
||||||
nodes: [Oauth2Session!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
An edge in a connection.
|
|
||||||
"""
|
|
||||||
type Oauth2SessionEdge {
|
|
||||||
"""
|
|
||||||
A cursor for use in pagination
|
|
||||||
"""
|
|
||||||
cursor: String!
|
|
||||||
"""
|
|
||||||
The item at the end of the edge
|
|
||||||
"""
|
|
||||||
node: Oauth2Session!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
Information about pagination in a connection
|
|
||||||
"""
|
|
||||||
type PageInfo {
|
|
||||||
"""
|
|
||||||
When paginating backwards, are there more items?
|
|
||||||
"""
|
|
||||||
hasPreviousPage: Boolean!
|
|
||||||
"""
|
|
||||||
When paginating forwards, are there more items?
|
|
||||||
"""
|
|
||||||
hasNextPage: Boolean!
|
|
||||||
"""
|
|
||||||
When paginating backwards, the cursor to continue.
|
|
||||||
"""
|
|
||||||
startCursor: String
|
|
||||||
"""
|
|
||||||
When paginating forwards, the cursor to continue.
|
|
||||||
"""
|
|
||||||
endCursor: String
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
The query root of the GraphQL interface.
|
|
||||||
"""
|
|
||||||
type RootQuery {
|
|
||||||
"""
|
|
||||||
Get the current logged in browser session
|
|
||||||
"""
|
|
||||||
currentBrowserSession: BrowserSession
|
|
||||||
"""
|
|
||||||
Get the current logged in user
|
|
||||||
"""
|
|
||||||
currentUser: User
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
URL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)
|
|
||||||
"""
|
|
||||||
scalar Url
|
|
||||||
|
|
||||||
"""
|
|
||||||
A user is an individual's account.
|
|
||||||
"""
|
|
||||||
type User implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
Username chosen by the user.
|
|
||||||
"""
|
|
||||||
username: String!
|
|
||||||
"""
|
|
||||||
Primary email address of the user.
|
|
||||||
"""
|
|
||||||
primaryEmail: UserEmail
|
|
||||||
"""
|
|
||||||
Get the list of compatibility SSO logins, chronologically sorted
|
|
||||||
"""
|
|
||||||
compatSsoLogins(after: String, before: String, first: Int, last: Int): CompatSsoLoginConnection!
|
|
||||||
"""
|
|
||||||
Get the list of active browser sessions, chronologically sorted
|
|
||||||
"""
|
|
||||||
browserSessions(after: String, before: String, first: Int, last: Int): BrowserSessionConnection!
|
|
||||||
"""
|
|
||||||
Get the list of emails, chronologically sorted
|
|
||||||
"""
|
|
||||||
emails(after: String, before: String, first: Int, last: Int): UserEmailConnection!
|
|
||||||
"""
|
|
||||||
Get the list of OAuth 2.0 sessions, chronologically sorted
|
|
||||||
"""
|
|
||||||
oauth2Sessions(after: String, before: String, first: Int, last: Int): Oauth2SessionConnection!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
A user email address
|
|
||||||
"""
|
|
||||||
type UserEmail implements Node {
|
|
||||||
"""
|
|
||||||
ID of the object.
|
|
||||||
"""
|
|
||||||
id: ID!
|
|
||||||
"""
|
|
||||||
Email address
|
|
||||||
"""
|
|
||||||
email: String!
|
|
||||||
"""
|
|
||||||
When the object was created.
|
|
||||||
"""
|
|
||||||
createdAt: DateTime!
|
|
||||||
"""
|
|
||||||
When the email address was confirmed. Is `null` if the email was never
|
|
||||||
verified by the user.
|
|
||||||
"""
|
|
||||||
confirmedAt: DateTime
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserEmailConnection {
|
|
||||||
"""
|
|
||||||
Information to aid in pagination.
|
|
||||||
"""
|
|
||||||
pageInfo: PageInfo!
|
|
||||||
"""
|
|
||||||
A list of edges.
|
|
||||||
"""
|
|
||||||
edges: [UserEmailEdge!]!
|
|
||||||
"""
|
|
||||||
A list of nodes.
|
|
||||||
"""
|
|
||||||
nodes: [UserEmail!]!
|
|
||||||
"""
|
|
||||||
Identifies the total count of items in the connection.
|
|
||||||
"""
|
|
||||||
totalCount: Int!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
An edge in a connection.
|
|
||||||
"""
|
|
||||||
type UserEmailEdge {
|
|
||||||
"""
|
|
||||||
A cursor for use in pagination
|
|
||||||
"""
|
|
||||||
cursor: String!
|
|
||||||
"""
|
|
||||||
The item at the end of the edge
|
|
||||||
"""
|
|
||||||
node: UserEmail!
|
|
||||||
}
|
|
||||||
|
|
||||||
schema {
|
|
||||||
query: RootQuery
|
|
||||||
}
|
|
||||||
|
|
@@ -29,6 +29,7 @@ pub use self::{
|
|||||||
users::{User, UserEmail},
|
users::{User, UserEmail},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// An object with an ID.
|
||||||
#[derive(Interface)]
|
#[derive(Interface)]
|
||||||
#[graphql(field(name = "id", desc = "ID of the object.", type = "ID"))]
|
#[graphql(field(name = "id", desc = "ID of the object.", type = "ID"))]
|
||||||
pub enum Node {
|
pub enum Node {
|
||||||
|
@@ -15,6 +15,10 @@
|
|||||||
/** @type {import('eslint').Linter.Config} */
|
/** @type {import('eslint').Linter.Config} */
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
ignorePatterns: ["**/dist/**", "**/__generated__/**"],
|
||||||
|
overrides: [
|
||||||
|
// General rules for JS/TS files
|
||||||
|
{
|
||||||
extends: [
|
extends: [
|
||||||
"react-app",
|
"react-app",
|
||||||
"react-app/jest",
|
"react-app/jest",
|
||||||
@@ -23,4 +27,85 @@ module.exports = {
|
|||||||
"plugin:jsx-a11y/recommended",
|
"plugin:jsx-a11y/recommended",
|
||||||
],
|
],
|
||||||
plugins: ["jsx-a11y"],
|
plugins: ["jsx-a11y"],
|
||||||
|
files: ["*.ts", "*.tsx", "*.cjs"],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Processor to extract GraphQL operations embedded in TS files
|
||||||
|
{
|
||||||
|
files: ["*.tsx", "*.ts"],
|
||||||
|
processor: "@graphql-eslint/graphql",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Validate the GraphQL schema
|
||||||
|
{
|
||||||
|
files: "./schema.graphql",
|
||||||
|
extends: [
|
||||||
|
"plugin:@graphql-eslint/schema-recommended",
|
||||||
|
"plugin:@graphql-eslint/relay",
|
||||||
|
"prettier",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
"@graphql-eslint/relay-edge-types": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
// We do have *some* fields without connections,
|
||||||
|
// and async-graphql's connections 'nodes' field break this anyway
|
||||||
|
listTypeCanWrapOnlyEdgeType: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"@graphql-eslint/strict-id-in-types": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
exceptions: {
|
||||||
|
// The '*Connection', '*Edge' and 'PageInfo' types don't have IDs
|
||||||
|
types: ["PageInfo"],
|
||||||
|
suffixes: ["Connection", "Edge"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// We need to disable this rule because of the 'username' field in the 'User' node
|
||||||
|
"@graphql-eslint/no-typename-prefix": "off",
|
||||||
|
|
||||||
|
// We need to disable this rule for object types,
|
||||||
|
// because the '*Connection' types lack descriptions
|
||||||
|
"@graphql-eslint/require-description": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
types: true,
|
||||||
|
ObjectTypeDefinition: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Validate the GraphQL operations
|
||||||
|
{
|
||||||
|
files: "./src/**/*.graphql",
|
||||||
|
extends: ["plugin:@graphql-eslint/operations-recommended"],
|
||||||
|
rules: {
|
||||||
|
// This rule is copied from the 'operations-recommended' config,
|
||||||
|
// but without the 'Query' forbidden suffix on operations,
|
||||||
|
// since it directly clashes with the relay operation naming convention
|
||||||
|
"@graphql-eslint/naming-convention": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
VariableDefinition: "camelCase",
|
||||||
|
OperationDefinition: {
|
||||||
|
style: "PascalCase",
|
||||||
|
forbiddenPrefixes: ["Query", "Mutation", "Subscription", "Get"],
|
||||||
|
forbiddenSuffixes: [/* "Query", */ "Mutation", "Subscription"],
|
||||||
|
},
|
||||||
|
FragmentDefinition: {
|
||||||
|
style: "PascalCase",
|
||||||
|
forbiddenPrefixes: ["Fragment"],
|
||||||
|
forbiddenSuffixes: ["Fragment"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
4
frontend/graphql.config.json
Normal file
4
frontend/graphql.config.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"schema": "./schema.graphql",
|
||||||
|
"documents": "./src/**/*"
|
||||||
|
}
|
3135
frontend/package-lock.json
generated
3135
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,9 +5,10 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"lint": "eslint src/ .eslintrc.cjs tailwind.config.cjs vite.config.ts",
|
"generate": "relay-compiler && eslint --fix .",
|
||||||
|
"lint": "relay-compiler --validate && eslint . && tsc",
|
||||||
"relay": "relay-compiler",
|
"relay": "relay-compiler",
|
||||||
"build": "tsc && vite build",
|
"build": "npm run lint && vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
"relay-runtime": "^14.1.0"
|
"relay-runtime": "^14.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@graphql-eslint/eslint-plugin": "^3.13.1",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
"@types/react": "^18.0.25",
|
"@types/react": "^18.0.25",
|
||||||
"@types/react-dom": "^18.0.8",
|
"@types/react-dom": "^18.0.8",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"src": "./src",
|
"src": "./src",
|
||||||
"schema": "../crates/graphql/schema.graphql",
|
"schema": "./schema.graphql",
|
||||||
"language": "typescript",
|
"language": "typescript",
|
||||||
"eagerEsModules": true,
|
"eagerEsModules": true,
|
||||||
"exclude": [
|
"exclude": [
|
||||||
|
415
frontend/schema.graphql
Normal file
415
frontend/schema.graphql
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
"""
|
||||||
|
An authentication records when a user enter their credential in a browser
|
||||||
|
session.
|
||||||
|
"""
|
||||||
|
type Authentication implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
When the object was created.
|
||||||
|
"""
|
||||||
|
createdAt: DateTime!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
A browser session represents a logged in user in a browser.
|
||||||
|
"""
|
||||||
|
type BrowserSession implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
The user logged in this session.
|
||||||
|
"""
|
||||||
|
user: User!
|
||||||
|
"""
|
||||||
|
The most recent authentication of this session.
|
||||||
|
"""
|
||||||
|
lastAuthentication: Authentication
|
||||||
|
"""
|
||||||
|
When the object was created.
|
||||||
|
"""
|
||||||
|
createdAt: DateTime!
|
||||||
|
}
|
||||||
|
|
||||||
|
type BrowserSessionConnection {
|
||||||
|
"""
|
||||||
|
Information to aid in pagination.
|
||||||
|
"""
|
||||||
|
pageInfo: PageInfo!
|
||||||
|
"""
|
||||||
|
A list of edges.
|
||||||
|
"""
|
||||||
|
edges: [BrowserSessionEdge!]!
|
||||||
|
"""
|
||||||
|
A list of nodes.
|
||||||
|
"""
|
||||||
|
nodes: [BrowserSession!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
An edge in a connection.
|
||||||
|
"""
|
||||||
|
type BrowserSessionEdge {
|
||||||
|
"""
|
||||||
|
A cursor for use in pagination
|
||||||
|
"""
|
||||||
|
cursor: String!
|
||||||
|
"""
|
||||||
|
The item at the end of the edge
|
||||||
|
"""
|
||||||
|
node: BrowserSession!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
A compat session represents a client session which used the legacy Matrix
|
||||||
|
login API.
|
||||||
|
"""
|
||||||
|
type CompatSession implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
The user authorized for this session.
|
||||||
|
"""
|
||||||
|
user: User!
|
||||||
|
"""
|
||||||
|
The Matrix Device ID of this session.
|
||||||
|
"""
|
||||||
|
deviceId: String!
|
||||||
|
"""
|
||||||
|
When the object was created.
|
||||||
|
"""
|
||||||
|
createdAt: DateTime!
|
||||||
|
"""
|
||||||
|
When the session ended.
|
||||||
|
"""
|
||||||
|
finishedAt: DateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
A compat SSO login represents a login done through the legacy Matrix login
|
||||||
|
API, via the `m.login.sso` login method.
|
||||||
|
"""
|
||||||
|
type CompatSsoLogin implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
When the object was created.
|
||||||
|
"""
|
||||||
|
createdAt: DateTime!
|
||||||
|
"""
|
||||||
|
The redirect URI used during the login.
|
||||||
|
"""
|
||||||
|
redirectUri: Url!
|
||||||
|
"""
|
||||||
|
When the login was fulfilled, and the user was redirected back to the
|
||||||
|
client.
|
||||||
|
"""
|
||||||
|
fulfilledAt: DateTime
|
||||||
|
"""
|
||||||
|
When the client exchanged the login token sent during the redirection.
|
||||||
|
"""
|
||||||
|
exchangedAt: DateTime
|
||||||
|
"""
|
||||||
|
The compat session which was started by this login.
|
||||||
|
"""
|
||||||
|
session: CompatSession
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompatSsoLoginConnection {
|
||||||
|
"""
|
||||||
|
Information to aid in pagination.
|
||||||
|
"""
|
||||||
|
pageInfo: PageInfo!
|
||||||
|
"""
|
||||||
|
A list of edges.
|
||||||
|
"""
|
||||||
|
edges: [CompatSsoLoginEdge!]!
|
||||||
|
"""
|
||||||
|
A list of nodes.
|
||||||
|
"""
|
||||||
|
nodes: [CompatSsoLogin!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
An edge in a connection.
|
||||||
|
"""
|
||||||
|
type CompatSsoLoginEdge {
|
||||||
|
"""
|
||||||
|
A cursor for use in pagination
|
||||||
|
"""
|
||||||
|
cursor: String!
|
||||||
|
"""
|
||||||
|
The item at the end of the edge
|
||||||
|
"""
|
||||||
|
node: CompatSsoLogin!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
Implement the DateTime<Utc> scalar
|
||||||
|
|
||||||
|
The input/output is a string in RFC3339 format.
|
||||||
|
"""
|
||||||
|
scalar DateTime
|
||||||
|
|
||||||
|
"""
|
||||||
|
An object with an ID.
|
||||||
|
"""
|
||||||
|
interface Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
An OAuth 2.0 client
|
||||||
|
"""
|
||||||
|
type Oauth2Client implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
OAuth 2.0 client ID
|
||||||
|
"""
|
||||||
|
clientId: String!
|
||||||
|
"""
|
||||||
|
Client name advertised by the client.
|
||||||
|
"""
|
||||||
|
clientName: String
|
||||||
|
"""
|
||||||
|
Client URI advertised by the client.
|
||||||
|
"""
|
||||||
|
clientUri: Url
|
||||||
|
"""
|
||||||
|
Terms of services URI advertised by the client.
|
||||||
|
"""
|
||||||
|
tosUri: Url
|
||||||
|
"""
|
||||||
|
Privacy policy URI advertised by the client.
|
||||||
|
"""
|
||||||
|
policyUri: Url
|
||||||
|
"""
|
||||||
|
List of redirect URIs used for authorization grants by the client.
|
||||||
|
"""
|
||||||
|
redirectUris: [Url!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
An OAuth 2.0 session represents a client session which used the OAuth APIs
|
||||||
|
to login.
|
||||||
|
"""
|
||||||
|
type Oauth2Session implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
OAuth 2.0 client used by this session.
|
||||||
|
"""
|
||||||
|
client: Oauth2Client!
|
||||||
|
"""
|
||||||
|
Scope granted for this session.
|
||||||
|
"""
|
||||||
|
scope: String!
|
||||||
|
"""
|
||||||
|
The browser session which started this OAuth 2.0 session.
|
||||||
|
"""
|
||||||
|
browserSession: BrowserSession!
|
||||||
|
"""
|
||||||
|
User authorized for this session.
|
||||||
|
"""
|
||||||
|
user: User!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Oauth2SessionConnection {
|
||||||
|
"""
|
||||||
|
Information to aid in pagination.
|
||||||
|
"""
|
||||||
|
pageInfo: PageInfo!
|
||||||
|
"""
|
||||||
|
A list of edges.
|
||||||
|
"""
|
||||||
|
edges: [Oauth2SessionEdge!]!
|
||||||
|
"""
|
||||||
|
A list of nodes.
|
||||||
|
"""
|
||||||
|
nodes: [Oauth2Session!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
An edge in a connection.
|
||||||
|
"""
|
||||||
|
type Oauth2SessionEdge {
|
||||||
|
"""
|
||||||
|
A cursor for use in pagination
|
||||||
|
"""
|
||||||
|
cursor: String!
|
||||||
|
"""
|
||||||
|
The item at the end of the edge
|
||||||
|
"""
|
||||||
|
node: Oauth2Session!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
Information about pagination in a connection
|
||||||
|
"""
|
||||||
|
type PageInfo {
|
||||||
|
"""
|
||||||
|
When paginating backwards, are there more items?
|
||||||
|
"""
|
||||||
|
hasPreviousPage: Boolean!
|
||||||
|
"""
|
||||||
|
When paginating forwards, are there more items?
|
||||||
|
"""
|
||||||
|
hasNextPage: Boolean!
|
||||||
|
"""
|
||||||
|
When paginating backwards, the cursor to continue.
|
||||||
|
"""
|
||||||
|
startCursor: String
|
||||||
|
"""
|
||||||
|
When paginating forwards, the cursor to continue.
|
||||||
|
"""
|
||||||
|
endCursor: String
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
The query root of the GraphQL interface.
|
||||||
|
"""
|
||||||
|
type RootQuery {
|
||||||
|
"""
|
||||||
|
Get the current logged in browser session
|
||||||
|
"""
|
||||||
|
currentBrowserSession: BrowserSession
|
||||||
|
"""
|
||||||
|
Get the current logged in user
|
||||||
|
"""
|
||||||
|
currentUser: User
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
URL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)
|
||||||
|
"""
|
||||||
|
scalar Url
|
||||||
|
|
||||||
|
"""
|
||||||
|
A user is an individual's account.
|
||||||
|
"""
|
||||||
|
type User implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
Username chosen by the user.
|
||||||
|
"""
|
||||||
|
username: String!
|
||||||
|
"""
|
||||||
|
Primary email address of the user.
|
||||||
|
"""
|
||||||
|
primaryEmail: UserEmail
|
||||||
|
"""
|
||||||
|
Get the list of compatibility SSO logins, chronologically sorted
|
||||||
|
"""
|
||||||
|
compatSsoLogins(
|
||||||
|
after: String
|
||||||
|
before: String
|
||||||
|
first: Int
|
||||||
|
last: Int
|
||||||
|
): CompatSsoLoginConnection!
|
||||||
|
"""
|
||||||
|
Get the list of active browser sessions, chronologically sorted
|
||||||
|
"""
|
||||||
|
browserSessions(
|
||||||
|
after: String
|
||||||
|
before: String
|
||||||
|
first: Int
|
||||||
|
last: Int
|
||||||
|
): BrowserSessionConnection!
|
||||||
|
"""
|
||||||
|
Get the list of emails, chronologically sorted
|
||||||
|
"""
|
||||||
|
emails(
|
||||||
|
after: String
|
||||||
|
before: String
|
||||||
|
first: Int
|
||||||
|
last: Int
|
||||||
|
): UserEmailConnection!
|
||||||
|
"""
|
||||||
|
Get the list of OAuth 2.0 sessions, chronologically sorted
|
||||||
|
"""
|
||||||
|
oauth2Sessions(
|
||||||
|
after: String
|
||||||
|
before: String
|
||||||
|
first: Int
|
||||||
|
last: Int
|
||||||
|
): Oauth2SessionConnection!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
A user email address
|
||||||
|
"""
|
||||||
|
type UserEmail implements Node {
|
||||||
|
"""
|
||||||
|
ID of the object.
|
||||||
|
"""
|
||||||
|
id: ID!
|
||||||
|
"""
|
||||||
|
Email address
|
||||||
|
"""
|
||||||
|
email: String!
|
||||||
|
"""
|
||||||
|
When the object was created.
|
||||||
|
"""
|
||||||
|
createdAt: DateTime!
|
||||||
|
"""
|
||||||
|
When the email address was confirmed. Is `null` if the email was never
|
||||||
|
verified by the user.
|
||||||
|
"""
|
||||||
|
confirmedAt: DateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserEmailConnection {
|
||||||
|
"""
|
||||||
|
Information to aid in pagination.
|
||||||
|
"""
|
||||||
|
pageInfo: PageInfo!
|
||||||
|
"""
|
||||||
|
A list of edges.
|
||||||
|
"""
|
||||||
|
edges: [UserEmailEdge!]!
|
||||||
|
"""
|
||||||
|
A list of nodes.
|
||||||
|
"""
|
||||||
|
nodes: [UserEmail!]!
|
||||||
|
"""
|
||||||
|
Identifies the total count of items in the connection.
|
||||||
|
"""
|
||||||
|
totalCount: Int!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
An edge in a connection.
|
||||||
|
"""
|
||||||
|
type UserEmailEdge {
|
||||||
|
"""
|
||||||
|
A cursor for use in pagination
|
||||||
|
"""
|
||||||
|
cursor: String!
|
||||||
|
"""
|
||||||
|
The item at the end of the edge
|
||||||
|
"""
|
||||||
|
node: UserEmail!
|
||||||
|
}
|
||||||
|
|
||||||
|
schema {
|
||||||
|
query: RootQuery
|
||||||
|
}
|
@@ -22,6 +22,7 @@ export const App: React.FC = () => {
|
|||||||
graphql`
|
graphql`
|
||||||
query AppQuery {
|
query AppQuery {
|
||||||
currentUser {
|
currentUser {
|
||||||
|
id
|
||||||
username
|
username
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
70
frontend/src/__generated__/AppQuery.graphql.ts
generated
70
frontend/src/__generated__/AppQuery.graphql.ts
generated
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<85f26fc928e25f5adee1aa4bdb35943f>>
|
* @generated SignedSource<<1d2a0ace12c4e6d2a684909c137cbc73>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -12,6 +12,7 @@ import { ConcreteRequest, Query } from 'relay-runtime';
|
|||||||
export type AppQuery$variables = {};
|
export type AppQuery$variables = {};
|
||||||
export type AppQuery$data = {
|
export type AppQuery$data = {
|
||||||
readonly currentUser: {
|
readonly currentUser: {
|
||||||
|
readonly id: string;
|
||||||
readonly username: string;
|
readonly username: string;
|
||||||
} | null;
|
} | null;
|
||||||
};
|
};
|
||||||
@@ -21,20 +22,7 @@ export type AppQuery = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const node: ConcreteRequest = (function(){
|
const node: ConcreteRequest = (function(){
|
||||||
var v0 = {
|
var v0 = [
|
||||||
"alias": null,
|
|
||||||
"args": null,
|
|
||||||
"kind": "ScalarField",
|
|
||||||
"name": "username",
|
|
||||||
"storageKey": null
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
"fragment": {
|
|
||||||
"argumentDefinitions": [],
|
|
||||||
"kind": "Fragment",
|
|
||||||
"metadata": null,
|
|
||||||
"name": "AppQuery",
|
|
||||||
"selections": [
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -43,11 +31,31 @@ return {
|
|||||||
"name": "currentUser",
|
"name": "currentUser",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v0/*: any*/)
|
{
|
||||||
],
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "username",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": [],
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "AppQuery",
|
||||||
|
"selections": (v0/*: any*/),
|
||||||
"type": "RootQuery",
|
"type": "RootQuery",
|
||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
},
|
},
|
||||||
@@ -56,39 +64,19 @@ return {
|
|||||||
"argumentDefinitions": [],
|
"argumentDefinitions": [],
|
||||||
"kind": "Operation",
|
"kind": "Operation",
|
||||||
"name": "AppQuery",
|
"name": "AppQuery",
|
||||||
"selections": [
|
"selections": (v0/*: any*/)
|
||||||
{
|
|
||||||
"alias": null,
|
|
||||||
"args": null,
|
|
||||||
"concreteType": "User",
|
|
||||||
"kind": "LinkedField",
|
|
||||||
"name": "currentUser",
|
|
||||||
"plural": false,
|
|
||||||
"selections": [
|
|
||||||
(v0/*: any*/),
|
|
||||||
{
|
|
||||||
"alias": null,
|
|
||||||
"args": null,
|
|
||||||
"kind": "ScalarField",
|
|
||||||
"name": "id",
|
|
||||||
"storageKey": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"storageKey": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "84b2b5650a0c71cce7c40242b378e52f",
|
"cacheID": "34c6b7534570705caab3d20018e06721",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "AppQuery",
|
"name": "AppQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query AppQuery {\n currentUser {\n username\n id\n }\n}\n"
|
"text": "query AppQuery {\n currentUser {\n id\n username\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "fef45d7542db63ccb8b3d59ca5dc6afb";
|
(node as any).hash = "25e4287bcbdf0f3f35028d4be484dda9";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
@@ -5,9 +5,12 @@ set -eu
|
|||||||
export SQLX_OFFLINE=1
|
export SQLX_OFFLINE=1
|
||||||
BASE_DIR="$(dirname "$0")/.."
|
BASE_DIR="$(dirname "$0")/.."
|
||||||
CONFIG_SCHEMA="${BASE_DIR}/docs/config.schema.json"
|
CONFIG_SCHEMA="${BASE_DIR}/docs/config.schema.json"
|
||||||
GRAPHQL_SCHEMA="${BASE_DIR}/crates/graphql/schema.graphql"
|
GRAPHQL_SCHEMA="${BASE_DIR}/frontend/schema.graphql"
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
# XXX: we shouldn't have to specify this feature
|
# XXX: we shouldn't have to specify this feature
|
||||||
cargo run -p mas-config --features webpki-roots > "${CONFIG_SCHEMA}"
|
cargo run -p mas-config --features webpki-roots > "${CONFIG_SCHEMA}"
|
||||||
cargo run -p mas-graphql --features webpki-roots > "${GRAPHQL_SCHEMA}"
|
cargo run -p mas-graphql --features webpki-roots > "${GRAPHQL_SCHEMA}"
|
||||||
|
|
||||||
|
cd "${BASE_DIR}/frontend"
|
||||||
|
npm run generate
|
Reference in New Issue
Block a user