From b8a0404e5a76ea7a6add2418e8eaaf75bfe8b18a Mon Sep 17 00:00:00 2001 From: qypol342 Date: Sun, 15 Sep 2024 21:45:20 +0200 Subject: [PATCH] WIP --- handlers/your-cal.go | 65 ++++- main.go | 11 +- static/encryption.js | 23 -- static/fonts/BricolageGrotesque-Bold.woff2 | Bin 0 -> 47044 bytes static/index.html | 186 ++++++++----- static/logo.svg | 5 + static/style.css | 184 ------------- static/styles.css | 290 +++++++++++++++++++++ 8 files changed, 491 insertions(+), 273 deletions(-) create mode 100644 static/fonts/BricolageGrotesque-Bold.woff2 create mode 100644 static/logo.svg delete mode 100644 static/style.css create mode 100644 static/styles.css diff --git a/handlers/your-cal.go b/handlers/your-cal.go index c9e82d9..ef671e0 100644 --- a/handlers/your-cal.go +++ b/handlers/your-cal.go @@ -11,7 +11,7 @@ import ( ) // generateICSHandler generates the ICS file and sends it in the response with a given filename -func GenerateICSHandler(w http.ResponseWriter, r *http.Request, filename, calendarName string) { +func GenerateICSHandler(w http.ResponseWriter, r *http.Request) { // Get start and end times from environment variables start := os.Getenv("START_TIMESTAMP") end := os.Getenv("END_TIMESTAMP") @@ -19,6 +19,10 @@ func GenerateICSHandler(w http.ResponseWriter, r *http.Request, filename, calend // Get separator from environment variable separator := os.Getenv("SEPARATOR") + filename := "cpe-calendar" + ".ics" + + calendarName := "CPE Calendar" + // Get query param 'creds' cryptedCreds := r.URL.Query().Get("creds") @@ -69,3 +73,62 @@ func GenerateICSHandler(w http.ResponseWriter, r *http.Request, filename, calend // Write the iCal content to the response w.Write([]byte(icsContent)) } + +func ValidateHandler(w http.ResponseWriter, r *http.Request) { + // Get start and end times from environment variables + start := os.Getenv("START_TIMESTAMP") + end := os.Getenv("END_TIMESTAMP") + + // Get separator from environment variable + separator := os.Getenv("SEPARATOR") + + // Get query param 'creds' + cryptedCreds := r.URL.Query().Get("creds") + + // Load the RSA private key + privateKey, err := decrypt.LoadPrivateKey() + if err != nil { + log.Printf("Error loading private key: %v", err) + http.Error(w, "Failed to load private key", http.StatusInternalServerError) + return + } + + // Decrypt the message + decryptedMessage, err := decrypt.DecryptMessage(cryptedCreds, privateKey) + if err != nil { + log.Printf("Error decrypting message: %v", err) + http.Error(w, "Invalid credentials", http.StatusBadRequest) + return + } + + // Split the decrypted message using the separator + parts := strings.Split(decryptedMessage, separator) + if len(parts) < 2 { + http.Error(w, "Invalid credentials format", http.StatusBadRequest) + return + } + username := parts[0] + pass := parts[1] + + // Fetch data from the source + data, err := request.FetchData(start, end, username, pass) + if err != nil { + log.Printf("Failed to fetch data: %v", err) + http.Error(w, "Failed to fetch data", http.StatusInternalServerError) + return + } + + // Parse the fetched data + events, err := ical.ParseEvents(data) + if err != nil { + log.Printf("Failed to parse events: %v", err) + http.Error(w, "Failed to parse events", http.StatusInternalServerError) + return + } + + if len(events) > 0 { + w.WriteHeader(http.StatusOK) + } else { + w.WriteHeader(http.StatusUnauthorized) + } +} diff --git a/main.go b/main.go index 384c406..f37ffd4 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,10 @@ func main() { r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static/")))) // Serve calendar.ics route - r.HandleFunc("/your-cpe-calendar.ics", generate3IRCHandler).Methods("GET") + r.HandleFunc("/your-cpe-calendar.ics", handlers.GenerateICSHandler).Methods("GET") + + //validate route + r.HandleFunc("/validate", handlers.ValidateHandler).Methods("POST") // Use the router in the http server log.Fatal(http.ListenAndServe(":8080", r)) @@ -56,9 +59,3 @@ func serveIndex(w http.ResponseWriter, r *http.Request) { http.Error(w, "Error rendering template", http.StatusInternalServerError) } } - -// generate3IRCHandler is a wrapper around generateICSHandler that uses a specific filename -func generate3IRCHandler(w http.ResponseWriter, r *http.Request) { - // Call generateICSHandler with the specific filename and calendar name - handlers.GenerateICSHandler(w, r, "3irc_calendar.ics", "3IRC Calendar") -} diff --git a/static/encryption.js b/static/encryption.js index 87eb4e0..cd92a13 100644 --- a/static/encryption.js +++ b/static/encryption.js @@ -1,13 +1,3 @@ - -function copyLink(link) { - const fullLink = `${window.location.origin}${link}`; - navigator.clipboard.writeText(fullLink).then(() => { - showToast(); - }).catch(err => { - console.error('Failed to copy text: ', err); - }); -} - /* The unwrapped signing key. */ @@ -100,16 +90,3 @@ async function encryptMessage(message) { // Convert the ciphertext to Base64 return arrayBufferToBase64(ciphertext); } - - -function showToast() { - const toast = document.getElementById('toast'); - toast.className = 'show'; - setTimeout(() => { - toast.className = toast.className.replace('show', ''); - }, 3000); -} - -importPublicKey(pemEncodedKey).then(key => { - encryptionKey = key; -}); diff --git a/static/fonts/BricolageGrotesque-Bold.woff2 b/static/fonts/BricolageGrotesque-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..84b8225916508b9c05de1d60edaa2edd0479ebb1 GIT binary patch literal 47044 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

