feat: ability to edit/delete users with master administrator

This commit is contained in:
diced 2022-10-22 14:50:53 -07:00
parent 4ef82bdff4
commit 615cbddc89
No known key found for this signature in database
GPG key ID: 370BD1BA142842D1
8 changed files with 35 additions and 8 deletions

View file

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "superAdmin" BOOLEAN NOT NULL DEFAULT false;

View file

@ -17,6 +17,7 @@ model User {
avatar String? avatar String?
token String token String
administrator Boolean @default(false) administrator Boolean @default(false)
superAdmin Boolean @default(false)
systemTheme String @default("system") systemTheme String @default("system")
embedTitle String? embedTitle String?
embedColor String @default("#2f3136") embedColor String @default("#2f3136")

View file

@ -7,14 +7,15 @@ import useFetch from 'hooks/useFetch';
export function EditUserModal({ open, setOpen, updateUsers, user }) { export function EditUserModal({ open, setOpen, updateUsers, user }) {
let form; let form;
if (user) if (user) {
form = useForm({ form = useForm({
initialValues: { initialValues: {
username: user?.username, username: user.username,
password: '', password: '',
administrator: user?.administrator, administrator: user.administrator,
}, },
}); });
}
const onSubmit = async (values) => { const onSubmit = async (values) => {
const cleanUsername = values.username.trim(); const cleanUsername = values.username.trim();

View file

@ -12,7 +12,7 @@ import { CreateUserModal } from './CreateUserModal';
import { EditUserModal } from './EditUserModal'; import { EditUserModal } from './EditUserModal';
export default function Users() { export default function Users() {
const user = useRecoilValue(userSelector); const self = useRecoilValue(userSelector);
const router = useRouter(); const router = useRouter();
const modals = useModals(); const modals = useModals();
@ -95,7 +95,7 @@ export default function Users() {
<SimpleGrid cols={3} spacing='lg' breakpoints={[{ maxWidth: 'sm', cols: 1, spacing: 'sm' }]}> <SimpleGrid cols={3} spacing='lg' breakpoints={[{ maxWidth: 'sm', cols: 1, spacing: 'sm' }]}>
{users.length {users.length
? users ? users
.filter((x) => x.username !== user.username) .filter((x) => x.username !== self.username)
.map((user) => ( .map((user) => (
<Card key={user.id} sx={{ maxWidth: '100%' }}> <Card key={user.id} sx={{ maxWidth: '100%' }}>
<Group position='apart'> <Group position='apart'>
@ -114,7 +114,7 @@ export default function Users() {
</Stack> </Stack>
</Group> </Group>
<Group position='right'> <Group position='right'>
{user.administrator ? null : ( {user.administrator && !self.superAdmin ? null : (
<> <>
<ActionIcon <ActionIcon
aria-label='edit' aria-label='edit'

View file

@ -10,6 +10,7 @@ export interface User {
domains: string[]; domains: string[];
avatar?: string; avatar?: string;
administrator: boolean; administrator: boolean;
superAdmin: boolean;
} }
export const userState = atom({ export const userState = atom({

View file

@ -27,13 +27,13 @@ async function handler(req: NextApiReq, res: NextApiRes) {
const newTarget = await prisma.user.delete({ const newTarget = await prisma.user.delete({
where: { id: target.id }, where: { id: target.id },
}); });
if (newTarget.administrator) return res.error('cannot delete administrator'); if (newTarget.administrator && !user.superAdmin) return res.error('cannot delete administrator');
delete newTarget.password; delete newTarget.password;
return res.json(newTarget); return res.json(newTarget);
} else if (req.method === 'PATCH') { } else if (req.method === 'PATCH') {
if (target.administrator) return res.forbid('cannot modify administrator'); if (target.administrator && !user.superAdmin) return res.forbid('cannot modify administrator');
if (req.body.password) { if (req.body.password) {
const hashed = await hashPassword(req.body.password); const hashed = await hashPassword(req.body.password);

View file

@ -68,6 +68,7 @@ async function handler(req: NextApiReq, res: NextApiRes) {
username: true, username: true,
id: true, id: true,
administrator: true, administrator: true,
superAdmin: true,
token: true, token: true,
embedColor: true, embedColor: true,
embedTitle: true, embedTitle: true,

View file

@ -39,6 +39,26 @@ async function start() {
const prisma = new PrismaClient(); const prisma = new PrismaClient();
const admin = await prisma.user.findFirst({
where: {
id: 1,
OR: {
username: 'administrator',
},
},
});
if (admin) {
await prisma.user.update({
where: {
id: admin.id,
},
data: {
superAdmin: true,
},
});
}
if (config.datasource.type === 'local') { if (config.datasource.type === 'local') {
await mkdir(config.datasource.local.directory, { recursive: true }); await mkdir(config.datasource.local.directory, { recursive: true });
} }
@ -99,6 +119,7 @@ async function start() {
await nextServer.prepare(); await nextServer.prepare();
} catch (e) { } catch (e) {
console.log(e); console.log(e);
process.exit(1);
} }
const http = createServer((req, res) => { const http = createServer((req, res) => {