Compare commits

..

59 Commits

Author SHA1 Message Date
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
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
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
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
34 changed files with 2714 additions and 96 deletions

View File

@@ -36,6 +36,8 @@ 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"/>

View File

@@ -33,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 (
@@ -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,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

@@ -365,7 +365,7 @@ const { sendEmail, isLoading, isSent, isError, error } =
| Name | Type | Notes |
| ------------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sendEmail` | (email?: string) => void | Requests the email change. The arguement password will take precedence over the the possible state value used when creating the hook. |
| `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. |
@@ -376,11 +376,11 @@ const { sendEmail, isLoading, isSent, isError, error } =
```jsx
import { useState } from 'react'
import { useChangeEmail } from '@nhost/react'
import { useSendVerificationEmail } from '@nhost/react'
const Component = () => {
const [email, setEmail] = useState('')
const { sendEmail, isLoading, isSent, isError, error } = useChangeEmail(password)
const { sendEmail, isLoading, isSent, isError, error } = useSendVerificationEmail(email)
return (
<div>
<input value={email} onChange={(event) => setEmail(event.target.value)} />

View File

@@ -33,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

@@ -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 it is too large Load Diff

View File

@@ -1,5 +1,13 @@
# @nhost/apollo
## 0.3.1
### Patch Changes
- 113beed: fix: Refetched queries and leaking subscriptions [#301](https://github.com/nhost/nhost/issues/301)
- Updated dependencies [4420c0e]
- @nhost/core@0.3.1
## 0.3.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/apollo",
"version": "0.3.0",
"version": "0.3.1",
"description": "Nhost Apollo Client library",
"license": "MIT",
"keywords": [

View File

@@ -131,26 +131,22 @@ export const createApolloClient = ({
if (token !== newToken) {
token = newToken
client.reFetchObservableQueries()
if (isBrowser && webSocketClient) {
if (newToken) {
if (webSocketClient.status === 1) {
// @ts-expect-error
webSocketClient.tryReconnect()
}
} else {
if (webSocketClient.status === 1) {
// must close first to avoid race conditions
webSocketClient.close()
// reconnect
// @ts-expect-error
webSocketClient.tryReconnect()
}
if (event.type === 'SIGNOUT') {
await client.resetStore().catch((error) => {
console.error('Error resetting Apollo client cache')
console.error(error)
})
if (webSocketClient.status === 1) {
// must close first to avoid race conditions
webSocketClient.close()
// @ts-expect-error
webSocketClient.tryReconnect()
}
if (!newToken && event.type === 'SIGNOUT') {
try {
await client.resetStore()
} catch (error) {
console.error('Error resetting Apollo client cache')
console.error(error)
}
}
}

View File

@@ -1,5 +1,13 @@
# @nhost/core
## 0.3.1
### Patch Changes
- 4420c0e: Check if `window.location` exists
When using [Expo](https://expo.dev/), `window` can be an object while `window.location` is `undefined`. It lead to [this issue](https://github.com/nhost/nhost/issues/309).
## 0.3.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/core",
"version": "0.3.0",
"version": "0.3.1",
"description": "Nhost core client library",
"license": "MIT",
"keywords": [

View File

@@ -18,7 +18,7 @@ export class AuthClient {
constructor({
backendUrl,
clientUrl = typeof window !== 'undefined' ? window.location.origin : '',
clientUrl = (typeof window !== 'undefined' && window.location?.origin) || '',
clientStorageGetter = defaultClientStorageGetter,
clientStorageSetter = defaultClientStorageSetter,
refreshIntervalTime = MIN_TOKEN_REFRESH_INTERVAL,

View File

@@ -635,27 +635,25 @@ export const createAuthMachine = ({
}),
autoSignIn: async () => {
if (typeof window !== 'undefined') {
const location = window.location
if (location.hash) {
const params = new URLSearchParams(location.hash.slice(1))
const refreshToken = params.get('refreshToken')
if (refreshToken) {
const session = await postRequest('/token', {
refreshToken
})
// * remove hash from the current url after consumming the token
// TODO remove the hash. For the moment, it is kept to avoid regression from the current SDK.
// * Then, only `refreshToken` will be in the hash, while `type` will be sent by hasura-auth as a query parameter
// window.history.pushState({}, '', location.pathname)
const channel = new BroadcastChannel('nhost')
// TODO broadcat session instead of token
channel.postMessage(refreshToken)
return { session }
}
}
if (typeof window === 'undefined' || !window.location)
throw Error('window is undefined or location does not exist')
const { hash } = window.location
if (!hash) return
const params = new URLSearchParams(hash.slice(1))
const refreshToken = params.get('refreshToken')
if (refreshToken) {
const session = await postRequest('/token', {
refreshToken
})
// * remove hash from the current url after consumming the token
// TODO remove the hash. For the moment, it is kept to avoid regression from the current SDK.
// * Then, only `refreshToken` will be in the hash, while `type` will be sent by hasura-auth as a query parameter
// window.history.pushState({}, '', location.pathname)
const channel = new BroadcastChannel('nhost')
// TODO broadcat session instead of token
channel.postMessage(refreshToken)
return { session }
}
throw Error()
},
importRefreshToken: async () => {
const stringExpiresAt = await clientStorageGetter(NHOST_JWT_EXPIRES_AT_KEY)

View File

@@ -1,5 +1,15 @@
# @nhost/hasura-auth-js
## 1.0.2
### Patch Changes
- 6eeb9d2: Wait for the authentication status to be known before executing auth actions
The auth client was able to start actions such as signUp or signIn before the authentication state was ready (e.g. before initial refresh token could be processed).
This patch solves the problem in waiting for the authentication status to be known before running these actions.
- Updated dependencies [4420c0e]
- @nhost/core@0.3.1
## 1.0.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/hasura-auth-js",
"version": "1.0.1",
"version": "1.0.2",
"description": "Hasura-auth client",
"license": "MIT",
"keywords": [

View File

@@ -33,6 +33,7 @@ import {
SignUpParams,
SignUpResponse
} from './utils/types'
const USER_ALREADY_SIGNED_IN: ApiError = {
message: 'User is already signed in',
status: 100
@@ -93,10 +94,7 @@ export class HasuraAuthClient {
* @docs https://docs.nhost.io/reference/sdk/authentication#nhost-auth-signup
*/
async signUp(params: SignUpParams): Promise<SignUpResponse> {
const interpreter = this.#client.interpreter
if (!interpreter) {
throw Error('Auth interpreter not set')
}
const interpreter = await this.waitUntilReady()
const { email, password, options } = params
@@ -145,8 +143,7 @@ export class HasuraAuthClient {
providerUrl?: string
provider?: string
}> {
const interpreter = this.#client.interpreter
if (!interpreter) throw Error('Auth interpreter not set')
const interpreter = await this.waitUntilReady()
// * Raise an error if the user is already authenticated
if (this.isAuthenticated()) {
@@ -282,8 +279,7 @@ export class HasuraAuthClient {
* @docs https://docs.nhost.io/reference/sdk/authentication#nhost-auth-signout
*/
async signOut(params?: { all?: boolean }): Promise<ApiSignOutResponse> {
const interpreter = this.#client.interpreter
if (!interpreter) throw Error('Auth interpreter not set')
const interpreter = await this.waitUntilReady()
if (!this.isAuthenticated()) return { error: USER_UNAUTHENTICATED }
return new Promise((resolve) => {
interpreter.send({ type: 'SIGNOUT', all: params?.all })
@@ -387,9 +383,8 @@ export class HasuraAuthClient {
* @docs https://docs.nhost.io/TODO
*/
async deanonymize(params: DeanonymizeParams): Promise<ApiDeanonymizeResponse> {
const interpreter = await this.waitUntilReady()
return new Promise((resolve) => {
const interpreter = this.#client.interpreter
if (!interpreter) throw Error('Auth interpreter not set')
if (!this.isAuthenticated() || !interpreter.state.context.user?.isAnonymous)
return { error: USER_NOT_ANONYMOUS }
interpreter.onTransition((state) => {
@@ -496,15 +491,8 @@ export class HasuraAuthClient {
* @docs https://docs.nhost.io/TODO
*/
async isAuthenticatedAsync(): Promise<boolean> {
return new Promise((resolve) => {
// if init auth loading is already completed, we can return the value of `isAuthenticated`.
if (this.isReady()) resolve(this.isAuthenticated())
const interpreter = this.#client.interpreter
if (!interpreter) resolve(false)
interpreter?.onTransition((state) => {
if (state.hasTag('ready')) resolve(state.matches({ authentication: 'signedIn' }))
})
})
const interpreter = await this.waitUntilReady()
return interpreter.state.matches({ authentication: 'signedIn' })
}
/**
@@ -571,20 +559,24 @@ export class HasuraAuthClient {
* @docs https://docs.nhost.io/TODO
*/
async refreshSession(refreshToken?: string): Promise<void> {
return new Promise((resolve) => {
const interpreter = this.#client.interpreter
if (!interpreter || !interpreter.state.matches({ token: 'idle' })) return resolve()
const token = refreshToken || interpreter.state.context.refreshToken.value
if (!token) return resolve()
interpreter?.onTransition((state) => {
if (state.matches({ token: { idle: 'error' } })) resolve()
else if (state.event.type === 'TOKEN_CHANGED') resolve()
try {
const interpreter = await this.waitUntilReady()
if (interpreter.state.matches({ token: 'idle' })) return
return new Promise((resolve) => {
const token = refreshToken || interpreter.state.context.refreshToken.value
if (!token) return resolve()
interpreter?.onTransition((state) => {
if (state.matches({ token: { idle: 'error' } })) resolve()
else if (state.event.type === 'TOKEN_CHANGED') resolve()
})
interpreter.send({
type: 'TRY_TOKEN',
token
})
})
interpreter.send({
type: 'TRY_TOKEN',
token
})
})
} catch {
return
}
}
/**
@@ -615,6 +607,31 @@ export class HasuraAuthClient {
return this.#client.interpreter?.state?.context?.user || null
}
/**
* Make sure the state machine is set, and wait for it to be ready
* @returns
*/
private waitUntilReady(): Promise<AuthInterpreter> {
const TIMEOUT_IN_SECONS = 15
const interpreter = this.#client.interpreter
if (!interpreter) {
throw Error('Auth interpreter not set')
}
if (interpreter.state.hasTag('ready')) return Promise.resolve(interpreter)
return new Promise((resolve, reject) => {
let timer: ReturnType<typeof setTimeout> = setTimeout(
() => reject(`The state machine is not yet ready after ${TIMEOUT_IN_SECONS} seconds.`),
TIMEOUT_IN_SECONS * 1_000
)
interpreter.onTransition((state) => {
if (state.hasTag('ready')) {
clearTimeout(timer)
return resolve(interpreter)
}
})
})
}
private isReady() {
return !!this.#client.interpreter?.state?.hasTag('ready')
}

View File

@@ -1,6 +1,13 @@
# @nhost/nextjs
## 2.0.0
## 1.0.3
### Patch Changes
- @nhost/nhost-js@1.0.2
- @nhost/react@0.4.1
## 1.0.2
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/nextjs",
"version": "2.0.0",
"version": "1.0.3",
"description": "Nhost NextJS library",
"license": "MIT",
"keywords": [

View File

@@ -1,5 +1,12 @@
# @nhost/nhost-js
## 1.0.2
### Patch Changes
- Updated dependencies [6eeb9d2]
- @nhost/hasura-auth-js@1.0.2
## 1.0.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/nhost-js",
"version": "1.0.1",
"version": "1.0.2",
"description": "Nhost JavaScript SDK",
"license": "MIT",
"keywords": [

View File

@@ -1,6 +1,14 @@
# @nhost/react-apollo
## 5.0.0
## 4.0.3
### Patch Changes
- Updated dependencies [113beed]
- @nhost/apollo@0.3.1
- @nhost/react@0.4.1
## 4.0.2
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/react-apollo",
"version": "5.0.0",
"version": "4.0.3",
"description": "Nhost React Apollo client",
"license": "MIT",
"keywords": [

View File

@@ -1,5 +1,11 @@
# @nhost/react
## 0.4.1
### Patch Changes
- @nhost/nhost-js@1.0.2
## 0.4.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/react",
"version": "0.4.0",
"version": "0.4.1",
"description": "Nhost React library",
"license": "MIT",
"keywords": [

433
pnpm-lock.yaml generated
View File

@@ -108,6 +108,7 @@ importers:
react-dom: ^17.0.2
react-merge-refs: ^1.1.0
react-syntax-highlighter: ^15.4.5
swagger-ui-react: ^4.5.2
tailwindcss: ^2.2.19
typescript: ^4.5.2
dependencies:
@@ -132,6 +133,7 @@ importers:
react-dom: 17.0.2_react@17.0.2
react-merge-refs: 1.1.0
react-syntax-highlighter: 15.4.5_react@17.0.2
swagger-ui-react: 4.8.0_react-dom@17.0.2+react@17.0.2
devDependencies:
'@types/react': 17.0.40
autoprefixer: 10.4.2_postcss@8.4.8
@@ -1778,6 +1780,10 @@ packages:
deprecated: Potential XSS vulnerability patched in v6.0.0.
dev: false
/@braintree/sanitize-url/6.0.0:
resolution: {integrity: sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w==}
dev: false
/@changesets/apply-release-plan/5.0.5:
resolution: {integrity: sha512-CxL9dkhzjHiVmXCyHgsLCQj7i/coFTMv/Yy0v6BC5cIWZkQml+lf7zvQqAcFXwY7b54HxRWZPku02XFB53Q0Uw==}
dependencies:
@@ -2719,6 +2725,13 @@ packages:
'@types/unist': 2.0.6
dev: false
/@types/hoist-non-react-statics/3.3.1:
resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==}
dependencies:
'@types/react': 17.0.40
hoist-non-react-statics: 3.3.2
dev: false
/@types/is-ci/3.0.0:
resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==}
dependencies:
@@ -2791,7 +2804,15 @@ packages:
/@types/prop-types/15.7.4:
resolution: {integrity: sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==}
dev: true
/@types/react-redux/7.1.23:
resolution: {integrity: sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==}
dependencies:
'@types/hoist-non-react-statics': 3.3.1
'@types/react': 17.0.40
hoist-non-react-statics: 3.3.2
redux: 4.1.2
dev: false
/@types/react/17.0.40:
resolution: {integrity: sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==}
@@ -2799,11 +2820,9 @@ packages:
'@types/prop-types': 15.7.4
'@types/scheduler': 0.16.2
csstype: 3.0.11
dev: true
/@types/scheduler/0.16.2:
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
dev: true
/@types/semver/6.2.3:
resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==}
@@ -3281,6 +3300,12 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/autolinker/3.15.0:
resolution: {integrity: sha512-N/5Dk5AZnqL9k6kkHdFIGLm/0/rRuSnJwqYYhLCJjU7ZtiaJwCBzNTvjzy1zzJADngv/wvtHYcrPHytPnASeFA==}
dependencies:
tslib: 2.3.1
dev: false
/autoprefixer/10.4.2_postcss@8.4.8:
resolution: {integrity: sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==}
engines: {node: ^10 || ^12 || >=14}
@@ -3521,6 +3546,10 @@ packages:
/balanced-match/1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
/base64-js/1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: false
/better-path-resolve/1.0.0:
resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
engines: {node: '>=4'}
@@ -3602,6 +3631,12 @@ packages:
node-int64: 0.4.0
dev: true
/btoa/1.2.1:
resolution: {integrity: sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==}
engines: {node: '>= 0.4.0'}
hasBin: true
dev: false
/buffer-from/1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
@@ -3884,6 +3919,7 @@ packages:
/commander/2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
requiresBuild: true
dev: false
/commander/7.2.0:
@@ -3921,6 +3957,11 @@ packages:
dependencies:
safe-buffer: 5.1.2
/cookie/0.4.2:
resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
engines: {node: '>= 0.6'}
dev: false
/cookiejar/2.1.3:
resolution: {integrity: sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==}
dev: false
@@ -3933,6 +3974,12 @@ packages:
keygrip: 1.1.0
dev: false
/copy-to-clipboard/3.3.1:
resolution: {integrity: sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==}
dependencies:
toggle-selection: 1.0.6
dev: false
/core-js-compat/3.21.1:
resolution: {integrity: sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==}
dependencies:
@@ -3959,6 +4006,14 @@ packages:
yaml: 1.10.2
dev: true
/cross-fetch/3.1.5:
resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
dependencies:
node-fetch: 2.6.7
transitivePeerDependencies:
- encoding
dev: false
/cross-spawn/5.1.0:
resolution: {integrity: sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=}
dependencies:
@@ -4009,6 +4064,10 @@ packages:
engines: {node: '>= 6'}
dev: true
/css.escape/1.5.1:
resolution: {integrity: sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=}
dev: false
/cssesc/3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@@ -4036,7 +4095,6 @@ packages:
/csstype/3.0.11:
resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==}
dev: true
/csv-generate/3.4.3:
resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==}
@@ -4617,13 +4675,17 @@ packages:
resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=}
dev: true
/deep-extend/0.6.0:
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
engines: {node: '>=4.0.0'}
dev: false
/deep-is/0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
/deepmerge/4.2.2:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
dev: true
/defaults/1.0.3:
resolution: {integrity: sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=}
@@ -4759,6 +4821,10 @@ packages:
domelementtype: 2.2.0
dev: true
/dompurify/2.3.3:
resolution: {integrity: sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==}
dev: false
/dompurify/2.3.5:
resolution: {integrity: sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==}
dev: false
@@ -4776,6 +4842,11 @@ packages:
engines: {node: '>=10'}
dev: false
/drange/1.1.1:
resolution: {integrity: sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==}
engines: {node: '>=4'}
dev: false
/electron-to-chromium/1.4.82:
resolution: {integrity: sha512-Ks+ANzLoIrFDUOJdjxYMH6CMKB8UQo5modAwvSZTxgF+vEs/U7G5IbWFUp6dS4klPkTDVdxbORuk8xAXXhMsWw==}
dev: true
@@ -5723,6 +5794,10 @@ packages:
merge2: 1.4.1
micromatch: 4.0.4
/fast-json-patch/3.1.0:
resolution: {integrity: sha512-IhpytlsVTRndz0hU5t0/MGzS/etxLlfrpG5V5M9mVbuj9TrJLWaMfsox9REM5rkuGX0T+5qjpe8XA1o0gZ42nA==}
dev: false
/fast-json-stable-stringify/2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
@@ -5819,6 +5894,10 @@ packages:
debug:
optional: true
/form-data-encoder/1.7.1:
resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==}
dev: false
/form-data/2.5.1:
resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==}
engines: {node: '>= 0.12'}
@@ -5851,6 +5930,14 @@ packages:
engines: {node: '>=0.4.x'}
dev: false
/formdata-node/4.3.2:
resolution: {integrity: sha512-k7lYJyzDOSL6h917favP8j1L0/wNyylzU+x+1w4p5haGVHNlP58dbpdJhiCUsDbWsa9HwEtLp89obQgXl2e0qg==}
engines: {node: '>= 12.20'}
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 4.0.0-beta.1
dev: false
/formidable/1.2.6:
resolution: {integrity: sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==}
deprecated: 'Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau'
@@ -6211,7 +6298,6 @@ packages:
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
dependencies:
react-is: 16.13.1
dev: true
/hosted-git-info/2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@@ -6347,6 +6433,10 @@ packages:
dependencies:
safer-buffer: 2.1.2
/ieee754/1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: false
/ignore/4.0.6:
resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
engines: {node: '>= 4'}
@@ -6365,6 +6455,11 @@ packages:
resolution: {integrity: sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==}
dev: false
/immutable/3.8.2:
resolution: {integrity: sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=}
engines: {node: '>=0.10.0'}
dev: false
/import-fresh/3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@@ -6425,6 +6520,12 @@ packages:
engines: {node: '>=12'}
dev: false
/invariant/2.2.4:
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
dependencies:
loose-envify: 1.4.0
dev: false
/ip-regex/4.3.0:
resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==}
engines: {node: '>=8'}
@@ -6519,6 +6620,13 @@ packages:
resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==}
dev: false
/is-dom/1.1.0:
resolution: {integrity: sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==}
dependencies:
is-object: 1.0.2
is-window: 1.0.2
dev: false
/is-extendable/0.1.1:
resolution: {integrity: sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=}
engines: {node: '>=0.10.0'}
@@ -6566,6 +6674,10 @@ packages:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
/is-object/1.0.2:
resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==}
dev: false
/is-plain-obj/1.1.0:
resolution: {integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=}
engines: {node: '>=0.10.0'}
@@ -6576,6 +6688,11 @@ packages:
engines: {node: '>=8'}
dev: false
/is-plain-object/5.0.0:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
dev: false
/is-potential-custom-element-name/1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
dev: true
@@ -6652,6 +6769,10 @@ packages:
resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==}
dev: false
/is-window/1.0.2:
resolution: {integrity: sha1-LIlspT25feRdPDMTOmXYyfVjSA0=}
dev: false
/is-windows/1.0.2:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
@@ -7207,6 +7328,10 @@ packages:
engines: {node: '>=12'}
dev: false
/js-file-download/0.4.12:
resolution: {integrity: sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==}
dev: false
/js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -7468,7 +7593,6 @@ packages:
/lodash.debounce/4.0.8:
resolution: {integrity: sha1-gteb/zCmfEAF/9XiUVMArZyk168=}
dev: true
/lodash.memoize/4.1.2:
resolution: {integrity: sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=}
@@ -7973,12 +8097,29 @@ packages:
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
dev: true
/node-domexception/1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
dev: false
/node-emoji/1.11.0:
resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==}
dependencies:
lodash: 4.17.21
dev: true
/node-fetch/2.6.7:
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
dependencies:
whatwg-url: 5.0.0
dev: false
/node-gyp/8.4.1:
resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==}
engines: {node: '>= 10.12.0'}
@@ -8580,6 +8721,10 @@ packages:
resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==}
dev: true
/punycode/1.3.2:
resolution: {integrity: sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=}
dev: false
/punycode/2.1.1:
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
engines: {node: '>=6'}
@@ -8615,6 +8760,16 @@ packages:
strict-uri-encode: 2.0.0
dev: false
/querystring/0.2.0:
resolution: {integrity: sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=}
engines: {node: '>=0.4.x'}
deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
dev: false
/querystringify/2.2.0:
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
dev: false
/queue-microtask/1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@@ -8628,6 +8783,20 @@ packages:
engines: {node: '>=10'}
dev: true
/randexp/0.5.3:
resolution: {integrity: sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==}
engines: {node: '>=4'}
dependencies:
drange: 1.1.1
ret: 0.2.2
dev: false
/randombytes/2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
dependencies:
safe-buffer: 5.2.1
dev: false
/re2/1.17.4:
resolution: {integrity: sha512-xyZ4h5PqE8I9tAxTh3G0UttcK5ufrcUxReFjGzfX61vtanNbS1XZHjnwRSyPcLgChI4KLxVgOT/ioZXnUAdoTA==}
requiresBuild: true
@@ -8639,6 +8808,26 @@ packages:
- supports-color
dev: true
/react-copy-to-clipboard/5.0.4_react@17.0.2:
resolution: {integrity: sha512-IeVAiNVKjSPeGax/Gmkqfa/+PuMTBhutEvFUaMQLwE2tS0EXrAdgOpWDX26bWTXF3HrioorR7lr08NqeYUWQCQ==}
peerDependencies:
react: ^15.3.0 || ^16.0.0 || ^17.0.0
dependencies:
copy-to-clipboard: 3.3.1
prop-types: 15.8.1
react: 17.0.2
dev: false
/react-debounce-input/3.2.4_react@17.0.2:
resolution: {integrity: sha512-fX70bNj0fLEYO2Zcvuh7eh9wOUQ29GIx6r8IxIJlc0i0mpUH++9ax0BhfAYfzndADli3RAMROrZQ014J01owrg==}
peerDependencies:
react: ^15.3.0 || ^16.0.0 || ^17.0.0
dependencies:
lodash.debounce: 4.0.8
prop-types: 15.8.1
react: 17.0.2
dev: false
/react-dom/17.0.2_react@17.0.2:
resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==}
peerDependencies:
@@ -8649,17 +8838,70 @@ packages:
react: 17.0.2
scheduler: 0.20.2
/react-immutable-proptypes/2.2.0_immutable@3.8.2:
resolution: {integrity: sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==}
peerDependencies:
immutable: '>=3.6.2'
dependencies:
immutable: 3.8.2
invariant: 2.2.4
dev: false
/react-immutable-pure-component/2.2.2_bd1a0e68a5e0e4857c26400f3b5f7e9d:
resolution: {integrity: sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==}
peerDependencies:
immutable: '>= 2 || >= 4.0.0-rc'
react: '>= 16.6'
react-dom: '>= 16.6'
dependencies:
immutable: 3.8.2
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
dev: false
/react-inspector/5.1.1_react@17.0.2:
resolution: {integrity: sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==}
peerDependencies:
react: ^16.8.4 || ^17.0.0
dependencies:
'@babel/runtime': 7.17.2
is-dom: 1.1.0
prop-types: 15.8.1
react: 17.0.2
dev: false
/react-is/16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
/react-is/17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
dev: true
/react-merge-refs/1.1.0:
resolution: {integrity: sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==}
dev: false
/react-redux/7.2.6_react-dom@17.0.2+react@17.0.2:
resolution: {integrity: sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==}
peerDependencies:
react: ^16.8.3 || ^17
react-dom: '*'
react-native: '*'
peerDependenciesMeta:
react-dom:
optional: true
react-native:
optional: true
dependencies:
'@babel/runtime': 7.17.2
'@types/react-redux': 7.1.23
hoist-non-react-statics: 3.3.2
loose-envify: 1.4.0
prop-types: 15.8.1
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
react-is: 17.0.2
dev: false
/react-refresh/0.11.0:
resolution: {integrity: sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==}
engines: {node: '>=0.10.0'}
@@ -8786,6 +9028,20 @@ packages:
postcss-value-parser: 3.3.1
dev: true
/redux-immutable/4.0.0_immutable@3.8.2:
resolution: {integrity: sha1-Ohoy32Y2ZGK2NpHw4dw15HK7yfM=}
peerDependencies:
immutable: ^3.8.1 || ^4.0.0-rc.1
dependencies:
immutable: 3.8.2
dev: false
/redux/4.1.2:
resolution: {integrity: sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==}
dependencies:
'@babel/runtime': 7.17.2
dev: false
/refractor/3.6.0:
resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==}
dependencies:
@@ -8894,6 +9150,15 @@ packages:
mdast-squeeze-paragraphs: 4.0.0
dev: false
/remarkable/2.0.1:
resolution: {integrity: sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==}
engines: {node: '>= 6.0.0'}
hasBin: true
dependencies:
argparse: 1.0.10
autolinker: 3.15.0
dev: false
/repeat-string/1.6.1:
resolution: {integrity: sha1-jcrkcOHIirwtYA//Sndihtp15jc=}
engines: {node: '>=0.10'}
@@ -8908,6 +9173,14 @@ packages:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
dev: true
/requires-port/1.0.0:
resolution: {integrity: sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=}
dev: false
/reselect/4.1.5:
resolution: {integrity: sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==}
dev: false
/resolve-cwd/3.0.0:
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
engines: {node: '>=8'}
@@ -8943,6 +9216,11 @@ packages:
is-core-module: 2.8.1
path-parse: 1.0.7
/ret/0.2.2:
resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==}
engines: {node: '>=4'}
dev: false
/retry/0.12.0:
resolution: {integrity: sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=}
engines: {node: '>= 4'}
@@ -8998,7 +9276,6 @@ packages:
/safe-buffer/5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: true
/safer-buffer/2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
@@ -9044,10 +9321,25 @@ packages:
dependencies:
lru-cache: 6.0.0
/serialize-error/8.1.0:
resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==}
engines: {node: '>=10'}
dependencies:
type-fest: 0.20.2
dev: false
/set-blocking/2.0.0:
resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=}
dev: true
/sha.js/2.4.11:
resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==}
hasBin: true
dependencies:
inherits: 2.0.4
safe-buffer: 5.2.1
dev: false
/shebang-command/1.2.0:
resolution: {integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=}
engines: {node: '>=0.10.0'}
@@ -9435,6 +9727,73 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/swagger-client/3.18.4:
resolution: {integrity: sha512-Wj26oEctONq/u0uM+eSj18675YM5e2vFnx7Kr4neLeXEHKUsfceVQ/OdtrBXdrT3VbtdBbZfMTfl1JOBpix2MA==}
dependencies:
'@babel/runtime-corejs3': 7.17.2
btoa: 1.2.1
cookie: 0.4.2
cross-fetch: 3.1.5
deepmerge: 4.2.2
fast-json-patch: 3.1.0
form-data-encoder: 1.7.1
formdata-node: 4.3.2
is-plain-object: 5.0.0
js-yaml: 4.1.0
lodash: 4.17.21
qs: 6.10.3
traverse: 0.6.6
url: 0.11.0
transitivePeerDependencies:
- encoding
dev: false
/swagger-ui-react/4.8.0_react-dom@17.0.2+react@17.0.2:
resolution: {integrity: sha512-zumBDcwifJaM4/7DdMh76fHvlzT5t4f8/Fx8hSlZ25VhJycv+F+s23KzfhoXsgAy4qE8TeEDz2fDiODx/1XAWA==}
peerDependencies:
react: '>=17.0.0'
react-dom: '>=17.0.0'
dependencies:
'@babel/runtime-corejs3': 7.17.2
'@braintree/sanitize-url': 6.0.0
base64-js: 1.5.1
classnames: 2.3.1
css.escape: 1.5.1
deep-extend: 0.6.0
dompurify: 2.3.3
ieee754: 1.2.1
immutable: 3.8.2
js-file-download: 0.4.12
js-yaml: 4.1.0
lodash: 4.17.21
prop-types: 15.8.1
randexp: 0.5.3
randombytes: 2.1.0
react: 17.0.2
react-copy-to-clipboard: 5.0.4_react@17.0.2
react-debounce-input: 3.2.4_react@17.0.2
react-dom: 17.0.2_react@17.0.2
react-immutable-proptypes: 2.2.0_immutable@3.8.2
react-immutable-pure-component: 2.2.2_bd1a0e68a5e0e4857c26400f3b5f7e9d
react-inspector: 5.1.1_react@17.0.2
react-redux: 7.2.6_react-dom@17.0.2+react@17.0.2
react-syntax-highlighter: 15.4.5_react@17.0.2
redux: 4.1.2
redux-immutable: 4.0.0_immutable@3.8.2
remarkable: 2.0.1
reselect: 4.1.5
serialize-error: 8.1.0
sha.js: 2.4.11
swagger-client: 3.18.4
url-parse: 1.5.10
xml: 1.0.1
xml-but-prettier: 1.0.1
zenscroll: 4.0.2
transitivePeerDependencies:
- encoding
- react-native
dev: false
/symbol-observable/1.2.0:
resolution: {integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==}
engines: {node: '>=0.10.0'}
@@ -9569,6 +9928,10 @@ packages:
dependencies:
is-number: 7.0.0
/toggle-selection/1.0.6:
resolution: {integrity: sha1-bkWxJj8gF/oKzH2J14sVuL932jI=}
dev: false
/tough-cookie/4.0.0:
resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==}
engines: {node: '>=6'}
@@ -9578,6 +9941,10 @@ packages:
universalify: 0.1.2
dev: true
/tr46/0.0.3:
resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=}
dev: false
/tr46/2.1.0:
resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==}
engines: {node: '>=8'}
@@ -9592,6 +9959,10 @@ packages:
punycode: 2.1.1
dev: true
/traverse/0.6.6:
resolution: {integrity: sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=}
dev: false
/trim-newlines/3.0.1:
resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==}
engines: {node: '>=8'}
@@ -10022,6 +10393,13 @@ packages:
dependencies:
punycode: 2.1.1
/url-parse/1.5.10:
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
dependencies:
querystringify: 2.2.0
requires-port: 1.0.0
dev: false
/url-regex-safe/3.0.0_re2@1.17.4:
resolution: {integrity: sha512-+2U40NrcmtWFVjuxXVt9bGRw6c7/MgkGKN9xIfPrT/2RX0LTkkae6CCEDp93xqUN0UKm/rr821QnHd2dHQmN3A==}
engines: {node: '>= 10.12.0'}
@@ -10036,6 +10414,13 @@ packages:
tlds: 1.230.0
dev: true
/url/0.11.0:
resolution: {integrity: sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=}
dependencies:
punycode: 1.3.2
querystring: 0.2.0
dev: false
/use-isomorphic-layout-effect/1.1.1_react@17.0.2:
resolution: {integrity: sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==}
peerDependencies:
@@ -10203,6 +10588,15 @@ packages:
resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==}
dev: false
/web-streams-polyfill/4.0.0-beta.1:
resolution: {integrity: sha512-3ux37gEX670UUphBF9AMCq8XM6iQ8Ac6A+DSRRjDoRBm1ufCkaCDdNVbaqq60PsEkdNlLKrGtv/YBP4EJXqNtQ==}
engines: {node: '>= 12'}
dev: false
/webidl-conversions/3.0.1:
resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=}
dev: false
/webidl-conversions/5.0.0:
resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==}
engines: {node: '>=8'}
@@ -10248,6 +10642,13 @@ packages:
webidl-conversions: 7.0.0
dev: true
/whatwg-url/5.0.0:
resolution: {integrity: sha1-lmRU6HZUYuN2RNNib2dCzotwll0=}
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
dev: false
/whatwg-url/8.7.0:
resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==}
engines: {node: '>=10'}
@@ -10357,6 +10758,12 @@ packages:
optional: true
dev: true
/xml-but-prettier/1.0.1:
resolution: {integrity: sha1-9aMyZ+1CzNTjVcYlV6XjmwH7QPM=}
dependencies:
repeat-string: 1.6.1
dev: false
/xml-name-validator/3.0.0:
resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==}
dev: true
@@ -10366,6 +10773,10 @@ packages:
engines: {node: '>=12'}
dev: true
/xml/1.0.1:
resolution: {integrity: sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=}
dev: false
/xmlchars/2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
dev: true
@@ -10455,6 +10866,10 @@ packages:
resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==}
dev: true
/zenscroll/4.0.2:
resolution: {integrity: sha1-6NV3TRwHOKR7z6hynzcS4t7d6yU=}
dev: false
/zwitch/1.0.5:
resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}
dev: false