Skip to content

Commit 8b7d725

Browse files
authored
fix(cli): implement missing response override referrer behavior (#543)
The documentation calls out user-defined redirect behavior using the .referrer parameter in the response override configuration. This PR enables the SWA CLI emulator to support that functionality. Fixes #542
1 parent ea62a4f commit 8b7d725

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

src/msha/routes-engine/rules/response-overrides.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,32 @@ describe("responseOverrides()", () => {
5656
expect(req.url).toBe(`${CUSTOM_URL_SCHEME}foo`);
5757
});
5858

59+
it("should override redirect rule with .referrer replacement and query string", () => {
60+
req.url = "/foo";
61+
res.statusCode = 404;
62+
userConfig = {
63+
"404": {
64+
redirect: "/.auth/login/aad/post_login_redirect_uri=.referrer",
65+
},
66+
};
67+
responseOverrides(req, res, userConfig);
68+
69+
expect(res.setHeader).toHaveBeenCalledWith("Location", "/.auth/login/aad/post_login_redirect_uri=%2Ffoo");
70+
});
71+
72+
it("should override redirect rule with .referrer replacement", () => {
73+
req.url = "/foo?with=query&params=1-1";
74+
res.statusCode = 404;
75+
userConfig = {
76+
"404": {
77+
redirect: "/.auth/login/aad/post_login_redirect_uri=.referrer",
78+
},
79+
};
80+
responseOverrides(req, res, userConfig);
81+
82+
expect(res.setHeader).toHaveBeenCalledWith("Location", "/.auth/login/aad/post_login_redirect_uri=%2Ffoo%3Fwith%3Dquery%26params%3D1-1");
83+
});
84+
5985
it("should override redirect rule", () => {
6086
res.statusCode = 404;
6187
userConfig = {

src/msha/routes-engine/rules/response-overrides.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@ export function responseOverrides(req: http.IncomingMessage, res: http.ServerRes
2727
if (rule.redirect) {
2828
const statusCodeToServe = parseInt(`${rule?.statusCode}`, 10) === 301 ? 301 : 302;
2929
res.statusCode = statusCodeToServe;
30-
res.setHeader("Location", rule.redirect);
30+
31+
if (rule.redirect.indexOf(".referrer") !== -1) {
32+
// The Production SWA service supports replacing `.referrer` with the current route, so that the user can redirected to a deep link after the authentication flow.
33+
// Since the route can contain a path with a query we will want to encode it and the `auth.html` page will need to decode it before changing the page.
34+
const redirectWithReferrerReplaced = rule.redirect.replace(".referrer", encodeURIComponent(req.url || ""));
35+
res.setHeader("Location", redirectWithReferrerReplaced);
36+
} else {
37+
// No `.referrer` param is used, just use user-provided rule redirect as-is
38+
res.setHeader("Location", rule.redirect);
39+
}
3140

3241
logger.silly(` - redirect: ${chalk.yellow(rule.redirect)}`);
3342
}

src/public/auth.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ <h1 class="pb-4">Azure Static Web Apps Auth</h1>
202202
const urlSearch = (metaSearch || location.search).replace("?", "");
203203
const urlQuery = urlSearch && Object.fromEntries(new Map(urlSearch.split("&").map((query) => query.split("="))));
204204
const postLoginRedirectUri = urlQuery ? urlQuery["post_login_redirect_uri"] : redirectPath;
205-
window.location.href = postLoginRedirectUri || defaultRedirectPath;
205+
206+
window.location.href = decodeURIComponent(postLoginRedirectUri) || defaultRedirectPath;
206207
} catch (error) {
207208
console.warn(error);
208209
window.location.href = defaultRedirectPath;

0 commit comments

Comments
 (0)