From ccad788e198623b048e52e65c4b77b8f366e245d Mon Sep 17 00:00:00 2001 From: fedyna-k Date: Tue, 14 Jan 2025 23:34:40 +0100 Subject: [PATCH] Added implementation for base page and log in log out --- certs/cert.pem | 31 ++++++++ certs/key.pem | 52 +++++++++++++ deno.json | 2 + fresh.config.ts | 8 +- fresh.gen.ts | 16 +++- mock/base.css | 127 ------------------------------ mock/index.html | 37 --------- mock/loading-page.css | 13 ---- mock/loading.html | 38 --------- mock/main.css | 15 ---- routes/(modules)/notes/index.tsx | 0 routes/_404.tsx | 17 +--- routes/_app.tsx | 31 ++++++-- routes/_middleware.ts | 39 ++++++++++ routes/api/joke.ts | 21 ----- routes/greet/[name].tsx | 5 -- routes/index.tsx | 19 +---- routes/login.tsx | 102 ++++++++++++++++++++++++ routes/logout.tsx | 32 ++++++++ routes/partials/about.tsx | 15 ++++ routes/partials/modules.tsx | 0 static/favicon.ico | Bin 22382 -> 0 bytes static/logo.svg | 6 -- static/styles.css | 129 ------------------------------- static/styles/main.css | 56 ++++++++++++++ test/cas.js | 27 ------- test/getInfo.js | 15 ---- 27 files changed, 374 insertions(+), 479 deletions(-) create mode 100644 certs/cert.pem create mode 100644 certs/key.pem delete mode 100644 mock/base.css delete mode 100644 mock/index.html delete mode 100644 mock/loading-page.css delete mode 100644 mock/loading.html delete mode 100644 mock/main.css create mode 100644 routes/(modules)/notes/index.tsx create mode 100644 routes/_middleware.ts delete mode 100644 routes/api/joke.ts delete mode 100644 routes/greet/[name].tsx create mode 100644 routes/login.tsx create mode 100644 routes/logout.tsx create mode 100644 routes/partials/about.tsx create mode 100644 routes/partials/modules.tsx delete mode 100644 static/favicon.ico delete mode 100644 static/logo.svg delete mode 100644 static/styles.css create mode 100644 static/styles/main.css delete mode 100644 test/cas.js delete mode 100644 test/getInfo.js diff --git a/certs/cert.pem b/certs/cert.pem new file mode 100644 index 0000000..1c825f4 --- /dev/null +++ b/certs/cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIUBzpjXMENeWGtcDHiOJ6mvvP+C48wDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNTAxMTQxNjUwMzhaFw0yNjAx +MTQxNjUwMzhaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCrwtnHsgIcPgiiwbJuwx7qDxIAoDX4TpGCfSemHJyp +OTHbEbYkuTwgFqMhn83fm3DMnn/vorDfWOCpm4OvYIJ4QB9ZeiwDyvmjJQITX0o7 +pm2J0tpmFv4WK9BF+46bq81TtXUG99/ryH9NKFGT0WSdu0XHIqtg9OfVHolw9vPD +PmmxRcPXg+2HziWBQuxqXHazdU31Cf8JDv3iBSYAIOmAsIAp4KuJtfX6MYK4/3jT +huSfGzCnMlieDYj2mUcvCEx4iMk+nshryp5UB6+mgmqC9XgBwPOsqbybd3WnQXaA +gT8bGqjLIYMqJrDVBPcuz+J9i3PFtheHtvmwE82aWSzWAK188NXzK6J2+BJFp97f +dmPaSh5sEFe3twXNeIQgYjQ0b1Y6K9wSyk0mEgitIrp+ARmuSR7a9SHgdLg9FaMg +LkUSrRk46r6P/lO9hSrCusH0cFwMIxgclS0DOPbfwqDIELClSaxO6umKh161W0kP +k38k1DIdrWDUQnb4dMrQdSZrYmpyXhDNsLfHF+hZtNSy+376Utuud0UJSnO6k4QK +JtpPaZRPPBIxcZ3a05JY09pVKHmev+j5U0fcuGWGyRa/cyPsHgU1kGVVOLaC21SJ +h8qWZCqUYby9AsbuTqz9qOpGNmCivmgUESs+h4VZoOOzj+5zGCK5LbIfsLL/nI2+ +QQIDAQABo1MwUTAdBgNVHQ4EFgQUrCJYEE6AckkV62vmB6NpgFSM1QYwHwYDVR0j +BBgwFoAUrCJYEE6AckkV62vmB6NpgFSM1QYwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEApzFmj9XCez3mRLctBCsrTHMueNFrLovscoxb2kWirnIJ +nM0GfLhZcx56+ZXUea5khbIbJrF47Eyh4GVz6ezZnoVBkb2PnD5FzafLxQEhg/bT +9zMWrcGVCe9/Uz1znUXDh7ljj15h60CdhyG3EVCfWxzJs3m/sOGDlA6qDxx0MNdY +PjdQaPPHCH1yDn7vkBWD9SRHJh4/wAl+LAf+3eF9Uz7CRRYA/sYu2dzLLfUXo+My +LJ8JIss2p24pRl6FyHNH5pJ1Uvr0wGfJ9h0rrKixfHgJ3478cxVxns8Ig0BTWJPV +kMdh+rplnnE4CSAaPWnAbD6O4WM7pDQDRXc8kfrcyt0MQ0UYPLwcpQ72umIOkonK +R0FsPLvRe0lmsMeG+Id34CEFtxegbsGCt5OOMKzA3k69JVvLvS85FuLO2a+TrDYg +itCKHVX06oAGa8XAsy1q/s9BMxNWzVDAza6svINaIqubHk1YGJ/hiAvVvBuEKHnT +Gc9uYQEngA3zVjhoiPx2Z6AoSj6Ve2K38JZgPOAfo887W+4a/mguV8QlVv2qeibm +jZKTKglZvH6Iz/v+zM2mWdh+RsyW+hkUum6lH/0vpQnZAUcMK8U5YnAjsFF8tfWy +eJY2gFisHwz6pVY5FwUW/FvaWRIfPTp9CdTHJlhlGTNb3SlLODaM+um46aFaUz0= +-----END CERTIFICATE----- diff --git a/certs/key.pem b/certs/key.pem new file mode 100644 index 0000000..21816ce --- /dev/null +++ b/certs/key.pem @@ -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----- diff --git a/deno.json b/deno.json index 76ef608..ef4b243 100644 --- a/deno.json +++ b/deno.json @@ -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", diff --git a/fresh.config.ts b/fresh.config.ts index e7b63d9..783c68c 100644 --- a/fresh.config.ts +++ b/fresh.config.ts @@ -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 + } +}); diff --git a/fresh.gen.ts b/fresh.gen.ts index dd4df1a..cce7416 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -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, diff --git a/mock/base.css b/mock/base.css deleted file mode 100644 index 7a1aa9f..0000000 --- a/mock/base.css +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/mock/index.html b/mock/index.html deleted file mode 100644 index fc623d4..0000000 --- a/mock/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Mock - - - - - - - - - - - - -
-

