zudoku 0.78.1 → 0.79.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/cli/cli.js +2 -1
- package/package.json +1 -1
- package/src/app/entry.client.tsx +3 -1
- package/src/app/entry.server.tsx +26 -21
- package/src/app/main.tsx +2 -1
- package/src/lib/authentication/state.ts +5 -5
- package/src/vite/config.ts +1 -0
- package/src/vite-env.d.ts +1 -0
package/dist/cli/cli.js
CHANGED
|
@@ -3853,7 +3853,7 @@ import {
|
|
|
3853
3853
|
// package.json
|
|
3854
3854
|
var package_default = {
|
|
3855
3855
|
name: "zudoku",
|
|
3856
|
-
version: "0.78.
|
|
3856
|
+
version: "0.78.1",
|
|
3857
3857
|
type: "module",
|
|
3858
3858
|
sideEffects: [
|
|
3859
3859
|
"**/*.css",
|
|
@@ -7786,6 +7786,7 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7786
7786
|
"process.env.ZUDOKU_VERSION": JSON.stringify(package_default.version),
|
|
7787
7787
|
"process.env.IS_ZUPLO": ZuploEnv.isZuplo,
|
|
7788
7788
|
"import.meta.env.IS_ZUPLO": ZuploEnv.isZuplo,
|
|
7789
|
+
"import.meta.env.ZUDOKU_HAS_SERVER": JSON.stringify(options.ssr === true),
|
|
7789
7790
|
"import.meta.env.ZUPLO_PUBLIC_DEPLOYMENT_NAME": JSON.stringify(deploymentName),
|
|
7790
7791
|
...defineEnvVars([
|
|
7791
7792
|
"SENTRY_DSN",
|
package/package.json
CHANGED
package/src/app/entry.client.tsx
CHANGED
|
@@ -13,7 +13,9 @@ import { BootstrapClient } from "../lib/components/Bootstrap.js";
|
|
|
13
13
|
import { joinUrl } from "../lib/util/joinUrl.js";
|
|
14
14
|
import { getRoutesByConfig, shikiReady } from "./main.js";
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
if (import.meta.env.ZUDOKU_HAS_SERVER) {
|
|
17
|
+
setupCookieSync(authState, joinUrl(config.basePath, "/__z/auth/session"));
|
|
18
|
+
}
|
|
17
19
|
|
|
18
20
|
const routes = getRoutesByConfig(config);
|
|
19
21
|
// biome-ignore lint/style/noNonNullAssertion: We know the root element exists
|
package/src/app/entry.server.tsx
CHANGED
|
@@ -54,6 +54,31 @@ const safeSerialize = (data: unknown) =>
|
|
|
54
54
|
.replace(/\u2028/g, "\\u2028")
|
|
55
55
|
.replace(/\u2029/g, "\\u2029");
|
|
56
56
|
|
|
57
|
+
// Profile must come from the verifier so a forged cookie can't render
|
|
58
|
+
// protected HTML. SSG has no runtime cookie and short-circuits.
|
|
59
|
+
const resolveSsrAuth = async (
|
|
60
|
+
request: Request,
|
|
61
|
+
): Promise<SSRAuthState | undefined> => {
|
|
62
|
+
if (!import.meta.env.ZUDOKU_HAS_SERVER || !configuredAuthProvider) return;
|
|
63
|
+
|
|
64
|
+
const { accessToken } = parseCookies(request);
|
|
65
|
+
if (!accessToken || !verifier)
|
|
66
|
+
return { accessToken: undefined, profile: null };
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const verified = await verifier(accessToken);
|
|
70
|
+
return verified
|
|
71
|
+
? { accessToken, profile: verified.profile }
|
|
72
|
+
: { accessToken: undefined, profile: null };
|
|
73
|
+
} catch (error) {
|
|
74
|
+
logger.error(
|
|
75
|
+
`SSR auth verifier error (${request.method} ${request.url}):`,
|
|
76
|
+
error,
|
|
77
|
+
);
|
|
78
|
+
return { accessToken: undefined, profile: null };
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
57
82
|
// Statically importing shiki.ts here ensures it's in the SSR bundle.
|
|
58
83
|
// main.tsx dynamically imports it instead to enable lazy loading on the client.
|
|
59
84
|
await import("virtual:zudoku-shiki-register").then(
|
|
@@ -75,27 +100,7 @@ export const handleRequest = async ({
|
|
|
75
100
|
basePath?: string;
|
|
76
101
|
bypassProtection?: boolean;
|
|
77
102
|
}): Promise<Response> => {
|
|
78
|
-
const
|
|
79
|
-
// Always derive profile from the verifier, never trust the client cookie.
|
|
80
|
-
// An unverified profile would let a stale/forged cookie render protected HTML.
|
|
81
|
-
let verifiedProfile: SSRAuthState["profile"] = null;
|
|
82
|
-
if (accessToken && verifier) {
|
|
83
|
-
try {
|
|
84
|
-
const verified = await verifier(accessToken);
|
|
85
|
-
if (verified) verifiedProfile = verified.profile;
|
|
86
|
-
} catch (error) {
|
|
87
|
-
logger.error(
|
|
88
|
-
`SSR auth verifier error (${request.method} ${request.url}):`,
|
|
89
|
-
error,
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
const ssrAuth: SSRAuthState | undefined = configuredAuthProvider
|
|
94
|
-
? {
|
|
95
|
-
accessToken: verifiedProfile ? accessToken : undefined,
|
|
96
|
-
profile: verifiedProfile,
|
|
97
|
-
}
|
|
98
|
-
: undefined;
|
|
103
|
+
const ssrAuth = await resolveSsrAuth(request);
|
|
99
104
|
|
|
100
105
|
// No-op lazy() on protected subtrees for unauthed requests so loaders
|
|
101
106
|
// don't run for a 401 render.
|
package/src/app/main.tsx
CHANGED
|
@@ -151,8 +151,9 @@ export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
|
|
|
151
151
|
</Meta>
|
|
152
152
|
),
|
|
153
153
|
errorElement: <RouterError />,
|
|
154
|
+
// Chunk-gate protected routes only in SSR; SSG has no 401 to avoid.
|
|
154
155
|
children:
|
|
155
|
-
typeof window === "undefined"
|
|
156
|
+
typeof window === "undefined" || !import.meta.env.ZUDOKU_HAS_SERVER
|
|
156
157
|
? processRoutes(routes)
|
|
157
158
|
: wrapProtectedRoutes(
|
|
158
159
|
processRoutes(routes),
|
|
@@ -49,11 +49,11 @@ const noopStorage: StateStorage = {
|
|
|
49
49
|
const ssrAuthInitial =
|
|
50
50
|
typeof window !== "undefined" ? window.ZUDOKU_SSR_AUTH : undefined;
|
|
51
51
|
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
// (
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
// SSR builds use cookies as the source of truth; SSG uses localStorage.
|
|
53
|
+
// `import.meta.env` is missing when this module is loaded outside a Vite
|
|
54
|
+
// build (e.g. esbuild bundling a vite.*.config.ts), so guard the access.
|
|
55
|
+
const ssrMode =
|
|
56
|
+
typeof import.meta.env !== "undefined" && import.meta.env.ZUDOKU_HAS_SERVER;
|
|
57
57
|
|
|
58
58
|
export const authState = create<AuthState>()(
|
|
59
59
|
persist(
|
package/src/vite/config.ts
CHANGED
|
@@ -123,6 +123,7 @@ export async function getViteConfig(
|
|
|
123
123
|
"process.env.ZUDOKU_VERSION": JSON.stringify(packageJson.version),
|
|
124
124
|
"process.env.IS_ZUPLO": ZuploEnv.isZuplo,
|
|
125
125
|
"import.meta.env.IS_ZUPLO": ZuploEnv.isZuplo,
|
|
126
|
+
"import.meta.env.ZUDOKU_HAS_SERVER": JSON.stringify(options.ssr === true),
|
|
126
127
|
"import.meta.env.ZUPLO_PUBLIC_DEPLOYMENT_NAME":
|
|
127
128
|
JSON.stringify(deploymentName),
|
|
128
129
|
...defineEnvVars([
|