tinacms 3.9.1 → 3.9.3

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
@@ -9720,6 +9720,15 @@ class GlobalFormPlugin {
9720
9720
  const cmsForm = cms.state.forms.find(
9721
9721
  ({ tinaForm }) => tinaForm.id === form.id
9722
9722
  );
9723
+ React.useEffect(() => {
9724
+ if (!cmsForm) {
9725
+ cms.dispatch({ type: "forms:add", value: form });
9726
+ cms.dispatch({ type: "forms:set-active-form-id", value: form.id });
9727
+ }
9728
+ }, [cms, cmsForm]);
9729
+ if (!cmsForm) {
9730
+ return null;
9731
+ }
9723
9732
  return /* @__PURE__ */ React.createElement(FormBuilder, { form: cmsForm });
9724
9733
  };
9725
9734
  }
@@ -13186,7 +13195,7 @@ const NavProvider = ({
13186
13195
  const name = "tinacms";
13187
13196
  const type = "module";
13188
13197
  const typings = "dist/index.d.ts";
13189
- const version$1 = "3.9.1";
13198
+ const version$1 = "3.9.3";
13190
13199
  const main = "dist/index.js";
13191
13200
  const module = "./dist/index.js";
13192
13201
  const exports = {
@@ -70597,6 +70606,7 @@ class AuthenticationCancelledError extends Error {
70597
70606
  const authenticate = (clientId, frontendUrl) => {
70598
70607
  return new Promise((resolve, reject) => {
70599
70608
  const origin = `${window.location.protocol}//${window.location.host}`;
70609
+ const expectedOrigin = new URL(frontendUrl).origin;
70600
70610
  const authTab = popupWindow(
70601
70611
  `${frontendUrl}/signin?clientId=${clientId}&origin=${origin}`,
70602
70612
  "_blank",
@@ -70612,10 +70622,16 @@ const authenticate = (clientId, frontendUrl) => {
70612
70622
  );
70613
70623
  return;
70614
70624
  }
70625
+ const cleanup = () => {
70626
+ clearInterval(pollInterval);
70627
+ window.removeEventListener("message", messageHandler);
70628
+ };
70615
70629
  const messageHandler = (e) => {
70630
+ if (e.origin !== expectedOrigin || e.source !== authTab) {
70631
+ return;
70632
+ }
70616
70633
  if (e.data.source === TINA_LOGIN_EVENT) {
70617
- clearInterval(pollInterval);
70618
- window.removeEventListener("message", messageHandler);
70634
+ cleanup();
70619
70635
  if (authTab) {
70620
70636
  authTab.close();
70621
70637
  }
@@ -70628,8 +70644,7 @@ const authenticate = (clientId, frontendUrl) => {
70628
70644
  };
70629
70645
  const pollInterval = setInterval(() => {
70630
70646
  if (authTab.closed) {
70631
- clearInterval(pollInterval);
70632
- window.removeEventListener("message", messageHandler);
70647
+ cleanup();
70633
70648
  reject(new AuthenticationCancelledError("Popup was closed"));
70634
70649
  }
70635
70650
  }, 500);
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export declare function TinaAdminOriginProvider(props: {
3
+ origin: string | string[];
4
+ children: React.ReactNode;
5
+ }): React.ReactElement;
6
+ export declare function useTrustedAdminOrigins(): string[];
7
+ export declare function isFromAdmin(event: MessageEvent, trustedOrigins: string[]): boolean;
package/dist/react.js CHANGED
@@ -3,6 +3,25 @@ import { addMetadata as addMetadata2, hashFromQuery as hashFromQuery2 } from "@t
3
3
  import { QUICK_EDIT_CSS } from "@tinacms/bridge/quick-edit-css";
4
4
  import React from "react";
5
5
  import { tinaField } from "@tinacms/bridge/tina-field";
6
+ const TinaAdminOriginContext = React.createContext(
7
+ null
8
+ );
9
+ function useTrustedAdminOrigins() {
10
+ const configured = React.useContext(TinaAdminOriginContext);
11
+ return React.useMemo(() => {
12
+ if (configured == null) {
13
+ return typeof window !== "undefined" ? [window.location.origin] : [];
14
+ }
15
+ return Array.isArray(configured) ? [...configured] : [configured];
16
+ }, [configured]);
17
+ }
18
+ function isFromAdmin(event, trustedOrigins) {
19
+ if (typeof window === "undefined")
20
+ return false;
21
+ if (!trustedOrigins.includes(event.origin))
22
+ return false;
23
+ return event.source === window.parent;
24
+ }
6
25
  function useTina(props) {
7
26
  const stringifiedQuery = JSON.stringify({
8
27
  query: props.query,
@@ -18,6 +37,7 @@ function useTina(props) {
18
37
  return addMetadata(id, dataCopy, []);
19
38
  }
20
39
  }, [props.data, id]);
40
+ const trustedAdminOrigins = useTrustedAdminOrigins();
21
41
  const [data, setData] = React.useState(processedData);
22
42
  const [isClient, setIsClient] = React.useState(false);
23
43
  const [quickEditEnabled, setQuickEditEnabled] = React.useState(false);
@@ -89,6 +109,8 @@ function useTina(props) {
89
109
  const { experimental___selectFormByFormId, ...rest } = props;
90
110
  parent.postMessage({ type: "open", ...rest, id }, window.location.origin);
91
111
  const handleMessage = (event) => {
112
+ if (!isFromAdmin(event, trustedAdminOrigins))
113
+ return;
92
114
  if (event.data.type === "quickEditEnabled") {
93
115
  setQuickEditEnabled(event.data.value);
94
116
  }
@@ -120,7 +142,7 @@ function useTina(props) {
120
142
  window.removeEventListener("message", handleMessage);
121
143
  parent.postMessage({ type: "close", id }, window.location.origin);
122
144
  };
123
- }, [id, setQuickEditEnabled]);
145
+ }, [id, setQuickEditEnabled, trustedAdminOrigins]);
124
146
  return { data, isClient };
125
147
  }
126
148
  function useEditState() {
@@ -1,3 +1,4 @@
1
+ import { sanitizeUrl } from "@tinacms/mdx";
1
2
  import React from "react";
2
3
  const TinaMarkdown = ({
3
4
  content,
@@ -122,7 +123,7 @@ const Node = ({ components, child }) => {
122
123
  const Component2 = components[child.type];
123
124
  return /* @__PURE__ */ React.createElement(Component2, { ...props });
124
125
  }
125
- return /* @__PURE__ */ React.createElement("img", { src: child.url, alt: child.alt });
126
+ return /* @__PURE__ */ React.createElement("img", { src: sanitizeUrl(child.url), alt: child.alt });
126
127
  case "a":
127
128
  if (components[child.type]) {
128
129
  const Component2 = components[child.type];
@@ -133,7 +134,7 @@ const Node = ({ components, child }) => {
133
134
  }
134
135
  return (
135
136
  // @ts-ignore FIXME: TinaMarkdownContent needs to be a union of all possible node types
136
- /* @__PURE__ */ React.createElement("a", { href: child.url }, /* @__PURE__ */ React.createElement(TinaMarkdown, { components, content: children }))
137
+ /* @__PURE__ */ React.createElement("a", { href: sanitizeUrl(child.url) }, /* @__PURE__ */ React.createElement(TinaMarkdown, { components, content: children }))
137
138
  );
138
139
  case "code_block": {
139
140
  let codeString = "";
@@ -1,3 +1,4 @@
1
+ import { sanitizeUrl } from "@tinacms/mdx";
1
2
  import React from "react";
2
3
  const StaticTinaMarkdown = ({
3
4
  content,
@@ -91,7 +92,7 @@ const Node = ({
91
92
  const Component2 = components[child.type];
92
93
  return /* @__PURE__ */ React.createElement(Component2, { ...props });
93
94
  }
94
- return /* @__PURE__ */ React.createElement("img", { src: child.url, alt: child.alt });
95
+ return /* @__PURE__ */ React.createElement("img", { src: sanitizeUrl(child.url), alt: child.alt });
95
96
  case "a":
96
97
  if (components[child.type]) {
97
98
  const Component2 = components[child.type];
@@ -100,7 +101,7 @@ const Node = ({
100
101
  /* @__PURE__ */ React.createElement(Component2, { ...props }, /* @__PURE__ */ React.createElement(StaticTinaMarkdown, { components, content: children }))
101
102
  );
102
103
  }
103
- return /* @__PURE__ */ React.createElement("a", { href: child.url }, /* @__PURE__ */ React.createElement(StaticTinaMarkdown, { components, content: children }));
104
+ return /* @__PURE__ */ React.createElement("a", { href: sanitizeUrl(child.url) }, /* @__PURE__ */ React.createElement(StaticTinaMarkdown, { components, content: children }));
104
105
  case "code_block": {
105
106
  let codeString = "";
106
107
  if (Array.isArray(child.children)) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "tinacms",
3
3
  "type": "module",
4
4
  "typings": "dist/index.d.ts",
5
- "version": "3.9.1",
5
+ "version": "3.9.3",
6
6
  "main": "dist/index.js",
7
7
  "module": "./dist/index.js",
8
8
  "exports": {
@@ -118,9 +118,9 @@
118
118
  "yup": "^1.6.1",
119
119
  "zod": "^3.24.2",
120
120
  "@tinacms/bridge": "0.3.0",
121
- "@tinacms/mdx": "2.1.6",
121
+ "@tinacms/mdx": "2.1.7",
122
122
  "@tinacms/schema-tools": "2.8.1",
123
- "@tinacms/search": "1.2.17"
123
+ "@tinacms/search": "1.2.19"
124
124
  },
125
125
  "devDependencies": {
126
126
  "@graphql-tools/utils": "^10.8.1",