@every-app/sdk 0.1.13 → 0.1.14
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/shared/bypassGatewayLocalOnly.d.ts +2 -1
- package/dist/shared/bypassGatewayLocalOnly.d.ts.map +1 -1
- package/dist/shared/bypassGatewayLocalOnly.js +6 -2
- package/dist/tanstack/server/authenticateRequest.d.ts +2 -0
- package/dist/tanstack/server/authenticateRequest.d.ts.map +1 -1
- package/dist/tanstack/server/authenticateRequest.js +75 -3
- package/package.json +3 -3
- package/src/cloudflare/getLocalD1Url.ts +0 -64
- package/src/cloudflare/index.ts +0 -1
- package/src/cloudflare/lazyInit.ts +0 -67
- package/src/cloudflare/server/gateway.test.ts +0 -262
- package/src/cloudflare/server/gateway.ts +0 -114
- package/src/cloudflare/server/index.ts +0 -2
- package/src/core/authenticatedFetch.ts +0 -54
- package/src/core/index.ts +0 -12
- package/src/core/sessionManager.test.ts +0 -939
- package/src/core/sessionManager.ts +0 -492
- package/src/env.d.ts +0 -13
- package/src/shared/bypassGatewayLocalOnly.ts +0 -55
- package/src/shared/parseMessagePayload.ts +0 -22
- package/src/tanstack/EmbeddedAppProvider.tsx +0 -96
- package/src/tanstack/GatewayRequiredError.tsx +0 -150
- package/src/tanstack/_internal/useEveryAppSession.test.ts +0 -40
- package/src/tanstack/_internal/useEveryAppSession.tsx +0 -74
- package/src/tanstack/index.ts +0 -3
- package/src/tanstack/server/authConfig.ts +0 -19
- package/src/tanstack/server/authenticateRequest.test.ts +0 -482
- package/src/tanstack/server/authenticateRequest.ts +0 -143
- package/src/tanstack/server/index.ts +0 -3
- package/src/tanstack/server/types.ts +0 -4
- package/src/tanstack/useEveryAppRouter.tsx +0 -83
- package/src/tanstack/useSessionTokenClientMiddleware.ts +0 -43
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { CSSProperties } from "react";
|
|
2
|
-
|
|
3
|
-
interface GatewayRequiredErrorProps {
|
|
4
|
-
/**
|
|
5
|
-
* The origin of the Gateway (e.g., "https://gateway.example.com").
|
|
6
|
-
*/
|
|
7
|
-
gatewayOrigin: string;
|
|
8
|
-
/**
|
|
9
|
-
* The app ID used in the Gateway URL path.
|
|
10
|
-
*/
|
|
11
|
-
appId: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// CSS custom properties for theming
|
|
15
|
-
const CSS_VARIABLES = `
|
|
16
|
-
@media (prefers-color-scheme: light) {
|
|
17
|
-
:root {
|
|
18
|
-
--gateway-bg: oklch(100% 0 0);
|
|
19
|
-
--gateway-text: oklch(0% 0 0);
|
|
20
|
-
--gateway-text-muted: oklch(40% 0 0);
|
|
21
|
-
--gateway-icon-bg: oklch(94% 0 0);
|
|
22
|
-
--gateway-icon-stroke: oklch(80% 0.18 90);
|
|
23
|
-
--gateway-border: oklch(94% 0 0);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
@media (prefers-color-scheme: dark) {
|
|
27
|
-
:root {
|
|
28
|
-
--gateway-bg: #0a0f0d;
|
|
29
|
-
--gateway-text: oklch(92% 0 0);
|
|
30
|
-
--gateway-text-muted: oklch(60% 0 0);
|
|
31
|
-
--gateway-icon-bg: oklch(22% 0 0);
|
|
32
|
-
--gateway-icon-stroke: oklch(85% 0.18 90);
|
|
33
|
-
--gateway-border: oklch(30% 0 0);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
`;
|
|
37
|
-
|
|
38
|
-
const styles = {
|
|
39
|
-
container: {
|
|
40
|
-
display: "flex",
|
|
41
|
-
flexDirection: "column",
|
|
42
|
-
alignItems: "center",
|
|
43
|
-
justifyContent: "center",
|
|
44
|
-
minHeight: "100vh",
|
|
45
|
-
padding: "24px",
|
|
46
|
-
fontFamily:
|
|
47
|
-
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif',
|
|
48
|
-
backgroundColor: "var(--gateway-bg, oklch(100% 0 0))",
|
|
49
|
-
color: "var(--gateway-text, oklch(0% 0 0))",
|
|
50
|
-
colorScheme: "light dark",
|
|
51
|
-
} satisfies CSSProperties,
|
|
52
|
-
content: {
|
|
53
|
-
maxWidth: "520px",
|
|
54
|
-
width: "100%",
|
|
55
|
-
textAlign: "left",
|
|
56
|
-
} satisfies CSSProperties,
|
|
57
|
-
iconContainer: {
|
|
58
|
-
width: "44px",
|
|
59
|
-
height: "44px",
|
|
60
|
-
marginBottom: "16px",
|
|
61
|
-
borderRadius: "0.25rem",
|
|
62
|
-
backgroundColor: "var(--gateway-icon-bg, oklch(94% 0 0))",
|
|
63
|
-
display: "flex",
|
|
64
|
-
alignItems: "center",
|
|
65
|
-
justifyContent: "center",
|
|
66
|
-
border: "1px solid var(--gateway-border, oklch(94% 0 0))",
|
|
67
|
-
} satisfies CSSProperties,
|
|
68
|
-
title: {
|
|
69
|
-
fontSize: "18px",
|
|
70
|
-
fontWeight: 600,
|
|
71
|
-
marginBottom: "8px",
|
|
72
|
-
color: "var(--gateway-text, oklch(0% 0 0))",
|
|
73
|
-
letterSpacing: "-0.01em",
|
|
74
|
-
} satisfies CSSProperties,
|
|
75
|
-
description: {
|
|
76
|
-
fontSize: "14px",
|
|
77
|
-
lineHeight: 1.5,
|
|
78
|
-
color: "var(--gateway-text-muted, oklch(40% 0 0))",
|
|
79
|
-
marginBottom: "20px",
|
|
80
|
-
} satisfies CSSProperties,
|
|
81
|
-
urlText: {
|
|
82
|
-
fontSize: "14px",
|
|
83
|
-
lineHeight: 1.5,
|
|
84
|
-
color: "var(--gateway-text-muted, oklch(40% 0 0))",
|
|
85
|
-
wordBreak: "break-all",
|
|
86
|
-
} satisfies CSSProperties,
|
|
87
|
-
urlLink: {
|
|
88
|
-
color: "rgb(168, 162, 158)",
|
|
89
|
-
textDecoration: "underline",
|
|
90
|
-
textDecorationColor: "rgb(87, 83, 78)",
|
|
91
|
-
textUnderlineOffset: "2px",
|
|
92
|
-
} satisfies CSSProperties,
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Error component displayed when an embedded app is accessed directly
|
|
97
|
-
* instead of through the Every App Gateway.
|
|
98
|
-
*
|
|
99
|
-
* This component informs users that authentication requires accessing
|
|
100
|
-
* the app through the Gateway and provides a link to do so.
|
|
101
|
-
*/
|
|
102
|
-
export function GatewayRequiredError({
|
|
103
|
-
gatewayOrigin,
|
|
104
|
-
appId,
|
|
105
|
-
}: GatewayRequiredErrorProps) {
|
|
106
|
-
const isLocalhost = window.location.hostname === "localhost";
|
|
107
|
-
const gatewayUrl = `${gatewayOrigin}/apps/${appId}${window.location.pathname}${isLocalhost ? "dev" : ""}`;
|
|
108
|
-
|
|
109
|
-
return (
|
|
110
|
-
<div style={styles.container}>
|
|
111
|
-
<style>{CSS_VARIABLES}</style>
|
|
112
|
-
<div style={styles.content}>
|
|
113
|
-
{/* Warning Icon */}
|
|
114
|
-
<div style={styles.iconContainer}>
|
|
115
|
-
<svg
|
|
116
|
-
width="22"
|
|
117
|
-
height="22"
|
|
118
|
-
viewBox="0 0 24 24"
|
|
119
|
-
fill="none"
|
|
120
|
-
stroke="var(--gateway-icon-stroke, oklch(55% 0.22 25))"
|
|
121
|
-
strokeWidth="2"
|
|
122
|
-
strokeLinecap="round"
|
|
123
|
-
strokeLinejoin="round"
|
|
124
|
-
>
|
|
125
|
-
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
|
|
126
|
-
<line x1="12" y1="9" x2="12" y2="13" />
|
|
127
|
-
<line x1="12" y1="17" x2="12.01" y2="17" />
|
|
128
|
-
</svg>
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
{/* Title */}
|
|
132
|
-
<h1 style={styles.title}>Open in Gateway</h1>
|
|
133
|
-
|
|
134
|
-
{/* Description */}
|
|
135
|
-
<p style={styles.description}>
|
|
136
|
-
The Gateway handles sign in and user auth. Access your app from there
|
|
137
|
-
so this works properly.
|
|
138
|
-
</p>
|
|
139
|
-
|
|
140
|
-
{/* URL Link */}
|
|
141
|
-
<p style={styles.urlText}>
|
|
142
|
-
Go to{" "}
|
|
143
|
-
<a href={gatewayUrl} style={styles.urlLink}>
|
|
144
|
-
{gatewayUrl}
|
|
145
|
-
</a>
|
|
146
|
-
</p>
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
);
|
|
150
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { shouldBootstrapSession } from "./useEveryAppSession";
|
|
3
|
-
|
|
4
|
-
describe("shouldBootstrapSession", () => {
|
|
5
|
-
it("returns false for standalone apps without bypass", () => {
|
|
6
|
-
expect(
|
|
7
|
-
shouldBootstrapSession({
|
|
8
|
-
isEmbedded: () => false,
|
|
9
|
-
isBypassGatewayLocalOnly: false,
|
|
10
|
-
}),
|
|
11
|
-
).toBe(false);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it("returns true for embedded apps", () => {
|
|
15
|
-
expect(
|
|
16
|
-
shouldBootstrapSession({
|
|
17
|
-
isEmbedded: () => true,
|
|
18
|
-
isBypassGatewayLocalOnly: false,
|
|
19
|
-
}),
|
|
20
|
-
).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("returns true for local bypass mode", () => {
|
|
24
|
-
expect(
|
|
25
|
-
shouldBootstrapSession({
|
|
26
|
-
isEmbedded: () => false,
|
|
27
|
-
isBypassGatewayLocalOnly: true,
|
|
28
|
-
}),
|
|
29
|
-
).toBe(true);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("does not depend on iframe detection for RN webviews", () => {
|
|
33
|
-
expect(
|
|
34
|
-
shouldBootstrapSession({
|
|
35
|
-
isEmbedded: () => true,
|
|
36
|
-
isBypassGatewayLocalOnly: false,
|
|
37
|
-
}),
|
|
38
|
-
).toBe(true);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
import { SessionManager } from "../../core/sessionManager.js";
|
|
3
|
-
|
|
4
|
-
interface SessionManagerConfig {
|
|
5
|
-
appId: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
interface UseEveryAppSessionParams {
|
|
9
|
-
sessionManagerConfig: SessionManagerConfig;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
type SessionBootstrapGate = Pick<
|
|
13
|
-
SessionManager,
|
|
14
|
-
"isEmbedded" | "isBypassGatewayLocalOnly"
|
|
15
|
-
>;
|
|
16
|
-
|
|
17
|
-
export function shouldBootstrapSession(
|
|
18
|
-
sessionManager: SessionBootstrapGate,
|
|
19
|
-
): boolean {
|
|
20
|
-
// Bootstrapping should happen whenever the app is hosted by a trusted container.
|
|
21
|
-
// This intentionally keys off embedded environment semantics (iframe OR RN WebView),
|
|
22
|
-
// not iframe-only detection, so RN can initialize auth from pushed tokens.
|
|
23
|
-
return sessionManager.isEmbedded() || sessionManager.isBypassGatewayLocalOnly;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function useEveryAppSession({
|
|
27
|
-
sessionManagerConfig,
|
|
28
|
-
}: UseEveryAppSessionParams) {
|
|
29
|
-
const sessionManagerRef = useRef<SessionManager>(null);
|
|
30
|
-
const [sessionTokenState, setSessionTokenState] = useState<
|
|
31
|
-
ReturnType<SessionManager["getTokenState"]>
|
|
32
|
-
>({
|
|
33
|
-
status: "NO_TOKEN",
|
|
34
|
-
token: null,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
if (!sessionManagerRef.current && typeof document !== "undefined") {
|
|
38
|
-
sessionManagerRef.current = new SessionManager(sessionManagerConfig);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const sessionManager = sessionManagerRef.current;
|
|
42
|
-
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
if (!sessionManager) return;
|
|
45
|
-
// Skip token bootstrap when not embedded (unless in demo mode) - the app will show GatewayRequiredError instead
|
|
46
|
-
if (!shouldBootstrapSession(sessionManager)) return;
|
|
47
|
-
|
|
48
|
-
const interval = setInterval(() => {
|
|
49
|
-
setSessionTokenState(sessionManager.getTokenState());
|
|
50
|
-
}, 5000);
|
|
51
|
-
|
|
52
|
-
sessionManager
|
|
53
|
-
.getToken()
|
|
54
|
-
.then(() => {
|
|
55
|
-
setSessionTokenState(sessionManager.getTokenState());
|
|
56
|
-
})
|
|
57
|
-
.catch((err) => {
|
|
58
|
-
console.error("[EmbeddedProvider] Initial token request failed:", err);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
return () => {
|
|
62
|
-
clearInterval(interval);
|
|
63
|
-
};
|
|
64
|
-
}, [sessionManager]);
|
|
65
|
-
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
if (!sessionManager) return;
|
|
68
|
-
|
|
69
|
-
// Make sessionManager globally accessible for middleware
|
|
70
|
-
(window as any).__embeddedSessionManager = sessionManager;
|
|
71
|
-
}, [sessionManager]);
|
|
72
|
-
|
|
73
|
-
return { sessionManager, sessionTokenState };
|
|
74
|
-
}
|
package/src/tanstack/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { AuthConfig } from "./types.js";
|
|
2
|
-
import { env } from "cloudflare:workers";
|
|
3
|
-
import { isBypassGatewayLocalOnlyServer } from "../../shared/bypassGatewayLocalOnly.js";
|
|
4
|
-
|
|
5
|
-
export function getAuthConfig(): AuthConfig {
|
|
6
|
-
const bypassGatewayLocalOnlyEnv = (
|
|
7
|
-
env as { BYPASS_GATEWAY_LOCAL_ONLY?: string }
|
|
8
|
-
).BYPASS_GATEWAY_LOCAL_ONLY;
|
|
9
|
-
const isBypassGatewayLocalOnly =
|
|
10
|
-
import.meta.env.PROD !== true &&
|
|
11
|
-
(bypassGatewayLocalOnlyEnv === "true" ||
|
|
12
|
-
isBypassGatewayLocalOnlyServer() === true);
|
|
13
|
-
const issuer = env.GATEWAY_URL || (isBypassGatewayLocalOnly ? "local" : "");
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
issuer,
|
|
17
|
-
audience: import.meta.env.VITE_APP_ID,
|
|
18
|
-
};
|
|
19
|
-
}
|