feat: allow admins to require invites before user accounts can be created (#3381)

* allow admins to require invites before user accounts can be created
* use new dialog component for general confirmation dialogs
This commit is contained in:
Nan Yu
2022-04-19 12:27:23 -07:00
committed by GitHub
parent 1b913054e8
commit 233f3af667
19 changed files with 313 additions and 136 deletions

View File

@@ -21,6 +21,7 @@ const teamUpdater = async ({ params, user, team, ip }: TeamUpdaterProps) => {
collaborativeEditing,
defaultCollectionId,
defaultUserRole,
inviteRequired,
} = params;
if (subdomain !== undefined && process.env.SUBDOMAINS_ENABLED === "true") {
@@ -54,6 +55,9 @@ const teamUpdater = async ({ params, user, team, ip }: TeamUpdaterProps) => {
if (defaultUserRole !== undefined) {
team.defaultUserRole = defaultUserRole;
}
if (inviteRequired !== undefined) {
team.inviteRequired = inviteRequired;
}
const changes = team.changed();

View File

@@ -184,7 +184,7 @@ describe("userCreator", () => {
});
it("should create a user from an invited user", async () => {
const team = await buildTeam();
const team = await buildTeam({ inviteRequired: true });
const invite = await buildInvite({
teamId: team.id,
email: "invite@example.com",
@@ -210,4 +210,33 @@ describe("userCreator", () => {
expect(user.email).toEqual(invite.email);
expect(isNewUser).toEqual(true);
});
it("should reject an uninvited user when invites are required", async () => {
const team = await buildTeam({ inviteRequired: true });
const authenticationProviders = await team.$get("authenticationProviders");
const authenticationProvider = authenticationProviders[0];
let error;
try {
await userCreator({
name: "Uninvited User",
email: "invite@ExamPle.com",
teamId: team.id,
ip,
authentication: {
authenticationProviderId: authenticationProvider.id,
providerId: "fake-service-id",
accessToken: "123",
scopes: ["read"],
},
});
} catch (err) {
error = err;
}
expect(error && error.toString()).toContain(
"You need an invite to join this team"
);
});
});

View File

@@ -1,4 +1,5 @@
import { Op } from "sequelize";
import { InviteRequiredError } from "@server/errors";
import { Event, Team, User, UserAuthentication } from "@server/models";
type UserCreatorResult = {
@@ -144,9 +145,16 @@ export default async function userCreator({
try {
const team = await Team.findByPk(teamId, {
attributes: ["defaultUserRole"],
attributes: ["defaultUserRole", "inviteRequired"],
transaction,
});
// If the team settings are set to require invites, and the user is not already invited,
// throw an error and fail user creation.
if (team?.inviteRequired && !invite) {
throw InviteRequiredError();
}
const defaultUserRole = team?.defaultUserRole;
const user = await User.create(