@coasys/ad4m-connect 0.13.0-postmessage-ws-proxy.0 → 0.13.0-postmessage-ws-proxy.1

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/index.js CHANGED
@@ -120,21 +120,26 @@ function getHue(str) {
120
120
  }
121
121
 
122
122
  // src/PostMessageWebSocket.ts
123
- var PostMessageWebSocket = class {
124
- constructor(_url) {
123
+ var _PostMessageWebSocket = class {
124
+ constructor(_url, targetOrigin) {
125
125
  this.readyState = 0;
126
126
  this.onopen = null;
127
127
  this.onmessage = null;
128
128
  this.onerror = null;
129
129
  this.onclose = null;
130
+ this._connectTimeout = null;
131
+ this._targetOrigin = targetOrigin;
130
132
  this._messageHandler = (e7) => {
131
133
  var _a, _b, _c, _d;
132
134
  if (e7.source !== window.parent)
133
135
  return;
136
+ if (e7.origin !== this._targetOrigin)
137
+ return;
134
138
  const msg = e7.data;
135
139
  if (!msg || typeof msg.type !== "string")
136
140
  return;
137
141
  if (msg.type === "AD4M_PROXY_WS_OPEN") {
142
+ this._clearConnectTimeout();
138
143
  this.readyState = 1;
139
144
  (_a = this.onopen) == null ? void 0 : _a.call(this, new Event("open"));
140
145
  return;
@@ -144,10 +149,12 @@ var PostMessageWebSocket = class {
144
149
  return;
145
150
  }
146
151
  if (msg.type === "AD4M_PROXY_WS_ERROR") {
152
+ this._clearConnectTimeout();
147
153
  (_c = this.onerror) == null ? void 0 : _c.call(this, new Event("error"));
148
154
  return;
149
155
  }
150
156
  if (msg.type === "AD4M_PROXY_WS_CLOSED") {
157
+ this._clearConnectTimeout();
151
158
  this.readyState = 3;
152
159
  (_d = this.onclose) == null ? void 0 : _d.call(
153
160
  this,
@@ -161,21 +168,37 @@ var PostMessageWebSocket = class {
161
168
  }
162
169
  };
163
170
  window.addEventListener("message", this._messageHandler);
164
- window.parent.postMessage({ type: "AD4M_PROXY_WS_CONNECT" }, "*");
171
+ window.parent.postMessage({ type: "AD4M_PROXY_WS_CONNECT" }, this._targetOrigin);
172
+ this._connectTimeout = setTimeout(() => {
173
+ var _a, _b;
174
+ this._connectTimeout = null;
175
+ window.removeEventListener("message", this._messageHandler);
176
+ this.readyState = 3;
177
+ (_a = this.onerror) == null ? void 0 : _a.call(this, new Event("error"));
178
+ (_b = this.onclose) == null ? void 0 : _b.call(this, new CloseEvent("close", { code: 1006, reason: "Connection timeout", wasClean: false }));
179
+ }, _PostMessageWebSocket.CONNECT_TIMEOUT_MS);
180
+ }
181
+ _clearConnectTimeout() {
182
+ if (this._connectTimeout !== null) {
183
+ clearTimeout(this._connectTimeout);
184
+ this._connectTimeout = null;
185
+ }
165
186
  }
166
187
  send(data) {
167
- window.parent.postMessage({ type: "AD4M_PROXY_WS_SEND", data }, "*");
188
+ window.parent.postMessage({ type: "AD4M_PROXY_WS_SEND", data }, this._targetOrigin);
168
189
  }
169
190
  close(code2, reason) {
170
191
  this.readyState = 2;
171
- window.parent.postMessage({ type: "AD4M_PROXY_WS_CLOSE", code: code2, reason }, "*");
192
+ window.parent.postMessage({ type: "AD4M_PROXY_WS_CLOSE", code: code2, reason }, this._targetOrigin);
172
193
  window.removeEventListener("message", this._messageHandler);
173
194
  }
174
195
  };
196
+ var PostMessageWebSocket = _PostMessageWebSocket;
175
197
  PostMessageWebSocket.CONNECTING = 0;
176
198
  PostMessageWebSocket.OPEN = 1;
177
199
  PostMessageWebSocket.CLOSING = 2;
178
200
  PostMessageWebSocket.CLOSED = 3;
201
+ PostMessageWebSocket.CONNECT_TIMEOUT_MS = 3e4;
179
202
 
180
203
  // ../core/lib/index.js
181
204
  var RpcError = class extends Error {
@@ -11232,7 +11255,18 @@ var Ad4mConnect = class extends EventTarget {
11232
11255
  console.warn("[Ad4m Connect] Rejected AD4M_CONFIG from invalid source (not parent window)");
11233
11256
  return;
11234
11257
  }
11235
- if (this.options.allowedOrigins && this.options.allowedOrigins.length > 0) {
11258
+ if (event.data.proxy) {
11259
+ if (!this.options.allowedOrigins || this.options.allowedOrigins.length === 0) {
11260
+ console.error("[Ad4m Connect] proxy mode requires allowedOrigins to be configured. Rejecting AD4M_CONFIG to prevent arbitrary sites from embedding this app.");
11261
+ this.rejectEmbedded(new Error("proxy mode requires allowedOrigins"));
11262
+ return;
11263
+ }
11264
+ if (!event.origin || !this.options.allowedOrigins.includes(event.origin)) {
11265
+ console.warn("[Ad4m Connect] Rejected AD4M_CONFIG from unauthorized origin:", event.origin);
11266
+ this.rejectEmbedded(new Error(`Unauthorized origin: ${event.origin}`));
11267
+ return;
11268
+ }
11269
+ } else if (this.options.allowedOrigins && this.options.allowedOrigins.length > 0) {
11236
11270
  if (!event.origin || !this.options.allowedOrigins.includes(event.origin)) {
11237
11271
  console.warn("[Ad4m Connect] Rejected AD4M_CONFIG from unauthorized origin:", event.origin);
11238
11272
  this.rejectEmbedded(new Error(`Unauthorized origin: ${event.origin}`));
@@ -11250,12 +11284,17 @@ var Ad4mConnect = class extends EventTarget {
11250
11284
  } else {
11251
11285
  removeLocal("ad4m-token");
11252
11286
  }
11287
+ if (!event.origin || event.origin === "null") {
11288
+ throw new Error("AD4M proxy mode requires a non-opaque parent origin. Ensure the host iframe is not sandboxed without allow-same-origin.");
11289
+ }
11290
+ const parentOrigin2 = event.origin;
11291
+ const wsImpl = (url) => new PostMessageWebSocket(url, parentOrigin2);
11253
11292
  this.notifyConnectionChange("connecting");
11254
11293
  this.ad4mClient = new Ad4mClient(
11255
11294
  "http://proxy",
11256
11295
  normalizedToken,
11257
11296
  false,
11258
- { webSocketImpl: PostMessageWebSocket }
11297
+ { webSocketImpl: wsImpl }
11259
11298
  );
11260
11299
  this.notifyConnectionChange("connected");
11261
11300
  yield this.checkAuth();