@hexclave/js 1.0.116 → 1.0.118
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/esm/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.js +3 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.js +3 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/package.json +2 -2
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.ts +6 -2
|
@@ -15,6 +15,7 @@ vi.mock("../../../cookie", () => {
|
|
|
15
15
|
else serverCookieState.values.set(name, value);
|
|
16
16
|
};
|
|
17
17
|
const helper = {
|
|
18
|
+
identity: {},
|
|
18
19
|
get: (name) => serverCookieState.values.get(name) ?? null,
|
|
19
20
|
getAll,
|
|
20
21
|
set: (name, value) => setOrDelete(name, value),
|
|
@@ -66,6 +67,7 @@ describe("StackClientApp custom refresh cookie updates", () => {
|
|
|
66
67
|
return domain === "_.example.com" ? "example.com" : null;
|
|
67
68
|
});
|
|
68
69
|
const tokenStore = Reflect.get(clientApp, "_getOrCreateTokenStore").call(clientApp, {
|
|
70
|
+
identity: {},
|
|
69
71
|
get: (name) => serverCookieState.values.get(name) ?? null,
|
|
70
72
|
getAll: () => Object.fromEntries(serverCookieState.values),
|
|
71
73
|
set: (name, value) => serverCookieState.values.set(name, value),
|
|
@@ -126,6 +128,7 @@ describe("StackClientApp custom refresh cookie updates", () => {
|
|
|
126
128
|
return domain === "_.example.com" ? "example.com" : null;
|
|
127
129
|
});
|
|
128
130
|
const tokenStore = Reflect.get(clientApp, "_getOrCreateTokenStore").call(clientApp, {
|
|
131
|
+
identity: {},
|
|
129
132
|
get: (name) => serverCookieState.values.get(name) ?? null,
|
|
130
133
|
getAll: () => Object.fromEntries(serverCookieState.values),
|
|
131
134
|
set: (name, value) => serverCookieState.values.set(name, value),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-app-impl.cookie.test.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it, vi } from \"vitest\";\nimport { encodeBase32 } from \"@hexclave/shared/dist/utils/bytes\";\nimport { getTrustedParentDomain } from \"@hexclave/shared/dist/utils/redirect-urls\";\nimport { TextEncoder } from \"util\";\nimport { StackClientApp } from \"../interfaces/client-app\";\n\nconst serverCookieState = vi.hoisted(() => ({\n values: new Map<string, string>(),\n}));\n\nvi.mock(\"../../../cookie\", () => {\n const getAll = () => Object.fromEntries(serverCookieState.values);\n const remove = (name: string) => {\n serverCookieState.values.delete(name);\n };\n const setOrDelete = (name: string, value: string | null) => {\n if (value === null) {\n remove(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n };\n const helper = {\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll,\n set: (name: string, value: string) => setOrDelete(name, value),\n setOrDelete,\n delete: remove,\n };\n return {\n createBrowserCookieHelper: () => helper,\n createCookieHelper: async () => helper,\n createPlaceholderCookieHelper: async () => helper,\n deleteCookie: async (name: string) => remove(name),\n deleteCookieClient: remove,\n getCookieClient: (name: string) => serverCookieState.values.get(name) ?? null,\n isSecure: async () => true,\n saveVerifierAndState: async () => {\n throw new Error(\"saveVerifierAndState is not used in this test\");\n },\n setOrDeleteCookie: async (name: string, value: string | null) => setOrDelete(name, value),\n setOrDeleteCookieClient: setOrDelete,\n };\n});\n\ndescribe(\"StackClientApp custom refresh cookie updates\", () => {\n it(\"preserves the existing custom and default cookies without a server hostname\", async () => {\n expect(getTrustedParentDomain(\"_.example.com\", [\"https://example.com\", \"https://**.example.com\"])).toBe(\"example.com\");\n const projectId = \"00000000-0000-4000-8000-000000000000\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n const trustedParentLookups: string[] = [];\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n trustedParentLookups.push(domain);\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper = {\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n const warnSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n tokenStore.set({ accessToken: \"new-access\", refreshToken: \"new-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect.soft(warnSpy).not.toHaveBeenCalled();\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect.soft(customCookieValue).toBeDefined();\n if (customCookieValue != null) {\n expect.soft(JSON.parse(customCookieValue)).toEqual({\n refresh_token: \"new-refresh\",\n updated_at_millis: expect.any(Number),\n });\n }\n expect.soft(serverCookieState.values.has(defaultCookieName)).toBe(true);\n expect.soft(trustedParentLookups).toEqual([\"_.example.com\"]);\n warnSpy.mockRestore();\n });\n\n it(\"recovers the custom cookie after overlapping server updates\", async () => {\n const projectId = \"00000000-0000-4000-8000-000000000001\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n let releaseTrustedParentLookup: (() => void) | undefined;\n let shouldBlockTrustedParentLookup = true;\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n if (shouldBlockTrustedParentLookup) {\n shouldBlockTrustedParentLookup = false;\n await new Promise<void>((resolve) => {\n releaseTrustedParentLookup = resolve;\n });\n }\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper = {\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n\n tokenStore.set({ accessToken: \"first-access\", refreshToken: \"first-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n if (releaseTrustedParentLookup == null) {\n throw new Error(\"Expected the first custom cookie recovery lookup to be pending.\");\n }\n tokenStore.set({ accessToken: \"second-access\", refreshToken: \"second-refresh\" });\n releaseTrustedParentLookup();\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect(customCookieValue).toBeDefined();\n if (customCookieValue == null) {\n throw new Error(\"Expected the custom refresh cookie to be recovered.\");\n }\n expect(JSON.parse(customCookieValue)).toMatchObject({\n refresh_token: \"second-refresh\",\n updated_at_millis: expect.any(Number),\n });\n expect(serverCookieState.values.has(defaultCookieName)).toBe(true);\n });\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client-app-impl.cookie.test.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it, vi } from \"vitest\";\nimport { encodeBase32 } from \"@hexclave/shared/dist/utils/bytes\";\nimport { getTrustedParentDomain } from \"@hexclave/shared/dist/utils/redirect-urls\";\nimport { TextEncoder } from \"util\";\nimport type { CookieHelper } from \"../../../cookie\";\nimport { StackClientApp } from \"../interfaces/client-app\";\n\nconst serverCookieState = vi.hoisted(() => ({\n values: new Map<string, string>(),\n}));\n\nvi.mock(\"../../../cookie\", () => {\n const getAll = () => Object.fromEntries(serverCookieState.values);\n const remove = (name: string) => {\n serverCookieState.values.delete(name);\n };\n const setOrDelete = (name: string, value: string | null) => {\n if (value === null) {\n remove(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n };\n const helper = {\n identity: {},\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll,\n set: (name: string, value: string) => setOrDelete(name, value),\n setOrDelete,\n delete: remove,\n };\n return {\n createBrowserCookieHelper: () => helper,\n createCookieHelper: async () => helper,\n createPlaceholderCookieHelper: async () => helper,\n deleteCookie: async (name: string) => remove(name),\n deleteCookieClient: remove,\n getCookieClient: (name: string) => serverCookieState.values.get(name) ?? null,\n isSecure: async () => true,\n saveVerifierAndState: async () => {\n throw new Error(\"saveVerifierAndState is not used in this test\");\n },\n setOrDeleteCookie: async (name: string, value: string | null) => setOrDelete(name, value),\n setOrDeleteCookieClient: setOrDelete,\n };\n});\n\ndescribe(\"StackClientApp custom refresh cookie updates\", () => {\n it(\"preserves the existing custom and default cookies without a server hostname\", async () => {\n expect(getTrustedParentDomain(\"_.example.com\", [\"https://example.com\", \"https://**.example.com\"])).toBe(\"example.com\");\n const projectId = \"00000000-0000-4000-8000-000000000000\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n const trustedParentLookups: string[] = [];\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n trustedParentLookups.push(domain);\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper: CookieHelper = {\n identity: {},\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n const warnSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n tokenStore.set({ accessToken: \"new-access\", refreshToken: \"new-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect.soft(warnSpy).not.toHaveBeenCalled();\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect.soft(customCookieValue).toBeDefined();\n if (customCookieValue != null) {\n expect.soft(JSON.parse(customCookieValue)).toEqual({\n refresh_token: \"new-refresh\",\n updated_at_millis: expect.any(Number),\n });\n }\n expect.soft(serverCookieState.values.has(defaultCookieName)).toBe(true);\n expect.soft(trustedParentLookups).toEqual([\"_.example.com\"]);\n warnSpy.mockRestore();\n });\n\n it(\"recovers the custom cookie after overlapping server updates\", async () => {\n const projectId = \"00000000-0000-4000-8000-000000000001\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n let releaseTrustedParentLookup: (() => void) | undefined;\n let shouldBlockTrustedParentLookup = true;\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n if (shouldBlockTrustedParentLookup) {\n shouldBlockTrustedParentLookup = false;\n await new Promise<void>((resolve) => {\n releaseTrustedParentLookup = resolve;\n });\n }\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper: CookieHelper = {\n identity: {},\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n\n tokenStore.set({ accessToken: \"first-access\", refreshToken: \"first-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n if (releaseTrustedParentLookup == null) {\n throw new Error(\"Expected the first custom cookie recovery lookup to be pending.\");\n }\n tokenStore.set({ accessToken: \"second-access\", refreshToken: \"second-refresh\" });\n releaseTrustedParentLookup();\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect(customCookieValue).toBeDefined();\n if (customCookieValue == null) {\n throw new Error(\"Expected the custom refresh cookie to be recovered.\");\n }\n expect(JSON.parse(customCookieValue)).toMatchObject({\n refresh_token: \"second-refresh\",\n updated_at_millis: expect.any(Number),\n });\n expect(serverCookieState.values.has(defaultCookieName)).toBe(true);\n });\n});\n"],"mappings":"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"}
|
|
@@ -12,8 +12,8 @@ import { resolveHandlerUrls } from "../../url-targets.js";
|
|
|
12
12
|
import { AsyncCache } from "@hexclave/shared/dist/utils/caches";
|
|
13
13
|
import { createGlobal, getGlobal } from "@hexclave/shared/dist/utils/globals";
|
|
14
14
|
//#region src/lib/hexclave-app/apps/implementations/common.ts
|
|
15
|
-
const clientVersion = "js @hexclave/js@1.0.
|
|
16
|
-
if ("js @hexclave/js@1.0.
|
|
15
|
+
const clientVersion = "js @hexclave/js@1.0.118";
|
|
16
|
+
if ("js @hexclave/js@1.0.118".startsWith("STACK_COMPILE_TIME"));
|
|
17
17
|
const replaceHexclavePortPrefix = (input) => {
|
|
18
18
|
if (!input) return input;
|
|
19
19
|
const prefix = envVars.HEXCLAVE_PORT_PREFIX;
|
|
@@ -15,6 +15,7 @@ vitest.vi.mock("../../../cookie", () => {
|
|
|
15
15
|
else serverCookieState.values.set(name, value);
|
|
16
16
|
};
|
|
17
17
|
const helper = {
|
|
18
|
+
identity: {},
|
|
18
19
|
get: (name) => serverCookieState.values.get(name) ?? null,
|
|
19
20
|
getAll,
|
|
20
21
|
set: (name, value) => setOrDelete(name, value),
|
|
@@ -66,6 +67,7 @@ vitest.vi.mock("../../../cookie", () => {
|
|
|
66
67
|
return domain === "_.example.com" ? "example.com" : null;
|
|
67
68
|
});
|
|
68
69
|
const tokenStore = Reflect.get(clientApp, "_getOrCreateTokenStore").call(clientApp, {
|
|
70
|
+
identity: {},
|
|
69
71
|
get: (name) => serverCookieState.values.get(name) ?? null,
|
|
70
72
|
getAll: () => Object.fromEntries(serverCookieState.values),
|
|
71
73
|
set: (name, value) => serverCookieState.values.set(name, value),
|
|
@@ -126,6 +128,7 @@ vitest.vi.mock("../../../cookie", () => {
|
|
|
126
128
|
return domain === "_.example.com" ? "example.com" : null;
|
|
127
129
|
});
|
|
128
130
|
const tokenStore = Reflect.get(clientApp, "_getOrCreateTokenStore").call(clientApp, {
|
|
131
|
+
identity: {},
|
|
129
132
|
get: (name) => serverCookieState.values.get(name) ?? null,
|
|
130
133
|
getAll: () => Object.fromEntries(serverCookieState.values),
|
|
131
134
|
set: (name, value) => serverCookieState.values.set(name, value),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-app-impl.cookie.test.js","names":["vi","TextEncoder","StackClientApp","expect"],"sources":["../../../../../src/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it, vi } from \"vitest\";\nimport { encodeBase32 } from \"@hexclave/shared/dist/utils/bytes\";\nimport { getTrustedParentDomain } from \"@hexclave/shared/dist/utils/redirect-urls\";\nimport { TextEncoder } from \"util\";\nimport { StackClientApp } from \"../interfaces/client-app\";\n\nconst serverCookieState = vi.hoisted(() => ({\n values: new Map<string, string>(),\n}));\n\nvi.mock(\"../../../cookie\", () => {\n const getAll = () => Object.fromEntries(serverCookieState.values);\n const remove = (name: string) => {\n serverCookieState.values.delete(name);\n };\n const setOrDelete = (name: string, value: string | null) => {\n if (value === null) {\n remove(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n };\n const helper = {\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll,\n set: (name: string, value: string) => setOrDelete(name, value),\n setOrDelete,\n delete: remove,\n };\n return {\n createBrowserCookieHelper: () => helper,\n createCookieHelper: async () => helper,\n createPlaceholderCookieHelper: async () => helper,\n deleteCookie: async (name: string) => remove(name),\n deleteCookieClient: remove,\n getCookieClient: (name: string) => serverCookieState.values.get(name) ?? null,\n isSecure: async () => true,\n saveVerifierAndState: async () => {\n throw new Error(\"saveVerifierAndState is not used in this test\");\n },\n setOrDeleteCookie: async (name: string, value: string | null) => setOrDelete(name, value),\n setOrDeleteCookieClient: setOrDelete,\n };\n});\n\ndescribe(\"StackClientApp custom refresh cookie updates\", () => {\n it(\"preserves the existing custom and default cookies without a server hostname\", async () => {\n expect(getTrustedParentDomain(\"_.example.com\", [\"https://example.com\", \"https://**.example.com\"])).toBe(\"example.com\");\n const projectId = \"00000000-0000-4000-8000-000000000000\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n const trustedParentLookups: string[] = [];\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n trustedParentLookups.push(domain);\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper = {\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n const warnSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n tokenStore.set({ accessToken: \"new-access\", refreshToken: \"new-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect.soft(warnSpy).not.toHaveBeenCalled();\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect.soft(customCookieValue).toBeDefined();\n if (customCookieValue != null) {\n expect.soft(JSON.parse(customCookieValue)).toEqual({\n refresh_token: \"new-refresh\",\n updated_at_millis: expect.any(Number),\n });\n }\n expect.soft(serverCookieState.values.has(defaultCookieName)).toBe(true);\n expect.soft(trustedParentLookups).toEqual([\"_.example.com\"]);\n warnSpy.mockRestore();\n });\n\n it(\"recovers the custom cookie after overlapping server updates\", async () => {\n const projectId = \"00000000-0000-4000-8000-000000000001\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n let releaseTrustedParentLookup: (() => void) | undefined;\n let shouldBlockTrustedParentLookup = true;\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n if (shouldBlockTrustedParentLookup) {\n shouldBlockTrustedParentLookup = false;\n await new Promise<void>((resolve) => {\n releaseTrustedParentLookup = resolve;\n });\n }\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper = {\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n\n tokenStore.set({ accessToken: \"first-access\", refreshToken: \"first-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n if (releaseTrustedParentLookup == null) {\n throw new Error(\"Expected the first custom cookie recovery lookup to be pending.\");\n }\n tokenStore.set({ accessToken: \"second-access\", refreshToken: \"second-refresh\" });\n releaseTrustedParentLookup();\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect(customCookieValue).toBeDefined();\n if (customCookieValue == null) {\n throw new Error(\"Expected the custom refresh cookie to be recovered.\");\n }\n expect(JSON.parse(customCookieValue)).toMatchObject({\n refresh_token: \"second-refresh\",\n updated_at_millis: expect.any(Number),\n });\n expect(serverCookieState.values.has(defaultCookieName)).toBe(true);\n });\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client-app-impl.cookie.test.js","names":["vi","TextEncoder","StackClientApp","expect"],"sources":["../../../../../src/lib/hexclave-app/apps/implementations/client-app-impl.cookie.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it, vi } from \"vitest\";\nimport { encodeBase32 } from \"@hexclave/shared/dist/utils/bytes\";\nimport { getTrustedParentDomain } from \"@hexclave/shared/dist/utils/redirect-urls\";\nimport { TextEncoder } from \"util\";\nimport type { CookieHelper } from \"../../../cookie\";\nimport { StackClientApp } from \"../interfaces/client-app\";\n\nconst serverCookieState = vi.hoisted(() => ({\n values: new Map<string, string>(),\n}));\n\nvi.mock(\"../../../cookie\", () => {\n const getAll = () => Object.fromEntries(serverCookieState.values);\n const remove = (name: string) => {\n serverCookieState.values.delete(name);\n };\n const setOrDelete = (name: string, value: string | null) => {\n if (value === null) {\n remove(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n };\n const helper = {\n identity: {},\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll,\n set: (name: string, value: string) => setOrDelete(name, value),\n setOrDelete,\n delete: remove,\n };\n return {\n createBrowserCookieHelper: () => helper,\n createCookieHelper: async () => helper,\n createPlaceholderCookieHelper: async () => helper,\n deleteCookie: async (name: string) => remove(name),\n deleteCookieClient: remove,\n getCookieClient: (name: string) => serverCookieState.values.get(name) ?? null,\n isSecure: async () => true,\n saveVerifierAndState: async () => {\n throw new Error(\"saveVerifierAndState is not used in this test\");\n },\n setOrDeleteCookie: async (name: string, value: string | null) => setOrDelete(name, value),\n setOrDeleteCookieClient: setOrDelete,\n };\n});\n\ndescribe(\"StackClientApp custom refresh cookie updates\", () => {\n it(\"preserves the existing custom and default cookies without a server hostname\", async () => {\n expect(getTrustedParentDomain(\"_.example.com\", [\"https://example.com\", \"https://**.example.com\"])).toBe(\"example.com\");\n const projectId = \"00000000-0000-4000-8000-000000000000\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n const trustedParentLookups: string[] = [];\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n trustedParentLookups.push(domain);\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper: CookieHelper = {\n identity: {},\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n const warnSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n tokenStore.set({ accessToken: \"new-access\", refreshToken: \"new-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect.soft(warnSpy).not.toHaveBeenCalled();\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect.soft(customCookieValue).toBeDefined();\n if (customCookieValue != null) {\n expect.soft(JSON.parse(customCookieValue)).toEqual({\n refresh_token: \"new-refresh\",\n updated_at_millis: expect.any(Number),\n });\n }\n expect.soft(serverCookieState.values.has(defaultCookieName)).toBe(true);\n expect.soft(trustedParentLookups).toEqual([\"_.example.com\"]);\n warnSpy.mockRestore();\n });\n\n it(\"recovers the custom cookie after overlapping server updates\", async () => {\n const projectId = \"00000000-0000-4000-8000-000000000001\";\n const customCookieName = `hexclave-refresh-${projectId}--custom-${encodeBase32(new TextEncoder().encode(\"example.com\"))}`;\n const defaultCookieName = `__Host-hexclave-refresh-${projectId}--default`;\n serverCookieState.values.clear();\n serverCookieState.values.set(defaultCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n serverCookieState.values.set(customCookieName, JSON.stringify({ refresh_token: \"old-refresh\", updated_at_millis: 1 }));\n\n const clientApp = new StackClientApp({\n baseUrl: \"http://localhost:12345\",\n projectId,\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n noAutomaticPrefetch: true,\n devTool: false,\n });\n let releaseTrustedParentLookup: (() => void) | undefined;\n let shouldBlockTrustedParentLookup = true;\n Reflect.set(clientApp, \"_getTrustedParentDomain\", async (domain: string) => {\n if (shouldBlockTrustedParentLookup) {\n shouldBlockTrustedParentLookup = false;\n await new Promise<void>((resolve) => {\n releaseTrustedParentLookup = resolve;\n });\n }\n return domain === \"_.example.com\" ? \"example.com\" : null;\n });\n const getOrCreateTokenStore = Reflect.get(clientApp, \"_getOrCreateTokenStore\");\n const cookieHelper: CookieHelper = {\n identity: {},\n get: (name: string) => serverCookieState.values.get(name) ?? null,\n getAll: () => Object.fromEntries(serverCookieState.values),\n set: (name: string, value: string) => serverCookieState.values.set(name, value),\n setOrDelete: (name: string, value: string | null) => {\n if (value === null) {\n serverCookieState.values.delete(name);\n } else {\n serverCookieState.values.set(name, value);\n }\n },\n delete: (name: string) => serverCookieState.values.delete(name),\n };\n const tokenStore = getOrCreateTokenStore.call(clientApp, cookieHelper, \"nextjs-cookie\");\n\n tokenStore.set({ accessToken: \"first-access\", refreshToken: \"first-refresh\" });\n await new Promise((resolve) => setTimeout(resolve, 0));\n if (releaseTrustedParentLookup == null) {\n throw new Error(\"Expected the first custom cookie recovery lookup to be pending.\");\n }\n tokenStore.set({ accessToken: \"second-access\", refreshToken: \"second-refresh\" });\n releaseTrustedParentLookup();\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n const customCookieValue = serverCookieState.values.get(customCookieName);\n expect(customCookieValue).toBeDefined();\n if (customCookieValue == null) {\n throw new Error(\"Expected the custom refresh cookie to be recovered.\");\n }\n expect(JSON.parse(customCookieValue)).toMatchObject({\n refresh_token: \"second-refresh\",\n updated_at_millis: expect.any(Number),\n });\n expect(serverCookieState.values.has(defaultCookieName)).toBe(true);\n });\n});\n"],"mappings":"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"}
|
|
@@ -13,8 +13,8 @@ let ______url_targets_js = require("../../url-targets.js");
|
|
|
13
13
|
let _hexclave_shared_dist_utils_caches = require("@hexclave/shared/dist/utils/caches");
|
|
14
14
|
let _hexclave_shared_dist_utils_globals = require("@hexclave/shared/dist/utils/globals");
|
|
15
15
|
//#region src/lib/hexclave-app/apps/implementations/common.ts
|
|
16
|
-
const clientVersion = "js @hexclave/js@1.0.
|
|
17
|
-
if ("js @hexclave/js@1.0.
|
|
16
|
+
const clientVersion = "js @hexclave/js@1.0.118";
|
|
17
|
+
if ("js @hexclave/js@1.0.118".startsWith("STACK_COMPILE_TIME"));
|
|
18
18
|
const replaceHexclavePortPrefix = (input) => {
|
|
19
19
|
if (!input) return input;
|
|
20
20
|
const prefix = ____________generated_env_js.envVars.HEXCLAVE_PORT_PREFIX;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
|
|
3
3
|
"name": "@hexclave/js",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.118",
|
|
5
5
|
"repository": "https://github.com/hexclave/hexclave",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"qrcode": "^1.5.4",
|
|
66
66
|
"rrweb": "^1.1.3",
|
|
67
67
|
"yup": "^1.7.1",
|
|
68
|
-
"@hexclave/shared": "1.0.
|
|
68
|
+
"@hexclave/shared": "1.0.118"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@quetzallabs/i18n": "^0.1.19",
|
|
@@ -6,6 +6,7 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
6
6
|
import { encodeBase32 } from "@hexclave/shared/dist/utils/bytes";
|
|
7
7
|
import { getTrustedParentDomain } from "@hexclave/shared/dist/utils/redirect-urls";
|
|
8
8
|
import { TextEncoder } from "util";
|
|
9
|
+
import type { CookieHelper } from "../../../cookie";
|
|
9
10
|
import { StackClientApp } from "../interfaces/client-app";
|
|
10
11
|
|
|
11
12
|
const serverCookieState = vi.hoisted(() => ({
|
|
@@ -25,6 +26,7 @@ vi.mock("../../../cookie", () => {
|
|
|
25
26
|
}
|
|
26
27
|
};
|
|
27
28
|
const helper = {
|
|
29
|
+
identity: {},
|
|
28
30
|
get: (name: string) => serverCookieState.values.get(name) ?? null,
|
|
29
31
|
getAll,
|
|
30
32
|
set: (name: string, value: string) => setOrDelete(name, value),
|
|
@@ -72,7 +74,8 @@ describe("StackClientApp custom refresh cookie updates", () => {
|
|
|
72
74
|
return domain === "_.example.com" ? "example.com" : null;
|
|
73
75
|
});
|
|
74
76
|
const getOrCreateTokenStore = Reflect.get(clientApp, "_getOrCreateTokenStore");
|
|
75
|
-
const cookieHelper = {
|
|
77
|
+
const cookieHelper: CookieHelper = {
|
|
78
|
+
identity: {},
|
|
76
79
|
get: (name: string) => serverCookieState.values.get(name) ?? null,
|
|
77
80
|
getAll: () => Object.fromEntries(serverCookieState.values),
|
|
78
81
|
set: (name: string, value: string) => serverCookieState.values.set(name, value),
|
|
@@ -134,7 +137,8 @@ describe("StackClientApp custom refresh cookie updates", () => {
|
|
|
134
137
|
return domain === "_.example.com" ? "example.com" : null;
|
|
135
138
|
});
|
|
136
139
|
const getOrCreateTokenStore = Reflect.get(clientApp, "_getOrCreateTokenStore");
|
|
137
|
-
const cookieHelper = {
|
|
140
|
+
const cookieHelper: CookieHelper = {
|
|
141
|
+
identity: {},
|
|
138
142
|
get: (name: string) => serverCookieState.values.get(name) ?? null,
|
|
139
143
|
getAll: () => Object.fromEntries(serverCookieState.values),
|
|
140
144
|
set: (name: string, value: string) => serverCookieState.values.set(name, value),
|