Compare commits

...

10 Commits

Author SHA1 Message Date
Pierre-Louis Mercereau
947b7e037f fix: correct dependency bump 2022-03-29 16:33:40 +02:00
github-actions[bot]
cd6f37f2a6 chore: update versions (#304)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-03-29 16:11:46 +02:00
Pilou
39df4d5b9c Deprecate useAuthLoading and introduce useAuthenticationStatus (#303)
* fix(react): keep authentication and loading status in sync

fix #302

* style: typo
2022-03-29 13:21:50 +02:00
Pilou
e91215bbac Docs/nextjs (#299)
* fix: correct access to user/session information through getUser/getSession/isReady

* chore: use carret instead of star

* docs: explain all react hooks are available from @nhost/nextjs

* docs: correct imports in nextjs example

* chore: remove orphan changeset

* docs: next.js instead of NextJs
2022-03-28 14:16:41 +02:00
github-actions[bot]
ccaa4c4bba chore: update versions (#300)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-03-28 10:11:31 +02:00
Pilou
ab36f90cec fix: correct access to user/session information through getUser/getSession/isReady (#298)
* fix: correct access to user/session information through getUser/getSession/isReady

* chore: use carret instead of star
2022-03-28 10:09:38 +02:00
Johan Eliasson
cfbe2db430 fix: make it clear the @nhost/react-auth package is depricated (#297)
* fix: make it clear this package is depricated

* Update README.md

Co-authored-by: Pilou <24897252+plmercereau@users.noreply.github.com>
2022-03-28 09:57:55 +02:00
Pilou
6838ac6201 docs: fix deadlinks in README (#256) 2022-03-25 15:38:19 +00:00
Johan Eliasson
0caf43037d fix: updated react apollo crm package versions (#296)
* update

* update
2022-03-25 16:33:30 +01:00
Pilou
4ed626d5b5 chore: bump fixed versions in examples (#257)
* chore: bump fixed versions in examples

* chore: bump to latest sdk version

* chore: bump to latest version

* chore: bump example version
2022-03-25 14:49:35 +00:00
51 changed files with 12807 additions and 48582 deletions

View File

@@ -99,8 +99,8 @@ Nhost libraries and tools
- [JavaScript/TypeScript SDK](https://docs.nhost.io/reference/sdk)
- [Dart and Flutter SDK](https://github.com/nhost/nhost-dart)
- [Nhost CLI](https://docs.nhost.io/reference/cli)
- [Nhost React Auth](https://docs.nhost.io/reference/supporting-libraries/react-auth)
- [Nhost React Apollo](https://docs.nhost.io/reference/supporting-libraries/react-apollo)
- [Nhost React](https://docs.nhost.io/reference/react)
- [Nhost Next.js](https://docs.nhost.io/reference/nextjs)
## Community ❤️

View File

@@ -58,7 +58,7 @@ The logic is the same as in a classic React application:
import { NextPageContext } from 'next'
import React from 'react'
import { useAccessToken, useAuthenticated, useUserData } from '@nhost/react'
import { useAccessToken, useAuthenticated, useUserData } from '@nhost/nextjs'
const ClientSidePage: React.FC = () => {
const isAuthenticated = useAuthenticated()
@@ -93,7 +93,7 @@ import {
useAccessToken,
useAuthenticated,
useUserData
} from '@nhost/react'
} from '@nhost/nextjs'
export async function getServerSideProps(context: NextPageContext) {
const nhostSession = await getNhostSession('my-app.nhost.run', context)

View File

@@ -2,7 +2,7 @@
title: 'Introduction'
---
It is possible to use [`@nhost/react`](/reference/react) in any Next.js page that would be configured to render on the client-side.
All the React hooks and helpers from [`@nhost/react`](/reference/react) are available in Next.js and are exported in the `@nhost/nextjs` package.
When rendering a page from the server-side, Next.js needs to get some information from the client to determine their authentication status. Such communication is only available from cookies, and the Nhost client is designed to enable such a mechanism.

View File

@@ -6,13 +6,12 @@ Create a `auth-protected.js` file:
```jsx
import { useRouter } from 'next/router'
import { useAuthLoading, useAuthenticated } from '@nhost/nextjs'
import { useAuthenticationStatus } from '@nhost/nextjs'
export function authProtected(Comp) {
return function AuthProtected(props) {
const router = useRouter()
const isLoading = useAuthLoading()
const isAuthenticated = useAuthenticated()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
if (isLoading) {
return <div>Loading...</div>

View File

@@ -218,20 +218,19 @@ const Component = () => {
## Authentication status
### `useAuthLoading`
### `useAuthenticationStatus`
The Nhost client may need some initial steps to determine the authentication status during startup, like fetching a new JWT from an existing refresh token.
`useAuthLoading` will return `true` until the authentication status is known.
`isLoading` will return `true` until the authentication status is known.
#### Usage
```jsx
import { useAuthLoading, useAuthenticated } from '@nhost/react'
import { useAuthenticationStatus } from '@nhost/react'
const Component = () => {
const isLoading = useAuthLoading()
const isAuthenticated = useAuthenticated()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
if (isLoading) return <div>Loading Nhost authentication status...</div>
else if (isAuthenticated) return <div>User is authenticated</div>
else return <div>Public section</div>

View File

@@ -8,11 +8,10 @@ You can protect routes by creating an `AuthGate` component when using `@nhost/re
```jsx
import { Redirect } from 'react-router-dom'
import { useAuthLoading, useAuthenticated } from '@nhost/react'
import { useAuthenticationStatus } from '@nhost/react'
export function AuthGate(children) {
const isLoading = useAuthLoading()
const isAuthenticated = useAuthenticated()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
if (isLoading) {
return <div>Loading...</div>

View File

@@ -4,12 +4,6 @@
### Patch Changes
- Updated dependencies [207ae38]
- Updated dependencies [207ae38]
- Updated dependencies [207ae38]
- Updated dependencies [207ae38]
- Updated dependencies [207ae38]
- Updated dependencies [207ae38]
- Updated dependencies [207ae38]
- @nhost/react-apollo@3.0.0
- @nhost/apollo@0.2.0

View File

@@ -7,7 +7,8 @@ export default function Header() {
<nav>
<Link href="/">Index</Link> <br />
<Link href="/second">Second</Link> <br />
<Link href="/third">Third</Link> <br />
<Link href="/third">SSR auth-guarded page</Link> <br />
<Link href="/client-side-auth-guard">CSR auth-guarded page</Link> <br />
</nav>
</header>
)

View File

@@ -0,0 +1,21 @@
import { useRouter } from 'next/router'
import { useAuthenticationStatus } from '@nhost/nextjs'
export function authProtected(Comp) {
return function AuthProtected(props) {
const router = useRouter()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
console.log('Authentication guard: check auth status', { isLoading, isAuthenticated })
if (isLoading) {
return <div>Loading...</div>
}
if (!isAuthenticated) {
router.push('/')
return null
}
return <Comp {...props} />
}
}

View File

@@ -4,7 +4,6 @@ table:
configuration:
custom_column_names:
id: id
redirect_url: redirectUrl
custom_name: authProviderRequests
custom_root_fields:
delete: deleteAuthProviderRequests

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/nextjs",
"version": "0.0.2",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
@@ -9,17 +9,18 @@
"lint": "next lint"
},
"dependencies": {
"@nhost/nextjs": "^0.2.0",
"@nhost/react": "^0.2.0",
"@nhost/react-apollo": "^3.0.0",
"@apollo/client": "^3.5.10",
"@nhost/nextjs": "^1.0.0",
"@nhost/react": "^0.3.0",
"@nhost/react-apollo": "^4.0.0",
"graphql": "^16.3.0",
"next": "12.1.0",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"@types/node": "17.0.17",
"@types/react": "17.0.39",
"@types/node": "17.0.23",
"@types/react": "17.0.43",
"@xstate/inspect": "^0.6.2",
"eslint": "8.8.0",
"eslint-config-next": "12.0.10",

View File

@@ -0,0 +1,17 @@
import React from 'react'
import { useAccessToken } from '@nhost/nextjs'
import { authProtected } from '../components/protected-route'
const ClientSideAuthPage: React.FC = () => {
const accessToken = useAccessToken()
return (
<div>
<h1>Client-side rendered page only accessible to authenticated users</h1>
<div>Access token: {accessToken}</div>
</div>
)
}
export default authProtected(ClientSideAuthPage)

View File

@@ -6,11 +6,11 @@ import {
useAuthenticated,
useChangeEmail,
useChangePassword,
useSignInEmailPasswordless,
useSignInEmailPassword,
useSignUpEmailPassword,
useSignOut
} from '@nhost/react'
useSignInEmailPasswordless,
useSignOut,
useSignUpEmailPassword
} from '@nhost/nextjs'
import { useAuthQuery } from '@nhost/react-apollo'
import { BOOKS_QUERY } from '../helpers'

View File

@@ -1,8 +1,8 @@
import { NextPageContext } from 'next'
import React from 'react'
import { getNhostSession, NhostSession } from '@nhost/nextjs'
import { useAccessToken, useAuthenticated, useUserData } from '@nhost/react'
import { NhostSession } from '@nhost/core'
import { getNhostSession, useAccessToken, useAuthenticated, useUserData } from '@nhost/nextjs'
import { BACKEND_URL } from '../helpers'

View File

@@ -1,9 +1,10 @@
import { NextPageContext } from 'next'
import React from 'react'
import { getNhostSession, NhostSession } from '@nhost/nextjs'
import { useAccessToken, useAuthenticated } from '@nhost/react'
import { NhostSession } from '@nhost/core'
import { getNhostSession, useAccessToken } from '@nhost/nextjs'
import { authProtected } from '../components/protected-route'
import { BACKEND_URL } from '../helpers'
export async function getServerSideProps(context: NextPageContext) {
@@ -17,15 +18,12 @@ export async function getServerSideProps(context: NextPageContext) {
const RefetchPage: React.FC<{ initial: NhostSession }> = () => {
const accessToken = useAccessToken()
const isAuthenticated = useAuthenticated()
if (!isAuthenticated) return <div>User it not authenticated </div>
return (
<div>
<h1>Third page</h1>
User is authenticated: {isAuthenticated ? 'yes' : 'no'}
<h1>SSR page only accessible to authenticated users</h1>
<div>Access token: {accessToken}</div>
</div>
)
}
export default RefetchPage
export default authProtected(RefetchPage)

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
module.exports = {
style: {
postcss: {
plugins: [require("tailwindcss"), require("autoprefixer")],
},
},
};

View File

@@ -0,0 +1,7 @@
import { NhostClient } from '@nhost/nhost-js'
const nhost = new NhostClient({
backendUrl: process.env.NHOST_BACKEND_URL!
})
export { nhost }

View File

@@ -1,107 +1,105 @@
import { Request, Response } from "express";
import { nhost } from "../../../src/utils/nhost";
import { Request, Response } from 'express'
import { nhost } from '../../_utils/nhost'
const handler = async (req: Request, res: Response) => {
if (
req.headers["nhsot-webhook-secret"] !== process.env.NHSOT_WEBHOOK_SECRET
) {
return res.status(401).send("Unauthorized");
}
if (req.headers['nhsot-webhook-secret'] !== process.env.NHSOT_WEBHOOK_SECRET) {
return res.status(401).send('Unauthorized')
}
// User who just signed up
const user = req.body.event.data.new;
// User who just signed up
const user = req.body.event.data.new
// Get the user's email domain
const emailDomain = user.email.split("@")[1];
// Get the user's email domain
const emailDomain = user.email.split('@')[1]
// Check if a company with the user's email domain already exists.
const GET_COMPANY_WITH_EMAIL_DOMAIN = `
// Check if a company with the user's email domain already exists.
const GET_COMPANY_WITH_EMAIL_DOMAIN = `
query getCompanyWithEmailDomain($emailDomain: String!) {
companies(where: { emailDomain: { _eq: $emailDomain } }) {
id
}
}
`;
const { data, error } = await nhost.graphql.request(
GET_COMPANY_WITH_EMAIL_DOMAIN,
{
emailDomain,
},
{
headers: {
"x-hasura-admin-secret": process.env.NHOST_ADMIN_SECRET,
`
const { data, error } = await nhost.graphql.request(
GET_COMPANY_WITH_EMAIL_DOMAIN,
{
emailDomain
},
}
);
{
headers: {
'x-hasura-admin-secret': process.env.NHOST_ADMIN_SECRET
}
}
)
if (error) {
return res.status(500).send(error);
}
if (error) {
return res.status(500).send(error)
}
const { companies } = data as any;
const { companies } = data as any
let companyId;
if (companies.length === 1) {
// if a company already exists, use that company's id
companyId = companies[0].id;
} else {
// else, create a new company for the newly created user with the same email domain as the user
const CREATE_NEW_COMPANY = `
let companyId
if (companies.length === 1) {
// if a company already exists, use that company's id
companyId = companies[0].id
} else {
// else, create a new company for the newly created user with the same email domain as the user
const CREATE_NEW_COMPANY = `
mutation insertCompany($emailDomain: String!) {
insertCompany(object: { name: $emailDomain, emailDomain: $emailDomain }) {
id
}
}
`;
const { data, error } = await nhost.graphql.request(
CREATE_NEW_COMPANY,
{
emailDomain,
},
{
headers: {
"x-hasura-admin-secret": process.env.NHOST_ADMIN_SECRET,
},
`
const { data, error } = await nhost.graphql.request(
CREATE_NEW_COMPANY,
{
emailDomain
},
{
headers: {
'x-hasura-admin-secret': process.env.NHOST_ADMIN_SECRET
}
}
)
if (error) {
return res.status(500).send(error)
}
);
if (error) {
return res.status(500).send(error);
}
const { insertCompany } = data as any
const { insertCompany } = data as any;
companyId = insertCompany.id
}
companyId = insertCompany.id;
}
// We now have the company id of an existing, or a newly created company.
// Now let's add the user to the company.
// We now have the company id of an existing, or a newly created company.
// Now let's add the user to the company.
const ADD_USER_TO_COMPANY = `
const ADD_USER_TO_COMPANY = `
mutation addUserToCompany($userId: uuid!, $companyId: uuid!) {
insertCompanyUser(object: {userId: $userId, companyId: $companyId}) {
id
}
}
`;
const { error: addUserToCompanyError } = await nhost.graphql.request(
ADD_USER_TO_COMPANY,
{
userId: user.id,
companyId,
},
{
headers: {
"x-hasura-admin-secret": process.env.NHOST_ADMIN_SECRET,
`
const { error: addUserToCompanyError } = await nhost.graphql.request(
ADD_USER_TO_COMPANY,
{
userId: user.id,
companyId
},
}
);
{
headers: {
'x-hasura-admin-secret': process.env.NHOST_ADMIN_SECRET
}
}
)
if (addUserToCompanyError) {
return res.status(500).send(error);
}
if (addUserToCompanyError) {
return res.status(500).send(error)
}
res.status(200).send(`OK`);
};
res.status(200).send(`OK`)
}
export default handler;
export default handler

File diff suppressed because it is too large Load Diff

View File

@@ -4,13 +4,11 @@
"private": true,
"dependencies": {
"@apollo/client": "^3.4.16",
"@craco/craco": "^6.4.0",
"@headlessui/react": "^1.4.2",
"@heroicons/react": "^1.0.5",
"@nhost/nhost-js": "^0.3.4",
"@nhost/react-apollo": "^2.0.7-0",
"@nhost/react-auth": "^2.0.3",
"@saeris/apollo-server-vercel": "^1.0.1",
"@nhost/nhost-js": "^1.0.0",
"@nhost/react": "^0.3.0",
"@nhost/react-apollo": "^4.0.0",
"@tailwindcss/forms": "^0.3.4",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
@@ -27,14 +25,14 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.0.2",
"react-scripts": "^4.0.3",
"react-scripts": "^5.0.0",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"codegen": "graphql-codegen --config codegen.yaml --errors-only"
},
@@ -68,4 +66,4 @@
"postcss": "^7.0.39",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17"
}
}
}

View File

@@ -1,26 +1,26 @@
import "./App.css";
import { NhostAuthProvider } from "@nhost/react-auth";
import { NhostApolloProvider } from "@nhost/react-apollo";
import { nhost } from "./utils/nhost";
import { Route, Routes } from "react-router";
import { Layout } from "./components/ui/Layout";
import { Customers } from "./components/Customers";
import { Dashboard } from "./components/Dashboard";
import { NewCustomer } from "./components/NewCustomer";
import { RequireAuth } from "./components/RequireAuth";
import { Customer } from "./components/Customer";
import { SignUp } from "./components/SignUp";
import { SignIn } from "./components/SignIn";
import { ResetPassword } from "./components/ResetPassword";
import './App.css'
import { NhostReactProvider } from '@nhost/react'
import { NhostApolloProvider } from '@nhost/react-apollo'
import { nhost } from './utils/nhost'
import { Route, Routes } from 'react-router'
import { Layout } from './components/ui/Layout'
import { Customers } from './components/Customers'
import { Dashboard } from './components/Dashboard'
import { NewCustomer } from './components/NewCustomer'
import { RequireAuth } from './components/RequireAuth'
import { Customer } from './components/Customer'
import { SignUp } from './components/SignUp'
import { SignIn } from './components/SignIn'
import { ResetPassword } from './components/ResetPassword'
function App() {
return (
<NhostAuthProvider nhost={nhost}>
<NhostReactProvider nhost={nhost}>
<NhostApolloProvider nhost={nhost}>
<AppRouter />
</NhostApolloProvider>
</NhostAuthProvider>
);
</NhostReactProvider>
)
}
function AppRouter() {
@@ -55,7 +55,7 @@ function AppRouter() {
</Route>
</Route>
</Routes>
);
)
}
export default App;
export default App

View File

@@ -1,98 +1,93 @@
import { Fragment, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import { CheckIcon } from "@heroicons/react/outline";
import { nhost } from "../utils/nhost";
import { Fragment, useState } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import { nhost } from '../utils/nhost'
export function ChangePasswordModal() {
const [open, setOpen] = useState(true);
const [newPassword, setNewPassword] = useState("");
const [open, setOpen] = useState(true)
const [newPassword, setNewPassword] = useState('')
const handleSubmit = async (e: React.SyntheticEvent<HTMLFormElement>) => {
e.preventDefault();
const handleSubmit = async (e: React.SyntheticEvent<HTMLFormElement>) => {
e.preventDefault()
const { error } = await nhost.auth.changePassword({ newPassword });
const { error } = await nhost.auth.changePassword({ newPassword })
if (error) {
return alert(error.message);
}
if (error) {
return alert(error.message)
}
setOpen(false);
};
setOpen(false)
}
return (
<Transition.Root show={open} as={Fragment}>
<Dialog
as="div"
className="fixed z-10 inset-0 overflow-y-auto"
onClose={setOpen}
>
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
return (
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="fixed z-10 inset-0 overflow-y-auto" onClose={setOpen}>
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
{/* This element is to trick the browser into centering the modal contents. */}
<span
className="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>
&#8203;
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-sm sm:w-full sm:p-6">
<form onSubmit={handleSubmit}>
<div>
<div className="mt-3 text-center sm:mt-5">
<Dialog.Title
as="h3"
className="text-lg leading-6 font-medium text-gray-900"
>
Change Password
</Dialog.Title>
<div className="mt-2">
<input
id="password"
name="password"
type="password"
autoComplete="current-password"
required
className="block w-full px-3 py-2 placeholder-gray-400 border border-gray-300 rounded-md shadow-sm appearance-none focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
tabIndex={2}
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
/>
</div>
{/* This element is to trick the browser into centering the modal contents. */}
<span
className="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>
&#8203;
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-sm sm:w-full sm:p-6">
<form onSubmit={handleSubmit}>
<div>
<div className="mt-3 text-center sm:mt-5">
<Dialog.Title
as="h3"
className="text-lg leading-6 font-medium text-gray-900"
>
Change Password
</Dialog.Title>
<div className="mt-2">
<input
id="password"
name="password"
type="password"
autoComplete="current-password"
required
className="block w-full px-3 py-2 placeholder-gray-400 border border-gray-300 rounded-md shadow-sm appearance-none focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
tabIndex={2}
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
/>
</div>
</div>
</div>
<div className="mt-5 sm:mt-6">
<button
type="submit"
className="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:text-sm"
>
Set new password
</button>
</div>
</form>
</div>
</div>
<div className="mt-5 sm:mt-6">
<button
type="submit"
className="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:text-sm"
>
Set new password
</button>
</div>
</form>
</Transition.Child>
</div>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
);
</Dialog>
</Transition.Root>
)
}

View File

@@ -1,18 +1,18 @@
import { useNhostAuth } from "@nhost/react-auth";
import React from "react";
import { Navigate, useLocation } from "react-router";
import { useNhostAuth } from '@nhost/react'
import React from 'react'
import { Navigate, useLocation } from 'react-router'
export function RequireAuth({ children }: { children: JSX.Element }) {
const { isAuthenticated, isLoading } = useNhostAuth();
const location = useLocation();
const { isAuthenticated, isLoading } = useNhostAuth()
const location = useLocation()
if (isLoading) {
return <div>Loading user data...</div>;
return <div>Loading user data...</div>
}
if (!isAuthenticated) {
return <Navigate to="/sign-in" state={{ from: location }} />;
return <Navigate to="/sign-in" state={{ from: location }} />
}
return children;
return children
}

View File

@@ -1,29 +1,29 @@
import { useNhostAuth } from "@nhost/react-auth";
import { useState } from "react";
import { useNavigate } from "react-router";
import { nhost } from "../utils/nhost";
import { useNhostAuth } from '@nhost/react'
import { useState } from 'react'
import { useNavigate } from 'react-router'
import { nhost } from '../utils/nhost'
export function ResetPassword() {
const [email, setEmail] = useState("");
const [email, setEmail] = useState('')
const { isAuthenticated } = useNhostAuth();
const { isAuthenticated } = useNhostAuth()
let navigate = useNavigate();
let navigate = useNavigate()
const handleSubmit = async (e: React.SyntheticEvent<HTMLFormElement>) => {
e.preventDefault();
e.preventDefault()
const { error } = await nhost.auth.resetPassword({ email });
const { error } = await nhost.auth.resetPassword({ email })
if (error) {
return alert(error.message);
return alert(error.message)
}
alert("Check out email inbox");
};
alert('Check out email inbox')
}
if (isAuthenticated) {
navigate("/");
navigate('/')
}
return (
@@ -33,19 +33,14 @@ export function ResetPassword() {
<div className="flex justify-center">
<div className="text-2xl font-bold text-blue-700">AquaSystem</div>
</div>
<h2 className="mt-6 text-3xl font-extrabold text-center text-gray-900">
Reset Password
</h2>
<h2 className="mt-6 text-3xl font-extrabold text-center text-gray-900">Reset Password</h2>
</div>
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div className="px-4 py-8 bg-white shadow sm:rounded-lg sm:px-10">
<form className="space-y-6" onSubmit={handleSubmit}>
<div>
<label
htmlFor="email"
className="block text-sm font-medium text-gray-700"
>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email address
</label>
<div className="mt-1">
@@ -77,5 +72,5 @@ export function ResetPassword() {
</div>
</div>
</>
);
)
}

View File

@@ -1,31 +1,31 @@
import { useNhostAuth } from "@nhost/react-auth";
import { useState } from "react";
import { useNavigate } from "react-router";
import { Link } from "react-router-dom";
import { nhost } from "../utils/nhost";
import { useNhostAuth } from '@nhost/react'
import { useState } from 'react'
import { useNavigate } from 'react-router'
import { Link } from 'react-router-dom'
import { nhost } from '../utils/nhost'
export function SignIn() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const { isAuthenticated } = useNhostAuth();
const { isAuthenticated } = useNhostAuth()
let navigate = useNavigate();
let navigate = useNavigate()
const handleSubmit = async (e: React.SyntheticEvent<HTMLFormElement>) => {
e.preventDefault();
e.preventDefault()
const { error } = await nhost.auth.signIn({ email, password });
const { error } = await nhost.auth.signIn({ email, password })
if (error) {
return alert(error.message);
return alert(error.message)
}
navigate("/", { replace: true });
};
navigate('/', { replace: true })
}
if (isAuthenticated) {
navigate("/");
navigate('/')
}
return (
@@ -44,10 +44,7 @@ export function SignIn() {
<div className="px-4 py-8 bg-white shadow sm:rounded-lg sm:px-10">
<form className="space-y-6" onSubmit={handleSubmit}>
<div>
<label
htmlFor="email"
className="block text-sm font-medium text-gray-700"
>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email address
</label>
<div className="mt-1">
@@ -66,10 +63,7 @@ export function SignIn() {
</div>
<div>
<label
htmlFor="password"
className="block text-sm font-medium text-gray-700"
>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
Password
</label>
<div className="mt-1">
@@ -110,7 +104,7 @@ export function SignIn() {
</form>
</div>
<div className="text-center py-4">
Don't have an account?{" "}
Don't have an account?{' '}
<Link to="/sign-up" className="text-blue-600 hover:text-blue-500">
Sign Up
</Link>
@@ -118,5 +112,5 @@ export function SignIn() {
</div>
</div>
</>
);
)
}

View File

@@ -1,31 +1,31 @@
import { useNhostAuth } from "@nhost/react-auth";
import { useState } from "react";
import { useNavigate } from "react-router";
import { Link } from "react-router-dom";
import { nhost } from "../utils/nhost";
import { useNhostAuth } from '@nhost/react'
import { useState } from 'react'
import { useNavigate } from 'react-router'
import { Link } from 'react-router-dom'
import { nhost } from '../utils/nhost'
export function SignUp() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const { isAuthenticated } = useNhostAuth();
const { isAuthenticated } = useNhostAuth()
let navigate = useNavigate();
let navigate = useNavigate()
const handleSubmit = async (e: React.SyntheticEvent<HTMLFormElement>) => {
e.preventDefault();
e.preventDefault()
const { error } = await nhost.auth.signUp({ email, password });
const { error } = await nhost.auth.signUp({ email, password })
if (error) {
return alert(error.message);
return alert(error.message)
}
navigate("/", { replace: true });
};
navigate('/', { replace: true })
}
if (isAuthenticated) {
navigate("/");
navigate('/')
}
return (
@@ -44,10 +44,7 @@ export function SignUp() {
<div className="px-4 py-8 bg-white shadow sm:rounded-lg sm:px-10">
<form className="space-y-6" onSubmit={handleSubmit}>
<div>
<label
htmlFor="email"
className="block text-sm font-medium text-gray-700"
>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email address
</label>
<div className="mt-1">
@@ -66,10 +63,7 @@ export function SignUp() {
</div>
<div>
<label
htmlFor="password"
className="block text-sm font-medium text-gray-700"
>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
Password
</label>
<div className="mt-1">
@@ -100,7 +94,7 @@ export function SignUp() {
</div>
<div className="text-center py-4">
Already have an account?{" "}
Already have an account?{' '}
<Link to="/sign-in" className="text-blue-600 hover:text-blue-500">
Sign In
</Link>
@@ -108,5 +102,5 @@ export function SignUp() {
</div>
</div>
</>
);
)
}

View File

@@ -1,55 +1,51 @@
import React, { Fragment, useEffect, useState } from "react";
import { Dialog, Menu, Transition } from "@headlessui/react";
import React, { Fragment, useEffect, useState } from 'react'
import { Dialog, Menu, Transition } from '@headlessui/react'
import {
FolderIcon,
HomeIcon,
InboxIcon,
MenuAlt2Icon,
UsersIcon,
XIcon,
} from "@heroicons/react/outline";
import { SearchIcon } from "@heroicons/react/solid";
import { NavLink, Outlet } from "react-router-dom";
import { nhost } from "../../utils/nhost";
import { ChangePasswordModal } from "../ChangePasswordModal";
XIcon
} from '@heroicons/react/outline'
import { SearchIcon } from '@heroicons/react/solid'
import { NavLink, Outlet } from 'react-router-dom'
import { nhost } from '../../utils/nhost'
import { ChangePasswordModal } from '../ChangePasswordModal'
const navigation = [
{ name: "Dashboard", href: "/", icon: HomeIcon, current: true },
{ name: "Orders", href: "/orders", icon: UsersIcon, current: false },
{ name: "Customers", href: "/customers", icon: FolderIcon, current: false },
{ name: "Settings", href: "/settings", icon: InboxIcon, current: false },
];
{ name: 'Dashboard', href: '/', icon: HomeIcon, current: true },
{ name: 'Orders', href: '/orders', icon: UsersIcon, current: false },
{ name: 'Customers', href: '/customers', icon: FolderIcon, current: false },
{ name: 'Settings', href: '/settings', icon: InboxIcon, current: false }
]
function classNames(...classes: string[]) {
return classes.filter(Boolean).join(" ");
return classes.filter(Boolean).join(' ')
}
export function Layout() {
const [sidebarOpen, setSidebarOpen] = useState(false);
const [showChangePasswordModal, setShowChangePasswordModal] = useState(false);
const [sidebarOpen, setSidebarOpen] = useState(false)
const [showChangePasswordModal, setShowChangePasswordModal] = useState(false)
console.log("Layout Reload");
console.log('Layout Reload')
useEffect(() => {
console.log("useEffect RUN");
console.log('useEffect RUN')
if (window.location.hash.search("type=passwordReset") !== -1) {
console.log("FOUND!");
if (window.location.hash.search('type=passwordReset') !== -1) {
console.log('FOUND!')
setShowChangePasswordModal(true);
setShowChangePasswordModal(true)
}
}, []);
}, [])
return (
<>
{showChangePasswordModal && <ChangePasswordModal />}
<div>
<Transition.Root show={sidebarOpen} as={Fragment}>
<Dialog
as="div"
className="fixed inset-0 z-40 flex md:hidden"
onClose={setSidebarOpen}
>
<Dialog as="div" className="fixed inset-0 z-40 flex md:hidden" onClose={setSidebarOpen}>
<Transition.Child
as={Fragment}
enter="transition-opacity ease-linear duration-300"
@@ -87,10 +83,7 @@ export function Layout() {
onClick={() => setSidebarOpen(false)}
>
<span className="sr-only">Close sidebar</span>
<XIcon
className="w-6 h-6 text-white"
aria-hidden="true"
/>
<XIcon className="w-6 h-6 text-white" aria-hidden="true" />
</button>
</div>
</Transition.Child>
@@ -109,11 +102,9 @@ export function Layout() {
to={item.href}
className={({ isActive }) => {
return classNames(
isActive
? "bg-blue-800 text-white"
: "text-blue-100 hover:bg-blue-600",
"group flex items-center px-2 py-2 text-base font-medium rounded-md"
);
isActive ? 'bg-blue-800 text-white' : 'text-blue-100 hover:bg-blue-600',
'group flex items-center px-2 py-2 text-base font-medium rounded-md'
)
}}
>
<item.icon
@@ -138,9 +129,7 @@ export function Layout() {
{/* Sidebar component, swap this element with another sidebar if you like */}
<div className="flex flex-col flex-grow pt-5 overflow-y-auto bg-blue-700">
<div className="flex items-center flex-shrink-0 px-4">
<span className="text-lg font-semibold text-white">
AquaSystem
</span>
<span className="text-lg font-semibold text-white">AquaSystem</span>
</div>
<div className="flex flex-col flex-1 mt-5">
<nav className="flex-1 px-2 pb-4 space-y-1">
@@ -150,11 +139,9 @@ export function Layout() {
to={item.href}
className={({ isActive }) => {
return classNames(
isActive
? "bg-blue-800 text-white"
: "text-blue-100 hover:bg-blue-600",
"group flex items-center px-2 py-2 text-sm font-medium rounded-md"
);
isActive ? 'bg-blue-800 text-white' : 'text-blue-100 hover:bg-blue-600',
'group flex items-center px-2 py-2 text-sm font-medium rounded-md'
)
}}
>
<item.icon
@@ -234,11 +221,11 @@ export function Layout() {
<div
// to={"/login"}
onClick={async () => {
await nhost.auth.signOut();
await nhost.auth.signOut()
}}
className={classNames(
active ? "bg-gray-100" : "",
"block px-4 py-2 text-sm text-gray-700"
active ? 'bg-gray-100' : '',
'block px-4 py-2 text-sm text-gray-700'
)}
>
Sign out
@@ -260,5 +247,5 @@ export function Layout() {
</div>
</div>
</>
);
)
}

View File

@@ -1,7 +1,7 @@
import { NhostClient } from "@nhost/nhost-js";
import { NhostClient } from '@nhost/react'
const nhost = new NhostClient({
backendUrl: process.env.REACT_APP_BACKEND_URL!,
});
backendUrl: process.env.REACT_APP_BACKEND_URL!
})
export { nhost };
export { nhost }

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,11 @@
{
"name": "@nhost-examples/react-apollo",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"dependencies": {
"@nhost/react": "^0.2.0",
"@nhost/react-apollo": "^3.0.0",
"@apollo/client": "^3.5.10",
"@nhost/react": "^0.3.0",
"@nhost/react-apollo": "^4.0.0",
"@rsuite/icons": "^1.0.2",
"jwt-decode": "^3.1.2",
"react": "^17.0.2",
@@ -14,7 +15,6 @@
"react-router-dom": "^6.2.1",
"rsuite": "^5.6.2"
},
"lib": "workspace:*",
"scripts": {
"dev": "vite",
"build": "vite build",

View File

@@ -1,9 +1,8 @@
import { Navigate, useLocation } from 'react-router-dom'
import { useAuthenticated, useAuthLoading } from '@nhost/react'
import { useAuthenticationStatus } from '@nhost/react'
export const AuthGate: React.FC = ({ children }) => {
const isAuthenticated = useAuthenticated()
const isLoading = useAuthLoading()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
const location = useLocation()
if (isLoading) {
return <div>Loading...</div>
@@ -17,8 +16,7 @@ export const AuthGate: React.FC = ({ children }) => {
}
export const PublicGate: React.FC = ({ children }) => {
const isAuthenticated = useAuthenticated()
const isLoading = useAuthLoading()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
const location = useLocation()
if (isLoading) {
return <div>Loading...</div>

File diff suppressed because it is too large Load Diff

View File

@@ -53,13 +53,13 @@
"@apollo/client": "^3.5.8"
},
"dependencies": {
"@nhost/core": "workspace:*",
"@nhost/core": "workspace:^",
"graphql": "16",
"subscriptions-transport-ws": "^0.11.0"
},
"devDependencies": {
"@apollo/client": "^3.5.8",
"xstate": "^4.30.5",
"@nhost/nhost-js": "workspace:*"
"@nhost/nhost-js": "workspace:^"
}
}

View File

@@ -1,5 +1,12 @@
# @nhost/hasura-auth-js
## 1.0.1
### Patch Changes
- ab36f90: Correct access to user/session information through getUser/getSession/isReady function when authentication state is not ready yet
In some cases e.g. NextJS build, `auth.getUser()`, `auth.getSession()` or `auth.isReady()` should be accessible without raising an error.
## 1.0.0
### Major Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/hasura-auth-js",
"version": "1.0.0",
"version": "1.0.1",
"description": "Hasura-auth client",
"license": "MIT",
"keywords": [
@@ -51,7 +51,7 @@
"dist"
],
"dependencies": {
"@nhost/core": "workspace:*"
"@nhost/core": "workspace:^"
},
"devDependencies": {
"@types/faker": "5",

View File

@@ -598,7 +598,7 @@ export class HasuraAuthClient {
* @docs https://docs.nhost.io/TODO
*/
getSession() {
return getSession(this.#client.interpreter?.state.context)
return getSession(this.#client.interpreter?.state?.context)
}
/**
@@ -612,11 +612,11 @@ export class HasuraAuthClient {
* @docs https://docs.nhost.io/reference/sdk/authentication#nhost-auth-getuser
*/
getUser() {
return this.#client.interpreter?.state.context?.user || null
return this.#client.interpreter?.state?.context?.user || null
}
private isReady() {
return !!this.#client.interpreter?.state.hasTag('ready')
return !!this.#client.interpreter?.state?.hasTag('ready')
}
get client() {

View File

@@ -1,5 +1,19 @@
# @nhost/nextjs
## 1.0.2
### Patch Changes
- Updated dependencies [39df4d5]
- @nhost/react@0.4.0
## 1.0.1
### Patch Changes
- @nhost/nhost-js@1.0.1
- @nhost/react@0.3.1
## 1.0.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/nextjs",
"version": "1.0.0",
"version": "1.0.2",
"description": "Nhost NextJS library",
"license": "MIT",
"keywords": [
@@ -50,18 +50,18 @@
"dist"
],
"dependencies": {
"@nhost/nhost-js": "workspace:*",
"@nhost/nhost-js": "workspace:^",
"cookies": "^0.8.0"
},
"peerDependencies": {
"@nhost/react": "workspace:*",
"@nhost/react": "workspace:^",
"next": "^12.0.10",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
},
"devDependencies": {
"@nhost/core": "workspace:*",
"@nhost/react": "workspace:*",
"@nhost/core": "workspace:^",
"@nhost/react": "workspace:^",
"next": "12.0.10",
"react": "^17.0.2",
"react-dom": "^17.0.2",

View File

@@ -1,5 +1,12 @@
# @nhost/nhost-js
## 1.0.1
### Patch Changes
- Updated dependencies [ab36f90]
- @nhost/hasura-auth-js@1.0.1
## 1.0.0
### Major Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/nhost-js",
"version": "1.0.0",
"version": "1.0.1",
"description": "Nhost JavaScript SDK",
"license": "MIT",
"keywords": [
@@ -52,13 +52,13 @@
"verify:fix": "run-p prettier:fix lint:fix"
},
"dependencies": {
"@nhost/hasura-auth-js": "workspace:*",
"@nhost/hasura-storage-js": "workspace:*",
"@nhost/hasura-auth-js": "workspace:^",
"@nhost/hasura-storage-js": "workspace:^",
"axios": "^0.23.0",
"jwt-decode": "^3.1.2",
"query-string": "^7.0.1"
},
"devDependencies": {
"@nhost/core": "workspace:*"
"@nhost/core": "workspace:^"
}
}

View File

@@ -1,5 +1,19 @@
# @nhost/react-apollo
## 4.0.2
### Patch Changes
- Updated dependencies [39df4d5]
- @nhost/react@0.4.0
## 4.0.1
### Patch Changes
- @nhost/react@0.3.1
- @nhost/apollo@0.3.0
## 4.0.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/react-apollo",
"version": "4.0.0",
"version": "4.0.2",
"description": "Nhost React Apollo client",
"license": "MIT",
"keywords": [
@@ -49,19 +49,19 @@
"dist"
],
"dependencies": {
"@nhost/apollo": "workspace:*"
"@nhost/apollo": "workspace:^"
},
"peerDependencies": {
"@apollo/client": "^3.5.8",
"@nhost/react": "workspace:*",
"@nhost/react": "workspace:^",
"graphql": "^16.0.0",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
},
"devDependencies": {
"@apollo/client": "^3.5.8",
"@nhost/core": "workspace:*",
"@nhost/react": "workspace:*",
"@nhost/core": "workspace:^",
"@nhost/react": "workspace:^",
"@types/react": "^17.0.39",
"@types/ws": "^8.2.2",
"graphql": "16",

View File

@@ -1,12 +1,11 @@
# ⚠️ This package is deprecated
Use the new [`@nhost/react`](https://github.com/nhost/nhost/tree/main/packages/react) package instead.
# Nhost React Auth
For easy usage of Auth with [Nhost](https://nhost.io).
## Deprecation notice
This package is deprecated. It is recommended to use `@nhost/react` instead.
If you want to continue to use it, don't forget to add `@nhost/react` to your packages as it is now a peer dependency.
## Install
`$ npm install @nhost/react-auth @nhost/react`

View File

@@ -53,8 +53,8 @@
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
},
"devDependencies": {
"@nhost/react": "workspace:*",
"@nhost/nhost-js": "workspace:*",
"@nhost/react": "workspace:^",
"@nhost/nhost-js": "workspace:^",
"@types/react": "^17.0.38",
"react": "^17.0.2",
"react-dom": "^17.0.2"

View File

@@ -1,5 +1,37 @@
# @nhost/react
## 0.4.0
### Minor Changes
- 39df4d5: Deprecate `useAuthLoading` and introduce `useAuthenticationStatus`
When using both `useAuthLoading` and `useAuthenticated` together, the hooks rerender independently from each other.
As a result, when a user loads the page while he previously authenticated, the hooks values were chronologically:
| isLoading | isAuthenticated |
| --------- | --------------- |
| `true` | `false` |
| `false` | `false` |
| `false` | `true` |
The intermediate (`false`, `false`) is incorrect and is causing issues when using an authentication gate.
It is therefore recommended to stop using `useAuthLoading`, and to use `useAuthenticationStatus` instead, in order to keep the loading state and the authentication in sync within the same hook.
Usage:
```js
const { isLoading, isAuthenticated } = useAuthenticationStatus()
```
Fixes [this issue](https://github.com/nhost/nhost/issues/302)
## 0.3.1
### Patch Changes
- @nhost/nhost-js@1.0.1
## 0.3.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/react",
"version": "0.3.0",
"version": "0.4.0",
"description": "Nhost React library",
"license": "MIT",
"keywords": [
@@ -48,13 +48,13 @@
"dist"
],
"dependencies": {
"@nhost/nhost-js": "workspace:*",
"@nhost/nhost-js": "workspace:^",
"@xstate/react": "^2.0.1",
"immer": "^9.0.12"
},
"devDependencies": {
"@nhost/hasura-auth-js": "workspace:*",
"@nhost/core": "workspace:*",
"@nhost/hasura-auth-js": "workspace:^",
"@nhost/core": "workspace:^",
"@xstate/inspect": "^0.6.2",
"react": "^17.0.2",
"ws": "^8.4.2",

View File

@@ -24,18 +24,24 @@ export const useNhostBackendUrl = () => {
return nhost.auth.client.backendUrl.replace('/v1/auth', '')
}
/**
* @deprecated When using both useAuthLoading and useAuthenticated together, their initial state will change three times: (true,false) -> (false,false) -> (false,true). Use useAuthenticationStatus instead.
*/
export const useAuthLoading = () => {
const service = useAuthInterpreter()
const [isLoading, setIsLoading] = useState(!service.status || !service?.state?.hasTag('ready'))
useEffect(() => {
const subscription = service.subscribe((state) => {
const newValue = !state.hasTag('ready')
setIsLoading(newValue)
})
return subscription.unsubscribe
}, [service])
return useSelector(service, (state) => !state.hasTag('ready'))
}
return isLoading
export const useAuthenticationStatus = () => {
const service = useAuthInterpreter()
return useSelector(
service,
(state) => ({
isAuthenticated: state.matches({ authentication: 'signedIn' }),
isLoading: !state.hasTag('ready')
}),
(a, b) => a.isAuthenticated === b.isAuthenticated && a.isLoading === b.isLoading
)
}
export const useAuthenticated = () => {

View File

@@ -1,14 +1,13 @@
import { useMemo } from 'react'
import { useAuthenticated, useAuthLoading } from './common'
import { useAuthenticationStatus } from './common'
import { useUserData } from './user'
/**
* @deprecated This hooks ensures backward compatibility with `@nhost/react-auth`, which is deprecated
* @deprecated This hook ensures backward compatibility with `@nhost/react-auth`, which is deprecated
*/
export const useNhostAuth = () => {
const isLoading = useAuthLoading()
const isAuthenticated = useAuthenticated()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
const user = useUserData()
return useMemo(() => ({ isLoading, isAuthenticated, user }), [isLoading, isAuthenticated, user])
}

View File

@@ -3,7 +3,7 @@ import { useMemo } from 'react'
import { SignUpOptions } from '@nhost/core'
import { useSelector } from '@xstate/react'
import { useAuthenticated, useAuthInterpreter, useAuthLoading } from './common'
import { useAuthenticationStatus, useAuthInterpreter } from './common'
export const useSignUpEmailPassword = (
stateEmail?: string,
@@ -18,8 +18,7 @@ export const useSignUpEmailPassword = (
(state) => state.context.errors.registration,
(a, b) => a?.error === b?.error
)
const loading = useAuthLoading()
const isSuccess = useAuthenticated()
const { isLoading: loading, isAuthenticated: isSuccess } = useAuthenticationStatus()
const isLoading = useMemo(() => loading && !isSuccess, [loading, isSuccess])
const needsEmailVerification =
!!service.status &&

34
pnpm-lock.yaml generated
View File

@@ -145,8 +145,8 @@ importers:
packages/apollo:
specifiers:
'@apollo/client': ^3.5.8
'@nhost/core': workspace:*
'@nhost/nhost-js': workspace:*
'@nhost/core': workspace:^
'@nhost/nhost-js': workspace:^
graphql: 15.7.2
subscriptions-transport-ws: ^0.11.0
xstate: ^4.30.5
@@ -173,7 +173,7 @@ importers:
packages/hasura-auth-js:
specifiers:
'@nhost/core': workspace:*
'@nhost/core': workspace:^
'@types/faker': '5'
axios: ^0.26.0
faker: '5'
@@ -198,9 +198,9 @@ importers:
packages/nextjs:
specifiers:
'@nhost/core': workspace:*
'@nhost/nhost-js': workspace:*
'@nhost/react': workspace:*
'@nhost/core': workspace:^
'@nhost/nhost-js': workspace:^
'@nhost/react': workspace:^
cookies: ^0.8.0
next: 12.0.10
react: ^17.0.2
@@ -219,9 +219,9 @@ importers:
packages/nhost-js:
specifiers:
'@nhost/core': workspace:*
'@nhost/hasura-auth-js': workspace:*
'@nhost/hasura-storage-js': workspace:*
'@nhost/core': workspace:^
'@nhost/hasura-auth-js': workspace:^
'@nhost/hasura-storage-js': workspace:^
axios: ^0.23.0
jwt-decode: ^3.1.2
query-string: ^7.0.1
@@ -236,9 +236,9 @@ importers:
packages/react:
specifiers:
'@nhost/core': workspace:*
'@nhost/hasura-auth-js': workspace:*
'@nhost/nhost-js': workspace:*
'@nhost/core': workspace:^
'@nhost/hasura-auth-js': workspace:^
'@nhost/nhost-js': workspace:^
'@xstate/inspect': ^0.6.2
'@xstate/react': ^2.0.1
immer: ^9.0.12
@@ -260,9 +260,9 @@ importers:
packages/react-apollo:
specifiers:
'@apollo/client': ^3.5.8
'@nhost/apollo': workspace:*
'@nhost/core': workspace:*
'@nhost/react': workspace:*
'@nhost/apollo': workspace:^
'@nhost/core': workspace:^
'@nhost/react': workspace:^
'@types/react': ^17.0.39
'@types/ws': ^8.2.2
graphql: 15.7.2
@@ -282,8 +282,8 @@ importers:
packages/react-auth:
specifiers:
'@nhost/nhost-js': workspace:*
'@nhost/react': workspace:*
'@nhost/nhost-js': workspace:^
'@nhost/react': workspace:^
'@types/react': ^17.0.38
react: ^17.0.2
react-dom: ^17.0.2