Filtry, omezení, audio náhled
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 294 KiB After Width: | Height: | Size: 50 KiB |
5
scripts/migrations/09_rename_reason.sql
Normal file
5
scripts/migrations/09_rename_reason.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE restrictions
|
||||
RENAME COLUMN reason TO note;
|
||||
|
||||
ALTER TABLE filters
|
||||
RENAME COLUMN reason TO note;
|
||||
@@ -13,11 +13,11 @@ const createFilter = async (
|
||||
filter_type: "replace" | "block" | "ban",
|
||||
filter_value: string,
|
||||
priority: number,
|
||||
reason: string | null,
|
||||
note: string | null,
|
||||
created_by: string,
|
||||
) => {
|
||||
const result = await postgres.query<Filter>(
|
||||
"INSERT INTO filters (board, target_type, target_value, filter_type, filter_value, priority, reason, created_by) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *",
|
||||
"INSERT INTO filters (board, target_type, target_value, filter_type, filter_value, priority, note, created_by) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *",
|
||||
[
|
||||
board,
|
||||
target_type,
|
||||
@@ -25,7 +25,7 @@ const createFilter = async (
|
||||
filter_type,
|
||||
filter_value,
|
||||
priority,
|
||||
reason,
|
||||
note,
|
||||
created_by,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -12,18 +12,18 @@ const createRestriction = async (
|
||||
target_mode: "blacklist" | "whitelist",
|
||||
target_value: string[],
|
||||
restrictions: string[],
|
||||
reason: string | null,
|
||||
note: string | null,
|
||||
created_by: string,
|
||||
) => {
|
||||
const result = await postgres.query(
|
||||
"INSERT INTO restrictions (board, target_type, target_mode, target_value, restrictions, reason, created_by) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *",
|
||||
"INSERT INTO restrictions (board, target_type, target_mode, target_value, restrictions, note, created_by) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *",
|
||||
[
|
||||
board,
|
||||
target_type,
|
||||
target_mode,
|
||||
JSON.stringify(target_value),
|
||||
JSON.stringify(restrictions),
|
||||
reason,
|
||||
note,
|
||||
created_by,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -85,7 +85,7 @@ const activeRestrictions = (
|
||||
case "region":
|
||||
active ||= isRestricted(
|
||||
restriction.target_value,
|
||||
req.ipInfo.region,
|
||||
`${req.ipInfo.country}-${req.ipInfo.region}`,
|
||||
restriction.target_mode,
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -96,7 +96,7 @@ type Restriction = {
|
||||
target_mode: "blacklist" | "whitelist";
|
||||
target_value: string[];
|
||||
restrictions: string[];
|
||||
reason: string | null;
|
||||
note: string | null;
|
||||
created_by: string;
|
||||
created: Date;
|
||||
};
|
||||
|
||||
@@ -89,13 +89,13 @@ const zFilterValue = z
|
||||
.string()
|
||||
.max(2048, "Hodnota filtru musí mít maximálně 2048 znaků.");
|
||||
|
||||
const zFilterReason = z
|
||||
const zFilterNote = z
|
||||
.string()
|
||||
.max(512, "Důvod filtru musí mít maximálně 512 znaků.");
|
||||
.max(512, "Poznámka k filtru musí mít maximálně 512 znaků.");
|
||||
|
||||
const zBanReason = z
|
||||
.string()
|
||||
.max(512, "Důvod banu musí mít maximálně 512 znaků.");
|
||||
.max(512, "Poznámka k banu musí mít maximálně 512 znaků.");
|
||||
|
||||
export {
|
||||
zUrlEncodedValue,
|
||||
@@ -113,6 +113,6 @@ export {
|
||||
zFilterType,
|
||||
zFilterTargetValue,
|
||||
zFilterValue,
|
||||
zFilterReason,
|
||||
zFilterNote,
|
||||
zBanReason,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
zFilterReason,
|
||||
zFilterNote,
|
||||
zFilterTargetType,
|
||||
zFilterTargetValue,
|
||||
zFilterType,
|
||||
@@ -29,7 +29,7 @@ const CreateFilterForm = z
|
||||
filter_type: zRequiredField(zFilterType),
|
||||
filter_value: zRequiredField(zFilterValue),
|
||||
priority: zRequiredField(zPriority),
|
||||
reason: zOptionalField(zFilterReason),
|
||||
note: zOptionalField(zFilterNote),
|
||||
})
|
||||
.refine(
|
||||
(form) =>
|
||||
@@ -57,7 +57,7 @@ export {
|
||||
zFilterType,
|
||||
zFilterTargetValue,
|
||||
zFilterValue,
|
||||
zFilterReason,
|
||||
zFilterNote,
|
||||
CreateFilterForm,
|
||||
FilterActionsForm,
|
||||
UpdateFilterPriorityForm,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
zBoardID,
|
||||
zCheckbox,
|
||||
zDuration,
|
||||
zFilterReason,
|
||||
zFilterNote,
|
||||
zFilterType,
|
||||
zFilterValue,
|
||||
zMultiField,
|
||||
@@ -114,7 +114,7 @@ const ZPostActionsForm = z.object({
|
||||
filter_type: zOptionalField(zFilterType),
|
||||
filter_value: zOptionalField(zFilterValue),
|
||||
filter_priority: zOptionalField(zPriority).transform((value) => value ?? 0),
|
||||
filter_reason: zOptionalField(zFilterReason),
|
||||
filter_note: zOptionalField(zFilterNote),
|
||||
set_sticky: zCheckbox, // Primary
|
||||
sticky: zOptionalField(zPriority),
|
||||
toggle_lock: zCheckbox, // Primary
|
||||
|
||||
@@ -31,15 +31,15 @@ const zRestrictionTargetValues = z
|
||||
.string()
|
||||
.transform((value) =>
|
||||
value
|
||||
.split(/\s+/g)
|
||||
.split(/[\s,]+/)
|
||||
.map((segment) => segment.trim())
|
||||
.filter((segment) => segment !== ""),
|
||||
)
|
||||
.refine((values) => values.length > 0, "Cíl omezení nesmí být prázdný.");
|
||||
|
||||
const zRestrictionReason = z
|
||||
const zRestrictionNote = z
|
||||
.string()
|
||||
.max(512, "Důvod omezení musí mít maximálně 512 znaků.");
|
||||
.max(512, "Poznámka k omezení musí mít maximálně 512 znaků.");
|
||||
|
||||
const zNullableBoardField = zOptionalField(zBoardID);
|
||||
|
||||
@@ -50,7 +50,7 @@ const CreateRestrictionForm = z.object({
|
||||
target_mode: zRequiredField(zRestrictionTargetMode),
|
||||
target_value: zRequiredField(zRestrictionTargetValues),
|
||||
restrictions: zMultiField(zRestrictionFlag),
|
||||
reason: zOptionalField(zRestrictionReason),
|
||||
note: zOptionalField(zRestrictionNote),
|
||||
});
|
||||
|
||||
const RestrictionActionsForm = z.object({
|
||||
@@ -64,7 +64,7 @@ export {
|
||||
zRestrictionTargetMode,
|
||||
zRestrictionFlag,
|
||||
zRestrictionTargetValues,
|
||||
zRestrictionReason,
|
||||
zRestrictionNote,
|
||||
CreateRestrictionForm,
|
||||
RestrictionActionsForm,
|
||||
};
|
||||
|
||||
@@ -137,8 +137,8 @@ const PostActionsForm = ({ ctx }: PropsWithChildren<{ ctx: TemplateCtx }>) => (
|
||||
<FormField label="↳ Priorita filtru">
|
||||
<input name="filter_priority" type="number" value="0" />
|
||||
</FormField>
|
||||
<FormField label="↳ Důvod filtru (poznámka)">
|
||||
<input name="filter_reason" type="text" />
|
||||
<FormField label="↳ Poznámka k filtru">
|
||||
<input name="filter_note" type="text" />
|
||||
</FormField>
|
||||
</Form>
|
||||
)}
|
||||
|
||||
@@ -87,8 +87,8 @@ const uconfigMiddleware = (req: Request, res: Response, next: NextFunction) => {
|
||||
if (req.cookies.non_public_overboard) {
|
||||
req.uconfig.nonPublicOverboard = new Set(
|
||||
req.cookies.non_public_overboard
|
||||
.split(",")
|
||||
.map((val: string) => val.trim()),
|
||||
.split(/[\s,]+/)
|
||||
.map((segment: string) => segment.trim()),
|
||||
);
|
||||
} else {
|
||||
req.uconfig.nonPublicOverboard = new Set();
|
||||
|
||||
@@ -360,7 +360,7 @@ const modActions = async (
|
||||
form.filter_type as "replace" | "block" | "ban",
|
||||
form.filter_value as string,
|
||||
form.filter_priority,
|
||||
form.filter_reason,
|
||||
form.filter_note,
|
||||
req.user?.username as string,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,13 +21,21 @@ export default async (req: Request, res: Response) => {
|
||||
filter_type,
|
||||
filter_value,
|
||||
priority,
|
||||
reason,
|
||||
note,
|
||||
} = CreateFilterForm.parse(fields);
|
||||
|
||||
if (board !== null) {
|
||||
await readBoard(board);
|
||||
}
|
||||
|
||||
if (target_type === "regex") {
|
||||
try {
|
||||
new RegExp(target_value, "gimv");
|
||||
} catch (_) {
|
||||
throw new CzchanError("Neplatný RegEx", 400);
|
||||
}
|
||||
}
|
||||
|
||||
await createFilter(
|
||||
board,
|
||||
target_type,
|
||||
@@ -35,7 +43,7 @@ export default async (req: Request, res: Response) => {
|
||||
filter_type,
|
||||
filter_value,
|
||||
priority,
|
||||
reason,
|
||||
note,
|
||||
req.user?.username as string,
|
||||
);
|
||||
|
||||
|
||||
@@ -14,14 +14,8 @@ export default async (req: Request, res: Response) => {
|
||||
|
||||
const parser = formidable({});
|
||||
const [fields, _] = await parser.parse(req);
|
||||
const {
|
||||
board,
|
||||
target_type,
|
||||
target_mode,
|
||||
target_value,
|
||||
restrictions,
|
||||
reason,
|
||||
} = CreateRestrictionForm.parse(fields);
|
||||
const { board, target_type, target_mode, target_value, restrictions, note } =
|
||||
CreateRestrictionForm.parse(fields);
|
||||
|
||||
if (board !== null) {
|
||||
await readBoard(board);
|
||||
@@ -33,7 +27,7 @@ export default async (req: Request, res: Response) => {
|
||||
target_mode,
|
||||
target_value,
|
||||
restrictions,
|
||||
reason,
|
||||
note,
|
||||
req.user?.username as string,
|
||||
);
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ const FilterTable = ({
|
||||
<th>Typ filtru</th>
|
||||
<th>Hodnota</th>
|
||||
<th>Priorita</th>
|
||||
<th>Důvod (poznámka)</th>
|
||||
<th>Poznámka</th>
|
||||
<th>Vytvořil</th>
|
||||
<th>Vytvořen</th>
|
||||
</tr>
|
||||
@@ -154,9 +154,9 @@ const CreateForm = ({ boards }: PropsWithChildren<{ boards: Board[] }>) => (
|
||||
</FormField>
|
||||
<FormField label="Typ cíle">
|
||||
<select name="target_type">
|
||||
<option value="text">text</option>
|
||||
<option value="regex">regex</option>
|
||||
<option value="sha1">sha1</option>
|
||||
<option value="text">Text (s velikostí znaků)</option>
|
||||
<option value="regex">RegEx (flagy: gimv)</option>
|
||||
<option value="sha1">SHA1</option>
|
||||
<option value="phash">phash</option>
|
||||
</select>
|
||||
</FormField>
|
||||
@@ -165,9 +165,9 @@ const CreateForm = ({ boards }: PropsWithChildren<{ boards: Board[] }>) => (
|
||||
</FormField>
|
||||
<FormField label="Typ filtru">
|
||||
<select name="filter_type">
|
||||
<option value="replace">replace</option>
|
||||
<option value="block">block</option>
|
||||
<option value="ban">ban</option>
|
||||
<option value="replace">Nahradit</option>
|
||||
<option value="block">Zakázat</option>
|
||||
<option value="ban">Zabanovat</option>
|
||||
</select>
|
||||
</FormField>
|
||||
<FormField label="Hodnota filtru">
|
||||
@@ -176,8 +176,8 @@ const CreateForm = ({ boards }: PropsWithChildren<{ boards: Board[] }>) => (
|
||||
<FormField label="Priorita">
|
||||
<input name="priority" type="number" value="0" />
|
||||
</FormField>
|
||||
<FormField label="Důvod">
|
||||
<input name="reason" type="text" />
|
||||
<FormField label="Poznámka">
|
||||
<input name="note" type="text" />
|
||||
</FormField>
|
||||
<FormButton submit="Vytvořit" action="create_filter" />
|
||||
</Form>
|
||||
|
||||
@@ -66,7 +66,7 @@ const RestrictionTable = ({
|
||||
<th>Režim</th>
|
||||
<th>Hodnoty</th>
|
||||
<th>Omezení</th>
|
||||
<th>Důvod (poznámka)</th>
|
||||
<th>Poznámka</th>
|
||||
<th>Vytvořil</th>
|
||||
<th>Vytvořeno</th>
|
||||
</tr>
|
||||
@@ -117,11 +117,7 @@ const RestrictionRow = ({
|
||||
<td safe>{restriction.target_value.join(", ")}</td>
|
||||
<td safe>{restriction.restrictions.join(", ")}</td>
|
||||
<td>
|
||||
{restriction.reason !== null ? (
|
||||
<span safe>{restriction.reason}</span>
|
||||
) : (
|
||||
"-"
|
||||
)}
|
||||
{restriction.note !== null ? <span safe>{restriction.note}</span> : "-"}
|
||||
</td>
|
||||
<td safe>{restriction.created_by}</td>
|
||||
<td>
|
||||
@@ -148,16 +144,16 @@ const CreateForm = ({ boards }: PropsWithChildren<{ boards: Board[] }>) => (
|
||||
</FormField>
|
||||
<FormField label="Typ cíle">
|
||||
<select name="target_type">
|
||||
<option value="country">country</option>
|
||||
<option value="region">region</option>
|
||||
<option value="asn">asn</option>
|
||||
<option value="list">list</option>
|
||||
<option value="country">Země (ISO)</option>
|
||||
<option value="region">Region (ISO země)-(ISO regionu)</option>
|
||||
<option value="asn">ASN</option>
|
||||
<option value="list">Seznam</option>
|
||||
</select>
|
||||
</FormField>
|
||||
<FormField label="Režim">
|
||||
<select name="target_mode">
|
||||
<option value="blacklist">blacklist</option>
|
||||
<option value="whitelist">whitelist</option>
|
||||
<option value="blacklist">Blokovat hodnoty</option>
|
||||
<option value="whitelist">Blokovat nehodnoty</option>
|
||||
</select>
|
||||
</FormField>
|
||||
<FormField label="Hodnoty cíle">
|
||||
@@ -165,24 +161,24 @@ const CreateForm = ({ boards }: PropsWithChildren<{ boards: Board[] }>) => (
|
||||
</FormField>
|
||||
<FormField label="Omezení" wrapper>
|
||||
<label>
|
||||
<input name="restrictions" type="checkbox" value="post" /> post
|
||||
<input name="restrictions" type="checkbox" value="post" /> Příspěvky
|
||||
</label>{" "}
|
||||
<label>
|
||||
<input name="restrictions" type="checkbox" value="thread" /> thread
|
||||
<input name="restrictions" type="checkbox" value="thread" /> Vlákna
|
||||
</label>{" "}
|
||||
<label>
|
||||
<input name="restrictions" type="checkbox" value="reply" /> reply
|
||||
<input name="restrictions" type="checkbox" value="reply" /> Odpovědi
|
||||
</label>{" "}
|
||||
<label>
|
||||
<input name="restrictions" type="checkbox" value="file" /> file
|
||||
<input name="restrictions" type="checkbox" value="file" /> Soubory
|
||||
</label>{" "}
|
||||
<label>
|
||||
<input name="restrictions" type="checkbox" value="captcha" />{" "}
|
||||
captcha
|
||||
<input name="restrictions" type="checkbox" value="captcha" /> Vnutit
|
||||
CAPTCHA
|
||||
</label>
|
||||
</FormField>
|
||||
<FormField label="Důvod">
|
||||
<input name="reason" type="text" />
|
||||
<FormField label="Poznámka">
|
||||
<input name="note" type="text" />
|
||||
</FormField>
|
||||
<FormButton submit="Vytvořit" action="create_restriction" />
|
||||
</Form>
|
||||
|
||||
@@ -58,15 +58,7 @@ const Template = (ctx: TemplateCtx) => (
|
||||
checked={ctx.uconfig.reltime}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField
|
||||
label={
|
||||
<>
|
||||
Neveřejné nástěnky na overboardu
|
||||
<br />
|
||||
<small>(dělěny čárkami)</small>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<FormField label="Neveřejné nástěnky na overboardu">
|
||||
<input
|
||||
name="non_public_overboard"
|
||||
type="text"
|
||||
|
||||
@@ -6,6 +6,7 @@ body {
|
||||
}
|
||||
|
||||
header {
|
||||
position: sticky; // On ancient browsers it just does nothing as it used to
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user