Skip to content

Commit c0dfa80

Browse files
authored
feat: BYO Auth (#491)
* feat: BYO Auth Define client-side auth resolvers to be able to supply custom authentication credentials for integrations before a run is performed - Added new defineAuthResolver - Update all integrations to support the new auth resolvers - Strip internal symbols from .d.ts in integrations and trigger-sdk - Added BYO Auth docs - Update Dynamic Schedule to support associated account IDs - Create external accounts just-in-time - Added Account ID field to test job when there are external auth integrations - Show Account ID on run dashboard - Added new Run error state called “Unresolved auth” * Added changeset * Remove @internal from TriggerIntegration public methods * Add void to the result union * DynamicTriggers now work with the new BYO auth system, and added a bunch of docs and docs changes * Add additional key material for registering dynamic trigger task * Add new define* instance methods to the overview
1 parent 3e63a7e commit c0dfa80

File tree

116 files changed

+2114
-515
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+2114
-515
lines changed

.changeset/tiny-pillows-dream.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
"@trigger.dev/airtable": patch
3+
"@trigger.dev/sendgrid": patch
4+
"@trigger.dev/supabase": patch
5+
"@trigger.dev/typeform": patch
6+
"@trigger.dev/sdk": patch
7+
"@trigger.dev/github": patch
8+
"@trigger.dev/openai": patch
9+
"@trigger.dev/resend": patch
10+
"@trigger.dev/stripe": patch
11+
"@trigger.dev/plain": patch
12+
"@trigger.dev/slack": patch
13+
"@trigger.dev/core": patch
14+
---
15+
16+
Add support for Bring Your Own Auth

.vscode/launch.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@
1919
"name": "Chrome webapp",
2020
"url": "http://localhost:3030",
2121
"webRoot": "${workspaceFolder}/apps/webapp/app"
22+
},
23+
{
24+
"type": "node-terminal",
25+
"request": "launch",
26+
"name": "Debug BYO Auth",
27+
"command": "pnpm run byo-auth",
28+
"envFile": "${workspaceFolder}/references/job-catalog/.env",
29+
"cwd": "${workspaceFolder}/references/job-catalog",
30+
"sourceMaps": true
2231
}
2332
]
2433
}

