@nebulr-group/bridge-svelte 0.3.2 → 0.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/BridgeBootstrap.d.ts +1 -1
- package/dist/client/BridgeBootstrap.js +104 -27
- package/dist/client/BridgeBootstrap.svelte +65 -4
- package/dist/client/BridgeBootstrap.svelte.d.ts +2 -0
- package/dist/client/BridgeProvider.svelte +31 -0
- package/dist/client/BridgeProvider.svelte.d.ts +8 -0
- package/dist/client/components/developer/ApiTokenManagement.svelte +1 -1
- package/dist/client/components/sdk-auth/LoginForm.svelte +10 -7
- package/dist/client/components/sdk-auth/LoginForm.svelte.d.ts +1 -1
- package/dist/client/components/sdk-auth/PasskeyLogin.svelte +1 -1
- package/dist/client/components/sdk-auth/PasskeySetup.svelte +1 -1
- package/dist/client/components/sdk-auth/SsoButton.svelte +1 -1
- package/dist/client/components/sdk-auth/SsoButton.svelte.d.ts +1 -1
- package/dist/client/components/sdk-auth/TenantSelector.svelte +1 -1
- package/dist/client/components/sdk-auth/TenantSelector.svelte.d.ts +1 -1
- package/dist/client/components/sdk-auth/WorkspaceSelector.svelte +3 -3
- package/dist/client/components/sdk-auth/WorkspaceSelector.svelte.d.ts +3 -3
- package/dist/client/components/subscription/BridgeBillingNotice.svelte +389 -0
- package/dist/client/components/subscription/BridgeBillingNotice.svelte.d.ts +19 -0
- package/dist/client/components/subscription/BridgePaywall.svelte +94 -0
- package/dist/client/components/subscription/BridgePaywall.svelte.d.ts +19 -0
- package/dist/client/components/subscription/BridgeQuotaBanner.svelte +275 -0
- package/dist/client/components/subscription/BridgeQuotaBanner.svelte.d.ts +24 -0
- package/dist/client/components/subscription/BridgeSubscriptionStatus.svelte +116 -0
- package/dist/client/components/subscription/BridgeSubscriptionStatus.svelte.d.ts +7 -0
- package/dist/client/components/subscription/PlanSelector.svelte +22 -14
- package/dist/client/components/subscription/PlanSelector.svelte.d.ts +3 -3
- package/dist/client/components/subscription/billing-notice-gate.test.d.ts +1 -0
- package/dist/client/components/subscription/billing-notice-gate.test.js +83 -0
- package/dist/client/components/team/TeamAddUserDialog.svelte +1 -1
- package/dist/client/components/team/TeamAddUserDialog.svelte.d.ts +1 -1
- package/dist/client/components/team/TeamEditUserDialog.svelte +1 -1
- package/dist/client/components/team/TeamEditUserDialog.svelte.d.ts +1 -1
- package/dist/client/components/team/TeamProfileForm.svelte +1 -1
- package/dist/client/components/team/TeamUserList.svelte +1 -1
- package/dist/client/components/team/TeamWorkspaceForm.svelte +1 -1
- package/dist/client/tracking/pii-hashing.spec.js +4 -14
- package/dist/core/bridge-instance.d.ts +1 -2
- package/dist/core/bridge-instance.js +0 -4
- package/dist/core/bridge-runtime.d.ts +101 -0
- package/dist/core/bridge-runtime.js +290 -0
- package/dist/core/bridge-runtime.test.d.ts +1 -0
- package/dist/core/bridge-runtime.test.js +203 -0
- package/dist/core/bridge.d.ts +93 -0
- package/dist/core/bridge.js +108 -0
- package/dist/core/bridge.test.d.ts +1 -0
- package/dist/core/bridge.test.js +224 -0
- package/dist/core/events.d.ts +74 -0
- package/dist/core/events.js +64 -0
- package/dist/core/events.test.d.ts +1 -0
- package/dist/core/events.test.js +116 -0
- package/dist/core/lazy-slice.d.ts +74 -0
- package/dist/core/lazy-slice.js +124 -0
- package/dist/core/lazy-slice.test.d.ts +1 -0
- package/dist/core/lazy-slice.test.js +144 -0
- package/dist/core/realtime-status.d.ts +6 -0
- package/dist/core/realtime-status.js +15 -0
- package/dist/core/snapshot-stores.d.ts +69 -0
- package/dist/core/snapshot-stores.js +64 -0
- package/dist/core/use-bridge.d.ts +13 -0
- package/dist/core/use-bridge.js +46 -0
- package/dist/core/use-bridge.test.d.ts +1 -0
- package/dist/core/use-bridge.test.js +24 -0
- package/dist/flags/FeatureFlag.svelte +57 -0
- package/dist/flags/FeatureFlag.svelte.d.ts +37 -0
- package/dist/flags/bootstrap.d.ts +72 -0
- package/dist/flags/bootstrap.js +323 -0
- package/dist/flags/bootstrap.test.d.ts +1 -0
- package/dist/flags/bootstrap.test.js +195 -0
- package/dist/flags/flag.svelte.d.ts +31 -0
- package/dist/flags/flag.svelte.js +99 -0
- package/dist/flags/index.d.ts +8 -0
- package/dist/flags/index.js +20 -0
- package/dist/flags/index.test.d.ts +1 -0
- package/dist/flags/index.test.js +81 -0
- package/dist/flags/realtime-status.d.ts +1 -0
- package/dist/flags/realtime-status.js +4 -0
- package/dist/flags/registry.d.ts +27 -0
- package/dist/flags/registry.js +63 -0
- package/dist/flags/us13-integration.test.d.ts +1 -0
- package/dist/flags/us13-integration.test.js +168 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.js +31 -2
- package/dist/styles.d.ts +2 -0
- package/package.json +92 -86
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RouteGuardConfig } from '../auth/route-guard.js';
|
|
2
2
|
import { waitForBridge as _waitForBridge } from '../core/bridge-instance.js';
|
|
3
3
|
import type { BridgeConfig } from '../shared/types/config.js';
|
|
4
|
-
export declare function bridgeBootstrap(url: URL, config: BridgeConfig | string, routeConfig?: RouteGuardConfig): Promise<{
|
|
4
|
+
export declare function bridgeBootstrap(url: URL, config: BridgeConfig | string, routeConfig?: RouteGuardConfig, kitFetch?: typeof globalThis.fetch): Promise<{
|
|
5
5
|
flagsReady: Promise<void>;
|
|
6
6
|
} | undefined>;
|
|
7
7
|
export declare const bridgeReady: import("svelte/store").Readable<boolean>;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// src/lib/bridge/bootstrap.ts
|
|
2
|
-
import {
|
|
2
|
+
import { redirect, isRedirect } from '@sveltejs/kit';
|
|
3
3
|
import { get } from 'svelte/store';
|
|
4
4
|
import { createRouteGuard } from '../auth/route-guard.js';
|
|
5
5
|
import { getBridgeAuth, bridgeReadyStore, markReady, waitForBridge as _waitForBridge, } from '../core/bridge-instance.js';
|
|
6
|
+
import { useBridge } from '@nebulr-group/bridge-auth-core';
|
|
6
7
|
import { featureFlags } from '../shared/feature-flag.js';
|
|
7
8
|
import { logger } from '../shared/logger.js';
|
|
8
9
|
import { bridgeConfig, getConfig } from './stores/config.store.js';
|
|
9
|
-
export async function bridgeBootstrap(url, config, routeConfig = { rules: [], defaultAccess: 'protected' }) {
|
|
10
|
+
export async function bridgeBootstrap(url, config, routeConfig = { rules: [], defaultAccess: 'protected' }, kitFetch) {
|
|
10
11
|
// If we've already completed bootstrap once, short-circuit
|
|
11
12
|
if (get(bridgeReadyStore)) {
|
|
12
13
|
return;
|
|
@@ -20,49 +21,85 @@ export async function bridgeBootstrap(url, config, routeConfig = { rules: [], de
|
|
|
20
21
|
}
|
|
21
22
|
// 1. Initialize configuration (synchronously) — this also calls initBridge()
|
|
22
23
|
bridgeConfig.initConfig(finalConfig, routeConfig);
|
|
23
|
-
// 1a.
|
|
24
|
+
// 1a. Unified callback handler — detects what is calling back and routes accordingly
|
|
24
25
|
try {
|
|
25
26
|
const resolvedCallbackUrl = getConfig().callbackUrl;
|
|
26
27
|
const callbackPath = resolvedCallbackUrl ? new URL(resolvedCallbackUrl).pathname : null;
|
|
27
28
|
if (callbackPath && url.pathname === callbackPath) {
|
|
28
|
-
logger.debug('[bridgeBootstrap] callback route detected
|
|
29
|
-
const bridge = getBridgeAuth();
|
|
29
|
+
logger.debug('[bridgeBootstrap] callback route detected');
|
|
30
30
|
const code = url.searchParams.get('code');
|
|
31
|
-
|
|
31
|
+
const sessionId = url.searchParams.get('session_id');
|
|
32
|
+
const stripeSuccess = url.searchParams.has('stripe_success');
|
|
33
|
+
const stripeCancel = url.searchParams.has('stripe_cancel');
|
|
34
|
+
// Strip any session_id Stripe appends to the redirect param destination
|
|
35
|
+
const rawRedirect = url.searchParams.get('redirect') ?? '/subscription';
|
|
36
|
+
const redirectTo = rawRedirect.split('?')[0];
|
|
32
37
|
if (code) {
|
|
38
|
+
// OAuth callback
|
|
39
|
+
const bridge = getBridgeAuth();
|
|
33
40
|
try {
|
|
34
|
-
logger.debug('[bridgeBootstrap] calling handleCallback');
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
logger.debug('[bridgeBootstrap] OAuth callback — calling handleCallback');
|
|
42
|
+
// bridge-auth-core calls history.replaceState to strip ?code= from the URL.
|
|
43
|
+
// SvelteKit intercepts replaceState as a navigation event, cancelling the
|
|
44
|
+
// current load before our redirect can propagate. Use the native prototype
|
|
45
|
+
// method directly so the URL is cleaned up without triggering SvelteKit's
|
|
46
|
+
// navigation interceptor.
|
|
47
|
+
const svelteReplaceState = history.replaceState;
|
|
48
|
+
history.replaceState = History.prototype.replaceState.bind(history);
|
|
49
|
+
try {
|
|
50
|
+
await bridge.handleCallback(code);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
history.replaceState = svelteReplaceState;
|
|
54
|
+
}
|
|
45
55
|
const payment = url.searchParams.get('payment');
|
|
46
|
-
|
|
47
|
-
logger.debug('[bridgeBootstrap] redirecting to', { redirectUrl, payment });
|
|
48
|
-
redirect(303, redirectUrl);
|
|
56
|
+
redirect(303, payment ? `/?payment=${payment}` : '/');
|
|
49
57
|
}
|
|
50
58
|
catch (err) {
|
|
51
|
-
if (isRedirect(err))
|
|
52
|
-
throw err;
|
|
59
|
+
if (isRedirect(err))
|
|
60
|
+
throw err;
|
|
61
|
+
logger.error('[bridgeBootstrap] OAuth callback error:', err);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (stripeSuccess && sessionId) {
|
|
65
|
+
// Stripe payment success — verify with bridge-api (server calls Stripe directly),
|
|
66
|
+
// then refresh tokens so the new JWT has shouldSelectPlan: false before redirect.
|
|
67
|
+
logger.debug('[bridgeBootstrap] Stripe success callback — confirming with bridge-api');
|
|
68
|
+
const bridge = getBridgeAuth();
|
|
69
|
+
const ctx = bridge.getApiContext();
|
|
70
|
+
try {
|
|
71
|
+
const res = await (kitFetch ?? fetch)(`${ctx.apiBaseUrl}/v1/account/stripe/confirm-checkout`, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: { 'Content-Type': 'application/json' },
|
|
74
|
+
body: JSON.stringify({ sessionId, appId: ctx.appId }),
|
|
75
|
+
});
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
logger.warn('[bridgeBootstrap] confirm-checkout failed', res.status);
|
|
78
|
+
redirect(303, getConfig().billing?.paymentErrorRoute ?? '/payment-error');
|
|
53
79
|
}
|
|
54
|
-
|
|
80
|
+
await bridge.refreshTokens();
|
|
81
|
+
redirect(303, redirectTo);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (isRedirect(err))
|
|
85
|
+
throw err;
|
|
86
|
+
logger.warn('[bridgeBootstrap] confirm-checkout error', err);
|
|
87
|
+
redirect(303, getConfig().billing?.paymentErrorRoute ?? '/payment-error');
|
|
55
88
|
}
|
|
56
89
|
}
|
|
90
|
+
else if (stripeCancel) {
|
|
91
|
+
// Stripe payment cancelled
|
|
92
|
+
logger.debug('[bridgeBootstrap] Stripe cancel callback — redirecting to', redirectTo);
|
|
93
|
+
redirect(303, redirectTo);
|
|
94
|
+
}
|
|
57
95
|
else {
|
|
58
|
-
logger.warn('[bridgeBootstrap] callback route
|
|
96
|
+
logger.warn('[bridgeBootstrap] callback route reached with no recognised signal');
|
|
59
97
|
}
|
|
60
98
|
}
|
|
61
99
|
}
|
|
62
100
|
catch (e) {
|
|
63
|
-
if (isRedirect(e))
|
|
64
|
-
throw e;
|
|
65
|
-
}
|
|
101
|
+
if (isRedirect(e))
|
|
102
|
+
throw e;
|
|
66
103
|
logger.warn('[bridgeBootstrap] failed parsing callbackUrl', e);
|
|
67
104
|
}
|
|
68
105
|
// 2. Ensure tokens are fresh if needed
|
|
@@ -75,6 +112,46 @@ export async function bridgeBootstrap(url, config, routeConfig = { rules: [], de
|
|
|
75
112
|
catch {
|
|
76
113
|
// Non-fatal — stale tokens will be caught by route guard
|
|
77
114
|
}
|
|
115
|
+
// 2b. Paywall redirect — fires before any page renders. Reads shouldSelectPlan
|
|
116
|
+
// and paymentsAutoRedirect from getSubscriptionStatus(). Only redirects when:
|
|
117
|
+
// - billing.paywallRoute is configured
|
|
118
|
+
// - the current path is not already the paywall route (no redirect loop)
|
|
119
|
+
// - the tenant is authenticated but has not selected a plan
|
|
120
|
+
// - the app has not opted out via paymentsAutoRedirect: false
|
|
121
|
+
try {
|
|
122
|
+
const paywallRoute = getConfig().billing?.paywallRoute;
|
|
123
|
+
if (paywallRoute && url.pathname !== paywallRoute) {
|
|
124
|
+
const bridge = getBridgeAuth();
|
|
125
|
+
if (bridge.isAuthenticated()) {
|
|
126
|
+
const status = await bridge.getSubscriptionStatus();
|
|
127
|
+
if (status?.shouldSelectPlan === true && status?.paymentsAutoRedirect !== false) {
|
|
128
|
+
logger.debug('[bridgeBootstrap] paywall redirect', paywallRoute);
|
|
129
|
+
redirect(303, paywallRoute);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
if (isRedirect(e))
|
|
136
|
+
throw e;
|
|
137
|
+
// Non-fatal — fail open if subscription fetch errors
|
|
138
|
+
}
|
|
139
|
+
// 2c. Auto-manage billing state so the notice/gate render without the
|
|
140
|
+
// integrator wiring a mount, and `hard` billing route rules can decide.
|
|
141
|
+
try {
|
|
142
|
+
const bridge = getBridgeAuth();
|
|
143
|
+
const ctx = bridge.getApiContext();
|
|
144
|
+
if (ctx.accessToken) {
|
|
145
|
+
await useBridge().subscription.mount({
|
|
146
|
+
apiBaseUrl: ctx.apiBaseUrl,
|
|
147
|
+
accessToken: ctx.accessToken,
|
|
148
|
+
appId: ctx.appId,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Non-fatal — gate fails open; the notice hydrates lazily on first render.
|
|
154
|
+
}
|
|
78
155
|
// 3. Fire flag fetch without awaiting so GQL queries can start in parallel.
|
|
79
156
|
// The flagsReady promise is passed to the guard and returned to callers
|
|
80
157
|
// so routes that need flags can still await before rendering.
|
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { beforeNavigate, goto } from '$app/navigation';
|
|
3
|
-
import { onMount } from 'svelte';
|
|
3
|
+
import { onMount, onDestroy } from 'svelte';
|
|
4
4
|
import { createRouteGuard } from '../auth/route-guard.js';
|
|
5
5
|
import { getBridgeAuth } from '../core/bridge-instance.js';
|
|
6
|
+
import { bridge as bridgeSurface } from '../core/bridge.js';
|
|
7
|
+
import { setBridgeContext } from '../core/use-bridge.js';
|
|
6
8
|
import { getConfig } from './stores/config.store.js';
|
|
9
|
+
import {
|
|
10
|
+
startBridgeRuntime,
|
|
11
|
+
stopBridgeRuntime,
|
|
12
|
+
type StartBridgeRuntimeOptions,
|
|
13
|
+
} from '../core/bridge-runtime.js';
|
|
14
|
+
import { loadSubscription, ensureAppConfig } from '../core/bridge-instance.js';
|
|
7
15
|
|
|
8
|
-
// Props:
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
// Props: optional `runtime` overrides for advanced/debug use (websocketFactory,
|
|
17
|
+
// reconnect overrides, etc.); `onBootstrapComplete` callback fires after the
|
|
18
|
+
// runtime + any auto-detected capabilities (flags) have attached.
|
|
19
|
+
let {
|
|
20
|
+
runtime,
|
|
21
|
+
onBootstrapComplete,
|
|
22
|
+
}: {
|
|
23
|
+
runtime?: StartBridgeRuntimeOptions;
|
|
24
|
+
onBootstrapComplete?: () => void;
|
|
11
25
|
} = $props();
|
|
12
26
|
|
|
27
|
+
// Phase 4 (TBP-288/320) — expose the unified bridge surface via Svelte
|
|
28
|
+
// context so descendants can call `useBridge()`.
|
|
29
|
+
setBridgeContext(bridgeSurface);
|
|
30
|
+
|
|
13
31
|
const guard = createRouteGuard();
|
|
14
32
|
|
|
15
33
|
async function handleRoute(pathname: string, cancel?: () => void) {
|
|
@@ -31,11 +49,54 @@
|
|
|
31
49
|
}
|
|
32
50
|
}
|
|
33
51
|
|
|
52
|
+
// Stash a teardown for the dynamically-attached capabilities (today: flags).
|
|
53
|
+
let _capabilityStop: (() => Promise<void>) | undefined;
|
|
54
|
+
|
|
34
55
|
onMount(async () => {
|
|
56
|
+
// Start the core runtime — realtime client, channel scoping, billing-store
|
|
57
|
+
// attach, session.snapshot fanout, billing-family event dispatch.
|
|
58
|
+
startBridgeRuntime(runtime);
|
|
59
|
+
|
|
60
|
+
// Fetch app config outside load() so we use the correct fetch context.
|
|
61
|
+
// LoginForm also calls ensureAppConfig() — both share the same in-flight promise.
|
|
62
|
+
void ensureAppConfig();
|
|
63
|
+
|
|
64
|
+
// Sync subscription when landing on any page after Stripe checkout success.
|
|
65
|
+
// BridgeBootstrap.ts runs server-side where sessionStorage is unavailable,
|
|
66
|
+
// so we write it here (client onMount) before calling loadSubscription().
|
|
67
|
+
const sessionId = new URLSearchParams(window.location.search).get('session_id');
|
|
68
|
+
if (sessionId) {
|
|
69
|
+
sessionStorage.setItem('bridge_checkout_session_id', sessionId);
|
|
70
|
+
loadSubscription().catch(() => { /* non-fatal */ });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Auto-detect Feature Flags 2.0. If `@nebulr-group/bridge-svelte/flags` is
|
|
74
|
+
// on the dependency graph, attach the flag-specific runtime onto the
|
|
75
|
+
// already-started core (BridgeFlags instance, attribute providers,
|
|
76
|
+
// telemetry, hydrate, reactivity). The dynamic import means auth-only apps
|
|
77
|
+
// never pull the flags bundle.
|
|
78
|
+
try {
|
|
79
|
+
const flagsMod = await import('../flags/bootstrap.js');
|
|
80
|
+
const bundle = flagsMod.createBridgeFlags();
|
|
81
|
+
_capabilityStop = bundle.stop;
|
|
82
|
+
} catch {
|
|
83
|
+
// /flags entry not installed — auth-only app, skip flag attach.
|
|
84
|
+
}
|
|
85
|
+
|
|
35
86
|
// Auth-core manages auto-refresh internally — no startAutoRefresh() needed
|
|
36
87
|
if (onBootstrapComplete) onBootstrapComplete();
|
|
37
88
|
});
|
|
38
89
|
|
|
90
|
+
onDestroy(() => {
|
|
91
|
+
void (async () => {
|
|
92
|
+
if (_capabilityStop) {
|
|
93
|
+
try { await _capabilityStop(); } catch { /* ignore */ }
|
|
94
|
+
_capabilityStop = undefined;
|
|
95
|
+
}
|
|
96
|
+
await stopBridgeRuntime();
|
|
97
|
+
})();
|
|
98
|
+
});
|
|
99
|
+
|
|
39
100
|
beforeNavigate(async ({ to, cancel }) => {
|
|
40
101
|
if (!to) return;
|
|
41
102
|
await handleRoute(to.url.pathname, cancel);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { type StartBridgeRuntimeOptions } from '../core/bridge-runtime.js';
|
|
1
2
|
type $$ComponentProps = {
|
|
3
|
+
runtime?: StartBridgeRuntimeOptions;
|
|
2
4
|
onBootstrapComplete?: () => void;
|
|
3
5
|
};
|
|
4
6
|
declare const BridgeBootstrap: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Phase 4 (TBP-288/320) — minimal context provider for the bridge surface.
|
|
3
|
+
|
|
4
|
+
Wrap your app:
|
|
5
|
+
<BridgeProvider>
|
|
6
|
+
<YourApp />
|
|
7
|
+
</BridgeProvider>
|
|
8
|
+
|
|
9
|
+
Without props, it sets the module-level singleton into context. To override
|
|
10
|
+
(SSR, multi-tenant tests, storybook), pass `{ bridge }`.
|
|
11
|
+
|
|
12
|
+
Distinct from <BridgeBootstrap>: that one orchestrates the full bootstrap
|
|
13
|
+
side effects (OAuth callback, route guards, billing mount). This is just
|
|
14
|
+
a thin context-setting wrapper. The two are composable — wrap
|
|
15
|
+
<BridgeBootstrap> in a <BridgeProvider> if you need both.
|
|
16
|
+
-->
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
import { bridge as singleton } from '../core/bridge.js';
|
|
19
|
+
import { setBridgeContext } from '../core/use-bridge.js';
|
|
20
|
+
import type { BridgeSurface } from '../core/bridge.js';
|
|
21
|
+
|
|
22
|
+
interface Props {
|
|
23
|
+
bridge?: BridgeSurface;
|
|
24
|
+
children?: import('svelte').Snippet;
|
|
25
|
+
}
|
|
26
|
+
const { bridge = singleton, children }: Props = $props();
|
|
27
|
+
|
|
28
|
+
setBridgeContext(bridge);
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
{@render children?.()}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BridgeSurface } from '../core/bridge.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
bridge?: BridgeSurface;
|
|
4
|
+
children?: import('svelte').Snippet;
|
|
5
|
+
}
|
|
6
|
+
declare const BridgeProvider: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type BridgeProvider = ReturnType<typeof BridgeProvider>;
|
|
8
|
+
export default BridgeProvider;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
import { getBridgeAuth } from '../../../core/bridge-instance.js';
|
|
4
|
-
import type { ApiToken, AvailablePrivilege, CreateApiTokenInput } from '@
|
|
4
|
+
import type { ApiToken, AvailablePrivilege, CreateApiTokenInput } from '@nebulr-group/bridge-auth-core';
|
|
5
5
|
|
|
6
6
|
interface Props extends HTMLAttributes<HTMLDivElement> {}
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import type { AppConfig, FederationConnection } from '@
|
|
4
|
+
import type { AppConfig, FederationConnection } from '@nebulr-group/bridge-auth-core';
|
|
5
5
|
import { onMount } from 'svelte';
|
|
6
6
|
import { getBridgeAuth, authState, appConfigStore, ensureAppConfig } from '../../../core/bridge-instance.js';
|
|
7
7
|
import { getConfig } from '../../stores/config.store.js';
|
|
@@ -83,12 +83,15 @@
|
|
|
83
83
|
function buildSsoConnections(appConfig: AppConfig | null): FederationConnection[] {
|
|
84
84
|
if (!appConfig) return [];
|
|
85
85
|
const out: FederationConnection[] = [];
|
|
86
|
-
if (appConfig.googleSsoEnabled)
|
|
87
|
-
if (appConfig.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
if (appConfig.googleSsoEnabled) out.push({ id: 'google', type: 'google', name: 'Google' });
|
|
87
|
+
if (appConfig.azureSsoEnabled) out.push({ id: 'azure', type: 'ms-azure-ad', name: 'Microsoft' });
|
|
88
|
+
// Remaining providers (LinkedIn, GitHub, Facebook, Apple, custom SAML/OIDC)
|
|
89
|
+
// come from the canonical federationConnections list. Skip google/azure so
|
|
90
|
+
// they don't duplicate the built-in toggles above.
|
|
91
|
+
for (const conn of appConfig.federationConnections ?? []) {
|
|
92
|
+
if (conn.type === 'google' || conn.type === 'ms-azure-ad') continue;
|
|
93
|
+
out.push(conn);
|
|
94
|
+
}
|
|
92
95
|
return out;
|
|
93
96
|
}
|
|
94
97
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import type { FederationConnection } from '@
|
|
3
|
+
import type { FederationConnection } from '@nebulr-group/bridge-auth-core';
|
|
4
4
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
5
|
/** Override signup link visibility. Default: derived from app config (signupEnabled). */
|
|
6
6
|
showSignupLink?: boolean | undefined;
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
} else {
|
|
45
45
|
// @ts-ignore — @simplewebauthn/browser is an optional peer dependency
|
|
46
46
|
const mod = await import('@simplewebauthn/browser');
|
|
47
|
-
authResponse = await mod.startAuthentication({ optionsJSON: options, useBrowserAutofill: autofill });
|
|
47
|
+
authResponse = await mod.startAuthentication({ optionsJSON: options as any, useBrowserAutofill: autofill });
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
await getBridgeAuth().authenticateWithPasskey(authResponse);
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
} else {
|
|
59
59
|
// @ts-ignore — @simplewebauthn/browser is an optional peer dependency
|
|
60
60
|
const mod = await import('@simplewebauthn/browser');
|
|
61
|
-
regResponse = await mod.startRegistration({ optionsJSON: options });
|
|
61
|
+
regResponse = await mod.startRegistration({ optionsJSON: options as any });
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const result = await getBridgeAuth().verifyPasskeyRegistration(regResponse, token);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
4
|
-
import type { FederationConnection } from '@
|
|
4
|
+
import type { FederationConnection } from '@nebulr-group/bridge-auth-core';
|
|
5
5
|
import { getBridgeAuth } from '../../../core/bridge-instance.js';
|
|
6
6
|
import Spinner from './shared/Spinner.svelte';
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
-
import type { FederationConnection } from '@
|
|
3
|
+
import type { FederationConnection } from '@nebulr-group/bridge-auth-core';
|
|
4
4
|
interface Props extends HTMLButtonAttributes {
|
|
5
5
|
connection: FederationConnection;
|
|
6
6
|
label?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import type { TenantUser } from '@
|
|
4
|
+
import type { TenantUser } from '@nebulr-group/bridge-auth-core';
|
|
5
5
|
import { getBridgeAuth, tenantUsersStore } from '../../../core/bridge-instance.js';
|
|
6
6
|
import AuthFormWrapper from './shared/AuthFormWrapper.svelte';
|
|
7
7
|
import Spinner from './shared/Spinner.svelte';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import type { TenantUser } from '@
|
|
3
|
+
import type { TenantUser } from '@nebulr-group/bridge-auth-core';
|
|
4
4
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
5
|
onSelect?: () => void;
|
|
6
6
|
onError?: (error: Error) => void;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type {
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
|
-
import type { Workspace } from '@
|
|
4
|
+
import type { Workspace } from '@nebulr-group/bridge-auth-core';
|
|
5
5
|
import { onMount } from 'svelte';
|
|
6
6
|
import { getBridgeAuth, profileStore } from '../../../core/bridge-instance.js';
|
|
7
7
|
import Spinner from './shared/Spinner.svelte';
|
|
8
8
|
import Alert from './shared/Alert.svelte';
|
|
9
9
|
|
|
10
|
-
interface Props extends
|
|
10
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
11
11
|
onSwitch?: () => void;
|
|
12
12
|
onError?: (error: Error) => void;
|
|
13
13
|
workspaceItem?: Snippet<[{ workspace: Workspace; isActive: boolean; isLoading: boolean; onSelect: () => void }]>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { Workspace } from '@
|
|
4
|
-
interface Props extends
|
|
3
|
+
import type { Workspace } from '@nebulr-group/bridge-auth-core';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
5
|
onSwitch?: () => void;
|
|
6
6
|
onError?: (error: Error) => void;
|
|
7
7
|
workspaceItem?: Snippet<[{
|