Added implementation for base page and log in log out
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQCrwtnHsgIcPgii
|
||||
wbJuwx7qDxIAoDX4TpGCfSemHJypOTHbEbYkuTwgFqMhn83fm3DMnn/vorDfWOCp
|
||||
m4OvYIJ4QB9ZeiwDyvmjJQITX0o7pm2J0tpmFv4WK9BF+46bq81TtXUG99/ryH9N
|
||||
KFGT0WSdu0XHIqtg9OfVHolw9vPDPmmxRcPXg+2HziWBQuxqXHazdU31Cf8JDv3i
|
||||
BSYAIOmAsIAp4KuJtfX6MYK4/3jThuSfGzCnMlieDYj2mUcvCEx4iMk+nshryp5U
|
||||
B6+mgmqC9XgBwPOsqbybd3WnQXaAgT8bGqjLIYMqJrDVBPcuz+J9i3PFtheHtvmw
|
||||
E82aWSzWAK188NXzK6J2+BJFp97fdmPaSh5sEFe3twXNeIQgYjQ0b1Y6K9wSyk0m
|
||||
EgitIrp+ARmuSR7a9SHgdLg9FaMgLkUSrRk46r6P/lO9hSrCusH0cFwMIxgclS0D
|
||||
OPbfwqDIELClSaxO6umKh161W0kPk38k1DIdrWDUQnb4dMrQdSZrYmpyXhDNsLfH
|
||||
F+hZtNSy+376Utuud0UJSnO6k4QKJtpPaZRPPBIxcZ3a05JY09pVKHmev+j5U0fc
|
||||
uGWGyRa/cyPsHgU1kGVVOLaC21SJh8qWZCqUYby9AsbuTqz9qOpGNmCivmgUESs+
|
||||
h4VZoOOzj+5zGCK5LbIfsLL/nI2+QQIDAQABAoICAAgg5QiP0oy+nM8DBqw6PLTL
|
||||
+MihzFwPb9ByltVEJl/Vzpe0+186iu9j0t2NAAO0if6NA7X2B5PSU3ODYhSDJzmE
|
||||
o1crMnkNeonvfu0mxc8T3bw3h9FsBiNLeIRPVtzkIQf0nvCw+15fszKWFWI+9xmF
|
||||
2tQFPoIMpQoPc2ausTOMuRjEGfQRkMSsC1dWMPUJoi50/zb4/aJSnM48+yLna9WE
|
||||
xNP2h3exbk4kWLDjmja8fAZRlZhcCBiWwGQXNeiyZlgP9SIrBoYfZSXJ5VSmeF7x
|
||||
OfgvRvjlYYEkAqPjM7X6J9/i/5j5YYk1oom6Pe5vtSLG3jg9mVh5XtCn50OGM9pq
|
||||
9eMPMGkWqqi3lldfuDkb/uN/N2Tf4da0Cw8bcpjLn1WF393RM9Q6QippcEwHlA5U
|
||||
DA8wp/wg7I3BGWioayQjJyj8gCvcItNhscMzk/DflS/IRR3odRDd+iyFyPfVRX+b
|
||||
rgIDC4bObiTun25yHamOoLFiCxRjixOVSRLZUyr0CgY0k+/qx4nvFgeESMZibI55
|
||||
l3HHdmKlBQbUQnnmVwsLgSPptIZX/lK42W2Qxm37zgCjSl7SCZ5uSLOVkhzY7U8s
|
||||
UDRvPyHag6wb+ZHvs3eImsNwDC1FwbW+oKoh9WLUSGCeKSV94vzIlDcg0lAjyQe3
|
||||
6tCU5UaaNJ96Mo/GultvAoIBAQDGRrB50Vqy3G4hmvlTn+kUaLr4740nzSqlxIBn
|
||||
Hv6+zu2jahoKm5eWsX1L4oxUWPpm/sWShTgeiBzVpBf5ZbNeUyaZjg+S4UKkfrZW
|
||||
e7gjV056OS2KTIJBR/jk/v7O3BB6G5BWW3C+ZCTDZELwYn68Q9qu1ruhpDA8fpbe
|
||||
nYVCP+XhSSipT84JXpBZgbqn+mZnP8jwQ0Irusqp4aEMJrRfCvBKZUC2xIr4Dj0u
|
||||
SmYRePJtsQfs6/1XIo4kO+nuHMq39tWfVWhpUfi2etxSFVx8IH8qTI3t3RbLRB4S
|
||||
TAPrR3JL9VkMeiSL6td6HQK1B6aaFdQN+kU+JfDTbpXoj23rAoIBAQDdxAbbLv+k
|
||||
K2dzSdzaU0gUebL5SUa4xhjcHlUoCR6mEUeFsHlZx7rf4RpsiKSiTA+qQEfISmou
|
||||
fc80q5X/vRxksziUC+UuNRUuJ/10qqEkzcpyss5J+JoeKEUPIU3tbTvi4bR/TT+T
|
||||
VGE0KZJwgSZ2jkiO42pp4J43MV1NiiucJEh1BqtAVXjFmknomKsVsIAnoUMOeQx5
|
||||
IS7MC2FQJko4i5zK36YFzjCNHFrP6em+NpfSBKDcR3BK9hAyYHfAA5BPbecz+1vv
|
||||
mywBAC/xqzPO2UJegYMNpf6XDzGVG8heE//S/zrAn5cnu6j1RO7JwZiVEIBbwuL+
|
||||
7D7PO2sKhr2DAoIBAGtQcU3NmQh7tAPuTAoN3+pS8PexODYVnoKQA2tM5FZDy20K
|
||||
DUQ2iGpgcE91M7ynWAgM1sSB5CjqRKkBIpSyjc18tcSglh9KWnaLuoa+eaBvLaOL
|
||||
dPGIjWtl1/mhZipyA10DtDB5V2FE9HzotC5FMREWrLK6uF05b34eieu9WBXOXc58
|
||||
eUyCTCLYEsrPI0atiWVSqaAY1ySx+eTOoQrhm/hhBENP4CHL6OdvVX/Ldsj4LEZg
|
||||
bci2xay2oDZOU0O0Q6gkKeUOJe/zFOk3QC4RL7hjIlCzlJHsetzTZm9Cw1BBoEQq
|
||||
a+ML7OHp3mxSbVer52k4bUiPb5C+mkTlcq+nibcCggEAA6XTzwso3VRxcS4H2feA
|
||||
ugV+cidIaIWppwVAtVXhES47lPFgLZ/hbQlQ2/QrcRf7Mfu4soy2zmj3XZBs+TXt
|
||||
H6LrDVRcwrPQ01+JBcBAwlA4Qka6qfDS6CgVarhLhdpEH+lChM2KfCvpJWiBpiQZ
|
||||
s92HSAJpn7A4KgQ/2qSpLvpRzsr7SiWdxPJSwOax+btbgEtgxP4svFlVYbnWMfFP
|
||||
SzrQq22eV34awldzDvR0CdLwEF5PHxB1wmXlwk5f6eKlHwlZwjsiOgC9ao7MOxdr
|
||||
1L0yIEfVFgZi960iTaeVVibSEHBuUPjPDbJChzZJDzyF+/23fsrn3PWZ2uLJUfUB
|
||||
bQKCAQBzNxJJZl3ByUvD5inPoD3ZwbOaMdHSeDpQbQrH2BbCJRgGCHkjCY2hIgzt
|
||||
v/ju1xYQVkmGKdjwIuLpcaTV+afmdV/zXhyuJF2TRh28JXzFieCOWCILJor0VsrY
|
||||
Nleva1zLKvBvJS7epDu/lrRZ4TCD42ZqyGnK4rQK4NhheDfECPuD9lYPfOxkpHAT
|
||||
nXqVeZHe6LdEBcCytrc9zRd2YGT5nAheEW2U+ui4KxYK135VcoMZ0qV3gzEad+DO
|
||||
ZAD+PqVmOLk3FaOHpvtdpPZwU5NpHun/iyHMMLOXY6D/9CQQ6xQR6p63//9QaxLu
|
||||
TbEoB7CaVs+VEYE4GJpDXp3V2CQ3
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -22,6 +22,8 @@
|
||||
],
|
||||
"imports": {
|
||||
"$fresh/": "https://deno.land/x/fresh@1.7.3/",
|
||||
"@melvdouc/xml-parser": "jsr:@melvdouc/xml-parser@^0.1.1",
|
||||
"@popov/jwt": "jsr:@popov/jwt@^1.0.1",
|
||||
"preact": "https://esm.sh/preact@10.22.0",
|
||||
"preact/": "https://esm.sh/preact@10.22.0/",
|
||||
"@preact/signals": "https://esm.sh/*@preact/signals@1.2.2",
|
||||
|
||||
+7
-1
@@ -1,3 +1,9 @@
|
||||
import { defineConfig } from "$fresh/server.ts";
|
||||
|
||||
export default defineConfig({});
|
||||
export default defineConfig({
|
||||
server: {
|
||||
cert: await Deno.readTextFile("certs/cert.pem"),
|
||||
key: await Deno.readTextFile("certs/key.pem"),
|
||||
port: 443
|
||||
}
|
||||
});
|
||||
|
||||
+12
-4
@@ -2,21 +2,29 @@
|
||||
// This file SHOULD be checked into source version control.
|
||||
// This file is automatically updated during development when running `dev.ts`.
|
||||
|
||||
import * as $_modules_notes_index from "./routes/(modules)/notes/index.tsx";
|
||||
import * as $_404 from "./routes/_404.tsx";
|
||||
import * as $_app from "./routes/_app.tsx";
|
||||
import * as $api_joke from "./routes/api/joke.ts";
|
||||
import * as $greet_name_ from "./routes/greet/[name].tsx";
|
||||
import * as $_middleware from "./routes/_middleware.ts";
|
||||
import * as $index from "./routes/index.tsx";
|
||||
import * as $login from "./routes/login.tsx";
|
||||
import * as $logout from "./routes/logout.tsx";
|
||||
import * as $partials_about from "./routes/partials/about.tsx";
|
||||
import * as $partials_modules from "./routes/partials/modules.tsx";
|
||||
import * as $Counter from "./islands/Counter.tsx";
|
||||
import type { Manifest } from "$fresh/server.ts";
|
||||
|
||||
const manifest = {
|
||||
routes: {
|
||||
"./routes/(modules)/notes/index.tsx": $_modules_notes_index,
|
||||
"./routes/_404.tsx": $_404,
|
||||
"./routes/_app.tsx": $_app,
|
||||
"./routes/api/joke.ts": $api_joke,
|
||||
"./routes/greet/[name].tsx": $greet_name_,
|
||||
"./routes/_middleware.ts": $_middleware,
|
||||
"./routes/index.tsx": $index,
|
||||
"./routes/login.tsx": $login,
|
||||
"./routes/logout.tsx": $logout,
|
||||
"./routes/partials/about.tsx": $partials_about,
|
||||
"./routes/partials/modules.tsx": $partials_modules,
|
||||
},
|
||||
islands: {
|
||||
"./islands/Counter.tsx": $Counter,
|
||||
|
||||
-127
@@ -1,127 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,100..900;1,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
|
||||
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
|
||||
--dark-background-color: rgb(30, 30, 42);
|
||||
--dark-background-color-ui: rgb(50, 50, 62);
|
||||
--dark-foreground: rgb(241, 241, 255);
|
||||
|
||||
--light-background-color: rgb(225, 225, 237);
|
||||
--light-background-color-ui: rgb(241, 241, 255);
|
||||
--light-foreground: rgb(30, 30, 42);
|
||||
|
||||
--wave-color-1: #282830;
|
||||
--wave-color-2: #383840;
|
||||
--wave-color-3: #585860;
|
||||
--wave-color-4: #969698;
|
||||
|
||||
--loader-size: 0.5em;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: light-dark(var(--light-foreground), var(--dark-foreground));
|
||||
background-color: light-dark(var(--light-background-color), var(--dark-background-color));
|
||||
height: 100dvh;
|
||||
width: 100dvw;
|
||||
}
|
||||
|
||||
body {
|
||||
display: grid;
|
||||
font-family: Jost, sans-serif;
|
||||
font-feature-settings: "ss01" 1;
|
||||
font-weight: 500;
|
||||
place-content: center;
|
||||
padding: 0.75em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: Jost, sans-serif;
|
||||
margin: 0;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
section#main {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
/** loader */
|
||||
|
||||
.loader {
|
||||
margin: 2em 0;
|
||||
width: calc(4 * var(--loader-size));
|
||||
height: calc(4 * var(--loader-size));
|
||||
position: relative;
|
||||
--c:no-repeat linear-gradient(light-dark(var(--light-foreground), var(--dark-foreground)) 0 0);
|
||||
background:
|
||||
var(--c) center/100% var(--loader-size),
|
||||
var(--c) center/var(--loader-size) 100%;
|
||||
}
|
||||
|
||||
.loader:before {
|
||||
content:'';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
var(--c) 0 0,
|
||||
var(--c) 100% 0,
|
||||
var(--c) 0 100%,
|
||||
var(--c) 100% 100%;
|
||||
background-size: calc(1.55 * var(--loader-size)) calc(1.55 * var(--loader-size));
|
||||
animation: l16 1.5s infinite cubic-bezier(0.3,1,0,1);
|
||||
}
|
||||
|
||||
@keyframes l16 {
|
||||
33% {inset:calc(-1 * var(--loader-size));transform: rotate(0deg)}
|
||||
66% {inset:calc(-1 * var(--loader-size));transform: rotate(90deg)}
|
||||
100% {inset:0 ;transform: rotate(90deg)}
|
||||
}
|
||||
|
||||
/** waves */
|
||||
|
||||
section#background {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.parallax > use {
|
||||
animation: move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite;
|
||||
}
|
||||
|
||||
.parallax > use:nth-child(1) {
|
||||
animation-delay: -2s;
|
||||
animation-duration: 7s;
|
||||
}
|
||||
|
||||
.parallax > use:nth-child(2) {
|
||||
animation-delay: -3s;
|
||||
animation-duration: 10s;
|
||||
}
|
||||
|
||||
.parallax > use:nth-child(3) {
|
||||
animation-delay: -4s;
|
||||
animation-duration: 13s;
|
||||
}
|
||||
|
||||
.parallax > use:nth-child(4) {
|
||||
animation-delay: -5s;
|
||||
animation-duration: 20s;
|
||||
}
|
||||
|
||||
@keyframes move-forever {
|
||||
0% {
|
||||
transform: translate3d(-90px,0,0);
|
||||
}
|
||||
100% {
|
||||
transform: translate3d(85px,0,0);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Mock</title>
|
||||
|
||||
<link rel="stylesheet" href="base.css">
|
||||
<link rel="stylesheet" href="main.css">
|
||||
<meta name="theme-color" content="#57575a">
|
||||
<meta name="msapplication-TileColor" content="#57575a">
|
||||
<meta name="msapplication-navbutton-color" content="#57575a">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="#57575a">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- <section id="background">
|
||||
<svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
|
||||
<defs>
|
||||
<path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||
</defs>
|
||||
<g class="parallax">
|
||||
<use xlink:href="#gentle-wave" x="48" y="5" fill="#fff1" />
|
||||
<use xlink:href="#gentle-wave" x="48" y="3" fill="#fff1" />
|
||||
<use xlink:href="#gentle-wave" x="48" y="0" fill="#fff1" />
|
||||
<use xlink:href="#gentle-wave" x="48" y="7" fill="#fff1" />
|
||||
</g>
|
||||
</svg>
|
||||
</section> -->
|
||||
|
||||
<section id="main">
|
||||
<h1>PolyMPR</h1>
|
||||
<p>Random text go brrr</p>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,13 +0,0 @@
|
||||
section#main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
|
||||
background-color: light-dark(var(--light-background-color-ui), var(--dark-background-color-ui));
|
||||
padding: 2em;
|
||||
font-size: 2em;
|
||||
border-radius: 0.5em;
|
||||
z-index: 999;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Mock</title>
|
||||
|
||||
<link rel="stylesheet" href="base.css">
|
||||
<link rel="stylesheet" href="loading-page.css">
|
||||
<meta name="theme-color" content="#57575a">
|
||||
<meta name="msapplication-TileColor" content="#57575a">
|
||||
<meta name="msapplication-navbutton-color" content="#57575a">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="#57575a">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- <section id="background">
|
||||
<svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
|
||||
<defs>
|
||||
<path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||
</defs>
|
||||
<g class="parallax">
|
||||
<use xlink:href="#gentle-wave" x="48" y="5" fill="#fff1" />
|
||||
<use xlink:href="#gentle-wave" x="48" y="3" fill="#fff1" />
|
||||
<use xlink:href="#gentle-wave" x="48" y="0" fill="#fff1" />
|
||||
<use xlink:href="#gentle-wave" x="48" y="7" fill="#fff1" />
|
||||
</g>
|
||||
</svg>
|
||||
</section> -->
|
||||
|
||||
<section id="main">
|
||||
<h1>PolyMPR</h1>
|
||||
<p>Logging in with amU credentials...</p>
|
||||
<div class="loader"></div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,15 +0,0 @@
|
||||
section#main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: start;
|
||||
|
||||
background-color: light-dark(var(--light-background-color-ui), var(--dark-background-color-ui));
|
||||
padding: 2em;
|
||||
font-size: 2em;
|
||||
border-radius: 0.5em;
|
||||
z-index: 999;
|
||||
|
||||
width: 90dvw;
|
||||
height: 90dvh;
|
||||
}
|
||||
+1
-16
@@ -6,22 +6,7 @@ export default function Error404() {
|
||||
<Head>
|
||||
<title>404 - Page not found</title>
|
||||
</Head>
|
||||
<div class="px-4 py-8 mx-auto bg-[#86efac]">
|
||||
<div class="max-w-screen-md mx-auto flex flex-col items-center justify-center">
|
||||
<img
|
||||
class="my-6"
|
||||
src="/logo.svg"
|
||||
width="128"
|
||||
height="128"
|
||||
alt="the Fresh logo: a sliced lemon dripping with juice"
|
||||
/>
|
||||
<h1 class="text-4xl font-bold">404 - Page not found</h1>
|
||||
<p class="my-4">
|
||||
The page you were looking for doesn't exist.
|
||||
</p>
|
||||
<a href="/" class="underline">Go back home</a>
|
||||
</div>
|
||||
</div>
|
||||
<p>404</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
+24
-7
@@ -1,16 +1,33 @@
|
||||
import { type PageProps } from "$fresh/server.ts";
|
||||
export default function App({ Component }: PageProps) {
|
||||
import { FreshContext } from "$fresh/server.ts";
|
||||
import { Partial } from "$fresh/runtime.ts";
|
||||
|
||||
|
||||
export default async function App(request: Request, context: FreshContext) {
|
||||
const link = context.state.isAuthenticated ? "out" : "in";
|
||||
|
||||
return (
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>polympr</title>
|
||||
<link rel="stylesheet" href="/styles.css" />
|
||||
<title>PolyMPR</title>
|
||||
<link rel="stylesheet" href="/styles/main.css" />
|
||||
</head>
|
||||
<body>
|
||||
<Component />
|
||||
<body f-client-nav>
|
||||
<header>
|
||||
<h1>PolyMPR</h1>
|
||||
<nav>
|
||||
<a href="/modules" f-partial="/partials/modules">Modules</a>
|
||||
<a href={`/log${link}`} f-client-nav={false}>Log {link}</a>
|
||||
</nav>
|
||||
</header>
|
||||
<Partial name="body">
|
||||
<context.Component />
|
||||
</Partial>
|
||||
<footer>
|
||||
<p>© 2025 PolyMPR - <a href="/about" f-partial="/partials/about">About</a></p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { MiddlewareHandlerContext } from "$fresh/server.ts";
|
||||
import { getCookies } from "$std/http/cookie.ts";
|
||||
import { isJwtValid } from "@popov/jwt";
|
||||
|
||||
|
||||
const PUBLIC_ROUTES = ["/", "/login", "/logout", "/about", "/contact"];
|
||||
|
||||
interface State {
|
||||
isAuthenticated: boolean;
|
||||
}
|
||||
|
||||
|
||||
function isRoutePublic(route: string) {
|
||||
return PUBLIC_ROUTES.includes(route) || route.match(/\..+$/);
|
||||
}
|
||||
|
||||
|
||||
export const handler = [
|
||||
async function checkAuthentication(request: Request, context: MiddlewareHandlerContext<State>) {
|
||||
const cookies = getCookies(request.headers);
|
||||
context.state.isAuthenticated = await isJwtValid(cookies["sessionToken"] ?? "", "NEED TO CHANGE THIS KEY FURTHER IN DEV");
|
||||
|
||||
return context.next();
|
||||
},
|
||||
async function ensureAuthentication(request: Request, context: MiddlewareHandlerContext<State>) {
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (!isRoutePublic(url.pathname) && !context.state.isAuthenticated) {
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: "/login"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return context.next();
|
||||
}
|
||||
];
|
||||
@@ -1,21 +0,0 @@
|
||||
import { FreshContext } from "$fresh/server.ts";
|
||||
|
||||
// Jokes courtesy of https://punsandoneliners.com/randomness/programmer-jokes/
|
||||
const JOKES = [
|
||||
"Why do Java developers often wear glasses? They can't C#.",
|
||||
"A SQL query walks into a bar, goes up to two tables and says “can I join you?”",
|
||||
"Wasn't hard to crack Forrest Gump's password. 1forrest1.",
|
||||
"I love pressing the F5 key. It's refreshing.",
|
||||
"Called IT support and a chap from Australia came to fix my network connection. I asked “Do you come from a LAN down under?”",
|
||||
"There are 10 types of people in the world. Those who understand binary and those who don't.",
|
||||
"Why are assembly programmers often wet? They work below C level.",
|
||||
"My favourite computer based band is the Black IPs.",
|
||||
"What programme do you use to predict the music tastes of former US presidential candidates? An Al Gore Rhythm.",
|
||||
"An SEO expert walked into a bar, pub, inn, tavern, hostelry, public house.",
|
||||
];
|
||||
|
||||
export const handler = (_req: Request, _ctx: FreshContext): Response => {
|
||||
const randomIndex = Math.floor(Math.random() * JOKES.length);
|
||||
const body = JOKES[randomIndex];
|
||||
return new Response(body);
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
import { PageProps } from "$fresh/server.ts";
|
||||
|
||||
export default function Greet(props: PageProps) {
|
||||
return <div>Hello {props.params.name}</div>;
|
||||
}
|
||||
+1
-18
@@ -2,24 +2,7 @@ import { useSignal } from "@preact/signals";
|
||||
import Counter from "../islands/Counter.tsx";
|
||||
|
||||
export default function Home() {
|
||||
const count = useSignal(3);
|
||||
return (
|
||||
<div class="px-4 py-8 mx-auto bg-[#86efac]">
|
||||
<div class="max-w-screen-md mx-auto flex flex-col items-center justify-center">
|
||||
<img
|
||||
class="my-6"
|
||||
src="/logo.svg"
|
||||
width="128"
|
||||
height="128"
|
||||
alt="the Fresh logo: a sliced lemon dripping with juice"
|
||||
/>
|
||||
<h1 class="text-4xl font-bold">Welcome to Fresh</h1>
|
||||
<p class="my-4">
|
||||
Try updating this message in the
|
||||
<code class="mx-2">./routes/index.tsx</code> file, and refresh.
|
||||
</p>
|
||||
<Counter count={count} />
|
||||
</div>
|
||||
</div>
|
||||
<h1>PolyMPR</h1>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { State } from "./_middleware.ts";
|
||||
import { parse, type XmlNode } from "@melvdouc/xml-parser";
|
||||
import { createJwt } from "@popov/jwt";
|
||||
import { setCookie } from "$std/http/cookie.ts";
|
||||
|
||||
|
||||
const SERVICE = "https://localhost/login";
|
||||
const CAS = "https://ident.univ-amu.fr/cas";
|
||||
|
||||
|
||||
function getTag(tag: XmlNode): [string, string] {
|
||||
return [
|
||||
tag.tagName.replace("cas:", ""),
|
||||
tag.children[0].value
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
async function createUserJWT(casResponse: XmlNode): Promise<string> {
|
||||
const nodes = casResponse.children[1].children.map(getTag);
|
||||
const fullUserInfos = {};
|
||||
|
||||
nodes.forEach(([key, value]) => {
|
||||
if (fullUserInfos[key] && Array.isArray(fullUserInfos[key])) {
|
||||
fullUserInfos[key].push(value);
|
||||
}
|
||||
else if (fullUserInfos[key]) {
|
||||
fullUserInfos[key] = [fullUserInfos[key], value];
|
||||
}
|
||||
else {
|
||||
fullUserInfos[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const oneHour = 60 * 60;
|
||||
|
||||
const payload = {
|
||||
iss: "PolyMPR",
|
||||
iat: now,
|
||||
exp: now + oneHour,
|
||||
aud: "PolyMPR",
|
||||
user: fullUserInfos
|
||||
};
|
||||
|
||||
const key = "NEED TO CHANGE THIS KEY FURTHER IN DEV";
|
||||
return createJwt(payload, key);
|
||||
}
|
||||
|
||||
|
||||
export const handler: Handlers<any, State> = {
|
||||
async GET(request, context) {
|
||||
const url = new URL(request.url);
|
||||
const ticket = url.searchParams.get("ticket");
|
||||
|
||||
if (ticket) {
|
||||
const response = await fetch(`${CAS}/serviceValidate?service=${SERVICE}&ticket=${ticket}`);
|
||||
const body = parse(await response.text(), "application/xml");
|
||||
const casResponse = body[0].children[0];
|
||||
|
||||
if (casResponse.tagName != "cas:authenticationSuccess") {
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: `${CAS}/login?service=${SERVICE}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const headers = new Headers();
|
||||
|
||||
setCookie(headers, {
|
||||
name: "sessionToken",
|
||||
value: await createUserJWT(casResponse)
|
||||
});
|
||||
headers.set("Location", "/apps");
|
||||
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers
|
||||
});
|
||||
}
|
||||
|
||||
if (context.state.isAuthenticated) {
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: "/apps"
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: `${CAS}/login?service=${SERVICE}`
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { State } from "./_middleware.ts";
|
||||
import { deleteCookie } from "$std/http/cookie.ts";
|
||||
|
||||
|
||||
const SERVICE = "https://localhost/";
|
||||
const CAS = "https://ident.univ-amu.fr/cas";
|
||||
|
||||
|
||||
export const handler: Handlers<any, State> = {
|
||||
async GET(request, context) {
|
||||
if (context.state.isAuthenticated) {
|
||||
const headers = new Headers();
|
||||
|
||||
deleteCookie(headers, "sessionToken", { path: "/" });
|
||||
headers.set("Location", `${CAS}/logout?service=${SERVICE}`);
|
||||
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers
|
||||
});
|
||||
}
|
||||
else {
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: "/"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { RouteConfig } from "$fresh/server.ts";
|
||||
import { Partial } from "$fresh/runtime.ts";
|
||||
|
||||
export const config: RouteConfig = {
|
||||
skipAppWrapper: true,
|
||||
skipInheritedLayouts: true,
|
||||
};
|
||||
|
||||
export default async function About(request, context) {
|
||||
return (
|
||||
<Partial name="body">
|
||||
<p>C'est nous wsh</p>
|
||||
</Partial>
|
||||
);
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@@ -1,6 +0,0 @@
|
||||
<svg width="40" height="40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M34.092 8.845C38.929 20.652 34.092 27 30 30.5c1 3.5-2.986 4.222-4.5 2.5-4.457 1.537-13.512 1.487-20-5C2 24.5 4.73 16.714 14 11.5c8-4.5 16-7 20.092-2.655Z" fill="#FFDB1E"/>
|
||||
<path d="M14 11.5c6.848-4.497 15.025-6.38 18.368-3.47C37.5 12.5 21.5 22.612 15.5 25c-6.5 2.587-3 8.5-6.5 8.5-3 0-2.5-4-5.183-7.75C2.232 23.535 6.16 16.648 14 11.5Z" fill="#fff" stroke="#FFDB1E"/>
|
||||
<path d="M28.535 8.772c4.645 1.25-.365 5.695-4.303 8.536-3.732 2.692-6.606 4.21-7.923 4.83-.366.173-1.617-2.252-1.617-1 0 .417-.7 2.238-.934 2.326-1.365.512-4.223 1.29-5.835 1.29-3.491 0-1.923-4.754 3.014-9.122.892-.789 1.478-.645 2.283-.645-.537-.773-.534-.917.403-1.546C17.79 10.64 23 8.77 25.212 8.42c.366.014.82.35.82.629.41-.14 2.095-.388 2.503-.278Z" fill="#FFE600"/>
|
||||
<path d="M14.297 16.49c.985-.747 1.644-1.01 2.099-2.526.566.121.841-.08 1.29-.701.324.466 1.657.608 2.453.701-.715.451-1.057.852-1.452 2.106-1.464-.611-3.167-.302-4.39.42Z" fill="#fff"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
@@ -1,129 +0,0 @@
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
button {
|
||||
color: inherit;
|
||||
}
|
||||
button, [role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
code {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
"Liberation Mono", "Courier New", monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
img,
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
img,
|
||||
video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
html {
|
||||
line-height: 1.5;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
|
||||
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
}
|
||||
.transition-colors {
|
||||
transition-property: background-color, border-color, color, fill, stroke;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
.my-6 {
|
||||
margin-bottom: 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
.text-4xl {
|
||||
font-size: 2.25rem;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
.mx-2 {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.my-4 {
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.py-8 {
|
||||
padding-bottom: 2rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
.bg-\[\#86efac\] {
|
||||
background-color: #86efac;
|
||||
}
|
||||
.text-3xl {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
}
|
||||
.py-6 {
|
||||
padding-bottom: 1.5rem;
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
.px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
.py-1 {
|
||||
padding-bottom: 0.25rem;
|
||||
padding-top: 0.25rem;
|
||||
}
|
||||
.border-gray-500 {
|
||||
border-color: #6b7280;
|
||||
}
|
||||
.bg-white {
|
||||
background-color: #fff;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.gap-8 {
|
||||
grid-gap: 2rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.max-w-screen-md {
|
||||
max-width: 768px;
|
||||
}
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
.border-2 {
|
||||
border-width: 2px;
|
||||
}
|
||||
.rounded {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
.hover\:bg-gray-200:hover {
|
||||
background-color: #e5e7eb;
|
||||
}
|
||||
.tabular-nums {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
|
||||
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
|
||||
--dark-background-color: rgb(30, 30, 42);
|
||||
--dark-background-color-ui: rgb(50, 50, 62);
|
||||
--dark-foreground: rgb(241, 241, 255);
|
||||
--dark-foreground-dim: rgb(171, 171, 179);
|
||||
|
||||
--light-background-color: rgb(225, 225, 237);
|
||||
--light-background-color-ui: rgb(241, 241, 255);
|
||||
--light-foreground: rgb(30, 30, 42);
|
||||
--light-foreground-dim: rgb(171, 171, 179);
|
||||
|
||||
--accent-color: rgb(38, 157, 217);
|
||||
|
||||
--loader-size: 0.5em;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
font-family: "Jetbrains Mono";
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100dvh;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
background-color: light-dark(var(--light-background-color), var(--dark-background-color));
|
||||
color: light-dark(var(--light-foreground), var(--dark-foreground));
|
||||
}
|
||||
|
||||
header {
|
||||
padding: 0.5em 2em;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header > nav {
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 0.5em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: light-dark(var(--light-foreground-dim), var(--dark-foreground-dim));
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
async function main() {
|
||||
const initResponse = await fetch("https://ident.univ-amu.fr/cas/login");
|
||||
const initHTML = await initResponse.text();
|
||||
const execution = initHTML.match(/(?<=name="execution" value=").*?(?=")/)[0];
|
||||
|
||||
const data = new URLSearchParams();
|
||||
data.append("username", Deno.env.get("CAS_USERNAME"));
|
||||
data.append("password", Deno.env.get("CAS_PASSWORD"));
|
||||
data.append("_eventId", "submit");
|
||||
data.append("execution", execution);
|
||||
|
||||
const response = await fetch("https://ident.univ-amu.fr/cas/login", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
body: data.toString()
|
||||
});
|
||||
console.log(response.status)
|
||||
console.log(response.headers);
|
||||
|
||||
const content = await response.text();
|
||||
console.log(content);
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
const token = Deno.env.get("CAS_TOKEN");
|
||||
|
||||
async function main() {
|
||||
const response = await fetch("https://ident.univ-amu.fr/login?service=http://localhost", {
|
||||
"Cookie": `TGC=${token}`
|
||||
});
|
||||
console.log(response.headers);
|
||||
|
||||
|
||||
const responseText = await response.text();
|
||||
|
||||
console.log(responseText);
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user