Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/web/app/(ee)/api/cron/domains/verify/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export async function GET(req: Request) {
"elegance.ai",
],
},
// only check domains that do not belong to a partner program
partnerProgram: null,
},
select: {
slug: true,
Expand Down
71 changes: 40 additions & 31 deletions apps/web/app/api/domains/[domain]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ export const PATCH = withWorkspace(
domain: params.domain,
dubDomainChecks: true,
});
const { slug: domain, registeredDomain, partnerProgram } = existingDomain;
const {
slug: currentDomain,
registeredDomain,
partnerProgram,
} = existingDomain;

const {
slug: newDomain,
Expand Down Expand Up @@ -93,10 +97,10 @@ export const PATCH = withWorkspace(
}
}

const domainUpdated =
newDomain && newDomain.toLowerCase() !== domain.toLowerCase();
const domainChanged =
newDomain && newDomain.toLowerCase() !== currentDomain.toLowerCase();

if (domainUpdated) {
if (domainChanged) {
if (registeredDomain) {
throw new DubApiError({
code: "forbidden",
Expand Down Expand Up @@ -136,7 +140,7 @@ export const PATCH = withWorkspace(
id: existingDomain.id,
},
data: {
...(domainUpdated && { slug: newDomain }),
...(domainChanged && { slug: newDomain }),
archived,
placeholder,
expiredUrl,
Expand Down Expand Up @@ -181,7 +185,7 @@ export const PATCH = withWorkspace(
if (autoRenew === false) {
waitUntil(
setRenewOption({
domain,
domain: currentDomain,
autoRenew,
}),
);
Expand All @@ -198,14 +202,14 @@ export const PATCH = withWorkspace(
});
}

if (domainUpdated) {
if (domainChanged) {
await Promise.all([
// remove old domain from Vercel
removeDomainFromVercel(domain),
removeDomainFromVercel(currentDomain),

// trigger the queue to rename the redis keys and update the links in Tinybird
queueDomainUpdate({
oldDomain: domain,
oldDomain: currentDomain,
newDomain: newDomain,
...(partnerProgram && { programId: partnerProgram.id }),
}),
Expand All @@ -217,43 +221,48 @@ export const PATCH = withWorkspace(
id: partnerProgram.id,
},
data: {
domain,
domain: newDomain,
},
}),
prisma.partnerGroupDefaultLink.updateMany({
where: {
programId: partnerProgram.id,
},
data: {
domain,
domain: newDomain,
},
}),
]
: []),
]);
}

// invalidate static / isr cached for notfound links
if (
notFoundUrl !== undefined &&
notFoundUrl !== existingDomain.notFoundUrl
) {
revalidateTag(`static:${domain.toLowerCase()}`);
revalidatePath(`/${domain.toLowerCase()}/notfound`);
}
// only need to run invalidations on currentDomain if domain was not changed
} else {
// invalidate static / isr cached for notfound links
if (
notFoundUrl !== undefined &&
notFoundUrl !== existingDomain.notFoundUrl
) {
revalidateTag(`static:${currentDomain.toLowerCase()}`);
revalidatePath(`/${currentDomain.toLowerCase()}/notfound`);
}

// invalidate static / isr cached for expired links
if (
expiredUrl !== undefined &&
expiredUrl !== existingDomain.expiredUrl
) {
revalidateTag(`static:${domain.toLowerCase()}`);
revalidatePath(`/${domain.toLowerCase()}/expired`);
}
// invalidate static / isr cached for expired links
if (
expiredUrl !== undefined &&
expiredUrl !== existingDomain.expiredUrl
) {
revalidateTag(`static:${currentDomain.toLowerCase()}`);
revalidatePath(`/${currentDomain.toLowerCase()}/expired`);
}

// invalidate wellknown cache if any of the wellknown files have changed
if (appleAppSiteAssociation !== undefined || assetLinks !== undefined) {
revalidateTag(`wellknown:${domain.toLowerCase()}`);
// invalidate wellknown cache if any of the wellknown files have changed
if (
appleAppSiteAssociation !== undefined ||
assetLinks !== undefined
) {
revalidateTag(`wellknown:${currentDomain.toLowerCase()}`);
}
}
})(),
);
Expand Down
2 changes: 1 addition & 1 deletion packages/stripe-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.example.dub",
"version": "0.0.19",
"version": "0.0.24",
"description": "Dub Partners",
"private": true,
"license": "~~proprietary~~",
Expand Down
6 changes: 0 additions & 6 deletions packages/stripe-app/src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { StripeMode } from "./types";

