Skip to content

Commit 5f79660

Browse files
authored
Merge pull request #1831 from dubinc/iframeable
Remove iframeable check on demand
2 parents 37cfdc3 + d9501de commit 5f79660

File tree

7 files changed

+46
-162
lines changed

7 files changed

+46
-162
lines changed

apps/web/lib/api/links/cache.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class LinkCache {
1919

2020
const redisLinks = await Promise.all(
2121
links.map(async (link) => ({
22-
...(await formatRedisLink(link)),
22+
...formatRedisLink(link),
2323
key: link.key.toLowerCase(),
2424
domain: link.domain.toLowerCase(),
2525
})),
@@ -40,7 +40,7 @@ class LinkCache {
4040
}
4141

4242
async set(link: ExpandedLink) {
43-
const redisLink = await formatRedisLink(link);
43+
const redisLink = formatRedisLink(link);
4444
const hasWebhooks = redisLink.webhookIds && redisLink.webhookIds.length > 0;
4545

4646
return await redis.set(

apps/web/lib/middleware/link.ts

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export default async function LinkMiddleware(
9090
}
9191

9292
// format link to fit the RedisLinkProps interface
93-
link = await formatRedisLink(linkData as any);
93+
link = formatRedisLink(linkData as any);
9494

9595
ev.waitUntil(linkCache.set(linkData as any));
9696
}
@@ -102,7 +102,6 @@ export default async function LinkMiddleware(
102102
trackConversion,
103103
proxy,
104104
rewrite,
105-
iframeable,
106105
expiresAt,
107106
ios,
108107
android,
@@ -280,41 +279,28 @@ export default async function LinkMiddleware(
280279
}),
281280
);
282281

283-
if (iframeable) {
284-
return createResponseWithCookie(
285-
NextResponse.rewrite(
286-
new URL(
287-
`/cloaked/${encodeURIComponent(
288-
getFinalUrl(url, {
289-
req,
290-
clickId: trackConversion ? clickId : undefined,
291-
}),
292-
)}`,
293-
req.url,
294-
),
295-
{
296-
headers: {
297-
...DUB_HEADERS,
298-
...(!shouldIndex && {
299-
"X-Robots-Tag": "googlebot: noindex",
300-
}),
301-
},
302-
},
282+
return createResponseWithCookie(
283+
NextResponse.rewrite(
284+
new URL(
285+
`/cloaked/${encodeURIComponent(
286+
getFinalUrl(url, {
287+
req,
288+
clickId: trackConversion ? clickId : undefined,
289+
}),
290+
)}`,
291+
req.url,
303292
),
304-
{ clickId, path: `/${originalKey}` },
305-
);
306-
} else {
307-
// if link is not iframeable, use Next.js rewrite instead
308-
return createResponseWithCookie(
309-
NextResponse.rewrite(url, {
293+
{
310294
headers: {
311295
...DUB_HEADERS,
312-
...(!shouldIndex && { "X-Robots-Tag": "googlebot: noindex" }),
296+
...(!shouldIndex && {
297+
"X-Robots-Tag": "googlebot: noindex",
298+
}),
313299
},
314-
}),
315-
{ clickId, path: `/${originalKey}` },
316-
);
317-
}
300+
},
301+
),
302+
{ clickId, path: `/${originalKey}` },
303+
);
318304

319305
// redirect to iOS link if it is specified and the user is on an iOS device
320306
} else if (ios && userAgent(req).os?.name === "iOS") {

apps/web/lib/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ export interface RedisLinkProps {
8585
password?: boolean;
8686
proxy?: boolean;
8787
rewrite?: boolean;
88-
iframeable?: boolean;
8988
expiresAt?: Date;
9089
expiredUrl?: string;
9190
ios?: string;

apps/web/lib/upstash/format-redis-link.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
import { isIframeable } from "@dub/utils";
21
import { ExpandedLink } from "../api/links/utils/transform-link";
32
import { RedisLinkProps } from "../types";
43

5-
export async function formatRedisLink(
6-
link: ExpandedLink,
7-
): Promise<RedisLinkProps> {
4+
export function formatRedisLink(link: ExpandedLink): RedisLinkProps {
85
const {
96
id,
10-
domain,
117
url,
128
trackConversion,
139
password,
@@ -34,7 +30,6 @@ export async function formatRedisLink(
3430
...(url &&
3531
rewrite && {
3632
rewrite: true,
37-
iframeable: await isIframeable({ url, requestDomain: domain }),
3833
}),
3934
...(expiresAt && { expiresAt: new Date(expiresAt) }),
4035
...(expiredUrl && { expiredUrl }),

apps/web/scripts/update-noindex.ts

Lines changed: 0 additions & 74 deletions
This file was deleted.

apps/web/ui/modals/link-builder/options-list.tsx

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { AlertCircleFill, CheckCircleFill, X } from "@/ui/shared/icons";
2-
import { Tooltip, useMediaQuery } from "@dub/ui";
2+
import { SimpleTooltipContent, Tooltip, useMediaQuery } from "@dub/ui";
33
import { LoadingSpinner } from "@dub/ui/icons";
4-
import { cn, fetcher, isValidUrl as isValidUrlFn } from "@dub/utils";
4+
import { fetcher, isValidUrl as isValidUrlFn } from "@dub/utils";
55
import { AnimatePresence, motion } from "framer-motion";
66
import { ReactNode, useMemo } from "react";
77
import { useFormContext } from "react-hook-form";
@@ -121,10 +121,10 @@ function LinkCloakingToggleBadge({
121121
icon={
122122
isLoading ? (
123123
<LoadingSpinner className="size-3.5" />
124-
) : !data ? null : data?.iframeable ? (
124+
) : !data ? null : data.iframeable ? (
125125
<CheckCircleFill className="size-3.5 text-green-500" />
126126
) : (
127-
<AlertCircleFill className="size-3.5 text-yellow-500" />
127+
<AlertCircleFill className="size-3.5 text-amber-500" />
128128
)
129129
}
130130
/>
@@ -135,48 +135,26 @@ function LinkCloakingToggleBadge({
135135
return data ? (
136136
<Tooltip
137137
content={
138-
<div
139-
className={cn(
140-
"block max-w-lg text-pretty p-4 text-center text-sm text-gray-700",
141-
{
142-
"max-w-sm": !data.iframeable,
143-
},
144-
)}
145-
>
146-
{data.iframeable ? (
147-
<div className="grid gap-2">
148-
<div className="h-[250px] w-[444px] overflow-hidden rounded-lg border border-gray-200">
149-
<iframe
150-
src={url}
151-
style={{
152-
zoom: 0.5,
153-
}}
154-
className="h-[500px] w-[888px]"
155-
/>
156-
</div>
157-
<p>Your link will be successfully cloaked.</p>
138+
data.iframeable ? (
139+
<div className="grid max-w-lg gap-2 text-pretty p-4 text-center text-sm text-gray-700">
140+
<div className="h-[250px] w-[444px] overflow-hidden rounded-lg border border-gray-200">
141+
<iframe
142+
src={url}
143+
style={{
144+
zoom: 0.5,
145+
}}
146+
className="h-[500px] w-[888px]"
147+
/>
158148
</div>
159-
) : (
160-
<span>
161-
We will try to cloak it with{" "}
162-
<a
163-
href="https://nextjs.org/docs/pages/api-reference/functions/next-response#rewrite"
164-
target="_blank"
165-
className="text-gray-500 underline underline-offset-2 hover:text-gray-700"
166-
>
167-
Next.js Rewrites
168-
</a>
169-
, but it might not work as expected.{" "}
170-
<a
171-
href="https://dub.co/help/article/link-cloaking"
172-
target="_blank"
173-
className="text-gray-500 underline underline-offset-2 hover:text-gray-700"
174-
>
175-
Learn more.
176-
</a>
177-
</span>
178-
)}
179-
</div>
149+
<p>Your link will be successfully cloaked.</p>
150+
</div>
151+
) : (
152+
<SimpleTooltipContent
153+
title="Your link is not cloakable – make sure you have the right security headers set on your target URL."
154+
cta="Learn more"
155+
href="https://dub.co/help/article/link-cloaking#link-cloaking-with-security-headers"
156+
/>
157+
)
180158
}
181159
>
182160
<div>{badge}</div>

packages/utils/src/functions/is-iframeable.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ export const isIframeable = async ({
2929
return false;
3030
}
3131

32-
return false;
32+
return true;
3333
};

0 commit comments

Comments
 (0)