mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 23:53:17 -05:00
fix(expo): support wildcard trusted origins in deep link cookie injection (#8013)
(cherry picked from commit 2468a2d918)
This commit is contained in:
@@ -66,12 +66,19 @@ export const expo = (options?: ExpoOptions | undefined) => {
|
||||
if (isProxyURL) {
|
||||
return;
|
||||
}
|
||||
const trustedOrigins = ctx.context.trustedOrigins.filter(
|
||||
(origin: string) => !origin.startsWith("http"),
|
||||
);
|
||||
const isTrustedOrigin = trustedOrigins.some((origin: string) =>
|
||||
location?.startsWith(origin),
|
||||
);
|
||||
let redirectURL: URL;
|
||||
try {
|
||||
redirectURL = new URL(location);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
const isHttpRedirect =
|
||||
redirectURL.protocol === "http:" ||
|
||||
redirectURL.protocol === "https:";
|
||||
if (isHttpRedirect) {
|
||||
return;
|
||||
}
|
||||
const isTrustedOrigin = ctx.context.isTrustedOrigin(location);
|
||||
if (!isTrustedOrigin) {
|
||||
return;
|
||||
}
|
||||
@@ -79,9 +86,8 @@ export const expo = (options?: ExpoOptions | undefined) => {
|
||||
if (!cookie) {
|
||||
return;
|
||||
}
|
||||
const url = new URL(location);
|
||||
url.searchParams.set("cookie", cookie);
|
||||
ctx.setHeader("location", url.toString());
|
||||
redirectURL.searchParams.set("cookie", cookie);
|
||||
ctx.setHeader("location", redirectURL.toString());
|
||||
}),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -789,6 +789,7 @@ describe("expo deep link cookie injection", async () => {
|
||||
callbackURL: "myapp:///dashboard",
|
||||
});
|
||||
|
||||
let redirectHandled = false;
|
||||
const { error } = await client.magicLink.verify({
|
||||
query: {
|
||||
token: magicLinkToken,
|
||||
@@ -796,6 +797,7 @@ describe("expo deep link cookie injection", async () => {
|
||||
},
|
||||
fetchOptions: {
|
||||
onError(context) {
|
||||
redirectHandled = true;
|
||||
expect(context.response.status).toBe(302);
|
||||
const location = context.response.headers.get("location");
|
||||
expect(location).toContain("myapp://");
|
||||
@@ -807,7 +809,73 @@ describe("expo deep link cookie injection", async () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(redirectHandled).toBe(true);
|
||||
expect(error?.status).toBe(302);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @see https://github.com/better-auth/better-auth/issues/6810
|
||||
*/
|
||||
describe("expo deep link cookie injection with wildcard trustedOrigins", async () => {
|
||||
let magicLinkToken = "";
|
||||
const storage = new Map<string, string>();
|
||||
|
||||
const { client } = await getTestInstance(
|
||||
{
|
||||
plugins: [
|
||||
expo(),
|
||||
magicLink({
|
||||
async sendMagicLink({ token }) {
|
||||
magicLinkToken = token;
|
||||
},
|
||||
}),
|
||||
],
|
||||
trustedOrigins: ["myapp://*"],
|
||||
},
|
||||
{
|
||||
clientOptions: {
|
||||
plugins: [
|
||||
expoClient({
|
||||
storage: {
|
||||
getItem: (key) => storage.get(key) || null,
|
||||
setItem: async (key, value) => storage.set(key, value),
|
||||
},
|
||||
}),
|
||||
magicLinkClient(),
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
it("should inject cookie into deep link for wildcard trusted origin", async () => {
|
||||
await client.signIn.magicLink({
|
||||
email: "wildcard-test@example.com",
|
||||
callbackURL: "myapp:///dashboard",
|
||||
});
|
||||
|
||||
let redirectHandled = false;
|
||||
const { error } = await client.magicLink.verify({
|
||||
query: {
|
||||
token: magicLinkToken,
|
||||
callbackURL: "myapp:///dashboard",
|
||||
},
|
||||
fetchOptions: {
|
||||
onError(context) {
|
||||
redirectHandled = true;
|
||||
expect(context.response.status).toBe(302);
|
||||
const location = context.response.headers.get("location");
|
||||
expect(location).toContain("myapp://");
|
||||
|
||||
const url = new URL(location!);
|
||||
const cookie = url.searchParams.get("cookie");
|
||||
expect(cookie).toBeDefined();
|
||||
expect(cookie).toContain("better-auth.session_token");
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(redirectHandled).toBe(true);
|
||||
expect(error?.status).toBe(302);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -853,6 +921,7 @@ describe("expo deep link cookie injection for verify-email", async () => {
|
||||
|
||||
expect(verificationToken).toBeTruthy();
|
||||
|
||||
let redirectHandled = false;
|
||||
const { error } = await client.verifyEmail(
|
||||
{
|
||||
query: {
|
||||
@@ -862,6 +931,7 @@ describe("expo deep link cookie injection for verify-email", async () => {
|
||||
},
|
||||
{
|
||||
onError(context) {
|
||||
redirectHandled = true;
|
||||
expect(context.response.status).toBe(302);
|
||||
const location = context.response.headers.get("location");
|
||||
expect(location).toContain("myapp://");
|
||||
@@ -873,7 +943,8 @@ describe("expo deep link cookie injection for verify-email", async () => {
|
||||
},
|
||||
},
|
||||
);
|
||||
expect(error).toBeDefined();
|
||||
expect(redirectHandled).toBe(true);
|
||||
expect(error?.status).toBe(302);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user