fix(client): remove extra slash when redirecting to client (#42588)

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>
pull/42829/head
Oliver Eyton-Williams 2021-07-12 10:24:54 +02:00 committed by GitHub
parent e2ca65c803
commit 92d7ae1725
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 17 deletions

View File

@ -17,8 +17,8 @@ import { fixCompletedChallengeItem } from '../../common/utils';
import { getChallenges } from '../utils/get-curriculum';
import {
getRedirectParams,
getRedirectBase,
normalizeParams
normalizeParams,
getPrefixedLandingPath
} from '../utils/redirection';
const log = debug('fcc:boot:challenges');
@ -341,7 +341,7 @@ export function createRedirectToCurrentChallenge(
const { user } = req;
const { origin, pathPrefix } = getRedirectParams(req, normalizeParams);
const redirectBase = getRedirectBase(origin, pathPrefix);
const redirectBase = getPrefixedLandingPath(origin, pathPrefix);
if (!user) {
return res.redirect(redirectBase + '/learn');
}

View File

@ -11,9 +11,9 @@ import passportProviders from './passport-providers';
import { setAccessTokenToResponse } from './utils/getSetAccessToken';
import {
getReturnTo,
getRedirectBase,
getPrefixedLandingPath,
getRedirectParams,
isRootPath
haveSamePath
} from './utils/redirection';
import { jwtSecret } from '../../../config/secrets';
import { availableLangs } from '../../../config/i18n/all-langs';
@ -100,9 +100,14 @@ export const devLoginRedirect = () => {
};
}
);
returnTo += isRootPath(getRedirectBase(origin, pathPrefix), returnTo)
? '/learn'
: '';
// if returnTo has a trailing slash, we need to remove it before comparing
// it to the prefixed landing path
if (returnTo.slice(-1) === '/') {
returnTo = returnTo.slice(0, -1);
}
const redirectBase = getPrefixedLandingPath(origin, pathPrefix);
returnTo += haveSamePath(redirectBase, returnTo) ? '/learn' : '';
return res.redirect(returnTo);
};
};
@ -142,7 +147,7 @@ we recommend using your email address: ${user.email} to sign in instead.
const state = req && req.query && req.query.state;
// returnTo, origin and pathPrefix are audited by getReturnTo
let { returnTo, origin, pathPrefix } = getReturnTo(state, jwtSecret);
const redirectBase = getRedirectBase(origin, pathPrefix);
const redirectBase = getPrefixedLandingPath(origin, pathPrefix);
// TODO: getReturnTo could return a success flag to show a flash message,
// but currently it immediately gets overwritten by a second message. We
@ -150,7 +155,12 @@ we recommend using your email address: ${user.email} to sign in instead.
// multiple messages to appear at once.
if (user.acceptedPrivacyTerms) {
returnTo += isRootPath(redirectBase, returnTo) ? '/learn' : '';
// if returnTo has a trailing slash, we need to remove it before comparing
// it to the prefixed landing path
if (returnTo.slice(-1) === '/') {
returnTo = returnTo.slice(0, -1);
}
returnTo += haveSamePath(redirectBase, returnTo) ? '/learn' : '';
return res.redirectWithFlash(returnTo);
} else {
return res.redirectWithFlash(`${redirectBase}/email-sign-up`);

View File

@ -50,10 +50,7 @@ function normalizeParams(
return { returnTo, origin, pathPrefix };
}
// TODO: tests!
// TODO: ensure origin and pathPrefix validation happens first
// (it needs a dedicated function that can be called from here and getReturnTo)
function getRedirectBase(origin, pathPrefix) {
function getPrefixedLandingPath(origin, pathPrefix) {
const redirectPathSegment = pathPrefix ? `/${pathPrefix}` : '';
return `${origin}${redirectPathSegment}`;
}
@ -70,14 +67,14 @@ function getRedirectParams(req, _normalizeParams = normalizeParams) {
return _normalizeParams({ returnTo: returnUrl.href, origin, pathPrefix });
}
function isRootPath(redirectBase, returnUrl) {
function haveSamePath(redirectBase, returnUrl) {
const base = new URL(redirectBase);
const url = new URL(returnUrl);
return base.pathname === url.pathname;
}
module.exports.getReturnTo = getReturnTo;
module.exports.getRedirectBase = getRedirectBase;
module.exports.getPrefixedLandingPath = getPrefixedLandingPath;
module.exports.normalizeParams = normalizeParams;
module.exports.getRedirectParams = getRedirectParams;
module.exports.isRootPath = isRootPath;
module.exports.haveSamePath = haveSamePath;

View File

@ -36,6 +36,7 @@
Cypress.Commands.add('login', () => {
cy.visit('/');
cy.contains("Get started (it's free)").click();
cy.url().should('eq', Cypress.config().baseUrl + '/learn/');
cy.contains('Welcome back');
});