Skip to content

Commit 7fc5b95

Browse files
committed
feat(worker): support multiple git platforms in fallback worker
Add platform field to repo query and check platform compatibility. Add GitLab and Bitbucket token scope fetching in auth callback. Default to GitHub for legacy repos and throw error for unsupported platforms.
1 parent 29f9082 commit 7fc5b95

2 files changed

Lines changed: 51 additions & 6 deletions

File tree

apps/web/src/app/api/auth/[provider]/callback/route.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,39 @@ async function fetchGithubTokenScopes(token: string): Promise<string[]> {
2323
.filter(Boolean);
2424
}
2525

26+
async function fetchGitlabTokenScopes(token: string): Promise<string[]> {
27+
// GitLab OAuth tokens have scopes defined at app creation, but we can verify
28+
// the token is valid by hitting the user endpoint
29+
const res = await fetch("https://gitlab.com/api/v4/user", {
30+
headers: {
31+
Authorization: `Bearer ${token}`,
32+
},
33+
cache: "no-store",
34+
});
35+
36+
if (!res.ok) return [];
37+
38+
// GitLab doesn't expose scopes in response headers for OAuth tokens
39+
// Return the default scopes we requested during OAuth
40+
return ["read_user", "read_api", "read_repository"];
41+
}
42+
43+
async function fetchBitbucketTokenScopes(token: string): Promise<string[]> {
44+
// Bitbucket OAuth scopes are defined at app creation time
45+
// Verify the token is valid by hitting the user endpoint
46+
const res = await fetch("https://api.bitbucket.org/2.0/user", {
47+
headers: {
48+
Authorization: `Bearer ${token}`,
49+
},
50+
cache: "no-store",
51+
});
52+
53+
if (!res.ok) return [];
54+
55+
// Return the scopes we requested during OAuth
56+
return ["account", "repository", "pullrequest"];
57+
}
58+
2659
export async function GET(
2760
request: Request,
2861
{ params }: { params: Promise<{ provider: string }> }
@@ -85,8 +118,11 @@ export async function GET(
85118
let scopes: string[] = [];
86119
if (provider === "github") {
87120
scopes = await fetchGithubTokenScopes(providerToken).catch(() => []);
121+
} else if (provider === "gitlab") {
122+
scopes = await fetchGitlabTokenScopes(providerToken).catch(() => []);
123+
} else if (provider === "bitbucket") {
124+
scopes = await fetchBitbucketTokenScopes(providerToken).catch(() => []);
88125
}
89-
// TODO: Implement scopes fetching for GitLab/Bitbucket if needed
90126

91127
// Check if we need to set is_primary
92128
// If the user has no other connections, this one is primary.

apps/worker/src/index.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,26 +468,35 @@ async function processJob(jobId: string, config: WorkerConfig): Promise<void> {
468468

469469
const { data: repo, error: repoError } = await supabase
470470
.from("repos")
471-
.select("id, owner, name, full_name")
471+
.select("id, owner, name, full_name, platform")
472472
.eq("id", job.repo_id)
473473
.single();
474474

475475
if (repoError || !repo) throw new Error("Job repo not found");
476476

477+
// Default to github for legacy repos without platform field
478+
const platform = repo.platform ?? "github";
479+
480+
// This fallback worker only supports GitHub - use Inngest for GitLab/Bitbucket
481+
if (platform !== "github") {
482+
throw new Error(`Platform "${platform}" not supported by fallback worker. Use Inngest-based processing for GitLab/Bitbucket repos.`);
483+
}
484+
477485
if (!config.githubTokenEncryptionKey) {
478486
throw new Error("Missing GITHUB_TOKEN_ENCRYPTION_KEY");
479487
}
480488

481-
const { data: ghAccount, error: ghError } = await supabase
482-
.from("github_accounts")
489+
const { data: platformConnection, error: connectionError } = await supabase
490+
.from("platform_connections")
483491
.select("encrypted_token")
484492
.eq("user_id", job.user_id)
493+
.eq("platform", platform)
485494
.single();
486495

487-
if (ghError || !ghAccount) throw new Error("GitHub account not connected");
496+
if (connectionError || !platformConnection) throw new Error(`${platform} account not connected`);
488497

489498
const githubToken = decryptString(
490-
ghAccount.encrypted_token,
499+
platformConnection.encrypted_token,
491500
config.githubTokenEncryptionKey
492501
);
493502

0 commit comments

Comments
 (0)