Compare commits

...

21 Commits

Author SHA1 Message Date
github-actions[bot]
82728da100 chore: update versions (#2556)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/apollo@6.0.7

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost/react-apollo@9.0.2

### Patch Changes

-   @nhost/apollo@6.0.7
-   @nhost/react@3.2.2

## @nhost/react-urql@6.0.2

### Patch Changes

-   @nhost/react@3.2.2

## @nhost/graphql-js@0.1.7

### Patch Changes

- 2d68fee: fix: resolve an issue where unauthenticated graphql requests
are not sent

## @nhost/nextjs@2.1.4

### Patch Changes

-   @nhost/react@3.2.2

## @nhost/nhost-js@3.0.7

### Patch Changes

-   Updated dependencies [2d68fee]
    -   @nhost/graphql-js@0.1.7

## @nhost/react@3.2.2

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost/vue@2.2.2

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost/dashboard@1.8.1

### Patch Changes

-   @nhost/react-apollo@9.0.2
-   @nhost/nextjs@2.1.4

## @nhost-examples/cli@0.1.8

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost-examples/codegen-react-apollo@0.1.16

### Patch Changes

-   @nhost/react@3.2.2
-   @nhost/react-apollo@9.0.2

## @nhost-examples/codegen-react-query@0.1.17

### Patch Changes

-   @nhost/react@3.2.2

## @nhost-examples/codegen-react-urql@0.0.13

### Patch Changes

-   @nhost/react@3.2.2
-   @nhost/react-urql@6.0.2

## @nhost-examples/multi-tenant-one-to-many@2.0.6

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost-examples/nextjs@0.1.18

### Patch Changes

-   @nhost/react@3.2.2
-   @nhost/react-apollo@9.0.2
-   @nhost/nextjs@2.1.4

## @nhost-examples/node-storage@0.0.10

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost-examples/nextjs-server-components@0.2.4

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost-examples/react-apollo@0.3.2

### Patch Changes

-   @nhost/react@3.2.2
-   @nhost/react-apollo@9.0.2

## @nhost-examples/react-gqty@1.0.6

### Patch Changes

-   @nhost/react@3.2.2

## @nhost-examples/vue-apollo@0.2.3

### Patch Changes

-   @nhost/nhost-js@3.0.7
-   @nhost/apollo@6.0.7
-   @nhost/vue@2.2.2

## @nhost-examples/vue-quickstart@0.0.15

### Patch Changes

-   @nhost/apollo@6.0.7
-   @nhost/vue@2.2.2

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-23 21:14:11 +01:00
Hassan Ben Jobrane
2d68fee54c fix(graphql-js): allow graphql requests with no access token (#2555) 2024-02-23 21:09:45 +01:00
github-actions[bot]
35010353c7 chore: update versions (#2547)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/apollo@6.0.6

### Patch Changes

-   e0ab6d9: fix: add extra logic to check and wait for a valid JWT
    -   @nhost/nhost-js@3.0.6

## @nhost/react-apollo@9.0.1

### Patch Changes

-   Updated dependencies [e0ab6d9]
    -   @nhost/apollo@6.0.6
    -   @nhost/react@3.2.1

## @nhost/react-urql@6.0.1

### Patch Changes

-   @nhost/react@3.2.1

## @nhost/graphql-js@0.1.6

### Patch Changes

-   e0ab6d9: fix: add extra logic to check and wait for a valid JWT

## @nhost/hasura-auth-js@2.3.1

### Patch Changes

- 7baee8a: fix(hasura-auth-js): replace `jwt-decode` with `jose` for
decoding access tokens that works on both the browser and Node.js
-   e0ab6d9: fix: add extra logic to check and wait for a valid JWT

## @nhost/nextjs@2.1.3

### Patch Changes

-   @nhost/react@3.2.1

## @nhost/nhost-js@3.0.6

### Patch Changes

-   Updated dependencies [7baee8a]
-   Updated dependencies [e0ab6d9]
    -   @nhost/hasura-auth-js@2.3.1
    -   @nhost/graphql-js@0.1.6

## @nhost/react@3.2.1

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost/vue@2.2.1

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost/dashboard@1.8.0

### Minor Changes

- 713d53c: feat: add catch-all route for workspace/project - useful for
documentation

### Patch Changes

-   3db2999: fix: refresh table list after running SQL using the editor
- 3c4dd55: fix: handle `Error` objects properly in the `ErrorToast`
component
- 92b434e: fix: resolve an issue where the checkbox in the data-grid
header did not select all rows
    -   @nhost/react-apollo@9.0.1
    -   @nhost/nextjs@2.1.3

## @nhost-examples/cli@0.1.7

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost-examples/codegen-react-apollo@0.1.15

### Patch Changes

-   @nhost/react-apollo@9.0.1
-   @nhost/react@3.2.1

## @nhost-examples/codegen-react-query@0.1.16

### Patch Changes

-   @nhost/react@3.2.1

## @nhost-examples/codegen-react-urql@0.0.12

### Patch Changes

-   @nhost/react@3.2.1
-   @nhost/react-urql@6.0.1

## @nhost-examples/docker-compose@0.1.1

### Patch Changes

-   aff059e: fix: timers

## @nhost-examples/multi-tenant-one-to-many@2.0.5

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost-examples/nextjs@0.1.17

### Patch Changes

-   @nhost/react-apollo@9.0.1
-   @nhost/react@3.2.1
-   @nhost/nextjs@2.1.3

## @nhost-examples/node-storage@0.0.9

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost-examples/nextjs-server-components@0.2.3

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost-examples/react-apollo@0.3.1

### Patch Changes

-   @nhost/react-apollo@9.0.1
-   @nhost/react@3.2.1

## @nhost-examples/react-gqty@1.0.5

### Patch Changes

-   @nhost/react@3.2.1

## @nhost-examples/vue-apollo@0.2.2

### Patch Changes

-   Updated dependencies [e0ab6d9]
    -   @nhost/apollo@6.0.6
    -   @nhost/nhost-js@3.0.6
    -   @nhost/vue@2.2.1

## @nhost-examples/vue-quickstart@0.0.14

### Patch Changes

-   Updated dependencies [e0ab6d9]
    -   @nhost/apollo@6.0.6
    -   @nhost/vue@2.2.1

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-23 10:07:53 +01:00
David Barroso
aff059ec71 fix (examples/docker-compose): timers (#2553) 2024-02-23 10:04:20 +01:00
Nuno Pato
713d53cfc0 feat: dashboard: add catch-all route (#2545) 2024-02-22 17:59:24 -01:00
Hassan Ben Jobrane
e0ab6d9a37 fix: JWT expired bug (#2533)
fixes: https://github.com/nhost/nhost/issues/2348

---------

Co-authored-by: David Barroso <dbarrosop@dravetech.com>
2024-02-22 18:44:43 +01:00
Hassan Ben Jobrane
7baee8a9cc fix(hasura-auth-js): use jose instead of jwt-decode to decode the accessToken and get the Hasura claims (#2550)
fixes https://github.com/nhost/nhost/issues/2513
2024-02-21 11:17:03 +01:00
Hassan Ben Jobrane
3db2999f60 fix(dashboard): refresh table list after running a SQL stmt using the editor (#2549)
fixes https://github.com/nhost/projects/issues/52
2024-02-20 13:40:46 +01:00
Hassan Ben Jobrane
3c4dd55045 fix(dashboard): handle Error alongside ApolloError properly in the ErrorToast component (#2548)
fixes https://github.com/nhost/nhost/issues/2525
2024-02-20 12:16:26 +01:00
Hassan Ben Jobrane
92b434e840 fix: refactor DataGridHeader component to allow for selecting all rows (#2546)
fixes https://github.com/nhost/nhost/issues/2526
2024-02-19 17:30:59 +01:00
github-actions[bot]
13d359602f chore: update versions (#2540)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/dashboard@1.7.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

## @nhost/docs@2.5.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

### Patch Changes

-   41617b9: feat: added elevated permissions docs
- 7db095f: chore: added a note about disk performance and CDN
information

## @nhost-examples/docker-compose@0.1.0

### Minor Changes

-   ed9df85: updated docker-compose.yaml and .env-example

## @nhost-examples/vue-apollo@0.2.1

### Patch Changes

-   c5c904b: fix: update signin methods settings

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-16 20:44:28 -01:00
Nuno Pato
0d8d0eb10f chore: update docs and fix dashboard references (#2543) 2024-02-16 18:21:30 -01:00
Seth Deegan
ed9df85778 Update docker-compose and .env-example (#2397)
The docker-compose example is severely outdated and the past
configuration used a docker image for the dashboard that did not allow
you to configure the URLs to the various API endpoints if you
self-hosted your own dashboard publicly.

The newest dashboard image allows you to do this so the docker-compose
has been updated to use this image and the env variables have been
updated accordingly.

Other variables have been updated in the docker-compose to support
self-hosting a public instance.

A commented traefik configuration in the docker-compose for the
dashboard service also allows the user to configure basic auth to
protect a publicly-facing dashboard.

---------

Co-authored-by: David Barroso <dbarrosop@dravetech.com>
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-02-16 08:52:58 +01:00
David Barroso
41617b970a feat (docs): added elevated permissions docs (#2519)
Co-authored-by: Nuno Pato <nunopato@gmail.com>
2024-02-15 16:00:44 +01:00
Hassan Ben Jobrane
c5c904b716 fix(vue-apollo): update signin methods settings (#2541) 2024-02-15 13:48:41 +01:00
David Barroso
7db095fe92 chore: docs: added a note about disk performance and CDN information (#2539)
Fixes #2504
2024-02-15 11:47:33 +01:00
github-actions[bot]
f33e07b191 chore: update versions (#2538)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/hasura-auth-js@2.3.0

### Minor Changes

-   017f1a6: feat: add elevated permission examples

## @nhost/react@3.2.0

### Minor Changes

-   017f1a6: feat: add elevated permission examples

### Patch Changes

-   @nhost/nhost-js@3.0.5

## @nhost/vue@2.2.0

### Minor Changes

-   017f1a6: feat: add elevated permission examples

### Patch Changes

-   @nhost/nhost-js@3.0.5

## @nhost/apollo@6.0.5

### Patch Changes

-   @nhost/nhost-js@3.0.5

## @nhost/react-apollo@9.0.0

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0
    -   @nhost/apollo@6.0.5

## @nhost/react-urql@6.0.0

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0

## @nhost/nextjs@2.1.2

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0

## @nhost/nhost-js@3.0.5

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/hasura-auth-js@2.3.0

## @nhost-examples/react-apollo@0.3.0

### Minor Changes

-   017f1a6: feat: add elevated permission examples

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0
    -   @nhost/react-apollo@9.0.0

## @nhost-examples/vue-apollo@0.2.0

### Minor Changes

-   017f1a6: feat: add elevated permission examples

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/vue@2.2.0
    -   @nhost/nhost-js@3.0.5
    -   @nhost/apollo@6.0.5

## @nhost/dashboard@1.6.9

### Patch Changes

-   @nhost/react-apollo@9.0.0
-   @nhost/nextjs@2.1.2

## @nhost-examples/cli@0.1.6

### Patch Changes

-   @nhost/nhost-js@3.0.5

## @nhost-examples/codegen-react-apollo@0.1.14

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0
    -   @nhost/react-apollo@9.0.0

## @nhost-examples/codegen-react-query@0.1.15

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0

## @nhost-examples/codegen-react-urql@0.0.11

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0
    -   @nhost/react-urql@6.0.0

## @nhost-examples/multi-tenant-one-to-many@2.0.4

### Patch Changes

-   @nhost/nhost-js@3.0.5

## @nhost-examples/nextjs@0.1.16

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0
    -   @nhost/react-apollo@9.0.0
    -   @nhost/nextjs@2.1.2

## @nhost-examples/node-storage@0.0.8

### Patch Changes

-   @nhost/nhost-js@3.0.5

## @nhost-examples/nextjs-server-components@0.2.2

### Patch Changes

-   @nhost/nhost-js@3.0.5

## @nhost-examples/react-gqty@1.0.4

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/react@3.2.0

## @nhost-examples/vue-quickstart@0.0.13

### Patch Changes

-   Updated dependencies [017f1a6]
    -   @nhost/vue@2.2.0
    -   @nhost/apollo@6.0.5

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-14 15:12:34 +01:00
Hassan Ben Jobrane
017f1a6c7b feat: add elevate workflow to react-apollo and vue-apollo example projects (#2521)
part-2 of https://github.com/nhost/nhost/issues/2394

---------

Co-authored-by: David Barroso <dbarrosop@dravetech.com>
2024-02-14 14:52:43 +01:00
github-actions[bot]
93957c8af3 chore: update versions (#2537)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/hasura-storage-js@2.4.0

### Minor Changes

-   2505b2e: fix: fix headers sent with getPresignedUrl

## @nhost/apollo@6.0.4

### Patch Changes

-   @nhost/nhost-js@3.0.4

## @nhost/react-apollo@8.0.1

### Patch Changes

-   @nhost/apollo@6.0.4
-   @nhost/react@3.1.1

## @nhost/react-urql@5.0.1

### Patch Changes

-   @nhost/react@3.1.1

## @nhost/nextjs@2.1.1

### Patch Changes

-   @nhost/react@3.1.1

## @nhost/nhost-js@3.0.4

### Patch Changes

-   Updated dependencies [2505b2e]
    -   @nhost/hasura-storage-js@2.4.0

## @nhost/react@3.1.1

### Patch Changes

-   @nhost/nhost-js@3.0.4

## @nhost/vue@2.1.1

### Patch Changes

-   @nhost/nhost-js@3.0.4

## @nhost/dashboard@1.6.8

### Patch Changes

-   @nhost/react-apollo@8.0.1
-   @nhost/nextjs@2.1.1

## @nhost-examples/cli@0.1.5

### Patch Changes

-   @nhost/nhost-js@3.0.4

## @nhost-examples/codegen-react-apollo@0.1.13

### Patch Changes

-   @nhost/react@3.1.1
-   @nhost/react-apollo@8.0.1

## @nhost-examples/codegen-react-query@0.1.14

### Patch Changes

-   @nhost/react@3.1.1

## @nhost-examples/codegen-react-urql@0.0.10

### Patch Changes

-   @nhost/react@3.1.1
-   @nhost/react-urql@5.0.1

## @nhost-examples/multi-tenant-one-to-many@2.0.3

### Patch Changes

-   @nhost/nhost-js@3.0.4

## @nhost-examples/nextjs@0.1.15

### Patch Changes

-   @nhost/react@3.1.1
-   @nhost/react-apollo@8.0.1
-   @nhost/nextjs@2.1.1

## @nhost-examples/node-storage@0.0.7

### Patch Changes

-   @nhost/nhost-js@3.0.4

## @nhost-examples/nextjs-server-components@0.2.1

### Patch Changes

-   @nhost/nhost-js@3.0.4

## @nhost-examples/react-apollo@0.2.1

### Patch Changes

-   @nhost/react@3.1.1
-   @nhost/react-apollo@8.0.1

## @nhost-examples/react-gqty@1.0.3

### Patch Changes

-   @nhost/react@3.1.1

## @nhost-examples/vue-apollo@0.1.1

### Patch Changes

-   @nhost/nhost-js@3.0.4
-   @nhost/apollo@6.0.4
-   @nhost/vue@2.1.1

## @nhost-examples/vue-quickstart@0.0.12

### Patch Changes

-   @nhost/apollo@6.0.4
-   @nhost/vue@2.1.1

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-14 10:29:57 +01:00
Nuno Pato
2505b2e26b fix: fix headers sent with getPresignedUrl (#2535) 2024-02-13 23:33:09 -01:00
Nuno Pato
5f4b4d2acc chore: update dependencies (#2536)
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-02-13 20:29:47 -01:00
167 changed files with 3765 additions and 2168 deletions

View File

@@ -1,5 +1,46 @@
# @nhost/dashboard
## 1.8.1
### Patch Changes
- @nhost/react-apollo@9.0.2
- @nhost/nextjs@2.1.4
## 1.8.0
### Minor Changes
- 713d53c: feat: add catch-all route for workspace/project - useful for documentation
### Patch Changes
- 3db2999: fix: refresh table list after running SQL using the editor
- 3c4dd55: fix: handle `Error` objects properly in the `ErrorToast` component
- 92b434e: fix: resolve an issue where the checkbox in the data-grid header did not select all rows
- @nhost/react-apollo@9.0.1
- @nhost/nextjs@2.1.3
## 1.7.0
### Minor Changes
- 0d8d0eb: Update docs and dashboard references
## 1.6.9
### Patch Changes
- @nhost/react-apollo@9.0.0
- @nhost/nextjs@2.1.2
## 1.6.8
### Patch Changes
- @nhost/react-apollo@8.0.1
- @nhost/nextjs@2.1.1
## 1.6.7
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/dashboard",
"version": "1.6.7",
"version": "1.8.1",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
@@ -106,7 +106,7 @@
"@storybook/addon-postcss": "^2.0.0",
"@storybook/builder-webpack5": "^6.5.16",
"@storybook/manager-webpack5": "^6.5.16",
"@storybook/react": "^6.5.16",
"@storybook/react": "^7.6.15",
"@storybook/testing-library": "^0.2.2",
"@tailwindcss/typography": "^0.5.10",
"@testing-library/dom": "^9.3.4",

View File

@@ -96,45 +96,52 @@ export default function DataGridHeader<T extends object>({
}}
key={column.id}
>
<Dropdown.Trigger
className={twMerge(
'focus:outline-none motion-safe:transition-colors',
)}
disabled={
column.isDisabled ||
column.id === 'selection' ||
(column.disableSortBy && !onRemoveColumn)
}
hideChevron
>
{column.id === 'selection' ? (
<span
{...headerProps}
className="relative grid w-full grid-flow-col items-center justify-between p-2"
>
{column.render('Header')}
{allowSort && (
<Box component="span" sx={{ color: 'text.primary' }}>
{column.isSorted && !column.isSortedDesc && (
<ArrowUpIcon className="h-3 w-3" />
)}
{column.isSorted && column.isSortedDesc && (
<ArrowDownIcon className="h-3 w-3" />
)}
</Box>
)}
</span>
{allowResize && !column.disableResizing && (
) : (
<Dropdown.Trigger
className={twMerge(
'focus:outline-none motion-safe:transition-colors',
)}
disabled={
column.isDisabled || (column.disableSortBy && !onRemoveColumn)
}
hideChevron
>
<span
{...column.getResizerProps({
onClick: (event: Event) => event.stopPropagation(),
})}
className="absolute top-0 bottom-0 -right-0.5 z-10 h-full w-1.5 group-hover:bg-slate-900 group-hover:bg-opacity-20 group-active:bg-slate-900 group-active:bg-opacity-20 motion-safe:transition-colors"
/>
)}
</Dropdown.Trigger>
{...headerProps}
className="relative grid w-full grid-flow-col items-center justify-between p-2"
>
{column.render('Header')}
{allowSort && (
<Box component="span" sx={{ color: 'text.primary' }}>
{column.isSorted && !column.isSortedDesc && (
<ArrowUpIcon className="h-3 w-3" />
)}
{column.isSorted && column.isSortedDesc && (
<ArrowDownIcon className="h-3 w-3" />
)}
</Box>
)}
</span>
{allowResize && !column.disableResizing && (
<span
{...column.getResizerProps({
onClick: (event: Event) => event.stopPropagation(),
})}
className="absolute -right-0.5 bottom-0 top-0 z-10 h-full w-1.5 group-hover:bg-slate-900 group-hover:bg-opacity-20 group-active:bg-slate-900 group-active:bg-opacity-20 motion-safe:transition-colors"
/>
)}
</Dropdown.Trigger>
)}
<Dropdown.Content
menu

View File

@@ -5,7 +5,7 @@ import { XIcon } from '@/components/ui/v2/icons/XIcon';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { getToastBackgroundColor } from '@/utils/constants/settings';
import { copy } from '@/utils/copy';
import { type ApolloError } from '@apollo/client';
import { ApolloError } from '@apollo/client';
import { useUserData } from '@nhost/nextjs';
import { AnimatePresence, motion } from 'framer-motion';
import { useRouter } from 'next/router';
@@ -20,6 +20,43 @@ interface ErrorDetails {
error: any;
}
const getInternalErrorMessage = (
error: Error | ApolloError | undefined,
): string | null => {
if (!error) {
return null;
}
if (error instanceof ApolloError) {
const internalError = error.graphQLErrors?.[0]?.extensions?.internal as
| { error: { message: string } }
| undefined;
return internalError?.error?.message || null;
}
if (error instanceof Error) {
return error.message;
}
return null;
};
const errorToObject = (error: ApolloError | Error) => {
if (error instanceof ApolloError) {
return error;
}
if (error instanceof Error) {
return {
name: error.name,
message: error.message,
stack: error.stack,
};
}
return {};
};
export default function ErrorToast({
isVisible,
errorMessage,
@@ -28,7 +65,7 @@ export default function ErrorToast({
}: {
isVisible: boolean;
errorMessage: string;
error: ApolloError;
error: ApolloError | Error;
close: () => void;
}) {
const userData = useUserData();
@@ -43,19 +80,10 @@ export default function ErrorToast({
userId: userData?.id || 'local',
url: asPath,
},
error,
error: errorToObject(error),
};
const internalError = error?.graphQLErrors?.at(0)?.extensions?.internal as {
error: {
message: string;
};
};
const msg =
internalError?.error?.message ||
error?.graphQLErrors?.at(0).message ||
errorMessage;
const msg = getInternalErrorMessage(error) || errorMessage;
return (
<AnimatePresence>

View File

@@ -130,7 +130,7 @@ export default function AllowedEmailDomainsSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#allowed-emails-and-domains"
docsLink="https://docs.nhost.io/guides/auth/overview#allowed-emails-and-domains"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -105,7 +105,7 @@ export default function AllowedRedirectURLsSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#allowed-redirect-urls"
docsLink="https://docs.nhost.io/guides/auth/overview#allowed-redirect-urls"
className="grid grid-flow-row px-4 lg:grid-cols-5"
>
<Input

View File

@@ -141,7 +141,7 @@ export default function AppleProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication/sign-in-with-apple"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-apple"
docsTitle="how to sign in users with Apple"
icon={
theme.palette.mode === 'dark'

View File

@@ -136,7 +136,7 @@ export default function BlockedEmailSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#blocked-emails-and-domains"
docsLink="https://docs.nhost.io/guides/auth/overview#allowed-emails-and-domains"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -99,7 +99,7 @@ export default function ClientURLSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#client-url"
docsLink="https://docs.nhost.io/guides/auth/overview#client-url"
className="grid grid-flow-row lg:grid-cols-5"
>
<Input

View File

@@ -89,7 +89,7 @@ export default function DisableNewUsersSettings() {
<SettingsContainer
title="Disable New Users"
description="If set, newly registered users are disabled and won't be able to sign in."
docsLink="https://docs.nhost.io/authentication#disable-new-users"
docsLink="https://docs.nhost.io/guides/auth/overview#disable-new-users"
switchId="disabled"
showSwitch
slotProps={{

View File

@@ -111,7 +111,7 @@ export default function DiscordProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-discord"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-discord"
docsTitle="how to sign in users with Discord"
icon="/assets/brands/discord.svg"
switchId="enabled"

View File

@@ -104,7 +104,7 @@ export default function EmailAndPasswordSettings() {
<SettingsContainer
title="Email and Password"
description="Allow users to sign in with email and password."
docsLink="https://docs.nhost.io/authentication/sign-in-with-email-and-password"
docsLink="https://docs.nhost.io/guides/auth/sign-in-email-password"
docsTitle="how to sign in users with email and password"
className="grid grid-flow-row"
showSwitch

View File

@@ -111,7 +111,7 @@ export default function FacebookProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-facebook"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-facebook"
docsTitle="how to sign in users with Facebook"
icon="/assets/brands/facebook.svg"
switchId="enabled"

View File

@@ -113,7 +113,7 @@ export default function GitHubProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-github"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-github"
docsTitle="how to sign in users with GitHub"
icon={
theme.palette.mode === 'dark'

View File

@@ -111,7 +111,7 @@ export default function GoogleProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-google"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-google"
docsTitle="how to sign in users with Google"
icon="/assets/brands/google.svg"
switchId="enabled"

View File

@@ -113,7 +113,7 @@ export default function GravatarSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#gravatar"
docsLink="https://docs.nhost.io/guides/auth/overview#gravatar"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -111,7 +111,7 @@ export default function LinkedInProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-linkedin"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-linkedin"
docsTitle="how to sign in users with LinkedIn"
icon="/assets/brands/linkedin.svg"
switchId="enabled"

View File

@@ -102,7 +102,7 @@ export default function MFASettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#multi-factor-authentication"
docsLink="https://docs.nhost.io/guides/auth/overview#multi-factor-authentication"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -97,7 +97,7 @@ export default function MagicLinkSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication/sign-in-with-magic-link"
docsLink="https://docs.nhost.io/guides/auth/sign-in-magic-link"
docsTitle="how to sign in users with Magic Link"
switchId="enabled"
showSwitch

View File

@@ -137,7 +137,7 @@ export default function SMSSettings() {
}}
switchId="enabled"
showSwitch
docsLink="https://docs.nhost.io/authentication/sign-in-with-phone-number-sms"
docsLink="https://docs.nhost.io/guides/auth/sign-in-phone-number"
docsTitle="how to sign in users with a phone number (SMS)"
className={twMerge(
'grid grid-flow-col grid-cols-2 grid-rows-4 gap-x-3 gap-y-4 px-4 py-2',

View File

@@ -111,7 +111,7 @@ export default function SpotifyProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-spotify"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-spotify"
docsTitle="how to sign in users with Spotify"
icon="/assets/brands/spotify.svg"
switchId="enabled"

View File

@@ -113,7 +113,7 @@ export default function TwitchProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-twitch"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-twitch"
docsTitle="how to sign in users with Twitch"
icon={
theme.palette.mode === 'dark'

View File

@@ -101,7 +101,7 @@ export default function WebAuthnSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication/sign-in-with-security-keys"
docsLink="https://docs.nhost.io/guides/auth/sign-in-webauthn"
docsTitle="how to sign in users with security keys"
switchId="enabled"
showSwitch

View File

@@ -137,7 +137,7 @@ export default function WorkOsProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication/sign-in-with-workos"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-workos"
docsTitle="how to sign in users with WorkOS"
icon="/assets/brands/workos.svg"
switchId="enabled"

View File

@@ -1,10 +1,12 @@
import { useDatabaseQuery } from '@/features/database/dataGrid/hooks/useDatabaseQuery';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import { getToastStyleProps } from '@/utils/constants/settings';
import { getHasuraAdminSecret } from '@/utils/env';
import { parseIdentifiersFromSQL } from '@/utils/sql';
import toast from 'react-hot-toast';
import { useRouter } from 'next/router';
import { useState } from 'react';
import toast from 'react-hot-toast';
export default function useRunSQL(
sqlCode: string,
@@ -22,6 +24,14 @@ export default function useRunSQL(
const [columns, setColumns] = useState<string[]>([]);
const [rows, setRows] = useState<string[][]>([[]]);
const router = useRouter();
const {
query: { dataSourceSlug },
} = router;
const { refetch } = useDatabaseQuery([dataSourceSlug as string]);
const appUrl = generateAppServiceUrl(
currentProject?.subdomain,
currentProject?.region,
@@ -269,6 +279,9 @@ export default function useRunSQL(
}
}
// refresh the table list after running the sql
await refetch();
setLoading(false);
};

View File

@@ -138,7 +138,7 @@ export default function PermissionVariableSettings() {
<SettingsContainer
title="Permission Variables"
description="Permission variables are used to define permission rules in the GraphQL API."
docsLink="https://docs.nhost.io/graphql/permissions"
docsLink="https://docs.nhost.io/guides/api/permissions#permission-variables"
rootClassName="gap-0"
className="my-2 px-0"
slotProps={{ submitButton: { className: 'hidden' } }}

View File

@@ -79,7 +79,7 @@ export default function ResourcesFormFooter() {
<Text>
Learn more about{' '}
<Link
href="https://docs.nhost.io/platform/compute"
href="https://docs.nhost.io/platform/compute-resources"
target="_blank"
rel="noopener noreferrer"
underline="hover"

View File

@@ -169,7 +169,7 @@ export default function RoleSettings() {
<SettingsContainer
title="Default Allowed Roles"
description="Default Allowed Roles are roles users get automatically when they sign up."
docsLink="https://docs.nhost.io/authentication/users#allowed-roles"
docsLink="https://docs.nhost.io/guides/auth/users#allowed-roles"
rootClassName="gap-0"
className={twMerge(
'my-2 px-0',

View File

@@ -0,0 +1,158 @@
import { AuthenticatedLayout } from '@/components/layout/AuthenticatedLayout';
import { Container } from '@/components/layout/Container';
import { RetryableErrorBoundary } from '@/components/presentational/RetryableErrorBoundary';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { Input } from '@/components/ui/v2/Input';
import { List } from '@/components/ui/v2/List';
import { ListItem } from '@/components/ui/v2/ListItem';
import { Text } from '@/components/ui/v2/Text';
import {
useGetAllWorkspacesAndProjectsQuery,
type GetAllWorkspacesAndProjectsQuery,
} from '@/utils/__generated__/graphql';
import { Divider } from '@mui/material';
import { useUserData } from '@nhost/nextjs';
import debounce from 'lodash.debounce';
import Image from 'next/image';
import { useRouter } from 'next/router';
import type { ChangeEvent, ReactElement } from 'react';
import { Fragment, useEffect, useMemo, useState } from 'react';
type Workspace = Omit<
GetAllWorkspacesAndProjectsQuery['workspaces'][0],
'__typename'
>;
export default function SelectWorkspaceAndProject() {
const user = useUserData();
const router = useRouter();
const { data, loading } = useGetAllWorkspacesAndProjectsQuery({
skip: !user,
});
const workspaces: Workspace[] = data?.workspaces || [];
const projects = workspaces.flatMap((workspace) =>
workspace.projects.map((project) => ({
workspaceName: workspace.name,
projectName: project.name,
value: `${workspace.slug}/${project.slug}`,
})),
);
const [filter, setFilter] = useState('');
const handleFilterChange = useMemo(
() =>
debounce((event: ChangeEvent<HTMLInputElement>) => {
setFilter(event.target.value);
}, 200),
[],
);
useEffect(() => () => handleFilterChange.cancel(), [handleFilterChange]);
const goToProjectPage = async (project: {
workspaceName: string;
projectName: string;
value: string;
}) => {
const { slug } = router.query;
await router.push({
pathname: `/${project.value}/${
Array.isArray(slug) ? slug.join('/') : slug
}`,
});
};
const projectsToDisplay = filter
? projects.filter((project) =>
project.projectName.toLowerCase().includes(filter.toLowerCase()),
)
: projects;
if (loading) {
return (
<div className="flex w-full justify-center">
<ActivityIndicator
delay={500}
label="Loading workspaces and projects..."
/>
</div>
);
}
return (
<Container>
<div className="mx-auto grid max-w-[760px] grid-flow-row gap-4 py-6 sm:py-14">
<Text variant="h2" component="h1" className="">
Select a Project
</Text>
<div>
<div className="mb-2 flex w-full">
<Input
placeholder="Search..."
onChange={handleFilterChange}
fullWidth
autoFocus
/>
</div>
<RetryableErrorBoundary>
{projectsToDisplay.length === 0 ? (
<Box className="h-import py-2">
<Text variant="subtitle2">No results found.</Text>
</Box>
) : (
<List className="h-import overflow-y-auto">
{projectsToDisplay.map((project, index) => (
<Fragment key={project.value}>
<ListItem.Root
className="grid grid-flow-col justify-start gap-2 py-2.5"
secondaryAction={
<Button
variant="borderless"
color="primary"
onClick={() => goToProjectPage(project)}
>
Select
</Button>
}
>
<ListItem.Avatar>
<span className="inline-block h-6 w-6 overflow-hidden rounded-md">
<Image
src="/logos/new.svg"
alt="Nhost Logo"
width={24}
height={24}
/>
</span>
</ListItem.Avatar>
<ListItem.Text
primary={project.projectName}
secondary={`${project.workspaceName} / ${project.projectName}`}
/>
</ListItem.Root>
{index < projects.length - 1 && <Divider component="li" />}
</Fragment>
))}
</List>
)}
</RetryableErrorBoundary>
</div>
</div>
</Container>
);
}
SelectWorkspaceAndProject.getLayout = function getLayout(page: ReactElement) {
return (
<AuthenticatedLayout title="Select a Project">{page}</AuthenticatedLayout>
);
};

View File

@@ -29,6 +29,7 @@ import { Toaster } from 'react-hot-toast';
const emotionCache = createEmotionCache();
process.env = {
TEST_MODE: 'true',
NODE_ENV: 'development',
NEXT_PUBLIC_NHOST_PLATFORM: 'false',
NEXT_PUBLIC_ENV: 'dev',

View File

@@ -1,5 +1,16 @@
# @nhost/docs
## 2.5.0
### Minor Changes
- 0d8d0eb: Update docs and dashboard references
### Patch Changes
- 41617b9: feat: added elevated permissions docs
- 7db095f: chore: added a note about disk performance and CDN information
## 2.4.0
### Minor Changes

View File

@@ -0,0 +1,92 @@
---
title: Elevated Permissions
sidebarTitle: Elevated Permissions
description: Require extra permissions to perform critical operations
icon: unlock
---
In some scenarios you may want to add an extra layer of security to perform certain actions or view certain data. For instance, you may wish to allow users to view their profile information after authenticating but you may want to require users to confirm changes to their profile by performing an extra validation step with a [security key](sign-in-webauthn).
![overview-flow](/images/guides/auth/elevated-permissions/overview.png)
This is accomplished by adding the claim `x-hasura-auth-elevated: $user-id` to the access token in response to the extra security challenge. With this new claim in mind you can start writing permissions that require this extra step.
It is important to keep in mind the claim is added to the access token so, for as long as you have that access token, you will have elevated access. Once the access token is renewed (due to expiration or any other reason), the claim will be lost and a new security challenge will be required to add it back.
# API Endpoints and SDK components
To implement this functionality [auth](/product/authentication) [0.26.0](https://github.com/nhost/hasura-auth/releases/tag/0.26.0) introduces the new endpoint [/elevate/webauthn](/reference/auth/elevate-webauthn). This endpoint works the same way as [/signin/webauthn](/reference/auth/sign-in-using-email-via-fido2-webauthn-authentication) but it requires an Authorization header with a valid token to add the elevated claim to.
In addition, a few methods and components have also been added to simplify it's usage:
- [nhost.auth.elevateEmailSecurityKey](/reference/javascript/auth/elevate-email-security-key)
- [React - useElevateSecurityKeyEmail](/reference/react/use-elevate-security-key-email)
- [Next.js - useElevateSecurityKeyEmail](/reference/nextjs/use-elevate-security-key-email)
- [Vue - useElevateSecurityKeyEmail](/reference/vue/use-elevate-security-key-email)
# Protecting Hasura data
You can use the claim `x-hasura-auth-elevated` in exactly the same way you would normally use `X-Hasura-User-Id` for added security. For instance, the following permissions would allow users to see their data without any extra security:
![example-select-permissions](/images/guides/auth/elevated-permissions/select.png)
While the following permissions would require them first to elevate their access in order to update them:
![example-update-permissions](/images/guides/auth/elevated-permissions/update.png)
# Protecting Auth data
Some user information needs to be changed via hasura-auth's API rather than via graphql mutations. These endpoints are:
- [/user/password](/reference/auth/set-a-new-password) for changing passwords
- [/user/email/change](/reference/auth/change-the-current-users-email) for changing emails
- [/user/mfa](/reference/auth/activatedeactivate-multi-factor-authentication) for enabling or disabling MFA
- [/user/webauthn/add](/reference/auth/initialize-adding-of-a-new-webauthn-security-key-device-browser) for adding security keys
- [/pat](/reference/auth/create-personal-access-token-pat) for PAT creation
To protect these endpoints and require the elevated claim you can use the following configuration option:
```toml
[auth.elevatedPrivileges]
mode = 'required'
```
The mode can be one of `disabled` (default), `required`, `recommended`.
In `disabled` mode the elevated claim isn't required in any of the options above. This is the default behavior.
In `required` mode, all of the endpoints above will require an access token with the elevated claim. There is only one exception to this rule. If the user has no security key, adding the first security key won't require the elevated claim. However, as the rest of the endpoints do require it, the user won't be able to perform any changes until it adds a security key and gets an access token with the elevated claim. Adding extra security keys after the first one has been added will require the elevated claim. Removing security keys always requires the elevated claim.
In `recommended` mode, the elevated claim is only required if the user has a security key configured. If a user doesn't have a security key the elevated claim won't be required to perform the actions described above. If the user has one or more keys the elevated claims will be required. This mode provides flexibility for the users to choose if they want the extra security or not.
<Warning>
If you are allowing users to perform changes to auth data directly by performing graphql mutations (i.e. deleting security keys), don't forget to update the permissions to match the desired behavior.
</Warning>
## Example
To demonstrate this functionality we have implemented them in our [react-apollo](https://react-apollo.example.nhost.io) ([source](https://github.com/nhost/nhost/tree/main/examples/react-apollo)) and [vue-apollo](https://vue-apollo.example.nhost.io) ([source](https://github.com/nhost/nhost/tree/main/examples/vue-apollo)) examples.
### Secret Notes
To demonstrate how the elevated claim can work for permissions you can check the "Secret Notes" example. In this example, we are allowing users to see their secret notes by giving the `select` permissions `notes.user_id eq X-Hasura-User-Id`
![view secret notes](/images/guides/auth/elevated-permissions/secret_notes_view.png)
However, we are requiring elevated permissions to `insert`, `update` and `delete` with the permissions `notes.user_id eq x-hasura-auth-elevated`. In our example we automatically initiate the elevation process if the claim isn't already present:
![add secret notes](/images/guides/auth/elevated-permissions/secret_notes_add.png)
Note that after elevating permissions the secret note is added and the elevated claim persists until there is a token refreshed.
![after adding secret notes](/images/guides/auth/elevated-permissions/secret_notes_added.png)
### Updating profile information
In addition, to demonstrate the new `auth.elevatedPrivileges` setting, we have set it to `required` in this example requiring elevated access to perform certain changes. For instance, if you try to change your password you will first have to elevate your access:
![change password](/images/guides/auth/elevated-permissions/password.png)
After elevating access the password is changed:
![password changed](/images/guides/auth/elevated-permissions/password_changed.png)

View File

@@ -0,0 +1,111 @@
---
title: Overview
description: Learn about Nhost Auth
icon: hand-wave
---
Nhost Auth is a ready-to-use authentication service seamlessly integrated with the [GraphQL API](/product/graphql) and its [Permission System](/guides/api/permissions) from Hasura. This allows you to easily add user authentication to your application without having to build and maintain your own authentication system.
## Supported Methods
<CardGroup cols={4}>
<Card title="Email and Password" icon="square-1" href="/guides/auth/sign-in-email-password">
</Card>
<Card title="Magic Link" icon="square-2" href="/guides/auth/sign-in-magic-link">
</Card>
<Card title="Phone Number (SMS)" icon="square-3" href="/guides/auth/sign-in-phone-number">
</Card>
<Card title="Security Keys (WebAuthn)" icon="square-4" href="/guides/auth/sign-in-webauthn">
</Card>
<Card title="Elevated Permissions" icon="square-5" href="/guides/auth/elevated-permissions">
</Card>
</CardGroup>
### OAuth Providers
<CardGroup cols={4}>
<Card title="Apple" icon="square-1" href="/guides/auth/social/sign-in-apple">
</Card>
<Card title="Discord" icon="square-2" href="/guides/auth/social/sign-in-discord">
</Card>
<Card title="Facebook" icon="square-3" href="/guides/auth/social/sign-in-facebook">
</Card>
<Card title="GitHub" icon="square-4" href="/guides/auth/social/sign-in-github">
</Card>
<Card title="Google" icon="square-5" href="/guides/auth/social/sign-in-google">
</Card>
<Card title="Linkedin" icon="square-6" href="/guides/auth/social/sign-in-linkedin">
</Card>
<Card title="Spotify" icon="square-7" href="/guides/auth/social/sign-in-spotify">
</Card>
<Card title="Twitch" icon="square-8" href="/guides/auth/social/sign-in-twitch">
</Card>
<Card title="WorkOS" icon="square-9" href="/guides/auth/social/sign-in-workos">
</Card>
</CardGroup>
## Client URL
Client URL is the URL of your frontend application. The Client URL is used to redirect the user in certain auth workflows like signing in or resetting a password.
## Allowed Redirect URLs
Allowed Redirect URLs are the URLs of your frontend application that users are allowed to be redirected to on specific auth workflows. This is useful if you have multiple applications using the same Nhost backend or if you want to redirect users to a specific URL after certain authentication workflows.
As an example, for a staging project, you can set the Client URL to `https://staging.example.com` and Allowed Redirect URLs to `https://*.vercel.app`. This way, the user can be redirected to any Vercel deployment of your frontend application.
## Allowed Emails and Domains
Allowed Emails and Domains are used to restrict what email adresses and domains are valid when signing up and signing in.
If both allowed emails and allowed domains are set a user can only sign up if their email address matches one of the allowed emails or one of the allowed domains.
## Blocked Emails and Domains
Blocked Emails and Domains are used to block specific email addresses and domains from signing up and signing in.
Note that even if a user's email address matches any allowed email or domain, they will still be blocked if their email address matches any blocked email or domain.
## Multi-factor Authentication
By enabling Multi-Factor Authentication (MFA), you can allow users to verify their identity using a second factor during the sign-in process. We currently support Authenticator Apps (TOTP) for MFA.
A user can enable MFA for their account by scanning a QR code with their Authenticator App. After that, they will be prompted to enter a code generated by their Authenticator App during the sign-in process.
## Gravatar
If Gravatar is enabled, Nhost Auth will use the user's email address to fetch their Gravatar profile picture. If the user doesn't have a Gravatar profile picture, a default image will be used.
There are two options for Gravatars.
<Steps>
<Step title="Default Image">
If the user doesn't have a Gravatar profile picture, a default image will be used. You can choose between the following options:
- `404`: Do not load any image if none is associated with the email hash, instead return an HTTP 404 (File Not Found) response.
- `mp`: (mystery-person) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash).
- `identicon`: a geometric pattern based on an email hash.
- `monsterid`: a generated 'monster' with different colors, faces, etc.
- `wavatar`: generated faces with differing features and backgrounds.
- `retro`: awesome generated, 8-bit arcade-style pixelated faces.
- `robohash`: a generated robot with different colors, faces, etc.
- `blank`: a transparent PNG image.
</Step>
<Step title="Rating">
Gravatar images are rated by default. You can choose between the following options:
- `g`: suitable for display on all websites with any audience type.
- `pg`: may contain rude gestures, provocatively dressed individuals, lesser swear words or mild violence.
- `r`: may contain such things as harsh profanity, intense violence, nudity, or hard drug use.
- `x`: may contain hardcore sexual imagery or extremely disturbing violence.
</Step>
</Steps>
## Disable New Users
If set, newly registered users are disabled and won't be able to sign in. This is useful if you want to manually approve new users before they can sign in.

155
docs/guides/auth/users.mdx Normal file
View File

@@ -0,0 +1,155 @@
---
title: Users
description: Learn about Users managed by Nhost Auth
icon: users
---
## Creating Users
Users are created using the sign-up or sign-in flows described under [Supported Methods](/guides/auth/overview#supported-methods).
- **Avoid** creating users directly via GraphQL or the database, unless you are [importing users](#import-users) from an external system.
- **Avoid** modifying the database schema for the `auth.users` table.
- **Avoid** modifying the GraphQL root queries or fields for any of the tables in the `auth` schema.
You're allowed to:
- Add and remove your GraphQL relationships for the `users` table and other tables in the `auth` schema.
- Create, edit and delete permissions for the `users` table and other tables in the `auth` schema.
## Roles
Each user has one **default role** and a list of **allowed roles**. These roles are used to resolve permissions for requests to [GraphQL](/graphql/permissions) and [Storage](/storage#permissions).
When the user makes a request, only one role is used to resolve permissions. The default role is used if no role is explicitly specified. Users can only make requests using the default role or one of the allowed roles.
### Default Role
The default role is used when no role is specified in the request. By default, users' default role is `user`.
You can change what the default role for new users should be at **Settings -> Roles and Permissions**.
### Allowed Roles
Allowed roles are roles the user is allowed to use when making a request. Usually, you would change the role from `user` (the default role) to some other role because you want to use a different role to resolve permissions for a particular request.
By default, users have two allowed roles:
- `user` (default)
- `me`
You can change the default role for new users at **Settings -> Roles and Permissions**.
#### Assign Allowed Roles
It's possible to give users a subset of allowed roles during signup.
**Example:** Only set the `user` role (exclude the `me` role) for the user's allowed roles:
```js
await nhost.auth.signUp({
email: 'joe@example.com',
password: 'secret-password'
options: {
allowedRoles: ['user']
}
})
```
### Set Role for GraphQL Requests
When no role is specified, the user's default role will be used:
```js
await nhost.graphql.request(QUERY, {})
```
If you want to make a GraphQL request using a specific role, you can do so by using the `x-hasura-role` header, like this:
```js
await nhost.graphql.request(
QUERY,
{},
{
headers: {
'x-hasura-role': 'me'
}
}
)
```
If the request is not part of the user's allowed roles, the request will fail.
## Metadata
You can store custom information about the user in the `metadata` column of the `users` table. The `metadata` column is of type JSONB so any JSON data can be stored.
**Example:** Add metadata to a user during sign-up:
```js
await nhost.auth.signUp({
email: 'joe@example.com',
password: 'secret-password',
options: {
metadata: {
birthYear: 1989,
town: 'Stockholm',
likes: ['Postgres', 'GraphQL', 'Hasura', 'Authentication', 'Storage', 'Serverless Functions']
}
}
})
```
## Get User Information using GraphQL
**Example:** Get all users.
```graphql
query {
users {
id
displayName
email
metadata
}
}
```
**Example:** Get a single user.
```graphql
query {
user(id: "<user-id>") {
id
displayName
email
metadata
}
}
```
## Import Users
If you have users in a different system, you can import them into Nhost. When importing users you should insert the users directly into the database instead of using the authentication endpoints (`/signup/email-password`) to avoid sending unnecessary transactional emails.
### GraphQL
Make a GraphQL request to insert a user like this:
```graphql
mutation insertUser($user: users_insert_input!) {
insertUser(object: $user) {
id
}
}
```
### SQL
Connect directly to the database and insert a user like this:
```sql
INSERT INTO auth.users (id, email, display_name, password_hash, ..) VALUES ('<user-id>', '<email>', '<display-name>', '<password-hash>', ..);
```
Passwords are hashed using [bcrypt](https://en.wikipedia.org/wiki/Bcrypt).

View File

@@ -12,78 +12,41 @@ Postgres configuration can be tweaked to customize the **runtime behavior**, **p
Postgres.
</Warning>
### Available Settings
The following `CUE` schema contains all postgres settings available in `nhost.toml`.
```cue schema
#Postgres: {
version: string | *"14.6-20230705-1"
// Resources for the service, optional
resources?: #Resources & {
replicas: 1
}
// postgres settings of the same name in camelCase, optional
settings?: {
jit: "off" | "on" | *"on"
maxConnections: int32 | *100
sharedBuffers: string | *"128MB"
effectiveCacheSize: string | *"4GB"
maintenanceWorkMem: string | *"64MB"
checkpointCompletionTarget: number | *0.9
walBuffers: int32 | *-1
defaultStatisticsTarget: int32 | *100
randomPageCost: number | *4.0
effectiveIOConcurrency: int32 | *1
workMem: string | *"4MB"
hugePages: string | *"try"
minWalSize: string | *"80MB"
maxWalSize: string | *"1GB"
maxWorkerProcesses: int32 | *8
maxParallelWorkersPerGather: int32 | *2
maxParallelWorkers: int32 | *8
maxParallelMaintenanceWorkers: int32 | *2
walLevel: string | *"replica"
maxWalSenders: int32 | *10
maxReplicationSlots: int32 | *10
}
}
```
### Configuration Example
To configure your Postgres instance, simply add the relevant settings under `[postgres.settings]` in your project's `nhost.toml` file.
```toml nhost.toml
[postgres]
version = '14.6-20230925-1'
version = '14-20230312-1'
[postgres.resources.compute]
cpu = 1000
memory = 2048
cpu = 2000
memory = 4096
[postgres.resources.storage]
capacity = 20
[postgres.settings]
jit = "off"
jit = 'off'
maxConnections = 100
sharedBuffers = '256MB'
effectiveCacheSize = '768MB'
sharedBuffers = '128MB'
effectiveCacheSize = '4GB'
maintenanceWorkMem = '64MB'
checkpointCompletionTarget = 0.9
walBuffers = -1
walBuffers = '-1'
defaultStatisticsTarget = 100
randomPageCost = 1.1
effectiveIOConcurrency = 200
workMem = '1310kB'
hugePages = 'off'
randomPageCost = 4.0
effectiveIOConcurrency = 1
workMem = '4MB'
hugePages = 'try'
minWalSize = '80MB'
maxWalSize = '1GB'
maxWorkerProcesses = 8
maxParallelWorkersPerGather = 2
maxParallelWorkers = 8
maxParallelMaintenanceWorkers = 2
walLevel = "replica"
walLevel = 'replica'
maxWalSenders = 10
maxReplicationSlots = 10
```

View File

@@ -16,6 +16,8 @@ In case your Postgres service is not meeting your performance expectations, you
4. Evaluate the usage of indexes in your database. Identify queries that could benefit from additional indexes and strategically add them to improve query performance.
5. Increase the disk size to increase [disk performance](/platform/compute-resources#disk-performance). Keep in mind increasing the disk size isn't reversible and increasing the memory of the service may yield better results. This is mostly useful when your data is very volatile and the postgres cache can't work effectively. Only attempt to increase disk for performance reasons if your reads and writes are very high and increasing memory isn't effective.
By implementing these steps, you can effectively address performance concerns and enhance the overall performance of your Postgres service.
## Upgrade to our latest postgres image

View File

@@ -0,0 +1,28 @@
---
title: CDN
description: Serving files lightning fast
icon: bolt
---
The [storage](/product/storage) service integrates with a CDN service to cache files and serve them close to users. This leads to faster response times and lower load on the backend service. You can read our initial [announcement](https://nhost.io/blog/launching-nhost-cdn-nhost-storage-is-now-blazing-fast) for some general information about what a CDN is and the performance gains.
# Security
The primary function of a CDN is to deliver cached files quickly to users without relying on the backend. While this is effective for public files, we need to handle non-public files differently to ensure that only users with proper permissions can access those files. Instead of serving the file directly, a conditional fetch is performed, including the user's Authorization header. This allows the backend service to verify the user's permissions. By conducting this conditional check, the backend service only needs to confirm to the CDN that the file can be served to the specific user, eliminating the need to serve the file itself.
# Cache invalidation
If a file is modified or deleted, we instruct the CDN to immediately invalidate the cached files. This is done automatically by the storage service and requires no special handling.
# Maximizing HITs
In CDN terminology, a HIT occurs when a file is found in the cache and can be served to the user. Conversely, a MISS happens when the file is not yet cached and requires a round trip to the backend to retrieve it before it can be served to the user.
To lower response times and backend load, we want to maximize HITs as much as possible. To do that here are some notes and recommendations:
1. Links with different query arguments are treated as different files, even if they all point to the same underlying file.
2. Due to (1), if you are using the image manipulation feature, each set of options (i.e. different sizes or qualities), will be treated as different files. Having too many different combinations may increase the number of MISSes and be counterproductive.
3. Only use presigned URLs if you really must to and reuse if possible. Due to (1) as well, each presigned URL is different, which means they are treated by the CDN as different files, even if they all point to the same file.
4. If possible, always prefer public files
5. Authenticated files are your second best option. You can use [nhost.storage.download](/reference/javascript/storage/download) to download private files.
6. If you are hosting large files, don't be afraid of using the [range header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range). The service should be able to cache and serve partial files too.

View File

@@ -0,0 +1,24 @@
sequenceDiagram
Note over User: User logins as usual
User->>App: I want to login, please
App->>Backend: /signin/...
Backend->>App: Session{...}
App->>User: Here is your session
Note over User: Actions that don't require elevated permissions work as usual
User->>App: I want to see my profile data
App->>Backend: query getProfileData { ... }
Backend->>App: data { ... }
App->>User: Here is your profile
Note over User: Action that requires elevated permissions starts here
User->>App: I want to change my address to X
App->>Backend: /elevate/webauthn
Backend->>App: SecurityChallenge{ ... }
App->>User: SecurityChallenge{ ... }
User->>App: SecurityChallengeResponse{ ... }
App->>+Backend: SecurityChallengeResponse{ ... }
Backend->>App: SessionWithElevatedClaim{ ... }
App->>Backend: mutation updateAddress { ... }
Backend->>App: success { ... }
App->>User: Your address has been changed

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -111,6 +111,8 @@
{
"group": "Authentication",
"pages": [
"guides/auth/overview",
"guides/auth/users",
{
"group": "Social Sign In",
"icon": "at",
@@ -130,6 +132,7 @@
"guides/auth/sign-in-magic-link",
"guides/auth/sign-in-phone-number",
"guides/auth/sign-in-webauthn",
"guides/auth/elevated-permissions",
"guides/auth/email-templates"
]
},
@@ -139,7 +142,7 @@
},
{
"group": "Storage",
"pages": ["guides/storage/overview", "guides/storage/antivirus"]
"pages": ["guides/storage/overview", "guides/storage/cdn", "guides/storage/antivirus"]
},
{
"group": "Functions",
@@ -193,7 +196,9 @@
"reference/auth/sign-up-using-email-via-fido2-webauthn-authentication",
"reference/auth/verfiy-fido2-webauthn-authentication-and-complete-signup",
"reference/auth/sign-in-using-email-via-fido2-webauthn-authentication",
"reference/auth/verfiy-fido2-webauthn-authentication-using-public-key-cryptography"
"reference/auth/verfiy-fido2-webauthn-authentication-using-public-key-cryptography",
"reference/auth/elevate-webauthn",
"reference/auth/elevate-webauthn-verify"
]
},
{
@@ -224,7 +229,8 @@
"reference/auth/get-user-information",
"reference/auth/refresh-the-oauth-access-tokens-of-a-given-user-you-must-be-an-admin-to-perform-this-operation",
"reference/auth/initialize-adding-of-a-new-webauthn-security-key-device-browser",
"reference/auth/verfiy-adding-of-a-new-webauth-security-key-device-browser"
"reference/auth/verfiy-adding-of-a-new-webauth-security-key-device-browser",
"reference/auth/create-personal-access-token-pat"
]
},
"reference/auth/sign-out"
@@ -291,7 +297,6 @@
"group": "Auth",
"pages": [
"reference/javascript/auth/hasura-auth-client",
"reference/javascript/auth/add-security-key",
"reference/javascript/auth/change-email",
"reference/javascript/auth/change-password",
"reference/javascript/auth/create-pat",
@@ -312,7 +317,9 @@
"reference/javascript/auth/sign-in",
"reference/javascript/auth/sign-in-pat",
"reference/javascript/auth/sign-out",
"reference/javascript/auth/sign-up"
"reference/javascript/auth/sign-up",
"reference/javascript/auth/add-security-key",
"reference/javascript/auth/elevate-email-security-key"
]
},
{
@@ -380,6 +387,7 @@
"reference/react/use-sign-out",
"reference/react/use-sign-up-email-password",
"reference/react/use-sign-up-email-security-key-email",
"reference/react/use-elevate-security-key-email",
"reference/react/use-user-avatar-url",
"reference/react/use-user-data",
"reference/react/use-user-default-role",
@@ -426,6 +434,7 @@
"reference/nextjs/use-sign-out",
"reference/nextjs/use-sign-up-email-password",
"reference/nextjs/use-sign-up-email-security-key-email",
"reference/nextjs/use-elevate-security-key-email",
"reference/nextjs/use-user-avatar-url",
"reference/nextjs/use-user-data",
"reference/nextjs/use-user-default-role",
@@ -472,7 +481,11 @@
"reference/vue/use-user-id",
"reference/vue/use-user-is-anonymous",
"reference/vue/use-user-locale",
"reference/vue/use-user-roles"
"reference/vue/use-user-roles",
"reference/vue/use-add-security-key",
"reference/vue/use-elevate-security-key-email",
"reference/vue/use-sign-in-email-security-key",
"reference/vue/use-sign-up-email-security-key"
]
}
]

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/docs",
"version": "2.4.0",
"version": "2.5.0",
"private": true,
"scripts": {
"start": "mintlify dev"

View File

@@ -4,7 +4,7 @@ description: "Allocate CPU and Memory to your backend infrastructure"
icon: server
---
Compute resources are the fundamental units that represent the processing power and memory available to your projects. The primary compute resources are vCPU and RAM.
Compute resources are the fundamental units that represent the processing power and memory available to your projects. The primary compute resources are vCPU and RAM.
This documentation outlines the key aspects of compute resources in the context of the Nhost Cloud Platform.
@@ -40,7 +40,7 @@ Projects on the pro tier have a total of 2 shared vCPUs and 2 GiB of RAM spread
## Dedicated Compute
For production workloads where latency is essential or consistent performance is non-negotiable, we strongly suggest the use of dedicated resources.
For production workloads where latency is essential or consistent performance is non-negotiable, we strongly suggest the use of dedicated resources.
<Note>Compute/Dedicated resources are only available on the Pro plan</Note>
@@ -72,3 +72,21 @@ To setup dedicated resources for your project, you can either use the Dashboard
</Tab>
</Tabs>
## Disk Performance
Services may require a disk provisioned to store data. For instance, [postgres](/guides/database/configuring-postgres#configuration-example) comes with a disk provisioned by default and [Nhost Run](/product/run) may [too](/guides/run/resources#storage). For these cases we provisioned SSD disks with the following performance:
- Baseline: 3000 IOPS
- Baseline: 125Mbps of thoughput
- Every 50GB: +350 IOPS and +15Mbps of throughput
For example, the following disk sizes will have the following performance:
| Size | IOPS | Throughput |
| ---- | ---- | ---------- |
| 1 | 3000| 125 |
| 10 | 3000| 125 |
| 49 | 3000| 125 |
| 50 | 3350| 140 |
| 100 | 3700 | 155 |
| 300 | 5100 | 215 |

View File

@@ -21,7 +21,7 @@ export default (req: Request, res: Response) => {
Variables created are available to all services, including Run Services and Functions
</Note>
## Add Environment Variables
## Adding Environment Variables
<Tabs>
<Tab title="Config">
@@ -39,3 +39,43 @@ value = "Nhost is Awesome!"
</Tab>
</Tabs>
## System Environment Variables
System environment variables are generated and managed by Nhost. The following variables are available:
- `NHOST_ADMIN_SECRET`
- `NHOST_WEBHOOK_SECRET`
- `NHOST_SUBDOMAIN`
- `NHOST_REGION`
- `NHOST_HASURA_URL`
- `NHOST_AUTH_URL`
- `NHOST_GRAPHQL_URL`
- `NHOST_STORAGE_URL`
- `NHOST_FUNCTIONS_URL`
- `NHOST_JWT_SECRET`
`NHOST_ADMIN_SECRET`, `NHOST_WEBHOOK_SECRET` and `NHOST_JWT_SECRET` are populated with values from their corresponding secrets.
**Example values**:
```text
NHOST_ADMIN_SECRET={{ secrets.HASURA_GRAPHQL_ADMIN_SECRET }}
NHOST_WEBHOOK_SECRET={{ secrets.NHOST_WEBHOOK_SECRET }}
NHOST_SUBDOMAIN=abv123abc
NHOST_REGION=eu-central-1
NHOST_HASURA_URL=https://abc123abc.hasura.eu-central-1.nhost.run/console
NHOST_AUTH_URL=https://abc123abc.auth.eu-central-1.nhost.run/v1
NHOST_GRAPHQL_URL=https://abc123abc.graphql.eu-central-1.nhost.run/v1
NHOST_STORAGE_URL=https://abc123abc.storage.eu-central-1.nhost.run/v1
NHOST_FUNCTIONS_URL=https://abc123abc.functions.eu-central-1.nhost.run/v1
NHOST_JWT_SECRET={"key": "{{ secrets.HASURA_GRAPHQL_JWT_SECRET }}", "type": "HS256" }
```

View File

@@ -19,6 +19,8 @@ Combined with a powerful **Permission Rules** system, Nhost Auth offers everythi
</Card>
<Card title="Security Keys (WebAuthn)" icon="square-4" href="../guides/auth/sign-in-webauthn">
</Card>
<Card title="Elevated Permissions" icon="square-5" href="../guides/auth/elevated-permissions">
</Card>
</CardGroup>
### OAuth Providers

View File

@@ -4,13 +4,18 @@ description: Store and Serve large files
icon: file
---
Use Nhost Storage to store and retrieve large files such as videos, images, large documents, or any other objects.
Use Nhost Storage to store and retrieve large files such as videos, images, large documents, or any other objects.
Nhost Storage includes a built-in image optimizer, so you can resize and compress your media files on the fly.
### CDN
Serve your assets with a global CDN to reduce latency.
<CardGroup cols={4}>
<Card title="Overview" icon="square-1" href="/guides/storage/overview">
</Card>
<Card title="CDN" icon="square-2" href="/guides/storage/cdn">
</Card>
<Card title="Antivirus" icon="square-3" href="/guides/storage/antivirus">
</Card>
</CardGroup>
### Additional Resources

View File

@@ -0,0 +1,3 @@
---
openapi: post /pat
---

View File

@@ -0,0 +1,4 @@
---
openapi: post /elevate/webauthn/verify
sidebarTitle: Elevate Verify
---

View File

@@ -0,0 +1,4 @@
---
openapi: post /elevate/webauthn
sidebarTitle: Elevate
---

View File

@@ -0,0 +1,16 @@
---
title: elevateEmailSecurityKey()
sidebarTitle: elevateEmailSecurityKey()
---
Use `nhost.auth.elevateEmailSecurityKey` to get a temporary elevated auth permissions to run sensitive operations.
## Parameters
---
**<span className="parameter-name">email</span>** <span className="optional-status">required</span> <code>string</code>
user email
---

View File

@@ -0,0 +1,39 @@
---
title: ElevateWithSecurityKeyHandlerResult
sidebarTitle: ElevateWithSecurityKeyHandlerResult
description: No description provided.
---
# `ElevateWithSecurityKeyHandlerResult`
## Parameters
---
**<span className="parameter-name">elevated</span>** <span className="optional-status">required</span> <code>boolean</code>
---
**<span className="parameter-name">isError</span>** <span className="optional-status">required</span> <code>boolean</code>
**`@returns`**
`true` if an error occurred
**`@depreacted`**
use `!isSuccess` or `!!error` instead
---
**<span className="parameter-name">error</span>** <span className="optional-status">required</span> <code>null &#124; [`AuthErrorPayload`](/reference/javascript/auth/types/auth-error-payload)</code>
Provides details about the error
---
**<span className="parameter-name">isSuccess</span>** <span className="optional-status">required</span> <code>boolean</code>
Returns `true` if the action is successful.
---

View File

@@ -16,7 +16,7 @@ instance of `NhostClient` that is ready to use on the server side (signed in or
---
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> <code>string &#124; Partial&lt;Pick&lt;NhostReactClientConstructorParams, "subdomain" &#124; "region" &#124; "authUrl" &#124; "graphqlUrl" &#124; "storageUrl" &#124; "functionsUrl"&gt;&gt;</code>
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> <code>Partial&lt;Pick&lt;NhostReactClientConstructorParams, "subdomain" &#124; "region" &#124; "authUrl" &#124; "graphqlUrl" &#124; "storageUrl" &#124; "functionsUrl"&gt;&gt;</code>
---

View File

@@ -28,7 +28,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
---
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> <code>string &#124; Partial&lt;Pick&lt;NhostReactClientConstructorParams, "subdomain" &#124; "region" &#124; "authUrl" &#124; "graphqlUrl" &#124; "storageUrl" &#124; "functionsUrl"&gt;&gt;</code>
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> <code>Partial&lt;Pick&lt;NhostReactClientConstructorParams, "subdomain" &#124; "region" &#124; "authUrl" &#124; "graphqlUrl" &#124; "storageUrl" &#124; "functionsUrl"&gt;&gt;</code>
---

View File

@@ -1,6 +1,5 @@
---
title: NhostClient
sidebarTitle: NhostClient
description: No description provided.
---
@@ -21,7 +20,6 @@ description: No description provided.
| <span className="parameter-name"><span className="light-grey">params.</span>authUrl</span> | <code>string</code> | | |
| <span className="parameter-name"><span className="light-grey">params.</span>region</span> | <code>string</code> | | Project region (e.g. `eu-central-1`) Project region is not required during local development (when `subdomain` is `localhost`) |
| <span className="parameter-name"><span className="light-grey">params.</span>subdomain</span> | <code>string</code> | | Project subdomain (e.g. `ieingiwnginwnfnegqwvdqwdwq`) Use `localhost` during local development |
| <span className="parameter-name"><span className="light-grey">params.</span>backendUrl</span> | <code>string</code> | | Nhost backend URL Will be deprecated in a future release. Please look at 'subdomain' and 'region' instead. |
| <span className="parameter-name"><span className="light-grey">params.</span>devTools</span> | <code>boolean</code> | | Activate devTools e.g. the ability to connect to the xstate inspector |
| <span className="parameter-name"><span className="light-grey">params.</span>autoSignIn</span> | <code>boolean</code> | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
| <span className="parameter-name"><span className="light-grey">params.</span>autoRefreshToken</span> | <code>boolean</code> | | When set to true, will automatically refresh token before it expires |

View File

@@ -1,11 +0,0 @@
---
title: BackendUrl
sidebarTitle: BackendUrl
description: No description provided.
---
# `BackendUrl`
```ts
type BackendUrl = () => { backendUrl: string }
```

View File

@@ -47,13 +47,6 @@ Use `localhost` during local development
---
**<span className="parameter-name">backendUrl</span>** <span className="optional-status">optional</span> <code>string</code>
Nhost backend URL
Will be deprecated in a future release. Please look at 'subdomain' and 'region' instead.
---
**<span className="parameter-name">devTools</span>** <span className="optional-status">optional</span> <code>boolean</code>
Activate devTools e.g. the ability to connect to the xstate inspector

View File

@@ -62,13 +62,6 @@ Activate devTools e.g. the ability to connect to the xstate inspector
---
**<span className="parameter-name">backendUrl</span>** <span className="optional-status">optional</span> <code>string</code>
Nhost backend URL
Will be deprecated in a future release. Please look at 'subdomain' and 'region' instead.
---
**<span className="parameter-name">subdomain</span>** <span className="optional-status">optional</span> <code>string</code>
Project subdomain (e.g. `ieingiwnginwnfnegqwvdqwdwq`)

View File

@@ -0,0 +1,14 @@
---
title: useElevateSecurityKeyEmail()
sidebarTitle: useElevateSecurityKeyEmail()
---
Use the hook `useElevateSecurityKeyEmail` to elevate the user auth permission in order to perform sensitive operations
```tsx
const { elevateEmailSecurityKey, elevated } = useElevateSecurityKeyEmail()
console.log({ elevated })
await elevateEmailSecurityKey('joe@example.com')
```

View File

@@ -3,7 +3,7 @@ title: useSignUpEmailSecurityKeyEmail()
sidebarTitle: useSignUpEmailSecurityKeyEmail()
---
Use the hook `useSignUpEmailSecurityKey` to sign up a user with security key and an email using the WebAuthn API.
Use the hook `useSignUpEmailSecurityKeyEmail` to sign up a user with security key and an email using the WebAuthn API.
```tsx
const {
@@ -13,7 +13,7 @@ const {
isSuccess,
isError,
error
} = useSignUpEmailSecurityKey()
} = useSignUpEmailSecurityKeyEmail()
console.log({ needsEmailVerification, isLoading, isSuccess, isError, error })

View File

@@ -50,6 +50,35 @@ components:
userVerification: "preferred"
rpId: "react-apollo.example.nhost.io"
ElevateWebauthnSessionPayload:
type: object
properties:
challenge:
type: string
allowCredentials:
type: array
items:
type: object
properties:
id:
type: string
type:
type: string
timeout:
type: integer
userVerification:
type: string
rpId:
type: string
example:
challenge: "KOGeoAfC2nrZ_SluhmU5RYYMvBsRDvzghjERGdXbbfQ"
allowCredentials:
- id: "zCnsWvxgtMrOCeX6eA_yqQ"
type: "public-key"
timeout: 60000
userVerification: "preferred"
rpId: "react-apollo.example.nhost.io"
WebauthnSessionPayload:
type: object
properties:
@@ -752,7 +781,69 @@ components:
example: john.smith@nhost.io
format: email
type: string
credential:
type: object
properties:
id:
type: string
rawId:
type: string
response:
type: object
properties:
authenticatorData:
type: string
clientDataJSON:
type: string
signature:
type: string
userHandle:
type: string
format: uuid
type:
type: string
clientExtensionResults:
type: object
authenticatorAttachment:
type: string
example:
email: "nuno@nhost.io"
credential:
id: "zCnsWvxgtMrOCeX6eA_yqQ"
rawId: "zCnsWvxgtMrOCeX6eA_yqQ"
response:
authenticatorData: "0RE6Bmg2J-FxNrC8136ZQSeTWKWtdni_Lpfv5XR4bDsdAAAAAA"
clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiTkNSSVRVU1pjeFE1ZTFhdUtUcXVlNnA4R0ZacHdxUS1kZzM4bnlWa3NCRSIsIm9yaWdpbiI6Imh0dHBzOi8vcmVhY3QtYXBvbGxvLmV4YW1wbGUubmhvc3QuaW8ifQ"
signature: "MEUCIQDRXq3aY-gXWsuYJZhOzqqn6UpoRQfcPdNLP7hpZ7IdvQIgX5rY6TomkYUtqydu-w88fW7KeFm-0oE-5jTdLNHg9zw"
userHandle: "8881037a-8495-48ef-8a04-ebbdb69415db"
type: "public-key"
clientExtensionResults: {}
authenticatorAttachment: "platform"
required:
- email
- credential
ElevateWebauthnSchema:
additionalProperties: false
type: object
properties:
email:
description: A valid email
example: john.smith@nhost.io
format: email
type: string
required:
- email
ElevateVerifyWebauthnSchema:
additionalProperties: true
type: object
properties:
email:
description: A valid email
example: john.smith@nhost.io
format: email
type: string
credential:
type: object
properties:
@@ -1279,6 +1370,20 @@ components:
example: 0.17.1
type: string
CreatePATSchema:
type: object
properties:
expiresAt:
type: string
format: date-time
description: The expiration date and time of the personal access token
example:
metadata:
type: object
description: Additional metadata associated with the personal access token
additionalProperties: true
required:
- expiresAt
paths:
/healthz:
@@ -1450,7 +1555,6 @@ paths:
tags:
- Authentication
/signin/anonymous:
post:
description: 'Sign In a user anonymously'
@@ -1743,7 +1847,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/SignInWebauthnSessionPayload'
description: The payload is invalid
description: Signed in successfully
'400':
content:
application/json:
@@ -1802,6 +1906,82 @@ paths:
tags:
- Authentication
/elevate/webauthn:
post:
description: Elevate access for an already signed in user using FIDO2 Webauthn
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ElevateWebauthnSchema'
description: ''
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ElevateWebauthnSessionPayload'
description: Elevated Webauthn successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/InvalidRequestError'
description: The payload is invalid
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/DisabledEndpointError'
description: The feature is not activated
security:
- BearerAuth: []
summary: Elevate WebAuthn
tags:
- Authentication
/elevate/webauthn/verify:
post:
description: Verify FIDO2 Webauthn authentication using public-key cryptography
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ElevateVerifyWebauthnSchema'
description: ''
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SessionPayload'
description: Access elevated successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/InvalidRequestError'
description: The payload is invalid
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedError'
description: Invalid email or password, or user is not verified
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/DisabledEndpointError'
description: The feature is not activated
security:
- BearerAuth: []
summary: Elevate WebAuthn Verify
tags:
- Authentication
/mfa/totp/generate:
get:
parameters: []
@@ -1955,7 +2135,7 @@ paths:
description: User is not authenticated
security:
- BearerAuth: []
summary: Get user information
summary: Get User Information
tags:
- User management
@@ -2130,7 +2310,7 @@ paths:
description: User is not authenticated
security:
- BearerAuth: []
summary: Set a new password
summary: Set New Password
tags:
- User management
@@ -2268,6 +2448,42 @@ paths:
tags:
- User management
/pat:
post:
deprecated: false
parameters: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreatePATSchema'
description: ''
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
description: User successfully authenticated
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/InvalidRequestError'
description: The payload format is invalid
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthenticatedUserError'
description: User is not authenticated
security:
- BearerAuth: []
summary: Create Personal Access Token (PAT)
tags:
- User management
/verify:
get:
deprecated: false

View File

@@ -1,6 +1,5 @@
---
title: NhostClient
sidebarTitle: NhostClient
description: No description provided.
---
@@ -21,7 +20,6 @@ description: No description provided.
| <span className="parameter-name"><span className="light-grey">params.</span>authUrl</span> | <code>string</code> | | |
| <span className="parameter-name"><span className="light-grey">params.</span>region</span> | <code>string</code> | | Project region (e.g. `eu-central-1`) Project region is not required during local development (when `subdomain` is `localhost`) |
| <span className="parameter-name"><span className="light-grey">params.</span>subdomain</span> | <code>string</code> | | Project subdomain (e.g. `ieingiwnginwnfnegqwvdqwdwq`) Use `localhost` during local development |
| <span className="parameter-name"><span className="light-grey">params.</span>backendUrl</span> | <code>string</code> | | Nhost backend URL Will be deprecated in a future release. Please look at 'subdomain' and 'region' instead. |
| <span className="parameter-name"><span className="light-grey">params.</span>devTools</span> | <code>boolean</code> | | Activate devTools e.g. the ability to connect to the xstate inspector |
| <span className="parameter-name"><span className="light-grey">params.</span>autoSignIn</span> | <code>boolean</code> | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
| <span className="parameter-name"><span className="light-grey">params.</span>autoRefreshToken</span> | <code>boolean</code> | | When set to true, will automatically refresh token before it expires |

View File

@@ -1,11 +0,0 @@
---
title: BackendUrl
sidebarTitle: BackendUrl
description: No description provided.
---
# `BackendUrl`
```ts
type BackendUrl = () => { backendUrl: string }
```

View File

@@ -47,13 +47,6 @@ Use `localhost` during local development
---
**<span className="parameter-name">backendUrl</span>** <span className="optional-status">optional</span> <code>string</code>
Nhost backend URL
Will be deprecated in a future release. Please look at 'subdomain' and 'region' instead.
---
**<span className="parameter-name">devTools</span>** <span className="optional-status">optional</span> <code>boolean</code>
Activate devTools e.g. the ability to connect to the xstate inspector

View File

@@ -0,0 +1,14 @@
---
title: useElevateSecurityKeyEmail()
sidebarTitle: useElevateSecurityKeyEmail()
---
Use the hook `useElevateSecurityKeyEmail` to elevate the user auth permission in order to perform sensitive operations
```tsx
const { elevateEmailSecurityKey, elevated } = useElevateSecurityKeyEmail()
console.log({ elevated })
await elevateEmailSecurityKey('joe@example.com')
```

View File

@@ -3,7 +3,7 @@ title: useSignUpEmailSecurityKeyEmail()
sidebarTitle: useSignUpEmailSecurityKeyEmail()
---
Use the hook `useSignUpEmailSecurityKey` to sign up a user with security key and an email using the WebAuthn API.
Use the hook `useSignUpEmailSecurityKeyEmail` to sign up a user with security key and an email using the WebAuthn API.
```tsx
const {
@@ -13,7 +13,7 @@ const {
isSuccess,
isError,
error
} = useSignUpEmailSecurityKey()
} = useSignUpEmailSecurityKeyEmail()
console.log({ needsEmailVerification, isLoading, isSuccess, isError, error })

View File

@@ -1,6 +1,5 @@
---
title: NhostClient
sidebarTitle: NhostClient
description: No description provided.
---
@@ -14,10 +13,13 @@ description: No description provided.
| Property | Type | Required | Notes |
| :----------------------------------------------------------------------------------------------------- | :----------------------------- | :------: | :--------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="parameter-name"><span className="light-grey">params.</span>functionsUrl</span> | <code>string</code> | | |
| <span className="parameter-name"><span className="light-grey">params.</span>storageUrl</span> | <code>string</code> | | |
| <span className="parameter-name"><span className="light-grey">params.</span>graphqlUrl</span> | <code>string</code> | | |
| <span className="parameter-name"><span className="light-grey">params.</span>authUrl</span> | <code>string</code> | | |
| <span className="parameter-name"><span className="light-grey">params.</span>adminSecret</span> | <code>string</code> | | When set, the admin secret is sent as a header, `x-hasura-admin-secret`, for all requests to GraphQL, Storage, and Serverless Functions. |
| <span className="parameter-name"><span className="light-grey">params.</span>region</span> | <code>string</code> | | Project region (e.g. `eu-central-1`) Project region is not required during local development (when `subdomain` is `localhost`) |
| <span className="parameter-name"><span className="light-grey">params.</span>subdomain</span> | <code>string</code> | | Project subdomain (e.g. `ieingiwnginwnfnegqwvdqwdwq`) Use `localhost` during local development |
| <span className="parameter-name"><span className="light-grey">params.</span>backendUrl</span> | <code>string</code> | | Nhost backend URL Will be deprecated in a future release. Please look at 'subdomain' and 'region' instead. |
| <span className="parameter-name"><span className="light-grey">params.</span>devTools</span> | <code>boolean</code> | | Activate devTools e.g. the ability to connect to the xstate inspector |
| <span className="parameter-name"><span className="light-grey">params.</span>autoSignIn</span> | <code>boolean</code> | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
| <span className="parameter-name"><span className="light-grey">params.</span>autoRefreshToken</span> | <code>boolean</code> | | When set to true, will automatically refresh token before it expires |

View File

@@ -0,0 +1,49 @@
---
title: AddSecuritKeyComposableResult
sidebarTitle: AddSecuritKeyComposableResult
description: No description provided.
---
# `AddSecuritKeyComposableResult`
## Parameters
---
**<span className="parameter-name">isError</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` if an error occurred
**`@depreacted`**
use `!isSuccess` or `!!error` instead
---
**<span className="parameter-name">error</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; ErrorPayload&lt;any&gt;&gt;</code>
Provides details about the error
---
**<span className="parameter-name">isLoading</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` when the action is executing, `false` when it finished its execution.
---
**<span className="parameter-name">isSuccess</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
Returns `true` if the action is successful.
---
**<span className="parameter-name">add</span>** <span className="optional-status">required</span> <code>AddSecurityKeyHandler</code>
Add a security key to the current user with the WebAuthn API
---

View File

@@ -1,11 +0,0 @@
---
title: BackendUrl
sidebarTitle: BackendUrl
description: No description provided.
---
# `BackendUrl`
```ts
type BackendUrl = () => { backendUrl: string }
```

View File

@@ -10,6 +10,22 @@ description: No description provided.
---
**<span className="parameter-name">functionsUrl</span>** <span className="optional-status">optional</span> <code>string</code>
---
**<span className="parameter-name">storageUrl</span>** <span className="optional-status">optional</span> <code>string</code>
---
**<span className="parameter-name">graphqlUrl</span>** <span className="optional-status">optional</span> <code>string</code>
---
**<span className="parameter-name">authUrl</span>** <span className="optional-status">optional</span> <code>string</code>
---
**<span className="parameter-name">adminSecret</span>** <span className="optional-status">optional</span> <code>string</code>
When set, the admin secret is sent as a header, `x-hasura-admin-secret`,
@@ -31,13 +47,6 @@ Use `localhost` during local development
---
**<span className="parameter-name">backendUrl</span>** <span className="optional-status">optional</span> <code>string</code>
Nhost backend URL
Will be deprecated in a future release. Please look at 'subdomain' and 'region' instead.
---
**<span className="parameter-name">devTools</span>** <span className="optional-status">optional</span> <code>boolean</code>
Activate devTools e.g. the ability to connect to the xstate inspector

View File

@@ -0,0 +1,73 @@
---
title: SignInSecurityKeyPasswordlessHookResult
sidebarTitle: SignInSecurityKeyPasswordlessHookResult
description: No description provided.
---
# `SignInSecurityKeyPasswordlessHookResult`
## Parameters
---
**<span className="parameter-name">isError</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` if an error occurred
**`@depreacted`**
use `!isSuccess` or `!!error` instead
---
**<span className="parameter-name">error</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; AuthErrorPayload&gt;</code>
Provides details about the error
---
**<span className="parameter-name">isLoading</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` when the action is executing, `false` when it finished its execution.
---
**<span className="parameter-name">isSuccess</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
Returns `true` if the action is successful.
---
**<span className="parameter-name">user</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; User&gt;</code>
User information
---
**<span className="parameter-name">accessToken</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; string&gt;</code>
Access token (JWT)
---
**<span className="parameter-name">refreshToken</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; string&gt;</code>
Access token (JWT)
---
**<span className="parameter-name">needsEmailVerification</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` if an email is required to complete the action, and that a verification email has been sent to complete the action.
---
**<span className="parameter-name">signInEmailSecurityKey</span>** <span className="optional-status">required</span> <code>SignInSecurityKeyPasswordlessHandler</code>
---

View File

@@ -0,0 +1,75 @@
---
title: SignUpSecurityKeyHookResult
sidebarTitle: SignUpSecurityKeyHookResult
description: No description provided.
---
# `SignUpSecurityKeyHookResult`
## Parameters
---
**<span className="parameter-name">isError</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` if an error occurred
**`@depreacted`**
use `!isSuccess` or `!!error` instead
---
**<span className="parameter-name">error</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; AuthErrorPayload&gt;</code>
Provides details about the error
---
**<span className="parameter-name">isLoading</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` when the action is executing, `false` when it finished its execution.
---
**<span className="parameter-name">isSuccess</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
Returns `true` if the action is successful.
---
**<span className="parameter-name">user</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; User&gt;</code>
User information
---
**<span className="parameter-name">accessToken</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; string&gt;</code>
Access token (JWT)
---
**<span className="parameter-name">refreshToken</span>** <span className="optional-status">required</span> <code>Ref&lt;null &#124; string&gt;</code>
Access token (JWT)
---
**<span className="parameter-name">needsEmailVerification</span>** <span className="optional-status">required</span> <code>Ref&lt;boolean&gt;</code>
**`@returns`**
`true` if an email is required to complete the action, and that a verification email has been sent to complete the action.
---
**<span className="parameter-name">signUpEmailSecurityKey</span>** <span className="optional-status">required</span> <code>SignUpSecurityKeyHandler</code>
Used for a new user to sign up with a security key. Returns a promise with the current context
---

View File

@@ -0,0 +1,16 @@
---
title: useAddSecurityKey()
sidebarTitle: useAddSecurityKey()
---
Use the composable `useAddSecurityKey` to add a WebAuthn security key.
```tsx
const { add, isLoading, isSuccess, isError, error } = useAddSecurityKey()
const handleFormSubmit = async (e) => {
e.preventDefault()
await add('key nickname')
}
```

View File

@@ -0,0 +1,16 @@
---
title: useElevateSecurityKeyEmail()
sidebarTitle: useElevateSecurityKeyEmail()
---
Use the composable `useElevateSecurityKeyEmail` to elevate the user auth permission in order to perform sensitive operations
```ts
const { elevateEmailSecurityKey, elevated } = useElevateSecurityKeyEmail()
watchEffect(() => {
console.log(elevated)
})
await elevateEmailSecurityKey('joe@example.com')
```

View File

@@ -0,0 +1,25 @@
---
title: useSignInEmailSecurityKey()
sidebarTitle: useSignInEmailSecurityKey()
---
Use the composable `useSignInEmailSecurityKey` to sign in a user using their email and a security key using the WebAuthn API.
```tsx
const {
signInEmailSecurityKey,
needsEmailVerification,
isLoading,
isSuccess,
isError,
error
} = useSignInEmailSecurityKey()
console.log({ needsEmailVerification, isLoading, isSuccess, isError, error })
const handleFormSubmit = async (e) => {
e.preventDefault()
await signInEmailSecurityKey('joe@example.com')
}
```

View File

@@ -0,0 +1,33 @@
---
title: useSignUpEmailSecurityKey()
sidebarTitle: useSignUpEmailSecurityKey()
---
Use the composable `useSignUpEmailSecurityKey` to sign up a user with security key and an email using the WebAuthn API.
```ts
const {
signUpEmailSecurityKey,
needsEmailVerification,
isLoading,
isSuccess,
isError,
error
} = useSignUpEmailSecurityKey()
console.log({ needsEmailVerification, isLoading, isSuccess, isError, error })
const handleFormSubmit = async (e) => {
e.preventDefault()
await signUpEmailSecurityKey('joe@example.com')
}
```
## Parameters
---
**<span className="parameter-name">options</span>** <span className="optional-status">optional</span> <code>SignUpSecurityKeyOptions</code>
---

View File

@@ -1,5 +1,29 @@
# @nhost-examples/cli
## 0.1.8
### Patch Changes
- @nhost/nhost-js@3.0.7
## 0.1.7
### Patch Changes
- @nhost/nhost-js@3.0.6
## 0.1.6
### Patch Changes
- @nhost/nhost-js@3.0.5
## 0.1.5
### Patch Changes
- @nhost/nhost-js@3.0.4
## 0.1.4
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/cli",
"version": "0.1.4",
"version": "0.1.8",
"main": "src/index.mjs",
"private": true,
"scripts": {

View File

@@ -1,5 +1,34 @@
# @nhost-examples/codegen-react-apollo
## 0.1.16
### Patch Changes
- @nhost/react@3.2.2
- @nhost/react-apollo@9.0.2
## 0.1.15
### Patch Changes
- @nhost/react-apollo@9.0.1
- @nhost/react@3.2.1
## 0.1.14
### Patch Changes
- Updated dependencies [017f1a6]
- @nhost/react@3.2.0
- @nhost/react-apollo@9.0.0
## 0.1.13
### Patch Changes
- @nhost/react@3.1.1
- @nhost/react-apollo@8.0.1
## 0.1.12
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/codegen-react-apollo",
"version": "0.1.12",
"version": "0.1.16",
"private": true,
"scripts": {
"codegen": "graphql-codegen",

View File

@@ -1,5 +1,30 @@
# @nhost-examples/codegen-react-query
## 0.1.17
### Patch Changes
- @nhost/react@3.2.2
## 0.1.16
### Patch Changes
- @nhost/react@3.2.1
## 0.1.15
### Patch Changes
- Updated dependencies [017f1a6]
- @nhost/react@3.2.0
## 0.1.14
### Patch Changes
- @nhost/react@3.1.1
## 0.1.13
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/codegen-react-query",
"version": "0.1.13",
"version": "0.1.17",
"private": true,
"scripts": {
"codegen": "graphql-codegen",

View File

@@ -1,5 +1,34 @@
# @nhost-examples/react-urql
## 0.0.13
### Patch Changes
- @nhost/react@3.2.2
- @nhost/react-urql@6.0.2
## 0.0.12
### Patch Changes
- @nhost/react@3.2.1
- @nhost/react-urql@6.0.1
## 0.0.11
### Patch Changes
- Updated dependencies [017f1a6]
- @nhost/react@3.2.0
- @nhost/react-urql@6.0.0
## 0.0.10
### Patch Changes
- @nhost/react@3.1.1
- @nhost/react-urql@5.0.1
## 0.0.9
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@nhost-examples/codegen-react-urql",
"private": true,
"version": "0.0.9",
"version": "0.0.13",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",

View File

@@ -1,5 +1,31 @@
# Change all these variables before first creating the containers
POSTGRES_PASSWORD=secret-pg-password-never-use-this-value
HASURA_GRAPHQL_ADMIN_SECRET=nhost-admin-secret
HASURA_GRAPHQL_ADMIN_SECRET=change-me
# The jwt secret key can be generated with `openssl rand -hex 32`
HASURA_GRAPHQL_JWT_SECRET='{"type":"HS256", "key":"5152fa850c02dc222631cca898ed1485821a70912a6e3649c49076912daa3b62182ba013315915d64f40cddfbb8b58eb5bd11ba225336a6af45bbae07ca873f3","issuer":"hasura-auth"}'
STORAGE_ACCESS_KEY=storage-access-key-never-use-this-value
STORAGE_SECRET_KEY=storage-secret-key-never-use-this-value
# The following HOST and URL env variables are separated since the HOST variables are used to define the allowed hosts to the traefik services in the docker-compose.yaml
# Public (proxy.my-nhost.com) or private (localhost) hostname for the Hasura API/proxy for the Nhost dashboard to send requests to
PROXY_HOST=localhost
# Change to https://${PROXY_HOST} if not using localhost
PROXY_URL=http://${PROXY_HOST}:1337
# Public (example-url.my-nhost.com) or private (localhost) hostname for the Nhost dashboard for the proxy to allow requests from
NHOST_HOST=localhost
# Environment variables for the Nhost Dashboard. See dashboard/.env.example for default values. The defualt values are changed to work with our traefik setup created with the docker-compose
# URL for the migrations API running from running `hasura-console`. If it needs to be publicly accessible, change it to your publicly-available URL (https://hasura-migrations.my-nhost.com)
NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL=http://localhost:9693
# The following do not need to be changed unless you modified the docker-compose.yaml
NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL=${PROXY_URL}
NEXT_PUBLIC_NHOST_HASURA_API_URL=${PROXY_URL}
NEXT_PUBLIC_NHOST_ADMIN_SECRET=${HASURA_GRAPHQL_ADMIN_SECRET}
NEXT_PUBLIC_NHOST_AUTH_URL=${PROXY_URL}/v1/auth
NEXT_PUBLIC_NHOST_GRAPHQL_URL=${PROXY_URL}/v1/graphql
NEXT_PUBLIC_NHOST_STORAGE_URL=${PROXY_URL}/v1/storage
NEXT_PUBLIC_NHOST_FUNCTIONS_URL=${PROXY_URL}/v1/functions

View File

@@ -1,5 +1,17 @@
# @nhost-examples/docker-compose
## 0.1.1
### Patch Changes
- aff059e: fix: timers
## 0.1.0
### Minor Changes
- ed9df85: updated docker-compose.yaml and .env-example
## 0.0.7
### Patch Changes

View File

@@ -8,9 +8,14 @@ services:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:1337"
- "--entryPoints.admin.address=:3030"
ports:
# hasura/services
- "1337:1337"
# traefik interface
- "9090:8080"
# dashboard
- "3030:3030"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
postgres:
@@ -24,7 +29,7 @@ services:
ports:
- '5432:5432'
graphql-engine:
image: hasura/graphql-engine:v2.15.2
image: hasura/graphql-engine:v2.35.1
depends_on:
- 'postgres'
restart: always
@@ -37,12 +42,19 @@ services:
HASURA_GRAPHQL_UNAUTHORIZED_ROLE: public
HASURA_GRAPHQL_LOG_LEVEL: debug
HASURA_GRAPHQL_ENABLE_CONSOLE: 'true'
healthcheck:
test:
- CMD-SHELL
- curl http://localhost:8080/healthz > /dev/null 2>&1
timeout: 60s
interval: 30s
start_period: 90s
labels:
- "traefik.enable=true"
- "traefik.http.routers.hasura.rule=Host(`localhost`) && PathPrefix(`/`)"
- "traefik.http.routers.hasura.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/`)"
- "traefik.http.routers.hasura.entrypoints=web"
auth:
image: nhost/hasura-auth:0.16.2
image: nhost/hasura-auth:0.24
depends_on:
- postgres
- graphql-engine
@@ -61,16 +73,16 @@ services:
AUTH_SMTP_USER: user
AUTH_SMTP_PASS: password
AUTH_SMTP_SENDER: mail@example.com
expose:
expose:
- 4000
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.strip-auth.stripprefix.prefixes=/v1/auth"
- "traefik.http.routers.auth.rule=Host(`localhost`) && PathPrefix(`/v1/auth`)"
- "traefik.http.routers.auth.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/v1/auth`)"
- "traefik.http.routers.auth.middlewares=strip-auth@docker"
- "traefik.http.routers.auth.entrypoints=web"
storage:
image: nhost/hasura-storage:0.3.1
image: nhost/hasura-storage:0.4.1
depends_on:
- postgres
- graphql-engine
@@ -79,7 +91,7 @@ services:
expose:
- 8000
environment:
PUBLIC_URL: http://localhost:${PROXY_PORT:-1337}
PUBLIC_URL: ${PROXY_URL}
HASURA_METADATA: 1
HASURA_ENDPOINT: http://graphql-engine:8080/v1
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
@@ -91,7 +103,7 @@ services:
POSTGRES_MIGRATIONS_SOURCE: postgres://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres?sslmode=disable
labels:
- "traefik.enable=true"
- "traefik.http.routers.storage.rule=Host(`localhost`) && PathPrefix(`/v1/storage`)"
- "traefik.http.routers.storage.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/v1/storage`)"
- "traefik.http.routers.storage.entrypoints=web"
# Rewrite the path so it matches with the new storage API path introduced in hasura-storage 0.2
- "traefik.http.middlewares.strip-suffix.replacepathregex.regex=^/v1/storage/(.*)"
@@ -99,15 +111,15 @@ services:
- "traefik.http.routers.storage.middlewares=strip-suffix@docker"
command: serve
functions:
image: nhost/functions:0.1.8
image: nhost/functions:1.0.0
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.strip-functions.stripprefix.prefixes=/v1/functions"
- "traefik.http.routers.functions.rule=Host(`localhost`) && PathPrefix(`/v1/functions`)"
- "traefik.http.routers.functions.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/v1/functions`)"
- "traefik.http.routers.functions.middlewares=strip-functions@docker"
- "traefik.http.routers.functions.entrypoints=web"
restart: always
expose:
expose:
- 3000
volumes:
- .:/opt/project
@@ -135,13 +147,29 @@ services:
SMTP_SECURE: "${AUTH_SMTP_SECURE:-false}"
SMTP_SENDER: ${AUTH_SMTP_SENDER:-hbp@hbp.com}
ports:
- ${AUTH_SMTP_PORT:-1025}:1025
- ${AUTH_SMTP_PORT:-1025}:1025
- 8025:8025
volumes:
- ./data/mailhog:/maildir
dashboard:
image: nhost/dashboard:0.7.4
ports:
- "3030:3000"
image: nhost/dashboard:0.21.1
environment:
NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL: ${NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL}
NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL: ${NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL}
NEXT_PUBLIC_NHOST_HASURA_API_URL: ${NEXT_PUBLIC_NHOST_HASURA_API_URL}
NEXT_PUBLIC_NHOST_ADMIN_SECRET: ${NEXT_PUBLIC_NHOST_ADMIN_SECRET}
NEXT_PUBLIC_NHOST_AUTH_URL: ${NEXT_PUBLIC_NHOST_AUTH_URL}
NEXT_PUBLIC_NHOST_GRAPHQL_URL: ${NEXT_PUBLIC_NHOST_GRAPHQL_URL}
NEXT_PUBLIC_NHOST_STORAGE_URL: ${NEXT_PUBLIC_NHOST_STORAGE_URL}
NEXT_PUBLIC_NHOST_FUNCTIONS_URL: ${NEXT_PUBLIC_NHOST_FUNCTIONS_URL}
expose:
- 3000
labels:
- "traefik.enable=true"
- "traefik.http.routers.nhost.rule=Host(`${NHOST_HOST}`)"
- "traefik.http.routers.nhost.entrypoints=admin"
# If you would like to protect your dashboard with a username and password if it is publicly-facing, uncomment and fill in the following lines below according to the documentation at https://doc.traefik.io/traefik/middlewares/http/basicauth/
#- "traefik.http.routers.nhost.middlewares=auth"
#- "traefik.http.middlewares.auth.basicauth.users=
volumes:
functions_node_modules:

View File

@@ -0,0 +1,5 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/docker-compose",
"version": "0.0.7",
"version": "0.1.1",
"private": true,
"scripts": {
"e2e": "vitest run"

View File

@@ -11,8 +11,12 @@ describe(
beforeAll(async () => {
// * Start docker compose
await promisifiedExec(
'docker compose -f docker-compose.yaml --env-file .env.example up --wait --quiet-pull'
'docker compose -f docker-compose.yaml --env-file .env.example up --wait --wait-timeout 300 --quiet-pull'
)
// we wait a bit extra because sometimes traefik takes a bit to configure the services
setTimeout(() => {}, 30000);
}, 5 * 60 * 1000)
afterAll(async () => {

View File

@@ -1,5 +1,29 @@
# @nhost-examples/multi-tenant-one-to-many
## 2.0.6
### Patch Changes
- @nhost/nhost-js@3.0.7
## 2.0.5
### Patch Changes
- @nhost/nhost-js@3.0.6
## 2.0.4
### Patch Changes
- @nhost/nhost-js@3.0.5
## 2.0.3
### Patch Changes
- @nhost/nhost-js@3.0.4
## 2.0.2
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@nhost-examples/multi-tenant-one-to-many",
"private": true,
"version": "2.0.2",
"version": "2.0.6",
"description": "",
"main": "index.js",
"scripts": {},

View File

@@ -1,5 +1,38 @@
# @nhost-examples/nextjs
## 0.1.18
### Patch Changes
- @nhost/react@3.2.2
- @nhost/react-apollo@9.0.2
- @nhost/nextjs@2.1.4
## 0.1.17
### Patch Changes
- @nhost/react-apollo@9.0.1
- @nhost/react@3.2.1
- @nhost/nextjs@2.1.3
## 0.1.16
### Patch Changes
- Updated dependencies [017f1a6]
- @nhost/react@3.2.0
- @nhost/react-apollo@9.0.0
- @nhost/nextjs@2.1.2
## 0.1.15
### Patch Changes
- @nhost/react@3.1.1
- @nhost/react-apollo@8.0.1
- @nhost/nextjs@2.1.1
## 0.1.14
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/nextjs",
"version": "0.1.14",
"version": "0.1.18",
"private": true,
"scripts": {
"dev": "next dev",

View File

@@ -1,5 +1,29 @@
# @nhost-examples/node-storage
## 0.0.10
### Patch Changes
- @nhost/nhost-js@3.0.7
## 0.0.9
### Patch Changes
- @nhost/nhost-js@3.0.6
## 0.0.8
### Patch Changes
- @nhost/nhost-js@3.0.5
## 0.0.7
### Patch Changes
- @nhost/nhost-js@3.0.4
## 0.0.6
### Patch Changes

Some files were not shown because too many files have changed in this diff Show More