PolyMPR

-

Random text go brrr

-
- - \ No newline at end of file diff --git a/mock/loading-page.css b/mock/loading-page.css deleted file mode 100644 index 78e7714..0000000 --- a/mock/loading-page.css +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/mock/loading.html b/mock/loading.html deleted file mode 100644 index c785837..0000000 --- a/mock/loading.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - Mock - - - - - - - - - - - - -
-

PolyMPR

-

Logging in with amU credentials...

-
-
- - \ No newline at end of file diff --git a/mock/main.css b/mock/main.css deleted file mode 100644 index e2ef1ee..0000000 --- a/mock/main.css +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/routes/(modules)/notes/index.tsx b/routes/(modules)/notes/index.tsx new file mode 100644 index 0000000..e69de29 diff --git a/routes/_404.tsx b/routes/_404.tsx index c63ae2e..fb42994 100644 --- a/routes/_404.tsx +++ b/routes/_404.tsx @@ -6,22 +6,7 @@ export default function Error404() { 404 - Page not found -
-
- the Fresh logo: a sliced lemon dripping with juice -

404 - Page not found

-

- The page you were looking for doesn't exist. -

- Go back home -
-
+

404

); } diff --git a/routes/_app.tsx b/routes/_app.tsx index 6e4ecf6..0d62d67 100644 --- a/routes/_app.tsx +++ b/routes/_app.tsx @@ -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 ( - polympr - + PolyMPR + - - + +
+

PolyMPR

+ +
+ + + +
+

© 2025 PolyMPR - About

+
); -} +} \ No newline at end of file diff --git a/routes/_middleware.ts b/routes/_middleware.ts new file mode 100644 index 0000000..b26a63e --- /dev/null +++ b/routes/_middleware.ts @@ -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) { + 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) { + 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(); + } +]; \ No newline at end of file diff --git a/routes/api/joke.ts b/routes/api/joke.ts deleted file mode 100644 index db17edd..0000000 --- a/routes/api/joke.ts +++ /dev/null @@ -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); -}; diff --git a/routes/greet/[name].tsx b/routes/greet/[name].tsx deleted file mode 100644 index 9c06827..0000000 --- a/routes/greet/[name].tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { PageProps } from "$fresh/server.ts"; - -export default function Greet(props: PageProps) { - return
Hello {props.params.name}
; -} diff --git a/routes/index.tsx b/routes/index.tsx index fc8061e..d06b743 100644 --- a/routes/index.tsx +++ b/routes/index.tsx @@ -2,24 +2,7 @@ import { useSignal } from "@preact/signals"; import Counter from "../islands/Counter.tsx"; export default function Home() { - const count = useSignal(3); return ( -
-
- the Fresh logo: a sliced lemon dripping with juice -

Welcome to Fresh

-

- Try updating this message in the - ./routes/index.tsx file, and refresh. -

- -
-
+

PolyMPR

); } diff --git a/routes/login.tsx b/routes/login.tsx new file mode 100644 index 0000000..fd0db53 --- /dev/null +++ b/routes/login.tsx @@ -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 { + 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 = { + 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}` + } + }); + } + } +}; \ No newline at end of file diff --git a/routes/logout.tsx b/routes/logout.tsx new file mode 100644 index 0000000..730d9d3 --- /dev/null +++ b/routes/logout.tsx @@ -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 = { + 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: "/" + } + }); + } + } +}; \ No newline at end of file diff --git a/routes/partials/about.tsx b/routes/partials/about.tsx new file mode 100644 index 0000000..f4f920c --- /dev/null +++ b/routes/partials/about.tsx @@ -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 ( + +

C'est nous wsh

+
+ ); +}; \ No newline at end of file diff --git a/routes/partials/modules.tsx b/routes/partials/modules.tsx new file mode 100644 index 0000000..e69de29 diff --git a/static/favicon.ico b/static/favicon.ico deleted file mode 100644 index 1cfaaa2193b0f210107a559f7421569f57a25388..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22382 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 bck@HGWY%2idMme??%p8ZW3z(%VE+9-Ofn0d diff --git a/static/logo.svg b/static/logo.svg deleted file mode 100644 index ef2fbe4..0000000 --- a/static/logo.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/static/styles.css b/static/styles.css deleted file mode 100644 index e94132d..0000000 --- a/static/styles.css +++ /dev/null @@ -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; -} diff --git a/static/styles/main.css b/static/styles/main.css new file mode 100644 index 0000000..9cedc36 --- /dev/null +++ b/static/styles/main.css @@ -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)); +} \ No newline at end of file diff --git a/test/cas.js b/test/cas.js deleted file mode 100644 index e2d442c..0000000 --- a/test/cas.js +++ /dev/null @@ -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() - diff --git a/test/getInfo.js b/test/getInfo.js deleted file mode 100644 index 269043a..0000000 --- a/test/getInfo.js +++ /dev/null @@ -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(); \ No newline at end of file