mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-07-08 01:31:00 +08:00
Add new settings
This commit is contained in:
@@ -34,6 +34,7 @@ export type ConfigType = {
|
|||||||
download_timeout_check_interval: number;
|
download_timeout_check_interval: number;
|
||||||
/** EH metadata cache time in hours */
|
/** EH metadata cache time in hours */
|
||||||
eh_metadata_cache_time: number;
|
eh_metadata_cache_time: number;
|
||||||
|
random_file_secret?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum ThumbnailMethod {
|
export enum ThumbnailMethod {
|
||||||
@@ -200,6 +201,9 @@ export class Config {
|
|||||||
get eh_metadata_cache_time() {
|
get eh_metadata_cache_time() {
|
||||||
return this._return_number("eh_metadata_cache_time") || 168;
|
return this._return_number("eh_metadata_cache_time") || 168;
|
||||||
}
|
}
|
||||||
|
get random_file_secret() {
|
||||||
|
return this._return_string("random_file_secret");
|
||||||
|
}
|
||||||
to_json(): ConfigType {
|
to_json(): ConfigType {
|
||||||
return {
|
return {
|
||||||
cookies: typeof this.cookies === "string",
|
cookies: typeof this.cookies === "string",
|
||||||
@@ -233,6 +237,7 @@ export class Config {
|
|||||||
download_timeout_check_interval:
|
download_timeout_check_interval:
|
||||||
this.download_timeout_check_interval,
|
this.download_timeout_check_interval,
|
||||||
eh_metadata_cache_time: this.eh_metadata_cache_time,
|
eh_metadata_cache_time: this.eh_metadata_cache_time,
|
||||||
|
random_file_secret: this.random_file_secret,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ function handle_auth(req: Request, ctx: FreshContext) {
|
|||||||
if (u.pathname === "/api/health_check" && req.method === "GET") {
|
if (u.pathname === "/api/health_check" && req.method === "GET") {
|
||||||
return true;
|
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")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if (!token) return check();
|
if (!token) return check();
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { encodeBase64 as encode } from "std/encoding/base64.ts";
|
|||||||
import { get_host, return_data, return_error } from "../../../server/utils.ts";
|
import { get_host, return_data, return_error } from "../../../server/utils.ts";
|
||||||
import type { EhFileExtend } from "../../../server/files.ts";
|
import type { EhFileExtend } from "../../../server/files.ts";
|
||||||
import { User, UserPermission } from "../../../db.ts";
|
import { User, UserPermission } from "../../../db.ts";
|
||||||
|
import { SortableURLSearchParams } from "../../../server/SortableURLSearchParams.ts";
|
||||||
|
|
||||||
export const handler: Handlers = {
|
export const handler: Handlers = {
|
||||||
async GET(req, ctx) {
|
async GET(req, ctx) {
|
||||||
@@ -21,13 +22,31 @@ export const handler: Handlers = {
|
|||||||
return return_error(403, "Permission denied.");
|
return return_error(403, "Permission denied.");
|
||||||
}
|
}
|
||||||
const u = new URL(req.url);
|
const u = new URL(req.url);
|
||||||
|
const m = get_task_manager();
|
||||||
|
const token = u.searchParams.get("token");
|
||||||
const data = await parse_bool(u.searchParams.get("data"), false);
|
const data = await parse_bool(u.searchParams.get("data"), false);
|
||||||
const id = parseInt(ctx.params.id);
|
const id = parseInt(ctx.params.id);
|
||||||
|
if (token && m.cfg.random_file_secret) {
|
||||||
|
const s = new SortableURLSearchParams(u.search, ["token"]);
|
||||||
|
const r = encode(
|
||||||
|
new Uint8Array(
|
||||||
|
await pbkdf2Hmac(
|
||||||
|
`${id}${s.toString2()}`,
|
||||||
|
m.cfg.random_file_secret,
|
||||||
|
1000,
|
||||||
|
64,
|
||||||
|
"SHA-512",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (token !== r) {
|
||||||
|
return new Response("Invalid token", { status: 403 });
|
||||||
|
}
|
||||||
|
}
|
||||||
if (isNaN(id)) {
|
if (isNaN(id)) {
|
||||||
if (data) return return_error(400, "Bad Request");
|
if (data) return return_error(400, "Bad Request");
|
||||||
return new Response("Bad Request", { status: 400 });
|
return new Response("Bad Request", { status: 400 });
|
||||||
}
|
}
|
||||||
const m = get_task_manager();
|
|
||||||
const f = m.db.get_file(id);
|
const f = m.db.get_file(id);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
if (data) return return_error(404, "File not found.");
|
if (data) return return_error(404, "File not found.");
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
import { Handlers } from "$fresh/server.ts";
|
import { Handlers } from "$fresh/server.ts";
|
||||||
import { get_task_manager } from "../../../server.ts";
|
import { get_task_manager } from "../../../server.ts";
|
||||||
import { parse_bool } from "../../../server/parse_form.ts";
|
import { parse_bool } from "../../../server/parse_form.ts";
|
||||||
|
import { SortableURLSearchParams } from "../../../server/SortableURLSearchParams.ts";
|
||||||
import { get_host } from "../../../server/utils.ts";
|
import { get_host } from "../../../server/utils.ts";
|
||||||
import { User, UserPermission } from "../../../db.ts";
|
import { User, UserPermission } from "../../../db.ts";
|
||||||
|
import pbkdf2Hmac from "pbkdf2-hmac";
|
||||||
|
import { encodeBase64 as encode } from "std/encoding/base64.ts";
|
||||||
|
import { return_data } from "../../../server/utils.ts";
|
||||||
|
|
||||||
export const handler: Handlers = {
|
export const handler: Handlers = {
|
||||||
async GET(req, ctx) {
|
async GET(req, ctx) {
|
||||||
@@ -15,6 +19,48 @@ export const handler: Handlers = {
|
|||||||
}
|
}
|
||||||
const m = get_task_manager();
|
const m = get_task_manager();
|
||||||
const u = new URL(req.url);
|
const u = new URL(req.url);
|
||||||
|
const token = u.searchParams.get("token");
|
||||||
|
const action = u.searchParams.get("action");
|
||||||
|
if (token && m.cfg.random_file_secret) {
|
||||||
|
const s = new SortableURLSearchParams(u.search, ["token"]);
|
||||||
|
const r = encode(
|
||||||
|
new Uint8Array(
|
||||||
|
await pbkdf2Hmac(
|
||||||
|
`${s.toString2()}`,
|
||||||
|
m.cfg.random_file_secret,
|
||||||
|
1000,
|
||||||
|
64,
|
||||||
|
"SHA-512",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (token !== r) {
|
||||||
|
return new Response("Invalid token", { status: 403 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action == "gentoken") {
|
||||||
|
if (!m.cfg.random_file_secret) {
|
||||||
|
return new Response("Random file secret is not enabled.", {
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const s = new SortableURLSearchParams(u.search, ["token", "action"]);
|
||||||
|
const token = encode(
|
||||||
|
new Uint8Array(
|
||||||
|
await pbkdf2Hmac(
|
||||||
|
`${s.toString2()}`,
|
||||||
|
m.cfg.random_file_secret,
|
||||||
|
1000,
|
||||||
|
64,
|
||||||
|
"SHA-512",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const b = new URLSearchParams(u.search);
|
||||||
|
b.delete("action");
|
||||||
|
b.set("token", token);
|
||||||
|
return return_data(`${get_host(req)}/api/file/random?${b}`);
|
||||||
|
}
|
||||||
const is_nsfw = await parse_bool(u.searchParams.get("is_nsfw"), null);
|
const is_nsfw = await parse_bool(u.searchParams.get("is_nsfw"), null);
|
||||||
const is_ad = await parse_bool(u.searchParams.get("is_ad"), null);
|
const is_ad = await parse_bool(u.searchParams.get("is_ad"), null);
|
||||||
const thumb = await parse_bool(u.searchParams.get("thumb"), false);
|
const thumb = await parse_bool(u.searchParams.get("thumb"), false);
|
||||||
@@ -53,7 +99,43 @@ export const handler: Handlers = {
|
|||||||
}
|
}
|
||||||
const f = m.db.get_random_file(is_nsfw, is_ad, gids);
|
const f = m.db.get_random_file(is_nsfw, is_ad, gids);
|
||||||
if (!f) return new Response("File not found.", { status: 404 });
|
if (!f) return new Response("File not found.", { status: 404 });
|
||||||
|
if (m.cfg.img_verify_secret && !thumb) {
|
||||||
|
const verify = encode(
|
||||||
|
new Uint8Array(
|
||||||
|
await pbkdf2Hmac(
|
||||||
|
`${f.id}`,
|
||||||
|
m.cfg.img_verify_secret,
|
||||||
|
1000,
|
||||||
|
64,
|
||||||
|
"SHA-512",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const b = new URLSearchParams();
|
||||||
|
b.append("verify", verify);
|
||||||
|
return Response.redirect(
|
||||||
|
`${get_host(req)}/file/${f.id}?${b}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
const t = thumb ? "thumbnail" : "file";
|
const t = thumb ? "thumbnail" : "file";
|
||||||
|
if (m.cfg.random_file_secret) {
|
||||||
|
const token = encode(
|
||||||
|
new Uint8Array(
|
||||||
|
await pbkdf2Hmac(
|
||||||
|
`${f.id}`,
|
||||||
|
m.cfg.random_file_secret,
|
||||||
|
1000,
|
||||||
|
64,
|
||||||
|
"SHA-512",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const b = new URLSearchParams();
|
||||||
|
b.append("token", token);
|
||||||
|
return Response.redirect(
|
||||||
|
`${get_host(req)}/api/${t}/${f.id}?${b}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
return Response.redirect(`${get_host(req)}/api/${t}/${f.id}`);
|
return Response.redirect(`${get_host(req)}/api/${t}/${f.id}`);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,10 +36,29 @@ export const handler: Handlers = {
|
|||||||
return new Response("Permission denied", { status: 403 });
|
return new Response("Permission denied", { status: 403 });
|
||||||
}
|
}
|
||||||
const id = parseInt(ctx.params.id);
|
const id = parseInt(ctx.params.id);
|
||||||
|
const m = get_task_manager();
|
||||||
|
const u = new URL(req.url);
|
||||||
|
const token = u.searchParams.get("token");
|
||||||
|
if (token && m.cfg.random_file_secret) {
|
||||||
|
const s = new SortableURLSearchParams(u.search, ["token"]);
|
||||||
|
const r = encode(
|
||||||
|
new Uint8Array(
|
||||||
|
await pbkdf2Hmac(
|
||||||
|
`${id}${s.toString2()}`,
|
||||||
|
m.cfg.random_file_secret,
|
||||||
|
1000,
|
||||||
|
64,
|
||||||
|
"SHA-512",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (token !== r) {
|
||||||
|
return new Response("Invalid token", { status: 403 });
|
||||||
|
}
|
||||||
|
}
|
||||||
if (isNaN(id)) {
|
if (isNaN(id)) {
|
||||||
return new Response("Bad Request", { status: 400 });
|
return new Response("Bad Request", { status: 400 });
|
||||||
}
|
}
|
||||||
const m = get_task_manager();
|
|
||||||
const b = m.cfg.thumbnail_dir;
|
const b = m.cfg.thumbnail_dir;
|
||||||
const method = m.cfg.thumbnail_method;
|
const method = m.cfg.thumbnail_method;
|
||||||
await sure_dir(b);
|
await sure_dir(b);
|
||||||
@@ -47,7 +66,6 @@ export const handler: Handlers = {
|
|||||||
if (!f) {
|
if (!f) {
|
||||||
return new Response("File not found.", { status: 404 });
|
return new Response("File not found.", { status: 404 });
|
||||||
}
|
}
|
||||||
const u = new URL(req.url);
|
|
||||||
const max = await parse_int(u.searchParams.get("max"), 1200);
|
const max = await parse_int(u.searchParams.get("max"), 1200);
|
||||||
const width = await parse_int(u.searchParams.get("width"), null);
|
const width = await parse_int(u.searchParams.get("width"), null);
|
||||||
const height = await parse_int(u.searchParams.get("height"), null);
|
const height = await parse_int(u.searchParams.get("height"), null);
|
||||||
|
|||||||
Reference in New Issue
Block a user