Add client config api

This commit is contained in:
2024-05-24 17:56:58 +08:00
parent d64917914f
commit fd680931bd
5 changed files with 121 additions and 2 deletions

42
db.ts
View File

@@ -177,6 +177,12 @@ type TokenRaw = {
client_version: string | null;
client_platform: string | null;
};
export type ClientConfig = {
uid: number;
client: string;
name: string;
data: string;
};
const ALL_TABLES = [
"version",
"task",
@@ -189,6 +195,7 @@ const ALL_TABLES = [
"user",
"token",
"ehmeta",
"client_config",
];
const VERSION_TABLE = `CREATE TABLE version (
id TEXT,
@@ -282,6 +289,13 @@ const EHMETA_TABLE = `CREATE TABLE ehmeta (
cached_time TEXT,
PRIMARY KEY (gid)
);`;
const CLIENT_CONFIG_TABLE = `CREATE TABLE client_config (
uid INT,
client TEXT,
name TEXT,
data TEXT,
PRIMARY KEY (uid, client, name)
);`;
function escape_fields(fields: string, namespace: string) {
const fs = fields.split(",");
@@ -508,6 +522,9 @@ export class EhDb {
if (!this.#exist_table.has("ehmeta")) {
this.db.execute(EHMETA_TABLE);
}
if (!this.#exist_table.has("client_config")) {
this.db.execute(CLIENT_CONFIG_TABLE);
}
this.#updateExistsTable();
}
#read_version() {
@@ -549,6 +566,12 @@ export class EhDb {
]);
});
}
add_client_config(config: ClientConfig) {
this.db.queryEntries(
"INSERT OR REPLACE INTO client_config VALUES (:uid, :client, :name, :data);",
config,
);
}
add_ehmeta(data: GalleryMetadataSingle) {
this.db.query(
"INSERT OR REPLACE INTO ehmeta VALUES (?, ?, ?);",
@@ -908,6 +931,12 @@ export class EhDb {
return t;
});
}
delete_client_config(uid: number, client: string, name: string) {
this.db.query(
"DELETE FROM client_config WHERE uid = ? AND client = ? AND name = ?;",
[uid, client, name],
);
}
delete_file(f: EhFile) {
this.db.query("DELETE FROM file WHERE id = ?;", [f.id]);
}
@@ -966,6 +995,13 @@ export class EhDb {
if (!this.#dblock) return;
eval(`Deno.funlockSync(${this.#dblock.rid});`);
}
get_client_config(uid: number, client: string, name: string) {
const d = this.db.queryEntries<ClientConfig>(
"SELECT * FROM client_config WHERE uid = ? AND client = ? AND name = ?;",
[uid, client, name],
);
return d.length ? d[0] : null;
}
get_ehmeta(gid: number) {
const d = this.db.query<[string]>(
"SELECT data FROM ehmeta WHERE gid = ?;",
@@ -1265,6 +1301,12 @@ export class EhDb {
get_user_count() {
return this.db.query<[number]>("SELECT COUNT(*) FROM user;")[0][0];
}
list_client_configs(uid: number, client: string) {
return this.db.queryEntries<ClientConfig>(
"SELECT * FROM client_config WHERE uid = ? AND client = ?;",
[uid, client],
);
}
optimize() {
this.db.execute("VACUUM;");
}

View File

@@ -4,6 +4,7 @@
import * as $_middleware from "./routes/_middleware.ts";
import * as $api_middleware from "./routes/api/_middleware.ts";
import * as $api_client_config from "./routes/api/client/config.ts";
import * as $api_config from "./routes/api/config.ts";
import * as $api_deploy_id from "./routes/api/deploy_id.ts";
import * as $api_eh_image_limit from "./routes/api/eh/image_limit.ts";
@@ -44,6 +45,7 @@ const manifest = {
routes: {
"./routes/_middleware.ts": $_middleware,
"./routes/api/_middleware.ts": $api_middleware,
"./routes/api/client/config.ts": $api_client_config,
"./routes/api/config.ts": $api_config,
"./routes/api/deploy_id.ts": $api_deploy_id,
"./routes/api/eh/image_limit.ts": $api_eh_image_limit,

View File

@@ -22,7 +22,13 @@ function handle_auth(req: Request, ctx: FreshContext) {
if (u.pathname === "/api/health_check" && req.method === "GET") {
return true;
}
if (m.cfg.random_file_secret && (u.pathname == "/api/file/random" || u.pathname.match(/^\/api\/file\/\d+/) || u.pathname.match(/^\/api\/thumbnail\/\d+/)) && req.method === "GET" && u.searchParams.get("token")) {
if (
m.cfg.random_file_secret &&
(u.pathname == "/api/file/random" ||
u.pathname.match(/^\/api\/file\/\d+/) ||
u.pathname.match(/^\/api\/thumbnail\/\d+/)) &&
req.method === "GET" && u.searchParams.get("token")
) {
return true;
}
return false;

View File

@@ -0,0 +1,68 @@
import { Handlers } from "$fresh/server.ts";
import { User } from "../../../db.ts";
import { get_task_manager } from "../../../server.ts";
import { get_string } from "../../../server/parse_form.ts";
import { return_data, return_error } from "../../../server/utils.ts";
export const handler: Handlers = {
async DELETE(req, ctx) {
const user = <User | undefined> ctx.state.user;
if (!user) {
return return_error(403, "Permission denied.");
}
let d: FormData | null = null;
try {
d = await req.formData();
} catch (_) {
return return_error(1, "Invalid parameters.");
}
const client = await get_string(d.get("client"));
if (!client) return return_error(2, "client is needed.");
const name = await get_string(d.get("name"));
if (!name) return return_error(2, "name is needed.");
const m = get_task_manager();
m.db.delete_client_config(user.id, client, name);
return return_data({});
},
GET(req, ctx) {
const user = <User | undefined> ctx.state.user;
if (!user) {
return return_error(403, "Permission denied.");
}
const d = new URL(req.url).searchParams;
const client = d.get("client");
if (!client) return return_error(2, "client is needed.");
const name = d.get("name");
const m = get_task_manager();
if (name) {
const data = m.db.get_client_config(user.id, client, name);
if (data === null) return return_error(404, "Not found");
return return_data(data.data);
} else {
return return_data(
m.db.list_client_configs(user.id, client).map((d) => d.name),
);
}
},
async PUT(req, ctx) {
const user = <User | undefined> ctx.state.user;
if (!user) {
return return_error(403, "Permission denied.");
}
let d: FormData | null = null;
try {
d = await req.formData();
} catch (_) {
return return_error(1, "Invalid parameters.");
}
const client = await get_string(d.get("client"));
if (!client) return return_error(2, "client is needed.");
const name = await get_string(d.get("name"));
if (!name) return return_error(2, "name is needed.");
const data = await get_string(d.get("data"));
if (data === null) return return_error(2, "data is needed.");
const m = get_task_manager();
m.db.add_client_config({ uid: user.id, client, name, data });
return return_data({});
},
};

View File

@@ -63,7 +63,8 @@ export function i18n_handle_request(req: Request) {
const a = req.headers.get("Accept-Language");
const l = (a
? pick(LANGUAGES, a) || pick(LANGUAGES, a, { loose: true })
: null) || "en";
: null) ||
"en";
const params = new URLSearchParams();
params.append("lang", l);
for (const p of u.searchParams.entries()) {