Compare commits

..

168 Commits

Author SHA1 Message Date
Pilou
57780ee645 Merge pull request #333 from nhost/changeset-release/main
chore: update versions
2022-04-03 15:35:58 +02:00
github-actions[bot]
aad8d22380 chore: update versions 2022-04-03 13:28:59 +00:00
Pilou
85d33c4de0 Merge pull request #332 from nhost/fix/auto-signin
fix: correct auto-signin bug introducted in previous version
2022-04-03 15:28:16 +02:00
Pierre-Louis Mercereau
ab3e2dcee9 refactor: remove log 2022-04-03 15:22:11 +02:00
Pierre-Louis Mercereau
12f4504b61 refactor: remove incorrect and unused snapshot script 2022-04-03 15:19:00 +02:00
Pierre-Louis Mercereau
71d7a11c96 refactor: correct script 2022-04-03 15:11:48 +02:00
Pierre-Louis Mercereau
16a6c5073e fix: correct auto-signin bug introducted in previous version 2022-04-03 15:05:13 +02:00
Pilou
3fcc86792a Merge branch 'main' into main 2022-04-03 13:40:31 +02:00
Pierre-Louis Mercereau
27909128e4 chore: bump versions to fix the workspace/package link bug 2022-04-02 11:25:38 +02:00
Pierre-Louis Mercereau
72371c72a1 chore: bump versions 2022-04-02 10:58:56 +02:00
Pierre-Louis Mercereau
d878414b10 ci: freeze node version 2022-04-02 10:52:27 +02:00
Pilou
4fd09b4080 Merge pull request #316 from nhost/changeset-release/main
chore: update versions
2022-04-01 16:18:58 +02:00
Pilou
bdb786fa83 Merge pull request #313 from chrtze/patch-2
Update hooks.mdx
2022-04-01 13:35:56 +02:00
Pierre-Louis Mercereau
d42be972b4 Merge branch 'main' into patch-2 2022-04-01 13:31:25 +02:00
Pierre-Louis Mercereau
5920c830b3 docs: minor adjustments 2022-04-01 13:25:32 +02:00
Pilou
5fc16653c0 Update index.mdx 2022-04-01 08:50:49 +02:00
Pilou
900ec48889 Update index.mdx 2022-04-01 08:45:55 +02:00
github-actions[bot]
cf20ee5a8f chore: update versions 2022-03-31 14:45:03 +00:00
Pilou
9180154325 Merge pull request #231 from nhost/hasura-auth-documentation
Hasura auth documentation
2022-03-31 16:44:19 +02:00
Pilou
1ae025b745 Merge pull request #310 from nhost/309-nhostclient-constructor-error-using-expo
fix: check if `window.location` exists
2022-03-31 16:16:55 +02:00
Pilou
ba538a4ad9 Merge pull request #315 from nhost/fix/wait-authentication-loaded
fix(sdk): wait for the authentication status to be known before executing auth actions
2022-03-31 16:15:07 +02:00
Szilárd Dóró
0e5e47b8f8 Merge pull request #314 from nhost/fix/token-refresh-usequery
fix: Query refetch and leaking GraphQL subscription
2022-03-31 15:06:05 +02:00
Szilárd Dóró
113beed447 added changeset 2022-03-31 14:53:10 +02:00
Pierre-Louis Mercereau
6eeb9d2e65 fix(sdk): wait for the authentication status to be known before executing auth actions 2022-03-31 14:47:31 +02:00
Szilárd Dóró
3db2959bc2 fixed query refetch and leaking GraphQL subscriptions when issuing new JWT token 2022-03-31 14:23:33 +02:00
Pierre-Louis Mercereau
16fcc08b0a refactor: simplify code 2022-03-31 13:53:08 +02:00
Christopher Möller
5b098c8ef4 Update hooks.mdx 2022-03-31 12:51:37 +02:00
Pierre-Louis Mercereau
d3384614b4 fix: typeof window still needs to be used 2022-03-31 11:28:16 +02:00
Pierre-Louis Mercereau
0064fccb12 docs: last missing suggestions 2022-03-31 11:25:16 +02:00
Pierre-Louis Mercereau
6efd45fcb7 docs: take suggestions into account - missing pieces 2022-03-31 11:23:22 +02:00
Pierre-Louis Mercereau
4420c0e070 fix: check if window.location exists 2022-03-31 11:18:05 +02:00
Pierre-Louis Mercereau
354b07947a docs(hasura-auth): update swagger to hasura-auth 0.5.0 2022-03-31 11:01:16 +02:00
Pierre-Louis Mercereau
2fa5c10e14 chore: merge main 2022-03-31 08:57:07 +02:00
Pierre-Louis Mercereau
94124c7754 docs: improve explainations 2022-03-31 08:54:49 +02:00
Johan Eliasson
e405b738a6 Update README.md (#307) 2022-03-30 16:19:30 +02:00
Pierre-Louis Mercereau
947b7e037f fix: correct dependency bump 2022-03-29 16:33:40 +02:00
github-actions[bot]
cd6f37f2a6 chore: update versions (#304)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-03-29 16:11:46 +02:00
Pilou
39df4d5b9c Deprecate useAuthLoading and introduce useAuthenticationStatus (#303)
* fix(react): keep authentication and loading status in sync

fix #302

* style: typo
2022-03-29 13:21:50 +02:00
Pierre-Louis Mercereau
63ee1d7659 docs: correct typo and code blocks 2022-03-28 17:18:58 +02:00
Pierre-Louis Mercereau
eb33952760 docs: take Szilard's comments into account 2022-03-28 14:18:59 +02:00
Pilou
e91215bbac Docs/nextjs (#299)
* fix: correct access to user/session information through getUser/getSession/isReady

* chore: use carret instead of star

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

* docs: correct imports in nextjs example

* chore: remove orphan changeset

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

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

* Update README.md

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

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

* chore: bump to latest sdk version

* chore: bump to latest version

* chore: bump example version
2022-03-25 14:49:35 +00:00
github-actions[bot]
9ff9abee6a chore: update versions (#293)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-03-25 11:50:45 +00:00
Pilou
9d3f0521a5 fix: keep location.hash in email redirections (#294)
In the next cycle, hasura-auth will only send the refresh token in the hash, and will add the
redirection type as a query parameter. We will then be able to remove/hide the hash from the url as
soon as the refresh token has been used
2022-03-25 11:34:41 +00:00
Pilou
744fd6929f Unify @nhost/react and @nhost/nhost-js (#273)
* chore: rename `@nhost/client` to `@nhost/core`

* chore: refactor hasura-auth-js to use @nhost/core

all existing tests pass

* refactor: adapt syntax to react, and rename machine to authMachine

* refactor: rename to authmachine and remove useless license files

pnpm uses the root license file when publishing packages

* feat: totp login+password

* refactor: passwordless sms, mfa, deanonymize

* refactor: state/value mfa code

* refactor: rename

* refactor: auth status and token change events

* refactor: adjust apollo to original syntax, and sync auth session accross all nhost-js sub-clients

* refactor: revert changelog and adjust documentation

* refactor: adjust to the shape-up signatures

* refactor: make nextjs work with the new system

* refactor: allow async storage getters and setters

* refactor: implement refreshSession

* chore: fix pnpm lock file

* docs: change NhostReactProvider to NhostNextProvider

* chore: changesets

* refactor: change signup/signin hooks signatures as per Johan's request

* refactor: remove `nhost.auth.verifyEmail`

* chore: add changeset

* docs: add mfa to the react example, and adjust examples to the new conventions

* feat: allow oauth providers to get options

* fix: sync sdk client with the machine state

* fix: don't use state.matches and state.hasTag in useSelector, and improve useSelectors

* refactor: set oauth options everywhere, document, and rewrite relative redirectTo

* chore: update pnpm lock file

* fix: correct paths to cjs dist file, and reactivate warning suppression about useLayoutEffect

* chore: keep the same parameters in the React Apollo providers

* refactor: use the new system in @nhost/react-auth, and mark it as deprecated

* chore: @nhost/react-auth changeset

* chore: update pnpm lock file

* docs: remove todos and point to the documenation when it exists

* docs: name files `.tsx` instead of `.jsx`

* refactor: retro-compatible clientStorageType and clientStorage options

* refactor: improve hooks names consistency

See https://github.com/nhost/nhost/pull/273#discussion_r829058348

* chore: don't override changelog

* refactor: bump hasura-auth to version 0.4.2

* refactor: move @apollo/client to a peer dependency

This was the case in the origination @nhost/react-apollo package

* refactor: prettier

* refactor: rename useConfigMfa properties

* chore: ellaborate changesets

* refactor: rename `anonymousSignIn` to `signInAnonymous`

* docs: correct typo

* refactor: rename anonymous signin hook

* refactor: use @nhost/nextjs instead of @nhost/react in Nextjs documentation

* chore: explain renaming from @nhost/client to @nhost/core

* chore: changeset

* chore: complete sentence in changeset
2022-03-24 20:37:56 +00:00
Szilárd Dóró
f43f52e766 updated react-apollo changelog (#292) 2022-03-24 12:33:31 +00:00
github-actions[bot]
fd4c54ee91 chore: update versions (#290)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-03-24 09:58:40 +00:00
Szilárd Dóró
b30ff6f507 fix: Auth header condition check (#291)
* fixed auth header conditions in storage functions

* fixed lint errors in hasura-storage-js package

* removed patch changeset file
2022-03-24 09:56:25 +00:00
Pilou
ff7ae21a87 feat: admin secret for storage (#289)
* added Hasura Admin Secret support to storage functions

* @nhost/hasura-storage-js changelog

Co-authored-by: Szilárd Dóró <szilard.doro@bishop.hu>
2022-03-23 16:55:30 +00:00
Pierre-Louis Mercereau
b2c398df22 docs: redirections 2022-03-23 14:35:05 +00:00
Pierre-Louis Mercereau
888192282f docs: hide missing chapters, and add todos 2022-03-23 14:23:07 +00:00
Pierre-Louis Mercereau
945b557dea docs: totp 2022-03-23 14:17:16 +00:00
Pierre-Louis Mercereau
4031d8a9e1 docs: smtp settings 2022-03-23 13:21:49 +00:00
Pierre-Louis Mercereau
c77aa16181 docs: email templates 2022-03-23 13:04:36 +00:00
Pierre-Louis Mercereau
ea2fb2e9a4 docs: extending user schema 2022-03-23 12:50:47 +00:00
Pierre-Louis Mercereau
e147487e27 docs: fix bullet points 2022-03-23 12:39:57 +00:00
Pierre-Louis Mercereau
6f52652e10 docs: hasura integration 2022-03-23 11:49:43 +00:00
Pierre-Louis Mercereau
1a8d9b5c28 docs: overview 2022-03-23 11:39:37 +00:00
Pierre-Louis Mercereau
9111299ddd docs: email passwordless 2022-03-23 11:27:31 +00:00
Pierre-Louis Mercereau
1c7f520073 docs: minor reshape 2022-03-23 11:09:26 +00:00
Pierre-Louis Mercereau
dff37a4cd0 docs: email and password checks 2022-03-23 11:04:53 +00:00
Pierre-Louis Mercereau
96a572379e docs: gravatar 2022-03-23 10:46:17 +00:00
Pierre-Louis Mercereau
da3bbf2e10 chore: update pnpm lockfile 2022-03-23 10:09:13 +00:00
Pierre-Louis Mercereau
a11fa372ff chore: merge main 2022-03-22 12:59:49 +00:00
Jerry Jäppinen
6d2c7b26c0 Formatting and paths (#285) 2022-03-21 15:23:09 +00:00
github-actions[bot]
d2d3ba6eb7 chore: update versions (#272)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-03-15 14:38:45 +01:00
Johan Eliasson
e688600ea2 fix: current options when sign in with a provider (#274)
* fix: current options when sign in with a provider

* Create eighty-pianos-try.md

* Create chilled-swans-repeat.md

* send sign-up options

* doesn't hurt to do encodeURIComponent everywhere

Co-authored-by: Pilou <24897252+plmercereau@users.noreply.github.com>
2022-03-15 14:32:09 +01:00
Hoang Do
d9aec711c4 Fix(nhost-js): Fix typo in README (#283) 2022-03-15 07:03:41 +01:00
Dominic Garms
9bd01e756f export refresh function (#281)
* export refresh utilitly function

For being able to receive a new accessToken on client side it would be ideal to expose the `refresh` function.

* Create loud-planets-impress.md

Co-authored-by: Pilou <24897252+plmercereau@users.noreply.github.com>
2022-03-14 18:33:52 +01:00
Pilou
8f7643a90e fix: change target ES module build target to es2019 (#282) 2022-03-14 18:32:27 +01:00
Johan Eliasson
50b9d763ae feat: correct available providers (Discord & Twitch added) (#266)
* feat: correct available providers (Discord & Twitch added)

* Create hip-eels-unite.md

* putting back proviers

Co-authored-by: Pierre-Louis Mercereau <24897252+plmercereau@users.noreply.github.com>
2022-03-11 08:11:57 +01:00
Quentin Decré
63cb1f0ce6 doc(hasura-auth-client): fixed onAuthStateChanged @example (#268) 2022-03-10 18:42:38 +01:00
Pilou
7c70b1823d fix broken ci pipeline (#267)
* ci: clean ci

* ci: matrix

* ci: install dependencies

* ci: debug

* ci: updated packages

* ci: remove scope

* ci: add src to files

* ci: deactivate turbo cache

* ci: debug

* ci: downgrade turborepo

* ci: reverse version

* ci: installl again

* ci: pwd

* ci: increase depth

* ci: decrease pnpm version

* ci: another turbo version

* ci: 1.1.5

* ci: clean

* ci: frozen lockfile

* ci: add options

* ci: deactivate cache

* ci: single ci command

* ci: correct

* ci: desesperant

* ci: again

* ci: again

* ci: remove testing project

* ci: remove testing project

* ci: exec nhost in tmp

* ci: deactivate nhost

* ci: manually create nhost project

* ci: again

* ci: copy existing nhost project

* ci: correct cp arg

* ci: correct cp

* ci: cd, not cp

* ci: wrap up

* ci: scope ci script
2022-03-10 13:16:48 +01:00
Pierre-Louis Mercereau
47c57ff665 ci: scope ci script 2022-03-10 13:12:08 +01:00
Pierre-Louis Mercereau
1cb330016b ci: wrap up 2022-03-10 13:06:17 +01:00
Pierre-Louis Mercereau
497652d1b4 ci: cd, not cp 2022-03-10 13:00:22 +01:00
Pierre-Louis Mercereau
20eb7aa381 ci: correct cp 2022-03-10 12:58:54 +01:00
Pierre-Louis Mercereau
4a3c2f92b1 ci: correct cp arg 2022-03-10 12:57:38 +01:00
Pierre-Louis Mercereau
5647e64265 ci: copy existing nhost project 2022-03-10 12:55:43 +01:00
Pierre-Louis Mercereau
c113debf46 ci: again 2022-03-10 12:52:49 +01:00
Pierre-Louis Mercereau
3f0ae4a58c ci: manually create nhost project 2022-03-10 12:50:36 +01:00
Pierre-Louis Mercereau
3d5b8183e8 ci: deactivate nhost 2022-03-10 12:47:38 +01:00
Pierre-Louis Mercereau
789ef8f783 ci: exec nhost in tmp 2022-03-10 12:44:45 +01:00
Pierre-Louis Mercereau
94df175ca3 ci: remove testing project 2022-03-10 12:41:24 +01:00
Pierre-Louis Mercereau
c8bcefb0e5 ci: remove testing project 2022-03-10 12:40:20 +01:00
Pierre-Louis Mercereau
fc52f59eb8 ci: again 2022-03-10 12:37:39 +01:00
Pierre-Louis Mercereau
a80389e5c7 ci: again 2022-03-10 12:30:57 +01:00
Pierre-Louis Mercereau
923276422b ci: desesperant 2022-03-10 12:28:43 +01:00
Pierre-Louis Mercereau
7c9192f3a0 ci: correct 2022-03-10 12:24:33 +01:00
Pierre-Louis Mercereau
51d139b7aa ci: single ci command 2022-03-10 12:21:58 +01:00
Pierre-Louis Mercereau
8fe1bdb6f7 ci: deactivate cache 2022-03-10 12:19:01 +01:00
Pierre-Louis Mercereau
5b288bc0d1 ci: add options 2022-03-10 12:18:38 +01:00
Pierre-Louis Mercereau
27cd769c76 ci: frozen lockfile 2022-03-10 12:16:08 +01:00
Pierre-Louis Mercereau
5bb370869d ci: clean 2022-03-10 12:13:57 +01:00
Pierre-Louis Mercereau
ec68f64db4 ci: 1.1.5 2022-03-10 12:11:48 +01:00
Pierre-Louis Mercereau
4cf8f146c9 ci: another turbo version 2022-03-10 12:08:16 +01:00
Pierre-Louis Mercereau
61cf317541 ci: decrease pnpm version 2022-03-10 12:04:03 +01:00
Pierre-Louis Mercereau
a2066c9b41 ci: increase depth 2022-03-10 12:02:25 +01:00
Pierre-Louis Mercereau
817b152704 ci: pwd 2022-03-10 12:00:40 +01:00
Pierre-Louis Mercereau
cc73494c91 ci: installl again 2022-03-10 11:58:05 +01:00
Pierre-Louis Mercereau
64ed4083b9 ci: reverse version 2022-03-10 11:54:12 +01:00
Pierre-Louis Mercereau
77e8c58cc6 ci: downgrade turborepo 2022-03-10 11:48:33 +01:00
Pierre-Louis Mercereau
0cd2eab309 ci: debug 2022-03-10 11:43:58 +01:00
Pierre-Louis Mercereau
7d8c843c74 ci: deactivate turbo cache 2022-03-10 11:41:34 +01:00
Pierre-Louis Mercereau
da1c2d6914 ci: add src to files 2022-03-10 11:38:58 +01:00
Pierre-Louis Mercereau
3a949301f9 ci: remove scope 2022-03-10 11:34:43 +01:00
Pierre-Louis Mercereau
585eebab49 ci: updated packages 2022-03-10 11:30:05 +01:00
Pierre-Louis Mercereau
45c3e4686e ci: debug 2022-03-10 11:26:04 +01:00
Pierre-Louis Mercereau
52f2e67952 ci: install dependencies 2022-03-10 11:22:24 +01:00
Pierre-Louis Mercereau
929774aa5b ci: matrix 2022-03-10 11:21:04 +01:00
Pierre-Louis Mercereau
e711e338e7 ci: clean ci 2022-03-10 11:18:56 +01:00
Pierre-Louis Mercereau
d2aae774a0 ci: wait-for at the end 2022-03-10 11:10:33 +01:00
Pierre-Louis Mercereau
322e8a1b07 ci: recreate pnpm lock 2022-03-10 11:07:24 +01:00
Pierre-Louis Mercereau
d154f8d71b ci: checkout twice 2022-03-10 11:00:53 +01:00
Pierre-Louis Mercereau
0931afd84c ci: nhost cli at the top 2022-03-10 10:48:17 +01:00
Pierre-Louis Mercereau
837548cfd5 ci: wrap wait-on in an action 2022-03-10 10:43:40 +01:00
Pierre-Louis Mercereau
a6cabbca79 ci: deactivate wait-on 2022-03-10 10:37:55 +01:00
Pierre-Louis Mercereau
82f19fe717 ci: internal wait-on script 2022-03-10 10:35:19 +01:00
Pierre-Louis Mercereau
82be281153 ci: use npx 2022-03-10 10:28:31 +01:00
Pierre-Louis Mercereau
0112ca775f ci: start nhost cli 2022-03-10 10:22:34 +01:00
Pierre-Louis Mercereau
b30b812b93 ci: install nhost cli 2022-03-10 10:20:52 +01:00
Pierre-Louis Mercereau
bace64c306 ci: without nhost 2022-03-10 10:19:40 +01:00
Pierre-Louis Mercereau
be49b641e3 ci: deactivate all cache 2022-03-10 10:16:56 +01:00
Pierre-Louis Mercereau
5ac8c2f516 ci: deactivate turborepo cache 2022-03-10 10:12:38 +01:00
Pierre-Louis Mercereau
168ae1d82b ci: reactivate all ci steps 2022-03-10 10:08:46 +01:00
Pierre-Louis Mercereau
b4a2e28fc3 ci: manually install node packages 2022-03-10 10:05:31 +01:00
Pierre-Louis Mercereau
ca3ae21286 ci: try explicit pnpm install params 2022-03-10 10:01:54 +01:00
Pierre-Louis Mercereau
9f30c1af09 ci: debug 2022-03-10 09:51:16 +01:00
Pierre-Louis Mercereau
e1f9f64910 ci: deactivate all cache 2022-03-10 09:48:36 +01:00
Pierre-Louis Mercereau
2634dd8335 ci: deactivate turborepo cache 2022-03-10 09:46:30 +01:00
Pierre-Louis Mercereau
42b4c78d4c ci: correct gh action 2022-03-10 09:44:01 +01:00
Pierre-Louis Mercereau
54174c1b0f ci: change gh action 2022-03-10 09:41:06 +01:00
Johan Eliasson
9fad359ae9 docs: Added docs for permission variables (#263)
* added docs for permissions

* update

* wording update

* typos
2022-03-09 14:15:10 +01:00
Johan Eliasson
1cbf460223 added Nhost diagram (#265) 2022-03-09 13:37:06 +01:00
Pilou
8a3aa007b8 Update README.md (#258) 2022-03-08 21:55:28 +01:00
github-actions[bot]
21b02a39e4 chore: update versions (#254)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-03-05 17:52:43 +01:00
Pilou
0d8afde2c3 improve examples, fix interdependencies, move examples away from the monorepo (#253)
* fix: improve examples, fix interdependencies, move examples away from the monorepo

* docs: flag the nextjs example as WIP

* docs: describe changesets
2022-03-05 17:43:49 +01:00
Pierre-Louis Mercereau
f366158d02 ci: improve turborepo caching 2022-03-05 16:50:21 +01:00
Pierre-Louis Mercereau
2c8aac2123 ci: simplify cache hash 2022-03-05 16:43:45 +01:00
Pierre-Louis Mercereau
2d9f6fbcfc ci: simplify turborepo cache key 2022-03-05 16:38:50 +01:00
Pierre-Louis Mercereau
31c845823d ci: correct gh action 2022-03-05 16:29:31 +01:00
Johan Eliasson
f949da055e Docs for social sign-in providers (#232)
* added Google

* added base for facebook, github, linkedin

* use sign-in instead of login

* order

* added docs for facebook, github and linkedin

* added spotify docs

* added Microsoft

* use Microsoft instead of Windows

* remove microsoft for now

* links + info about client URL

* wording

Co-authored-by: Guido Curcio <guidomaurocurcio@gmail.com>
2022-03-05 11:47:44 +01:00
Pierre-Louis Mercereau
0cd1654f88 docs: add readme and remove file that's not ready 2022-03-04 19:16:52 +01:00
Pilou
a71ae28192 docs: improve NextJS example (#252)
add basic input fields to the main page, and create a basic readme
2022-03-04 19:13:48 +01:00
Johan Eliasson
bd56c3522b Update README.md 2022-03-04 12:53:05 +01:00
Pierre-Louis Mercereau
a00152b8b6 chore: clean changelogs 2022-03-04 10:18:46 +01:00
Pierre-Louis Mercereau
4235eb812e Merge branch 'main' into hasura-auth-documentation 2022-03-04 09:59:48 +01:00
Pierre-Louis Mercereau
ed145234b2 Merge branch 'main' into hasura-auth-documentation 2022-03-04 09:52:42 +01:00
Pierre-Louis Mercereau
7c2597ddc7 chore: merge main 2022-03-04 09:52:11 +01:00
Pierre-Louis Mercereau
2b1f8182f2 docs: add hasura auth schema 2022-03-03 11:09:15 +01:00
Pierre-Louis Mercereau
ded9e7637a chore: fix lockfile 2022-02-24 22:31:07 +01:00
Pilou
c42fb85bae Merge branch 'main' into hasura-auth-documentation 2022-02-24 22:26:44 +01:00
Pierre-Louis Mercereau
33edc4291b docs(hasura-auth): structure documentation 2022-02-24 22:25:17 +01:00
Pierre-Louis Mercereau
df89d804c5 docs(hasura-auth): complete openapi documentation 2022-02-24 21:55:08 +01:00
Pierre-Louis Mercereau
89da44d715 docs: update hasura-auth swagger 2022-02-24 17:32:01 +01:00
Pierre-Louis Mercereau
789faad645 docs: add hasura-auth swagger documentation 2022-02-24 15:59:20 +01:00
Pierre-Louis Mercereau
8c7267cbee chore: merge main 2022-02-24 14:21:27 +01:00
Pilou
96c12ffff1 Correct typo 2022-02-19 13:01:15 +01:00
Pierre-Louis Mercereau
783729a6f6 docs(hasura-auth): move docs to the right directory and adjust the menu 2022-02-10 23:09:30 +01:00
Pierre-Louis Mercereau
60d4dbabdf Merge branch 'main' into hasura-auth-documentation 2022-02-10 22:47:07 +01:00
Pierre-Louis Mercereau
a77ddcdbc2 docs: document hasura-auth v0.2 features 2022-02-03 12:11:16 +01:00
Pierre-Louis Mercereau
f4c8a776a4 docs(wip): basic installation information 2022-02-01 10:37:11 +01:00
Pierre-Louis Mercereau
efbaf08483 docs(wip): add hasura-auth documentation 2022-02-01 10:02:38 +01:00
238 changed files with 23441 additions and 64962 deletions

View File

@@ -25,6 +25,6 @@ esbuild
platform: 'browser',
format: 'esm',
sourcemap: true,
target: 'esnext'
target: 'es2019'
})
.catch(() => process.exit(1))

View File

@@ -38,10 +38,11 @@ export default defineConfig({
fileName: 'index'
},
rollupOptions: {
external: ['react'],
external: ['react', '@nhost/react'],
output: {
globals: {
react: 'react'
react: 'react',
'@nhost/react': '@nhost/react'
}
}
}

View File

@@ -16,29 +16,30 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Cache pnpm modules
uses: actions/cache@v2
- name: Checkout repository
uses: actions/checkout@v2
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-
fetch-depth: 0
- uses: pnpm/action-setup@v2.1.0
with:
version: 6.30.1
run_install: true
version: 6.32.3
# run_install: true
- name: Use Node.js 17
uses: actions/setup-node@v2
with:
node-version: '17.8.0'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Create PR or Publish release
id: changesets
uses: changesets/action@v1
with:
version: pnpm ci:version
version: pnpm run ci:version
commit: 'chore: update versions'
title: 'chore: update versions'
publish: pnpm release
publish: pnpm run ci:publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -27,45 +27,44 @@ on:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
node-version: [14, 16]
steps:
- uses: actions/checkout@v2
- name: Cache pnpm modules
uses: actions/cache@v2
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-
- uses: pnpm/action-setup@v2.0.1
with:
version: 6.30.1
run_install: true
- name: Cache turbo
uses: actions/cache@v2
with:
path: ./node_modules/.cache
key: ${{ runner.os }}-${{ matrix.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-${{ matrix.node-version }}
- name: Install nhost CLI
run: curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | bash
- name: Start Nhost Backend
run: |
cd examples/testing-project
cp -R examples/testing-project /tmp/
cd /tmp/testing-project
nhost dev &
nhost dev -d --no-browser &
- name: Wait for Nhost Backend to start
run: |
pnpm dlx wait-on http://localhost:1337/v1/auth/healthz -i 500 -t 120000
- uses: pnpm/action-setup@v2.2.1
with:
version: 6.32.3
- run: pnpm run ci
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- name: Cache turbo
uses: actions/cache@v2
with:
path: ./node_modules/.cache/turbo
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
turbo-${{ github.job }}-${{ github.ref_name }}-
- name: Install dependencies
run: pnpm install
- name: Wait for Nhost
run: pnpm run wait
- name: Build, tests and lint
run: pnpm run ci

View File

@@ -20,7 +20,7 @@
<hr />
</div>
**Nhost is a serverless backend for web and mobile apps** and is built with the following things in mind:
**Nhost is a serverless backend for web and mobile apps** built with the following things in mind:
- Open Source
- Developer Productivity
@@ -36,6 +36,15 @@ Nhost consists of open source software:
- Serverless Functions: Node.js (JavaScript and TypeScript)
- [Nhost CLI](https://docs.nhost.io/reference/cli) for local development
## Architecture of Nhost
<div align="center">
<br />
<img src="assets/nhost-diagram.png"/>
<br />
<br />
</div>
Visit [https://docs.nhost.io](http://docs.nhost.io) for the complete documentation.
# How to get started
@@ -92,8 +101,8 @@ Nhost libraries and tools
- [JavaScript/TypeScript SDK](https://docs.nhost.io/reference/sdk)
- [Dart and Flutter SDK](https://github.com/nhost/nhost-dart)
- [Nhost CLI](https://docs.nhost.io/reference/cli)
- [Nhost React Auth](https://docs.nhost.io/reference/supporting-libraries/react-auth)
- [Nhost React Apollo](https://docs.nhost.io/reference/supporting-libraries/react-apollo)
- [Nhost React](https://docs.nhost.io/reference/react)
- [Nhost Next.js](https://docs.nhost.io/reference/nextjs)
## Community ❤️

BIN
assets/nhost-diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@@ -2,12 +2,15 @@
## Get started
1. Install dependencies: `yarn`
2. Start dev server: `yarn dev`
From the **root** of the `nhost/nhost` repository:
## NOTES;
```bash
pnpm run clean:all
pnpm i
cd docs
pnpm run dev
```
The content is copied from the main `nhost/nhost` repo. This repo is only to modify styles/react components.
## Structure
@@ -30,8 +33,10 @@ export const orderTwo = {
},
reference: {
sdk: ['index', 'graphql', 'authentication', 'storage', 'functions'],
react: ['index', 'hooks', 'protecting-routes', 'apollo'],
nextjs: ['index', 'configuration', 'protecting-routes', ],
cli: ['index'],
'supporting-libraries': ['react-apollo', 'react-auth']
'hasura-auth': ['index', 'installation', 'configuration', 'environment-variables', 'schema', 'api-reference']
}
};
```

View File

@@ -8,6 +8,7 @@ import React, { DetailedHTMLProps, HTMLProps, PropsWithChildren } from 'react'
import Command from '../Command'
import Divider from '../Divider'
import { Swagger } from '../Swagger'
function Note({ children }: PropsWithChildren<unknown>) {
return (
@@ -65,7 +66,7 @@ const CustomLink = ({
const components = {
img: (props: DetailedHTMLProps<HTMLProps<HTMLImageElement>, HTMLImageElement>) => {
return (
<span className="block mx-10 mt-5 ">
<span className="block mx-10 my-10 ">
<img src={props.src} alt={props.alt} className="mx-auto mt-2" />
</span>
)
@@ -135,6 +136,7 @@ const components = {
}: DetailedHTMLProps<HTMLProps<HTMLTableCellElement>, HTMLTableCellElement>) => {
return <td className={clsx('font-display', className)} {...props} />
},
Swagger,
Mermaid: ({ chart }) => {
const [html, setHtml] = React.useState('')
React.useEffect(() => {

View File

@@ -0,0 +1,29 @@
import SwaggerUI from 'swagger-ui-react'
import 'swagger-ui-react/swagger-ui.css'
const OperationsLayout = (props) => {
const { getComponent } = props
const Operations = getComponent('operations', true)
let SvgAssets = getComponent('SvgAssets')
return (
<div className="swagger-ui">
<SvgAssets />
<Operations />
</div>
)
}
const OperationsLayoutPlugin = () => ({
components: {
OperationsLayout
}
})
export const Swagger: React.FC<{ spec: string }> = ({ spec }) => (
<SwaggerUI
url={`/openapi/${spec}`}
plugins={[OperationsLayoutPlugin]}
layout="OperationsLayout"
supportedSubmitMethods={[]}
/>
)

View File

@@ -0,0 +1,58 @@
---
title: Sign In with Facebook
---
Follow this guide to sign in users with Facebook with your Nhost App.
![Facebook Sign In Preview](/images/platform/social-providers/facebook-preview.png)
# Create Facebook account
- Create a new [Facebook account](https://www.facebook.com/) if you dont have one already.
## Create Facebook App
- Go to [Meta for Developers](https://developers.facebook.com/).
- Click **My Apps** in the top right
- Click **Create App** in the top right.
- Select your **app type** (e.g. Consumer).
- Click **Next**.
- Fill in the **Display name.**
- Click **Create app**.
## Set up Facebook Login
- Click on Add Product in the left menu.
- Click on Setup in the Facebook login card.
- **Dont** complete the quickstart. Instead, follow the next step.
- Click on **Settings** under **Facebook Login** in the left menu.
- Make sure **Embedded Browser OAuth Login** is set to **Yes**.
- Fill in **Valid OAuth Redirect URIs** with your **OAuth Callback URL** from Nhost.
- Click **Save changes**.
## Activate Facebook permissions and features
To make sure we can fetch all user data (email, profile picture and name). For that we need to enable **email** and **public_profile** permissions.
- Click on App Review and Permission and Features in the left menu
- Search and for **email** in the **Search Permissions and Features** search box**.**
- Click on Request advanced access and complete the steps.
- Search and for **public_profile** in the **Search Permissions and Features** search box**.**
- Click on **Request advanced access** and complete the steps.
## Configure Nhost
- Click **Settings** and then **Basic** in the left menu.
- Copy and paste the **App ID (Client ID)** and **App secret (Client Secret)** from Facebook to your Nhost OAuth settings for Facebook. Make sure the [OAuth provider is enabled in Nhost](/platform/authentication/social-sign-in#enabling-social-sign-in).
- Click the checkbox “**I have pasted the redirect URI into Facebook”**.
- Click **Confirm settings**.
## Sign In users in your app
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
```js
nhost.auth.signIn({
provider: 'facebook'
})
```

View File

@@ -0,0 +1,43 @@
---
title: Sign In with GitHub
---
Follow this guide to sign in users with GitHub with your Nhost App.
![GitHub Sign In Preview](/images/platform/social-providers/github-preview.png)
# Create GitHub account
- Create a new [GitHub account](https://github.com/signup) if you dont have one already.
## Create GitHub OAuth App
- Create a new OAuth application [(direct link)](https://github.com/settings/applications/new) by:
- Click on your profile photo in the top right.
- Click on Settings
- In the left menu, click Developer settings at the bottom.
- Click on Oauth Apps in the left menu
- Click on New OAuth App button in the top right
## GitHub OAuth App information
- Fill in Application Name
- Fill in Homepage URL
- Fill in **Authorization callback URL** with your OAuth Callbacke URL from Nhost
## Configure Nhost
- Click Generate a new client secret to generate a OAuth client secret.
- Copy and paste the **Client ID** and **Client Secret** from GitHub to your Nhost OAuth settings for GitHub. Make sure the [OAuth provider is enabled in Nhost](/platform/authentication/social-sign-in#enabling-social-sign-in).
- Click the checkbox “**I have pasted the redirect URI into GitHub”**.
- Click **Confirm settings**.
## Sign In users in your app
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
```js
nhost.auth.signIn({
provider: 'github'
})
```

View File

@@ -0,0 +1,67 @@
---
title: Sign In with Google
---
Follow this guide to sign in users with Google with your Nhost App.
![Google Sign In Preview](/images/platform/social-providers/google-preview.png)
## Sign up for Google
- Sign up for [Google Cloud](https://cloud.google.com/free) if you dont have one already.
## Create a Google Cloud Project
> 💡 You can skip this step if you already have a Google Cloud project you want to use.
- Create a new Google Cloud project if you dont already have a project you want to use.
## Configure OAuth consent screen
- Search for **OAuth consent screen** in the top search bar in the Google Cloud Console.
- Click on **OAuth consent screen** in the search results.
- Select User Type **External** and click **CREATE**.
## **Edit app registration**
### OAuth consent screen
- Fill in your App information.
- Click **SAVE AND CONTINUE.**
### Scopes
- Click **SAVE AND CONTINUE**.
### Test user
- Click **SAVE AND CONTINUE**.
### Summary
- Click **BACK TO DASHBOARD**.
## Create credentials
- Click on **Credentials** under **APIs & Services** in the left menu.
- Click **+ CREATE CREDENTIALS** and then **OAuth client ID** in the top menu.
- On the **Create OAuth client ID** page for **Application Type** select **Web application**.
- Under **Authorized redirect URIs** add your **OAuth Callback URL** from Nhost.
- Click **CREATE**.
## Configure Nhost
- A modal appears with your Google Client ID and Client secret.
- Copy and paste the **Client ID** and **Client Secret** from Google to your Nhost OAuth settings for Google. Make sure the [OAuth provider is enabled in Nhost](/platform/authentication/social-sign-in#enabling-social-sign-in).
- Click the checkbox “**I have pasted the redirect URI into Google”**.
- Click **Confirm settings**.
## Sign In users in your app
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
```js
nhost.auth.signIn({
provider: 'google'
})
```

View File

@@ -0,0 +1,50 @@
---
title: Sign In with LinkedIn
---
Follow this guide to sign in users with LinkedIn with your Nhost App.
![LinkedIn Sign In Preview](/images/platform/social-providers/linkedin-preview.png)
## Create LinkedIn account
- Create a [LinkedIn account](https://linkedin.com/) if you don't have one already.
## Create LinkedIn OAuth App
- Go to the [LinkedIn Developer Dashboard](https://www.linkedin.com/developers/apps).
- Click on Create App in the top right.
- Fill in **App Name**, **LinkedIn Page** and **App Logo**.
- Click **“I have read and agree to these terms”**.
- Click **Create app** in the bottom right.
## LinkedIn OAuth App information
- Click on **Auth** in the top menu.
- Click on the **pen icon** under **OAuth 2.0 settings** and right next to **Authorized redirect URLs for your app.**
- Click **Add redirect URL**.
- Copy and past the **OAuth Callback URL** from Nhost.
- Click **Update**.
## Configure Nhost
- Copy and paste the **Client ID** and **Client Secret** from LinkedIn to your Nhost OAuth settings for LinkedIn.
- Click the checkbox “**I have pasted the redirect URI into LinkedIn”**.
- Click **Confirm settings**.
## Enable Auth for your LinkedIn OAuth App
- Click on **Products** in the top menu
- Click Select on the **Sign In with LinkedIn**.
- Check the checkbox **I have read and agree to these terms.**
- Click **Add product**.
## Sign In users in your app
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
```js
nhost.auth.signIn({
provider: 'linkedin'
})
```

View File

@@ -0,0 +1,43 @@
---
title: Sign In with Spotify
---
Follow this guide to sign in users with Spotify with your Nhost App.
![Spotify Sign In Preview](/images/platform/social-providers/spotify-preview.png)
# Create Spotify account
- Create a new [Spotify account](https://www.spotify.com/) if you don't have one already.
## Create Spotify App
- Go to the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/).
- Click on CREATE AN APP.
- Fill in a App name and App description
- Check the box to aggre Spotify's [Developer Terms of Service](https://developer.spotify.com/terms) and [Branding Guidelines](https://developer.spotify.com/branding-guidelines).
## Configure OAuth Callback URL
- Click EDIT SETTINGS
- A modal appears
- Fill in **Redirect URIs** with your **OAuth Callback URL** from Nhost.
- Click ADD to add the OAuth callback URL.
- Click SAVE.
## Configure Nhost
- Click SHOW CLIENT SECRET in the Spotify App Dashboard.
- Copy and paste the **Client ID** and **Client Secret** from Spotify to your Nhost OAuth settings for Spotify.
- Click the checkbox “**I have pasted the redirect URI into Spotify”**.
- Click **Confirm settings**.
## Sign In users in your app
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
```js
nhost.auth.signIn({
provider: 'spotify'
})
```

View File

@@ -1,38 +0,0 @@
---
title: 'Social login'
---
Nhost Auth supports the following social login providers:
- GitHub
- Google
- Facebook
- LinkedIn
---
## Enabling social login
To start with social login, select your app in Nhost Console and go to **Users** → **Login settings**.
Enabling any of the supported login providers requires a developer account for the selected login provider. Follow the on-screen instructions to enable the login method of your choosing.
---
## Implementing login experience
To implement social login in your app, use the [Nhost JavaScript SDK](/reference/sdk) and the `signIn()` method:
```js
nhost.auth.signIn({
provider: 'github'
})
```
---
## OAuth scopes
Scopes are a mechanism in OAuth to allow or limit an application's access to a user's account.
By default, Nhost sets the scope to get the name, email and avatar for each user. Editing scope is not currently supported.

View File

@@ -0,0 +1,47 @@
---
title: 'Social Sign-In Providers'
---
Nhost Auth supports the following social sign-in providers:
- [GitHub](/platform/authentication/sign-in-with-github)
- [Google](/platform/authentication/sign-in-with-google)
- [Facebook](/platform/authentication/sign-in-with-facebook)
- [LinkedIn](/platform/authentication/sign-in-with-linkedin)
- [Spotify](/platform/authentication/sign-in-with-spotify)
---
## Enabling Social Sign-In Provider
To start with social sign-in, select your app in Nhost Console and go to **Users** → **Login settings**.
You need to set client ID and client secret for each provider that you want to enable.
---
## Implementing sign-in experience
Use the [Nhost JavaScript SDK](/reference/sdk) and the `signIn()` method to implement social sign-in in your app,
Here's an example of how to implement sign-in with GitHub:
```js
nhost.auth.signIn({
provider: 'github'
})
```
Users are redirected to your Nhost app's **client URL** by default. By default your Nhost app's client URL is set to `http://localhost:3000`. You can change the value of your client URL in the Nhost console by going to **Users** → **Login settings** → **Client URL**.
---
## Provider OAuth scopes
Scopes are a mechanism in OAuth to allow or limit an application's access to a user's account.
By default, Nhost sets the scope to get the name, email and avatar for each user. Editing scope is not currently supported.
## Provider OAuth Tokens
Nhost saves both access and refresh tokens for each user and provider in the `auth.user_providers` table. These tokens can be used to interact with the provider if needed.

View File

@@ -24,7 +24,7 @@ Example of getting one user in GraphQL:
```graphql
query {
user(id: "some-user-id") {
user(id: "<user-id>") {
id
displayName
email

View File

@@ -20,6 +20,8 @@ Access token data is included as headers with every API request. By default, eve
The default role for users is `user`.
> You can also [add custom permission](#add-permission-variables) varaibles if you need to.
---
## Select permissions
@@ -60,3 +62,23 @@ In our example, we only select `name`, because we want all other other columns t
We also want every new record's `user_id` value to be set to the ID of the user making the request. We can tell Hasura to do this with **column presets**.
1. Under column presets, set `user_id` to `x-hasura-user-id`.
## Add Permission Variables
You can add extra permission variables in the Nhost console under **Users** and then **Roles and permissions**. These permission variables are then available when creating permissions for your GraphQL API in the Hasura console.
![Permission Variables](/images/platform/permission-variables-preview.svg)
As an example, let's say you add a new permission variable `x-hasura-organisation-id` with path `user.profile.organisation.id`. This means that Nhost Auth will get the value for `x-hasura-organisation-id` by internally generating the following GraphQL query:
```graphql
query {
user(id: "<user-id>") {
profile {
organisation {
id
}
}
}
}
```

View File

@@ -39,10 +39,10 @@ HTTP endpoints are automatically generated based on the file structure under `fu
As such, given this file structure:
```js
functions / index.js
users / index.ts
active.ts
my - company.js
functions/index.js
functions/users/index.ts
functions/active.ts
functions/my-company.js
```
The following endpoints will be available:

View File

@@ -0,0 +1,6 @@
---
title: 'API Reference'
subtitle: 'Hasura Auth'
---
<Swagger spec="hasura-auth.json" />

View File

@@ -0,0 +1,221 @@
---
title: Configuration
---
## Email configuration
Hasura Auth automatically sends transactional emails to manage the following operations:
- Sign up
- Password reset
- Email change
- Passwordless with emails
### SMTP settings
```bash
AUTH_SMTP_HOST=smtp.example.com
AUTH_SMTP_PORT=1025
AUTH_SMTP_USER=user
AUTH_SMTP_PASS=password
AUTH_SMTP_SENDER=hasura-auth@example.com
```
See the [environment variables](/reference/hasura-auth/environment-variables) for additional information about how to connnect to an SMTP server.
### Email templates
You can create your own templates to customize the emails that will be sent to the users. You can have a look at the [official email templates](https://github.com/nhost/hasura-auth/tree/main/email-templates) to understand how they are structured.
#### With Docker
When using Docker, you can mount your own email templates from the local file system. You can have a look at this [docker-compose example](https://github.com/nhost/hasura-auth/blob/16df3e84b6c9a4f888b2ff07bd85afc34f8ed051/docker-compose-example.yaml#L41) to see how to set it up.
#### Remote email templates
When running Hasura Auth in its own infrastructure, it is possible to mount a volume with custom `email-templates` directory. However, in some cases, we may want to fetch templates from an external HTTP endpoint. Hence the introduction of a new `AUTH_EMAIL_TEMPLATE_FETCH_URL` environment variable:
```bash
AUTH_EMAIL_TEMPLATE_FETCH_URL=https://github.com/nhost/nhost/tree/custom-email-templates-example/examples/custom-email-templates
```
In the above example, on every email creation, the server will use this URL to fetch its templates, depending on the locale, email type and field.
For instance, the template for english verification email body will the fetched in [https://raw.githubusercontent.com/nhost/nhost/main/examples/custom-email-templates/en/email-verify/body.html](https://raw.githubusercontent.com/nhost/nhost/main/examples/custom-email-templates/en/email-verify/body.html).
See the [example in the main nhost/nhost repository](https://github.com/nhost/nhost/tree/main/examples/custom-email-templates).
The context variables in email templates have been simplified: the `${link}` variable contains the entire redirection url the recipient needs to follow.
---
## Redirections
Some authentication operations redirects the users to the frontend application:
- After an OAuth provider completes or fails authentication, the user is redirected to the frontend
- Every email sent to the user (passwordless with email, password/email change, password reset) contains a link, that redirects the user to the frontend
In order to achieve that, you need to set the `AUTH_CLIENT_URL` environment variable, for instance:
```bash
AUTH_CLIENT_URL=https://my-app.vercel.com
```
---
## Email + password authentication
### Email checks
You can specify a list of allowed emails or domains with `AUTH_ACCESS_CONTROL_ALLOWED_EMAILS` and `AUTH_ACCESS_CONTROL_ALLOWED_EMAIL_DOMAINS`.
As an example, the following environment variables will only allow `@nhost.io`, `@example.com` and `bob@smith.com` to register to the application:
```bash
AUTH_ACCESS_CONTROL_ALLOWED_EMAILS=bob@smith.com
AUTH_ACCESS_CONTROL_ALLOWED_EMAIL_DOMAINS=nhost.io,example.com
```
In the above example, users with the following emails would be able to register `bob@smith.com`, `emma@example.com`, `john@nhost.io`, whereas `mary@firebase.com` won't.
Similarly, it is possible to provide a list of forbidden emails or domains with `AUTH_ACCESS_CONTROL_BLOCKED_EMAILS` and `AUTH_ACCESS_CONTROL_BLOCKED_EMAIL_DOMAINS`.
### Password checks
Hasura auth does not accepts passwords with less than three characters. This limit can be changed in changing the `AUTH_PASSWORD_MIN_LENGTH` environment variable.
It is also possible to only allow [passwords that have not been pwned](https://haveibeenpwned.com/) in setting `AUTH_PASSWORD_HIBP_ENABLED` to `true`.
<!-- TODO ### Change -->
<!-- TODO ### Reset email -->
<!-- TODO ### Reset password -->
<!-- ---
TODO ## Anonymous users -->
---
## Multi-factor authentication
Hasura Auth supports different types of Multi-Factor Authentication (MFA): passwordless with emails (magic links), passwordless with SMS, and Time-based one-time passwords.
### Passwordless with emails (magic links)
Hasura Auth supports email [passwordless authentication](https://en.wikipedia.org/wiki/Passwordless_authentication). It requires [SMTP](#email-configuration) to be configured properly.
Set `AUTH_EMAIL_PASSWORDLESS_ENABLED` to `true` to enable passwordless authentication.
<!-- TODO ### Passwordless with SMS -->
### Time-based one-time password (TOTP)
It is possible to add a step to authentication with email and password authentication. Once users registered, they can activate MFA TOTP:
1. Users generate a QR Code, that is then scanned in an authentication app such as [Authy](https://authy.com/) or [Google Authenticator](https://en.wikipedia.org/wiki/Google_Authenticator).
2. They then send the TOTP code to Hasura Auth. MFA is now activated
3. Next time they authenticate, Hasura Auth will first expect their email and password, but then, instead of completing authentication, Hasura Auth will expect the TOTP in order to return the refresh and the access tokens.
In order for users to be able to activate MFA TOTP, `AUTH_MFA_ENABLED` must be set to `true`.
<!-- ---
TODO ## OAuth authentication -->
---
## Gravatar
Hasura Auth stores the avatar URL of users in `auth.users.avatar_url`. By default, it will look for the Gravatar linked to the email, and store it into this field.
It is possible to deactivate the use of Gravatar in setting the `AUTH_GRAVATAR_ENABLED` environment variable to `false`.
---
## Extending user schema
Adding columns to the user tables may be tempting. However, all the tables and columns have a specific purpose, and changing the structure of the `auth` schema will very likely end in breaking the functionning of Hasura Auth. It's, therefore, **highly recommended** not to modify the database schema for any tables in the `auth` schema.
Instead, we recommend adding extra user information in the following ways:
- to store information in the `auth.users.metadata` column
- to store information in a separate table located in the `public` PostgreSQL schema, and to point to `auth.users.id` through a foreign key.
### `metadata` user field
The `auth.users.metadata` field is a JSON column, that can be used as an option on registration:
```json
{
"email": "bob@bob.com",
"passord": "12345678",
"options": {
"metadata": {
"first_name": "Bob"
}
}
}
```
### Additional user information in the `public` schema
As previously explained, the alteration of the `auth` schema may seriously hamper the functionning of Hasura Auth. The `metadata` field in the `auth.users` table may tackle some use cases, but in some other cases, we want to keep a certain level of structure in the way data is structured.
In that case, it is possible to create a dedicated table in the `public` schema, with a `user_id` foreign key column that would point to the `auth.users.id` column. It is then possible to add an Hasura object relationship that would join the two tables together.
<!-- TODO hooks on the metadata field -->
---
## Custom Hasura JWT claims
Hasura comes with a [powerful authorisation system](https://hasura.io/docs/latest/graphql/core/auth/authorization/index.html). Hasura Auth is already configured to add `x-hasura-user-id`, `x-hasura-allowed-roles`, and `x-hasura-user-isAnonymous` to the JSON Web Tokens it generates.
In Hasura Auth, it is possible to define custom claims to add to the JWT, so they can be used by Hasura to determine the permissions of the received GraphQL operation.
Each custom claim is defined by a pair of a key and a value:
- The key determines the name of the claim, prefixed by `x-hasura`. For instance, `organisation-id` will become `x-hasura-organisation-id`.
- The value is a representation of the path to look at to determine the value of the claim. For instance `profile.organisation.id` will look for the `user.profile` Hasura relationship, and the `profile.organisation` Hasura relationship. Array values are transformed into Postgres syntax so Hasura can interpret them. See the official Hasura documentation to understand the [session variables format](https://hasura.io/docs/latest/graphql/core/auth/authorization/roles-variables.html#format-of-session-variables).
```bash
AUTH_JWT_CUSTOM_CLAIMS={"organisation-id":"profile.organisation.id", "project-ids":"profile.contributesTo.project.id"}
```
Will automatically generate and fetch the following GraphQL query:
```graphql
{
user(id: "<user-id>") {
profile {
organisation {
id
}
contributesTo {
project {
id
}
}
}
}
}
```
It will then use the same expressions e.g. `profile.contributesTo.project.id` to evaluate the result with [JSONata](https://jsonata.org/), and possibly transform arrays into Hasura-readable, PostgreSQL arrays.Finally, it adds the custom claims to the JWT in the `https://hasura.io/jwt/claims` namespace:
```json
{
"https://hasura.io/jwt/claims": {
"x-hasura-organisation-id": "8bdc4f57-7d64-4146-a663-6bcb05ea2ac1",
"x-hasura-project-ids": "{\"3af1b33f-fd0f-425e-92e2-0db09c8b2e29\",\"979cb94c-d873-4d5b-8ee0-74527428f58f\"}",
"x-hasura-allowed-roles": [ "me", "user" ],
"x-hasura-default-role": "user",
"x-hasura-user-id": "121bbea4-908e-4540-ac5d-52c7f6f93bec",
"x-hasura-user-isAnonymous": "false"
}
"sub": "f8776768-4bbd-46f8-bae1-3c40da4a89ff",
"iss": "hasura-auth",
"iat": 1643040189,
"exp": 1643041089
}
```

View File

@@ -0,0 +1,107 @@
---
title: Environment Variables
---
## General environment variables
| Name (a star**\*** means the variable is required) | Description | Default value |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
| HASURA_GRAPHQL_JWT_SECRET**\*** | Key used for generating JWTs. Must be `HMAC-SHA`-based and the same as configured in Hasura. [More info](https://hasura.io/docs/latest/graphql/core/auth/authentication/jwt.html#running-with-jwt) | |
| HASURA_GRAPHQL_DATABASE_URL**\*** | [PostgreSQL connection URI](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING). Required to inject the `auth` schema into the database. | |
| HASURA_GRAPHQL_GRAPHQL_URL**\*** | Hasura GraphQL endpoint. Required to manipulate account data. For instance: `https://graphql-engine:8080/v1/graphql` | |
| HASURA_GRAPHQL_ADMIN_SECRET**\*** | Hasura GraphQL Admin Secret. Required to manipulate account data. | |
| AUTH_HOST | Server host. [Docs](http://expressjs.com/en/5x/api.html#app.listen) | `0.0.0.0` |
| AUTH_PORT | Server port. [Docs](http://expressjs.com/en/5x/api.html#app.listen) | `4000` |
| AUTH_SERVER_URL | Server URL of where Hasura Backend Plus is running. This value is to used as a callback in email templates and for the OAuth authentication process. | |
| AUTH_CLIENT_URL | URL of your frontend application. Used to redirect users to the right page once actions based on emails or OAuth succeed. | |
| AUTH_SMTP_HOST | SMTP server hostname used for sending emails | |
| AUTH_SMTP_PORT | SMTP port | `587` |
| AUTH_SMTP_USER | Username to use to authenticate on the SMTP server | |
| AUTH_SMTP_PASS | Password to use to authenticate on the SMTP server | |
| AUTH_SMTP_SENDER | Email to use in the `From` field of the email | |
| AUTH_SMTP_AUTH_METHOD | SMTP authentication method | `PLAIN` |
| AUTH_SMTP_SECURE | Enables SSL. [More info](https://nodemailer.com/smtp/#tls-options). | `false` |
| AUTH_GRAVATAR_ENABLED | | `true` |
| AUTH_GRAVATAR_DEFAULT | | `blank` |
| AUTH_GRAVATAR_RATING | | `g` |
| AUTH_ANONYMOUS_USERS_ENABLED | Enables users to register as an anonymous user. | `false` |
| AUTH_DISABLE_NEW_USERS | If set, new users will be disabled after finishing registration and won't be able to connect. | `false` |
| AUTH_ACCESS_CONTROL_ALLOWED_EMAILS | Comma-separated list of emails that are allowed to register. | |
| AUTH_ACCESS_CONTROL_ALLOWED_EMAIL_DOMAINS | Comma-separated list of email domains that are allowed to register. If `ALLOWED_EMAIL_DOMAINS` is `tesla.com,ikea.se`, only emails from tesla.com and ikea.se would be allowed to register an account. | `` (allow all email domains) |
| AUTH_ACCESS_CONTROL_BLOCKED_EMAILS | Comma-separated list of emails that cannot register. | |
| AUTH_ACCESS_CONTROL_BLOCKED_EMAIL_DOMAINS | Comma-separated list of email domains that cannot register. | |
| AUTH_PASSWORD_MIN_LENGTH | Minimum password length. | `3` |
| AUTH_PASSWORD_HIBP_ENABLED | User's password is checked against [Pwned Passwords](https://haveibeenpwned.com/Passwords). | `false` |
| AUTH_USER_DEFAULT_ROLE | Default user role for registered users. | `user` |
| AUTH_USER_DEFAULT_ALLOWED_ROLES | Comma-separated list of default allowed user roles. | `me,$AUTH_USER_DEFAULT_ROLE` |
| AUTH_LOCALE_DEFAULT | | `en` |
| AUTH_LOCALE_ALLOWED_LOCALES | | `en` |
| AUTH_EMAIL_PASSWORDLESS_ENABLED | Enables passwordless authentication by email. The SMTP server must then be configured. | `false` |
| AUTH_SMS_PASSWORDLESS_ENABLED | Enables passwordless authentication by SMS. An SMS provider must then be configured. | `false` |
| AUTH_SMS_PROVIDER | SMS provider name. Only `twilio` is possible as an option for now. | |
| AUTH_SMS_TWILIO_ACCOUNT_SID | | |
| AUTH_SMS_TWILIO_AUTH_TOKEN | | |
| AUTH_SMS_TWILIO_MESSAGING_SERVICE_ID | | |
| AUTH_SMS_TWILIO_FROM | | |
| AUTH_EMAIL_SIGNIN_EMAIL_VERIFIED_REQUIRED | When enabled, any email-based authentication requires emails to be verified by a link sent to this email. | `true` |
| AUTH_ACCESS_CONTROL_ALLOWED_REDIRECT_URLS | | |
| AUTH_MFA_ENABLED | Enables users to use Multi Factor Authentication | `false` |
| AUTH_MFA_TOTP_ISSUER | The name of the One Time Password (OTP) issuer. Probably your app's name. | `hasura-auth` |
| AUTH_ACCESS_TOKEN_EXPIRES_IN | | `900`(15 minutes) |
| AUTH_REFRESH_TOKEN_EXPIRES_IN | | `43200` (12 hours) |
| AUTH_EMAIL_TEMPLATE_FETCH_URL | | |
| AUTH_JWT_CUSTOM_CLAIMS | | |
## OAuth environment variables
| Name (a star**\*** means the variable is required when the provider is enabled) | Default value |
| ------------------------------------------------------------------------------- | ----------------------------------- |
| AUTH_PROVIDER_GITHUB_ENABLED | `false` |
| AUTH_PROVIDER_GITHUB_CLIENT_ID**\*** | |
| AUTH_PROVIDER_GITHUB_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_GITHUB_AUTHORIZATION_URL | |
| AUTH_PROVIDER_GITHUB_TOKEN_URL | |
| AUTH_PROVIDER_GITHUB_USER_PROFILE_URL | |
| AUTH_PROVIDER_GITHUB_SCOPE | `user:email ` |
| AUTH_PROVIDER_GOOGLE_ENABLED | `false` |
| AUTH_PROVIDER_GOOGLE_CLIENT_ID**\*** | |
| AUTH_PROVIDER_GOOGLE_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_GOOGLE_SCOPE | `email,profile` |
| AUTH_PROVIDER_FACEBOOK_ENABLED | `false` |
| AUTH_PROVIDER_FACEBOOK_CLIENT_ID**\*** | |
| AUTH_PROVIDER_FACEBOOK_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_FACEBOOK_PROFILE_FIELDS | `email,photos,displayName` |
| AUTH_PROVIDER_FACEBOOK_SCOPE | `email` |
| AUTH_PROVIDER_TWITTER_ENABLED | `false` |
| AUTH_PROVIDER_TWITTER_CONSUMER_KEY**\*** | |
| AUTH_PROVIDER_TWITTER_CONSUMER_SECRET**\*** | |
| AUTH_PROVIDER_LINKEDIN_ENABLED | |
| AUTH_PROVIDER_LINKEDIN_CLIENT_ID**\*** | |
| AUTH_PROVIDER_LINKEDIN_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_LINKEDIN_SCOPE | `r_emailaddress,r_liteprofile` |
| AUTH_PROVIDER_APPLE_ENABLED | `false` |
| AUTH_PROVIDER_APPLE_CLIENT_ID**\*** | |
| AUTH_PROVIDER_APPLE_TEAM_ID**\*** | |
| AUTH_PROVIDER_APPLE_KEY_ID**\*** | |
| AUTH_PROVIDER_APPLE_PRIVATE_KEY**\*** | Base64 format |
| AUTH_PROVIDER_APPLE_SCOPE | `name,email` |
| AUTH_PROVIDER_WINDOWS_LIVE_ENABLED | `false` |
| AUTH_PROVIDER_WINDOWS_LIVE_CLIENT_ID**\*** | |
| AUTH_PROVIDER_WINDOWS_LIVE_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_WINDOWS_LIVE_SCOPE | `wl.basic,wl.emails` |
| AUTH_PROVIDER_SPOTIFY_ENABLED | `false` |
| AUTH_PROVIDER_SPOTIFY_CLIENT_ID**\*** | |
| AUTH_PROVIDER_SPOTIFY_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_SPOTIFY_SCOPE | `user-read-email,user-read-private` |
| AUTH_PROVIDER_GITLAB_ENABLED | `false` |
| AUTH_PROVIDER_GITLAB_CLIENT_ID**\*** | |
| AUTH_PROVIDER_GITLAB_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_GITLAB_BASE_URL | |
| AUTH_PROVIDER_GITLAB_SCOPE | `read_user` |
| AUTH_PROVIDER_BITBUCKET_ENABLED | `false` |
| AUTH_PROVIDER_BITBUCKET_CLIENT_ID**\*** | |
| AUTH_PROVIDER_BITBUCKET_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_STRAVA_ENABLED | `false` |
| AUTH_PROVIDER_STRAVA_CLIENT_ID**\*** | |
| AUTH_PROVIDER_STRAVA_CLIENT_SECRET**\*** | |
| AUTH_PROVIDER_STRAVA_SCOPE | `profile:read_all` |

View File

@@ -0,0 +1,41 @@
---
title: 'Overview'
---
Hasura Auth handles **authentication** for [Hasura](https://github.com/hasura/graphql-engine).
Hasura Auth runs in a separate Docker container alongside Postgres and Hasura.
## Features
- 🧑‍🤝‍🧑 Users are stored in Postgres and accessed via GraphQL
- 🔑 Multiple sign-in methods
- ✨ Integrates with GraphQL and Hasura Permissions
- 🔐 JWT tokens and Refresh Tokens.
- ✉️ Emails sent on various operations
<!-- - ✅ Optional checking for Pwned Passwords. -->
- 🛡️ Two-factor authentication support.
- 👨‍💻 Written 100% in TypeScript.
### Authentication methods
- **Email and Password**: simple email and password method.
- **Email**, also called **passwordless email** or **magic link**.
- **SMS**, also called **passwordless sms**.
- **Anonymous**: sign in users without any method. Anonymous users can be
converted to _regular_ users at a later stage.
- **OAuth providers**: Facebook, Google, GitHub, Twitter, Apple, LinkedIn, Windows Live, Spotify, Strave, GitLab, BitBucket
## Integration with Hasura
Hasura Auth's final purpose is to securely provide a JSON Web Token that can be added as an authorization header to GraphQL operation sent to Hasura.
Hasura auth automatically generates and manages two kinds of tokens:
- An access token (JWT), that will be used to authenticate the GraphQL operations in Hasura, and that has a limited expiration limit (15 minutes by default)
- A refresh token, that is used to ask Hasura Auth for a new access token, and that can be consummed only once.
Access tokens generated by Hasura Auth contains information and user id, its default role, and the roles they actually have. In addition, it is possible since version `0.2.0` to extend JWT claims with custom information such as organisation or project ownership, so your application can leverage the capabilities of the [Hasura permissions layer](https://hasura.io/docs/latest/graphql/core/auth/authorization/index.html).
<!-- - Users and accounts are saved in the database. -->
You can read further information about JWT and Hasura in the [official Hasura documentation](https://hasura.io/docs/latest/graphql/core/auth/authentication/jwt.html).

View File

@@ -0,0 +1,24 @@
---
title: Installation
---
Hasura Auth runs in a container alongside Postgres and Hasura.
## Nhost (recommended)
The recommended way to start using Hasura Auth is by using Nhost. With Nhost, you will get a complete backend ready in seconds with Hasura, authentication, storage and serverless functions.
Go to [Nhost](https://nhost.io) and start building your app now.
## Docker-compose
```sh
git clone https://github.com/nhost/hasura-auth.git
cd hasura-auth
cp .env.example .env
docker-compose -f docker-compose-example.yaml up
```
Hasura Auth comes with plenty of options. They are explained in the [configuration section](/reference/hasura-auth/configuration).
If you are already familiar with the application, you can also have a look at the [environment variables](/reference/hasura-auth/environment-variables) that can be passed on to your docker container.

View File

@@ -0,0 +1,85 @@
---
title: 'Schema'
---
Hasura Auth stores all its data in a dedicated `auth` PostgreSQL schema. When Hasura Auth starts, it checks if the `auth` schema exists, then automatically syncs the following tables and their corresponding Hasura metadata:
```mermaid
erDiagram
migrations {
integer id PK
varchar name
varchar hash
timestamp executed_at "CURRENT_TIMESTAMP"
}
users ||--o{ user_roles : roles
user_roles }o--|| roles: role
users }o--|| roles: role
users ||--o{ refresh_tokens: refreshTokens
users ||--o{ user_providers: provider
providers ||--o{ user_providers: user
provider_requests {
uuid id PK "gen_random_uuid()"
test redirect_url
}
refresh_tokens {
uuid refresh_token PK
uuid user_id FK
timestamptz created_at "now()"
timestamptz expires_at
}
providers {
text id PK
}
user_providers {
uuid id PK "gen_random_uuid()"
timestamptz created_at "now()"
timestamptz updated_at "now()"
uuid user_id FK
text access_token
text refresh_token
text provider_id FK
text provider_user_id
}
user_roles {
uuid id PK "gen_random_uuid()"
timestamptz created_at "now()"
uuid user_id FK
text role FK
}
users {
uuid id PK "gen_random_uuid()"
timestamptz created_at "now()"
timestamptz updated_at "now()"
timestamptz last_seen "nullable"
boolean disabled "false"
text display_name "''"
text avatar_url "''"
varchar locale
email email "nullable"
text phone_number "nullable"
text password_hash "nullable"
boolean email_verified "false"
boolean phone_number_verified "false"
email new_email "nullable"
text otp_method_last_used "nullable"
text otp_hash "nullable"
timestamptz opt_hash_expires_at "now()"
text default_role FK "user"
boolean is_anonymous "false"
text totp_secret "nullable"
text active_mfa_type "nullable"
text ticket "nullable"
timestamptz ticket_expires_at "now()"
jsonb metadata "nullable"
}
roles {
text roles PK
}
```

View File

@@ -28,3 +28,11 @@ In this section:
### Nhost CLI
- [CLI overview](/reference/cli)
### Hasura Auth
- [Overview](./reference/hasura-auth)
- [Installation](./reference/hasura-auth/installation)
- [Configuration](./reference/hasura-auth/configuration)
- [Environment variables](./reference/hasura-auth/environment-variables)
- [API](./reference/hasura-auth/api-reference)
- [Schema](./reference/hasura-auth/api-reference)

View File

@@ -2,41 +2,59 @@
title: 'Configuration'
---
## Installation
With yarn:
```sh
yarn add @nhost/react @nhost/nextjs
```
With Npm:
```sh
npm install @nhost/react @nhost/nextjs
```
---
## Configuration
Configuring Nhost with Next.js follows the same logic as React, except we are initializing with `NhostSSR` instead of `Nhost`.
Under the hood, `NhostSSR` uses cookies to store the refresh token, and disables auto-refresh and auto-login when running on the server-side.
Configuring Nhost with Next.js follows the same logic as React, except we are initializing with the `NhostClient` from the `@nhost/nextjs` package.
Under the hood, `NhostClient` uses cookies to store the refresh token, and disables auto-refresh and auto-login when running on the server-side.
```jsx
// {project-root}/pages/_app.tsx
import type { AppProps } from 'next/app'
import { NhostSSR, NhostProvider } from '@nhost/nextjs'
import { NhostClient, NhostNextProvider } from '@nhost/nextjs'
import Header from '../components/Header'
const nhost = new NhostSSR({ backendUrl: 'my-app.nhost.run' })
const nhost = new NhostClient({ backendUrl: 'my-app.nhost.run' })
function MyApp({ Component, pageProps }: AppProps) {
return (
<NhostProvider nhost={nhost} initial={pageProps.nhostSession}>
<NhostNextProvider nhost={nhost} initial={pageProps.nhostSession}>
<div>
<Header />
<Component {...pageProps} />
</div>
</NhostProvider>
</NhostNextProvider>
)
}
export default MyApp
```
---
## Client-side rendering
The logic is the same as in a classic React application:
```jsx
// {project-root}/pages/csr-page.jsx
// {project-root}/pages/csr-page.tsx
import { NextPageContext } from 'next'
import React from 'react'
@@ -58,12 +76,14 @@ const ClientSidePage: React.FC = () => {
export default ClientSidePage
```
---
## Server-side rendering
You need to load the session from the server first from `getServerSideProps`. Once it is done, the `_app` component will make sure to load or update the session through `pageProps`.
```jsx
// {project-root}/pages/ssr-page.jsx
// {project-root}/pages/ssr-page.tsx
import { NextPageContext } from 'next'
import React from 'react'

View File

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

View File

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

View File

@@ -7,38 +7,37 @@ title: 'Apollo GraphQL'
With Yarn:
```sh
yarn add @nhost/react @nhost/react-apollo
yarn add @nhost/react @nhost/react-apollo @apollo/client
```
With Npm:
```sh
npm install @nhost/react @nhost/react-apollo
npm install @nhost/react @nhost/react-apollo @apollo/client
```
## Configuration
Let's add a `NhostApolloProvider`. Make sure the Apollo Provider is nested into `NhostProvider`, as it will need the Nhost context to determine the authentication headers to be sent to the GraphQL endpoint.
Let's add a `NhostApolloProvider`. Make sure the Apollo Provider is nested into `NhostReactProvider`, as it will need the Nhost context to determine the authentication headers to be sent to the GraphQL endpoint.
```jsx
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { NhostApolloProvider } from '@nhost/react-apollo'
import { NhostProvider } from '@nhost/react'
import { Nhost } from '@nhost/client'
import { NhostClient, NhostReactProvider } from '@nhost/react'
const nhost = new Nhost({
const nhost = new NhostClient({
backendUrl: 'http://localhost:1337'
})
ReactDOM.render(
<React.StrictMode>
<NhostProvider nhost={nhost}>
<NhostApolloProvider>
<NhostReactProvider nhost={nhost}>
<NhostApolloProvider nhost={nhost}>
<App />
</NhostApolloProvider>
</NhostProvider>
</NhostReactProvider>
</React.StrictMode>,
document.getElementById('root')
)

View File

@@ -7,36 +7,36 @@ title: 'Hooks'
### Email and Password Sign-Un
```js
const { signUp, isLoading, isSuccess, needsVerification, isError, error } =
useEmailPasswordSignUp(email?: string, password?: string, options?: Options )
const { signUpEmailPassword, isLoading, isSuccess, needsEmailVerification, isError, error } =
useSignUpEmailPassword(email?: string, password?: string, options?: Options )
```
| Name | Type | Notes |
| ---------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `signUp` | (email?: string, password?: string) => void | Used for a new user to sign up. The email/password arguments will take precedence over the possible state values used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `needsVerification` | boolean | Returns `true` if the sign-up has been accepted, but a verificaiton email has been sent and is awaiting. |
| `isSuccess` | boolean | Returns `true` if the sign-up suceeded. Returns `false` if the new email needs to be verified first, or if an error occurred. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} \| undefined | Provides details about the error. |
| `options.locale` | string \| undefined | Locale of the user, in two digits, for instance `en`. |
| `options.allowedRoles` | string[] \| undefined | Allowed roles of the user. Must be a subset of the default allowed roles defined in Hasura Auth. |
| `options.defaultRole` | string \| undefined | Default role of the user. Must be part of the default allowed roles defined in Hasura Auth. |
| `options.displayName` | string \| undefined | |
| `options.metadata` | Record<string, unknown> \| undefined | Custom additional user information stored in the `metadata` column. Can be any JSON object. |
| `options.redirectTo` | string \| undefined | redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
| Name | Type | Notes |
| ------------------------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `signUpEmailPassword` | (email?: string, password?: string) => void | Used for a new user to sign up. The email/password arguments will take precedence over the possible state values used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `needsEmailVerification` | boolean | Returns `true` if the sign-up has been accepted, but a verificaiton email has been sent and is awaiting. |
| `isSuccess` | boolean | Returns `true` if the sign-up suceeded. Returns `false` if the new email needs to be verified first, or if an error occurred. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} \| undefined | Provides details about the error. |
| `options.locale` | string \| undefined | Locale of the user, in two digits, for instance `en`. |
| `options.allowedRoles` | string[] \| undefined | Allowed roles of the user. Must be a subset of the default allowed roles defined in Hasura Auth. |
| `options.defaultRole` | string \| undefined | Default role of the user. Must be part of the default allowed roles defined in Hasura Auth. |
| `options.displayName` | string \| undefined | |
| `options.metadata` | Record<string, unknown> \| undefined | Custom additional user information stored in the `metadata` column. Can be any JSON object. |
| `options.redirectTo` | string \| undefined | redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
#### Usage
```jsx
import { useState } from 'react'
import { useEmailPasswordSignUp } from '@nhost/react'
import { useSignUpEmailPassword } from '@nhost/react'
const Component = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const { signUp, isLoading, isSuccess, needsVerification, isError, error } =
useEmailPasswordSignUp(email, password)
const { signUpEmailPassword, isLoading, isSuccess, needsEmailVerification, isError, error } =
useSignUpEmailPassword(email, password)
return (
<div>
<input value={email} onChange={(event) => setEmail(event.target.value)} placeholder="Email" />
@@ -45,9 +45,9 @@ const Component = () => {
onChange={(event) => setPassword(event.target.value)}
placeholder="Password"
/>
<button onClick={signUp}>Register</button>
<button onClick={signUpEmailPassword}>Register</button>
{isSuccess && <div>Your account have beed created! You are now authenticated</div>}
{needsVerification && (
{needsEmailVerification && (
<div>Please check your mailbox and follow the verification link to verify your email</div>
)}
</div>
@@ -58,30 +58,32 @@ const Component = () => {
### Email and Password Sign-In
```js
const { signIn, isLoading, needsVerification, isSuccess, isError, error } =
useEmailPasswordSignIn(email?: string, password?: string)
const { signInEmailPassword, isLoading, needsEmailVerification, needsMfaOtp, sendMfaOtp, isSuccess, isError, error } =
useSignInEmailPassword(email?: string, password?: string)
```
| Name | Type | Notes |
| ------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `signIn` | (email?: string, password?: string) => void | Will try to authenticate. The email/password arguments will take precedence over the possible state values used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `needsVerification` | boolean | Returns `true` if the user email is still pending verification. |
| `isSuccess` | boolean | Returns `true` if the user has successfully authenticated. Returns `false` in case or error or if the new email needs to be verified first. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} \| undefined | Provides details about the error. |
| Name | Type | Notes |
| ------------------------ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `signInEmailPassword` | (email?: string, password?: string) => void | Will try to authenticate. The email/password arguments will take precedence over the possible state values used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `needsEmailVerification` | boolean | Returns `true` if the user email is still pending email verification. |
| `needsMfaOtp` | boolean | Returns `true` if the server is awaiting an MFA one-time password to complete the authentication. |
| `sendMfaOtp` | (otp: string) => void | Sends MFA One-time password. Will turn either `isSuccess` or `isError` to true, and store potential error in `error`. |
| `isSuccess` | boolean | Returns `true` if the user has successfully authenticated. Returns `false` in case or error or if the new email needs to be verified first. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} \| undefined | Provides details about the error. |
#### Usage
```jsx
import { useState } from 'react'
import { useEmailPasswordSignIn } from '@nhost/react'
import { useSignInEmailPassword } from '@nhost/react'
const Component = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const { signIn, isLoading, isSuccess, needsVerification, isError, error } =
useEmailPasswordSignIn(email, password)
const { signInEmailPassword, isLoading, isSuccess, needsEmailVerification, isError, error } =
useSignInEmailPassword(email, password)
return (
<div>
<input value={email} onChange={(event) => setEmail(event.target.value)} placeholder="Email" />
@@ -90,9 +92,9 @@ const Component = () => {
onChange={(event) => setPassword(event.target.value)}
placeholder="Password"
/>
<button onClick={signUp}>Register</button>
<button onClick={signInEmailPassword}>Register</button>
{isSuccess && <div>Authentication suceeded</div>}
{needsVerification && (
{needsEmailVerification && (
<div>
You must verify your email to sign in. Check your mailbox and follow the instructions to
verify your email.
@@ -105,49 +107,69 @@ const Component = () => {
### Oauth Providers
```js
const providerLink = useProviderLink(options?: Options)
```
| Name | Type | Notes |
| ---------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options.locale` | string \| undefined | Locale of the user, in two digits, for instance `en`. |
| `options.allowedRoles` | string[] \| undefined | Allowed roles of the user. Must be a subset of the default allowed roles defined in Hasua Auth. |
| `options.defaultRole` | string \| undefined | Default role of the user. Must be part of the default allowed roles defined in Hasura Auth. |
| `options.displayName` | string \| undefined |
| `options.metadata` | Record<string, unknown> \| undefined | Custom additional user information stored in the `metadata` column. Can be any JSON object. |
| `options.redirectTo` | string \| undefined | Redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
#### Usage
```js
import { useProviderLink } from '@nhost/react'
const Component = () => {
const { github } = useProviderLink()
return <a href={github}>Authenticate with GitHub</a>
const { facebook, github } = useProviderLink()
return
;<div>
<a href={facebook}>Authenticate with Facebook</a>
<a href={github}>Authenticate with GitHub</a>
</div>
}
```
### Passwordless email authentication
```js
const { signIn, isLoading, isSuccess, isError, error } =
useEmailPasswordlessSignIn(email?: string, options?: Options)
const { signInEmailPasswordless, isLoading, isSuccess, isError, error } =
useSignInEmailPasswordless(email?: string, options?: Options)
```
| Name | Type | Notes |
| ---------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `signIn` | (email?: string) => void | Sends a magic link to the given email The email argument will take precedence over the the possible state value used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `isSuccess` | boolean | Returns `true` if the magic link email user has successfully send. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} | Provides details about the error. |
| `options.locale` | string \| undefined | Locale of the user, in two digits, for instance `en`. |
| `options.allowedRoles` | string[] \| undefined | Allowed roles of the user. Must be a subset of the default allowed roles defined in Hasua Auth. |
| `options.defaultRole` | string \| undefined | Default role of the user. Must be part of the default allowed roles defined in Hasura Auth. |
| `options.displayName` | string \| undefined |
| `options.metadata` | Record<string, unknown> \| undefined | Custom additional user information stored in the `metadata` column. Can be any JSON object. |
| `options.redirectTo` | string \| undefined | Redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
| Name | Type | Notes |
| ------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `signInEmailPasswordless` | (email?: string) => void | Sends a magic link to the given email The email argument will take precedence over the the possible state value used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `isSuccess` | boolean | Returns `true` if the magic link email user has successfully send. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} | Provides details about the error. |
| `options.locale` | string \| undefined | Locale of the user, in two digits, for instance `en`. |
| `options.allowedRoles` | string[] \| undefined | Allowed roles of the user. Must be a subset of the default allowed roles defined in Hasua Auth. |
| `options.defaultRole` | string \| undefined | Default role of the user. Must be part of the default allowed roles defined in Hasura Auth. |
| `options.displayName` | string \| undefined |
| `options.metadata` | Record<string, unknown> \| undefined | Custom additional user information stored in the `metadata` column. Can be any JSON object. |
| `options.redirectTo` | string \| undefined | Redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
#### Usage
```jsx
import { useState } from 'react'
import { useEmailPasswordlessSignIn } from '@nhost/react'
import { useSignInEmailPasswordless } from '@nhost/react'
const Component = () => {
const [email, setEmail] = useState('')
const { signIn, isLoading, isSuccess, isError, error } = useEmailPasswordlessSignIn(email)
const { signInEmailPasswordless, isLoading, isSuccess, isError, error } =
useSignInEmailPasswordless(email)
return (
<div>
<input value={email} onChange={(event) => setEmail(event.target.value)} placeholder="Email" />
<button onClick={signUp}>Register</button>
<button onClick={signInEmailPasswordless}>Authenticate</button>
{isSuccess && (
<div>
An email has been sent to {email}. Please check your mailbox and click on the
@@ -192,22 +214,23 @@ const Component = () => {
}
```
---
## Authentication status
### `useAuthLoading`
### `useAuthenticationStatus`
The Nhost client may need some initial steps to determine the authentication status during startup, like fetching a new JWT from an existing refresh token.
`useAuthLoading` will return `true` until the authentication status is known.
`isLoading` will return `true` until the authentication status is known.
#### Usage
```jsx
import { useAuthLoading, useAuthenticated } from '@nhost/react'
import { useAuthenticationStatus } from '@nhost/react'
const Component = () => {
const isLoading = useAuthLoading()
const isAuthenticated = useAuthenticated()
const { isLoading, isAuthenticated } = useAuthenticationStatus()
if (isLoading) return <div>Loading Nhost authentication status...</div>
else if (isAuthenticated) return <div>User is authenticated</div>
else return <div>Public section</div>
@@ -216,29 +239,31 @@ const Component = () => {
### Get the JWT access token
<!-- TODO better documentation -->
<!-- TODO ellaborate -->
```js
const accessToken = useAccessToken()
```
---
## User management
### Change email
```js
const { changeEmail, isLoading, isSuccess, needsVerification, isError, error } =
const { changeEmail, isLoading, isSuccess, needsEmailVerification, isError, error } =
useChangeEmail(email?: string, options?: { redirectTo?: string })
```
| Name | Type | Notes |
| ------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `changeEmail` | (email?: string) => void | Rrequests the email change. The arguement password will take precedence over the the possible state value used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `needsVerification` | boolean | Returns `true` if the email change has been requested, but that a email has been sent to the user to verify the new email. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} \| undefined | Provides details about the error. |
| `redirectTo` | string \| undefined | Redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
| Name | Type | Notes |
| ------------------------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `changeEmail` | (email?: string) => void | Requests the email change. The arguement password will take precedence over the the possible state value used when creating the hook. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `needsEmailVerification` | boolean | Returns `true` if the email change has been requested, but that a email has been sent to the user to verify the new email. |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} \| undefined | Provides details about the error. |
| `redirectTo` | string \| undefined | Redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
#### Usage
@@ -248,12 +273,13 @@ import { useChangeEmail } from '@nhost/react'
const Component = () => {
const [email, setEmail] = useState('')
const { changeEmail, isLoading, needsVerification, isError, error } = useChangeEmail(password)
const { changeEmail, isLoading, needsEmailVerification, isError, error } =
useChangeEmail(password)
return (
<div>
<input value={email} onChange={(event) => setEmail(event.target.value)} />
<button onClick={changeEmail}>Change password</button>
{needsVerification && (
{needsEmailVerification && (
<div>
Please check your mailbox and follow the verification link to confirm your new email
</div>
@@ -330,9 +356,48 @@ const Component = () => {
}
```
### Send email verification
```js
const { sendEmail, isLoading, isSent, isError, error } =
useSendVerificationEmail(email?: string, options?: { redirectTo?: string })
```
| Name | Type | Notes |
| ------------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sendEmail` | (email?: string) => void | Resend the verification email. |
| `isLoading` | boolean | Returns `true` when the action is executing, `false` when it finished its execution. |
| `isSent` | boolean | Returns `true` if the verification email has been sent |
| `isError` | boolean | Returns `true` if an error occurred. |
| `error` | {status: number, error: string, message: string} \| undefined | Provides details about the error. |
| `redirectTo` | string \| undefined | Redirection path in the client application that will be used in the link in the verification email. For instance, if you want to redirect to `https://myapp.com/success`, the `redirectTo` value is `'/success'`. |
#### Usage
```jsx
import { useState } from 'react'
import { useSendVerificationEmail } from '@nhost/react'
const Component = () => {
const [email, setEmail] = useState('')
const { sendEmail, isLoading, isSent, isError, error } = useSendVerificationEmail(email)
return (
<div>
<input value={email} onChange={(event) => setEmail(event.target.value)} />
<button onClick={sendEmail}>Send email verification</button>
{isSent && (
<div>Please check your mailbox and follow the verification link to confirm your email</div>
)}
</div>
)
}
```
---
## User data
<!-- TODO document -->
<!-- TODO ellaborate -->
```js
const userData = useUserData()

View File

@@ -16,43 +16,53 @@ With Npm:
npm install @nhost/react
```
---
## Configuration
`@nhost/react` exports a React provider `NhostProvider` that makes the authentication state and the several hooks available in your application. Wrap this component around your whole App.
`@nhost/react` exports a React provider `NhostReactProvider` that makes the authentication state and the several hooks available in your application. Wrap this component around your whole App.
```jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { NhostProvider } from '@nhost/react'
import { Nhost } from '@nhost/client'
import { NhostClient, NhostReactProvider } from '@nhost/react'
import App from './App'
const nhost = new Nhost({
const nhost = new NhostClient({
backendUrl: 'http://localhost:1337'
})
ReactDOM.render(
<React.StrictMode>
<NhostProvider nhost={nhost}>
<NhostReactProvider nhost={nhost}>
<App />
</NhostProvider>
</NhostReactProvider>
</React.StrictMode>,
document.getElementById('root')
)
```
---
### Options
```js
const nhost = new Nhost({ backendUrl, autoSignIn, autoRefreshToken, storageGetter, storageSetter })
const nhost = new NhostClient({
backendUrl,
autoLogin,
autoRefreshToken,
clientStorageGetter,
clientStorageSetter
})
```
| Name | Type | Default | Notes |
| ------------------ | ----------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `backendUrl` | string | | The Nhost app url, for instance `https://my-app.nhost.run`. When using the CLI, its value is `http://localhost:1337` |
| `autoSignIn` | boolean | `true` | If set to `true`, the client will detect credentials in the current URL that could have been sent during an email verification or an Oauth authentication. It will also automatically authenticate all the active tabs in the current browser. |
| `autoRefreshToken` | boolean | `true` | If set to `true`, the JWT (access token) will be automatically refreshed before it expires. |
| `storageGetter` | (key:string) => string \| null | use localStorage | Nhost stores a refresh token in `localStorage` so the session can be restored when starting the browser. |
| `storageSetter` | (key: string, value: string \| null | use localStorage | |
| Name | Type | Default | Notes |
| --------------------- | ----------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `backendUrl` | string | | The Nhost app url, for instance `https://my-app.nhost.run`. When using the CLI, its value is `http://localhost:1337` |
| `autoLogin` | boolean | `true` | If set to `true`, the client will detect credentials in the current URL that could have been sent during an email verification or an Oauth authentication. It will also automatically authenticate all the active tabs in the current browser. |
| `autoRefreshToken` | boolean | `true` | If set to `true`, the JWT (access token) will be automatically refreshed before it expires. |
| `clientStorageGetter` | (key:string) => string \| null | use localStorage | Nhost stores a refresh token in `localStorage` so the session can be restored when starting the browser. |
| `clientStorageGetter` | (key: string, value: string \| null | use localStorage | |
| `refreshIntervalTime` | | |

View File

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

View File

@@ -2,12 +2,29 @@ export const orderTwo = {
'get-started': {
'quick-start': ['index', 'schema', 'javascript-client', 'permissions'],
authentication: ['index'],
'cli-workflow': ['index', 'workflow-setup', 'install-cli', 'local-changes', 'metadata-and-serverless-functions'],
'cli-workflow': [
'index',
'workflow-setup',
'install-cli',
'local-changes',
'metadata-and-serverless-functions'
],
upgrade: ['index']
},
platform: {
database: ['index', 'permissions', 'graphql'],
authentication: ['index', 'user-management', 'sign-in-methods', 'social-login', 'email-templates'],
authentication: [
'index',
'user-management',
'sign-in-methods',
'social-sign-in',
'sign-in-with-google',
'sign-in-with-github',
'sign-in-with-facebook',
'sign-in-with-linkedin',
'sign-in-with-spotify',
'email-templates'
],
storage: ['index'],
'serverless-functions': ['index', 'event-triggers'],
nhost: ['index', 'environment-variables', 'github-integration', 'local-development']
@@ -16,6 +33,7 @@ export const orderTwo = {
sdk: ['index', 'graphql', 'authentication', 'storage', 'functions'],
react: ['index', 'hooks', 'protecting-routes', 'apollo'],
nextjs: ['index', 'configuration', 'protecting-routes', ],
cli: ['index']
cli: ['index'],
'hasura-auth': ['index', 'installation', 'configuration', 'environment-variables', 'schema', 'api-reference']
}
}

View File

@@ -15,6 +15,11 @@ module.exports = {
source: '/reference/sdk/javascript-sdk',
destination: '/reference/sdk',
permanent: false
},
{
source: '/platform/authentication/social-login',
destination: '/platform/authentication/social-sign-in',
permanent: false
}
]
}

View File

@@ -34,7 +34,8 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-merge-refs": "^1.1.0",
"react-syntax-highlighter": "^15.4.5"
"react-syntax-highlighter": "^15.4.5",
"swagger-ui-react": "^4.5.2"
},
"devDependencies": {
"@types/react": "^17.0.37",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +0,0 @@
{
"presets": ["next/babel"],
"plugins": []
}

View File

@@ -35,3 +35,4 @@ yarn-error.log*
# typescript
*.tsbuildinfo
.nhost

View File

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

View File

@@ -1,34 +1,25 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Nhost & Next.js example (WIP)
## Getting Started
This demo is a work in progress, further improvements are to come
First, run the development server:
### Installation
```bash
npm run dev
# or
First, clone this repo. Then run the commands:
```sh
cd examples/nextjs
yarn
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
If you want to use this demo with your own cloud instance:
You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
- modify the `BACKEND_URL` value in `src/helpers/index.ts`
- don't forget to change the client URL in the Nhost console so email verification will work: `Users -> Login Settings -> Client login URLs`: `http://localhost:4000`
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
If you want to use a local Nhost instance, start the CLI in parallel to Nextjs:
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
```sh
# Inside examples/nextjs
nhost -d
```

View File

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

View File

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

View File

@@ -1,18 +1,10 @@
import { gql } from '@apollo/client'
export const QUERY = gql`
query MyQuery {
test {
export const BOOKS_QUERY = gql`
query BookQuery {
books {
id
}
}
`
export const QUERY_INDEX = gql`
query MyQuery {
test {
id
bidon
title
}
}
`

View File

@@ -1,28 +0,0 @@
/** @type {import('next').NextConfig} */
// * Only required to make it work with the monorepo. Is not required otherwise
const nextConfig = {
reactStrictMode: true,
typescript: {
ignoreBuildErrors: true
},
eslint: {
ignoreDuringBuilds: true
},
webpack: (config, { isServer }) => {
if (isServer) {
// * Related to monorepo and the use of ws in @nhost/apollo
config.resolve.fallback = { bufferutil: false, 'utf-8-validate': false }
}
return config
}
}
const withTM = require('next-transpile-modules')(
['@nhost/client', '@nhost/react', '@nhost/react-apollo', '@nhost/apollo', '@nhost/nextjs'],
{
// resolveSymlinks: true
// debug: true
}
) // pass the modules you would like to see transpiled
module.exports = withTM(nextConfig)

View File

@@ -0,0 +1,133 @@
metadata_directory: metadata
services:
mailhog:
port: 8025
hasura:
version: v2.2.0
environment:
hasura_graphql_enable_remote_schema_permissions: false
auth:
version: 0.4.2
auth:
access_control:
email:
allowed_email_domains: ''
allowed_emails: ''
blocked_email_domains: ''
blocked_emails: ''
url:
allowed_redirect_urls: ''
anonymous_users_enabled: false
client_url: http://localhost:3000
disable_new_users: false
email:
passwordless:
enabled: true
template_fetch_url: ''
gravatar:
default: ''
enabled: true
rating: ''
locale:
allowed: en
default: en
password:
hibp_enabled: false
min_length: 3
provider:
apple:
client_id: ''
enabled: false
key_id: ''
private_key: ''
scope: name,email
team_id: ''
bitbucket:
client_id: ''
client_secret: ''
enabled: false
facebook:
client_id: ''
client_secret: ''
enabled: false
scope: email,photos,displayName
github:
client_id: ''
client_secret: ''
enabled: false
scope: user:email
token_url: ''
user_profile_url: ''
gitlab:
base_url: ''
client_id: ''
client_secret: ''
enabled: false
scope: read_user
google:
client_id: ''
client_secret: ''
enabled: false
scope: email,profile
linkedin:
client_id: ''
client_secret: ''
enabled: false
scope: r_emailaddress,r_liteprofile
spotify:
client_id: ''
client_secret: ''
enabled: false
scope: user-read-email,user-read-private
strava:
client_id: ''
client_secret: ''
enabled: false
twilio:
account_sid: ''
auth_token: ''
enabled: false
messaging_service_id: ''
twitter:
consumer_key: ''
consumer_secret: ''
enabled: false
windows_live:
client_id: ''
client_secret: ''
enabled: false
scope: wl.basic,wl.emails,wl.contacts_emails
sms:
enabled: false
passwordless:
enabled: false
provider:
twilio:
account_sid: ''
auth_token: ''
from: ''
messaging_service_id: ''
smtp:
host: nhost_mailhog
method: ''
pass: password
port: 1807
secure: false
sender: hasura-auth@example.com
user: user
token:
access:
expires_in: 900
refresh:
expires_in: 43200
user:
allowed_roles: user,me
default_allowed_roles: user,me
default_role: user
mfa:
enabled: false
issuer: nhost
signin_email_verified_required: true
storage:
force_download_for_content_types: text/html,application/javascript
version: 3

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Confirm Email Change</h2>
<p>Use this link to confirm changing email:</p>
<p>
<a
href="${serverUrl}/verify?&ticket=${ticket}&type=emailConfirmChange&redirectTo=${redirectTo}"
>
Change email
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Change your email address

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Verify Email</h2>
<p>Use this link to verify your email:</p>
<p>
<a href="${serverUrl}/verify?&ticket=${ticket}&type=emailVerify&redirectTo=${redirectTo}">
Verify Email
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Verify your email

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Reset Password</h2>
<p>Use this link to reset your password:</p>
<p>
<a href="${serverUrl}/verify?&ticket=${ticket}&type=passwordReset&redirectTo=${redirectTo}">
Reset password
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Reset your password

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Magic Link</h2>
<p>Use this link to securely sign in:</p>
<p>
<a
href="${serverUrl}/verify?&ticket=${ticket}&type=signinPasswordless&redirectTo=${redirectTo}"
>
Sign In
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Secure sign-in link

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Confirmer changement de courriel</h2>
<p>Utilisez ce lien pour confirmer le changement de courriel:</p>
<p>
<a
href="${serverUrl}/verify?&ticket=${ticket}&type=emailConfirmChange&redirectTo=${redirectTo}"
>
Changer courriel
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Changez votre adresse courriel

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>V&eacute;rifiez votre courriel</h2>
<p>Utilisez ce lien pour v&eacute;rifier votre courriel:</p>
<p>
<a href="${serverUrl}/verify?&ticket=${ticket}&type=emailVerify&redirectTo=${redirectTo}">
V&eacute;rifier courriel
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Vérifier votre courriel

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>R&eacute;initializer votre mot de passe</h2>
<p>Utilisez ce lien pour r&eacute;initializer votre mot de passe:</p>
<p>
<a href="${serverUrl}/verify?&ticket=${ticket}&type=passwordReset&redirectTo=${redirectTo}">
R&eacute;initializer mot de passe
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Réinitialiser votre mot de passe

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Lien magique</h2>
<p>Utilisez ce lien pour vous connecter de fa&ccedil;on s&eacute;curitaire:</p>
<p>
<a
href="${serverUrl}/verify?&ticket=${ticket}&type=signinPasswordless&redirectTo=${redirectTo}"
>
Connexion
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Lien de connexion sécurisé

View File

@@ -0,0 +1,6 @@
actions: []
custom_types:
enums: []
input_objects: []
objects: []
scalars: []

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,14 @@
- name: default
kind: postgres
configuration:
connection_info:
database_url:
from_env: HASURA_GRAPHQL_DATABASE_URL
isolation_level: read-committed
pool_settings:
connection_lifetime: 600
idle_timeout: 180
max_connections: 50
retries: 20
use_prepared_statements: true
tables: "!include default/tables/tables.yaml"

View File

@@ -0,0 +1,17 @@
table:
name: provider_requests
schema: auth
configuration:
custom_column_names:
id: id
custom_name: authProviderRequests
custom_root_fields:
delete: deleteAuthProviderRequests
delete_by_pk: deleteAuthProviderRequest
insert: insertAuthProviderRequests
insert_one: insertAuthProviderRequest
select: authProviderRequests
select_aggregate: authProviderRequestsAggregate
select_by_pk: authProviderRequest
update: updateAuthProviderRequests
update_by_pk: updateAuthProviderRequest

View File

@@ -0,0 +1,25 @@
table:
name: providers
schema: auth
configuration:
custom_column_names:
id: id
custom_name: authProviders
custom_root_fields:
delete: deleteAuthProviders
delete_by_pk: deleteAuthProvider
insert: insertAuthProviders
insert_one: insertAuthProvider
select: authProviders
select_aggregate: authProvidersAggregate
select_by_pk: authProvider
update: updateAuthProviders
update_by_pk: updateAuthProvider
array_relationships:
- name: userProviders
using:
foreign_key_constraint_on:
column: provider_id
table:
name: user_providers
schema: auth

View File

@@ -0,0 +1,24 @@
table:
name: refresh_tokens
schema: auth
configuration:
custom_column_names:
created_at: createdAt
expires_at: expiresAt
refresh_token: refreshToken
user_id: userId
custom_name: authRefreshTokens
custom_root_fields:
delete: deleteAuthRefreshTokens
delete_by_pk: deleteAuthRefreshToken
insert: insertAuthRefreshTokens
insert_one: insertAuthRefreshToken
select: authRefreshTokens
select_aggregate: authRefreshTokensAggregate
select_by_pk: authRefreshToken
update: updateAuthRefreshTokens
update_by_pk: updateAuthRefreshToken
object_relationships:
- name: user
using:
foreign_key_constraint_on: user_id

View File

@@ -0,0 +1,32 @@
table:
name: roles
schema: auth
configuration:
custom_column_names:
role: role
custom_name: authRoles
custom_root_fields:
delete: deleteAuthRoles
delete_by_pk: deleteAuthRole
insert: insertAuthRoles
insert_one: insertAuthRole
select: authRoles
select_aggregate: authRolesAggregate
select_by_pk: authRole
update: updateAuthRoles
update_by_pk: updateAuthRole
array_relationships:
- name: userRoles
using:
foreign_key_constraint_on:
column: role
table:
name: user_roles
schema: auth
- name: usersByDefaultRole
using:
foreign_key_constraint_on:
column: default_role
table:
name: users
schema: auth

View File

@@ -0,0 +1,31 @@
table:
name: user_providers
schema: auth
configuration:
custom_column_names:
access_token: accessToken
created_at: createdAt
id: id
provider_id: providerId
provider_user_id: providerUserId
refresh_token: refreshToken
updated_at: updatedAt
user_id: userId
custom_name: authUserProviders
custom_root_fields:
delete: deleteAuthUserProviders
delete_by_pk: deleteAuthUserProvider
insert: insertAuthUserProviders
insert_one: insertAuthUserProvider
select: authUserProviders
select_aggregate: authUserProvidersAggregate
select_by_pk: authUserProvider
update: updateAuthUserProviders
update_by_pk: updateAuthUserProvider
object_relationships:
- name: provider
using:
foreign_key_constraint_on: provider_id
- name: user
using:
foreign_key_constraint_on: user_id

View File

@@ -0,0 +1,27 @@
table:
name: user_roles
schema: auth
configuration:
custom_column_names:
created_at: createdAt
id: id
role: role
user_id: userId
custom_name: authUserRoles
custom_root_fields:
delete: deleteAuthUserRoles
delete_by_pk: deleteAuthUserRole
insert: insertAuthUserRoles
insert_one: insertAuthUserRole
select: authUserRoles
select_aggregate: authUserRolesAggregate
select_by_pk: authUserRole
update: updateAuthUserRoles
update_by_pk: updateAuthUserRole
object_relationships:
- name: roleByRole
using:
foreign_key_constraint_on: role
- name: user
using:
foreign_key_constraint_on: user_id

View File

@@ -0,0 +1,65 @@
table:
name: users
schema: auth
configuration:
custom_column_names:
active_mfa_type: activeMfaType
avatar_url: avatarUrl
created_at: createdAt
default_role: defaultRole
disabled: disabled
display_name: displayName
email: email
email_verified: emailVerified
id: id
is_anonymous: isAnonymous
last_seen: lastSeen
locale: locale
new_email: newEmail
otp_hash: otpHash
otp_hash_expires_at: otpHashExpiresAt
otp_method_last_used: otpMethodLastUsed
password_hash: passwordHash
phone_number: phoneNumber
phone_number_verified: phoneNumberVerified
ticket: ticket
ticket_expires_at: ticketExpiresAt
totp_secret: totpSecret
updated_at: updatedAt
custom_name: users
custom_root_fields:
delete: deleteUsers
delete_by_pk: deleteUser
insert: insertUsers
insert_one: insertUser
select: users
select_aggregate: userAggregate
select_by_pk: user
update: updateUsers
update_by_pk: updateUser
object_relationships:
- name: defaultRoleByRole
using:
foreign_key_constraint_on: default_role
array_relationships:
- name: refreshTokens
using:
foreign_key_constraint_on:
column: user_id
table:
name: refresh_tokens
schema: auth
- name: roles
using:
foreign_key_constraint_on:
column: user_id
table:
name: user_roles
schema: auth
- name: userProviders
using:
foreign_key_constraint_on:
column: user_id
table:
name: user_providers
schema: auth

View File

@@ -0,0 +1,10 @@
table:
name: books
schema: public
select_permissions:
- permission:
columns:
- id
- title
filter: {}
role: user

View File

@@ -0,0 +1,10 @@
table:
name: test
schema: public
select_permissions:
- permission:
columns:
- bidon
- id
filter: {}
role: user

View File

@@ -0,0 +1,32 @@
table:
name: buckets
schema: storage
configuration:
custom_column_names:
cache_control: cacheControl
created_at: createdAt
download_expiration: downloadExpiration
id: id
max_upload_file_size: maxUploadFileSize
min_upload_file_size: minUploadFileSize
presigned_urls_enabled: presignedUrlsEnabled
updated_at: updatedAt
custom_name: buckets
custom_root_fields:
delete: deleteBuckets
delete_by_pk: deleteBucket
insert: insertBuckets
insert_one: insertBucket
select: buckets
select_aggregate: bucketsAggregate
select_by_pk: bucket
update: updateBuckets
update_by_pk: updateBucket
array_relationships:
- name: files
using:
foreign_key_constraint_on:
column: bucket_id
table:
name: files
schema: storage

View File

@@ -0,0 +1,30 @@
table:
name: files
schema: storage
configuration:
custom_column_names:
bucket_id: bucketId
created_at: createdAt
etag: etag
id: id
is_uploaded: isUploaded
mime_type: mimeType
name: name
size: size
updated_at: updatedAt
uploaded_by_user_id: uploadedByUserId
custom_name: files
custom_root_fields:
delete: deleteFiles
delete_by_pk: deleteFile
insert: insertFiles
insert_one: insertFile
select: files
select_aggregate: filesAggregate
select_by_pk: file
update: updateFiles
update_by_pk: updateFile
object_relationships:
- name: bucket
using:
foreign_key_constraint_on: bucket_id

View File

@@ -0,0 +1,10 @@
- "!include auth_provider_requests.yaml"
- "!include auth_providers.yaml"
- "!include auth_refresh_tokens.yaml"
- "!include auth_roles.yaml"
- "!include auth_user_providers.yaml"
- "!include auth_user_roles.yaml"
- "!include auth_users.yaml"
- "!include public_books.yaml"
- "!include storage_buckets.yaml"
- "!include storage_files.yaml"

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
version: 3

View File

@@ -0,0 +1 @@
DROP TABLE "public"."test";

View File

@@ -0,0 +1,2 @@
CREATE TABLE "public"."test" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), PRIMARY KEY ("id") );
CREATE EXTENSION IF NOT EXISTS pgcrypto;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."test" add column "bidon" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."test" add column "bidon" text
null;

View File

@@ -0,0 +1,3 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- DROP table "public"."test";

View File

@@ -0,0 +1 @@
DROP table "public"."test";

View File

@@ -0,0 +1 @@
DROP TABLE "public"."books";

View File

@@ -0,0 +1,2 @@
CREATE TABLE "public"."books" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "title" text NOT NULL, PRIMARY KEY ("id") );
CREATE EXTENSION IF NOT EXISTS pgcrypto;

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/nextjs",
"version": "0.0.2",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
@@ -9,30 +9,22 @@
"lint": "next lint"
},
"dependencies": {
"@nhost/apollo": "workspace:^0.2.0",
"@nhost/client": "workspace:^0.2.0",
"@nhost/nextjs": "workspace:^0.2.0",
"@nhost/react": "workspace:^0.2.0",
"@nhost/react-apollo": "workspace:^3.0.0",
"@xstate/react": "^2.0.0",
"apollo-boost": "^0.4.9",
"apollo-client": "^2.6.10",
"next": "12.0.10",
"@apollo/client": "^3.5.10",
"@nhost/nextjs": "^1.0.0",
"@nhost/react": "^0.3.0",
"@nhost/react-apollo": "^4.0.0",
"graphql": "^16.3.0",
"next": "12.1.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"subscriptions-transport-ws": "^0.11.0"
"react-dom": "17.0.2"
},
"devDependencies": {
"@apollo/client": "^3.5.8",
"@types/js-cookie": "^3.0.1",
"@types/node": "17.0.17",
"@types/react": "17.0.39",
"@types/node": "17.0.23",
"@types/react": "17.0.43",
"@xstate/inspect": "^0.6.2",
"eslint": "8.8.0",
"eslint-config-next": "12.0.10",
"graphql": "16",
"next-transpile-modules": "^9.0.0",
"typescript": "4.5.5",
"ws": "^8.4.2"
"ws": "^8.5.0"
}
}

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