From 46902a9e33a25d711ea452c4845ab2c2e8134d42 Mon Sep 17 00:00:00 2001 From: ImAlpha Date: Wed, 21 Aug 2024 13:56:18 -0700 Subject: [PATCH] form modified to send to backend only instead of email --- backend/instance/mydatabase.db | Bin 24576 -> 24576 bytes backend/main.py | 61 ++++++++++++++++++++++- backend/private_key.txt | 1 + backend/public_key.txt | 2 + backend/readme.md | 4 ++ backend/requirements.txt | 6 ++- backend/templates/orders.html | 4 +- backend/templates/pushnotifications.html | 50 +++++++++++++++++++ backend/vapid_private.pem | 5 ++ frontend/src/app/page.tsx | 50 +++++++++++-------- 10 files changed, 156 insertions(+), 27 deletions(-) create mode 100644 backend/private_key.txt create mode 100644 backend/public_key.txt create mode 100644 backend/readme.md create mode 100644 backend/templates/pushnotifications.html create mode 100644 backend/vapid_private.pem diff --git a/backend/instance/mydatabase.db b/backend/instance/mydatabase.db index c2ae9eb30b5a8f1733ab49bcc8b480b136af10d2..7e8c98f3be5027a67a3fcdd61a015598d71a7359 100644 GIT binary patch delta 153 zcmZoTz}Rqrae_1>*F+g-RxSp;aIcLi3;c!H`F=9+U*%uL-@+fqZ^^IB_j9wLz+=8t z4R#g=YxVrhwBp39w5;+}hqV06(&EIl6usp9+_aRe#Ny2S0_)WBl1dRa76xVU;?%s9 v)FRj1#LS%hA|Okdm4!i5za+J|#33Cd2+{`PW#*+TfE6et7GzG2i(do)hjB9C delta 45 zcmZoTz}Rqrae_1>`$QRMR(1xxvhIy33;cOl_~RJ(ukx?rZ{d&IEGXc|KRGUb5db!k B4Wa-5 diff --git a/backend/main.py b/backend/main.py index 89dfffd..c23e910 100644 --- a/backend/main.py +++ b/backend/main.py @@ -3,7 +3,64 @@ from config import app, db, bcrypt from models import Contact, User, Orders from werkzeug.utils import secure_filename from werkzeug.exceptions import RequestEntityTooLarge -import os +import json, os +import logging +from pywebpush import webpush, WebPushException + + +DER_BASE64_ENCODED_PRIVATE_KEY_FILE_PATH = os.path.join(os.getcwd(),"private_key.txt") +DER_BASE64_ENCODED_PUBLIC_KEY_FILE_PATH = os.path.join(os.getcwd(),"public_key.txt") + +VAPID_PRIVATE_KEY = open(DER_BASE64_ENCODED_PRIVATE_KEY_FILE_PATH, "r+").readline().strip("\n") +VAPID_PUBLIC_KEY = open(DER_BASE64_ENCODED_PUBLIC_KEY_FILE_PATH, "r+").read().strip("\n") + +VAPID_CLAIMS = { +"sub": "mailto:arcjcb11p@gmail.com" +} + + +def send_web_push(subscription_information, message_body): + return webpush( + subscription_info=subscription_information, + data=message_body, + vapid_private_key=VAPID_PRIVATE_KEY, + vapid_claims=VAPID_CLAIMS + ) + + +@app.route("/subscription/", methods=["GET", "POST"]) +def subscription(): + """ + POST creates a subscription + GET returns vapid public key which clients uses to send around push notification + """ + + if request.method == "GET": + return Response(response=json.dumps({"public_key": VAPID_PUBLIC_KEY}), + headers={"Access-Control-Allow-Origin": "*"}, content_type="application/json") + + subscription_token = request.get_json("subscription_token") + return Response(status=201, mimetype="application/json") + + +@app.route("/push_v1/",methods=['POST']) +def push_v1(): + message = "Push Test v1" + print("is_json",request.is_json) + + if not request.json or not request.json.get('sub_token'): + return jsonify({'failed':1}) + + print("request.json",request.json) + + token = request.json.get('sub_token') + try: + token = json.loads(token) + send_web_push(token, message) + return jsonify({'success':1}) + except Exception as e: + print("error",e) + return jsonify({'failed':str(e)}) @app.route('/') @@ -70,7 +127,7 @@ def serve_image(filename): return send_from_directory(app.config['UPLOAD_DIRECTORY'], filename) -# Register User +# New Orders @app.route("/new-order", methods=["POST"]) def register_user(): email = request.json["email"] diff --git a/backend/private_key.txt b/backend/private_key.txt new file mode 100644 index 0000000..1ac27d5 --- /dev/null +++ b/backend/private_key.txt @@ -0,0 +1 @@ +eQYEgHfr53K8YbTLdqSiTWT8XrFvUxpnxtT_3Z9gks4 diff --git a/backend/public_key.txt b/backend/public_key.txt new file mode 100644 index 0000000..470dd76 --- /dev/null +++ b/backend/public_key.txt @@ -0,0 +1,2 @@ +BINa1y6A1wjwKg96cBGZ3uU7maveC_ifiuu9hW4E_Gx-m5ocB4zur5_wIpgQPq4cn26Q6cxAyYBR +dzp7FVtBPDU diff --git a/backend/readme.md b/backend/readme.md new file mode 100644 index 0000000..7090cd5 --- /dev/null +++ b/backend/readme.md @@ -0,0 +1,4 @@ +# Install vapid keys +`openssl ecparam -name prime256v1 -genkey -noout -out vapid_private.pem` +`openssl ec -in ./vapid_private.pem -outform DER|tail -c +8|head -c 32|base64|tr -d '=' |tr '/+' '_-' >> private_key.txt` +`openssl ec -in ./vapid_private.pem -pubout -outform DER|tail -c 65|base64|tr -d '=' |tr '/+' '_-' >> public_key.txt` \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt index 49a248a..00fed51 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -7,4 +7,8 @@ flask-session redis # Flask-Migrate # flask_validator -# psycopg2-binary \ No newline at end of file +# psycopg2-binary +py-vapid +pywebpush +cryptography +FLASK-API \ No newline at end of file diff --git a/backend/templates/orders.html b/backend/templates/orders.html index 381b40e..362ca97 100644 --- a/backend/templates/orders.html +++ b/backend/templates/orders.html @@ -7,7 +7,7 @@ Kevos orders diff --git a/backend/templates/pushnotifications.html b/backend/templates/pushnotifications.html new file mode 100644 index 0000000..3ce27ca --- /dev/null +++ b/backend/templates/pushnotifications.html @@ -0,0 +1,50 @@ + + + + + + + + + Push Notification | Raturi + + + + + + + + + + +
+

