allow moderators to ban user (#1458)

* allow mod to ban user

* fix middleware
This commit is contained in:
notmd
2023-02-11 15:10:10 +07:00
committed by GitHub
parent 406cf28f79
commit 71326d485e
7 changed files with 48 additions and 29 deletions
+17
View File
@@ -85,6 +85,7 @@
"msw-storybook-addon": "^1.7.0",
"prettier": "2.8.1",
"prisma": "^4.7.1",
"ts-essentials": "^9.3.0",
"ts-node": "^10.9.1",
"typescript": "^4.9.4"
}
@@ -36509,6 +36510,15 @@
"node": ">=6.10"
}
},
"node_modules/ts-essentials": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-9.3.0.tgz",
"integrity": "sha512-XeiCboEyBG8UqXZtXl59bWEi4ZgOqRsogFDI6WDGIF1LmzbYiAkIwjkXN6zZWWl4re/lsOqMlYfe8KA0XiiEPw==",
"dev": true,
"peerDependencies": {
"typescript": ">=4.1.0"
}
},
"node_modules/ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
@@ -66035,6 +66045,13 @@
"resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
"integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="
},
"ts-essentials": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-9.3.0.tgz",
"integrity": "sha512-XeiCboEyBG8UqXZtXl59bWEi4ZgOqRsogFDI6WDGIF1LmzbYiAkIwjkXN6zZWWl4re/lsOqMlYfe8KA0XiiEPw==",
"dev": true,
"requires": {}
},
"ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+1
View File
@@ -103,6 +103,7 @@
"msw-storybook-addon": "^1.7.0",
"prettier": "2.8.1",
"prisma": "^4.7.1",
"ts-essentials": "^9.3.0",
"ts-node": "^10.9.1",
"typescript": "^4.9.4"
},
+6 -3
View File
@@ -1,8 +1,11 @@
import { LucideIcon } from "lucide-react";
import { LucideIcon, LucideProps } from "lucide-react";
import { forwardRef } from "react";
export const Discord: LucideIcon = ({ size = 24, ...rest }) => {
// eslint-disable-next-line react/display-name
export const Discord: LucideIcon = forwardRef<SVGSVGElement, LucideProps>(function ({ size = 24, ...rest }, ref) {
return (
<svg
ref={ref}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 127.14 96.36"
fill="currentColor"
@@ -13,4 +16,4 @@ export const Discord: LucideIcon = ({ size = 24, ...rest }) => {
<path d="M107.7 8.07A105.15 105.15 0 0 0 81.47 0a72.06 72.06 0 0 0-3.36 6.83 97.68 97.68 0 0 0-29.11 0A72.37 72.37 0 0 0 45.64 0a105.89 105.89 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.73 105.73 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.42 68.42 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2a68.68 68.68 0 0 1-10.87 5.19 77 77 0 0 0 6.89 11.1 105.25 105.25 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15ZM42.45 65.69C36.18 65.69 31 60 31 53s5-12.74 11.43-12.74S54 46 53.89 53s-5.05 12.69-11.44 12.69Zm42.24 0C78.41 65.69 73.25 60 73.25 53s5-12.74 11.44-12.74S96.23 46 96.12 53s-5.04 12.69-11.43 12.69Z" />
</svg>
);
};
});
@@ -8,7 +8,7 @@ import NextLink from "next/link";
import { ROUTES } from "src/lib/routes";
import { Message } from "src/types/Conversation";
import { isKnownEmoji } from "src/types/Emoji";
import { StrictOmit } from "src/types/utils";
import { StrictOmit } from "ts-essentials";
import { DataTable, DataTableProps } from "../DataTable/DataTable";
import { DataTableAction } from "../DataTable/DataTableAction";
+10 -4
View File
@@ -1,9 +1,15 @@
import { Select, SelectProps } from "@chakra-ui/react";
import { forwardRef } from "react";
import { ElementOf } from "src/types/utils";
import { ValueOf } from "ts-essentials";
export const roles = ["general", "admin", "banned", "moderator"] as const;
export type Role = ElementOf<typeof roles>;
export const ROLES = {
GERNERAL: "general",
BANNED: "banned",
ADMIN: "admin",
MODERATOR: "moderator",
} as const;
export type Role = ValueOf<typeof ROLES>;
type RoleSelectProps = Omit<SelectProps, "defaultValue"> & {
defaultValue?: Role;
@@ -13,7 +19,7 @@ type RoleSelectProps = Omit<SelectProps, "defaultValue"> & {
export const RoleSelect = forwardRef<HTMLSelectElement, RoleSelectProps>((props, ref) => {
return (
<Select {...props} ref={ref}>
{roles.map((role) => (
{Object.values(ROLES).map((role) => (
<option value={role} key={role}>
{role}
</option>
+13 -11
View File
@@ -1,21 +1,23 @@
import { withRole } from "src/lib/auth";
import { ROLES } from "src/components/RoleSelect";
import { withAnyRole } from "src/lib/auth";
import { createApiClient } from "src/lib/oasst_client_factory";
import prisma from "src/lib/prismadb";
/**
* Update's the user's data in the database. Accessible only to admins.
*/
const handler = withRole("admin", async (req, res, token) => {
const { id, auth_method, user_id, notes, role, show_on_leaderboard } = req.body;
const oasstApiClient = await createApiClient(token);
// If the user is authorized by the web, update their role.
if (auth_method === "local") {
await prisma.user.update({
where: { id },
data: { role },
});
const handler = withAnyRole(["admin", "moderator"], async (req, res, token) => {
const { id, user_id, notes, role, show_on_leaderboard } = req.body;
// mod can't update user role to mod or admin
if (token.role === ROLES.MODERATOR && (role === ROLES.MODERATOR || role === ROLES.ADMIN)) {
return res.status(403).json({});
}
const oasstApiClient = await createApiClient(token);
await prisma.user.update({
where: { id },
data: { role },
});
// Tell the backend the user's enabled or not enabled status.
await oasstApiClient.set_user_status(user_id, role !== "banned", notes, show_on_leaderboard);
-10
View File
@@ -1,10 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// https://github.com/ts-essentials/ts-essentials/blob/25cae45c162f8784e3cdae8f43783d0c66370a57/lib/types.ts#L437
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ElementOf<T extends readonly any[]> = T extends readonly (infer ET)[] ? ET : never;
type AnyRecord<T = any> = Record<KeyofBase, T>;
type KeyofBase = keyof any;
export type AnyArray<T = any> = Array<T> | ReadonlyArray<T>;
export type StrictOmit<T extends AnyRecord, K extends keyof T> = T extends AnyArray ? never : Omit<T, K>;