diff --git a/package.json b/package.json index 3b7d772f..95c901d1 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "shared" ], "moduleNameMapper": { + "^shared/(.*)$": "/shared/$1", "^.*[.](s?css|css)$": "/__mocks__/styleMock.js", "^.*[.](gif|ttf|eot|svg)$": "/__test__/fileMock.js" }, diff --git a/server/auth/google.js b/server/auth/google.js index 48b16019..6c00ef3c 100644 --- a/server/auth/google.js +++ b/server/auth/google.js @@ -92,14 +92,8 @@ router.get('google.callback', auth({ required: false }), async ctx => { }); if (isFirstUser) { - await team.createFirstCollection(user.id); - - // attempt to give the new team a subdomain based on google hosted domain - try { - await team.update({ subdomain: hostname }); - } catch (err) { - // subdomain was invalid or already used - } + await team.provisionFirstCollection(user.id); + await team.provisionSubdomain(hostname); } // set cookies on response and redirect to team subdomain diff --git a/server/auth/slack.js b/server/auth/slack.js index 24741e72..45ee15f0 100644 --- a/server/auth/slack.js +++ b/server/auth/slack.js @@ -61,14 +61,8 @@ router.get('slack.callback', auth({ required: false }), async ctx => { }); if (isFirstUser) { - await team.createFirstCollection(user.id); - - // attempt to give the new team the same subdomain as they use on slack - try { - await team.update({ subdomain: data.team.domain }); - } catch (err) { - // subdomain was invalid or already used - } + await team.provisionFirstCollection(user.id); + await team.provisionSubdomain(data.team.domain); } // set cookies on response and redirect to team subdomain diff --git a/server/models/Team.js b/server/models/Team.js index 265e566b..47ee9c83 100644 --- a/server/models/Team.js +++ b/server/models/Team.js @@ -85,7 +85,22 @@ const uploadAvatar = async model => { } }; -Team.prototype.createFirstCollection = async function(userId) { +Team.prototype.provisionSubdomain = async function(subdomain) { + let append = 0; + + while (true) { + try { + await this.update({ subdomain }); + break; + } catch (err) { + // subdomain was invalid or already used, try again + subdomain = `${subdomain}${++append}`; + } + } + return subdomain; +}; + +Team.prototype.provisionFirstCollection = async function(userId) { return await Collection.create({ name: 'General', description: 'Your first Collection', diff --git a/server/models/Team.test.js b/server/models/Team.test.js new file mode 100644 index 00000000..6172923e --- /dev/null +++ b/server/models/Team.test.js @@ -0,0 +1,19 @@ +/* eslint-disable flowtype/require-valid-file-annotation */ +import { flushdb } from '../test/support'; +import { buildTeam } from '../test/factories'; + +beforeEach(flushdb); + +it('should set subdomain if available', async () => { + const team = await buildTeam(); + const subdomain = await team.provisionSubdomain('testy'); + expect(subdomain).toEqual('testy'); + expect(team.subdomain).toEqual('testy'); +}); + +it('should set subdomain with append if unavailable', async () => { + const team = await buildTeam({ subdomain: 'myteam' }); + const subdomain = await team.provisionSubdomain('myteam'); + expect(subdomain).toEqual('myteam1'); + expect(team.subdomain).toEqual('myteam1'); +});