BREAKING CHANGE: deprecated use of auth and bot api to only use 2chi verifier be

This commit is contained in:
Alie 2025-02-12 13:01:37 +01:00
parent e04dbdce01
commit 00991ad93c
5 changed files with 97 additions and 163 deletions

View File

@ -1,7 +1,7 @@
services: services:
mongodb: mongodb:
image: mongo:bionic image: mongo:bionic
container_name: mongodb-fe container_name: fe-mongodb
ports: ports:
- "27017:27017" - "27017:27017"
environment: environment:
@ -10,32 +10,34 @@ services:
MONGO_INITDB_DATABASE: bot MONGO_INITDB_DATABASE: bot
volumes: volumes:
- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
- mongodb_data:/data/db
bot-api: bot-api:
image: git.fai.st/fedi-image-bot/bot-api:v1.0.2 image: ghcr.io/siesta-cat/2chi-api:v1.0.1
container_name: bot-api-fe container_name: fe-2chi-api
restart: on-failure
ports: ports:
- 8080:8080 - 8080:8080
depends_on: depends_on:
- mongodb - mongodb
environment: environment:
PORT: 8080 PORT: 8080
MONGODB_URI: "mongodb://mongodb:27017/bot" DB_HOST: "mongodb"
MONGODB_USER: "root" DB_NAME: "bot"
MONGODB_PASS: "password" DB_USER: "root"
JWTSECRET: "cooljwtsecret" DB_PASS: "password"
fe-middleware: fe-middleware:
image: git.fai.st/fedi-image-bot/fe-middleware:v1.0.2 image: ghcr.io/siesta-cat/2chi-verifier-be:v2.1.2
container_name: fe-middleware-fe container_name: fe-2chi-verifier-be
stop_signal: sigkill
ports: ports:
- 8081:8081 - 8081:8081
depends_on: depends_on:
- bot-api - bot-api
environment: environment:
PORT: 8081 PORT: 8081
BOT_API_URI: "http://bot-api:8080" BOT_API_BASE_URL: "http://bot-api:8080"
TOKEN_SECRET: Y2hpY2FzZWNyZXQK
GELBOORU_IMAGES_PER_REQUEST: 100 # Number of images per request, maximum 100 GELBOORU_IMAGES_PER_REQUEST: 100 # Number of images per request, maximum 100
GELBOORU_TAGS: "2girls sleeping" # Tags of the images. The images will have all of these tags GELBOORU_TAGS: "2girls sleeping" # Tags of the images. The images will have all of these tags
@ -44,12 +46,11 @@ services:
container_name: bot-image-moderation-fe container_name: bot-image-moderation-fe
ports: ports:
- 80:80 - 80:80
environment:
VITE_BACKEND_URL: "http://localhost:8081"
develop: develop:
watch: watch:
- action: rebuild - action: rebuild
path: . path: .
ignore: ignore:
- node_modules/ - node_modules/
volumes:
mongodb_data:

View File

@ -1,24 +1,14 @@
import { useState } from "react"; import { useState } from "react";
import GetBackendUrl from "./components/ImageModerator/GetBackendUrl";
import ImageModerator from "./components/ImageModerator/ImageModerator"; import ImageModerator from "./components/ImageModerator/ImageModerator";
import Login from "./components/Login/Login";
function App() { function App() {
const [{ apiUrl, middlewareUrl, token }, setRemote] = useState({ const [backendUrl, setBackendUrl] = useState("");
apiUrl: "",
middlewareUrl: "",
token: "",
});
if (token) { if (backendUrl) {
return ( return <ImageModerator backendUrl={backendUrl} />;
<ImageModerator
token={token}
apiUrl={apiUrl}
middlewareUrl={middlewareUrl}
/>
);
} else { } else {
return <Login setRemote={setRemote} />; return <GetBackendUrl setRemote={setBackendUrl} />;
} }
} }

View File

