Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/build-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ jobs:
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
NEXT_PUBLIC_DOCS_URL: ${{ secrets.NEXT_PUBLIC_DOCS_URL }}
NEXT_PUBLIC_STREAMS_URL: ${{ secrets.NEXT_PUBLIC_STREAMS_URL }}
NEXT_PUBLIC_ELECTRIC_URL: ${{ secrets.NEXT_PUBLIC_ELECTRIC_URL }}
SENTRY_DSN_DESKTOP: ${{ secrets.SENTRY_DSN_DESKTOP }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SUPERSET_WORKSPACE_NAME: superset
Expand Down
24 changes: 5 additions & 19 deletions .superset/lib/setup/steps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ step_write_env() {
# Each workspace gets a range of 20 ports from its base.
# Offsets: +0 web, +1 api, +2 marketing, +3 admin, +4 docs,
# +5 desktop vite, +6 notifications, +7 streams, +8 streams internal, +9 electric,
# +10 caddy (HTTP/2 reverse proxy for electric-proxy), +11 code inspector, +12 electric-proxy (wrangler dev)
# +10 caddy (HTTP/2 reverse proxy for API electric endpoint), +11 code inspector
local BASE=$SUPERSET_PORT_BASE

# App ports (fixed offsets from base)
Expand All @@ -366,7 +366,6 @@ step_write_env() {
local ELECTRIC_PORT=$((BASE + 9))
local CADDY_ELECTRIC_PORT=$((BASE + 10))
local CODE_INSPECTOR_PORT=$((BASE + 11))
local ELECTRIC_PROXY_PORT=$((BASE + 12))

echo ""
echo "# Workspace Ports (allocated from SUPERSET_PORT_BASE=$BASE, range=20)"
Expand All @@ -383,7 +382,6 @@ step_write_env() {
write_env_var "ELECTRIC_PORT" "$ELECTRIC_PORT"
write_env_var "CADDY_ELECTRIC_PORT" "$CADDY_ELECTRIC_PORT"
write_env_var "CODE_INSPECTOR_PORT" "$CODE_INSPECTOR_PORT"
write_env_var "ELECTRIC_PROXY_PORT" "$ELECTRIC_PROXY_PORT"
echo ""
echo "# Cross-app URLs (overrides from root .env)"
write_env_var "NEXT_PUBLIC_API_URL" "http://localhost:$API_PORT"
Expand All @@ -405,27 +403,16 @@ step_write_env() {
echo "# Electric URLs (overrides from root .env)"
write_env_var "ELECTRIC_URL" "http://localhost:$ELECTRIC_PORT/v1/shape"
echo "# Caddy HTTPS proxy for HTTP/2 (avoids browser 6-connection limit with 10+ SSE streams)"
write_env_var "NEXT_PUBLIC_ELECTRIC_URL" "https://localhost:$CADDY_ELECTRIC_PORT"
write_env_var "NEXT_PUBLIC_ELECTRIC_URL" "https://localhost:$CADDY_ELECTRIC_PORT/api/electric"
} >> .env

success "Workspace .env written"

# Generate Electric proxy .dev.vars for wrangler dev
local api_port="${API_PORT:-3041}"
local electric_port="${ELECTRIC_PORT:-3049}"
{
write_env_var "ELECTRIC_URL" "http://localhost:${electric_port}/v1/shape"
write_env_var "ELECTRIC_SECRET" "${ELECTRIC_SECRET:-local_electric_dev_secret}"
write_env_var "JWKS_URL" "http://localhost:${api_port}/api/auth/jwks"
write_env_var "JWT_ISSUER" "http://localhost:${api_port}"
write_env_var "JWT_AUDIENCE" "http://localhost:${api_port}"
} > apps/electric-proxy/.dev.vars
success "Electric proxy .dev.vars written"

# Generate Caddyfile for HTTP/2 reverse proxy (avoids browser 6-connection limit with Electric SSE streams)
# Caddy proxies to the API server which handles auth and forwards to Electric Docker
cat > Caddyfile <<-CADDYEOF
https://localhost:{\$CADDY_ELECTRIC_PORT} {
reverse_proxy localhost:{\$ELECTRIC_PROXY_PORT} {
reverse_proxy localhost:{\$API_PORT} {
flush_interval -1
}
}
Expand All @@ -449,8 +436,7 @@ step_write_env() {
{ "port": $STREAMS_INTERNAL_PORT, "label": "Streams Internal" },
{ "port": $ELECTRIC_PORT, "label": "Electric" },
{ "port": $CADDY_ELECTRIC_PORT, "label": "Caddy Electric" },
{ "port": $CODE_INSPECTOR_PORT, "label": "Code Inspector" },
{ "port": $ELECTRIC_PROXY_PORT, "label": "Electric Proxy" }
{ "port": $CODE_INSPECTOR_PORT, "label": "Code Inspector" }
]
}
PORTSJSON
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export default defineConfig({
),
"process.env.NEXT_PUBLIC_ELECTRIC_URL": defineEnv(
process.env.NEXT_PUBLIC_ELECTRIC_URL,
"https://electric.superset.sh",
"https://api.superset.sh/api/electric",
),
"process.env.NEXT_PUBLIC_DOCS_URL": defineEnv(
process.env.NEXT_PUBLIC_DOCS_URL,
Expand Down
4 changes: 3 additions & 1 deletion apps/desktop/src/renderer/env.renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ const envSchema = z.object({
.default("development"),
NEXT_PUBLIC_API_URL: z.url().default("https://api.superset.sh"),
NEXT_PUBLIC_WEB_URL: z.url().default("https://app.superset.sh"),
NEXT_PUBLIC_ELECTRIC_URL: z.url().default("https://electric.superset.sh"),
NEXT_PUBLIC_ELECTRIC_URL: z
.url()
.default("https://api.superset.sh/api/electric"),
NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(),
NEXT_PUBLIC_POSTHOG_HOST: z.string().default("https://us.i.posthog.com"),
SENTRY_DSN_DESKTOP: z.string().optional(),
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/renderer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- default-src 'self': Only allow resources from same origin
- script-src 'self' 'wasm-unsafe-eval' https://*.posthog.com: Allow scripts from same origin + WebAssembly (for xterm ImageAddon) + PostHog
- style-src 'self' 'unsafe-inline': Allow styles from same origin + inline (needed for CSS-in-JS)
- connect-src 'self' ws: wss: %NEXT_PUBLIC_API_URL% %NEXT_PUBLIC_ELECTRIC_URL% %NEXT_PUBLIC_STREAMS_URL% https://*.posthog.com https://*.sentry.io sentry-ipc:: Allow WebSocket + API + Electric worker + Streams server + PostHog + Sentry
- connect-src 'self' ws: wss: %NEXT_PUBLIC_API_URL% %NEXT_PUBLIC_ELECTRIC_URL% %NEXT_PUBLIC_STREAMS_URL% https://*.posthog.com https://*.sentry.io sentry-ipc:: Allow WebSocket + API + Electric proxy + Streams server + PostHog + Sentry
- img-src 'self' data: %NEXT_PUBLIC_API_URL% https://*.public.blob.vercel-storage.com https://github.com https://avatars.githubusercontent.com https://models.dev: Allow images from same origin + data URIs + API (Linear image proxy) + Vercel blob storage + GitHub avatars + model provider logos
- font-src 'self': Allow fonts from same origin
-->
Expand Down
2 changes: 0 additions & 2 deletions apps/desktop/src/renderer/lib/auth-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { auth } from "@superset/auth/server";
import {
apiKeyClient,
customSessionClient,
jwtClient,
organizationClient,
} from "better-auth/client/plugins";
import { createAuthClient } from "better-auth/react";
Expand Down Expand Up @@ -32,7 +31,6 @@ export const authClient = createAuthClient({
customSessionClient<typeof auth>(),
stripeClient({ subscription: true }),
apiKeyClient(),
jwtClient(),
],
fetchOptions: {
credentials: "include",
Expand Down
11 changes: 0 additions & 11 deletions apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,6 @@ import { type ReactNode, useEffect, useState } from "react";
import { authClient, setAuthToken } from "renderer/lib/auth-client";
import { electronTrpc } from "../../lib/electron-trpc";

/**
* AuthProvider: Manages token synchronization between memory and encrypted disk storage.
*
* Flow:
* 1. Load token from disk on mount
* 2. If valid (not expired), set in memory and validate session in background
* 3. Render children immediately without blocking on network
*
* Electric JWT tokens are fetched on-demand via async headers in collections.ts
* using authClient.token() from better-auth's JWT plugin.
*/
export function AuthProvider({ children }: { children: ReactNode }) {
const [isHydrated, setIsHydrated] = useState(false);
const { refetch: refetchSession } = authClient.useSession();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { Collection } from "@tanstack/react-db";
import { createCollection } from "@tanstack/react-db";
import { createTRPCProxyClient, httpBatchLink } from "@trpc/client";
import { env } from "renderer/env.renderer";
import { authClient, getAuthToken } from "renderer/lib/auth-client";
import { getAuthToken } from "renderer/lib/auth-client";
import superjson from "superjson";
import { z } from "zod";

Expand Down Expand Up @@ -66,32 +66,27 @@ const apiClient = createTRPCProxyClient<AppRouter>({
],
});

const electricHeaders = {
Authorization: () => {
const token = getAuthToken();
return token ? `Bearer ${token}` : "";
},
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const organizationsCollection = createCollection(
electricCollectionOptions<SelectOrganization>({
id: "organizations",
shapeOptions: {
url: electricUrl,
params: { table: "auth.organizations" },
headers: {
Authorization: async () => {
const { data } = await authClient.token();
return data?.token ? `Bearer ${data.token}` : "";
},
},
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
}),
);

function createOrgCollections(organizationId: string): OrgCollections {
const headers = {
Authorization: async () => {
const { data } = await authClient.token();
return data?.token ? `Bearer ${data.token}` : "";
},
};

const tasks = createCollection(
electricCollectionOptions<SelectTask>({
id: `tasks-${organizationId}`,
Expand All @@ -101,7 +96,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "tasks",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand Down Expand Up @@ -135,7 +130,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "task_statuses",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -151,7 +146,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "projects",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -167,7 +162,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "auth.members",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -183,7 +178,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "auth.users",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -199,7 +194,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "auth.invitations",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -215,7 +210,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "agent_commands",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand Down Expand Up @@ -247,7 +242,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "device_presence",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -263,7 +258,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "integration_connections",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -279,7 +274,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "subscriptions",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand All @@ -295,7 +290,7 @@ function createOrgCollections(organizationId: string): OrgCollections {
table: "auth.apikeys",
organizationId,
},
headers,
headers: electricHeaders,
columnMapper,
},
getKey: (item) => item.id,
Expand Down
6 changes: 4 additions & 2 deletions apps/desktop/vite/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ export function htmlEnvTransformPlugin(): Plugin {
)
.replace(
/%NEXT_PUBLIC_ELECTRIC_URL%/g,
process.env.NEXT_PUBLIC_ELECTRIC_URL ||
"https://electric.superset.sh",
new URL(
process.env.NEXT_PUBLIC_ELECTRIC_URL ||
"https://api.superset.sh/api/electric",
).origin,
)
.replace(
/%NEXT_PUBLIC_STREAMS_URL%/g,
Expand Down
20 changes: 0 additions & 20 deletions apps/electric-proxy/package.json

This file was deleted.

40 changes: 0 additions & 40 deletions apps/electric-proxy/src/auth.ts

This file was deleted.

7 changes: 0 additions & 7 deletions apps/electric-proxy/src/env.ts

This file was deleted.

Loading
Loading