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:
@@ -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();
|
||||
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user