@ -0,0 +1,64 @@
import { useEffect, useState } from "react";
export default function GetBackendUrl({ setRemote }: { setRemote: Function }) {
const sendLabel = "Input Backend URL";
const [backendUrl, setBackendUrl] = useState("");
function sendAction() {
event?.preventDefault();
try {
if (backendUrl) {
localStorage.setItem("backendUrl", backendUrl);
}
} catch (error) {
console.error(error);
}
setRemote(backendUrl);
}
function handleChange(
e: {
target: { value: React.SetStateAction<string> };
},
setter: React.Dispatch<React.SetStateAction<string>>
): void {
setter(e.target.value);
}
useEffect(() => {
const savedRemote = localStorage.getItem("backendUrl");
if (savedRemote) {
setBackendUrl(savedRemote);
}
}, []);
return (
<div
style={{
height: "100vh",
width: "100vw",
}}>
<form
style={{
height: "100%",
width: "100%",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}
onSubmit={sendAction}>
<label>Backend URL: </label>
<input
type="url"
id="backend"
name="backend"
value={backendUrl}
onChange={(e) => handleChange(e, setBackendUrl)}
/>
<button type="submit">{sendLabel}</button>
</form>
</div>
);
}

View File

@ -2,50 +2,42 @@ import { useEffect, useState } from "react";
import Button from "../Button/Button"; import Button from "../Button/Button";
interface ImageModeratorProps { interface ImageModeratorProps {
token: string; backendUrl: string;
apiUrl: string;
middlewareUrl: string;
} }
export default function ImageModerator({ export default function ImageModerator({ backendUrl }: ImageModeratorProps) {
token,
apiUrl,
middlewareUrl,
}: ImageModeratorProps) {
const acceptLabel = "Accept"; const acceptLabel = "Accept";
const discardLabel = "Discard"; const discardLabel = "Discard";
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [imageData, setImageData] = useState({ url: "", tags: [] }); const [imageData, setImageData] = useState({ url: "", token: "" });
const [imageAlt, setImageAlt] = useState("No image"); const [imageAlt, setImageAlt] = useState("No image");
function acceptAction() { function acceptAction() {
fetch(`${apiUrl}/images`, { fetch(`${backendUrl}/image/review`, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
url: imageData.url, url: imageData.url,
status: "available", token: imageData.token,
tags: imageData.tags, is_accepted: true,
}), }),
headers: { headers: {
"Content-type": "application/json", "Content-type": "application/json",
Authorization: `Bearer ${token}`,
}, },
}); });
setIsLoading(true); setIsLoading(true);
} }
function discardAction() { function discardAction() {
fetch(`${apiUrl}/images`, { fetch(`${backendUrl}/image/review`, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
url: imageData.url, url: imageData.url,
status: "unavailable", token: imageData.token,
tags: imageData.tags, is_accepted: false,
}), }),
headers: { headers: {
"Content-type": "application/json", "Content-type": "application/json",
Authorization: `Bearer ${token}`,
}, },
}); });
setIsLoading(true); setIsLoading(true);
@ -53,8 +45,8 @@ export default function ImageModerator({
const getNewImage = () => { const getNewImage = () => {
if (isLoading) { if (isLoading) {
setImageData({ url: "", tags: [] }); setImageData({ url: "", token: "" });
fetch(`${middlewareUrl}/image`, { fetch(`${backendUrl}/image`, {
method: "GET", method: "GET",
}) })
.then((response) => { .then((response) => {
@ -62,10 +54,8 @@ export default function ImageModerator({
return response.json(); return response.json();
}) })
.then((data) => { .then((data) => {
const url = data.url; setImageData({ url: data.url, token: data.token });
const tags = data.tags; setImageAlt(data.url);
setImageData({ url, tags });
setImageAlt(url);
}) })
.catch((error) => { .catch((error) => {
setImageAlt("Error"); setImageAlt("Error");

View File

@ -1,111 +0,0 @@
import { useEffect, useState } from "react";
export default function Login({ setRemote }: { setRemote: Function }) {
const sendLabel = "Login";
const [middlewareUrl, setMiddlewareUrl] = useState("");
const [apiUrl, setApiUrl] = useState("");
const [app, setApp] = useState("");
const [secret, setSecret] = useState("");
function sendAction() {
event?.preventDefault();
try {
if (apiUrl && middlewareUrl && app && secret) {
localStorage.setItem(
"credentials",
JSON.stringify({ apiUrl, middlewareUrl, app, secret })
);
}
} catch (error) {
console.error(error);
}
fetch(`${apiUrl}/login`, {
method: "POST",
body: JSON.stringify({ app, secret }),
headers: { "Content-type": "application/json" },
})
.then((response) => {
return response.json();
})
.then((body) => {
setRemote({ apiUrl, middlewareUrl, token: body.token });
});
}
function handleChange(
e: {
target: { value: React.SetStateAction<string> };
},
setter: React.Dispatch<React.SetStateAction<string>>
): void {
setter(e.target.value);
}
useEffect(() => {
const savedRemote = localStorage.getItem("credentials");
if (savedRemote) {
const savedData = JSON.parse(savedRemote);
setApiUrl(savedData.apiUrl);
setMiddlewareUrl(savedData.middlewareUrl);
setApp(savedData.app);
setSecret(savedData.secret);
}
}, []);
useEffect(() => {
if (secret) {
sendAction();
}
}, [secret]);
return (
<div
style={{
height: "100vh",
width: "100vw",
}}>
<form
style={{
height: "100%",
width: "100%",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}
onSubmit={sendAction}>
<label>API URL: </label>
<input
type="url"
id="api"
name="api"
value={apiUrl}
onChange={(e) => handleChange(e, setApiUrl)}
/>
<label>Source URL: </label>
<input
type="url"
id="middleware"
name="middleware"
value={middlewareUrl}
onChange={(e) => handleChange(e, setMiddlewareUrl)}
/>
<label>App name: </label>
<input
type="text"
id="username"
name="username"
value={app}
onChange={(e) => handleChange(e, setApp)}
/>
<label>Secret: </label>
<input
type="password"
value={secret}
onChange={(e) => handleChange(e, setSecret)}
/>
<button type="submit">{sendLabel}</button>
</form>
</div>
);
}