diff --git a/dashboard/CHANGELOG.md b/dashboard/CHANGELOG.md index 1d3bf24413..c3fa3d8bec 100644 --- a/dashboard/CHANGELOG.md +++ b/dashboard/CHANGELOG.md @@ -1,5 +1,11 @@ # @nhost/dashboard +## 1.7.0 + +### Minor Changes + +- 0d8d0eb: Update docs and dashboard references + ## 1.6.9 ### Patch Changes diff --git a/dashboard/package.json b/dashboard/package.json index 29c176bc96..f117f4c5b7 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@nhost/dashboard", - "version": "1.6.9", + "version": "1.7.0", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", diff --git a/dashboard/src/features/authentication/settings/components/AllowedEmailSettings/AllowedEmailSettings.tsx b/dashboard/src/features/authentication/settings/components/AllowedEmailSettings/AllowedEmailSettings.tsx index ff74da9188..a200bac1c7 100644 --- a/dashboard/src/features/authentication/settings/components/AllowedEmailSettings/AllowedEmailSettings.tsx +++ b/dashboard/src/features/authentication/settings/components/AllowedEmailSettings/AllowedEmailSettings.tsx @@ -130,7 +130,7 @@ export default function AllowedEmailDomainsSettings() { loading: formState.isSubmitting, }, }} - docsLink="https://docs.nhost.io/authentication#allowed-emails-and-domains" + docsLink="https://docs.nhost.io/guides/auth/overview#allowed-emails-and-domains" switchId="enabled" showSwitch className={twMerge( diff --git a/dashboard/src/features/authentication/settings/components/AllowedRedirectURLsSettings/AllowedRedirectURLsSettings.tsx b/dashboard/src/features/authentication/settings/components/AllowedRedirectURLsSettings/AllowedRedirectURLsSettings.tsx index f966091406..3b263d61b0 100644 --- a/dashboard/src/features/authentication/settings/components/AllowedRedirectURLsSettings/AllowedRedirectURLsSettings.tsx +++ b/dashboard/src/features/authentication/settings/components/AllowedRedirectURLsSettings/AllowedRedirectURLsSettings.tsx @@ -105,7 +105,7 @@ export default function AllowedRedirectURLsSettings() { loading: formState.isSubmitting, }, }} - docsLink="https://docs.nhost.io/authentication#allowed-redirect-urls" + docsLink="https://docs.nhost.io/guides/auth/overview#allowed-redirect-urls" className="grid grid-flow-row px-4 lg:grid-cols-5" > Learn more about{' '} + + + + + + + + + + + + +### OAuth Providers + + + + + + + + + + + + + + + + + + + + + + +## Client URL + +Client URL is the URL of your frontend application. The Client URL is used to redirect the user in certain auth workflows like signing in or resetting a password. + +## Allowed Redirect URLs + +Allowed Redirect URLs are the URLs of your frontend application that users are allowed to be redirected to on specific auth workflows. This is useful if you have multiple applications using the same Nhost backend or if you want to redirect users to a specific URL after certain authentication workflows. + +As an example, for a staging project, you can set the Client URL to `https://staging.example.com` and Allowed Redirect URLs to `https://*.vercel.app`. This way, the user can be redirected to any Vercel deployment of your frontend application. + +## Allowed Emails and Domains + +Allowed Emails and Domains are used to restrict what email adresses and domains are valid when signing up and signing in. + +If both allowed emails and allowed domains are set a user can only sign up if their email address matches one of the allowed emails or one of the allowed domains. + +## Blocked Emails and Domains + +Blocked Emails and Domains are used to block specific email addresses and domains from signing up and signing in. + +Note that even if a user's email address matches any allowed email or domain, they will still be blocked if their email address matches any blocked email or domain. + +## Multi-factor Authentication + +By enabling Multi-Factor Authentication (MFA), you can allow users to verify their identity using a second factor during the sign-in process. We currently support Authenticator Apps (TOTP) for MFA. + +A user can enable MFA for their account by scanning a QR code with their Authenticator App. After that, they will be prompted to enter a code generated by their Authenticator App during the sign-in process. + +## Gravatar + +If Gravatar is enabled, Nhost Auth will use the user's email address to fetch their Gravatar profile picture. If the user doesn't have a Gravatar profile picture, a default image will be used. + +There are two options for Gravatars. + + + + +If the user doesn't have a Gravatar profile picture, a default image will be used. You can choose between the following options: + +- `404`: Do not load any image if none is associated with the email hash, instead return an HTTP 404 (File Not Found) response. +- `mp`: (mystery-person) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash). +- `identicon`: a geometric pattern based on an email hash. +- `monsterid`: a generated 'monster' with different colors, faces, etc. +- `wavatar`: generated faces with differing features and backgrounds. +- `retro`: awesome generated, 8-bit arcade-style pixelated faces. +- `robohash`: a generated robot with different colors, faces, etc. +- `blank`: a transparent PNG image. + + + + + +Gravatar images are rated by default. You can choose between the following options: + +- `g`: suitable for display on all websites with any audience type. +- `pg`: may contain rude gestures, provocatively dressed individuals, lesser swear words or mild violence. +- `r`: may contain such things as harsh profanity, intense violence, nudity, or hard drug use. +- `x`: may contain hardcore sexual imagery or extremely disturbing violence. + + + + +## Disable New Users + +If set, newly registered users are disabled and won't be able to sign in. This is useful if you want to manually approve new users before they can sign in. diff --git a/docs/guides/auth/users.mdx b/docs/guides/auth/users.mdx new file mode 100644 index 0000000000..fbef8f1aa4 --- /dev/null +++ b/docs/guides/auth/users.mdx @@ -0,0 +1,155 @@ +--- +title: Users +description: Learn about Users managed by Nhost Auth +icon: users +--- + +## Creating Users + +Users are created using the sign-up or sign-in flows described under [Supported Methods](/guides/auth/overview#supported-methods). + +- **Avoid** creating users directly via GraphQL or the database, unless you are [importing users](#import-users) from an external system. +- **Avoid** modifying the database schema for the `auth.users` table. +- **Avoid** modifying the GraphQL root queries or fields for any of the tables in the `auth` schema. + +You're allowed to: + +- Add and remove your GraphQL relationships for the `users` table and other tables in the `auth` schema. +- Create, edit and delete permissions for the `users` table and other tables in the `auth` schema. + +## Roles + +Each user has one **default role** and a list of **allowed roles**. These roles are used to resolve permissions for requests to [GraphQL](/graphql/permissions) and [Storage](/storage#permissions). + +When the user makes a request, only one role is used to resolve permissions. The default role is used if no role is explicitly specified. Users can only make requests using the default role or one of the allowed roles. + +### Default Role + +The default role is used when no role is specified in the request. By default, users' default role is `user`. + +You can change what the default role for new users should be at **Settings -> Roles and Permissions**. + +### Allowed Roles + +Allowed roles are roles the user is allowed to use when making a request. Usually, you would change the role from `user` (the default role) to some other role because you want to use a different role to resolve permissions for a particular request. + +By default, users have two allowed roles: + +- `user` (default) +- `me` + +You can change the default role for new users at **Settings -> Roles and Permissions**. + +#### Assign Allowed Roles + +It's possible to give users a subset of allowed roles during signup. + +**Example:** Only set the `user` role (exclude the `me` role) for the user's allowed roles: + +```js +await nhost.auth.signUp({ + email: 'joe@example.com', + password: 'secret-password' + options: { + allowedRoles: ['user'] + } +}) +``` + +### Set Role for GraphQL Requests + +When no role is specified, the user's default role will be used: + +```js +await nhost.graphql.request(QUERY, {}) +``` + +If you want to make a GraphQL request using a specific role, you can do so by using the `x-hasura-role` header, like this: + +```js +await nhost.graphql.request( + QUERY, + {}, + { + headers: { + 'x-hasura-role': 'me' + } + } +) +``` + +If the request is not part of the user's allowed roles, the request will fail. + +## Metadata + +You can store custom information about the user in the `metadata` column of the `users` table. The `metadata` column is of type JSONB so any JSON data can be stored. + +**Example:** Add metadata to a user during sign-up: + +```js +await nhost.auth.signUp({ + email: 'joe@example.com', + password: 'secret-password', + options: { + metadata: { + birthYear: 1989, + town: 'Stockholm', + likes: ['Postgres', 'GraphQL', 'Hasura', 'Authentication', 'Storage', 'Serverless Functions'] + } + } +}) +``` + +## Get User Information using GraphQL + +**Example:** Get all users. + +```graphql +query { + users { + id + displayName + email + metadata + } +} +``` + +**Example:** Get a single user. + +```graphql +query { + user(id: "") { + id + displayName + email + metadata + } +} +``` + +## Import Users + +If you have users in a different system, you can import them into Nhost. When importing users you should insert the users directly into the database instead of using the authentication endpoints (`/signup/email-password`) to avoid sending unnecessary transactional emails. + +### GraphQL + +Make a GraphQL request to insert a user like this: + +```graphql +mutation insertUser($user: users_insert_input!) { + insertUser(object: $user) { + id + } +} +``` + +### SQL + +Connect directly to the database and insert a user like this: + +```sql +INSERT INTO auth.users (id, email, display_name, password_hash, ..) VALUES ('', '', '', '', ..); +``` + +Passwords are hashed using [bcrypt](https://en.wikipedia.org/wiki/Bcrypt). diff --git a/docs/mint.json b/docs/mint.json index b13eb5ec81..16b715af47 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -111,6 +111,8 @@ { "group": "Authentication", "pages": [ + "guides/auth/overview", + "guides/auth/users", { "group": "Social Sign In", "icon": "at", diff --git a/docs/package.json b/docs/package.json index f06e16b064..c6bea8825a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@nhost/docs", - "version": "2.4.0", + "version": "2.5.0", "private": true, "scripts": { "start": "mintlify dev" diff --git a/docs/platform/environment-variables.mdx b/docs/platform/environment-variables.mdx index 97956fd8c8..8ca1e3064b 100644 --- a/docs/platform/environment-variables.mdx +++ b/docs/platform/environment-variables.mdx @@ -21,7 +21,7 @@ export default (req: Request, res: Response) => { Variables created are available to all services, including Run Services and Functions -## Add Environment Variables +## Adding Environment Variables @@ -39,3 +39,43 @@ value = "Nhost is Awesome!" +## System Environment Variables + +System environment variables are generated and managed by Nhost. The following variables are available: + +- `NHOST_ADMIN_SECRET` +- `NHOST_WEBHOOK_SECRET` +- `NHOST_SUBDOMAIN` +- `NHOST_REGION` +- `NHOST_HASURA_URL` +- `NHOST_AUTH_URL` +- `NHOST_GRAPHQL_URL` +- `NHOST_STORAGE_URL` +- `NHOST_FUNCTIONS_URL` +- `NHOST_JWT_SECRET` + +`NHOST_ADMIN_SECRET`, `NHOST_WEBHOOK_SECRET` and `NHOST_JWT_SECRET` are populated with values from their corresponding secrets. + +**Example values**: + +```text +NHOST_ADMIN_SECRET={{ secrets.HASURA_GRAPHQL_ADMIN_SECRET }} + +NHOST_WEBHOOK_SECRET={{ secrets.NHOST_WEBHOOK_SECRET }} + +NHOST_SUBDOMAIN=abv123abc + +NHOST_REGION=eu-central-1 + +NHOST_HASURA_URL=https://abc123abc.hasura.eu-central-1.nhost.run/console + +NHOST_AUTH_URL=https://abc123abc.auth.eu-central-1.nhost.run/v1 + +NHOST_GRAPHQL_URL=https://abc123abc.graphql.eu-central-1.nhost.run/v1 + +NHOST_STORAGE_URL=https://abc123abc.storage.eu-central-1.nhost.run/v1 + +NHOST_FUNCTIONS_URL=https://abc123abc.functions.eu-central-1.nhost.run/v1 + +NHOST_JWT_SECRET={"key": "{{ secrets.HASURA_GRAPHQL_JWT_SECRET }}", "type": "HS256" } +``` diff --git a/examples/docker-compose/.env.example b/examples/docker-compose/.env.example index cf3b0e5d50..3149801bd1 100644 --- a/examples/docker-compose/.env.example +++ b/examples/docker-compose/.env.example @@ -1,5 +1,31 @@ +# Change all these variables before first creating the containers POSTGRES_PASSWORD=secret-pg-password-never-use-this-value -HASURA_GRAPHQL_ADMIN_SECRET=nhost-admin-secret +HASURA_GRAPHQL_ADMIN_SECRET=change-me +# The jwt secret key can be generated with `openssl rand -hex 32` HASURA_GRAPHQL_JWT_SECRET='{"type":"HS256", "key":"5152fa850c02dc222631cca898ed1485821a70912a6e3649c49076912daa3b62182ba013315915d64f40cddfbb8b58eb5bd11ba225336a6af45bbae07ca873f3","issuer":"hasura-auth"}' STORAGE_ACCESS_KEY=storage-access-key-never-use-this-value STORAGE_SECRET_KEY=storage-secret-key-never-use-this-value + +# The following HOST and URL env variables are separated since the HOST variables are used to define the allowed hosts to the traefik services in the docker-compose.yaml + +# Public (proxy.my-nhost.com) or private (localhost) hostname for the Hasura API/proxy for the Nhost dashboard to send requests to +PROXY_HOST=localhost +# Change to https://${PROXY_HOST} if not using localhost +PROXY_URL=http://${PROXY_HOST}:1337 + +# Public (example-url.my-nhost.com) or private (localhost) hostname for the Nhost dashboard for the proxy to allow requests from +NHOST_HOST=localhost + +# Environment variables for the Nhost Dashboard. See dashboard/.env.example for default values. The defualt values are changed to work with our traefik setup created with the docker-compose + +# URL for the migrations API running from running `hasura-console`. If it needs to be publicly accessible, change it to your publicly-available URL (https://hasura-migrations.my-nhost.com) +NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL=http://localhost:9693 + +# The following do not need to be changed unless you modified the docker-compose.yaml +NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL=${PROXY_URL} +NEXT_PUBLIC_NHOST_HASURA_API_URL=${PROXY_URL} +NEXT_PUBLIC_NHOST_ADMIN_SECRET=${HASURA_GRAPHQL_ADMIN_SECRET} +NEXT_PUBLIC_NHOST_AUTH_URL=${PROXY_URL}/v1/auth +NEXT_PUBLIC_NHOST_GRAPHQL_URL=${PROXY_URL}/v1/graphql +NEXT_PUBLIC_NHOST_STORAGE_URL=${PROXY_URL}/v1/storage +NEXT_PUBLIC_NHOST_FUNCTIONS_URL=${PROXY_URL}/v1/functions diff --git a/examples/docker-compose/CHANGELOG.md b/examples/docker-compose/CHANGELOG.md index 68577d1e62..533d62634e 100644 --- a/examples/docker-compose/CHANGELOG.md +++ b/examples/docker-compose/CHANGELOG.md @@ -1,5 +1,11 @@ # @nhost-examples/docker-compose +## 0.1.0 + +### Minor Changes + +- ed9df85: updated docker-compose.yaml and .env-example + ## 0.0.7 ### Patch Changes diff --git a/examples/docker-compose/docker-compose.yaml b/examples/docker-compose/docker-compose.yaml index ce185956fc..166b787f14 100644 --- a/examples/docker-compose/docker-compose.yaml +++ b/examples/docker-compose/docker-compose.yaml @@ -8,9 +8,14 @@ services: - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:1337" + - "--entryPoints.admin.address=:3030" ports: + # hasura/services - "1337:1337" + # traefik interface - "9090:8080" + # dashboard + - "3030:3030" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" postgres: @@ -24,7 +29,7 @@ services: ports: - '5432:5432' graphql-engine: - image: hasura/graphql-engine:v2.15.2 + image: hasura/graphql-engine:v2.35.1 depends_on: - 'postgres' restart: always @@ -39,10 +44,10 @@ services: HASURA_GRAPHQL_ENABLE_CONSOLE: 'true' labels: - "traefik.enable=true" - - "traefik.http.routers.hasura.rule=Host(`localhost`) && PathPrefix(`/`)" + - "traefik.http.routers.hasura.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/`)" - "traefik.http.routers.hasura.entrypoints=web" auth: - image: nhost/hasura-auth:0.16.2 + image: nhost/hasura-auth:0.24 depends_on: - postgres - graphql-engine @@ -66,11 +71,11 @@ services: labels: - "traefik.enable=true" - "traefik.http.middlewares.strip-auth.stripprefix.prefixes=/v1/auth" - - "traefik.http.routers.auth.rule=Host(`localhost`) && PathPrefix(`/v1/auth`)" + - "traefik.http.routers.auth.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/v1/auth`)" - "traefik.http.routers.auth.middlewares=strip-auth@docker" - "traefik.http.routers.auth.entrypoints=web" storage: - image: nhost/hasura-storage:0.3.1 + image: nhost/hasura-storage:0.4.1 depends_on: - postgres - graphql-engine @@ -79,7 +84,7 @@ services: expose: - 8000 environment: - PUBLIC_URL: http://localhost:${PROXY_PORT:-1337} + PUBLIC_URL: ${PROXY_URL} HASURA_METADATA: 1 HASURA_ENDPOINT: http://graphql-engine:8080/v1 HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET} @@ -91,7 +96,7 @@ services: POSTGRES_MIGRATIONS_SOURCE: postgres://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres?sslmode=disable labels: - "traefik.enable=true" - - "traefik.http.routers.storage.rule=Host(`localhost`) && PathPrefix(`/v1/storage`)" + - "traefik.http.routers.storage.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/v1/storage`)" - "traefik.http.routers.storage.entrypoints=web" # Rewrite the path so it matches with the new storage API path introduced in hasura-storage 0.2 - "traefik.http.middlewares.strip-suffix.replacepathregex.regex=^/v1/storage/(.*)" @@ -99,11 +104,11 @@ services: - "traefik.http.routers.storage.middlewares=strip-suffix@docker" command: serve functions: - image: nhost/functions:0.1.8 + image: nhost/functions:1.0.0 labels: - "traefik.enable=true" - "traefik.http.middlewares.strip-functions.stripprefix.prefixes=/v1/functions" - - "traefik.http.routers.functions.rule=Host(`localhost`) && PathPrefix(`/v1/functions`)" + - "traefik.http.routers.functions.rule=Host(`${PROXY_HOST}`, `localhost`) && PathPrefix(`/v1/functions`)" - "traefik.http.routers.functions.middlewares=strip-functions@docker" - "traefik.http.routers.functions.entrypoints=web" restart: always @@ -140,8 +145,24 @@ services: volumes: - ./data/mailhog:/maildir dashboard: - image: nhost/dashboard:0.7.4 - ports: - - "3030:3000" + image: nhost/dashboard:0.21.1 + environment: + NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL: ${NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL} + NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL: ${NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL} + NEXT_PUBLIC_NHOST_HASURA_API_URL: ${NEXT_PUBLIC_NHOST_HASURA_API_URL} + NEXT_PUBLIC_NHOST_ADMIN_SECRET: ${NEXT_PUBLIC_NHOST_ADMIN_SECRET} + NEXT_PUBLIC_NHOST_AUTH_URL: ${NEXT_PUBLIC_NHOST_AUTH_URL} + NEXT_PUBLIC_NHOST_GRAPHQL_URL: ${NEXT_PUBLIC_NHOST_GRAPHQL_URL} + NEXT_PUBLIC_NHOST_STORAGE_URL: ${NEXT_PUBLIC_NHOST_STORAGE_URL} + NEXT_PUBLIC_NHOST_FUNCTIONS_URL: ${NEXT_PUBLIC_NHOST_FUNCTIONS_URL} + expose: + - 3000 + labels: + - "traefik.enable=true" + - "traefik.http.routers.nhost.rule=Host(`${NHOST_HOST}`)" + - "traefik.http.routers.nhost.entrypoints=admin" + # If you would like to protect your dashboard with a username and password if it is publicly-facing, uncomment and fill in the following lines below according to the documentation at https://doc.traefik.io/traefik/middlewares/http/basicauth/ + #- "traefik.http.routers.nhost.middlewares=auth" + #- "traefik.http.middlewares.auth.basicauth.users= volumes: functions_node_modules: diff --git a/examples/docker-compose/functions/pnpm-lock.yaml b/examples/docker-compose/functions/pnpm-lock.yaml new file mode 100644 index 0000000000..2b9f1883a1 --- /dev/null +++ b/examples/docker-compose/functions/pnpm-lock.yaml @@ -0,0 +1,5 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false diff --git a/examples/docker-compose/package.json b/examples/docker-compose/package.json index b646debc13..dd1e464d72 100644 --- a/examples/docker-compose/package.json +++ b/examples/docker-compose/package.json @@ -1,6 +1,6 @@ { "name": "@nhost-examples/docker-compose", - "version": "0.0.7", + "version": "0.1.0", "private": true, "scripts": { "e2e": "vitest run" diff --git a/examples/vue-apollo/CHANGELOG.md b/examples/vue-apollo/CHANGELOG.md index f116469778..1690fd6097 100644 --- a/examples/vue-apollo/CHANGELOG.md +++ b/examples/vue-apollo/CHANGELOG.md @@ -1,5 +1,11 @@ # @nhost-examples/vue-apollo +## 0.2.1 + +### Patch Changes + +- c5c904b: fix: update signin methods settings + ## 0.2.0 ### Minor Changes diff --git a/examples/vue-apollo/package.json b/examples/vue-apollo/package.json index cf283836fc..592f09a0a5 100644 --- a/examples/vue-apollo/package.json +++ b/examples/vue-apollo/package.json @@ -1,7 +1,7 @@ { "name": "@nhost-examples/vue-apollo", "private": true, - "version": "0.2.0", + "version": "0.2.1", "scripts": { "dev": "vite", "build": "vite build",