diff --git a/app/components/Auth.js b/app/components/Auth.js index 2a6b33ac1..19f111323 100644 --- a/app/components/Auth.js +++ b/app/components/Auth.js @@ -24,6 +24,14 @@ const Auth = observer(({ auth, children }: Props) => { return ; } + if ( + team.subdomain && + !window.location.hostname.startsWith(team.subdomain) + ) { + window.location.href = `${team.url}${window.location.pathname}`; + return ; + } + // Only initialize stores once. Kept in global scope because otherwise they // will get overridden on route change if (!authenticatedStores) { diff --git a/app/components/Button/Button.js b/app/components/Button/Button.js index 1e455e654..a37921bf1 100644 --- a/app/components/Button/Button.js +++ b/app/components/Button/Button.js @@ -32,7 +32,7 @@ const RealButton = styled.button` } &:disabled { - opacity: 0.8; + opacity: 0.6; cursor: default; } diff --git a/app/scenes/Settings/Details.js b/app/scenes/Settings/Details.js index 927ca356f..2c33a54ad 100644 --- a/app/scenes/Settings/Details.js +++ b/app/scenes/Settings/Details.js @@ -84,18 +84,10 @@ class Details extends React.Component {

Details

- {team.slackConnected && ( - - This team is connected to a Slack team. Your - colleagues can join by signing in with their Slack account details. - - )} - {team.googleConnected && ( - - This team is connected to a Google domain. Your - colleagues can join by signing in with their Google account. - - )} + + These details affect the way that your Outline appears to everyone on + the team. + Logo @@ -129,13 +121,14 @@ class Details extends React.Component { name="subdomain" value={this.subdomain || ''} onChange={this.handleSubdomainChange} - placeholder="Optional" - autocomplete={false} + autocomplete="off" + minLength={4} + maxLength={32} short /> {this.subdomain && ( - You will access your knowledgebase at{' '} + Your knowledgebase will be accessed at{' '} {this.subdomain}.getoutline.com )} diff --git a/app/utils/ApiClient.js b/app/utils/ApiClient.js index ff2fcc4f5..de937a5df 100644 --- a/app/utils/ApiClient.js +++ b/app/utils/ApiClient.js @@ -1,5 +1,5 @@ // @flow -import _ from 'lodash'; +import { map } from 'lodash'; import invariant from 'invariant'; import stores from 'stores'; @@ -51,7 +51,7 @@ class ApiClient { body, headers, redirect: 'follow', - credentials: 'include', + credentials: 'omit', }); if (response.status >= 200 && response.status < 300) { @@ -89,7 +89,7 @@ class ApiClient { // Helpers constructQueryString = (data: Object) => { - return _.map(data, (v, k) => { + return map(data, (v, k) => { return `${encodeURIComponent(k)}=${encodeURIComponent(v)}`; }).join('&'); }; diff --git a/server/models/Team.js b/server/models/Team.js index 4c7b6b34e..bf8fe1fc8 100644 --- a/server/models/Team.js +++ b/server/models/Team.js @@ -1,6 +1,6 @@ // @flow import uuid from 'uuid'; -import url from 'url'; +import { URL } from 'url'; import { DataTypes, sequelize, Op } from '../sequelize'; import { publicS3Endpoint, uploadToS3FromUrl } from '../utils/s3'; import { RESERVED_SUBDOMAINS } from '../utils/domains'; @@ -47,11 +47,9 @@ const Team = sequelize.define( url() { if (!this.subdomain) return process.env.URL; - const u = url.parse(process.env.URL); - if (u.hostname) { - u.hostname = `${this.subdomain}.${u.hostname}`; - return u.href; - } + const url = new URL(process.env.URL); + url.host = `${this.subdomain}.${url.host}`; + return url.href.replace(/\/$/, ''); }, }, } diff --git a/server/routes.js b/server/routes.js index bb1fd2960..fa8c6d0f1 100644 --- a/server/routes.js +++ b/server/routes.js @@ -67,8 +67,8 @@ router.get('/changelog', async ctx => { router.get('/', async ctx => { const lastSignedIn = ctx.cookies.get('lastSignedIn'); const accessToken = ctx.cookies.get('accessToken'); - const subdomain = parseDomain(ctx.request.hostname).subdomain; - console.log('subdomain', subdomain); + const domain = parseDomain(ctx.request.hostname); + const subdomain = domain ? domain.subdomain : false; if (accessToken) { return renderapp(ctx);