Crisp is a managed (Model B) connector: Probo holds one plugin token server-side and each connection carries only a Website ID. Nothing stops one organization from entering another organization's Website ID, so prove control of the website before creating the connection. Probo derives a per-(organization, website) verification code as an HMAC over the token secret and exposes it through a new crispVerificationCode query. The customer pastes it into the Probo plugin's per-website settings; at connect time the resolver reads the setting back through the managed plugin token and requires a constant-time match before any row is written. The managed key and plugin ID come from bootstrap, so the connector stays hidden until the deployment configures them. The settings fetch is injected so the create-time gate's branch wiring is unit-tested (mismatch and not-subscribed reject, internal errors stay generic, a matching code passes), and the managed-versus-client key resolution is covered too. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
236 lines
8.5 KiB
GraphQL
236 lines
8.5 KiB
GraphQL
enum ConnectorProvider
|
|
@goModel(model: "go.probo.inc/probo/pkg/coredata.ConnectorProvider") {
|
|
SLACK @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderSlack")
|
|
GOOGLE_WORKSPACE
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderGoogleWorkspace"
|
|
)
|
|
LINEAR @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderLinear")
|
|
ONE_PASSWORD
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderOnePassword"
|
|
)
|
|
HUBSPOT
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderHubSpot")
|
|
DOCUSIGN
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderDocuSign")
|
|
GRAFANA
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderGrafana")
|
|
NOTION @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderNotion")
|
|
BREX @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderBrex")
|
|
TALLY @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderTally")
|
|
CLOUDFLARE
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderCloudflare")
|
|
OPENAI @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderOpenAI")
|
|
POSTHOG @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderPostHog")
|
|
SENTRY @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderSentry")
|
|
SIGNOZ
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderSigNoz")
|
|
SUPABASE
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderSupabase")
|
|
BETTER_STACK
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderBetterStack"
|
|
)
|
|
GITHUB @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderGitHub")
|
|
INTERCOM
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderIntercom")
|
|
RESEND @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderResend")
|
|
SENDGRID
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderSendGrid")
|
|
MICROSOFT_365
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderMicrosoft365"
|
|
)
|
|
GITLAB @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderGitLab")
|
|
BITBUCKET
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderBitbucket")
|
|
HEROKU @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderHeroku")
|
|
PAGERDUTY
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderPagerDuty")
|
|
ASANA @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderAsana")
|
|
NETLIFY
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderNetlify")
|
|
CLICKUP
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderClickUp")
|
|
CLERK @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderClerk")
|
|
VERCEL @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderVercel")
|
|
MONDAY @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderMonday")
|
|
METABASE
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderMetabase")
|
|
TAILSCALE
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderTailscale")
|
|
ANTHROPIC
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderAnthropic"
|
|
)
|
|
CURSOR @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderCursor")
|
|
DATADOG @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderDatadog")
|
|
OKTA @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderOkta")
|
|
ZENDESK @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderZendesk")
|
|
QOVERY @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderQovery")
|
|
RENDER @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderRender")
|
|
NEON @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderNeon")
|
|
MERCURY
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderMercury")
|
|
APOLLO @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderApollo")
|
|
DEEPGRAM
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderDeepgram")
|
|
CLICKHOUSE
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderClickHouse"
|
|
)
|
|
LANGFUSE
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderLangfuse")
|
|
PYLON @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderPylon")
|
|
OPENROUTER
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderOpenRouter"
|
|
)
|
|
INCIDENT_IO
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderIncidentIO"
|
|
)
|
|
BREVO @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderBrevo")
|
|
SCALEWAY
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderScaleway")
|
|
YOUSIGN
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderYousign")
|
|
RAILWAY
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderRailway")
|
|
CRISP @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderCrisp")
|
|
}
|
|
|
|
type ConnectorProviderInfo {
|
|
provider: ConnectorProvider!
|
|
displayName: String!
|
|
oauthConfigured: Boolean!
|
|
apiKeySupported: Boolean!
|
|
"""
|
|
apiKeyManaged is true when the provider connects with a Probo-supplied
|
|
API key (Model B, e.g. Crisp's marketplace plugin token) that the
|
|
operator has configured. The customer supplies only the extra settings
|
|
(e.g. a Website ID), not the key. False until the key is configured,
|
|
which keeps such a provider out of the catalog.
|
|
"""
|
|
apiKeyManaged: Boolean!
|
|
clientCredentialsSupported: Boolean!
|
|
oauth2Scopes: [String!]!
|
|
extraSettings: [ConnectorProviderSettingInfo!]!
|
|
}
|
|
|
|
type ConnectorProviderSettingInfo {
|
|
key: String!
|
|
label: String!
|
|
required: Boolean!
|
|
}
|
|
|
|
input ConnectorFilter {
|
|
providers: [ConnectorProvider!]
|
|
}
|
|
|
|
type Connector {
|
|
id: ID!
|
|
provider: ConnectorProvider!
|
|
oauth2Scopes: [String!]! @goField(forceResolver: true)
|
|
createdAt: Datetime!
|
|
}
|
|
|
|
type SlackConnection implements Node {
|
|
id: ID!
|
|
channel: String
|
|
channelId: String
|
|
createdAt: Datetime!
|
|
updatedAt: Datetime!
|
|
|
|
permission(action: String!): Boolean! @goField(forceResolver: true)
|
|
}
|
|
|
|
type SlackConnectionConnection {
|
|
edges: [SlackConnectionEdge!]!
|
|
pageInfo: PageInfo!
|
|
}
|
|
|
|
type SlackConnectionEdge {
|
|
cursor: CursorKey!
|
|
node: SlackConnection!
|
|
}
|
|
|
|
extend type Mutation {
|
|
createAPIKeyConnector(
|
|
input: CreateAPIKeyConnectorInput!
|
|
): CreateAPIKeyConnectorPayload!
|
|
createClientCredentialsConnector(
|
|
input: CreateClientCredentialsConnectorInput!
|
|
): CreateClientCredentialsConnectorPayload!
|
|
deleteConnector(input: DeleteConnectorInput!): DeleteConnectorPayload!
|
|
deleteSlackConnection(
|
|
input: DeleteSlackConnectionInput!
|
|
): DeleteSlackConnectionPayload!
|
|
}
|
|
|
|
input CreateAPIKeyConnectorInput {
|
|
organizationId: ID!
|
|
provider: ConnectorProvider!
|
|
"""
|
|
apiKey is the customer-supplied credential. It is null for
|
|
ManagedAPIKey (Model B) providers such as Crisp, where the server
|
|
injects Probo's own key and the customer provides only the extra
|
|
settings.
|
|
"""
|
|
apiKey: String
|
|
tallyOrganizationId: String
|
|
sentryOrganizationSlug: String
|
|
supabaseOrganizationSlug: String
|
|
githubOrganization: String
|
|
grafanaBaseUrl: String
|
|
signozBaseUrl: String
|
|
onePasswordScimBridgeUrl: String
|
|
metabaseInstanceUrl: String
|
|
posthogRegion: String
|
|
posthogInstanceUrl: String
|
|
oktaDomain: String
|
|
betterStackTeamName: String
|
|
qoveryOrganizationId: String
|
|
renderWorkspaceId: String
|
|
neonOrganizationId: String
|
|
langfuseBaseUrl: String
|
|
scalewayOrganizationId: String
|
|
crispWebsiteId: String
|
|
}
|
|
|
|
type CreateAPIKeyConnectorPayload {
|
|
connector: Connector!
|
|
}
|
|
|
|
input CreateClientCredentialsConnectorInput {
|
|
organizationId: ID!
|
|
provider: ConnectorProvider!
|
|
clientId: String!
|
|
clientSecret: String!
|
|
tokenUrl: String!
|
|
scope: String
|
|
onePasswordAccountId: String
|
|
onePasswordRegion: String
|
|
}
|
|
|
|
type CreateClientCredentialsConnectorPayload {
|
|
connector: Connector
|
|
}
|
|
|
|
input DeleteConnectorInput {
|
|
connectorId: ID!
|
|
}
|
|
|
|
type DeleteConnectorPayload {
|
|
deletedConnectorId: ID!
|
|
}
|
|
|
|
input DeleteSlackConnectionInput {
|
|
slackConnectionId: ID!
|
|
}
|
|
|
|
type DeleteSlackConnectionPayload {
|
|
deletedSlackConnectionId: ID!
|
|
}
|