@sanity/vercel-protection-bypass
5.0.135.0.14
dist/_chunks-es/VercelProtectionBypassTool.js+
dist/_chunks-es/VercelProtectionBypassTool.jsNew file+276
Index: package/dist/_chunks-es/VercelProtectionBypassTool.js
===================================================================
--- package/dist/_chunks-es/VercelProtectionBypassTool.js
+++ package/dist/_chunks-es/VercelProtectionBypassTool.js
@@ -0,0 +1,276 @@
+import { apiVersion, fetchVercelProtectionBypassSecret, tag, vercelProtectionBypassSchemaId, vercelProtectionBypassSchemaType } from "@sanity/preview-url-secret/constants";
+import { Activity, Suspense, use, useActionState, useEffect, useEffectEvent, useState, useTransition } from "react";
+import { useClient } from "sanity";
+import { c } from "react/compiler-runtime";
+import { AddIcon } from "@sanity/icons/Add";
+import { TrashIcon } from "@sanity/icons/Trash";
+import { Box, Button, Card, Dialog, Flex, Heading, Spinner, Stack, Text, TextInput, useToast } from "@sanity/ui";
+import { Fragment, jsx, jsxs } from "react/jsx-runtime";
+async function enableVercelProtectionBypass(client, secret) {
+ let patch = client.patch(vercelProtectionBypassSchemaId).set({ secret });
+ await client.transaction().createIfNotExists({
+ _id: vercelProtectionBypassSchemaId,
+ _type: vercelProtectionBypassSchemaType
+ }).patch(patch).commit({ tag });
+}
+async function disableVercelProtectionBypass(client) {
+ let patch = client.patch(vercelProtectionBypassSchemaId).set({ secret: null });
+ await client.transaction().createIfNotExists({
+ _id: vercelProtectionBypassSchemaId,
+ _type: vercelProtectionBypassSchemaType
+ }).patch(patch).commit({ tag });
+}
+function VercelProtectionBypassTool() {
+ let $ = c(9), t0;
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = { apiVersion }, $[0] = t0) : t0 = $[0];
+ let client = useClient(t0), t1;
+ $[1] === client ? t1 = $[2] : (t1 = async function(lastLiveEventId) {
+ let { result, syncTags } = await client.fetch(fetchVercelProtectionBypassSecret, {}, {
+ filterResponse: !1,
+ lastLiveEventId: typeof lastLiveEventId == "string" ? lastLiveEventId : null,
+ tag: "preview-url-secret.fetch-vercel-bypass-protection-secret"
+ });
+ return {
+ secret: result,
+ syncTags: syncTags ?? []
+ };
+ }, $[1] = client, $[2] = t1);
+ let fetchSecret = t1, t2;
+ $[3] === fetchSecret ? t2 = $[4] : (t2 = () => fetchSecret(null), $[3] = fetchSecret, $[4] = t2);
+ let [initialStatePromise] = useState(t2), t3;
+ $[5] === Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsx(Flex, {
+ align: "center",
+ direction: "column",
+ height: "fill",
+ justify: "center",
+ style: { width: "100%" },
+ children: /* @__PURE__ */ jsx(Spinner, {})
+ }), $[5] = t3) : t3 = $[5];
+ let t4;
+ return $[6] !== fetchSecret || $[7] !== initialStatePromise ? (t4 = /* @__PURE__ */ jsx(Suspense, {
+ fallback: t3,
+ children: /* @__PURE__ */ jsx(Layout, {
+ initialStatePromise,
+ fetchSecret
+ })
+ }), $[6] = fetchSecret, $[7] = initialStatePromise, $[8] = t4) : t4 = $[8], t4;
+}
+function Layout(t0) {
+ let $ = c(29), { initialStatePromise, fetchSecret } = t0, { push: pushToast } = useToast(), [isDialogOpen, setIsDialogOpen] = useState(!1), t1;
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = { apiVersion }, $[0] = t1) : t1 = $[0];
+ let client = useClient(t1), t2;
+ $[1] !== client || $[2] !== fetchSecret || $[3] !== pushToast ? (t2 = async (prevState, formData) => {
+ let action = formData.get("action");
+ if (typeof action != "string") throw Error("Action is not a string");
+ switch (action) {
+ case "remove-secret": return disableVercelProtectionBypass(client).then(() => (pushToast({
+ status: "warning",
+ title: "Protection bypass is now disabled"
+ }), {
+ ...prevState,
+ secret: null
+ })).catch((reason_0) => (console.error(reason_0), pushToast({
+ status: "error",
+ title: "There was an error when trying to disable protection bypass. See the browser console for more information."
+ }), prevState));
+ case "add-secret": {
+ let secret = formData.get("secret");
+ if (typeof secret != "string") throw Error("Secret is not a string");
+ return enableVercelProtectionBypass(client, secret).then(() => (pushToast({
+ status: "success",
+ title: "Protection bypass is now enabled"
+ }), setIsDialogOpen(!1), {
+ ...prevState,
+ secret
+ })).catch((reason) => (console.error(reason), pushToast({
+ status: "error",
+ title: "There was an error when trying to enable protection bypass. See the browser console for more information."
+ }), prevState));
+ }
+ case "refresh-secret": return fetchSecret(formData.get("lastLiveEventId"));
+ default: throw Error(`Unknown action: ${action}`);
+ }
+ }, $[1] = client, $[2] = fetchSecret, $[3] = pushToast, $[4] = t2) : t2 = $[4];
+ let [formState, formAction, isPending] = useActionState(t2, use(initialStatePromise)), isBackgroundRefetch = useRefetchOnLiveEvent(client, formState, formAction), loading = isPending && !isBackgroundRefetch, enabled = !!formState.secret, t3;
+ $[5] === Symbol.for("react.memo_cache_sentinel") ? (t3 = {
+ height: "100%",
+ alignItems: "center",
+ justifyContent: "center",
+ flexDirection: "column"
+ }, $[5] = t3) : t3 = $[5];
+ let t4;
+ $[6] === Symbol.for("react.memo_cache_sentinel") ? (t4 = { maxWidth: 640 }, $[6] = t4) : t4 = $[6];
+ let t5, t6;
+ $[7] === Symbol.for("react.memo_cache_sentinel") ? (t5 = {
+ justifyItems: "flex-start",
+ textWrap: "pretty"
+ }, t6 = /* @__PURE__ */ jsx(Heading, { children: "Vercel Protection Bypass" }), $[7] = t5, $[8] = t6) : (t5 = $[7], t6 = $[8]);
+ let t7;
+ $[9] !== enabled || $[10] !== loading ? (t7 = /* @__PURE__ */ jsx(Box, {
+ as: "form",
+ action: formAction,
+ sizing: "border",
+ display: "flex",
+ style: t3,
+ children: /* @__PURE__ */ jsx(Stack, {
+ gap: 5,
+ children: /* @__PURE__ */ jsx(Card, {
+ padding: 4,
+ style: t4,
+ children: /* @__PURE__ */ jsxs(Stack, {
+ gap: 4,
+ style: t5,
+ children: [t6, enabled ? /* @__PURE__ */ jsxs(Fragment, { children: [
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, {
+ style: { textWrap: "pretty" },
+ children: [
+ "Sanity Presentation is setup to use",
+ " ",
+ /* @__PURE__ */ jsx("a", {
+ href: "https://vercel.com/docs/security/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation",
+ target: "_blank",
+ rel: "noreferrer",
+ children: "protection bypass for automation"
+ }),
+ " ",
+ "in order to display protected deployments in its preview iframe for the current Sanity dataset."
+ ]
+ }) }),
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: "You can turn off automatic protection bypass at any time by clicking the button below." }) }),
+ /* @__PURE__ */ jsx(Button, {
+ mode: "ghost",
+ tone: "critical",
+ icon: /* @__PURE__ */ jsx(TrashIcon, {}),
+ loading,
+ type: "submit",
+ name: "action",
+ value: "remove-secret",
+ text: "Remove secret"
+ }),
+ /* @__PURE__ */ jsx(Text, { children: "Protection bypass remains enabled if this plugin is removed from your Sanity config." })
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, {
+ style: { textWrap: "pretty" },
+ children: [
+ "Follow the instructions on",
+ " ",
+ /* @__PURE__ */ jsx("a", {
+ href: "https://vercel.com/docs/security/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation",
+ target: "_blank",
+ rel: "noreferrer",
+ children: "how to enable protection bypass for automation"
+ }),
+ "."
+ ]
+ }) }),
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: "This will setup a secret that Vercel exposes as an environment variable called VERCEL_AUTOMATION_BYPASS_SECRET, its value is the secret you need." }) }),
+ /* @__PURE__ */ jsx(Button, {
+ mode: "ghost",
+ icon: /* @__PURE__ */ jsx(AddIcon, {}),
+ onClick: () => {
+ setIsDialogOpen(!0);
+ },
+ text: "Add secret"
+ }),
+ /* @__PURE__ */ jsx(Text, { children: "If you're using Sanity Presentation Tool with multiple protected deployments ensure that they have the same secret set, as this tool will set a secret that is shared in your dataset with all instances of Presentation Tool." })
+ ] })]
+ })
+ })
+ })
+ }), $[9] = enabled, $[10] = loading, $[11] = t7) : t7 = $[11];
+ let t8 = isDialogOpen ? "visible" : "hidden", t9;
+ $[12] === Symbol.for("react.memo_cache_sentinel") ? (t9 = () => setIsDialogOpen(!1), $[12] = t9) : t9 = $[12];
+ let t10, t11;
+ $[13] === Symbol.for("react.memo_cache_sentinel") ? (t10 = /* @__PURE__ */ jsx(Text, {
+ as: "label",
+ weight: "semibold",
+ size: 1,
+ children: "Add bypass secret"
+ }), t11 = /* @__PURE__ */ jsx(Text, {
+ muted: !0,
+ size: 1,
+ children: "Make sure it's the same secret the Vercel deployment is using that's loaded in the preview iframe."
+ }), $[13] = t10, $[14] = t11) : (t10 = $[13], t11 = $[14]);
+ let t12;
+ $[15] === loading ? t12 = $[16] : (t12 = /* @__PURE__ */ jsxs(Stack, {
+ gap: 2,
+ children: [
+ t10,
+ t11,
+ /* @__PURE__ */ jsx(TextInput, {
+ name: "secret",
+ onFocus: _temp,
+ onBlur: _temp2,
+ minLength: 32,
+ maxLength: 32,
+ autoComplete: "off",
+ autoCapitalize: "off",
+ autoCorrect: "off",
+ spellCheck: "false",
+ disabled: loading
+ })
+ ]
+ }), $[15] = loading, $[16] = t12);
+ let t13 = loading ? "Saving…" : "Save", t14;
+ $[17] !== loading || $[18] !== t13 ? (t14 = /* @__PURE__ */ jsx(Button, {
+ type: "submit",
+ loading,
+ text: t13,
+ tone: "positive",
+ name: "action",
+ value: "add-secret"
+ }), $[17] = loading, $[18] = t13, $[19] = t14) : t14 = $[19];
+ let t15;
+ $[20] !== t12 || $[21] !== t14 ? (t15 = /* @__PURE__ */ jsx(Dialog, {
+ animate: !0,
+ id: "add-secret-dialog",
+ onClickOutside: t9,
+ children: /* @__PURE__ */ jsx(Card, {
+ as: "form",
+ action: formAction,
+ padding: 3,
+ children: /* @__PURE__ */ jsxs(Stack, {
+ gap: 3,
+ children: [t12, t14]
+ })
+ })
+ }), $[20] = t12, $[21] = t14, $[22] = t15) : t15 = $[22];
+ let t16;
+ $[23] !== t15 || $[24] !== t8 ? (t16 = /* @__PURE__ */ jsx(Activity, {
+ mode: t8,
+ children: t15
+ }), $[23] = t15, $[24] = t8, $[25] = t16) : t16 = $[25];
+ let t17;
+ return $[26] !== t16 || $[27] !== t7 ? (t17 = /* @__PURE__ */ jsxs(Fragment, { children: [t7, t16] }), $[26] = t16, $[27] = t7, $[28] = t17) : t17 = $[28], t17;
+}
+function _temp2(event_0) {
+ event_0.currentTarget.setCustomValidity(event_0.currentTarget.value.length == 32 ? "" : "Secret must be 32 characters long"), event_0.currentTarget.required = !0;
+}
+function _temp(event) {
+ event.currentTarget.setCustomValidity("");
+}
+function useRefetchOnLiveEvent(client, formState, action) {
+ let $ = c(8), [isBackgroundRefetch, startTransition] = useTransition(), t0;
+ $[0] !== action || $[1] !== formState ? (t0 = (event) => {
+ if (event.type === "message" && event.tags.some((tag) => formState.syncTags.includes(tag))) {
+ let formData = new FormData();
+ formData.set("action", "refresh-secret"), formData.set("lastLiveEventId", event.id), startTransition(() => action(formData));
+ }
+ }, $[0] = action, $[1] = formState, $[2] = t0) : t0 = $[2];
+ let handleLiveEvent = useEffectEvent(t0), t1;
+ $[3] !== client.live || $[4] !== handleLiveEvent ? (t1 = () => {
+ let subscription = client.live.events().subscribe({
+ next: handleLiveEvent,
+ error: _temp3
+ });
+ return () => subscription.unsubscribe();
+ }, $[3] = client.live, $[4] = handleLiveEvent, $[5] = t1) : t1 = $[5];
+ let t2;
+ return $[6] === client ? t2 = $[7] : (t2 = [client], $[6] = client, $[7] = t2), useEffect(t1, t2), isBackgroundRefetch;
+}
+function _temp3(reason) {
+ return console.error(reason);
+}
+export { VercelProtectionBypassTool as default };
+
+//# sourceMappingURL=VercelProtectionBypassTool.js.map
\ No newline at end of file