feat: allow ad-hoc creation of new teams (#3964)
Co-authored-by: Tom Moor <tom@getoutline.com>
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
import invariant from "invariant";
|
||||
import Router from "koa-router";
|
||||
import { RateLimiterStrategy } from "@server/RateLimiter";
|
||||
import teamCreator from "@server/commands/teamCreator";
|
||||
import teamUpdater from "@server/commands/teamUpdater";
|
||||
import { sequelize } from "@server/database/sequelize";
|
||||
import auth from "@server/middlewares/authentication";
|
||||
import { rateLimiter } from "@server/middlewares/rateLimiter";
|
||||
import { Team, TeamDomain } from "@server/models";
|
||||
import { Event, Team, TeamDomain, User } from "@server/models";
|
||||
import { authorize } from "@server/policies";
|
||||
import { presentTeam, presentPolicies } from "@server/presenters";
|
||||
import { assertUuid } from "@server/validation";
|
||||
@@ -69,4 +72,83 @@ router.post(
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
"teams.create",
|
||||
auth(),
|
||||
rateLimiter(RateLimiterStrategy.FivePerHour),
|
||||
async (ctx) => {
|
||||
const { user } = ctx.state;
|
||||
const { name } = ctx.body;
|
||||
|
||||
const existingTeam = await Team.scope(
|
||||
"withAuthenticationProviders"
|
||||
).findByPk(user.teamId, {
|
||||
rejectOnEmpty: true,
|
||||
});
|
||||
|
||||
authorize(user, "createTeam", existingTeam);
|
||||
|
||||
const authenticationProviders = existingTeam.authenticationProviders.map(
|
||||
(provider) => {
|
||||
return {
|
||||
name: provider.name,
|
||||
providerId: provider.providerId,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
invariant(
|
||||
authenticationProviders?.length,
|
||||
"Team must have at least one authentication provider"
|
||||
);
|
||||
|
||||
const [team, newUser] = await sequelize.transaction(async (transaction) => {
|
||||
const team = await teamCreator({
|
||||
name,
|
||||
subdomain: name,
|
||||
authenticationProviders,
|
||||
ip: ctx.ip,
|
||||
transaction,
|
||||
});
|
||||
|
||||
const newUser = await User.create(
|
||||
{
|
||||
teamId: team.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
isAdmin: true,
|
||||
avatarUrl: user.avatarUrl,
|
||||
},
|
||||
{ transaction }
|
||||
);
|
||||
|
||||
await Event.create(
|
||||
{
|
||||
name: "users.create",
|
||||
actorId: user.id,
|
||||
userId: newUser.id,
|
||||
teamId: newUser.teamId,
|
||||
data: {
|
||||
name: newUser.name,
|
||||
},
|
||||
ip: ctx.ip,
|
||||
},
|
||||
{ transaction }
|
||||
);
|
||||
|
||||
return [team, newUser];
|
||||
});
|
||||
|
||||
ctx.body = {
|
||||
success: true,
|
||||
data: {
|
||||
team: presentTeam(team),
|
||||
transferUrl: `${
|
||||
team.url
|
||||
}/auth/redirect?token=${newUser?.getTransferToken()}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user