Migrate X-API-Token to Authorization header (#122)

This commit is contained in:
Kamil Kisiela 2022-07-01 11:43:27 +02:00 committed by GitHub
parent 80358619b1
commit 25d6b0191b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 260 additions and 3381 deletions

View file

@ -0,0 +1,6 @@
---
'@graphql-hive/cli': minor
'@graphql-hive/client': minor
---
Migrate to Authorization header (previously X-API-Token)

View file

@ -75,6 +75,12 @@ export function deployProxy({
customRewrite: '/graphql',
service: graphql.service,
},
{
name: 'graphql-api',
path: '/graphql',
customRewrite: '/graphql',
service: graphql.service,
},
{
name: 'usage',
path: '/usage',

View file

@ -186,7 +186,7 @@ export function updateMemberAccess(input: OrganizationMemberAccessInput, authTok
});
}
export function publishSchema(input: SchemaPublishInput, token: string) {
export function publishSchema(input: SchemaPublishInput, token: string, authHeader?: 'x-api-token' | 'authorization') {
return execute({
document: gql(/* GraphQL */ `
mutation schemaPublish($input: SchemaPublishInput!) {
@ -229,6 +229,7 @@ export function publishSchema(input: SchemaPublishInput, token: string) {
variables: {
input,
},
legacyAuthorizationMode: authHeader === 'x-api-token',
});
}

View file

@ -11,6 +11,7 @@ export async function execute<R, V>(params: {
variables?: V;
authToken?: string;
token?: string;
legacyAuthorizationMode?: boolean;
}) {
const res = await axios.post<ExecutionResult<R>>(
`http://${registryAddress}/graphql`,
@ -28,9 +29,13 @@ export async function execute<R, V>(params: {
}
: {}),
...(params.token
? {
'X-API-Token': params.token,
}
? params.legacyAuthorizationMode
? {
'X-API-Token': params.token,
}
: {
Authorization: `Bearer ${params.token}`,
}
: {}),
},
responseType: 'json',

View file

@ -21,11 +21,21 @@ export interface CollectedOperation {
};
}
export async function collect(params: { operations: CollectedOperation[]; token: string }) {
export async function collect(params: {
operations: CollectedOperation[];
token: string;
authorizationHeader?: 'x-api-token' | 'authorization';
}) {
const res = await axios.post(`http://${usageAddress}`, params.operations, {
headers: {
'Content-Type': 'application/json',
'X-API-Token': params.token,
...(params.authorizationHeader === 'x-api-token'
? {
'X-API-Token': params.token,
}
: {
Authorization: `Bearer ${params.token}`,
}),
},
});

View file

@ -0,0 +1,122 @@
import { TargetAccessScope, ProjectType } from '@app/gql/graphql';
import formatISO from 'date-fns/formatISO';
import subHours from 'date-fns/subHours';
import { authenticate } from '../../testkit/auth';
import {
publishSchema,
createOrganization,
createProject,
createToken,
readOperationsStats,
waitFor,
} from '../../testkit/flow';
import { collect } from '../../testkit/usage';
test('X-API-Token header should work when calling GraphQL API and collecting usage', async () => {
const { access_token: owner_access_token } = await authenticate('main');
const orgResult = await createOrganization(
{
name: 'foo',
},
owner_access_token
);
const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization;
const projectResult = await createProject(
{
organization: org.cleanId,
type: ProjectType.Single,
name: 'foo',
},
owner_access_token
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{
name: 'test',
organization: org.cleanId,
project: project.cleanId,
target: target.cleanId,
organizationScopes: [],
projectScopes: [],
targetScopes: [TargetAccessScope.RegistryRead, TargetAccessScope.RegistryWrite],
},
owner_access_token
);
expect(tokenResult.body.errors).not.toBeDefined();
const token = tokenResult.body.data!.createToken.ok!.secret;
const result = await publishSchema(
{
author: 'Kamil',
commit: 'abc123',
sdl: `type Query { ping: String }`,
},
token,
'x-api-token'
);
expect(result.body.errors).not.toBeDefined();
expect(result.body.data!.schemaPublish.__typename).toBe('SchemaPublishSuccess');
const collectResult = await collect({
operations: [
{
operation: 'query ping { ping }',
operationName: 'ping',
fields: ['Query', 'Query.ping'],
execution: {
ok: true,
duration: 200000000,
errorsTotal: 0,
},
},
],
token,
authorizationHeader: 'x-api-token',
});
expect(collectResult.status).toEqual(200);
await waitFor(5_000);
const from = formatISO(subHours(Date.now(), 6));
const to = formatISO(Date.now());
const operationStatsResult = await readOperationsStats(
{
organization: org.cleanId,
project: project.cleanId,
target: target.cleanId,
period: {
from,
to,
},
},
token
);
expect(operationStatsResult.body.errors).not.toBeDefined();
const operationsStats = operationStatsResult.body.data!.operationsStats;
expect(operationsStats.operations.nodes).toHaveLength(1);
const op = operationsStats.operations.nodes[0];
expect(op.count).toEqual(1);
expect(op.document).toMatch('ping');
expect(op.operationHash).toBeDefined();
expect(op.duration.p75).toEqual(200);
expect(op.duration.p90).toEqual(200);
expect(op.duration.p95).toEqual(200);
expect(op.duration.p99).toEqual(200);
expect(op.kind).toEqual('query');
expect(op.name).toMatch('ping');
expect(op.percentage).toBeGreaterThan(99);
});

View file

@ -18,7 +18,7 @@
"pre-commit": "lint-staged",
"prerelease": "yarn build:libraries",
"release": "changeset publish",
"upload-sourcemaps": "./scripts/upload-sourcmaps.sh",
"upload-sourcemaps": "./scripts/upload-sourcemaps.sh",
"test": "jest",
"lint": "eslint --cache --ignore-path .gitignore \"packages/**/*.{ts,tsx}\"",
"prettier": "prettier --cache --write --list-different .",

View file

@ -1,7 +1,7 @@
import { Command, Config as OclifConfig, Errors } from '@oclif/core';
import colors from 'colors';
import symbols from 'log-symbols';
import { GraphQLClient } from 'graphql-request';
import { GraphQLClient, ClientError } from 'graphql-request';
import { Config } from './helpers/config';
import { getSdk } from './sdk';
@ -125,6 +125,7 @@ export default abstract class extends Command {
new GraphQLClient(registry, {
headers: {
'User-Agent': `HiveCLI@${this.config.version}`,
// Authorization: `Bearer ${token}`,
'X-API-Token': token,
'graphql-client-name': 'Hive CLI',
'graphql-client-version': this.config.version,
@ -133,6 +134,32 @@ export default abstract class extends Command {
);
}
handleFetchError(error: unknown): never {
if (typeof error === 'string') {
return this.error(error);
}
if (error instanceof Error) {
if (isClientError(error)) {
const errors = error.response?.errors;
if (Array.isArray(errors) && errors.length > 0) {
return this.error(errors[0].message, {
ref: this.cleanRequestId(error.response?.headers?.get('x-request-id')),
});
}
return this.error(error.message, {
ref: this.cleanRequestId(error.response?.headers?.get('x-request-id')),
});
}
return this.error(error);
}
return this.error(JSON.stringify(error));
}
async require<
TFlags extends {
require: string[];
@ -144,3 +171,7 @@ export default abstract class extends Command {
}
}
}
function isClientError(error: Error): error is ClientError {
return 'response' in error;
}

View file

@ -3,6 +3,7 @@ import { buildSchema, Source, GraphQLError } from 'graphql';
import { validate, InvalidDocument } from '@graphql-inspector/core';
import Command from '../../base-command';
import { loadOperations } from '../../helpers/operations';
import { graphqlEndpoint } from '../../helpers/config';
export default class OperationsCheck extends Command {
static description = 'checks operations against a published schema';
@ -38,7 +39,7 @@ export default class OperationsCheck extends Command {
const registry = this.ensure({
key: 'registry',
args: flags,
defaultValue: 'https://app.graphql-hive.com/registry',
defaultValue: graphqlEndpoint,
env: 'HIVE_REGISTRY',
});
const file: string = args.file;
@ -91,16 +92,8 @@ export default class OperationsCheck extends Command {
if (error instanceof Errors.ExitError) {
throw error;
} else {
const parsedError: Error & { response?: any } = error instanceof Error ? error : new Error(error as string);
this.fail('Failed to validate operations');
if ('response' in parsedError) {
this.error(parsedError.response.errors[0].message, {
ref: this.cleanRequestId(parsedError.response?.headers?.get('x-request-id')),
});
} else {
this.error(parsedError);
}
this.handleFetchError(error);
}
}
}

View file

@ -1,6 +1,7 @@
import { Flags, Errors } from '@oclif/core';
import Command from '../../base-command';
import { loadOperations } from '../../helpers/operations';
import { graphqlEndpoint } from '../../helpers/config';
export default class OperationsPublish extends Command {
static description = 'saves operations to the store';
@ -36,7 +37,7 @@ export default class OperationsPublish extends Command {
const registry = this.ensure({
key: 'registry',
args: flags,
defaultValue: 'https://app.graphql-hive.com/registry',
defaultValue: graphqlEndpoint,
env: 'HIVE_REGISTRY',
});
const file: string = args.file;
@ -94,16 +95,8 @@ export default class OperationsPublish extends Command {
if (error instanceof Errors.ExitError) {
throw error;
} else {
const parsedError: Error & { response?: any } = error instanceof Error ? error : new Error(error as string);
this.fail('Failed to publish operations');
if ('response' in parsedError) {
this.error(parsedError.response.errors[0].message, {
ref: this.cleanRequestId(parsedError.response?.headers?.get('x-request-id')),
});
} else {
this.error(parsedError);
}
this.handleFetchError(error);
}
}
}

View file

@ -2,6 +2,7 @@ import { Flags, Errors } from '@oclif/core';
import { loadSchema, renderChanges, renderErrors, minifySchema } from '../../helpers/schema';
import { invariant } from '../../helpers/validation';
import { gitInfo } from '../../helpers/git';
import { graphqlEndpoint } from '../../helpers/config';
import Command from '../../base-command';
export default class SchemaCheck extends Command {
@ -51,7 +52,7 @@ export default class SchemaCheck extends Command {
const registry = this.ensure({
key: 'registry',
args: flags,
defaultValue: 'https://app.graphql-hive.com/registry',
defaultValue: graphqlEndpoint,
env: 'HIVE_REGISTRY',
});
const file = args.file;
@ -120,16 +121,8 @@ export default class SchemaCheck extends Command {
if (error instanceof Errors.ExitError) {
throw error;
} else {
const parsedError: Error & { response?: any } = error instanceof Error ? error : new Error(error as string);
this.fail('Failed to check schema');
if ('response' in parsedError) {
this.error(parsedError.response.errors[0].message, {
ref: this.cleanRequestId(parsedError.response?.headers?.get('x-request-id')),
});
} else {
this.error(parsedError);
}
this.handleFetchError(error);
}
}
}

View file

@ -2,6 +2,7 @@ import { transformCommentsToDescriptions } from '@graphql-tools/utils';
import { Flags, Errors } from '@oclif/core';
import { GraphQLError, print } from 'graphql';
import Command from '../../base-command';
import { graphqlEndpoint } from '../../helpers/config';
import { gitInfo } from '../../helpers/git';
import { invariant } from '../../helpers/validation';
import { loadSchema, minifySchema, renderChanges, renderErrors } from '../../helpers/schema';
@ -98,7 +99,7 @@ export default class SchemaPublish extends Command {
const registry = this.ensure({
key: 'registry',
args: flags,
defaultValue: 'https://app.graphql-hive.com/registry',
defaultValue: graphqlEndpoint,
env: 'HIVE_REGISTRY',
});
const service = this.maybe('service', flags);
@ -220,16 +221,8 @@ export default class SchemaPublish extends Command {
if (error instanceof Errors.ExitError) {
throw error;
} else {
const parsedError: Error & { response?: any } = error instanceof Error ? error : new Error(error as string);
this.fail('Failed to publish schema');
if ('response' in parsedError) {
this.error(parsedError.response.errors[0].message, {
ref: this.cleanRequestId(parsedError.response?.headers?.get('x-request-id')),
});
} else {
this.error(parsedError);
}
this.handleFetchError(error);
}
}
}

View file

@ -1,6 +1,7 @@
import { Flags } from '@oclif/core';
import colors from 'colors';
import Command from '../base-command';
import { graphqlEndpoint } from '../helpers/config';
export default class WhoAmI extends Command {
static description = 'checks schema';
@ -19,7 +20,7 @@ export default class WhoAmI extends Command {
const registry = this.ensure({
key: 'registry',
args: flags,
defaultValue: 'https://app.graphql-hive.com/registry',
defaultValue: graphqlEndpoint,
env: 'HIVE_REGISTRY',
});
const token = this.ensure({
@ -30,14 +31,8 @@ export default class WhoAmI extends Command {
const result = await this.registryApi(registry, token)
.myTokenInfo()
.catch((error: Error & { response?: any }) => {
if ('response' in error) {
this.error(error.response.errors[0].message, {
ref: this.cleanRequestId(error.response?.headers?.get('x-request-id')),
});
} else {
this.error(error);
}
.catch(error => {
this.handleFetchError(error);
});
if (result.tokenInfo.__typename === 'TokenInfo') {

View file

@ -2,6 +2,9 @@ import fs from 'fs';
import mkdirp from 'mkdirp';
import path from 'path';
// export const graphqlEndpoint = 'https://app.graphql-hive.com/graphql';
export const graphqlEndpoint = 'https://app.graphql-hive.com/registry';
export class Config<TValue = any> {
private cache?: Record<string, TValue>;
private filepath: string;

View file

@ -35,7 +35,7 @@ export function createHive(options: HivePluginOptions): HiveClient {
}
try {
let endpoint = 'https://app.graphql-hive.com/registry';
let endpoint = 'https://app.graphql-hive.com/graphql';
if (options.reporting && options.reporting.endpoint) {
endpoint = options.reporting.endpoint;
@ -82,7 +82,7 @@ export function createHive(options: HivePluginOptions): HiveClient {
{
headers: {
'content-type': 'application/json',
'x-api-token': options.token,
Authorization: `Bearer ${options.token}`,
},
timeout: 30_000,
decompress: true,

View file

@ -140,7 +140,7 @@ export function createAgent<T>(
.post(options.endpoint, buffer, {
headers: {
'content-type': 'application/json',
'x-api-token': options.token,
Authorization: `Bearer ${options.token}`,
'User-Agent': `${options.name}@${version}`,
...headers(),
},

View file

@ -39,7 +39,7 @@ export function createOperationsStore(pluginOptions: HivePluginOptions): Operati
const load: OperationsStore['load'] = async () => {
const response = await axios.post(
operationsStoreOptions.endpoint ?? 'https://app.graphql-hive.com/registry',
operationsStoreOptions.endpoint ?? 'https://app.graphql-hive.com/graphql',
{
query,
operationName: 'loadStoredOperations',
@ -48,7 +48,7 @@ export function createOperationsStore(pluginOptions: HivePluginOptions): Operati
responseType: 'json',
headers: {
'content-type': 'application/json',
'x-api-token': token,
Authorization: `Bearer ${token}`,
},
}
);

View file

@ -39,7 +39,7 @@ export function createReporting(pluginOptions: HivePluginOptions): SchemaReporte
{
logger,
...(pluginOptions.agent ?? {}),
endpoint: reportingOptions.endpoint ?? 'https://app.graphql-hive.com/registry',
endpoint: reportingOptions.endpoint ?? 'https://app.graphql-hive.com/graphql',
token: token,
enabled: pluginOptions.enabled,
debug: pluginOptions.debug,

View file

@ -72,7 +72,7 @@ test('should send data to Hive', async () => {
let body: any = {};
const http = nock('http://localhost')
.post('/200')
.matchHeader('x-api-token', token)
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
@ -139,7 +139,7 @@ test.only('should send data to Hive immediately', async () => {
let body: any = {};
const http = nock('http://localhost')
.post('/200')
.matchHeader('x-api-token', token)
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
@ -232,7 +232,7 @@ test('should send original schema of a federated service', async () => {
let body: any = {};
const http = nock('http://localhost')
.post('/200')
.matchHeader('x-api-token', token)
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])

View file

@ -109,7 +109,7 @@ test('should send data to Hive', async () => {
};
const http = nock('http://localhost')
.post('/200')
.matchHeader('x-api-token', token)
.matchHeader('Authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])
@ -236,7 +236,7 @@ test('sendImmediately should not stop the schedule', async () => {
const http = nock('http://localhost')
.post('/200')
.matchHeader('x-api-token', token)
.matchHeader('authorization', `Bearer ${token}`)
.matchHeader('Content-Type', headers['Content-Type'])
.matchHeader('graphql-client-name', headers['graphql-client-name'])
.matchHeader('graphql-client-version', headers['graphql-client-version'])

View file

@ -1,8 +0,0 @@
# @hive/api
## 0.0.2
### Patch Changes
- Updated dependencies [ac9b868c]
- @graphql-hive/core@0.2.0

View file

@ -153,7 +153,7 @@ export class AuthManager {
return this.apiToken;
}
throw new AccessError('X-API-Token is missing');
throw new AccessError('Authorization header is missing');
}
getUserIdForTracking: () => Promise<string | never> = share(async () => {

View file

@ -13,6 +13,20 @@ export const ApiTokenProvider: FactoryProvider<string | undefined> = {
if (singleValue && singleValue !== '') {
token = singleValue;
break;
}
} else if (headerName.toLowerCase() === 'authorization') {
const values = context.headers[headerName];
const singleValue = Array.isArray(values) ? values[0] : values;
if (singleValue && singleValue !== '') {
const bearer = singleValue.replace(/^Bearer\s+/i, '');
// Skip if bearer is missing or it's JWT generated by Auth0 (not API token)
if (bearer && bearer !== '' && !bearer.includes('.')) {
token = bearer;
break;
}
}
}
}

View file

@ -1,106 +0,0 @@
# @hive/schema
## 0.2.1
### Patch Changes
- e204afe4: Controller concurrency
## 0.2.0
### Minor Changes
- 845e0880: Trim descriptions
## 0.1.14
### Patch Changes
- 1623aca5: Upgrade sentry
## 0.1.13
### Patch Changes
- ffb6feb6: Add Redis word to redis logging
## 0.1.12
### Patch Changes
- Updated dependencies [3a435baa]
- @hive/service-common@0.1.3
## 0.1.11
### Patch Changes
- 689610ac: fix(deps): update sentry-javascript monorepo to v6.16.1
## 0.1.10
### Patch Changes
- d4a4c464: Use throng
## 0.1.9
### Patch Changes
- 4b85bf48: Seems like calculateDelay owns the retry limit
## 0.1.8
### Patch Changes
- 4e27e93e: Scrape schema and webhooks services
## 0.1.7
### Patch Changes
- 0ea9cf3e: Adjust connection to ClickHouse
## 0.1.6
### Patch Changes
- 953794f2: Fix #945
## 0.1.5
### Patch Changes
- a8485a06: Use Pino logger
- Updated dependencies [a8485a06]
- @hive/service-common@0.1.2
## 0.1.4
### Patch Changes
- 7a6f4e6f: Logs and printing
## 0.1.3
### Patch Changes
- e08d7691: Share stitchSchemas across validate and build phases
## 0.1.2
### Patch Changes
- 2e513bed: Smaller payload
## 0.1.1
### Patch Changes
- 79129085: Bump
## 0.1.0
### Minor Changes
- 747fccdb: Introduces Schema service to validate and build GraphQL schemas

File diff suppressed because it is too large Load diff

View file

@ -1,33 +0,0 @@
# @hive/service-common
## 0.1.3
### Patch Changes
- 3a435baa: Show one value of x-request-id
## 0.1.2
### Patch Changes
- a8485a06: Use Pino logger
## 0.1.1
### Patch Changes
- db2c1c3: Remove console.log
- 4e9f0aa: Mark every transaction containing GraphQL errors as failure
## 0.1.0
### Minor Changes
- 6ed9bf2: Add prometheus metrics
- 588285c: Reuse or generate request id in fastify logger
## 0.0.2
### Patch Changes
- 6b9dfc7: Add referer

View file

@ -1,321 +0,0 @@
# @hive/storage
## 0.14.1
### Patch Changes
- 1623aca5: Upgrade sentry
## 0.14.0
### Minor Changes
- ffb6feb6: Allow to check usage from multiple targets
## 0.13.3
### Patch Changes
- 689610ac: fix(deps): update sentry-javascript monorepo to v6.16.1
## 0.13.2
### Patch Changes
- b3e54d5a: Fixed 'only one service schema...'
## 0.13.1
### Patch Changes
- 33fbb5e: Bump
## 0.13.0
### Minor Changes
- dc8fb96: Introduce base schema
### Patch Changes
- bf78c16: Bump
## 0.12.0
### Minor Changes
- b5966ab: Say hi to TSUP!
## 0.11.2
### Patch Changes
- 02b00f0: Update undici, sentry, bullmq
## 0.11.1
### Patch Changes
- 7549a38: Fix startup
## 0.11.0
### Minor Changes
- 7eca7f0: Introduce access scopes
## 0.10.3
### Patch Changes
- 19d4cd5: Bump
## 0.10.2
### Patch Changes
- cc9aa01: Update dependencies
## 0.10.1
### Patch Changes
- 65b687e: Batch getSchema calls
## 0.10.0
### Minor Changes
- 94f45a5: Do not remove tokens, mark as deleted
## 0.9.0
### Minor Changes
- 91a6957: Allow to update url of a service
## 0.8.7
### Patch Changes
- 3d828f4: Use latest Sentry and Sentry NextJS integration
## 0.8.6
### Patch Changes
- b502e9e: Fix issue with conflicting name on target
## 0.8.5
### Patch Changes
- 9fb90bc: Fix issues with fetching project by name, and use org_id as well
## 0.8.4
### Patch Changes
- df6c501: Make Query.lab nullable
## 0.8.3
### Patch Changes
- 05d0140: Use @theguild/buddy
## 0.8.2
### Patch Changes
- 5f99c67: Batch getOrganizationOwner calls (homemade dataloader)
## 0.8.1
### Patch Changes
- 4ee9a3b: Fix operations count
## 0.8.0
### Minor Changes
- efd7b74: Admin panel
## 0.7.0
### Minor Changes
- 889368b: Bump
## 0.6.0
### Minor Changes
- 11e6800: Allow multiple auth providers and add displayName and fullName to profiles
## 0.5.6
### Patch Changes
- 0527e3c: Update Sentry
## 0.5.5
### Patch Changes
- 23636de: Fix missing URLs
## 0.5.4
### Patch Changes
- b010137: Update Sentry to 6.10.0
## 0.5.3
### Patch Changes
- 4bc83be: Node 16
## 0.5.2
### Patch Changes
- 93674cf: Update Sentry to 6.7.0
- 3e16adb: Attach originalError to captured expection by Sentry and set sql and values from Slonik
## 0.5.1
### Patch Changes
- 5aa5e93: Bump
## 0.5.0
### Minor Changes
- 87e3d2e: Alerts, yay!
### Patch Changes
- 968614d: Fix persisting the same query twice
## 0.4.0
### Minor Changes
- 143fa32: Added Schema Laboratory
## 0.3.3
### Patch Changes
- 148b294: Fix issues with undici headers timeout
## 0.3.2
### Patch Changes
- 85b85d4: Dependencies update, cleanup, ui fixes
## 0.3.1
### Patch Changes
- 9b14d18: Bump
## 0.3.0
### Minor Changes
- 36097a6: Add mixpanel
## 0.2.3
### Patch Changes
- 127e1fb: Bump storage
## 0.2.2
### Patch Changes
- f6d2ca6: bump
## 0.2.1
### Patch Changes
- 8f3e43c: Track usage of tokens
## 0.2.0
### Minor Changes
- 60cd35d: Consider Usage in Inspector
- 078e758: Token per Target
### Patch Changes
- 7113a0e: Update Sentry to 6.3.5
## 0.1.10
### Patch Changes
- 8d06fd4: Eh console.log
## 0.1.9
### Patch Changes
- 6a344d3: Fix invitations, expose only organization.name
## 0.1.8
### Patch Changes
- e688d94: Use native bidings, improve perf by disabling error stack traces
## 0.1.7
### Patch Changes
- 4793381: Prevent some organization names
## 0.1.6
### Patch Changes
- c1e705a: bump
## 0.1.5
### Patch Changes
- 54b60f6: Fix issues with build artifact
## 0.1.4
### Patch Changes
- 7e88e71: bump
## 0.1.3
### Patch Changes
- b2d686e: bump
## 0.1.2
### Patch Changes
- 9da6738: bump
## 0.1.1
### Patch Changes
- e8cb071: fix issues with ncc packages

View file

@ -1,345 +0,0 @@
# @hive/tokens
## 0.6.8
### Patch Changes
- 1623aca5: Upgrade sentry
- Updated dependencies [1623aca5]
- @hive/storage@0.14.1
## 0.6.7
### Patch Changes
- Updated dependencies [ffb6feb6]
- @hive/storage@0.14.0
## 0.6.6
### Patch Changes
- Updated dependencies [3a435baa]
- @hive/service-common@0.1.3
## 0.6.5
### Patch Changes
- 689610ac: fix(deps): update sentry-javascript monorepo to v6.16.1
- Updated dependencies [689610ac]
- @hive/storage@0.13.3
## 0.6.4
### Patch Changes
- Updated dependencies [a8485a06]
- @hive/service-common@0.1.2
## 0.6.3
### Patch Changes
- Updated dependencies [b3e54d5a]
- @hive/storage@0.13.2
## 0.6.2
### Patch Changes
- 33fbb5e: Bump
- Updated dependencies [33fbb5e]
- @hive/storage@0.13.1
## 0.6.1
### Patch Changes
- bf78c16: Bump
- Updated dependencies [bf78c16]
- Updated dependencies [dc8fb96]
- @hive/storage@0.13.0
## 0.6.0
### Minor Changes
- b5966ab: Replace undici with got
- b5966ab: Say hi to TSUP!
### Patch Changes
- Updated dependencies [b5966ab]
- @hive/storage@0.12.0
## 0.5.2
### Patch Changes
- 02b00f0: Update undici, sentry, bullmq
## 0.5.1
### Patch Changes
- 7549a38: Fix startup
## 0.5.0
### Minor Changes
- 7eca7f0: Introduce access scopes
## 0.4.3
### Patch Changes
- 2f7bc32: Collect default metrics
## 0.4.2
### Patch Changes
- 19d4cd5: Bump
## 0.4.1
### Patch Changes
- cc9aa01: Update dependencies
## 0.4.0
### Minor Changes
- 94f45a5: Do not remove tokens, mark as deleted
## 0.3.3
### Patch Changes
- 3d828f4: Use latest Sentry and Sentry NextJS integration
## 0.3.2
### Patch Changes
- 542b9b9: Better health/readiness in tokens service
## 0.3.1
### Patch Changes
- 207890c: Purge target cache when creating a token
## 0.3.0
### Minor Changes
- a835491: Use 404 when token is not found
## 0.2.19
### Patch Changes
- 0527e3c: Update Sentry
- 0527e3c: Add serverName tag to Sentry.init
## 0.2.18
### Patch Changes
- c28ebdf: Improve tiny-lru in tokens
## 0.2.17
### Patch Changes
- e0a47fb: Update tsconfig target
## 0.2.16
### Patch Changes
- 5ff2e7a: Bump
- 8627a9e: Fix fastify hooks
## 0.2.15
### Patch Changes
- 8f62c26: Update fastify
## 0.2.14
### Patch Changes
- 292b30f: Display token
## 0.2.13
### Patch Changes
- b010137: Update Sentry to 6.10.0
## 0.2.12
### Patch Changes
- bfbc724: Handle token read errors on route level and capture exceptions only once per 10m
## 0.2.11
### Patch Changes
- 455c033: Cache failed GET /:token requests for 10 minutes
## 0.2.10
### Patch Changes
- Updated dependencies [db2c1c3]
- Updated dependencies [4e9f0aa]
- @hive/service-common@0.1.1
## 0.2.9
### Patch Changes
- Updated dependencies [6ed9bf2]
- Updated dependencies [588285c]
- @hive/service-common@0.1.0
## 0.2.8
### Patch Changes
- 4bc83be: Use HEAD and GET for healthchecks
- 4bc83be: Node 16
## 0.2.7
### Patch Changes
- 93674cf: Update Sentry to 6.7.0
## 0.2.6
### Patch Changes
- c6ef3d2: Bob update
## 0.2.5
### Patch Changes
- 148b294: Fix issues with undici headers timeout
## 0.2.4
### Patch Changes
- 85b85d4: Dependencies update, cleanup, ui fixes
## 0.2.3
### Patch Changes
- f6d2ca6: bump
## 0.2.2
### Patch Changes
- 8f3e43c: Track usage of tokens
## 0.2.1
### Patch Changes
- 67660b1: Bump
- c083cb6: Use SENTRY_DSN
## 0.2.0
### Minor Changes
- 078e758: Token per Target
### Patch Changes
- 7113a0e: Update Sentry to 6.3.5
## 0.1.12
### Patch Changes
- d485371: Use trustProxy
## 0.1.11
### Patch Changes
- 22d5d6e: Add more data to Http requests in Sentry
## 0.1.10
### Patch Changes
- 3a03b35: Fix release id and LOG_LEVEL debug
## 0.1.9
### Patch Changes
- df4abcb: Enable Sentry only in prod
## 0.1.8
### Patch Changes
- 93fbf26: Use Sentry Tracing
- 28124b9: X-Cache HIT MISS on tokens
## 0.1.7
### Patch Changes
- 7bfdb93: Use Sentry to track performance
## 0.1.6
### Patch Changes
- c1e705a: bump
## 0.1.5
### Patch Changes
- efc1fbd: Fix build issues
## 0.1.4
### Patch Changes
- 7e88e71: bump
## 0.1.3
### Patch Changes
- b2d686e: bump
## 0.1.2
### Patch Changes
- 9da6738: bump
## 0.1.1
### Patch Changes
- e8cb071: fix issues with ncc packages

View file

@ -1,8 +0,0 @@
# @hive/usage-ingestor
## 0.0.2
### Patch Changes
- Updated dependencies [ac9b868c]
- @graphql-hive/core@0.2.0

View file

@ -81,7 +81,19 @@ async function main() {
url: '/',
async handler(req, res) {
httpRequests.inc();
const token = req.headers['x-api-token'] as string;
let token: string | undefined;
const legacyToken = req.headers['x-api-token'] as string;
if (legacyToken) {
// TODO: add metrics to track legacy x-api-token header
token = legacyToken;
} else {
const authValue = req.headers.authorization;
if (authValue) {
token = authValue.replace(/^Bearer\s+/, '');
}
}
if (!token) {
res.status(400).send('Missing token'); // eslint-disable-line @typescript-eslint/no-floating-promises -- false positive, FastifyReply.then returns void

View file

@ -1,33 +0,0 @@
# @hive/webhooks
## 0.1.4
### Patch Changes
- 1623aca5: Upgrade sentry
## 0.1.3
### Patch Changes
- Updated dependencies [3a435baa]
- @hive/service-common@0.1.3
## 0.1.2
### Patch Changes
- 689610ac: fix(deps): update sentry-javascript monorepo to v6.16.1
- 8a38ced6: Pass error as second or first
## 0.1.1
### Patch Changes
- 4e27e93e: Scrape schema and webhooks services
## 0.1.0
### Minor Changes
- b12a7254: Introduce Webhooks service

View file

@ -1,920 +0,0 @@
# @hive/app
## 0.16.2
### Patch Changes
- fef049c0: Capture exceptions in Urql
## 0.16.1
### Patch Changes
- 1623aca5: Upgrade sentry
## 0.16.0
### Minor Changes
- ffb6feb6: Allow to check usage from multiple targets
## 0.15.6
### Patch Changes
- ba69e567: Use NextJS API to redirect to an organization page
## 0.15.5
### Patch Changes
- 3a435baa: Show one value of x-request-id
## 0.15.4
### Patch Changes
- 3936341a: Show data from last 24h in admin view
## 0.15.3
### Patch Changes
- 689610ac: fix(deps): update sentry-javascript monorepo to v6.16.1
## 0.15.2
### Patch Changes
- d003d7b8: Fix decimals
## 0.15.1
### Patch Changes
- 4d511e3f: Fix
## 0.15.0
### Minor Changes
- 74f8187b: Add failure rate column to operations list
## 0.14.3
### Patch Changes
- 33fbb5e: Bump
## 0.14.2
### Patch Changes
- 5798314: Single x-request-id header
## 0.14.1
### Patch Changes
- bca0950: Improve UI and UX of base schema editor
## 0.14.0
### Minor Changes
- c6a842c: Introduce base schema
## 0.13.5
### Patch Changes
- 02b00f0: Update undici, sentry, bullmq
## 0.13.4
### Patch Changes
- 0df6a60: Enable global handlers
## 0.13.3
### Patch Changes
- c31e08b: Enable Sentry for nextjs client-side
## 0.13.2
### Patch Changes
- aebf898: Fixes
## 0.13.1
### Patch Changes
- 7549a38: Fix startup
## 0.13.0
### Minor Changes
- 7eca7f0: Introduce access scopes
## 0.12.4
### Patch Changes
- 7cc3bc6: Allow access to schema for single-schema projects
## 0.12.3
### Patch Changes
- 58b0c95: Set padding-bottom in Settings
## 0.12.2
### Patch Changes
- 1a98713: Smaller color mode button
## 0.12.1
### Patch Changes
- 57f56c3: Remove redirect_uri
## 0.12.0
### Minor Changes
- 14494fd: Notify user when slack is added
## 0.11.4
### Patch Changes
- 45541e7: add gql-tag-operations preset
## 0.11.3
### Patch Changes
- 19d4cd5: Bump
## 0.11.2
### Patch Changes
- cc9aa01: Update dependencies
## 0.11.1
### Patch Changes
- 14446ed: Adjust dark theme
## 0.11.0
### Minor Changes
- 301fdf2: Dark mode is here
## 0.10.30
### Patch Changes
- 273f096: fix GraphiQL editor styles
## 0.10.29
### Patch Changes
- 91a6957: Allow Integrations in Personal org"
## 0.10.28
### Patch Changes
- 9752ccb: Add Connect to Stitching projects
## 0.10.27
### Patch Changes
- d567beb: Update pages/api/proxy.ts and remove no longer needed console.log
## 0.10.26
### Patch Changes
- 2d561b7: No Sentry cli release + reuse transaction if available
## 0.10.25
### Patch Changes
- 28d8aec: Fix sentry
## 0.10.24
### Patch Changes
- 3d828f4: Use latest Sentry and Sentry NextJS integration
- efd8648: Better error ui with basic information
## 0.10.23
### Patch Changes
- 1da24b0: Push-only to crisp
## 0.10.22
### Patch Changes
- b15020b: Fix Crisp exceptions
## 0.10.21
### Patch Changes
- 6ac2116: Identify user on Crisp
## 0.10.20
### Patch Changes
- ce155d4: Adjust is-beta-accepted to changes in Crisp API
- 91573fb: Better error handling for checking beta approved
## 0.10.19
### Patch Changes
- 740bfd1: Better ui and error handling for Lab
## 0.10.18
### Patch Changes
- f99c737: Bump version to release recent changes (spinner)
## 0.10.17
### Patch Changes
- 7cceb48: Replace bee spinner
## 0.10.16
### Patch Changes
- 62b1d90: Add service filter to schema view
## 0.10.15
### Patch Changes
- c1971c2: Added missing robots.txt file
## 0.10.14
### Patch Changes
- b264205: Show organization clean id in Admin Stats
## 0.10.13
### Patch Changes
- df6c501: Make Query.lab nullable
## 0.10.12
### Patch Changes
- 3e2fdd8: Limit version name to 32 characters
## 0.10.11
### Patch Changes
- aff0857: Pass x-request-id to responses
## 0.10.10
### Patch Changes
- 9494f7f: Fit labels and move clients to a separate row
## 0.10.9
### Patch Changes
- 7c5c710: Show stats for client versions
## 0.10.8
### Patch Changes
- 5eee602: Add with-schema-pushes filter
## 0.10.7
### Patch Changes
- 249e484: Add "schedule a meeting" link to user menu
## 0.10.6
### Patch Changes
- 056f51d: Fix time series and fill missing gaps
## 0.10.5
### Patch Changes
- 5f99c67: Batch getOrganizationOwner calls (homemade dataloader)
## 0.10.4
### Patch Changes
- e5240d8: Skip if the email is not found
## 0.10.3
### Patch Changes
- 5fdfc22: Expose /is-beta-accepted endpoint
## 0.10.2
### Patch Changes
- 88fe4b6: Show more data in admin stats
## 0.10.1
### Patch Changes
- 4ee9a3b: Fix operations count
## 0.10.0
### Minor Changes
- efd7b74: Admin panel
## 0.9.1
### Patch Changes
- 28ff6df: Change opacity when loading data in operations view
## 0.9.0
### Minor Changes
- 889368b: Bump
## 0.8.0
### Minor Changes
- 11e6800: Allow multiple auth providers and add displayName and fullName to profiles
## 0.7.32
### Patch Changes
- ea7b7f9: Create empty series
## 0.7.31
### Patch Changes
- 4647d25: Show last 24h by default
- 4647d25: Dynamically calculate windows for operations data based on resolution
- 0527e3c: Update Sentry
- 0527e3c: Add serverName tag to Sentry.init
## 0.7.30
### Patch Changes
- deee331: Fix inputs in Conditional Breaking Changes
- 4a90860: Use react-virtualized to improve perf of operations filter
- 4a90860: Add pagination to the operations table
## 0.7.29
### Patch Changes
- 168a1f2: Improve History view
## 0.7.28
### Patch Changes
- bde9548: Create a separate view for schema version
## 0.7.27
### Patch Changes
- 5e8b34f: Update dependencies
- 5e8b34f: Activities are missing when switching pages
## 0.7.26
### Patch Changes
- c22c0c0: Add link to Using the Registry with a Apollo Gateway chapter
## 0.7.25
### Patch Changes
- 23636de: Add link to documentation in top bar navigation
- 23636de: Use VSCode icons
- 23636de: Remove Identifier from the CDN
- 23636de: Improve the design of the lab view
- 23636de: Store supergraph in CDN
- 23636de: Minor UI improvements
- 23636de: Add CDN access generation (to supergraph) to the Schema view page
## 0.7.24
### Patch Changes
- 3d4852c: Update urql and codegen
## 0.7.23
### Patch Changes
- 2dbfaf3: Redesign token creation
- 202ac80: Improve feedback modal
- f6c868f: Fix operations filter droping state
- f6c868f: Fix checkboxes in operations filter
## 0.7.22
### Patch Changes
- 9295075: Bump
## 0.7.21
### Patch Changes
- 1ac74a4: Fix an issue with stale data
## 0.7.20
### Patch Changes
- aa4e661: Use Fetch in Next
## 0.7.19
### Patch Changes
- fb3efda: Use defer in general operations stats query
## 0.7.18
### Patch Changes
- 66369be: Track inflight requests without forking fetchExchange
## 0.7.17
### Patch Changes
- 8d1811b: Fix target validation period and percentage being a string
## 0.7.16
### Patch Changes
- e0a47fb: Use Undici instead of Got and Agentkeepalive
## 0.7.15
### Patch Changes
- d7348a3: Merge few stats related queries into one query (improves perf in ClickHouse)
- d7348a3: Increase window times
## 0.7.14
### Patch Changes
- b010137: Update Sentry to 6.10.0
## 0.7.13
### Patch Changes
- abd3d3e: Use p75, p90, p95 and p99 only
## 0.7.12
### Patch Changes
- 11b3eb9: Added CDN using CF
## 0.7.11
### Patch Changes
- a154c1c: Upgrade Auth0 and Chakra UI
## 0.7.10
### Patch Changes
- f87350d: Floor dates (in date range) to 1 minute
## 0.7.9
### Patch Changes
- dae2b90: Add operations filter to operations stats page
## 0.7.8
### Patch Changes
- 553c093: UI Fixes
- 553c093: Alert icon with tooltip on anonymous operations
## 0.7.7
### Patch Changes
- 30b8847: Use NextJS 11
## 0.7.6
### Patch Changes
- 4bc83be: Node 16
## 0.7.5
### Patch Changes
- bed8e34: Reset feedback form and handle loading
## 0.7.4
### Patch Changes
- bf76381: Feedback dialog
## 0.7.3
### Patch Changes
- 93674cf: Update Sentry to 6.7.0
- ec5fa1d: Do not fetch unavailable fields when deleting an entity
## 0.7.2
### Patch Changes
- 3365d22: Fix double slash in slack integration endpoints
## 0.7.1
### Patch Changes
- 5aa5e93: Bump
## 0.7.0
### Minor Changes
- 87e3d2e: Alerts, yay!
## 0.6.4
### Patch Changes
- 1a16360: Send GraphQL Client name and version
## 0.6.3
### Patch Changes
- b1fc400: Add Release Notes
## 0.6.2
### Patch Changes
- 203c563: Use "experiment" as the default branch instead of "development"
## 0.6.1
### Patch Changes
- 4224cb9: Add info with a link to documentation on missing data
- c6ef3d2: Bob update
## 0.6.0
### Minor Changes
- 143fa32: Added Schema Laboratory
## 0.5.8
### Patch Changes
- e65b9cc: Do not capture Access Token related errors
- e65b9cc: Identify and update profile in Mixpanel once per page load
## 0.5.7
### Patch Changes
- d76ba3f: Fix no-auth redirect on API Proxy level
## 0.5.6
### Patch Changes
- aa12cdc: Small fixes
## 0.5.5
### Patch Changes
- 148b294: Fix issues with undici headers timeout
## 0.5.4
### Patch Changes
- 25fec29: Notify on modals only when open
## 0.5.3
### Patch Changes
- c346c4b: Fix mixpanel, NEXT_PUBLIC is compiled at build time, we don't have envs at that stage
## 0.5.2
### Patch Changes
- 85b85d4: Dependencies update, cleanup, ui fixes
## 0.5.1
### Patch Changes
- 9b14d18: Bump
## 0.5.0
### Minor Changes
- 36097a6: Add mixpanel
## 0.4.3
### Patch Changes
- 167f81e: ui fixes
## 0.4.2
### Patch Changes
- dbcfa69: Split operations stats query into smaller queries (looks WAY better)
## 0.4.1
### Patch Changes
- 824a403: Duration over time stats
## 0.4.0
### Minor Changes
- acab74b: Added support for persisted operations - Changes made in API, APP, CLI, Server, Storage
### Patch Changes
- b84a685: UI fixes
## 0.3.3
### Patch Changes
- bd4b28e: Better UI
## 0.3.2
### Patch Changes
- 0873fba: Use logarithim scale in latency histogram
## 0.3.1
### Patch Changes
- 6bf8518: Adjustements
## 0.3.0
### Minor Changes
- c507159: Redesign, fixes, different structure of components and RPM over time
## 0.2.14
### Patch Changes
- c591b5b: Distribution of latency
- ba5f690: Show requests per minute
## 0.2.13
### Patch Changes
- 3c72c34: Percentiles per operation
## 0.2.12
### Patch Changes
- ec400f8: Show failures over time
- a471c88: Support percentiles of request duration
## 0.2.11
### Patch Changes
- a32277c: Use ?period=window
## 0.2.10
### Patch Changes
- 4a1de8c: Change windows and add min/max to xAxis
## 0.2.9
### Patch Changes
- f6d2ca6: bump
## 0.2.8
### Patch Changes
- 6e68e25: More stats
## 0.2.7
### Patch Changes
- 0c08558: Fix barWidth
## 0.2.6
### Patch Changes
- 23e19fe: Add Requests Over Time plot
## 0.2.5
### Patch Changes
- ed8b326: Show simple stats
## 0.2.4
### Patch Changes
- 65dfbe9: Logout on auth error
- f7347a1: Distributed Tracing
- 8f3e43c: Track usage of tokens
- 4822bf2: Add TargetSwitcher
- dd5f0b0: Add a date range filter to operations
## 0.2.3
### Patch Changes
- b33bf11: List of collected operations
## 0.2.2
### Patch Changes
- c083cb6: Use SENTRY_DSN
## 0.2.1
### Patch Changes
- b036111: Fix sentry
## 0.2.0
### Minor Changes
- 60cd35d: Consider Usage in Inspector
- 078e758: Token per Target
### Patch Changes
- 7113a0e: Sentry
## 0.1.13
### Patch Changes
- 64b6c15: X-Request-ID
## 0.1.12
### Patch Changes
- ab5c204: Collect more with Sentry
## 0.1.11
### Patch Changes
- 6a344d3: Fix invitations, expose only organization.name
## 0.1.10
### Patch Changes
- d433269: Fixes
## 0.1.9
### Patch Changes
- 93fbf26: Use Sentry Tracing
## 0.1.8
### Patch Changes
- 2269c61: No extra calls to Auth0
## 0.1.7
### Patch Changes
- ede30d2: Added healthcheck endpoint
## 0.1.6
### Patch Changes
- fc3de1d: bump app to test partial deployment
## 0.1.5
### Patch Changes
- 519ee98: fix next start
## 0.1.4
### Patch Changes
- 20e886c: Fix missing public
## 0.1.3
### Patch Changes
- c1e705a: bump
## 0.1.2
### Patch Changes
- 7e88e71: bump
## 0.1.1
### Patch Changes
- b2d686e: bump

View file

@ -19,6 +19,7 @@ async function lab(req: NextApiRequest, res: NextApiResponse) {
const headers: Record<string, string> = {};
if (req.headers['x-hive-key']) {
// TODO: change that to Authorization: Bearer
headers['X-API-Token'] = req.headers['x-hive-key'] as string;
} else {
try {

View file

@ -1,7 +1,6 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { withSentry, captureException, startTransaction } from '@sentry/nextjs';
import type { Transaction } from '@sentry/types';
import { Readable } from 'stream';
import { auth0 } from '../../src/lib/auth0';
import hyperid from 'hyperid';
import { AccessTokenError } from '@auth0/nextjs-auth0';
@ -47,6 +46,8 @@ async function graphql(req: NextApiRequest, res: NextApiResponse) {
accept: req.headers['accept'],
'accept-encoding': req.headers['accept-encoding'],
'x-request-id': requestId,
authorization: req.headers.authorization,
// We need that to be backwards compatible with the new Authorization header format
'X-API-Token': req.headers['x-api-token'] ?? '',
'graphql-client-name': 'Hive App',
'x-use-proxy': '/api/proxy',
@ -106,40 +107,17 @@ async function graphql(req: NextApiRequest, res: NextApiResponse) {
body: JSON.stringify(req.body || {}),
} as any);
const contentType = (response.headers && response.headers.get('Content-Type')) || '';
const isStream = /multipart\/mixed/i.test(contentType);
if (isStream) {
graphqlSpan.setHttpStatus(response.status);
const headers: Record<string, string> = {};
response.headers.forEach((value, key) => {
headers[key] = value;
});
res.writeHead(response.status, headers);
const body = response.body as unknown as Readable;
body.on('data', (chunk: Buffer) => {
res.write(chunk.toString('utf8'));
});
body.on('end', () => {
graphqlSpan.finish();
finishTransaction();
res.end();
});
} else {
const xRequestId = response.headers.get('x-request-id');
if (xRequestId) {
res.setHeader('x-request-id', xRequestId);
}
const parsedData = await response.json();
graphqlSpan.setHttpStatus(200);
graphqlSpan.finish();
finishTransaction();
res.status(200).json(parsedData);
const xRequestId = response.headers.get('x-request-id');
if (xRequestId) {
res.setHeader('x-request-id', xRequestId);
}
const parsedData = await response.json();
graphqlSpan.setHttpStatus(200);
graphqlSpan.finish();
finishTransaction();
res.status(200).json(parsedData);
} catch (error) {
console.error(error);
captureException(error);

View file

@ -1,122 +0,0 @@
# @hive/landing-page
## 0.1.20
### Patch Changes
- da6cbaf9: fix(landing): update @theguild/components to fix algolia search
## 0.1.19
### Patch Changes
- 41ef8d7: Added missing icon files
## 0.1.18
### Patch Changes
- 4bfb049: Added robots to landing page as well
## 0.1.17
### Patch Changes
- 6cdc6b1: Add legal docs
- ffadea3: Cookie consent
## 0.1.16
### Patch Changes
- bde9548: Bump
## 0.1.15
### Patch Changes
- 5e8b34f: Update dependencies
## 0.1.14
### Patch Changes
- cb030e0: Bump The Guild Components
## 0.1.13
### Patch Changes
- 30b8847: Use NextJS 11
## 0.1.12
### Patch Changes
- 4bc83be: Node 16
## 0.1.11
### Patch Changes
- c6ef3d2: Bob update
## 0.1.10
### Patch Changes
- 85b85d4: Dependencies update, cleanup, ui fixes
## 0.1.9
### Patch Changes
- 824ae66: Included the-guild-components library (header integration)
## 0.1.8
### Patch Changes
- ede30d2: Added healthcheck endpoint
## 0.1.7
### Patch Changes
- 519ee98: fix next start
## 0.1.6
### Patch Changes
- 20e886c: Fix missing public
## 0.1.5
### Patch Changes
- c1e705a: bump
## 0.1.4
### Patch Changes
- 7e88e71: bump
## 0.1.3
### Patch Changes
- b2d686e: bump
## 0.1.2
### Patch Changes
- d578572: test
## 0.1.1
### Patch Changes
- 3c01907: test release