OzthdUU>7mo2E6z#Ot*9FxfA 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 EO9Z_gHvj+t literal 0 HcmV?d00001 diff --git a/static/index.html b/static/index.html index 037e2a7..bd25d18 100644 --- a/static/index.html +++ b/static/index.html @@ -1,83 +1,153 @@ - + - CPE Calendar - - + Calendrier CPE + + - - + + - - - - - + -

-
-

CPE Calendar

-
-
-
-

The best way to stay up-to-date with your schedule using your personal calendar app.

- Let's get started -
-
-
- -
-
-

Get your calendars

-
-
    -
  • - -
    - - +
    + +
    + +
    +
    +

    Synchronisez votre calendrier CPE avec votre téléphone

    +

    Restez informé de tout changement de plan sans effort et accédez facilement à votre prochain lieu de + rendez-vous.

    + + + Obtenez votre calendrier +
    + +
    +

    Obtenez votre calendrier

    +
    +
    + +
    - -
  • -
-
+
+ + +
+ + + -
Link copied to clipboard!
+
+

À propos

+

L'objectif du Calendrier CPE est d'offrir à chaque étudiant un accès simple et sans effort à leur + calendrier en connectant leur calendrier scolaire à leur calendrier personnel. Cela fonctionne sur tous + les appareils—téléphone, ordinateur portable—et avec n'importe quel fournisseur, y compris Apple et + Android.

+

Le calendrier se mettra automatiquement à jour sur votre appareil toutes les heures, vous permettant de + rester informé de tout changement d'emploi du temps.

+

Ce projet est open-source. Si à tout moment vous constatez un problème ou une fonctionnalité manquante, + n'hésitez pas à nous contacter et à partager cela sur GitHub.

+
+ +
+

Confiance

+

Comme pour tous les projets open-source hébergés, il n'y a aucune garantie que le propriétaire de + l'instance n'ait pas altéré le code officiel. Cela signifie qu'il y aura toujours un certain niveau de + confiance impliqué dans la chaîne.

+

Voici quelques recommandations et bonnes pratiques en fonction de votre niveau de confiance ou du risque + que vous êtes prêt à accepter :

+
    +
  1. Pleine confiance : Utilisez le service tel quel.
  2. +
  3. Quelques doutes : Limitez l'impact des problèmes potentiels en prenant des précautions, comme créer + un mot de passe dédié pour le service.
  4. +
  5. Aucun risque : Comme il s'agit d'un projet open-source, vous pouvez héberger votre propre instance. + Un guide est disponible ici.
  6. +
