From d921d881e043f9076820cccbaca8959698590375 Mon Sep 17 00:00:00 2001 From: Yoav Farhi Date: Mon, 13 Jul 2026 11:05:03 +0300 Subject: [PATCH] fix(auth): deploy auth config with workspace keys --- .../cli/src/core/resources/auth-config/api.ts | 16 ++++- packages/cli/tests/cli/env-token-auth.spec.ts | 61 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/core/resources/auth-config/api.ts b/packages/cli/src/core/resources/auth-config/api.ts index db7410621..b79330744 100644 --- a/packages/cli/src/core/resources/auth-config/api.ts +++ b/packages/cli/src/core/resources/auth-config/api.ts @@ -1,4 +1,5 @@ import type { KyResponse } from "ky"; +import { hasWorkspaceApiKeyAuth } from "@/core/auth/config.js"; import { base44Client } from "@/core/clients/index.js"; import { ApiError, SchemaValidationError } from "@/core/errors.js"; import { getAppContext } from "@/core/project/index.js"; @@ -37,11 +38,24 @@ export async function pushAuthConfigToApi( config: AuthConfig, ): Promise { const { id } = getAppContext(); + const payload = toAuthConfigPayload(config); + + if (hasWorkspaceApiKeyAuth()) { + try { + await base44Client.put(`api/apps/${id}/deployment/auth-configuration`, { + json: payload, + }); + } catch (error) { + throw await ApiError.fromHttpError(error, "updating auth config"); + } + + return config; + } let response: KyResponse; try { response = await base44Client.put(`api/apps/${id}`, { - json: { auth_config: toAuthConfigPayload(config) }, + json: { auth_config: payload }, }); } catch (error) { throw await ApiError.fromHttpError(error, "updating auth config"); diff --git a/packages/cli/tests/cli/env-token-auth.spec.ts b/packages/cli/tests/cli/env-token-auth.spec.ts index 62fb92c18..a5d4c759b 100644 --- a/packages/cli/tests/cli/env-token-auth.spec.ts +++ b/packages/cli/tests/cli/env-token-auth.spec.ts @@ -1,3 +1,5 @@ +import { mkdir, writeFile } from "node:fs/promises"; +import { join } from "node:path"; import { sign } from "jsonwebtoken"; import { describe, expect, it } from "vitest"; import { fixture, setupCLITests } from "./testkit/index.js"; @@ -152,6 +154,65 @@ describe("env credential seeding", () => { t.expectResult(result).toContain("App deployed successfully"); }); + it("pushes auth config through the deployment endpoint with a workspace API key", async () => { + await t.givenProject(fixture("with-entities")); + const authDir = join(t.getTempDir(), "project", "base44", "auth"); + await mkdir(authDir, { recursive: true }); + await writeFile( + join(authDir, "config.jsonc"), + JSON.stringify({ + enableUsernamePassword: true, + enableGoogleLogin: false, + enableMicrosoftLogin: false, + enableFacebookLogin: false, + enableAppleLogin: false, + ssoProviderName: null, + enableSSOLogin: false, + googleOAuthMode: "default", + googleOAuthClientId: null, + useWorkspaceSSO: false, + }), + ); + + const workspaceApiKey = + "b44k_eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; + t.givenEnv({ BASE44_API_KEY: workspaceApiKey }); + t.api.mockEntitiesPush({ + created: ["Customer", "Product"], + updated: [], + deleted: [], + }); + t.api.mockAgentsPush({ created: [], updated: [], deleted: [] }); + + let deploymentAuthConfigBody: unknown; + let deploymentApiKeyHeader: string | undefined; + let genericAppUpdateCalled = false; + t.api.mockRoute( + "PUT", + `/api/apps/${APP_ID}/deployment/auth-configuration`, + (req, res) => { + deploymentAuthConfigBody = req.body; + deploymentApiKeyHeader = req.headers.api_key as string | undefined; + res.status(200).json({ name: "auth_config", hash: "auth-hash" }); + }, + ); + t.api.mockRoute("PUT", `/api/apps/${APP_ID}`, (_req, res) => { + genericAppUpdateCalled = true; + res.status(500).json({ error: "Unexpected generic app update" }); + }); + + const result = await t.run("deploy", "-y"); + + t.expectResult(result).toSucceed(); + expect(deploymentApiKeyHeader).toBe(workspaceApiKey); + expect(deploymentAuthConfigBody).toMatchObject({ + enable_username_password: true, + enable_google_login: false, + }); + expect(deploymentAuthConfigBody).not.toHaveProperty("auth_config"); + expect(genericAppUpdateCalled).toBe(false); + }); + it("ignores a non-workspace BASE44_API_KEY when OAuth auth exists", async () => { await t.givenLoggedInWithProject(fixture("with-entities")); t.givenEnv({ BASE44_API_KEY: "not-a-workspace-key" });