Closes #805 - Unable to signin on self-hosted installations with non-www subdomain

This commit is contained in:
Tom Moor 2018-11-18 12:07:11 -08:00
parent 3c563e3001
commit 3718a9609d
4 changed files with 39 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import UsersStore from 'stores/UsersStore';
import CollectionsStore from 'stores/CollectionsStore';
import IntegrationsStore from 'stores/IntegrationsStore';
import LoadingIndicator from 'components/LoadingIndicator';
import { isCustomSubdomain } from 'shared/utils/domains';
type Props = {
auth: AuthStore,
@ -26,13 +27,12 @@ const Auth = observer(({ auth, children }: Props) => {
}
// If we're authenticated but viewing a subdomain that doesn't match the
// authenticated team then kick the user to the teams subdomain.
// www is a special case, as always
// currently authenticated team then kick the user to the teams subdomain.
if (
process.env.SUBDOMAINS_ENABLED &&
team.subdomain &&
!hostname.startsWith(`${team.subdomain}.`) &&
!hostname.startsWith('www.')
isCustomSubdomain(hostname) &&
!hostname.startsWith(`${team.subdomain}.`)
) {
window.location.href = `${team.url}${window.location.pathname}`;
return <LoadingIndicator />;

View File

@ -8,6 +8,7 @@ import serve from 'koa-static';
import parseDomain from 'parse-domain';
import apexRedirect from './middlewares/apexRedirect';
import renderpage from './utils/renderpage';
import { isCustomSubdomain } from '../shared/utils/domains';
import { robotsResponse } from './utils/robots';
import { NotFoundError } from './errors';
import { Team } from './models';
@ -67,8 +68,6 @@ router.get('/changelog', async ctx => {
router.get('/', async ctx => {
const lastSignedIn = ctx.cookies.get('lastSignedIn');
const accessToken = ctx.cookies.get('accessToken');
const domain = parseDomain(ctx.request.hostname);
const subdomain = domain ? domain.subdomain : undefined;
// Because we render both the signed in and signed out views depending
// on a cookie it's important that the browser does not render from cache.
@ -82,11 +81,16 @@ router.get('/', async ctx => {
// If we're on a custom subdomain then we display a slightly different signed
// out view that includes the teams basic information.
if (subdomain && subdomain !== 'www') {
if (
process.env.SUBDOMAINS_ENABLED === 'true' &&
isCustomSubdomain(ctx.request.hostname)
) {
const domain = parseDomain(ctx.request.hostname);
const subdomain = domain ? domain.subdomain : undefined;
const team = await Team.find({
where: { subdomain },
});
if (team && process.env.SUBDOMAINS_ENABLED === 'true') {
if (team) {
return renderpage(
ctx,
<SubdomainSignin

View File

@ -9,6 +9,13 @@ export function stripSubdomain(hostname: string) {
return parsed.domain;
}
export function isCustomSubdomain(hostname: string) {
const parsed = parseDomain(hostname);
if (!parsed) return false;
if (!parsed.subdomain || parsed.subdomain === 'www') return false;
return true;
}
export const RESERVED_SUBDOMAINS = [
'about',
'account',

View File

@ -1,5 +1,5 @@
/* eslint-disable flowtype/require-valid-file-annotation */
import { stripSubdomain } from './domains';
import { stripSubdomain, isCustomSubdomain } from './domains';
describe('#stripSubdomain', () => {
test('to work with localhost', () => {
@ -15,3 +15,22 @@ describe('#stripSubdomain', () => {
expect(stripSubdomain('test.example.com:3000')).toBe('example.com');
});
});
describe('#isCustomSubdomain', () => {
test('to work with localhost', () => {
expect(isCustomSubdomain('localhost')).toBe(false);
});
test('to return false for domains without a subdomain', () => {
expect(isCustomSubdomain('example')).toBe(false);
expect(isCustomSubdomain('example.com')).toBe(false);
expect(isCustomSubdomain('example.org:3000')).toBe(false);
});
test('to return false for www', () => {
expect(isCustomSubdomain('www.example.com')).toBe(false);
expect(isCustomSubdomain('www.example.com:3000')).toBe(false);
});
test('to return true for subdomains', () => {
expect(isCustomSubdomain('test.example.com')).toBe(true);
expect(isCustomSubdomain('test.example.com:3000')).toBe(true);
});
});