WebPush Notification

+
+ +
+

Welcome to the webpush notification. The button below needs to be + fixed to support subscribing to push.

+

+ +

+ +
+ + + + + + + + \ No newline at end of file diff --git a/backend/vapid_private.pem b/backend/vapid_private.pem new file mode 100644 index 0000000..3fd37a6 --- /dev/null +++ b/backend/vapid_private.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIHkGBIB36+dyvGG0y3akok1k/F6xb1MaZ8bU/92fYJLOoAoGCCqGSM49 +AwEHoUQDQgAEg1rXLoDXCPAqD3pwEZne5TuZq94L+J+K672FbgT8bH6bmhwHjO6v +n/AimBA+rhyfbpDpzEDJgFF3OnsVW0E8NQ== +-----END EC PRIVATE KEY----- diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index ab5ed77..8900bb4 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -9,6 +9,7 @@ import ClientPortal from "@/components/ClientPortal/ClientPortal"; import styles from "@/styles/Home.module.css"; import { Poppins } from "next/font/google"; import { sendEmail } from "./actions/sendEmail"; +import { createEmptyCacheNode } from "next/dist/client/components/app-router"; const Popp = Poppins({ weight: "400", subsets: ["latin"] }); @@ -17,31 +18,35 @@ const Popp = Poppins({ weight: "400", subsets: ["latin"] }); export default function Home() { const [email, setEmail] = React.useState(""); const [order, setOrder] = React.useState(""); - + + const [isOpen, setIsOpen] = React.useState(false); const [showPortal, setShowPortal] = React.useState(false); const handleModal = () => { setShowPortal(!showPortal); }; - // const registerUser = async () => { - // console.log(email, password); - // try { - // const res = await httpAxios.post("http://127.0.0.1:5080/register", { - // email, - // password, - // }); - // console.log(res) - // router.push("/LandingPage") - // } catch (error: any) { - // if (error.response.status === 401) { - // alert("Invalid Credentials"); - // } - // } - // }; + + async function newOrder(event: React.FormEvent) { + event.preventDefault(); + const response = await fetch("http://192.168.50.107:5580/new-order", { + method: "POST", + headers: { + 'Content-type': 'application/json', + }, + body: JSON.stringify({email:email, order:order }), + }) + .then((response) => response.json()) + .then((data) => { + console.log(data); + }) + .catch((error) => { + console.error(error); + }); + } return ( -
+
{/* Title */}
Kevo's Attire @@ -64,15 +69,16 @@ export default function Home() {
{ - await sendEmail(formData); - }} + // action={async (formData) => { + // await sendEmail(formData); + // }} + onSubmit={newOrder} >

Order Form

setEmail(e.target.value)} required maxLength={500} placeholder="Your email" @@ -82,7 +88,7 @@ export default function Home() {