Sessions!
This commit is contained in:
parent
f34ead505b
commit
7af220de2e
23
db/mod.ts
23
db/mod.ts
|
@ -159,6 +159,12 @@ export async function createToken(
|
||||||
if (!(digest instanceof Uint8Array)) throw "token digest was non-brinary";
|
if (!(digest instanceof Uint8Array)) throw "token digest was non-brinary";
|
||||||
intermediateToken.digest = digest;
|
intermediateToken.digest = digest;
|
||||||
}
|
}
|
||||||
|
log.debug(
|
||||||
|
`intermediateToken bytes: ${base64.encode(intermediateToken.bytes)}`,
|
||||||
|
);
|
||||||
|
log.debug(
|
||||||
|
`intermediateToken digest: ${base64.encode(intermediateToken.digest)}`,
|
||||||
|
);
|
||||||
if (!intermediateToken.data) intermediateToken.data = null;
|
if (!intermediateToken.data) intermediateToken.data = null;
|
||||||
const result = singleRow(
|
const result = singleRow(
|
||||||
await queryObject<Token>(
|
await queryObject<Token>(
|
||||||
|
@ -174,8 +180,20 @@ export async function createToken(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function deleteToken(
|
||||||
|
token: TokenDigest,
|
||||||
|
) {
|
||||||
|
const digest = sha256(base64.decode(token));
|
||||||
|
return await queryObject(
|
||||||
|
`
|
||||||
|
delete from user_token where digest = $1
|
||||||
|
`,
|
||||||
|
[digest],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export async function getToken(token: TokenDigest): Promise<Token | null> {
|
export async function getToken(token: TokenDigest): Promise<Token | null> {
|
||||||
const digest = base64.decode(token);
|
const digest = sha256(base64.decode(token));
|
||||||
return singleRow(
|
return singleRow(
|
||||||
await queryObject(
|
await queryObject(
|
||||||
`
|
`
|
||||||
|
@ -202,6 +220,7 @@ export async function getUser(
|
||||||
export async function getUserFromNonExpiredLoginToken(
|
export async function getUserFromNonExpiredLoginToken(
|
||||||
token: TokenDigest,
|
token: TokenDigest,
|
||||||
): Promise<User | null> {
|
): Promise<User | null> {
|
||||||
|
// TODO: if the token has expired, return a specific error?
|
||||||
const digest = sha256(base64.decode(token));
|
const digest = sha256(base64.decode(token));
|
||||||
return singleRow(
|
return singleRow(
|
||||||
await queryObject<User>(
|
await queryObject<User>(
|
||||||
|
@ -210,7 +229,7 @@ export async function getUserFromNonExpiredLoginToken(
|
||||||
left join "user" u on u.id = ut.user_id
|
left join "user" u on u.id = ut.user_id
|
||||||
where ut."digest" = $1
|
where ut."digest" = $1
|
||||||
and ut."data"->>'type' = 'login'
|
and ut."data"->>'type' = 'login'
|
||||||
and now() < (ut.created_at + '7 days'::interval)
|
and now() < (ut.created_at + '14 days'::interval)
|
||||||
`,
|
`,
|
||||||
[digest],
|
[digest],
|
||||||
),
|
),
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as $0 from "./routes/[name].tsx";
|
||||||
import * as $1 from "./routes/_404.tsx";
|
import * as $1 from "./routes/_404.tsx";
|
||||||
import * as $2 from "./routes/_500.tsx";
|
import * as $2 from "./routes/_500.tsx";
|
||||||
import * as $3 from "./routes/_app.tsx";
|
import * as $3 from "./routes/_app.tsx";
|
||||||
import * as $4 from "./routes/_middleware.ts";
|
import * as $4 from "./routes/_middleware.tsx";
|
||||||
import * as $5 from "./routes/about.tsx";
|
import * as $5 from "./routes/about.tsx";
|
||||||
import * as $6 from "./routes/api/joke.ts";
|
import * as $6 from "./routes/api/joke.ts";
|
||||||
import * as $7 from "./routes/api/random-uuid.ts";
|
import * as $7 from "./routes/api/random-uuid.ts";
|
||||||
|
@ -33,7 +33,7 @@ const manifest = {
|
||||||
"./routes/_404.tsx": $1,
|
"./routes/_404.tsx": $1,
|
||||||
"./routes/_500.tsx": $2,
|
"./routes/_500.tsx": $2,
|
||||||
"./routes/_app.tsx": $3,
|
"./routes/_app.tsx": $3,
|
||||||
"./routes/_middleware.ts": $4,
|
"./routes/_middleware.tsx": $4,
|
||||||
"./routes/about.tsx": $5,
|
"./routes/about.tsx": $5,
|
||||||
"./routes/api/joke.ts": $6,
|
"./routes/api/joke.ts": $6,
|
||||||
"./routes/api/random-uuid.ts": $7,
|
"./routes/api/random-uuid.ts": $7,
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
"imports": {
|
"imports": {
|
||||||
"@/": "./",
|
"@/": "./",
|
||||||
"$std/": "https://deno.land/std@0.158.0/",
|
"$std/": "https://deno.land/std@0.158.0/",
|
||||||
"$fresh/": "https://deno.land/x/fresh@1.1.2/",
|
"$freshbranch/": "https://raw.githubusercontent.com/lytedev/fresh/v1.1.2-df/",
|
||||||
|
"$fresh/": "../fresh/",
|
||||||
"preact": "https://esm.sh/preact@10.11.0",
|
"preact": "https://esm.sh/preact@10.11.0",
|
||||||
"preact/": "https://esm.sh/preact@10.11.0/",
|
"preact/": "https://esm.sh/preact@10.11.0/",
|
||||||
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@5.2.4",
|
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@5.2.4",
|
||||||
|
|
|
@ -2,18 +2,6 @@ import { type AppProps, Handlers } from "$fresh/server.ts";
|
||||||
import { type PublicUser } from "@/types.ts";
|
import { type PublicUser } from "@/types.ts";
|
||||||
import { type ContextState } from "@/types.ts";
|
import { type ContextState } from "@/types.ts";
|
||||||
|
|
||||||
interface MyAppProps extends AppProps {
|
|
||||||
user?: PublicUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const handler: Handlers<MyAppProps, ContextState> = {
|
|
||||||
async GET(request: Request, context) {
|
|
||||||
console.error("\n\nYO\n\n");
|
|
||||||
console.log("AppHandler:", request, context);
|
|
||||||
return await context.render({ user: context.state.user });
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const NAV_ITEM_CLASSES =
|
const NAV_ITEM_CLASSES =
|
||||||
"flex justify-center items-center px-4 py-2 hover:bg-gray-300 dark:hover:bg-gray-700";
|
"flex justify-center items-center px-4 py-2 hover:bg-gray-300 dark:hover:bg-gray-700";
|
||||||
|
|
||||||
|
@ -50,8 +38,9 @@ export function UserNavItems() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function App({ Component, ...props }: MyAppProps) {
|
export default function App(
|
||||||
console.log("AppProps:", props);
|
{ Component, contextState }: AppProps<ContextState>,
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<div class="relative min-h-screen flex flex-col">
|
<div class="relative min-h-screen flex flex-col">
|
||||||
<header class="flex justify-start items-center">
|
<header class="flex justify-start items-center">
|
||||||
|
@ -64,11 +53,11 @@ export default function App({ Component, ...props }: MyAppProps) {
|
||||||
<h1 class="text-2xl">LyricScreen</h1>
|
<h1 class="text-2xl">LyricScreen</h1>
|
||||||
</a>
|
</a>
|
||||||
<a tabIndex={11} href="/note" class={NAV_ITEM_CLASSES}>Notes</a>
|
<a tabIndex={11} href="/note" class={NAV_ITEM_CLASSES}>Notes</a>
|
||||||
{props.user ? UserNavItems() : LoginNavItems()}
|
{contextState.user ? UserNavItems() : LoginNavItems()}
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main class="p-2">
|
<main class="p-2">
|
||||||
<Component></Component>
|
<Component />
|
||||||
</main>
|
</main>
|
||||||
<footer class={`p-2 w-full mt-auto ${HEADER_CLASSES}`}>
|
<footer class={`p-2 w-full mt-auto ${HEADER_CLASSES}`}>
|
||||||
"It's a bit much, really..."
|
"It's a bit much, really..."
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { MiddlewareHandlerContext } from "$fresh/server.ts";
|
import { LayoutProps, MiddlewareHandlerContext } from "$fresh/server.ts";
|
||||||
import { deleteCookie, getCookies } from "$std/http/cookie.ts";
|
import { deleteCookie, getCookies } from "$std/http/cookie.ts";
|
||||||
import { getUserFromNonExpiredLoginToken } from "@/db/mod.ts";
|
import { getUserFromNonExpiredLoginToken } from "@/db/mod.ts";
|
||||||
import { type ContextState, type PublicUser, type User } from "@/types.ts";
|
import { type ContextState, type PublicUser, type User } from "@/types.ts";
|
||||||
|
@ -14,10 +14,22 @@ function toPublicUser(user: User): PublicUser {
|
||||||
return publicUser;
|
return publicUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Layout({ state, Component }: LayoutProps<ContextState>) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{state.something
|
||||||
|
? <p>Oh my! You said something!</p>
|
||||||
|
: <p>You aren't saying anything.</p>}
|
||||||
|
<Component />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async function currentUser(
|
async function currentUser(
|
||||||
request: Request,
|
request: Request,
|
||||||
context: MiddlewareHandlerContext<ContextState>,
|
context: MiddlewareHandlerContext<ContextState>,
|
||||||
) {
|
) {
|
||||||
|
context.layout = Layout;
|
||||||
let hasBadAuthCookie = false;
|
let hasBadAuthCookie = false;
|
||||||
const { lsauth } = getCookies(request.headers);
|
const { lsauth } = getCookies(request.headers);
|
||||||
log.debug("lsauth cookie:", lsauth);
|
log.debug("lsauth cookie:", lsauth);
|
||||||
|
@ -46,7 +58,16 @@ export async function serverHeader(
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function someState(
|
||||||
|
_request: Request,
|
||||||
|
context: MiddlewareHandlerContext<ContextState>,
|
||||||
|
) {
|
||||||
|
context.state.something = "I said something!";
|
||||||
|
return await context.next();
|
||||||
|
}
|
||||||
|
|
||||||
export const handler = [
|
export const handler = [
|
||||||
|
someState,
|
||||||
currentUser,
|
currentUser,
|
||||||
serverHeader,
|
serverHeader,
|
||||||
];
|
];
|
|
@ -10,7 +10,6 @@ export const handler: Handlers<unknown, ContextState> = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Dashboard({ data }: PageProps) {
|
export default function Dashboard({ data }: PageProps) {
|
||||||
console.log(data);
|
|
||||||
if (data) {
|
if (data) {
|
||||||
return You(data);
|
return You(data);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
import { Handlers } from "$fresh/server.ts";
|
import { Handlers } from "$fresh/server.ts";
|
||||||
// import { getToken, getUser } from "@/db/mod.ts";
|
// import { getToken, getUser } from "@/db/mod.ts";
|
||||||
// import * as base64 from "$std/encoding/base64.ts";
|
// import * as base64 from "$std/encoding/base64.ts";
|
||||||
import { deleteCookie } from "$std/http/cookie.ts";
|
import { deleteCookie, getCookies } from "$std/http/cookie.ts";
|
||||||
|
import { deleteToken } from "@/db/mod.ts";
|
||||||
|
|
||||||
export const handler: Handlers<unknown> = {
|
export const handler: Handlers<unknown> = {
|
||||||
async GET(_request: Request, context) {
|
async GET(request: Request, context) {
|
||||||
|
const { lsauth } = getCookies(request.headers);
|
||||||
|
if (lsauth) {
|
||||||
|
console.log("deleteToken:", await deleteToken(lsauth));
|
||||||
|
}
|
||||||
const response = await context.render();
|
const response = await context.render();
|
||||||
deleteCookie(response.headers, "lsauth");
|
deleteCookie(response.headers, "lsauth");
|
||||||
return response;
|
return response;
|
||||||
|
|
Loading…
Reference in a new issue