mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-06 15:22:12 +03:00
fix(adobe-firefly): open browser sign-in and resolve provider slug in /login (#9097)
Validated in local merge-train T5 (base49+contributors+pacocartones)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* POST /api/providers/[id]/login
|
||||
*
|
||||
* Web-cookie provider login endpoint. Launches a Playwright browser,
|
||||
* Web-cookie provider login endpoint. Launches a browser,
|
||||
* navigates to the provider's login page, polls for session tokens,
|
||||
* and persists extracted credentials to the provider connection.
|
||||
*/
|
||||
@@ -11,6 +11,15 @@ import { getCachedProviderConnectionById, updateProviderConnection } from "@/lib
|
||||
import { requireManagementAuth } from "@/lib/api/requireManagementAuth";
|
||||
import { sanitizeErrorMessage } from "@omniroute/open-sse/utils/error.ts";
|
||||
|
||||
const ADOBE_FIREFLY_SLUGS = new Set(["adobe-firefly", "firefly"]);
|
||||
|
||||
/** Resolve the provider slug (e.g. "claude-web", "adobe-firefly") from the connection row. */
|
||||
function resolveProviderSlug(connection: Record<string, unknown> | null): string {
|
||||
const raw = connection?.provider;
|
||||
if (typeof raw === "string" && raw.trim()) return raw.trim();
|
||||
return "";
|
||||
}
|
||||
|
||||
// ─── POST: Start login flow ────────────────────────────────────────────────
|
||||
|
||||
export async function POST(
|
||||
@@ -28,22 +37,75 @@ export async function POST(
|
||||
|
||||
const body = await req.json().catch(() => ({}));
|
||||
const timeout = typeof body.timeout === "number" ? body.timeout : undefined;
|
||||
const providerSlug = resolveProviderSlug(provider as Record<string, unknown>);
|
||||
|
||||
try {
|
||||
// Dynamic import — InAppLoginService depends on Playwright (heavy)
|
||||
const { inAppLoginService } = await import(
|
||||
"@omniroute/open-sse/services/inAppLoginService.ts"
|
||||
);
|
||||
// Adobe Firefly is special: the IMS JWT is only ever in the Authorization
|
||||
// header of firefly-3p.ff.adobe.io XHRs (never cookies/localStorage), so
|
||||
// the generic cookie-extraction service cannot capture it. Use a dedicated
|
||||
// Playwright service that intercepts that request instead.
|
||||
if (ADOBE_FIREFLY_SLUGS.has(providerSlug)) {
|
||||
const { startAdobeFireflyBrowserLogin } =
|
||||
await import("@omniroute/open-sse/services/adobeFireflyBrowserLogin.ts");
|
||||
const fireflyResult = await startAdobeFireflyBrowserLogin(timeout);
|
||||
|
||||
const result = await inAppLoginService.startLogin(id, { timeout });
|
||||
if (fireflyResult.success && fireflyResult.credentials) {
|
||||
const credentials = fireflyResult.credentials;
|
||||
try {
|
||||
// Store the JWT in apiKey (where resolveAdobeAccessToken looks first)
|
||||
// and the cookie + access_token in providerSpecificData (camelCase —
|
||||
// updateProviderConnection ignores snake_case keys).
|
||||
const providerSpecificData: Record<string, string> = {};
|
||||
if (credentials.accessToken) {
|
||||
providerSpecificData.access_token = credentials.accessToken;
|
||||
}
|
||||
if (credentials.cookie) {
|
||||
providerSpecificData.cookie = credentials.cookie;
|
||||
}
|
||||
|
||||
await updateProviderConnection(id, {
|
||||
apiKey: credentials.accessToken || "",
|
||||
providerSpecificData,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
accessToken: credentials.accessToken || "",
|
||||
cookie: credentials.cookie || "",
|
||||
account: fireflyResult.account || "",
|
||||
credentials: providerSpecificData,
|
||||
persisted: true,
|
||||
});
|
||||
} catch (err) {
|
||||
const msg = sanitizeErrorMessage(err instanceof Error ? err.message : err);
|
||||
return NextResponse.json(
|
||||
{ success: false, error: `Extracted but failed to persist: ${msg}` },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ success: false, error: fireflyResult.error || "Adobe Firefly sign-in failed" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Generic web-cookie path: pass the provider SLUG (not the DB id) so
|
||||
// TOKEN_EXTRACTION_CONFIGS can find the extraction config.
|
||||
// Bug: the previous code passed `id` (connection UUID), so the lookup always
|
||||
// missed and returned "No extraction config" without launching a browser.
|
||||
const { inAppLoginService } = await import("@omniroute/open-sse/services/inAppLoginService.ts");
|
||||
|
||||
const result = await inAppLoginService.startLogin(providerSlug || id, { timeout });
|
||||
|
||||
// Persist credentials if extraction succeeded
|
||||
if (result.success && result.credentials) {
|
||||
try {
|
||||
const credentialsStr = JSON.stringify(result.credentials);
|
||||
await updateProviderConnection(id, {
|
||||
api_key: credentialsStr,
|
||||
provider_specific_data: result.credentials,
|
||||
apiKey: credentialsStr,
|
||||
providerSpecificData: result.credentials,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
|
||||
Reference in New Issue
Block a user