feat: add permission section to create user page (#1524)

* feat: add permission section to create user page

* fix: deepsource issues
This commit is contained in:
Meier Lukas
2024-11-23 17:18:29 +01:00
committed by GitHub
parent 8fea983c2e
commit 1fc48f9db0
7 changed files with 232 additions and 32 deletions

View File

@@ -100,14 +100,33 @@ export const groupRouter = createTRPCRouter({
};
}),
// Is protected because also used in board access / integration access forms
selectable: protectedProcedure.query(async ({ ctx }) => {
return await ctx.db.query.groups.findMany({
columns: {
id: true,
name: true,
},
});
}),
selectable: protectedProcedure
.input(z.object({ withPermissions: z.boolean().default(false) }).optional())
.query(async ({ ctx, input }) => {
const withPermissions = input?.withPermissions && ctx.session.user.permissions.includes("admin");
if (!withPermissions) {
return await ctx.db.query.groups.findMany({
columns: {
id: true,
name: true,
},
});
}
const groups = await ctx.db.query.groups.findMany({
columns: {
id: true,
name: true,
},
with: { permissions: { columns: { permission: true } } },
});
return groups.map((group) => ({
...group,
permissions: group.permissions.map((permission) => permission.permission),
}));
}),
search: permissionRequiredProcedure
.requiresPermission("admin")
.input(

View File

@@ -78,7 +78,11 @@ export const userRouter = createTRPCRouter({
throwIfCredentialsDisabled();
await checkUsernameAlreadyTakenAndThrowAsync(ctx.db, "credentials", input.username);
await createUserAsync(ctx.db, input);
const userId = await createUserAsync(ctx.db, input);
if (input.groupIds.length >= 1) {
await ctx.db.insert(groupMembers).values(input.groupIds.map((groupId) => ({ groupId, userId })));
}
}),
setProfileImage: protectedProcedure
.input(
@@ -459,7 +463,7 @@ export const userRouter = createTRPCRouter({
}),
});
const createUserAsync = async (db: Database, input: z.infer<typeof validation.user.create>) => {
const createUserAsync = async (db: Database, input: z.infer<typeof validation.user.baseCreate>) => {
const salt = await createSaltAsync();
const hashedPassword = await hashPasswordAsync(input.password, salt);

View File

@@ -1943,9 +1943,10 @@
"security": {
"label": "Security"
},
"permissions": {
"label": "Permissions",
"description": "Coming soon"
"groups": {
"label": "Groups",
"title": "Select all groups user should be member of",
"description": "The {everyoneGroup} group is assigned to all users and can not be removed."
},
"review": {
"label": "Review"

View File

@@ -49,7 +49,7 @@ const confirmPasswordRefine = [
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] satisfies [(args: any) => boolean, unknown];
const createUserSchema = z
const baseCreateUserSchema = z
.object({
username: usernameSchema,
password: passwordSchema,
@@ -58,7 +58,9 @@ const createUserSchema = z
})
.refine(confirmPasswordRefine[0], confirmPasswordRefine[1]);
const initUserSchema = createUserSchema;
const createUserSchema = baseCreateUserSchema.and(z.object({ groupIds: z.array(z.string()) }));
const initUserSchema = baseCreateUserSchema;
const signInSchema = z.object({
name: z.string().min(1),
@@ -124,6 +126,7 @@ export const userSchemas = {
registrationApi: registrationSchemaApi,
init: initUserSchema,
create: createUserSchema,
baseCreate: baseCreateUserSchema,
password: passwordSchema,
editProfile: editProfileSchema,
changePassword: changePasswordSchema,