apps/webapp/app/components/jobs/JobsTable.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ function classForJobStatus(status: JobRunStatus) {
197197
case "TIMED_OUT":
198198
case "WAITING_ON_CONNECTIONS":
199199
case "PENDING":
200+
case "UNRESOLVED_AUTH":
200201
return "text-rose-500";
201202
default:
202203
return "";

apps/webapp/app/components/run/RunOverview.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,13 @@ export function RunOverview({ run, trigger, showRerun, paths }: RunOverviewProps
167167
<RunPanelHeader icon={trigger.icon} title={trigger.title} />
168168
<RunPanelBody>
169169
<RunPanelProperties
170-
properties={[{ label: "Event name", text: run.event.name }, ...run.properties]}
170+
properties={[{ label: "Event name", text: run.event.name }]
171+
.concat(
172+
run.event.externalAccount
173+
? [{ label: "Account ID", text: run.event.externalAccount.identifier }]
174+
: []
175+
)
176+
.concat(run.properties)}
171177
/>
172178
</RunPanelBody>
173179
</RunPanel>

apps/webapp/app/components/run/TriggerDetail.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ export function TriggerDetail({
4545
/>
4646
)}
4747
<RunPanelIconProperty icon="id" label="Event name" value={name} />
48+
{trigger.externalAccount && (
49+
<RunPanelIconProperty
50+
icon="account"
51+
label="Account ID"
52+
value={trigger.externalAccount.identifier}
53+
/>
54+
)}
4855
</RunPanelIconSection>
4956
<RunPanelDivider />
5057
<div className="mt-4 flex flex-col gap-2">

apps/webapp/app/components/runs/RunStatuses.tsx

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
import type { JobRunExecution, JobRunStatus } from "@trigger.dev/database";
1+
import { NoSymbolIcon } from "@heroicons/react/20/solid";
22
import {
33
CheckCircleIcon,
44
ClockIcon,
55
ExclamationTriangleIcon,
6-
StopIcon,
76
WrenchIcon,
87
XCircleIcon,
98
} from "@heroicons/react/24/solid";
9+
import type { JobRunStatus } from "@trigger.dev/database";
1010
import { cn } from "~/utils/cn";
1111
import { Spinner } from "../primitives/Spinner";
12-
import { HandRaisedIcon, NoSymbolIcon } from "@heroicons/react/20/solid";
1312

1413
export function hasFinished(status: JobRunStatus): boolean {
1514
return (
1615
status === "SUCCESS" ||
1716
status === "FAILURE" ||
1817
status === "ABORTED" ||
1918
status === "TIMED_OUT" ||
20-
status === "CANCELED"
19+
status === "CANCELED" ||
20+
status === "UNRESOLVED_AUTH"
2121
);
2222
}
2323

@@ -48,6 +48,8 @@ export function RunStatusIcon({ status, className }: { status: JobRunStatus; cla
4848
return <XCircleIcon className={cn(runStatusClassNameColor(status), className)} />;
4949
case "TIMED_OUT":
5050
return <ExclamationTriangleIcon className={cn(runStatusClassNameColor(status), className)} />;
51+
case "UNRESOLVED_AUTH":
52+
return <XCircleIcon className={cn(runStatusClassNameColor(status), className)} />;
5153
case "WAITING_ON_CONNECTIONS":
5254
return <WrenchIcon className={cn(runStatusClassNameColor(status), className)} />;
5355
case "ABORTED":
@@ -63,26 +65,25 @@ export type RunBasicStatus = "WAITING" | "PENDING" | "RUNNING" | "COMPLETED" | "
6365

6466
export function runBasicStatus(status: JobRunStatus): RunBasicStatus {
6567
switch (status) {
66-
case "SUCCESS":
67-
return "COMPLETED";
68+
case "WAITING_ON_CONNECTIONS":
69+
case "QUEUED":
70+
case "PREPROCESSING":
6871
case "PENDING":
6972
return "PENDING";
7073
case "STARTED":
7174
return "RUNNING";
72-
case "QUEUED":
73-
return "PENDING";
7475
case "FAILURE":
75-
return "FAILED";
7676
case "TIMED_OUT":
77-
return "FAILED";
78-
case "WAITING_ON_CONNECTIONS":
79-
return "PENDING";
80-
case "ABORTED":
81-
return "FAILED";
82-
case "PREPROCESSING":
83-
return "PENDING";
77+
case "UNRESOLVED_AUTH":
8478
case "CANCELED":
79+
case "ABORTED":
8580
return "FAILED";
81+
case "SUCCESS":
82+
return "COMPLETED";
83+
default: {
84+
const _exhaustiveCheck: never = status;
85+
throw new Error(`Non-exhaustive match for value: ${status}`);
86+
}
8687
}
8788
}
8889

@@ -108,6 +109,12 @@ export function runStatusTitle(status: JobRunStatus): string {
108109
return "Preprocessing";
109110
case "CANCELED":
110111
return "Canceled";
112+
case "UNRESOLVED_AUTH":
113+
return "Unresolved auth";
114+
default: {
115+
const _exhaustiveCheck: never = status;
116+
throw new Error(`Non-exhaustive match for value: ${status}`);
117+
}
111118
}
112119
}
113120

@@ -122,6 +129,7 @@ export function runStatusClassNameColor(status: JobRunStatus): string {
122129
case "QUEUED":
123130
return "text-amber-300";
124131
case "FAILURE":
132+
case "UNRESOLVED_AUTH":
125133
return "text-rose-500";
126134
case "TIMED_OUT":
127135
return "text-amber-300";

apps/webapp/app/models/runConnection.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export async function resolveRunConnections(
1616
const result: Record<string, ConnectionAuth> = {};
1717

1818
for (const connection of connections) {
19-
if (connection.integration.authSource === "LOCAL") {
19+
if (connection.integration.authSource !== "HOSTED") {
2020
continue;
2121
}
2222

apps/webapp/app/presenters/IntegrationClientPresenter.server.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,12 @@ export class IntegrationClientPresenter {
120120
icon: integration.definition.icon,
121121
},
122122
authMethod: {
123-
type: integration.authMethod?.type ?? "local",
124-
name: integration.authMethod?.name ?? "Local Auth",
123+
type:
124+
integration.authMethod?.type ?? integration.authSource === "RESOLVER" ? "local" : "local",
125+
name:
126+
integration.authMethod?.name ?? integration.authSource === "RESOLVER"
127+
? "Auth Resolver"
128+
: "Local Auth",
125129
},
126130
help,
127131
};

apps/webapp/app/presenters/IntegrationsPresenter.server.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ export class IntegrationsPresenter {
125125
name: c.definition.name,
126126
},
127127
authMethod: {
128-
type: c.authMethod?.type ?? "local",
129-
name: c.authMethod?.name ?? "Local Only",
128+
type: c.authMethod?.type ?? c.authSource === "RESOLVER" ? "resolver" : "local",
129+
name:
130+
c.authMethod?.name ?? c.authSource === "RESOLVER" ? "Auth Resolver" : "Local Only",
130131
},
131132
authSource: c.authSource,
132133
setupStatus: c.setupStatus,

apps/webapp/app/presenters/RunPresenter.server.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ export class RunPresenter {
115115
payload: true,
116116
timestamp: true,
117117
deliveredAt: true,
118+
externalAccount: {
119+
select: {
120+
identifier: true,
121+
},
122+
},
118123
},
119124
},
120125
tasks: {

0 commit comments

Comments
 (0)