@worldcoin/idkit-core 1.1.3 → 1.1.4

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/build/index.cjs CHANGED
@@ -69,6 +69,45 @@ var VerificationLevel = /* @__PURE__ */ ((VerificationLevel2) => {
69
69
  // src/bridge.ts
70
70
  var import_zustand = require("zustand");
71
71
 
72
+ // src/lib/validation.ts
73
+ function validate_bridge_url(bridge_url, is_staging) {
74
+ try {
75
+ new URL(bridge_url);
76
+ } catch (e) {
77
+ return { valid: false, errors: ["Failed to parse Bridge URL."] };
78
+ }
79
+ const test_url = new URL(bridge_url);
80
+ const errors = [];
81
+ if (is_staging && ["localhost", "127.0.0.1"].includes(test_url.hostname)) {
82
+ console.log("Using staging app_id with localhost bridge_url. Skipping validation.");
83
+ return { valid: true };
84
+ }
85
+ if (test_url.protocol !== "https:") {
86
+ errors.push("Bridge URL must use HTTPS.");
87
+ }
88
+ if (test_url.port) {
89
+ errors.push("Bridge URL must use the default port (443).");
90
+ }
91
+ if (test_url.pathname !== "/") {
92
+ errors.push("Bridge URL must not have a path.");
93
+ }
94
+ if (test_url.search) {
95
+ errors.push("Bridge URL must not have query parameters.");
96
+ }
97
+ if (test_url.hash) {
98
+ errors.push("Bridge URL must not have a fragment.");
99
+ }
100
+ if (!test_url.hostname.endsWith(".worldcoin.org") && !test_url.hostname.endsWith(".toolsforhumanity.com")) {
101
+ console.warn(
102
+ "Bridge URL should be a subdomain of worldcoin.org or toolsforhumanity.com. The user's identity wallet may refuse to connect. This is a temporary measure and may be removed in the future."
103
+ );
104
+ }
105
+ if (errors.length) {
106
+ return { valid: false, errors };
107
+ }
108
+ return { valid: true };
109
+ }
110
+
72
111
  // src/lib/hashing.ts
73
112
  var import_buffer = require("buffer/index.js");
74
113
  var import_viem = require("viem");
@@ -177,7 +216,15 @@ var useWorldBridgeStore = (0, import_zustand.create)((set, get) => ({
177
216
  verificationState: "loading_widget" /* PreparingClient */,
178
217
  createClient: async ({ bridge_url, app_id, verification_level, action_description, action, signal }) => {
179
218
  const { key, iv } = await generateKey();
180
- const res = await fetch(`${bridge_url ?? DEFAULT_BRIDGE_URL}/request`, {
219
+ if (bridge_url) {
220
+ const validation = validate_bridge_url(bridge_url, app_id.includes("staging"));
221
+ if (!validation.valid) {
222
+ console.error(validation.errors.join("\n"));
223
+ set({ verificationState: "failed" /* Failed */ });
224
+ throw new Error("Invalid bridge_url. Please check the console for more details.");
225
+ }
226
+ }
227
+ const res = await fetch(new URL("/request", bridge_url ?? DEFAULT_BRIDGE_URL), {
181
228
  method: "POST",
182
229
  headers: { "Content-Type": "application/json" },
183
230
  body: JSON.stringify(
@@ -217,7 +264,7 @@ var useWorldBridgeStore = (0, import_zustand.create)((set, get) => ({
217
264
  const key = get().key;
218
265
  if (!key)
219
266
  throw new Error("No keypair found. Please call `createClient` first.");
220
- const res = await fetch(`${get().bridge_url}/response/${get().requestId}`);
267
+ const res = await fetch(new URL(`/response/${get().requestId}`, get().bridge_url));
221
268
  if (!res.ok) {
222
269
  return set({
223
270
  errorCode: "connection_failed" /* ConnectionFailed */,
package/build/index.js CHANGED
@@ -42,6 +42,45 @@ var VerificationLevel = /* @__PURE__ */ ((VerificationLevel2) => {
42
42
  // src/bridge.ts
43
43
  import { create } from "zustand";
44
44
 
45
+ // src/lib/validation.ts
46
+ function validate_bridge_url(bridge_url, is_staging) {
47
+ try {
48
+ new URL(bridge_url);
49
+ } catch (e) {
50
+ return { valid: false, errors: ["Failed to parse Bridge URL."] };
51
+ }
52
+ const test_url = new URL(bridge_url);
53
+ const errors = [];
54
+ if (is_staging && ["localhost", "127.0.0.1"].includes(test_url.hostname)) {
55
+ console.log("Using staging app_id with localhost bridge_url. Skipping validation.");
56
+ return { valid: true };
57
+ }
58
+ if (test_url.protocol !== "https:") {
59
+ errors.push("Bridge URL must use HTTPS.");
60
+ }
61
+ if (test_url.port) {
62
+ errors.push("Bridge URL must use the default port (443).");
63
+ }
64
+ if (test_url.pathname !== "/") {
65
+ errors.push("Bridge URL must not have a path.");
66
+ }
67
+ if (test_url.search) {
68
+ errors.push("Bridge URL must not have query parameters.");
69
+ }
70
+ if (test_url.hash) {
71
+ errors.push("Bridge URL must not have a fragment.");
72
+ }
73
+ if (!test_url.hostname.endsWith(".worldcoin.org") && !test_url.hostname.endsWith(".toolsforhumanity.com")) {
74
+ console.warn(
75
+ "Bridge URL should be a subdomain of worldcoin.org or toolsforhumanity.com. The user's identity wallet may refuse to connect. This is a temporary measure and may be removed in the future."
76
+ );
77
+ }
78
+ if (errors.length) {
79
+ return { valid: false, errors };
80
+ }
81
+ return { valid: true };
82
+ }
83
+
45
84
  // src/lib/utils.ts
46
85
  import { Buffer } from "buffer/index.js";
47
86
  var DEFAULT_VERIFICATION_LEVEL = "orb" /* Orb */;
@@ -109,7 +148,15 @@ var useWorldBridgeStore = create((set, get) => ({
109
148
  verificationState: "loading_widget" /* PreparingClient */,
110
149
  createClient: async ({ bridge_url, app_id, verification_level, action_description, action, signal }) => {
111
150
  const { key, iv } = await generateKey();
112
- const res = await fetch(`${bridge_url ?? DEFAULT_BRIDGE_URL}/request`, {
151
+ if (bridge_url) {
152
+ const validation = validate_bridge_url(bridge_url, app_id.includes("staging"));
153
+ if (!validation.valid) {
154
+ console.error(validation.errors.join("\n"));
155
+ set({ verificationState: "failed" /* Failed */ });
156
+ throw new Error("Invalid bridge_url. Please check the console for more details.");
157
+ }
158
+ }
159
+ const res = await fetch(new URL("/request", bridge_url ?? DEFAULT_BRIDGE_URL), {
113
160
  method: "POST",
114
161
  headers: { "Content-Type": "application/json" },
115
162
  body: JSON.stringify(
@@ -149,7 +196,7 @@ var useWorldBridgeStore = create((set, get) => ({
149
196
  const key = get().key;
150
197
  if (!key)
151
198
  throw new Error("No keypair found. Please call `createClient` first.");
152
- const res = await fetch(`${get().bridge_url}/response/${get().requestId}`);
199
+ const res = await fetch(new URL(`/response/${get().requestId}`, get().bridge_url));
153
200
  if (!res.ok) {
154
201
  return set({
155
202
  errorCode: "connection_failed" /* ConnectionFailed */,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@worldcoin/idkit-core",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "homepage": "https://docs.worldcoin.org/id/idkit",
5
5
  "license": "MIT",
6
6
  "private": false,