Compare commits
3 Commits
9df08fc14f
...
120106bfbc
| Author | SHA1 | Date | |
|---|---|---|---|
| 120106bfbc | |||
| aa3e81de27 | |||
| 6dbd389f02 |
@@ -30,7 +30,7 @@
|
|||||||
"test": "craco test",
|
"test": "craco test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"graphql:gen": "graphql-codegen --config codegen.yml",
|
"graphql:gen": "graphql-codegen --config codegen.yml",
|
||||||
"graphql:download": "apollo schema:download --endpoint=http://localhost:8080/graphql src/generated/schema.json"
|
"graphql:download": "apollo schema:download --endpoint=http://localhost:8080/api/graphql src/generated/schema.json"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ import React from "react"
|
|||||||
import FileBrowser from "./components/FileBrowser"
|
import FileBrowser from "./components/FileBrowser"
|
||||||
import { BrowserRouter as Router, Switch, Route, Redirect } from "react-router-dom"
|
import { BrowserRouter as Router, Switch, Route, Redirect } from "react-router-dom"
|
||||||
import NotFound from "./components/NotFound"
|
import NotFound from "./components/NotFound"
|
||||||
|
import Login from "./components/Login"
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="dark:text-gray-300">
|
||||||
<Router>
|
<Router>
|
||||||
<Switch>
|
<Switch>
|
||||||
|
<Route path="/login" exact component={Login} />
|
||||||
<Route path="/f/" component={FileBrowser}/>
|
<Route path="/f/" component={FileBrowser}/>
|
||||||
<Redirect from="/" exact to="/f/" />
|
<Redirect from="/" exact to="/f/" />
|
||||||
<Route path="*" component={NotFound} />
|
<Route path="*" component={NotFound} />
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const CreateDirButton: React.FC<Props> = (props) => {
|
|||||||
}}>
|
}}>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
className="bg-transparent dark:text-gray-300 outline-none mx-1 border-b"
|
className="mx-1 text-input"
|
||||||
type="text"
|
type="text"
|
||||||
onChange={(e)=>setName(e.target.value)}
|
onChange={(e)=>setName(e.target.value)}
|
||||||
value={name}
|
value={name}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ const FileBrowser: React.FC<RouteComponentProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dark:text-gray-300">
|
<div>
|
||||||
<FileBrowserContextMenu
|
<FileBrowserContextMenu
|
||||||
onSelect={onContextSelect}
|
onSelect={onContextSelect}
|
||||||
pasteActive={!!srcID}
|
pasteActive={!!srcID}
|
||||||
|
|||||||
77
src/components/Login.tsx
Normal file
77
src/components/Login.tsx
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import React from "react"
|
||||||
|
import { useState } from "react"
|
||||||
|
import { RouteComponentProps } from "react-router-dom"
|
||||||
|
import { useLoginMutation } from "../generated/graphql"
|
||||||
|
|
||||||
|
const Login: React.FC<RouteComponentProps> = (props) => {
|
||||||
|
const [username,setUsername] = useState("")
|
||||||
|
const [password,setPassword] = useState("")
|
||||||
|
|
||||||
|
const [loginFailed,setLoginFailed] = useState(false)
|
||||||
|
|
||||||
|
const [loginMutation] = useLoginMutation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center h-screen items-center">
|
||||||
|
<div>
|
||||||
|
<form onSubmit={async (e)=>{
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
const result = await loginMutation({
|
||||||
|
variables:{
|
||||||
|
username: username,
|
||||||
|
password: password
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const successful = result.data?.login.successful
|
||||||
|
|
||||||
|
if (!successful){
|
||||||
|
setLoginFailed(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = result.data?.login.token
|
||||||
|
|
||||||
|
if (token){
|
||||||
|
const response = await fetch("/api/cookie",{
|
||||||
|
method:"POST",
|
||||||
|
body: token
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.ok){
|
||||||
|
// Login successful
|
||||||
|
props.history.push("/f/")
|
||||||
|
}else{
|
||||||
|
setLoginFailed(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}} >
|
||||||
|
{loginFailed &&
|
||||||
|
<div className="text-red-600 mb-4" >
|
||||||
|
<div className="font-bold" >
|
||||||
|
Login failed
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Wrong username or password
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<input type="text" placeholder="Username"
|
||||||
|
className="block my-2 text-input"
|
||||||
|
required
|
||||||
|
onChange={(e)=>setUsername(e.target.value)}
|
||||||
|
/>
|
||||||
|
<input type="password" placeholder="Password"
|
||||||
|
className="block my-2 text-input"
|
||||||
|
required
|
||||||
|
onChange={(e)=>setPassword(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button className="block my-2 w-full" >Login</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Login
|
||||||
@@ -40,12 +40,22 @@ export type File = {
|
|||||||
size: Scalars["Int"];
|
size: Scalars["Int"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Result of a login */
|
||||||
|
export type LoginResut = {
|
||||||
|
__typename?: "LoginResut";
|
||||||
|
/** If the login was successful */
|
||||||
|
successful: Scalars["Boolean"];
|
||||||
|
/** JWT token if login was successful */
|
||||||
|
token?: Maybe<Scalars["String"]>;
|
||||||
|
};
|
||||||
|
|
||||||
export type RootMutation = {
|
export type RootMutation = {
|
||||||
__typename?: "RootMutation";
|
__typename?: "RootMutation";
|
||||||
copy?: Maybe<File>;
|
copy?: Maybe<File>;
|
||||||
createDir: Directory;
|
createDir: Directory;
|
||||||
delete?: Maybe<Scalars["String"]>;
|
delete?: Maybe<Scalars["String"]>;
|
||||||
deleteDir: Scalars["String"];
|
deleteDir: Scalars["String"];
|
||||||
|
login: LoginResut;
|
||||||
move?: Maybe<File>;
|
move?: Maybe<File>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,6 +81,12 @@ export type RootMutationDeleteDirArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type RootMutationLoginArgs = {
|
||||||
|
username: Scalars["String"];
|
||||||
|
password: Scalars["String"];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type RootMutationMoveArgs = {
|
export type RootMutationMoveArgs = {
|
||||||
src: Scalars["ID"];
|
src: Scalars["ID"];
|
||||||
dest: Scalars["ID"];
|
dest: Scalars["ID"];
|
||||||
@@ -158,6 +174,20 @@ export type GetFileQuery = (
|
|||||||
)> }
|
)> }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export type LoginMutationVariables = Exact<{
|
||||||
|
username: Scalars["String"];
|
||||||
|
password: Scalars["String"];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type LoginMutation = (
|
||||||
|
{ __typename?: "RootMutation" }
|
||||||
|
& { login: (
|
||||||
|
{ __typename?: "LoginResut" }
|
||||||
|
& Pick<LoginResut, "token" | "successful">
|
||||||
|
) }
|
||||||
|
);
|
||||||
|
|
||||||
export type MoveMutationVariables = Exact<{
|
export type MoveMutationVariables = Exact<{
|
||||||
src: Scalars["ID"];
|
src: Scalars["ID"];
|
||||||
dest: Scalars["ID"];
|
dest: Scalars["ID"];
|
||||||
@@ -357,6 +387,41 @@ export function useGetFileLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<Ge
|
|||||||
export type GetFileQueryHookResult = ReturnType<typeof useGetFileQuery>;
|
export type GetFileQueryHookResult = ReturnType<typeof useGetFileQuery>;
|
||||||
export type GetFileLazyQueryHookResult = ReturnType<typeof useGetFileLazyQuery>;
|
export type GetFileLazyQueryHookResult = ReturnType<typeof useGetFileLazyQuery>;
|
||||||
export type GetFileQueryResult = Apollo.QueryResult<GetFileQuery, GetFileQueryVariables>;
|
export type GetFileQueryResult = Apollo.QueryResult<GetFileQuery, GetFileQueryVariables>;
|
||||||
|
export const LoginDocument = gql`
|
||||||
|
mutation Login($username: String!, $password: String!) {
|
||||||
|
login(username: $username, password: $password) {
|
||||||
|
token
|
||||||
|
successful
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
export type LoginMutationFn = Apollo.MutationFunction<LoginMutation, LoginMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useLoginMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useLoginMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useLoginMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [loginMutation, { data, loading, error }] = useLoginMutation({
|
||||||
|
* variables: {
|
||||||
|
* username: // value for 'username'
|
||||||
|
* password: // value for 'password'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useLoginMutation(baseOptions?: Apollo.MutationHookOptions<LoginMutation, LoginMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useMutation<LoginMutation, LoginMutationVariables>(LoginDocument, options)
|
||||||
|
}
|
||||||
|
export type LoginMutationHookResult = ReturnType<typeof useLoginMutation>;
|
||||||
|
export type LoginMutationResult = Apollo.MutationResult<LoginMutation>;
|
||||||
|
export type LoginMutationOptions = Apollo.BaseMutationOptions<LoginMutation, LoginMutationVariables>;
|
||||||
export const MoveDocument = gql`
|
export const MoveDocument = gql`
|
||||||
mutation move($src: ID!, $dest: ID!) {
|
mutation move($src: ID!, $dest: ID!) {
|
||||||
move(src: $src, dest: $dest) {
|
move(src: $src, dest: $dest) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
6
src/graphql/login.graphql
Normal file
6
src/graphql/login.graphql
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
mutation Login($username: String!, $password: String!){
|
||||||
|
login(username:$username,password:$password){
|
||||||
|
token
|
||||||
|
successful
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
/* Commonly used classes*/
|
||||||
|
|
||||||
|
.text-input{
|
||||||
|
@apply bg-transparent border-gray-900 dark:border-gray-300 dark:text-gray-300 outline-none border-b
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user