diff --git a/.dockerignore b/.dockerignore index 2fb3c74..1e10d15 100644 --- a/.dockerignore +++ b/.dockerignore @@ -9,3 +9,4 @@ Dockerfile cloudbuild.yaml cloudbuild-pr.yaml ./kubernetes +.env* diff --git a/README.md b/README.md index b7e18bd..a356bc6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This application is deployed at https://go.armand1m.dev -This is my personal version of Go Links built with [Next.js](https://nextjs.org/) and [GraphQL](http://graphql.org/). +This is my personal version of Go Links powered by [Next.js](https://nextjs.org/) , [GraphQL](http://graphql.org/) (through PostGraphile) and Auth0.
@@ -23,12 +23,13 @@ This is my personal version of Go Links built with [Next.js](https://nextjs.org/ - [x] Delete Links - [ ] Edit Links - [x] Redirect Links -- [x] Link Usage Count -- [ ] Auth -- [ ] Security +- [x] Auth + - [x] Powered by Auth0 +- [x] Security + - [x] Row Level Security using Auth0 Roles and Permissions - [ ] Link Description - [ ] Link Suggestion on 404 -- [ ] Link Usage Metrics +- [x] Link Usage Metrics - [ ] Link Ownership ## Deploying @@ -78,7 +79,7 @@ kubectl apply -f ./kubernetes/istio/destination-rule.yaml armand1m/golinks is a Next.js app using GraphQL. -The database must be a [PostgreSQL 12.x](http://postgresql.org/) database as the GraphQL API is generated using [Postgraphile](https://www.graphile.org/postgraphile/). +The database must be a [Postgres 12.x](http://postgresql.org/) database as the GraphQL API is generated using [Postgraphile](https://www.graphile.org/postgraphile/) and leverages features like Row Level Security only available from Postgres 9.6+. PostGraphile is then used as a NPM module and served through Next.js routes itself, so you don't have to worry about CORS, and the api is initialized together with the Next.js application. @@ -91,7 +92,7 @@ GraphQL Type definitions are generated on application startup during development Start the database: ```sh -docker-compose up db -d +docker-compose up -d db ``` Prepare the project and run in development mode: diff --git a/components/LinkTable/index.tsx b/components/LinkTable/index.tsx index 40be328..baefc69 100644 --- a/components/LinkTable/index.tsx +++ b/components/LinkTable/index.tsx @@ -1,17 +1,26 @@ -import { Table, Text, Link as FannyLink, Button } from 'bumbag'; +import { Box, Table, Text, Link as FannyLink, Button } from 'bumbag'; import { GetAllLinksQuery } from '../../lib/queries/getAllLinks.graphql'; interface Props { data: GetAllLinksQuery; + isDeleteEnabled: boolean; onDelete: (linkId: string) => void | Promise; } -export const LinkTable: React.FC = ({ data, onDelete }) => { +export const LinkTable: React.FC = ({ + data, + isDeleteEnabled, + onDelete, +}) => { const links = data?.links; if (links?.nodes.length === 0) { - return There are no links yet. Create one!; + return ( + + There are no golinks available. + + ); } return ( @@ -21,7 +30,9 @@ export const LinkTable: React.FC = ({ data, onDelete }) => { Alias Destination Usage - Actions + {isDeleteEnabled && ( + Actions + )} @@ -44,15 +55,17 @@ export const LinkTable: React.FC = ({ data, onDelete }) => { - {link.usage} - - - + {link.linkUsageMetrics.totalCount} + {isDeleteEnabled && ( + + + + )} ); })} diff --git a/database/1-links-table.sql b/database/1-links-table.sql deleted file mode 100644 index da5a514..0000000 --- a/database/1-links-table.sql +++ /dev/null @@ -1,19 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - --- Create links table -DROP TABLE IF EXISTS links CASCADE; -CREATE TABLE public.links ( - id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), - alias VARCHAR ( 50 ) UNIQUE NOT NULL, - url VARCHAR ( 255 ) NOT NULL, - usage INT NOT NULL DEFAULT 0, - created_at TIMESTAMP NOT NULL DEFAULT NOW() -); - --- Add comments to links table and fields -comment on table public.links is 'A link alias posted by an user.'; -comment on column public.links.id is 'The id for a link alias.'; -comment on column public.links.alias is 'The alias for an url. It must be unique.'; -comment on column public.links.url is 'The link alias url.'; -comment on column public.links.usage is 'The amount of times someone accessed through this link alias.'; -comment on column public.links.created_at is 'The time this link alias was created.'; diff --git a/database/1-tables.sql b/database/1-tables.sql new file mode 100644 index 0000000..6d05941 --- /dev/null +++ b/database/1-tables.sql @@ -0,0 +1,29 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +DROP TABLE IF EXISTS public.links CASCADE; +CREATE TABLE public.links ( + id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + alias VARCHAR ( 50 ) UNIQUE NOT NULL, + url VARCHAR ( 255 ) NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT NOW() +); + +comment on table public.links is 'A link alias posted by an user.'; +comment on column public.links.id is 'The id for a link alias.'; +comment on column public.links.alias is 'The alias for an url. It must be unique.'; +comment on column public.links.url is 'The link alias url.'; +comment on column public.links.created_at is 'The time this link alias was created.'; + +DROP TABLE IF EXISTS public.link_usage_metrics CASCADE; +CREATE TABLE public.link_usage_metrics ( + id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + link_id uuid NOT NULL REFERENCES public.links ON DELETE CASCADE, + accessed_at TIMESTAMP NOT NULL DEFAULT NOW() +); + +CREATE INDEX ON public.link_usage_metrics (link_id); + +comment on table public.link_usage_metrics is 'A link usage metric posted by the application when a link is accessed.'; +comment on column public.link_usage_metrics.id is 'The id for this metric record.'; +comment on column public.link_usage_metrics.link_id is 'The id of the link being accessed.'; +comment on column public.link_usage_metrics.accessed_at is 'The time this link was accessed.'; diff --git a/database/2-jwt-token-type.sql b/database/2-jwt-token-type.sql deleted file mode 100644 index a0762b3..0000000 --- a/database/2-jwt-token-type.sql +++ /dev/null @@ -1,7 +0,0 @@ -create type public.jwt_token as ( - role text, - exp integer, - person_id integer, - is_admin boolean, - username varchar -); diff --git a/database/2-roles.sql b/database/2-roles.sql new file mode 100644 index 0000000..3e6cbda --- /dev/null +++ b/database/2-roles.sql @@ -0,0 +1,5 @@ +CREATE ROLE postgraphile; + +-- Not used yet +CREATE ROLE viewer; +CREATE ROLE editor; \ No newline at end of file diff --git a/database/3-functions.sql b/database/3-functions.sql new file mode 100644 index 0000000..71d65bd --- /dev/null +++ b/database/3-functions.sql @@ -0,0 +1,13 @@ +create function get_current_permissions() returns json as $$ + select nullif(current_setting('jwt.claims.permissions', true), '[]')::json; +$$ language sql stable SECURITY DEFINER; + +create function has_permission(permission text) returns boolean as $$ + with claims as ( + select + get_current_permissions() as permissions + ) + select count(claims.permissions) > 0 + from claims + where claims.permissions::jsonb ? permission; +$$ language sql stable SECURITY DEFINER; \ No newline at end of file diff --git a/database/3-users-table.sql b/database/3-users-table.sql deleted file mode 100644 index 948ef30..0000000 --- a/database/3-users-table.sql +++ /dev/null @@ -1,13 +0,0 @@ --- Create app_private schema -CREATE SCHEMA IF NOT EXISTS app_private; - --- Create users table -DROP TABLE IF EXISTS app_private.users CASCADE; -CREATE TABLE app_private.users ( - id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), - email TEXT UNIQUE NOT NULL, - username TEXT UNIQUE NOT NULL, - password_hash TEXT NOT NULL, - is_admin BOOLEAN NOT NULL DEFAULT FALSE, - created_at TIMESTAMP NOT NULL DEFAULT NOW() -); \ No newline at end of file diff --git a/database/4-authenticate-function.sql b/database/4-authenticate-function.sql deleted file mode 100644 index f08e0de..0000000 --- a/database/4-authenticate-function.sql +++ /dev/null @@ -1,24 +0,0 @@ -create function public.authenticate( - email text, - password text -) returns public.jwt_token as $$ -declare - user app_private.users; -begin - select u.* into user - from app_private.users as u - where u.email = authenticate.email; - - if user.password_hash = crypt(authenticate.password, user.password_hash) then - return ( - 'person_role', - extract(epoch from now() + interval '7 days'), - user.id, - user.is_admin, - user.username - )::public.jwt_token; - else - return null; - end if; -end; -$$ language plpgsql strict security definer; \ No newline at end of file diff --git a/database/4-policies.sql b/database/4-policies.sql new file mode 100644 index 0000000..6e46292 --- /dev/null +++ b/database/4-policies.sql @@ -0,0 +1,54 @@ +CREATE POLICY read_links + ON public.links + FOR SELECT + USING ( + has_permission('read:golinks') + ); + +CREATE POLICY update_links + ON public.links + FOR UPDATE + USING ( + has_permission('update:golinks') + ) + WITH CHECK ( + has_permission('update:golinks') + ); + +CREATE POLICY create_links + ON public.links + FOR INSERT + WITH CHECK ( + has_permission('create:golinks') + ); + +CREATE POLICY delete_links + ON public.links + FOR DELETE + USING ( + has_permission('delete:golinks') + ); + +ALTER TABLE public.links ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.links FORCE ROW LEVEL SECURITY; + +GRANT ALL ON public.links TO postgraphile; + +CREATE POLICY read_link_metric + ON public.link_usage_metrics + FOR SELECT + USING ( + has_permission('read:golinks') + ); + +CREATE POLICY create_link_metric + ON public.link_usage_metrics + FOR INSERT + WITH CHECK ( + has_permission('read:golinks') + ); + +ALTER TABLE public.link_usage_metrics ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.link_usage_metrics FORCE ROW LEVEL SECURITY; + +GRANT ALL ON public.link_usage_metrics TO postgraphile; diff --git a/docker-compose.yml b/docker-compose.yml index 553a7f3..d9ee713 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,10 +9,8 @@ services: - 3000:3000/tcp networks: - overlay - environment: - DATABASE_CONNECTION_STRING: postgres://dev:dev@db:5432/golinks - DATABASE_SCHEMA: public - NODE_ENV: production + env_file: + - .env.local depends_on: - db @@ -26,10 +24,10 @@ services: - overlay volumes: - db-data:/var/lib/postgresql/data - - ./database/1-links-table.sql:/docker-entrypoint-initdb.d/1-links-table.sql - - ./database/2-jwt-token-type.sql:/docker-entrypoint-initdb.d/2-jwt-token-type.sql - - ./database/3-users-table.sql:/docker-entrypoint-initdb.d/3-users-table.sql - - ./database/4-authenticate-function.sql:/docker-entrypoint-initdb.d/4-authenticate-function.sql + - ./database/1-tables.sql:/docker-entrypoint-initdb.d/1-tables.sql + - ./database/2-roles.sql:/docker-entrypoint-initdb.d/2-roles.sql + - ./database/3-functions.sql:/docker-entrypoint-initdb.d/3-functions.sql + - ./database/4-policies.sql:/docker-entrypoint-initdb.d/4-policies.sql ports: - 5432:5432/tcp diff --git a/lib/auth.ts b/lib/auth.ts new file mode 100644 index 0000000..4096d87 --- /dev/null +++ b/lib/auth.ts @@ -0,0 +1,127 @@ +import { promisify } from 'util'; +import jsonwebtoken from 'jsonwebtoken'; +import jwksRsa from 'jwks-rsa'; +import { initAuth0 } from '@auth0/nextjs-auth0'; +import { ISession } from '@auth0/nextjs-auth0/dist/session/session'; + +const ANONYMOUS_PERMISSIONS = ['read:golinks']; +const ANONYMOUS_ROLES = ['viewer']; + +const DOMAIN = String(process.env.AUTH0_DOMAIN); +const AUDIENCE = String(process.env.AUTH0_AUDIENCE); +const CLIENT_ID = String(process.env.AUTH0_CLIENT_ID); +const CLIENT_SECRET = String(process.env.AUTH0_CLIENT_SECRET); +const COOKIE_DOMAIN = String(process.env.AUTH0_COOKIE_DOMAIN); +const COOKIE_SECRET = String(process.env.AUTH0_COOKIE_SECRET); +const REDIRECT_URL = String(process.env.AUTH0_REDIRECT_URL); +const POST_LOGOUT_REDIRECT_URL = String( + process.env.AUTH0_POST_LOGOUT_REDIRECT_URL +); + +const jwksSecretClient = jwksRsa({ + cache: true, + rateLimit: true, + jwksRequestsPerMinute: 5, + jwksUri: `https://${DOMAIN}/.well-known/jwks.json`, +}); + +interface JwtHeader { + kid: string; +} + +interface DecodedAccessToken { + header: JwtHeader; +} + +interface DecodedJwtToken { + iss: string; + sub: string; + aud: string[]; + iat: number; + exp: number; + azp: string; + scope: string; + permissions: string[]; + /** + * This is set by a Custom Auth0 Rule + * + * For some reason, the key needs to be a URI + * otherwise Auth0 filters it out :shrug: + **/ + 'https://user/roles': string[]; +} + +export const getPermissionsFromSession = async ( + session?: ISession | null +) => { + if (!session || !session.accessToken) { + return { + permissions: ANONYMOUS_PERMISSIONS, + roles: ANONYMOUS_ROLES, + }; + } + + const decodedAccessToken = jsonwebtoken.decode( + session.accessToken, + { complete: true } + ) as DecodedAccessToken | undefined; + + if (!decodedAccessToken) { + throw new Error('Failed to decode token.'); + } + + const signingKey = await promisify(jwksSecretClient.getSigningKey)( + decodedAccessToken.header.kid + ); + + const token = jsonwebtoken.verify( + session.accessToken, + signingKey.getPublicKey(), + { + audience: AUDIENCE, + issuer: new URL(`https://${DOMAIN}`).href, + algorithms: ['RS256'], + } + ); + + if (typeof token === 'string') { + throw new Error( + 'Decoded token is a string. An object with permissions is expected.' + ); + } + + const jwtToken = token as DecodedJwtToken; + + return { + permissions: jwtToken.permissions || ANONYMOUS_PERMISSIONS, + roles: jwtToken['https://user/roles'] || ANONYMOUS_ROLES, + }; +}; + +export const auth0 = initAuth0({ + domain: DOMAIN, + clientId: CLIENT_ID, + audience: AUDIENCE, + clientSecret: CLIENT_SECRET, + scope: 'openid email profile', + redirectUri: REDIRECT_URL, + postLogoutRedirectUri: POST_LOGOUT_REDIRECT_URL, + session: { + cookieSecret: COOKIE_SECRET, + cookieLifetime: 60 * 60 * 8, + cookieDomain: + process.env.NODE_ENV === 'development' + ? 'localhost' + : COOKIE_DOMAIN, + cookieSameSite: 'lax', + storeIdToken: true, + storeAccessToken: true, + storeRefreshToken: true, + }, + oidcClient: { + httpTimeout: 2500, + clockTolerance: 10000, + }, +}); + +export type { IClaims } from '@auth0/nextjs-auth0/dist/session/session'; diff --git a/lib/graphql.ts b/lib/graphql.ts index 03b2ad1..2baf6fe 100644 --- a/lib/graphql.ts +++ b/lib/graphql.ts @@ -1,4 +1,6 @@ import { postgraphile, PostGraphileOptions } from 'postgraphile'; +import { auth0, getPermissionsFromSession } from './auth'; +import { NextApiRequest } from 'next'; const commonProperties: Partial = { subscriptions: true, @@ -10,8 +12,22 @@ const commonProperties: Partial = { graphqlRoute: '/api/graphql', graphiqlRoute: '/api/graphiql', legacyRelations: 'omit', - // jwtSecret: process.env.JWT_SECRET || "dev-secret", - // jwtPgTypeIdentifier: "public.jwt_token", + pgSettings: async (req) => { + const settings = {} as Record; + + const session = await auth0.getSession(req as NextApiRequest); + const claims = await getPermissionsFromSession(session); + + settings['role'] = 'postgraphile'; + settings['jwt.claims.roles'] = JSON.stringify(claims.roles); + settings['jwt.claims.permissions'] = JSON.stringify( + claims.permissions + ); + + console.log('pgSettings: ', settings); + + return settings; + }, }; const devProperties: PostGraphileOptions = { diff --git a/lib/mutations/createLink.graphql b/lib/mutations/createLink.graphql index 95431e8..9fd98d4 100644 --- a/lib/mutations/createLink.graphql +++ b/lib/mutations/createLink.graphql @@ -4,7 +4,6 @@ mutation CreateLink($alias: String!, $url: String!) { id, url, alias, - usage, createdAt, } } diff --git a/lib/mutations/createLinkUsageMetric.graphql b/lib/mutations/createLinkUsageMetric.graphql new file mode 100644 index 0000000..52a6690 --- /dev/null +++ b/lib/mutations/createLinkUsageMetric.graphql @@ -0,0 +1,7 @@ +mutation CreateLinkUsageMetric($linkId: UUID!) { + createLinkUsageMetric(input: {linkUsageMetric: {linkId: $linkId}}) { + linkUsageMetric { + id + } + } +} \ No newline at end of file diff --git a/lib/mutations/updateLinkUsage.graphql b/lib/mutations/updateLinkUsage.graphql deleted file mode 100644 index 52683b7..0000000 --- a/lib/mutations/updateLinkUsage.graphql +++ /dev/null @@ -1,10 +0,0 @@ -mutation UpdateLinkUsage($alias: String!, $usage: Int!) { - __typename - updateLinkByAlias(input: {patch: {usage: $usage}, alias: $alias}) { - link { - id - alias - usage - } - } -} diff --git a/lib/queries/getAllLinks.graphql b/lib/queries/getAllLinks.graphql index dd9ed49..ad481df 100644 --- a/lib/queries/getAllLinks.graphql +++ b/lib/queries/getAllLinks.graphql @@ -4,7 +4,9 @@ query getAllLinks { id url alias - usage + linkUsageMetrics { + totalCount + } } } } diff --git a/lib/queries/getLinkByAlias.graphql b/lib/queries/getLinkByAlias.graphql index 346adbd..be0ef22 100644 --- a/lib/queries/getLinkByAlias.graphql +++ b/lib/queries/getLinkByAlias.graphql @@ -1,7 +1,7 @@ query GetLinkByAlias($alias: String!) { linkByAlias(alias: $alias) { + id url alias - usage } } diff --git a/lib/type-defs.graphqls b/lib/type-defs.graphqls index 61065d7..fb582a2 100644 --- a/lib/type-defs.graphqls +++ b/lib/type-defs.graphqls @@ -33,6 +33,44 @@ type CreateLinkPayload { ): LinksEdge } +"""All input for the create `LinkUsageMetric` mutation.""" +input CreateLinkUsageMetricInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + + """The `LinkUsageMetric` to be created by this mutation.""" + linkUsageMetric: LinkUsageMetricInput! +} + +"""The output of our create `LinkUsageMetric` mutation.""" +type CreateLinkUsageMetricPayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + + """The `LinkUsageMetric` that was created by this mutation.""" + linkUsageMetric: LinkUsageMetric + + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query + + """Reads a single `Link` that is related to this `LinkUsageMetric`.""" + link: Link + + """An edge for our `LinkUsageMetric`. May be used by Relay 1.""" + linkUsageMetricEdge( + """The method to use when ordering `LinkUsageMetric`.""" + orderBy: [LinkUsageMetricsOrderBy!] = [PRIMARY_KEY_ASC] + ): LinkUsageMetricsEdge +} + """A location in a connection that can be used for resuming pagination.""" scalar Cursor @@ -104,6 +142,64 @@ type DeleteLinkPayload { ): LinksEdge } +"""All input for the `deleteLinkUsageMetricByNodeId` mutation.""" +input DeleteLinkUsageMetricByNodeIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + + """ + The globally unique `ID` which will identify a single `LinkUsageMetric` to be deleted. + """ + nodeId: ID! +} + +"""All input for the `deleteLinkUsageMetric` mutation.""" +input DeleteLinkUsageMetricInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + + """The id for this metric record.""" + id: UUID! +} + +"""The output of our delete `LinkUsageMetric` mutation.""" +type DeleteLinkUsageMetricPayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + + """The `LinkUsageMetric` that was deleted by this mutation.""" + linkUsageMetric: LinkUsageMetric + deletedLinkUsageMetricNodeId: ID + + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query + + """Reads a single `Link` that is related to this `LinkUsageMetric`.""" + link: Link + + """An edge for our `LinkUsageMetric`. May be used by Relay 1.""" + linkUsageMetricEdge( + """The method to use when ordering `LinkUsageMetric`.""" + orderBy: [LinkUsageMetricsOrderBy!] = [PRIMARY_KEY_ASC] + ): LinkUsageMetricsEdge +} + +""" +The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSON + """A link alias posted by an user.""" type Link implements Node { """ @@ -120,11 +216,37 @@ type Link implements Node { """The link alias url.""" url: String! - """The amount of times someone accessed through this link alias.""" - usage: Int! - """The time this link alias was created.""" createdAt: Datetime! + + """Reads and enables pagination through a set of `LinkUsageMetric`.""" + linkUsageMetrics( + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """The method to use when ordering `LinkUsageMetric`.""" + orderBy: [LinkUsageMetricsOrderBy!] = [PRIMARY_KEY_ASC] + + """ + A condition to be used in determining which values should be returned by the collection. + """ + condition: LinkUsageMetricCondition + ): LinkUsageMetricsConnection! } """ @@ -149,9 +271,6 @@ input LinkInput { """The link alias url.""" url: String! - """The amount of times someone accessed through this link alias.""" - usage: Int - """The time this link alias was created.""" createdAt: Datetime } @@ -167,9 +286,6 @@ input LinkPatch { """The link alias url.""" url: String - """The amount of times someone accessed through this link alias.""" - usage: Int - """The time this link alias was created.""" createdAt: Datetime } @@ -211,10 +327,115 @@ enum LinksOrderBy { PRIMARY_KEY_DESC } +"""A link usage metric posted by the application when a link is accessed.""" +type LinkUsageMetric implements Node { + """ + A globally unique identifier. Can be used in various places throughout the system to identify this single value. + """ + nodeId: ID! + + """The id for this metric record.""" + id: UUID! + + """The id of the link being accessed.""" + linkId: UUID! + + """The time this link was accessed.""" + accessedAt: Datetime! + + """Reads a single `Link` that is related to this `LinkUsageMetric`.""" + link: Link +} + +""" +A condition to be used against `LinkUsageMetric` object types. All fields are +tested for equality and combined with a logical ‘and.’ +""" +input LinkUsageMetricCondition { + """Checks for equality with the object’s `id` field.""" + id: UUID + + """Checks for equality with the object’s `linkId` field.""" + linkId: UUID +} + +"""An input for mutations affecting `LinkUsageMetric`""" +input LinkUsageMetricInput { + """The id for this metric record.""" + id: UUID + + """The id of the link being accessed.""" + linkId: UUID! + + """The time this link was accessed.""" + accessedAt: Datetime +} + +""" +Represents an update to a `LinkUsageMetric`. Fields that are set will be updated. +""" +input LinkUsageMetricPatch { + """The id for this metric record.""" + id: UUID + + """The id of the link being accessed.""" + linkId: UUID + + """The time this link was accessed.""" + accessedAt: Datetime +} + +"""A connection to a list of `LinkUsageMetric` values.""" +type LinkUsageMetricsConnection { + """A list of `LinkUsageMetric` objects.""" + nodes: [LinkUsageMetric!]! + + """ + A list of edges which contains the `LinkUsageMetric` and cursor to aid in pagination. + """ + edges: [LinkUsageMetricsEdge!]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `LinkUsageMetric` you could get from the connection. + """ + totalCount: Int! +} + +"""A `LinkUsageMetric` edge in the connection.""" +type LinkUsageMetricsEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `LinkUsageMetric` at the end of the edge.""" + node: LinkUsageMetric! +} + +"""Methods to use when ordering `LinkUsageMetric`.""" +enum LinkUsageMetricsOrderBy { + NATURAL + ID_ASC + ID_DESC + LINK_ID_ASC + LINK_ID_DESC + PRIMARY_KEY_ASC + PRIMARY_KEY_DESC +} + """ The root mutation type which contains root level fields which mutate data. """ type Mutation { + """Creates a single `LinkUsageMetric`.""" + createLinkUsageMetric( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: CreateLinkUsageMetricInput! + ): CreateLinkUsageMetricPayload + """Creates a single `Link`.""" createLink( """ @@ -223,6 +444,24 @@ type Mutation { input: CreateLinkInput! ): CreateLinkPayload + """ + Updates a single `LinkUsageMetric` using its globally unique id and a patch. + """ + updateLinkUsageMetricByNodeId( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateLinkUsageMetricByNodeIdInput! + ): UpdateLinkUsageMetricPayload + + """Updates a single `LinkUsageMetric` using a unique key and a patch.""" + updateLinkUsageMetric( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateLinkUsageMetricInput! + ): UpdateLinkUsageMetricPayload + """Updates a single `Link` using its globally unique id and a patch.""" updateLinkByNodeId( """ @@ -247,6 +486,22 @@ type Mutation { input: UpdateLinkByAliasInput! ): UpdateLinkPayload + """Deletes a single `LinkUsageMetric` using its globally unique id.""" + deleteLinkUsageMetricByNodeId( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteLinkUsageMetricByNodeIdInput! + ): DeleteLinkUsageMetricPayload + + """Deletes a single `LinkUsageMetric` using a unique key.""" + deleteLinkUsageMetric( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteLinkUsageMetricInput! + ): DeleteLinkUsageMetricPayload + """Deletes a single `Link` using its globally unique id.""" deleteLinkByNodeId( """ @@ -314,6 +569,35 @@ type Query implements Node { nodeId: ID! ): Node + """Reads and enables pagination through a set of `LinkUsageMetric`.""" + linkUsageMetrics( + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """The method to use when ordering `LinkUsageMetric`.""" + orderBy: [LinkUsageMetricsOrderBy!] = [PRIMARY_KEY_ASC] + + """ + A condition to be used in determining which values should be returned by the collection. + """ + condition: LinkUsageMetricCondition + ): LinkUsageMetricsConnection + """Reads and enables pagination through a set of `Link`.""" links( """Only read the first `n` values of the set.""" @@ -342,8 +626,19 @@ type Query implements Node { """ condition: LinkCondition ): LinksConnection + linkUsageMetric(id: UUID!): LinkUsageMetric link(id: UUID!): Link linkByAlias(alias: String!): Link + getCurrentPermissions: JSON + hasPermission(permission: String): Boolean + + """Reads a single `LinkUsageMetric` using its globally unique `ID`.""" + linkUsageMetricByNodeId( + """ + The globally unique `ID` to be used in selecting a single `LinkUsageMetric`. + """ + nodeId: ID! + ): LinkUsageMetric """Reads a single `Link` using its globally unique `ID`.""" linkByNodeId( @@ -428,6 +723,68 @@ type UpdateLinkPayload { ): LinksEdge } +"""All input for the `updateLinkUsageMetricByNodeId` mutation.""" +input UpdateLinkUsageMetricByNodeIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + + """ + The globally unique `ID` which will identify a single `LinkUsageMetric` to be updated. + """ + nodeId: ID! + + """ + An object where the defined keys will be set on the `LinkUsageMetric` being updated. + """ + patch: LinkUsageMetricPatch! +} + +"""All input for the `updateLinkUsageMetric` mutation.""" +input UpdateLinkUsageMetricInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + + """ + An object where the defined keys will be set on the `LinkUsageMetric` being updated. + """ + patch: LinkUsageMetricPatch! + + """The id for this metric record.""" + id: UUID! +} + +"""The output of our update `LinkUsageMetric` mutation.""" +type UpdateLinkUsageMetricPayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + + """The `LinkUsageMetric` that was updated by this mutation.""" + linkUsageMetric: LinkUsageMetric + + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query + + """Reads a single `Link` that is related to this `LinkUsageMetric`.""" + link: Link + + """An edge for our `LinkUsageMetric`. May be used by Relay 1.""" + linkUsageMetricEdge( + """The method to use when ordering `LinkUsageMetric`.""" + orderBy: [LinkUsageMetricsOrderBy!] = [PRIMARY_KEY_ASC] + ): LinkUsageMetricsEdge +} + """ A universally unique identifier as defined by [RFC 4122](https://tools.ietf.org/html/rfc4122). """ diff --git a/package.json b/package.json index 0429366..b7e27aa 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "@apollo/react-common": "3.1.4", "@apollo/react-components": "^3.1.5", "@apollo/react-hooks": "3.1.5", + "@auth0/auth0-react": "^1.0.0", + "@auth0/nextjs-auth0": "^0.15.0", "@emotion/core": "^10.0.28", "@graphile-contrib/pg-simplify-inflector": "^6.0.0", "apollo-cache": "^1.3.5", @@ -27,16 +29,22 @@ "bumbag": "^1.0.0-rc.11", "bumbag-server": "^1.0.0-rc.11", "emotion": "^10.0.27", + "express": "^4.17.1", + "express-jwt": "^6.0.0", "formik": "^2.1.5", "graphile-build": "^4.7.0", "graphile-build-pg": "^4.7.0", "graphql": "^14.6.0", "graphql-tag": "^2.10.3", "graphql-tools": "^6.0.15", + "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^1.8.1", + "jwt-decode": "^2.2.0", "next": "latest", "postgraphile": "^4.7.0", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-kawaii": "^0.16.0", "yup": "^0.29.1" }, "devDependencies": { @@ -46,6 +54,7 @@ "@graphql-codegen/typescript-operations": "^1.13.3", "@graphql-codegen/typescript-react-apollo": "^1.13.3", "@graphql-codegen/typescript-resolvers": "^1.15.1", + "@types/jwt-decode": "^2.2.1", "@types/react": "^16.9.34", "@types/react-dom": "^16.9.7", "@types/yup": "^0.29.3", diff --git a/pages/[alias].tsx b/pages/[alias].tsx index 1ee0be0..dcbbea0 100644 --- a/pages/[alias].tsx +++ b/pages/[alias].tsx @@ -4,7 +4,7 @@ import { useRouter } from 'next/router'; import { PageContent, Heading, Text, Callout } from 'bumbag'; import { useGetLinkByAliasQuery } from '../lib/queries/getLinkByAlias.graphql'; -import { useUpdateLinkUsageMutation } from '../lib/mutations/updateLinkUsage.graphql'; +import { useCreateLinkUsageMetricMutation } from '../lib/mutations/createLinkUsageMetric.graphql'; const RouterQuerySchema = Yup.object().shape({ alias: Yup.string() @@ -18,7 +18,7 @@ interface RedirectProps { } const Redirect: React.FC = ({ alias }) => { - const [updateLinkUsage] = useUpdateLinkUsageMutation(); + const [createLinkMetric] = useCreateLinkUsageMetricMutation(); const { data, loading } = useGetLinkByAliasQuery({ variables: { alias, @@ -27,10 +27,9 @@ const Redirect: React.FC = ({ alias }) => { const updateAndRedirect = useCallback(async () => { if (data?.linkByAlias) { - await updateLinkUsage({ + await createLinkMetric({ variables: { - alias: data.linkByAlias.alias, - usage: data.linkByAlias.usage + 1, + linkId: data.linkByAlias.id, }, }); diff --git a/pages/api/callback.ts b/pages/api/callback.ts new file mode 100644 index 0000000..2ece322 --- /dev/null +++ b/pages/api/callback.ts @@ -0,0 +1,14 @@ +import { auth0 } from '../../lib/auth'; +import { NextApiRequest, NextApiResponse } from 'next'; + +export default async function callback( + req: NextApiRequest, + res: NextApiResponse +) { + try { + await auth0.handleCallback(req, res, { redirectTo: '/' }); + } catch (error) { + console.error(error); + res.status(error.status || 400).end(error.message); + } +} diff --git a/pages/api/login.ts b/pages/api/login.ts new file mode 100644 index 0000000..6bc050a --- /dev/null +++ b/pages/api/login.ts @@ -0,0 +1,14 @@ +import { auth0 } from '../../lib/auth'; +import { NextApiRequest, NextApiResponse } from 'next'; + +export default async function login( + req: NextApiRequest, + res: NextApiResponse +) { + try { + await auth0.handleLogin(req, res); + } catch (error) { + console.error(error); + res.status(error.status || 400).end(error.message); + } +} diff --git a/pages/api/logout.ts b/pages/api/logout.ts new file mode 100644 index 0000000..3093708 --- /dev/null +++ b/pages/api/logout.ts @@ -0,0 +1,14 @@ +import { auth0 } from '../../lib/auth'; +import { NextApiRequest, NextApiResponse } from 'next'; + +export default async function logout( + req: NextApiRequest, + res: NextApiResponse +) { + try { + await auth0.handleLogout(req, res); + } catch (error) { + console.error(error); + res.status(error.status || 400).end(error.message); + } +} diff --git a/pages/api/me.ts b/pages/api/me.ts new file mode 100644 index 0000000..350d526 --- /dev/null +++ b/pages/api/me.ts @@ -0,0 +1,14 @@ +import { auth0 } from '../../lib/auth'; +import { NextApiRequest, NextApiResponse } from 'next'; + +export default async function me( + req: NextApiRequest, + res: NextApiResponse +) { + try { + await auth0.handleProfile(req, res); + } catch (error) { + console.error(error); + res.status(error.status || 500).end(error.message); + } +} diff --git a/pages/index.tsx b/pages/index.tsx index 6f401d8..f0ce412 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,62 +1,94 @@ +import { + GetServerSideProps, + NextApiRequest, + NextApiResponse, +} from 'next'; import { Modal, Dialog, - Box, + Flex, PageContent, Card, Stack, Heading, Button, + Spinner, } from 'bumbag'; +import { IClaims } from '../lib/auth'; +import { LinkTable } from '../components/LinkTable'; +import { CreateLinkForm } from '../components/CreateLinkForm'; import { useGetAllLinksQuery } from '../lib/queries/getAllLinks.graphql'; import { useCreateLinkMutation } from '../lib/mutations/createLink.graphql'; import { useDeleteLinkMutation } from '../lib/mutations/deleteLink.graphql'; -import { CreateLinkForm } from '../components/CreateLinkForm'; -import { LinkTable } from '../components/LinkTable'; -const Index = () => { +interface Props { + user: IClaims; + grants: { + permissions: string[]; + }; +} + +const Index: React.FC = ({ grants }) => { const [createLink] = useCreateLinkMutation(); const [deleteLink] = useDeleteLinkMutation(); - const { data, refetch } = useGetAllLinksQuery(); + const { loading, data, refetch } = useGetAllLinksQuery(); const createLinkModal = Modal.useState(); + const canCreate = grants.permissions.includes('create:golinks'); + const canDelete = grants.permissions.includes('delete:golinks'); + return ( - + go.armand1m.dev - + + + + - <> - - Create - - - { - await createLink({ - variables: values, - }); - - await refetch(); - - createLinkModal.hide(); - - form.resetForm(); - }} - /> - - + {canCreate && ( + <> + + Create + + + { + await createLink({ + variables: values, + }); + + await refetch(); + + createLinkModal.hide(); + + form.resetForm(); + }} + /> + + + )} + + {loading && ( + + + + )} {data !== undefined && data !== null && ( { await deleteLink({ variables: { @@ -76,3 +108,34 @@ const Index = () => { }; export default Index; + +export const getServerSideProps: GetServerSideProps = async ( + context +) => { + const { auth0, getPermissionsFromSession } = require('../lib/auth'); + const request = context?.req as NextApiRequest; + const session = await auth0.getSession(request); + const grants = await getPermissionsFromSession(session); + const user = session?.user; + + if (user) { + return { + props: { + user, + grants, + }, + }; + } + + const response = context?.res as NextApiResponse; + + response.writeHead(302, { + Location: '/api/login', + }); + + response.end(); + + return { + props: {}, + }; +}; diff --git a/yarn.lock b/yarn.lock index 72405ec..15dd6a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -99,6 +99,36 @@ resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.1.tgz#1403ac5de10d8ca689fc1f65844c27179ae1d44f" integrity sha512-UQ9BequOTIavs0pTHLMwQwKQF8tTV1oezY/H2O9chA+JNPFZSua55xpU5dPSjAU9/jLJ1VwU+HJuTVN8u7S6Fg== +"@auth0/auth0-react@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@auth0/auth0-react/-/auth0-react-1.0.0.tgz#3eeced9557d54d4092032ecc071cd74052d09da7" + integrity sha512-AaGftJFXYsJNEHZq/PNNr5HVSOQCVjstBF2pD3gAwOrgjKO7fYoeNgKKQOcTLm/ge5vAkEBGgSBzWBj2SgZ38w== + dependencies: + "@auth0/auth0-spa-js" "^1.9.0" + +"@auth0/auth0-spa-js@^1.9.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@auth0/auth0-spa-js/-/auth0-spa-js-1.11.0.tgz#800a59ddeaa11ad8a94a699c58f9971842ea065f" + integrity sha512-PHYykO4IoEGeTT2SVzvZiJNK5QgznLJweJfVcb0C8X+rZYooBN5Qrdj0AfECzgK9h90kfU4u3s9h83VTSh6t3A== + dependencies: + abortcontroller-polyfill "^1.4.0" + browser-tabs-lock "^1.2.8" + core-js "^3.6.4" + es-cookie "^1.3.2" + fast-text-encoding "^1.0.1" + promise-polyfill "^8.1.3" + unfetch "^4.1.0" + +"@auth0/nextjs-auth0@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@auth0/nextjs-auth0/-/nextjs-auth0-0.15.0.tgz#68353d2cdfcbce1da5ae3e48eaaace448553f9cf" + integrity sha512-UN1Hsbpet6xMTTFl8kvyylyN8C8sFfR4M97IBY5mPdYq9ydhBckY/1L8LlG/Ie5P7fyoRQgf97XWxIzV8JH6MQ== + dependencies: + "@hapi/iron" "^5.1.4" + base64url "^3.0.1" + cookie "^0.4.1" + openid-client "^3.15.0" + "@babel/code-frame@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -1644,6 +1674,48 @@ aggregate-error "3.0.1" tslib "~2.0.0" +"@hapi/b64@4.x.x": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@hapi/b64/-/b64-4.2.1.tgz#bf8418d7907c5e73463f2e3b5c6fca7e9f2a1357" + integrity sha512-zqHpQuH5CBMw6hADzKfU/IGNrxq1Q+/wTYV+OiZRQN9F3tMyk+9BUMeBvFRMamduuqL8iSp62QAnJ+7ATiYLWA== + dependencies: + "@hapi/hoek" "8.x.x" + +"@hapi/boom@7.x.x": + version "7.4.11" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-7.4.11.tgz#37af8417eb9416aef3367aa60fa04a1a9f1fc262" + integrity sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A== + dependencies: + "@hapi/hoek" "8.x.x" + +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== + +"@hapi/cryptiles@4.x.x": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@hapi/cryptiles/-/cryptiles-4.2.1.tgz#ff0f18d79074659838caedbb911851313ad1ffbc" + integrity sha512-XoqgKsHK0l/VpqPs+tr6j6vE+VQ3+2bkF2stvttmc7xAOf1oSAwHcJ0tlp/6MxMysktt1IEY0Csy3khKaP9/uQ== + dependencies: + "@hapi/boom" "7.x.x" + +"@hapi/hoek@8.x.x": + version "8.5.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" + integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== + +"@hapi/iron@^5.1.4": + version "5.1.4" + resolved "https://registry.yarnpkg.com/@hapi/iron/-/iron-5.1.4.tgz#7406f36847f798f52b92d1d97f855e27973832b7" + integrity sha512-+ElC+OCiwWLjlJBmm8ZEWjlfzTMQTdgPnU/TsoU5QsktspIWmWi9IU4kU83nH+X/SSya8TP8h8P11Wr5L7dkQQ== + dependencies: + "@hapi/b64" "4.x.x" + "@hapi/boom" "7.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/cryptiles" "4.x.x" + "@hapi/hoek" "8.x.x" + "@next/react-dev-overlay@9.4.4": version "9.4.4" resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.4.4.tgz#4ae03ac839ff022b3ce5c695bd24b179d4ef459d" @@ -1686,6 +1758,11 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@panva/asn1.js@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6" + integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw== + "@popperjs/core@^2.4.2": version "2.4.4" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.4.4.tgz#11d5db19bd178936ec89cd84519c4de439574398" @@ -1698,6 +1775,18 @@ dependencies: any-observable "^0.3.0" +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + "@types/accepts@*": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" @@ -1745,6 +1834,14 @@ "@types/keygrip" "*" "@types/node" "*" +"@types/express-jwt@0.0.42": + version "0.0.42" + resolved "https://registry.yarnpkg.com/@types/express-jwt/-/express-jwt-0.0.42.tgz#4f04e1fadf9d18725950dc041808a4a4adf7f5ae" + integrity sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag== + dependencies: + "@types/express" "*" + "@types/express-unless" "*" + "@types/express-serve-static-core@*": version "4.17.9" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz#2d7b34dcfd25ec663c25c85d76608f8b249667f1" @@ -1754,6 +1851,13 @@ "@types/qs" "*" "@types/range-parser" "*" +"@types/express-unless@*": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@types/express-unless/-/express-unless-0.5.1.tgz#4f440b905e42bbf53382b8207bc337dc5ff9fd1f" + integrity sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw== + dependencies: + "@types/express" "*" + "@types/express@*": version "4.17.7" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.7.tgz#42045be6475636d9801369cd4418ef65cdb0dd59" @@ -1764,6 +1868,15 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/got@^9.6.9": + version "9.6.11" + resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.11.tgz#482b402cc5ee459481aeeadb08142ebb1a9afb26" + integrity sha512-dr3IiDNg5TDesGyuwTrN77E1Cd7DCdmCFtEfSGqr83jMMtcwhf/SGPbN2goY4JUWQfvxwY56+e5tjfi+oXeSdA== + dependencies: + "@types/node" "*" + "@types/tough-cookie" "*" + form-data "^2.5.0" + "@types/http-assert@*": version "1.5.1" resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" @@ -1786,6 +1899,11 @@ dependencies: "@types/node" "*" +"@types/jwt-decode@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@types/jwt-decode/-/jwt-decode-2.2.1.tgz#afdf5c527fcfccbd4009b5fd02d1e18241f2d2f2" + integrity sha512-aWw2YTtAdT7CskFyxEX2K21/zSDStuf/ikI3yBqmwpwJF0pS+/IX5DWv+1UFffZIbruP6cnT9/LAJV1gFwAT1A== + "@types/keygrip@*": version "1.0.2" resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" @@ -1882,6 +2000,11 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" +"@types/tough-cookie@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" + integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== + "@types/websocket@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.1.tgz#039272c196c2c0e4868a0d8a1a27bbb86e9e9138" @@ -2083,6 +2206,19 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +abortcontroller-polyfill@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.5.0.tgz#2c562f530869abbcf88d949a2b60d1d402e87a7c" + integrity sha512-O6Xk757Jb4o0LMzMOMdWvxpHWrQzruYBaUruFaIOfAQRnWFxfdXYobw12jrVHGtoXk6WiiyYzc0QWN9aL62HQA== + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + acorn@^6.4.1: version "6.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" @@ -2355,6 +2491,11 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -2435,6 +2576,11 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -2465,6 +2611,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + babel-code-frame@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -2577,6 +2730,11 @@ base64-js@^1.0.2: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== +base64url@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== + base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -2634,7 +2792,7 @@ bn.js@^5.1.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== -body-parser@^1.15.2: +body-parser@1.19.0, body-parser@^1.15.2: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== @@ -2696,6 +2854,13 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-tabs-lock@^1.2.8: + version "1.2.11" + resolved "https://registry.yarnpkg.com/browser-tabs-lock/-/browser-tabs-lock-1.2.11.tgz#59d72c6653b827685b54fca1c0e6eb4aee08ef52" + integrity sha512-R0xXMzQ8CU0v52zSFn3EDGIfsjteMFJ6oIhhZK6+Vhz5NYzSxCP2epLD9PN7e2HprQl2QTReFptwp6c9tdOF0g== + dependencies: + lodash ">=4.17.19" + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -2919,6 +3084,19 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -3149,6 +3327,13 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -3294,6 +3479,13 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -3311,6 +3503,21 @@ convert-source-map@^0.3.3: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +cookie@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -3341,6 +3548,11 @@ core-js@^2.4.1: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== +core-js@^3.6.4: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -3681,7 +3893,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@3.1.0: +debug@3.1.0, debug@=3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== @@ -3712,6 +3924,13 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -3727,6 +3946,11 @@ deepmerge@^2.1.1: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -3779,6 +4003,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + detect-indent@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" @@ -3874,6 +4103,11 @@ duplexer2@^0.1.2: dependencies: readable-stream "^2.0.2" +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + duplexify@^3.4.2, duplexify@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" @@ -4045,6 +4279,11 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" +es-cookie@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/es-cookie/-/es-cookie-1.3.2.tgz#80e831597f72a25721701bdcb21d990319acd831" + integrity sha512-UTlYYhXGLOy05P/vKVT2Ui7WtC7NiRzGtJyAKKn32g5Gvcjn7KAClLPWlipCtxIus934dFg9o9jXiBL0nP+t9Q== + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -4137,6 +4376,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + eventemitter3@^3.1.0: version "3.1.2" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" @@ -4183,6 +4427,57 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +express-jwt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/express-jwt/-/express-jwt-6.0.0.tgz#20886c730983ffb1c706a4383235df86eff349b8" + integrity sha512-C26y9myRjx7CyhZ+BAT3p+gQyRCoDZ7qo8plCvLDaRT6je6ALIAQknT6XLVQGFKwIy/Ux7lvM2MNap5dt0T7gA== + dependencies: + async "^1.5.0" + express-unless "^0.3.0" + jsonwebtoken "^8.1.0" + lodash.set "^4.0.0" + +express-unless@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/express-unless/-/express-unless-0.3.1.tgz#2557c146e75beb903e2d247f9b5ba01452696e20" + integrity sha1-JVfBRudb65A+LSR/m1ugFFJpbiA= + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + ext@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" @@ -4275,6 +4570,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-text-encoding@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" + integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== + fastq@^1.6.0: version "1.8.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" @@ -4357,7 +4657,7 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@^1.0.6: +finalhandler@^1.0.6, finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== @@ -4428,6 +4728,13 @@ fn-name@~3.0.0: resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-3.0.0.tgz#0596707f635929634d791f452309ab41558e3c5c" integrity sha512-eNMNr5exLoavuAMhIUVsOKF79SWd/zG104ef6sxBTSw+cZc6BXdQXDvYcGvp0VbxVVSp1XDUNoz7mg1xMtSznA== +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -4461,6 +4768,15 @@ form-data@3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -4484,6 +4800,11 @@ formik@^2.1.5: tiny-warning "^1.0.2" tslib "^1.10.0" +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -4491,6 +4812,11 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -4573,6 +4899,13 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-stream@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" @@ -4580,6 +4913,13 @@ get-stream@^5.0.0: dependencies: pump "^3.0.0" +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -4641,6 +4981,23 @@ globby@11.0.1, globby@^11.0.0: merge2 "^1.3.0" slash "^3.0.0" +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" @@ -4927,6 +5284,11 @@ htmlparser2@4.1.0: domutils "^2.0.0" entities "^2.0.0" +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -4949,6 +5311,17 @@ http-errors@^1.5.1: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-proxy-agent@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" @@ -5122,6 +5495,11 @@ invariant@^2.2.2, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" @@ -5454,6 +5832,13 @@ jest-worker@24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" +jose@^1.27.1: + version "1.28.0" + resolved "https://registry.yarnpkg.com/jose/-/jose-1.28.0.tgz#0803f8c71f43cd293a9d931c555c30531f5ca5dc" + integrity sha512-JmfDRzt/HSj8ipd9TsDtEHoLUnLYavG+7e8F6s1mx2jfVSfXOTaFQsJUydbjJpTnTDHP1+yKL9Ke7ktS/a0Eiw== + dependencies: + "@panva/asn1.js" "^1.0.0" + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -5487,6 +5872,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -5597,6 +5987,19 @@ jwa@^1.4.1: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" +jwks-rsa@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/jwks-rsa/-/jwks-rsa-1.8.1.tgz#375c62a50c4ca805ad5bd682c12c8a695de13ddf" + integrity sha512-CcE8ypsATHwGmzELwzeFjLzPBXTXTrMmDYbn92LTQwYsZdOedp+ZIuYTofUdrWreu8CKRuXmhk17+6/li2sR6g== + dependencies: + "@types/express-jwt" "0.0.42" + axios "^0.19.2" + debug "^4.1.0" + jsonwebtoken "^8.5.1" + limiter "^1.1.5" + lru-memoizer "^2.1.2" + ms "^2.1.2" + jws@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" @@ -5605,6 +6008,18 @@ jws@^3.2.2: jwa "^1.4.1" safe-buffer "^5.0.1" +jwt-decode@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-2.2.0.tgz#7d86bd56679f58ce6a84704a657dd392bba81a79" + integrity sha1-fYa9VmefWM5qhHBKZX3TkruoGnk= + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -5641,6 +6056,11 @@ levenary@^1.1.1: dependencies: leven "^3.1.0" +limiter@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2" + integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA== + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -5785,6 +6205,11 @@ lodash-es@^4.17.11, lodash-es@^4.17.14: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -5825,6 +6250,11 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= +lodash.set@^4.0.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" + integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -5835,7 +6265,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.19, "lodash@>=4 <5", lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@~4.17.15: +lodash@4.17.19, "lodash@>=4 <5", lodash@>=4.17.19, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@~4.17.15: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== @@ -5887,6 +6317,16 @@ lower-case@2.0.1, lower-case@^2.0.1: dependencies: tslib "^1.10.0" +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lru-cache@5.1.1, lru-cache@^5.0.0, lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5902,6 +6342,29 @@ lru-cache@5.1.1, lru-cache@^5.0.0, lru-cache@^5.1.1: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-cache@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + integrity sha1-HRdnnAac2l0ECZGgnbwsDbN35V4= + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +lru-memoizer@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/lru-memoizer/-/lru-memoizer-2.1.2.tgz#5c6b43659c78ad0e9e65bf81a9e5ef1ee109a2dd" + integrity sha512-N5L5xlnVcbIinNn/TJ17vHBZwBMt9t7aJDz2n97moWubjNl6VO9Ao2XuAGBBddkYdjrwR9HfzXbT6NfMZXAZ/A== + dependencies: + lodash.clonedeep "^4.5.0" + lru-cache "~4.0.0" + make-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -5917,6 +6380,11 @@ make-dir@^3.0.2: dependencies: semver "^6.0.0" +make-error@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + map-cache@^0.2.0, map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -5969,6 +6437,11 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -5979,6 +6452,11 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + microevent.ts@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" @@ -6031,6 +6509,11 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.44.0" +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -6041,6 +6524,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + mini-css-extract-plugin@0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz#81d41ec4fe58c713a96ad7c723cdb2d0bd4d70e1" @@ -6161,7 +6649,12 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1, ms@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -6208,6 +6701,11 @@ native-url@0.3.1: dependencies: querystring "^0.2.0" +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + neo-async@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" @@ -6377,6 +6875,11 @@ normalize-url@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + npm-run-path@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -6420,6 +6923,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-hash@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" + integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + object-inspect@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" @@ -6482,6 +6990,11 @@ object.values@^1.1.0: function-bind "^1.1.1" has "^1.0.3" +oidc-token-hash@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.0.tgz#acdfb1f4310f58e64d5d74a4e8671a426986e888" + integrity sha512-8Yr4CZSv+Tn8ZkN3iN2i2w2G92mUKClp4z7EGUfdsERiYSbj7P4i/NHm72ft+aUdsiFx9UdIPSTwbyzQ6C4URg== + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -6510,6 +7023,21 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +openid-client@^3.15.0: + version "3.15.9" + resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-3.15.9.tgz#eba7d7546159db69567dda90b8ade89667bffe76" + integrity sha512-CNKMxM1oj4+JIWi/TQ4kGQuG2l5S/5yvSZ1wzz1fg+/fhD/MWRmqRB8GHW0EV+fbbSncDx9Lhoq04mu7S0/fbw== + dependencies: + "@types/got" "^9.6.9" + base64url "^3.0.1" + got "^9.6.0" + jose "^1.27.1" + lru-cache "^6.0.0" + make-error "^1.3.6" + object-hash "^2.0.1" + oidc-token-hash "^5.0.0" + p-any "^3.0.0" + optimism@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.10.3.tgz#163268fdc741dea2fb50f300bedda80356445fd7" @@ -6534,6 +7062,24 @@ os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +p-any@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-any/-/p-any-3.0.0.tgz#79847aeed70b5d3a10ea625296c0c3d2e90a87b9" + integrity sha512-5rqbqfsRWNb0sukt0awwgJMlaep+8jV45S15SKKB34z4UuzjcofIfnriCBhWjZP2jbVtjt9yRl7buB6RlKsu9w== + dependencies: + p-cancelable "^2.0.0" + p-some "^5.0.0" + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-cancelable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" + integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== + p-limit@3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" @@ -6595,6 +7141,14 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" +p-some@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-some/-/p-some-5.0.0.tgz#8b730c74b4fe5169d7264a240ad010b6ebc686a4" + integrity sha512-Js5XZxo6vHjB9NOYAzWDYAIyyiPvva0DWESAIWIK7uhSpGsyg5FwUPxipU/SOQx5x9EqhOh545d1jo6cVkitig== + dependencies: + aggregate-error "^3.0.0" + p-cancelable "^2.0.0" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -6743,6 +7297,11 @@ path-root@^0.1.1: dependencies: path-root-regex "^0.1.0" +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -7293,6 +7852,11 @@ prepend-http@^1.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + prettier@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" @@ -7342,6 +7906,11 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-polyfill@^8.1.3: + version "8.1.3" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116" + integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g== + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -7372,12 +7941,20 @@ property-expr@^2.0.2: resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.2.tgz#fff2a43919135553a3bc2fdd94bdb841965b2330" integrity sha512-bc/5ggaYZxNkFKj374aLbEDqVADdYaLcFo8XBkishUWbaAdjlphaBFns9TvRA2pUseVL/wMFmui9X3IdNDU37g== +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -pseudomap@^1.0.2: +pseudomap@^1.0.1, pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= @@ -7487,6 +8064,11 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + raw-body@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" @@ -7525,6 +8107,13 @@ react-is@16.13.1, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-kawaii@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/react-kawaii/-/react-kawaii-0.16.0.tgz#6543f82a911269b9e7a470bf5316fe3976404636" + integrity sha512-ZD8QkK8pQbLdV391aJ4CAwuFq2rxVeRhYIsyj9d9q68aobFjcs3UwmGOFgSLWoI642ecXJD/4wBscYXMCcCWJw== + dependencies: + prop-types "^15.6.2" + "react-loads-next@npm:react-loads@9.2.3": version "9.2.3" resolved "https://registry.yarnpkg.com/react-loads/-/react-loads-9.2.3.tgz#141dd23cc94a7658c37cc65b798c03e93054a9ff" @@ -7827,6 +8416,13 @@ resolve@^1.12.0, resolve@^1.3.2, resolve@^1.8.1: dependencies: path-parse "^1.0.6" +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -7922,16 +8518,16 @@ rxjs@^6.3.3, rxjs@^6.6.0: dependencies: tslib "^1.9.0" +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -8032,6 +8628,25 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + serialize-javascript@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" @@ -8039,6 +8654,16 @@ serialize-javascript@^3.1.0: dependencies: randombytes "^2.1.0" +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -8673,6 +9298,11 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" @@ -8782,7 +9412,7 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== -type-is@~1.6.17: +type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -8827,6 +9457,11 @@ unc-path-regex@^0.1.2: resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= +unfetch@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.1.0.tgz#6ec2dd0de887e58a4dee83a050ded80ffc4137db" + integrity sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg== + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -8943,6 +9578,13 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -8999,6 +9641,11 @@ util@^0.11.0: dependencies: inherits "2.0.3" +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -9009,6 +9656,11 @@ valid-url@1.0.9: resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + vendors@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" @@ -9239,7 +9891,7 @@ yaeti@^0.0.6: resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= -yallist@^2.1.2: +yallist@^2.0.0, yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=