diff --git a/apps/api/lib/api_web/router.ex b/apps/api/lib/api_web/router.ex index 245446107..43e273860 100644 --- a/apps/api/lib/api_web/router.ex +++ b/apps/api/lib/api_web/router.ex @@ -21,7 +21,10 @@ defmodule ApiWeb.Router do forward "/", Absinthe.Plug, schema: GraphQl, - document_providers: [GraphQl.APQ, Absinthe.Plug.DocumentProvider.Default] + document_providers: [GraphQl.APQ, Absinthe.Plug.DocumentProvider.Default], + analyze_complexity: true, + max_complexity: 500, + token_limit: 5_000 end scope "/", ApiWeb do diff --git a/apps/core/lib/core/schema/user.ex b/apps/core/lib/core/schema/user.ex index d589df368..f34a6ab01 100644 --- a/apps/core/lib/core/schema/user.ex +++ b/apps/core/lib/core/schema/user.ex @@ -90,6 +90,8 @@ defmodule Core.Schema.User do timestamps() end + def intercom_id(%__MODULE__{id: id}), do: Core.sha("#{id}:#{Core.conf(:intercom_salt)}") + def service_account(query \\ __MODULE__, is_svc \\ :yes) def service_account(query, :yes) do diff --git a/apps/graphql/lib/graphql/schema/user.ex b/apps/graphql/lib/graphql/schema/user.ex index 8bb35bbc2..bb1d3d75f 100644 --- a/apps/graphql/lib/graphql/schema/user.ex +++ b/apps/graphql/lib/graphql/schema/user.ex @@ -130,6 +130,12 @@ defmodule GraphQl.Schema.User do _, _, _ -> {:error, "forbidden"} end + field :intercom_id, :string, resolve: fn + %{id: id} = user, _, %{context: %{current_user: %{id: id}}} -> + {:ok, Schema.User.intercom_id(user)} + _, _, _ -> {:error, "you can only read your own intercom id"} + end + field :has_installations, :boolean, resolve: fn user, _, _ -> {:ok, Core.Services.Users.has_installations?(user)} end diff --git a/apps/graphql/test/queries/user_queries_test.exs b/apps/graphql/test/queries/user_queries_test.exs index 5159ead7e..da542a0b5 100644 --- a/apps/graphql/test/queries/user_queries_test.exs +++ b/apps/graphql/test/queries/user_queries_test.exs @@ -24,6 +24,25 @@ defmodule GraphQl.UserQueriesTest do assert length(me["boundRoles"]) == 1 end + test "it can fetch an intercom id" do + user = insert(:user) + insert(:role_binding, user: user, group_id: nil) + + {:ok, %{data: %{"me" => me}}} = run_query(""" + query { + me { + id + name + intercomId + } + } + """, %{}, %{current_user: Core.Services.Rbac.preload(user)}) + + assert me["id"] == user.id + assert me["name"] == user.name + assert me["intercomId"] && me["intercomId"] != user.id + end + test "It will mark user as demoed if demo_count reaches the limit" do user = insert(:user, demo_count: 3) diff --git a/config/config.exs b/config/config.exs index 926581da9..126782ebf 100644 --- a/config/config.exs +++ b/config/config.exs @@ -147,6 +147,7 @@ config :core, mgmt_repo: "https://github.com/pluralsh/plural.git", cockroach_parameters: [], bootstrap_ssl: true, + intercom_salt: "intercomsalt", cloud_domain: "cloud.plural.sh" config :briefly, diff --git a/mix.exs b/mix.exs index 0f46abf6d..77c180b29 100644 --- a/mix.exs +++ b/mix.exs @@ -54,7 +54,7 @@ defmodule Plural.MixProject do {:shards, "~> 1.0"}, {:ecto, "~> 3.9.0", override: true}, {:hackney, "~> 1.18.1", override: true}, - {:absinthe_plug, "~> 1.5.8"}, + {:absinthe_plug, "~> 1.5.8", git: "https://github.com/absinthe-graphql/absinthe_plug.git", commit: "3a984cc341ebb32c79e7ae58b4ebd116d5c62f9e", override: true}, {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, {:sobelow, "~> 0.8", only: :dev}, {:excoveralls, "~> 0.10", only: :test}, diff --git a/mix.lock b/mix.lock index 2438f28e1..64d5cef43 100644 --- a/mix.lock +++ b/mix.lock @@ -2,7 +2,7 @@ "absinthe": {:hex, :absinthe, "1.7.8", "43443d12ad2b4fcce60e257ac71caf3081f3d5c4ddd5eac63a02628bcaf5b556", [:mix], [{:dataloader, "~> 1.0.0 or ~> 2.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:opentelemetry_process_propagator, "~> 0.2.1 or ~> 0.3", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c4085df201892a498384f997649aedb37a4ce8a726c170d5b5617ed3bf45d40b"}, "absinthe_client": {:hex, :absinthe_client, "0.1.1", "1e778d587a27b85ecc35e4a5fedc64c85d9fdfd05395745c7af5345564dff54e", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:req, "~> 0.4", [hex: :req, repo: "hexpm", optional: false]}, {:slipstream, "~> 1.0", [hex: :slipstream, repo: "hexpm", optional: false]}], "hexpm", "e75a28c5bb647f485e9c03bbc3a47e7783742794bd4c10f3307a495a9e7273b6"}, "absinthe_phoenix": {:hex, :absinthe_phoenix, "2.0.2", "e607b438db900049b9b3760f8ecd0591017a46122fffed7057bf6989020992b5", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm", "d36918925c380dc7d2ed7d039c9a3b4182ec36723f7417a68745ade5aab22f8d"}, - "absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"}, + "absinthe_plug": {:git, "https://github.com/absinthe-graphql/absinthe_plug.git", "3a984cc341ebb32c79e7ae58b4ebd116d5c62f9e", []}, "absinthe_relay": {:hex, :absinthe_relay, "1.5.2", "cfb8aed70f4e4c7718d3f1c212332d2ea728f17c7fc0f68f1e461f0f5f0c4b9a", [:mix], [{:absinthe, "~> 1.5.0 or ~> 1.6.0 or ~> 1.7.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "0587ee913afa31512e1457a5064ee88427f8fe7bcfbeeecd41c71d9cff0b62b6"}, "accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm", "11b18c220bcc2eab63b5470c038ef10eb6783bcb1fcdb11aa4137defa5ac1bb8"}, "amqp": {:hex, :amqp, "3.2.0", "51e85e06e4d283d98f21dce95906e42cb181fc7ceeb967b33b3be73d6ea41aa5", [:mix], [{:amqp_client, "~> 3.9.1", [hex: :amqp_client, repo: "hexpm", optional: false]}], "hexpm", "1439570336df6e79000239938fb055a0944dc9a768b4dec0af1375404508a014"}, @@ -121,9 +121,9 @@ "phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"}, "phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"}, "piazza_core": {:git, "https://github.com/michaeljguarino/piazza_core", "ebbda3cff4f49f5ec647a28c03a3dd3ce03766db", []}, - "plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"}, + "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, "plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"}, - "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, + "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "porcelain": {:hex, :porcelain, "2.0.3", "2d77b17d1f21fed875b8c5ecba72a01533db2013bd2e5e62c6d286c029150fdc", [:mix], [], "hexpm", "dc996ab8fadbc09912c787c7ab8673065e50ea1a6245177b0c24569013d23620"}, diff --git a/rel/config/config.exs b/rel/config/config.exs index 14460e178..591ce374a 100644 --- a/rel/config/config.exs +++ b/rel/config/config.exs @@ -106,6 +106,10 @@ if get_env("SYSBOX_WHITELIST") do config :core, :sysbox_emails, String.split(get_env("SYSBOX_WHITELIST"), ",") end +if get_env("INTERCOM_SALT") do + config :core, intercom_salt: get_env("INTERCOM_SALT") +end + config :workos, client_id: get_env("WORKOS_CLIENT_ID"), api_key: get_env("WORKOS_API_KEY") diff --git a/schema/schema.graphql b/schema/schema.graphql index f24bb3bd3..ad1ace80f 100644 --- a/schema/schema.graphql +++ b/schema/schema.graphql @@ -3358,6 +3358,8 @@ type User { jwt: String + intercomId: String + hasInstallations: Boolean demoing: Boolean diff --git a/www/src/components/Plural.tsx b/www/src/components/Plural.tsx index 70cff8ca7..86077239a 100644 --- a/www/src/components/Plural.tsx +++ b/www/src/components/Plural.tsx @@ -1,8 +1,6 @@ -import { Suspense, lazy, useEffect, useState } from 'react' +import { Suspense, lazy } from 'react' import { Navigate, Outlet, Route, Routes, useMatch } from 'react-router-dom' -import { Toast } from '@pluralsh/design-system' -import { growthbook } from '../helpers/growthbook' import { useHistory } from '../router' import { WrapStripe } from './WrapStripe' @@ -288,30 +286,6 @@ function OAuthOrFallback() { ) } -function TestBanner() { - const [enable, setEnable] = useState(true) - - useEffect(() => { - const timeout = setTimeout(() => setEnable(false), 5000) - - return () => clearTimeout(timeout) - }, []) - - if (growthbook.isOn('growthbook-test') && enable) { - return ( - - Growthbook Test! - - ) - } - - return null -} - export function PluralInner() { return ( @@ -322,7 +296,6 @@ export function PluralInner() { - {/* --- OAUTH --- */} {/* TODO: Enable if route will be used by the app */} diff --git a/www/src/components/login/CurrentUser.tsx b/www/src/components/login/CurrentUser.tsx index 24f31055d..244758a4f 100644 --- a/www/src/components/login/CurrentUser.tsx +++ b/www/src/components/login/CurrentUser.tsx @@ -13,7 +13,6 @@ import { setToken, wipeToken, } from '../../helpers/authentication' -import { growthbook } from '../../helpers/growthbook' import { useNotificationSubscription } from '../../hooks/useNotificationSubscription' import BillingPlatformPlansProvider from '../account/billing/BillingPlatformPlansProvider' import BillingSubscriptionProvider from '../account/billing/BillingSubscriptionProvider' @@ -66,12 +65,7 @@ export function PluralProvider({ children }: any) { if (!data?.me) return const { me } = data - boot({ name: me.name, email: me.email, userId: me.id }) - growthbook.setAttributes({ - company: me.account.name, - id: me.id, - email: me.email, - }) + boot({ name: me.name, email: me.email, userId: me.intercomId || me.id }) }, [data, boot]) useEffect(() => { diff --git a/www/src/components/marketplace/MarketplaceRepositories.tsx b/www/src/components/marketplace/MarketplaceRepositories.tsx index fa40c8cfa..82db36417 100644 --- a/www/src/components/marketplace/MarketplaceRepositories.tsx +++ b/www/src/components/marketplace/MarketplaceRepositories.tsx @@ -17,8 +17,6 @@ import orderBy from 'lodash/orderBy' import { upperFirst } from 'lodash' -import { growthbook } from '../../helpers/growthbook' - import { ResponsiveLayoutSidecarContainer } from '../utils/layout/ResponsiveLayoutSidecarContainer' import { ResponsiveLayoutSpacer } from '../utils/layout/ResponsiveLayoutSpacer' @@ -109,7 +107,7 @@ function MarketplaceRepositories({ publisher }: { publisher?: any }) { const isFiltered = !isEmpty(categories) || !isEmpty(tags) const isFilteredOrSearched = isFiltered || search - const shouldRenderStacks = growthbook.isOn('stacks') && !isFilteredOrSearched + const shouldRenderStacks = !isFilteredOrSearched useEffect(() => { const { current } = scrollRef diff --git a/www/src/components/shell/onboarding/sections/cloud/CloudCredentials.tsx b/www/src/components/shell/onboarding/sections/cloud/CloudCredentials.tsx index 2621e831e..d5741875c 100644 --- a/www/src/components/shell/onboarding/sections/cloud/CloudCredentials.tsx +++ b/www/src/components/shell/onboarding/sections/cloud/CloudCredentials.tsx @@ -2,14 +2,12 @@ import { useContext, useEffect, useState } from 'react' import { FormField, ListBoxItem, Select } from '@pluralsh/design-system' -import { growthbook } from '../../../../../helpers/growthbook' import { CloudProvider, CloudProviderDisplayName } from '../../context/types' import { OnboardingContext } from '../../context/onboarding' import Provider from './provider/Provider' const CLOUDS = Object.values(CloudProvider) -const GROWTHBOOK_AZURE_CLOUD_KEY = 'azure-cloud-shell' interface ProviderItem { key: string @@ -21,11 +19,7 @@ function CloudCredentials() { const [provider, setProvider] = useState( cloud?.provider || CloudProvider.AWS ) - const providers = ( - growthbook.isOn(GROWTHBOOK_AZURE_CLOUD_KEY) - ? CLOUDS - : CLOUDS.filter((c) => c !== CloudProvider.Azure) - ).map((c) => ({ + const providers = CLOUDS.map((c) => ({ key: c, label: CloudProviderDisplayName[c], })) diff --git a/www/src/generated/graphql.ts b/www/src/generated/graphql.ts index e7eee7752..5d42cc259 100644 --- a/www/src/generated/graphql.ts +++ b/www/src/generated/graphql.ts @@ -4972,6 +4972,7 @@ export type User = { id: Scalars['ID']['output']; impersonationPolicy?: Maybe; insertedAt?: Maybe; + intercomId?: Maybe; invites?: Maybe>>; jwt?: Maybe; loginMethod?: Maybe; @@ -5971,7 +5972,7 @@ export type EabCredentialFragment = { __typename?: 'EabCredential', id: string, export type MeQueryVariables = Exact<{ [key: string]: never; }>; -export type MeQuery = { __typename?: 'RootQueryType', me?: { __typename?: 'User', demoing?: boolean | null, loginMethod?: LoginMethod | null, hasInstallations?: boolean | null, hasShell?: boolean | null, id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, account: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null, rootUser?: { __typename?: 'User', id: string, name: string, email: string } | null, domainMappings?: Array<{ __typename?: 'DomainMapping', id: string, domain: string, enableSso?: boolean | null } | null> | null }, publisher?: { __typename?: 'Publisher', billingAccountId?: string | null, id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, boundRoles?: Array<{ __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null } | null> | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, configuration?: { __typename?: 'PluralConfiguration', stripeConnectId?: string | null, stripePublishableKey?: string | null, registry?: string | null, gitCommit?: string | null } | null }; +export type MeQuery = { __typename?: 'RootQueryType', me?: { __typename?: 'User', demoing?: boolean | null, loginMethod?: LoginMethod | null, hasInstallations?: boolean | null, hasShell?: boolean | null, intercomId?: string | null, id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, account: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null, rootUser?: { __typename?: 'User', id: string, name: string, email: string } | null, domainMappings?: Array<{ __typename?: 'DomainMapping', id: string, domain: string, enableSso?: boolean | null } | null> | null }, publisher?: { __typename?: 'Publisher', billingAccountId?: string | null, id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, boundRoles?: Array<{ __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null } | null> | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, configuration?: { __typename?: 'PluralConfiguration', stripeConnectId?: string | null, stripePublishableKey?: string | null, registry?: string | null, gitCommit?: string | null } | null }; export type GetLoginMethodQueryVariables = Exact<{ email: Scalars['String']['input']; @@ -10507,6 +10508,7 @@ export const MeDocument = gql` loginMethod hasInstallations hasShell + intercomId account { ...Account rootUser { diff --git a/www/src/graph/users.graphql b/www/src/graph/users.graphql index e824b3032..587f22450 100644 --- a/www/src/graph/users.graphql +++ b/www/src/graph/users.graphql @@ -165,6 +165,7 @@ query Me { loginMethod hasInstallations hasShell + intercomId account { ...Account rootUser {