+
- + - + - + \ No newline at end of file diff --git a/static/logo.svg b/static/logo.svg new file mode 100644 index 0000000..bb92da7 --- /dev/null +++ b/static/logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/style.css b/static/style.css deleted file mode 100644 index f6763c0..0000000 --- a/static/style.css +++ /dev/null @@ -1,184 +0,0 @@ -/* CSS Variables for colors and other reusable values */ -:root { - --primary-color: #007bff; - --primary-color-dark: #0056b3; - --text-color: #333; - --background-color: #f4f4f4; - --card-background: #fff; - --card-shadow: rgba(0, 0, 0, 0.1); - --toast-background: #333; - --toast-color: #fff; - --border-color: #ddd; - --font-family: 'Bricolage Grotesque', sans-serif; - --toast-animation-time: 0.5s; -} - -body { - margin: 0; - padding: 0; - background-color: var(--background-color); - color: var(--text-color); - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - box-sizing: border-box; - - font-family: "Bricolage Grotesque", sans-serif; - font-optical-sizing: auto; - font-weight: 800; - font-style: normal; - font-variation-settings: - "wdth" 75; -} - -.core { - display: flex; - flex-direction: column; - width: 100%; - height: 100dvh; - background-color: var(--card-background); - overflow: hidden; -} - -header { - background-color: var(--primary-color); - color: #fff; - padding: 20px; - text-align: center; -} - -main { - padding: 20px; - height: 100dvh; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -#calendar { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - padding: 20px; - width: fit-content; - height: fit-content; -} - -#calendar h2 { - font-size: 2em; - margin-bottom: 10px; -} - -#calendar a { - color: var(--primary-color); - text-decoration: none; - font-weight: bold; -} - -#calendar a:hover { - text-decoration: underline; -} - -.list { - padding: 20px; - background-color: var(--background-color); - min-height: 90dvh; - max-width: 800px; - width: 100%; -} - -.list h2 { - font-size: 1.5em; - margin-bottom: 15px; -} - -.list ul { - list-style: none; - padding: 0; - margin: 0; -} - -.list li { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 0; - border-bottom: 1px solid var(--border-color); - flex-direction: column; - gap: 1rem; -} - -.list label { - font-size: 1.1em; - color: var(--text-color); -} - -.list button { - background-color: var(--primary-color); - color: #fff; - border: none; - padding: 8px 12px; - border-radius: 5px; - cursor: pointer; - font-size: 0.9em; - transition: background-color 0.3s ease; -} - -.list button:hover { - background-color: var(--primary-color-dark); -} - -#toast { - visibility: hidden; - min-width: 250px; - background-color: var(--toast-background); - color: var(--toast-color); - text-align: center; - border-radius: 5px; - padding: 10px; - position: fixed; - z-index: 1; - left: 50%; - bottom: 30px; - font-size: 17px; - transform: translateX(-50%); -} - -#toast.show { - visibility: visible; - animation: fadein var(--toast-animation-time), fadeout var(--toast-animation-time) 2.5s; -} - -.center { - display: flex; - width: 100%; - justify-content: center; - align-items: center; -} - -@keyframes fadein { - from { - bottom: 0; - opacity: 0; - } - - to { - bottom: 30px; - opacity: 1; - } -} - -@keyframes fadeout { - from { - bottom: 30px; - opacity: 1; - } - - to { - bottom: 0; - opacity: 0; - } -} \ No newline at end of file diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..7e2ce34 --- /dev/null +++ b/static/styles.css @@ -0,0 +1,290 @@ +/* font */ + +@font-face { + font-family: "Bricolage Grotesque"; + src: url("/static/fonts/BricolageGrotesque-Bold.woff2"); + font-weight: bold; +} + +/* Root-level variables for colors and font-sizes */ +:root { + /* Color Variables */ + --primary-color: #5D688A; + --secondary-color: #ADC3C1; + --text-color: #333; + --background-color: #EBF1F1; + --secondary-background-color: #ffffff; + --input-border-color: #ccc; + + /* Font Size Variables */ + --font-size-base: 1rem; + --font-size-md: 1.2rem; + --font-size-lg: 1.5rem; + --font-size-xl: 3.5rem; + --font-size-2xl: 4rem; + + --toast-animation-time: 0.5s; + --toast-background: #333; + --toast-color: #fff; + + + /* Border Radius */ + --border-radius: 2rem; + --border-radius-lg: 10px; +} + +/* Reset default styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Inter', sans-serif; + font-weight: bold; + text-decoration: none; +} + +html { + scroll-behavior: smooth; +} + +body { + background-color: var(--background-color); + color: var(--text-color); + line-height: 1.6; + font-size: var(--font-size-base); + display: flex; + flex-direction: column; + min-height: 100dvh; + width: 100%; +} + +header { + width: 100%; + height: 4rem; + display: flex; + align-items: center; + justify-content: center; +} + +nav { + display: flex; + justify-content: space-between; + align-items: center; + background-color: var(--secondary-background-color); + width: 80%; + max-width: 800px; + padding: 0 .5rem 0 1rem; + border-radius: var(--border-radius); + height: 2.8rem; +} + +ul { + list-style: none; + display: flex; + align-items: center; + gap: 1rem; +} + +li { + align-items: center; + height: fit-content; +} + +nav ul li { + display: flex; +} + +ul img { + height: 2rem; +} + +a { + color: var(--text-color); +} + +h1 { + font-size: var(--font-size-2xl); + font-family: 'Bricolage Grotesque', sans-serif; + font-weight: bold; + text-align: center; +} + +h2 { + font-size: var(--font-size-xl); + font-family: 'Bricolage Grotesque', sans-serif; + font-weight: bold; + margin-bottom: 1rem; + text-align: center; +} + +button { + font-size: var(--font-size-base); +} + +section { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 2rem; + width: 100%; + max-width: 800px; + margin: 0 auto; + gap: 1.5rem; +} + +form { + display: flex; + flex-direction: column; + gap: 2rem; + align-items: center; +} + +label { + font-size: var(--font-size-md); +} + +input { + padding: 0.5rem 1rem; + border: none; + border-radius: var(--border-radius); + font-size: var(--font-size-md); +} + +ol { + margin-left: 2rem; +} + +footer { + display: flex; + justify-content: center; + align-items: center; + background-color: var(--secondary-background-color); + height: 4rem; + width: 100%; +} + +footer div { + display: flex; + justify-content: space-between; + align-items: center; + width: 80%; + max-width: 800px; + padding: 0 .5rem; +} + +.btn-primary { + background-color: var(--primary-color); + color: var(--secondary-background-color); + border: none; + padding: 0.5rem 1rem; + border-radius: var(--border-radius); + cursor: pointer; + width: fit-content; +} + +.btn-secondary { + background-color: var(--secondary-color); + color: var(--text-color); + border: none; + padding: 0.5rem 1rem; + border-radius: var(--border-radius); + cursor: pointer; +} + +li .btn-secondary { + padding: 0.25rem 1rem; +} + +.btn-primary { + font-size: var(--font-size-lg); + font-family: 'Bricolage Grotesque', sans-serif; +} + +.btn-hero { + background-color: var(--secondary-background-color); + color: var(--text-color); + padding: 0.5rem 1rem; + border-radius: var(--border-radius); + cursor: pointer; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.btn-hero img { + height: 2rem; +} + +.btn-hero span { + font-size: var(--font-size-lg); +} + +.hero { + height: calc(100vh - 4rem); + gap: 1.5rem; + max-width: 1100px; +} + +.hero p { + font-size: var(--font-size-md); + font-weight: bold; + text-align: center; + max-width: 800px; +} + +.get-calendar { + height: 50dvh; +} + +.form-row { + display: flex; + flex-direction: column; + gap: 0.5rem; + width: 100%; +} + +#toast { + visibility: hidden; + min-width: 250px; + background-color: var(--toast-background); + color: var(--toast-color); + text-align: center; + border-radius: 5px; + padding: 10px; + position: fixed; + z-index: 1; + left: 50%; + bottom: 30px; + font-size: 17px; + transform: translateX(-50%); +} + +#toast.show { + visibility: visible; + animation: fadein var(--toast-animation-time), fadeout var(--toast-animation-time) 2.5s; +} + +@keyframes fadein { + from { + bottom: 0; + opacity: 0; + } + + to { + bottom: 30px; + opacity: 1; + } +} + +@keyframes fadeout { + from { + bottom: 30px; + opacity: 1; + } + + to { + bottom: 0; + opacity: 0; + } +} \ No newline at end of file