feat: add authentication
This commit is contained in:
@ -1,15 +1,14 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { Readability } from "https://cdn.skypack.dev/@mozilla/readability";
|
||||
import { DOMParser } from "https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts";
|
||||
import { BadRequestError } from "@lib/errors.ts";
|
||||
import { createStreamResponse, isValidUrl, json } from "@lib/helpers.ts";
|
||||
import { AccessDeniedError, BadRequestError } from "@lib/errors.ts";
|
||||
import { createStreamResponse, isValidUrl } from "@lib/helpers.ts";
|
||||
import * as openai from "@lib/openai.ts";
|
||||
|
||||
import tds from "https://cdn.skypack.dev/turndown@7.1.1";
|
||||
//import { gfm } from "https://cdn.skypack.dev/@guyplusplus/turndown-plugin-gfm@1.0.7";
|
||||
import { Article, createArticle } from "@lib/resource/articles.ts";
|
||||
import { getYoutubeVideoDetails } from "@lib/youtube.ts";
|
||||
import { extractYoutubeId, formatDate, isYoutubeLink } from "@lib/string.ts";
|
||||
import { extractYoutubeId, isYoutubeLink } from "@lib/string.ts";
|
||||
|
||||
const parser = new DOMParser();
|
||||
|
||||
@ -34,6 +33,11 @@ async function processCreateArticle(
|
||||
|
||||
const title = document?.querySelector("title")?.innerText;
|
||||
|
||||
const images: HTMLImageElement[] = [];
|
||||
document?.querySelectorAll("img").forEach((img) => {
|
||||
images.push(img as unknown as HTMLImageElement);
|
||||
});
|
||||
|
||||
const metaAuthor =
|
||||
document?.querySelector('meta[name="twitter:creator"]')?.getAttribute(
|
||||
"content",
|
||||
@ -62,6 +66,19 @@ async function processCreateArticle(
|
||||
});
|
||||
|
||||
const url = new URL(fetchUrl);
|
||||
|
||||
function makeUrlAbsolute(src: string) {
|
||||
if (src.startsWith("/")) {
|
||||
return `${url.origin}${src.replace(/$\//, "")}`;
|
||||
}
|
||||
|
||||
if (!src.startsWith("https://") && !src.startsWith("http://")) {
|
||||
return `${url.origin.replace(/\/$/, "")}/${src.replace(/^\//, "")})`;
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
service.addRule("fix image links", {
|
||||
filter: ["img"],
|
||||
replacement: function (_: string, node: HTMLImageElement) {
|
||||
@ -69,17 +86,7 @@ async function processCreateArticle(
|
||||
const alt = node.getAttribute("alt") || "";
|
||||
if (!src || src.startsWith("data:image")) return "";
|
||||
|
||||
if (src.startsWith("/")) {
|
||||
return `})`;
|
||||
}
|
||||
|
||||
if (!src.startsWith("https://") && !src.startsWith("http://")) {
|
||||
return `}/${
|
||||
src.replace(/^\//, "")
|
||||
})`;
|
||||
}
|
||||
|
||||
return ``;
|
||||
return `})`;
|
||||
},
|
||||
});
|
||||
service.addRule("fix normal links", {
|
||||
@ -119,19 +126,40 @@ async function processCreateArticle(
|
||||
|
||||
const id = shortTitle || title || "";
|
||||
|
||||
const meta: Article["meta"] = {
|
||||
author: (author || "").replace("@", "twitter:"),
|
||||
link: fetchUrl,
|
||||
status: "not-finished",
|
||||
date: new Date(),
|
||||
};
|
||||
|
||||
const largestImage = images.filter((img) => {
|
||||
const src = img.getAttribute("src");
|
||||
return !!src && !src.startsWith("data:");
|
||||
}).sort((a, b) => {
|
||||
const aSize = +(a.getAttribute("width") || 0) +
|
||||
+(a.getAttribute("height") || 0);
|
||||
const bSize = +(b.getAttribute("width") || 0) +
|
||||
+(b.getAttribute("height") || 0);
|
||||
return aSize > bSize ? -1 : 1;
|
||||
})[0];
|
||||
|
||||
const newArticle = {
|
||||
type: "article",
|
||||
id,
|
||||
name: title || "",
|
||||
content: markdown,
|
||||
tags: tags || [],
|
||||
meta: {
|
||||
author: (author || "").replace("@", "twitter:"),
|
||||
link: fetchUrl,
|
||||
status: "not-finished",
|
||||
date: new Date(),
|
||||
},
|
||||
meta,
|
||||
} as const;
|
||||
|
||||
if (largestImage) {
|
||||
const src = makeUrlAbsolute(largestImage.getAttribute("src") || "");
|
||||
if (src) {
|
||||
meta.image = src;
|
||||
}
|
||||
}
|
||||
|
||||
streamResponse.enqueue("finished processing");
|
||||
|
||||
await createArticle(newArticle);
|
||||
@ -181,7 +209,12 @@ async function processCreateYoutubeVideo(
|
||||
}
|
||||
|
||||
export const handler: Handlers = {
|
||||
GET(req) {
|
||||
GET(req, ctx) {
|
||||
const session = ctx.state.session;
|
||||
if (!session) {
|
||||
throw new AccessDeniedError();
|
||||
}
|
||||
|
||||
const url = new URL(req.url);
|
||||
const fetchUrl = url.searchParams.get("url");
|
||||
|
||||
|
Reference in New Issue
Block a user