[next] Auth Callback + Chunking (#2139)

* feat: added new auth-callback

* fix: removed unused polyfill code

* fix: fixed missed intersection observer

* feat: enabled vendor chunks

* fix: fix some issues with chunk splitting

* fix: added intersection-observer to app polyfill

* fix: fixed test

* fix: removed lodash plugin which caused issue in prod

* chore: access_token -> accessToken

* feat: Show social login errors

* fix: lint + add test

* fix: restore width after facebook social login
This commit is contained in:
Wyatt Johnson
2019-01-11 15:31:24 +01:00
committed by Kiwi
parent 0e941222c5
commit 94eb72a9bf
42 changed files with 880 additions and 277 deletions
@@ -4,7 +4,11 @@ import ms from "ms";
export const noCacheMiddleware: RequestHandler = (req, res, next) => {
// Set cache control headers to prevent browsers/cdn's from caching these
// requests.
res.set({ "Cache-Control": "no-cache, no-store, must-revalidate" });
res.set({
"Cache-Control": "private, no-cache, no-store, must-revalidate",
Expires: "-1",
Pragma: "no-cache",
});
next();
};
@@ -138,12 +138,23 @@ export async function handleSuccessfulLogin(
}
export async function handleOAuth2Callback(
user: User,
err: Error | null,
user: User | null,
signingConfig: JWTSigningConfig,
req: Request,
res: Response,
next: NextFunction
) {
const path = "/embed/auth/callback";
if (!user) {
if (!err) {
// TODO: (wyattjoh) replace with better error
err = new Error("user not on request");
}
return res.redirect(path + `#error=${encodeURIComponent(err.message)}`);
}
try {
// Talk is guaranteed at this point.
const { tenant } = req.talk!;
@@ -158,35 +169,10 @@ export async function handleOAuth2Callback(
// Grab the token.
const token = await signTokenString(signingConfig, user, options);
// Set the cache control headers.
res.header("Cache-Control", "private, no-cache, no-store, must-revalidate");
res.header("Expires", "-1");
res.header("Pragma", "no-cache");
// Send back the details!
res.send(
`<html>
<head></head>
<body>
<script type="text/javascript">
const redirect = sessionStorage.getItem("authRedirectBackTo");
if (!redirect) {
var textnode = document.createTextNode("'authRedirectBackTo' not set in Session Storage");
document.body.appendChild(textnode);
}
else if (redirect[0] !== '/') {
var textnode = document.createTextNode("'authRedirectBackTo' must begin with '/'");
document.body.appendChild(textnode);
}
else {
location.href = \`\${redirect}#${token}\`;
}
</script>
</body>
</html>`
);
res.redirect(path + `#accessToken=${token}`);
} catch (err) {
return next(err);
res.redirect(path + `#error=${encodeURIComponent(err.message)}`);
}
}
@@ -209,15 +195,7 @@ export const wrapOAuth2Authn = (
name,
{ ...options, session: false },
(err: Error | null, user: User | null) => {
if (err) {
return next(err);
}
if (!user) {
// TODO: (wyattjoh) replace with better error.
return next(new Error("no user on request"));
}
handleOAuth2Callback(user, signingConfig, req, res, next);
handleOAuth2Callback(err, user, signingConfig, req, res, next);
}
)(req, res, next);
+3 -2
View File
@@ -5,6 +5,7 @@ import {
logoutHandler,
signupHandler,
} from "talk-server/app/handlers/api/tenant/auth/local";
import { noCacheMiddleware } from "talk-server/app/middleware/cacheHeaders";
import {
wrapAuthn,
wrapOAuth2Authn,
@@ -24,8 +25,8 @@ function wrapPath(
strategy
);
router.get(path, handler);
router.get(path + "/callback", handler);
router.get(path, noCacheMiddleware, handler);
router.get(path + "/callback", noCacheMiddleware, handler);
}
export function createNewAuthRouter(app: AppOptions, options: RouterOptions) {
+8
View File
@@ -44,6 +44,14 @@ export async function createRouter(app: AppOptions, options: RouterOptions) {
cacheDuration: false,
})
);
router.use(
"/embed/auth/callback",
createClientTargetRouter({
staticURI,
view: "auth-callback",
cacheDuration: false,
})
);
// Add the standalone targets.
router.use(
+1 -1
View File
@@ -29,7 +29,7 @@ describe("extractJWTFromRequest", () => {
};
expect(extractJWTFromRequest((req as any) as Request)).toEqual(null);
req.url = "https://talk.coralproject.net/api?access_token=token";
req.url = "https://talk.coralproject.net/api?accessToken=token";
expect(extractJWTFromRequest((req as any) as Request)).toEqual("token");
});
+1 -1
View File
@@ -115,7 +115,7 @@ export const signPATString = async (
export function extractJWTFromRequest(req: Request) {
const permit = new Bearer({
basic: "password",
query: "access_token",
query: "accessToken",
});
return permit.check(req) || null;
+1 -1
View File
@@ -26,7 +26,7 @@ describe("extractJWTFromRequest", () => {
};
expect(extractJWTFromRequest((req as any) as Request)).toEqual(null);
req.url = "https://talk.coralproject.net/api?access_token=token";
req.url = "https://talk.coralproject.net/api?accessToken=token";
expect(extractJWTFromRequest((req as any) as Request)).toEqual("token");
});