Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: rework the useAuth hook #126

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 48 additions & 92 deletions ui/src/app/(auth)/initialize/page.tsx
Original file line number Diff line number Diff line change
@@ -1,113 +1,69 @@
"use client"

import { passwordIsValid } from "@/utils"
import { statusResponse } from "@/types"
import { getStatus, login, postFirstUser } from "@/queries"
import { useAuth } from "@/app/auth/authContext"
import { Input, PasswordToggle, Button, Form, LoginPageLayout } from "@canonical/react-components";
import { useMutation, useQuery } from "@tanstack/react-query"
import { useState, ChangeEvent } from "react"
import { useRouter } from "next/navigation"
import { useCookies } from "react-cookie"

import { useAuth } from "@/hooks/useAuth";

export default function Initialize() {
const router = useRouter()
const auth = useAuth()
const [cookies, setCookie, removeCookie] = useCookies(['user_token']);
const statusQuery = useQuery<statusResponse, Error>({
queryKey: ["status"],
queryFn: () => getStatus(),
})
if (statusQuery.data && statusQuery.data.initialized) {
auth.setFirstUserCreated(true)
router.push("/login")
}
const loginMutation = useMutation({
mutationFn: login,
onSuccess: (result) => {
setErrorText("")
setCookie('user_token', result?.token, {
sameSite: true,
secure: true,
expires: new Date(new Date().getTime() + 60 * 60 * 1000),
})
router.push('/certificate_requests')
},
onError: (e: Error) => {
setErrorText(e.message)
}
})
const postUserMutation = useMutation({
mutationFn: postFirstUser,
onSuccess: () => {
setErrorText("")
auth.setFirstUserCreated(true)
loginMutation.mutate({ username: username, password: password1 })
},
onError: (e: Error) => {
setErrorText(e.message)
}
})

const [username, setUsername] = useState<string>("")
const [password1, setPassword1] = useState<string>("")
const [password2, setPassword2] = useState<string>("")
const passwordsMatch = password1 === password2
const password1Error = password1 && !passwordIsValid(password1) ? "Password is not valid" : ""
const password2Error = password2 && !passwordsMatch ? "Passwords do not match" : ""

const [errorText, setErrorText] = useState<string>("")
const handleUsernameChange = (event: ChangeEvent<HTMLInputElement>) => { setUsername(event.target.value) }
const handlePassword1Change = (event: ChangeEvent<HTMLInputElement>) => { setPassword1(event.target.value) }
const handlePassword2Change = (event: ChangeEvent<HTMLInputElement>) => { setPassword2(event.target.value) }
return (
<>
<LoginPageLayout
logo={{
src: 'https://assets.ubuntu.com/v1/82818827-CoF_white.svg',
title: 'Notary',
url: '#'
}}
title="Initialize Notary"
>
<Form>
<h4>Create the initial admin user</h4>
<Input
id="InputUsername"
label="Username"
type="text"
required={true}
onChange={handleUsernameChange}
/>
<PasswordToggle
help="Password must have 8 or more characters, must include at least one capital letter, one lowercase letter, and either a number or a symbol."
id="password1"
label="Password"
onChange={handlePassword1Change}
required={true}
error={password1Error}
/>
<PasswordToggle
id="password2"
label="Confirm Password"
onChange={handlePassword2Change}
required={true}
error={password2Error}
/>
<Button
appearance="positive"
disabled={!passwordsMatch || !passwordIsValid(password1)}
onClick={(event) => {
event.preventDefault();
if (passwordsMatch && passwordIsValid(password1)) {
postUserMutation.mutate({ username: username, password: password1 });
}
}}
>
Submit
</Button>
</Form>
</LoginPageLayout>
</>
<LoginPageLayout
logo={{
src: 'https://assets.ubuntu.com/v1/82818827-CoF_white.svg',
title: 'Notary',
url: '#'
}}
title="Initialize Notary"
>
<Form>
<h4>Create the initial admin user</h4>
<Input
id="InputUsername"
label="Username"
type="text"
required={true}
onChange={handleUsernameChange}
/>
<PasswordToggle
help="Password must have 8 or more characters, must include at least one capital letter, one lowercase letter, and either a number or a symbol."
id="password1"
label="Password"
onChange={handlePassword1Change}
required={true}
error={password1Error}
/>
<PasswordToggle
id="password2"
label="Confirm Password"
onChange={handlePassword2Change}
required={true}
error={password2Error}
/>
<Button
appearance="positive"
disabled={!passwordsMatch || !passwordIsValid(password1)}
onClick={(event) => {
event.preventDefault();
if (passwordsMatch && passwordIsValid(password1)) {
auth.initializeFirstUser(username, password1)
}
}}
>
Submit
</Button>
</Form>
</LoginPageLayout>
)
}
10 changes: 5 additions & 5 deletions ui/src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"
import '@/globals.scss'
import { AuthProvider } from "@/app/auth/authContext";
import { AuthProvider } from "@/hooks/useAuth";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient()
Expand All @@ -11,11 +11,11 @@ export default function RootLayout({
}>) {
return (
<body>
<AuthProvider>
<QueryClientProvider client={queryClient}>
<QueryClientProvider client={queryClient}>
<AuthProvider>
{children}
</QueryClientProvider>
</AuthProvider>
</AuthProvider>
</QueryClientProvider>
</body>
);
}
107 changes: 50 additions & 57 deletions ui/src/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,29 @@
import { getStatus, login } from "@/queries"
import { useMutation, useQuery } from "@tanstack/react-query"
import { useState, ChangeEvent } from "react"
import { useCookies } from "react-cookie"
import { useRouter } from "next/navigation"
import { useAuth } from "@/app/auth/authContext"
import { useAuth } from "@/hooks/useAuth"
import { statusResponse } from "@/types"
import { Input, PasswordToggle, Button, Form, Notification, LoginPageLayout } from "@canonical/react-components";


