Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/api/fever/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const secs = (d: Date | null | undefined) => (d ? Math.floor(d.getTime() / 1000)
async function params(request: Request) {
const url = new URL(request.url);
const all = new URLSearchParams(url.search);
for (const key of [...all.keys()]) if (key.toLowerCase() === "api_key") all.delete(key);
if (request.method === "POST") {
const type = request.headers.get("content-type") ?? "";
const body = type.includes("multipart/form-data")
Expand Down Expand Up @@ -144,7 +145,7 @@ async function handle(request: Request) {
if (!user) return Response.json(base);

await ensureMissingRefs(user.id);
if (p.has("mark")) await mark(user, p);
if (request.method === "POST" && p.has("mark")) await mark(user, p);

const subs = await subscriptionsOf(user.id);
const body: Record<string, unknown> = {
Expand Down
18 changes: 17 additions & 1 deletion src/lib/api/greader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,23 @@ export function parseItemId(raw: string): number | null {
return Number.isSafeInteger(n) && n > 0 ? n : null;
}

function stripKey(params: URLSearchParams, name: string) {
for (const key of [...params.keys()]) if (key.toLowerCase() === name) params.delete(key);
}

async function readPostBody(request: Request) {
if (request.method !== "POST") return new URLSearchParams();
const type = request.headers.get("content-type") ?? "";
const entries = type.includes("multipart/form-data")
? [...(await request.formData()).entries()].map(([k, v]) => [k, String(v)] as [string, string])
: [...new URLSearchParams(await request.text())];
return new URLSearchParams(entries);
}

async function readParams(request: Request) {
const params = new URLSearchParams(new URL(request.url).search);
// A senha de aplicativo não pode ir na query: ela cai em log, histórico e Referer.
stripKey(params, "passwd");
if (request.method === "POST") {
const type = request.headers.get("content-type") ?? "";
const body = type.includes("multipart/form-data")
Expand Down Expand Up @@ -324,7 +339,8 @@ async function streamContents(user: ApiUser, p: URLSearchParams, stream: string)

export async function handleGReader(request: Request, path: string): Promise<Response> {
if (path === "accounts/ClientLogin") {
const p = await readParams(request);
if (request.method !== "POST") return unauthorized();
const p = await readPostBody(request);
const password = p.get("Passwd");
const user = await userFromAppPassword(password);
if (!user || user.email.toLowerCase() !== (p.get("Email") ?? "").trim().toLowerCase()) return unauthorized();
Expand Down
Loading