fmt
This commit is contained in:
parent
e2ee2c6375
commit
21111549b6
@ -12,18 +12,23 @@ export function MarkdownRenderer(props: { text: string | undefined }) {
|
|||||||
meta = text.slice(4, index);
|
meta = text.slice(4, index);
|
||||||
c = text.slice(index + 4, text.length);
|
c = text.slice(index + 4, text.length);
|
||||||
}
|
}
|
||||||
return (<>
|
return (
|
||||||
{meta ? <div>
|
<>
|
||||||
<h2>Meta</h2>
|
{meta
|
||||||
<pre>{meta}</pre>
|
? (
|
||||||
<hr class="mt-2 mb-2"></hr>
|
<div>
|
||||||
</div> : <div></div>}
|
<h2>Meta</h2>
|
||||||
<div
|
<pre>{meta}</pre>
|
||||||
class="markdown-body"
|
<hr class="mt-2 mb-2"></hr>
|
||||||
dangerouslySetInnerHTML={{ __html: marked.parse(c) }}
|
</div>
|
||||||
|
)
|
||||||
|
: <div></div>}
|
||||||
|
<div
|
||||||
|
class="markdown-body"
|
||||||
|
dangerouslySetInnerHTML={{ __html: marked.parse(c) }}
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
dev.ts
16
dev.ts
@ -8,11 +8,11 @@ await devUserAdd();
|
|||||||
await dev(import.meta.url, "./main.ts");
|
await dev(import.meta.url, "./main.ts");
|
||||||
|
|
||||||
async function devUserAdd() {
|
async function devUserAdd() {
|
||||||
if(Deno.env.get("DB_PATH") === ":memory:") {
|
if (Deno.env.get("DB_PATH") === ":memory:") {
|
||||||
const db = await connectDB();
|
const db = await connectDB();
|
||||||
const username = "admin";
|
const username = "admin";
|
||||||
const password = "admin";
|
const password = "admin";
|
||||||
const new_user = await users.createUser(username, password);
|
const new_user = await users.createUser(username, password);
|
||||||
await users.addUser(db, new_user);
|
await users.addUser(db, new_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,4 +15,4 @@
|
|||||||
"sqlite": "https://deno.land/x/sqlite@v3.7.0/mod.ts",
|
"sqlite": "https://deno.land/x/sqlite@v3.7.0/mod.ts",
|
||||||
"djwt": "https://deno.land/x/djwt@v2.8/mod.ts"
|
"djwt": "https://deno.land/x/djwt@v2.8/mod.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ function FetchAndRender(props: { src: string; type: string }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RenderView(props: { src: string, mdbase?: string }) {
|
export function RenderView(props: { src: string; mdbase?: string }) {
|
||||||
const src = props.src;
|
const src = props.src;
|
||||||
const type = extToType(extname(src));
|
const type = extToType(extname(src));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -61,7 +61,9 @@ export function DirList(props: DirListProps) {
|
|||||||
{files.map((file) => (
|
{files.map((file) => (
|
||||||
<ListItem
|
<ListItem
|
||||||
key={file.name}
|
key={file.name}
|
||||||
href={`/dir/${encodePath(join(data.path, file.name))}${(file.isDirectory ? "/" : "")}?pretty`}
|
href={`/dir/${
|
||||||
|
encodePath(join(data.path, file.name))
|
||||||
|
}${(file.isDirectory ? "/" : "")}?pretty`}
|
||||||
icon={file.isDirectory
|
icon={file.isDirectory
|
||||||
? "/icon/folder.svg"
|
? "/icon/folder.svg"
|
||||||
: extToIcon(extname(file.name))}
|
: extToIcon(extname(file.name))}
|
||||||
|
@ -1,52 +1,51 @@
|
|||||||
export default function LoginForm({
|
export default function LoginForm({
|
||||||
redirect = "/",
|
redirect = "/",
|
||||||
failed = false,
|
failed = false,
|
||||||
}: { redirect?: string
|
}: { redirect?: string; failed?: boolean }) {
|
||||||
failed?: boolean }
|
return (
|
||||||
) {
|
<div class="p-4 absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
|
||||||
|
|
||||||
return <div class="p-4 absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
|
|
||||||
flex flex-col items-center border-gray-500 border-2 rounded-md
|
flex flex-col items-center border-gray-500 border-2 rounded-md
|
||||||
sm:max-w-screen-sm max-w-screen-md">
|
sm:max-w-screen-sm max-w-screen-md">
|
||||||
<img
|
<img
|
||||||
src="/logo.svg"
|
src="/logo.svg"
|
||||||
class="w-32 h-32"
|
class="w-32 h-32"
|
||||||
alt="the fresh logo: a sliced lemon dripping with juice"
|
alt="the fresh logo: a sliced lemon dripping with juice"
|
||||||
/>
|
/>
|
||||||
<h1 class="text-2xl font-bold">Login</h1>
|
<h1 class="text-2xl font-bold">Login</h1>
|
||||||
{failed ? <p class="text-red-500">Login failed</p> : null}
|
{failed ? <p class="text-red-500">Login failed</p> : null}
|
||||||
<form
|
<form
|
||||||
action={"/login?redirect=" + redirect}
|
action={"/login?redirect=" + redirect}
|
||||||
method="POST"
|
method="POST"
|
||||||
class="flex flex-col gap-2 items-stretch"
|
class="flex flex-col gap-2 items-stretch"
|
||||||
>
|
>
|
||||||
<div class="flex gap-2 flex-wrap">
|
<div class="flex gap-2 flex-wrap">
|
||||||
<div class="basis-40 flex items-center flex-1">
|
<div class="basis-40 flex items-center flex-1">
|
||||||
<label for="username" class="w-20">Username</label>
|
<label for="username" class="w-20">Username</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="username"
|
name="username"
|
||||||
id="username"
|
id="username"
|
||||||
class="border-b-2 focus:border-green-500 transition-colors flex-1"
|
class="border-b-2 focus:border-green-500 transition-colors flex-1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center flex-1">
|
<div class="flex items-center flex-1">
|
||||||
<label for="password" class="w-20">Password</label>
|
<label for="password" class="w-20">Password</label>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
id="password"
|
id="password"
|
||||||
class="border-b-2 focus:border-green-500 transition-colors flex-1"
|
class="border-b-2 focus:border-green-500 transition-colors flex-1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="bg-gray-400 p-2 rounded
|
class="bg-gray-400 p-2 rounded
|
||||||
m-auto"
|
m-auto"
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { encodePath } from "../util/util.ts";
|
|||||||
|
|
||||||
function stairs(path: string) {
|
function stairs(path: string) {
|
||||||
if (path === ".") return [];
|
if (path === ".") return [];
|
||||||
const uplist = path.split("/").filter(x=> x.length > 0);
|
const uplist = path.split("/").filter((x) => x.length > 0);
|
||||||
let current = ".";
|
let current = ".";
|
||||||
const stairs = [];
|
const stairs = [];
|
||||||
for (const up of uplist) {
|
for (const up of uplist) {
|
||||||
|
7
main.ts
7
main.ts
@ -4,11 +4,7 @@
|
|||||||
/// <reference lib="dom.asynciterable" />
|
/// <reference lib="dom.asynciterable" />
|
||||||
/// <reference lib="deno.ns" />
|
/// <reference lib="deno.ns" />
|
||||||
|
|
||||||
import {
|
import { Manifest, ServerContext, StartOptions } from "$fresh/server.ts";
|
||||||
Manifest,
|
|
||||||
ServerContext,
|
|
||||||
StartOptions,
|
|
||||||
} from "$fresh/server.ts";
|
|
||||||
import manifest from "./fresh.gen.ts";
|
import manifest from "./fresh.gen.ts";
|
||||||
|
|
||||||
import twindPlugin from "$fresh/plugins/twind.ts";
|
import twindPlugin from "$fresh/plugins/twind.ts";
|
||||||
@ -25,7 +21,6 @@ import { prepareDocs } from "./src/store/doc.ts";
|
|||||||
import { connectDB } from "./src/user/db.ts";
|
import { connectDB } from "./src/user/db.ts";
|
||||||
import * as users from "./src/user/user.ts";
|
import * as users from "./src/user/user.ts";
|
||||||
|
|
||||||
|
|
||||||
async function startServer(manifest: Manifest, options: StartOptions = {}) {
|
async function startServer(manifest: Manifest, options: StartOptions = {}) {
|
||||||
const ctx = await ServerContext.fromManifest(manifest, options);
|
const ctx = await ServerContext.fromManifest(manifest, options);
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import { HandlerContext, MiddlewareHandlerContext, Status } from "$fresh/server.ts";
|
import {
|
||||||
|
HandlerContext,
|
||||||
|
MiddlewareHandlerContext,
|
||||||
|
Status,
|
||||||
|
} from "$fresh/server.ts";
|
||||||
import { getCookies } from "http/cookie.ts";
|
import { getCookies } from "http/cookie.ts";
|
||||||
import { verify } from "djwt";
|
import { verify } from "djwt";
|
||||||
import { prepareSecretKey } from "../util/secret.ts";
|
import { prepareSecretKey } from "../util/secret.ts";
|
||||||
@ -17,4 +21,4 @@ export const handler = async (
|
|||||||
ctx.state["login"] = null;
|
ctx.state["login"] = null;
|
||||||
}
|
}
|
||||||
return await ctx.next();
|
return await ctx.next();
|
||||||
}
|
};
|
||||||
|
@ -28,9 +28,13 @@ export type DirOrFileProps = DirProps | FileProps;
|
|||||||
|
|
||||||
type RenderOption = {
|
type RenderOption = {
|
||||||
fileInfo?: Deno.FileInfo;
|
fileInfo?: Deno.FileInfo;
|
||||||
}
|
};
|
||||||
|
|
||||||
async function renderFile(req: Request, path: string, { fileInfo }: RenderOption = {}) {
|
async function renderFile(
|
||||||
|
req: Request,
|
||||||
|
path: string,
|
||||||
|
{ fileInfo }: RenderOption = {},
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
fileInfo = await Deno.stat(path);
|
fileInfo = await Deno.stat(path);
|
||||||
@ -82,7 +86,12 @@ async function renderFile(req: Request, path: string, { fileInfo }: RenderOption
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderPage(_req: Request, path: string, ctx: HandlerContext, { fileInfo }: RenderOption = {}) {
|
async function renderPage(
|
||||||
|
_req: Request,
|
||||||
|
path: string,
|
||||||
|
ctx: HandlerContext,
|
||||||
|
{ fileInfo }: RenderOption = {},
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
fileInfo = await Deno.stat(path);
|
fileInfo = await Deno.stat(path);
|
||||||
@ -233,4 +242,4 @@ export default function DirLists(props: PageProps<DirOrFileProps>) {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export { handler } from "../../src/login_middleware.ts";
|
export { handler } from "../../src/login_middleware.ts";
|
||||||
|
@ -1 +1 @@
|
|||||||
export { handler } from "../../src/login_middleware.ts";
|
export { handler } from "../../src/login_middleware.ts";
|
||||||
|
@ -5,7 +5,6 @@ export default function Home() {
|
|||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Simple file server</title>
|
<title>Simple file server</title>
|
||||||
|
|
||||||
</Head>
|
</Head>
|
||||||
<div class="p-4 mx-auto max-w-screen-md">
|
<div class="p-4 mx-auto max-w-screen-md">
|
||||||
<img
|
<img
|
||||||
|
@ -8,7 +8,7 @@ import { create as createJWT } from "djwt";
|
|||||||
import { prepareSecretKey } from "../util/secret.ts";
|
import { prepareSecretKey } from "../util/secret.ts";
|
||||||
import LoginForm from "../islands/Login.tsx";
|
import LoginForm from "../islands/Login.tsx";
|
||||||
|
|
||||||
async function GET(_req: Request, ctx: HandlerContext){
|
async function GET(_req: Request, ctx: HandlerContext) {
|
||||||
return await ctx.render();
|
return await ctx.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ async function POST(req: Request, _ctx: HandlerContext): Promise<Response> {
|
|||||||
path: "/",
|
path: "/",
|
||||||
secure: url.protocol === "https:",
|
secure: url.protocol === "https:",
|
||||||
});
|
});
|
||||||
|
|
||||||
let redirect = "/";
|
let redirect = "/";
|
||||||
if (url.searchParams.has("redirect")) {
|
if (url.searchParams.has("redirect")) {
|
||||||
redirect = url.searchParams.get("redirect")!;
|
redirect = url.searchParams.get("redirect")!;
|
||||||
@ -58,7 +58,9 @@ async function POST(req: Request, _ctx: HandlerContext): Promise<Response> {
|
|||||||
<h1> Login Failed </h1>
|
<h1> Login Failed </h1>
|
||||||
<p> <a href="/"> Back to Home </a> </p>
|
<p> <a href="/"> Back to Home </a> </p>
|
||||||
<script>
|
<script>
|
||||||
document.location.href = "/login?failed=true&redirect=${url.searchParams.get("redirect")}";
|
document.location.href = "/login?failed=true&redirect=${
|
||||||
|
url.searchParams.get("redirect")
|
||||||
|
}";
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>`,
|
</html>`,
|
||||||
@ -85,7 +87,7 @@ export default function Login(props: PageProps) {
|
|||||||
<title>Simple file server - Login</title>
|
<title>Simple file server - Login</title>
|
||||||
</Head>
|
</Head>
|
||||||
<div class="">
|
<div class="">
|
||||||
<LoginForm redirect={redirect ?? "/"} failed={failed}/>
|
<LoginForm redirect={redirect ?? "/"} failed={failed} />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import { MiddlewareHandlerContext, Status } from "$fresh/server.ts";
|
import { MiddlewareHandlerContext, Status } from "$fresh/server.ts";
|
||||||
|
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
req: Request,
|
req: Request,
|
||||||
ctx: MiddlewareHandlerContext<Record<string, unknown>>,
|
ctx: MiddlewareHandlerContext<Record<string, unknown>>,
|
||||||
) => {
|
) => {
|
||||||
const authRequired = Deno.env.get("AUTH_REQUIRED") === "true";
|
const authRequired = Deno.env.get("AUTH_REQUIRED") === "true";
|
||||||
if (authRequired) {
|
if (authRequired) {
|
||||||
const login = ctx.state["login"];
|
const login = ctx.state["login"];
|
||||||
if (!login) {
|
if (!login) {
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
status: Status.Found,
|
status: Status.Found,
|
||||||
headers: {
|
headers: {
|
||||||
Location: `/login?redirect=${encodeURIComponent(req.url)}`,
|
Location: `/login?redirect=${encodeURIComponent(req.url)}`,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return await ctx.next();
|
}
|
||||||
}
|
return await ctx.next();
|
||||||
|
};
|
||||||
|
@ -11,8 +11,7 @@ tags: ["한글", "테스트"]
|
|||||||
2. asdf
|
2. asdf
|
||||||
3. sdf
|
3. sdf
|
||||||
|
|
||||||
|
- a
|
||||||
* a
|
- b
|
||||||
* b
|
- c
|
||||||
* c
|
- d
|
||||||
* d
|
|
||||||
|
Loading…
Reference in New Issue
Block a user