// Dub
export const DUB_CLIENT_ID =
"dub_app_517290377fe6b4dfcc8726a7061ba9b6da1c4d7d7d75f77a";
export const DUB_HOST = "https://app.dub.co";
export const DUB_API_HOST = "https://api.dub.co";

// Stripe
export const STRIPE_MODE: StripeMode = "live";
export const STRIPE_REDIRECT_URL = `https://dashboard.stripe.com/${STRIPE_MODE === "live" ? "" : "test/"}apps-oauth/dub.co`;
25 changes: 13 additions & 12 deletions packages/stripe-app/src/utils/oauth.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import Stripe from "stripe";
import {
DUB_API_HOST,
DUB_CLIENT_ID,
DUB_HOST,
STRIPE_REDIRECT_URL,
} from "./constants";
import { DUB_API_HOST, DUB_CLIENT_ID, DUB_HOST } from "./constants";
import { getSecret, setSecret } from "./secrets";
import { Token, Workspace } from "./types";
import { StripeMode, Token, Workspace } from "./types";

function getRedirectUrl(mode: StripeMode) {
return `https://dashboard.stripe.com/${mode === "live" ? "" : "test/"}apps-oauth/dub.co`;
}

// Returns the authorization URL
export function getOAuthUrl({
state,
challenge,
mode,
}: {
state: string;
challenge: string;
mode: StripeMode;
}) {
const searchParams = {
client_id: DUB_CLIENT_ID,
redirect_uri: STRIPE_REDIRECT_URL,
redirect_uri: getRedirectUrl(mode),
response_type: "code",
code_challenge: challenge,
code_challenge_method: "S256",
Expand All @@ -32,21 +33,21 @@ export function getOAuthUrl({
export async function getToken({
code,
verifier,
mode,
}: {
code: string;
verifier: string;
mode: StripeMode;
}) {
const url = `${DUB_API_HOST}/oauth/token`;

try {
const response = await fetch(url, {
const response = await fetch(`${DUB_API_HOST}/oauth/token`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: DUB_CLIENT_ID,
redirect_uri: STRIPE_REDIRECT_URL,
redirect_uri: getRedirectUrl(mode),
grant_type: "authorization_code",
code_verifier: verifier,
code,
Expand Down
18 changes: 15 additions & 3 deletions packages/stripe-app/src/views/AppSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import {
import { deleteSecret, setSecret } from "../utils/secrets";
import { stripe } from "../utils/stripe";

const AppSettings = ({ userContext, oauthContext }: ExtensionContextValue) => {
const AppSettings = ({
userContext,
oauthContext,
environment,
}: ExtensionContextValue) => {
const credentialsUsed = useRef(false);
const [oauthState, setOAuthState] = useState("");
const [challenge, setChallenge] = useState("");
Expand Down Expand Up @@ -72,7 +76,11 @@ const AppSettings = ({ userContext, oauthContext }: ExtensionContextValue) => {
return;
}

const token = await getToken({ code, verifier });
const token = await getToken({
code,
verifier,
mode: environment.mode,
});

if (!token) {
return;
Expand Down Expand Up @@ -163,7 +171,11 @@ const AppSettings = ({ userContext, oauthContext }: ExtensionContextValue) => {
: "Connect workspace",
href: connecting
? "#"
: getOAuthUrl({ state: oauthState, challenge }),
: getOAuthUrl({
state: oauthState,
challenge,
mode: environment.mode,
}),
}}
footerContent={
<>
Expand Down
2 changes: 1 addition & 1 deletion packages/stripe-app/stripe-app.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://stripe.com/stripe-app.schema.json",
"id": "dub.co",
"name": "Dub Partners",
"version": "0.0.23",
"version": "0.0.24",
"icon": "./stripe-icon.png",
"ui_extension": {
"views": [
Expand Down
Loading