@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.
@@ -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.116";
16
- if ("js @hexclave/js@1.0.116".startsWith("STACK_COMPILE_TIME"));
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.116";
17
- if ("js @hexclave/js@1.0.116".startsWith("STACK_COMPILE_TIME"));
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.116",
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.116"
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),