export default function LoginPage() {
const router = useRouter()
const auth = useAuth()
const [cookies, setCookie, removeCookie] = useCookies(['user_token']);
const statusQuery = useQuery<statusResponse, Error>({
queryKey: ["status"],
queryFn: () => getStatus()
queryFn: () => getStatus(),
enabled: auth.firstUserInitialized == "unknown"
})
if (!auth.firstUserCreated && (statusQuery.data && !statusQuery.data.initialized)) {
router.push("/initialize")
if (auth.firstUserInitialized == "unknown" && statusQuery.data) {
auth.setFirstUserInitialized(statusQuery.data.initialized)
}
const mutation = useMutation({
mutationFn: login,
onSuccess: (result) => {
setErrorText("")
setCookie('user_token', result?.token, {
sameSite: true,
secure: true,
expires: new Date(new Date().getTime() + 60 * 60 * 1000),
})
router.push('/certificate_requests')
auth.login(result?.token)
router.push('/')
},
onError: (e: Error) => {
setErrorText(e.message)
Expand All @@ -43,51 +38,49 @@ export default function LoginPage() {
const handleUsernameChange = (event: ChangeEvent<HTMLInputElement>) => { setUsername(event.target.value) }
const handlePasswordChange = (event: ChangeEvent<HTMLInputElement>) => { setPassword(event.target.value) }
return (
<>
<LoginPageLayout
logo={{
src: 'https://assets.ubuntu.com/v1/82818827-CoF_white.svg',
title: 'Notary',
url: '#'
}}
title="Log in"
>
<Form>
<Input
id="InputUsername"
label="Username"
type="text"
required={true}
onChange={handleUsernameChange}
/>
<PasswordToggle
id="InputPassword"
label="Password"
required={true}
onChange={handlePasswordChange}
/>
{errorText &&
<Notification
severity="negative"
title="Error"
>
{errorText.split("error: ")}
</Notification>
}
<Button
appearance="positive"
disabled={password.length == 0 || username.length == 0}
onClick={
(event) => {
event.preventDefault();
mutation.mutate({ username: username, password: password })
}
}
<LoginPageLayout
logo={{
src: 'https://assets.ubuntu.com/v1/82818827-CoF_white.svg',
title: 'Notary',
url: '#'
}}
title="Log in"
>
<Form>
<Input
id="InputUsername"
label="Username"
type="text"
required={true}
onChange={handleUsernameChange}
/>
<PasswordToggle
id="InputPassword"
label="Password"
required={true}
onChange={handlePasswordChange}
/>
{errorText &&
<Notification
severity="negative"
title="Error"
>
Log In
</Button>
</Form>
</LoginPageLayout>
</>
{errorText.split("error: ")}
</Notification>
}
<Button
appearance="positive"
disabled={password.length == 0 || username.length == 0}
onClick={
(event) => {
event.preventDefault();
mutation.mutate({ username: username, password: password })
}
}
>
Log In
</Button>
</Form>
</LoginPageLayout>
)
}
8 changes: 4 additions & 4 deletions ui/src/app/(notary)/certificate_requests/asideForm.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { csrIsValid } from "@/utils";
import { useCookies } from "react-cookie";
import { postCSR } from "@/queries";
import { ChangeEvent, useContext, useState, useEffect } from "react";
import { AsideContext } from "@/components/aside";
import { Textarea, Button, Input, Panel, Form } from "@canonical/react-components";
import { useAuth } from "@/hooks/useAuth";


export default function CertificateRequestsAsidePanel(): JSX.Element {
const auth = useAuth()
const asideContext = useContext(AsideContext);
const [cookies] = useCookies(['user_token']);
const [errorText, setErrorText] = useState<string>("");
const [CSRPEMString, setCSRPEMString] = useState<string>("");
const queryClient = useQueryClient();
Expand Down Expand Up @@ -52,7 +52,7 @@ export default function CertificateRequestsAsidePanel(): JSX.Element {
};

const handleSubmit = () => {
mutation.mutate({ authToken: cookies.user_token, csr: CSRPEMString });
mutation.mutate({ authToken: auth.user ? auth.user.authToken : "", csr: CSRPEMString });
};

return (
Expand Down Expand Up @@ -90,7 +90,7 @@ export default function CertificateRequestsAsidePanel(): JSX.Element {
appearance="positive"
name="submit"
disabled={!csrIsValid(CSRPEMString)}
onClick={handleSubmit}
onClick={(event) => { event?.preventDefault(); handleSubmit() }}
>
Submit
</Button>
Expand Down
Loading
Loading