diff --git a/.gitea/workflows/deploy_via_docker_compose.yml b/.gitea/workflows/deploy_via_docker_compose.yml
index 518ab47..d423851 100644
--- a/.gitea/workflows/deploy_via_docker_compose.yml
+++ b/.gitea/workflows/deploy_via_docker_compose.yml
@@ -21,6 +21,10 @@ jobs:
git pull
echo "============ Git pull finished! ========="
echo '${{ vars.ENV }}' > .env
+ echo '\n' >> .env
+ echo '${{ secrets.CB_EMAIL_SMTP }}\n' >> .env
+ echo '${{ secrets.CB_EMAIL_ADDR }}\n' >> .env
+ echo '${{ secrets.CB_EMAIL_PWD }}\n' >> .env
echo "============ Env creation finished! ========="
diff --git a/backend/app.py b/backend/app.py
index 655d8eb..89508a7 100644
--- a/backend/app.py
+++ b/backend/app.py
@@ -19,7 +19,6 @@ from flask import Flask, send_from_directory, send_file, Response, request, json
from flask_openapi3 import Info, Tag, OpenAPI, Server #FileStorage
from flask_socketio import SocketIO, join_room, leave_room, rooms, send
from werkzeug.utils import secure_filename
-
import asyncio
import logging
@@ -133,6 +132,9 @@ def uses_jwt(logger=None, required=True):
def create_app():
+ app_name = "Creative Bots"
+
+
# JWT Bearer Sample
jwt = {
"type": "http",
@@ -144,7 +146,7 @@ def create_app():
info = Info(
- title="CreativeBots-API",
+ title=app_name + " API",
version=__version__,
summary="The REST-API to manage bots, users and more!",
description=""
@@ -192,13 +194,10 @@ def create_app():
@socket.on('client message')
def handle_message(message):
-
SocketMessage.model_validate(message)
logger.info("Starting stream")
-
- #try:
room = message["room"]
question = message["question"]
system_prompt = message["system_prompt"]
@@ -305,12 +304,20 @@ def create_app():
case [user]:
if user["password_hash"] == hash_password(form.password + form.email):
- token = pyjwt.encode({"email": form.email}, jwt_secret, algorithm="HS256")
- #logger.info(token)
- return jsonify({
- 'status': 'success',
- 'jwt': token
- })
+ if not user["isEmailVerified"]:
+ msg = "E-Mail unverified!"
+ logger.error(msg)
+ return jsonify({
+ 'status': 'error',
+ 'message': msg
+ }), 400
+ else:
+ token = pyjwt.encode({"email": form.email}, jwt_secret, algorithm="HS256")
+ #logger.info(token)
+ return jsonify({
+ 'status': 'success',
+ 'jwt': token
+ })
else:
msg = "Invalid password!"
logger.error(msg)
@@ -341,12 +348,15 @@ def create_app():
if User.get(id=form.email, ignore=404) is not None:
+ msg = "User with that e-mail address already exists!"
+ logger.error(msg)
return jsonify({
'status': 'error',
- "message": "User with that e-mail address already exists!"
+ "message": msg
})
else:
+ logger.info("Try creating user...!")
user = User(meta={'id': form.email})
user.creation_date = datetime.now()
user.email = form.email
@@ -354,21 +364,23 @@ def create_app():
user.role = "User"
user.isEmailVerified = False
user.save()
+ logger.info("User created!")
- msg = """
+ msg = f"""
Verify E-Mail
- Hi!
-
Please click on the following link to verify your e-mail:
-
- Click here!
+ Click here!
"""
- send_mail(user.email, "User registration @ Creative Bots", "Creative Bots", msg)
-
+ send_mail(
+ target_mail=user.email,
+ subject="User registration @ " + app_name,
+ msg=msg
+ )
+ logger.info("Mail send!")
return jsonify({
'status': 'success'
})
@@ -599,9 +611,6 @@ def create_app():
"score_docs": xs
})
-
-
-
#-----------------Embedding----------------------
class TrainTextRequest(BaseModel):
@@ -659,15 +668,41 @@ def create_app():
d = {}
d["module_versions"] = get_module_versions()
- d["OLLAMA_NUM_PARALLEL"] = os.getenv("OLLAMA_NUM_PARALLEL")
- d["OLLAMA_MAX_LOADED_MODELS"] = os.getenv("OLLAMA_MAX_LOADED_MODELS")
+ #d["OLLAMA_NUM_PARALLEL"] = os.getenv("OLLAMA_NUM_PARALLEL")
+ #d["OLLAMA_MAX_LOADED_MODELS"] = os.getenv("OLLAMA_MAX_LOADED_MODELS")
d["cpus"] = multiprocessing.cpu_count()
#return "CPUs: " + str(cpus) + "
" + json.dumps(get_module_versions(), indent=4).replace("\n", "
")
-
return json.dumps(d, indent=4).replace("\n", "
")
+ @app.route("/verify", methods=['GET'])
+ def verify_email():
+ x = request.args.get('id')
+ s = User.search()
+ s = s.filter('term', isEmailVerified=False).query('match', password_hash=x)
+ results = s.execute()
+
+ # when you execute the search the results are wrapped in your document class (Post)
+ for user in results:
+ #print(post.meta.score, post.title)
+ if user.password_hash == x:
+ user.isEmailVerified = True
+ user.save()
+ return "E-Mail verified!"
+
+
+ return "Verrification Error!"
+ """
+ match get_by_id(index="user", id_field_name="password_hash", id_value=x):
+ case [d]:
+ #user.isEmailVerified = True
+ #user.save()
+ return "E-Mail verified!"
+
+ case _:
+ return "Verrification Error!"
+ """
@app.route('/') #generische Route (auch Unterordner)
diff --git a/backend/lib/elastictools.py b/backend/lib/elastictools.py
index d4c6399..33087be 100644
--- a/backend/lib/elastictools.py
+++ b/backend/lib/elastictools.py
@@ -9,8 +9,7 @@ from elasticsearch.exceptions import ConnectionError
def get_by_id(index: str, id_field_name: str, id_value: str):
- client = connections.get_connection()
- response = Search(using=client, index=index).filter("term", **{id_field_name: id_value})[0:10000].execute()
+ response = Search(using=connections.get_connection(), index=index).filter("term", **{id_field_name: id_value})[0:10000].execute()
return [hit.to_dict() for hit in response]
@@ -30,15 +29,13 @@ def update_by_id(index: str, id_field_name: str, id_value: str, values_to_set: D
def delete_by_id(index: str, id_field_name: str, id_value: str):
- client = connections.get_connection()
- s = Search(using=client, index=index).filter("term", **{id_field_name: id_value})
+ s = Search(using=connections.get_connection(), index=index).filter("term", **{id_field_name: id_value})
response = s.delete()
#if not response.success():
# raise Exception("Unable to delete id '%s' in index '%' !" % (index, id_value))
print(response, flush=True)
-
def get_datetime_interval(search: Search, start, end) -> Search:
return search.filter("range", timest={"gte": start}).filter("range", timest={"lte": end})
@@ -57,21 +54,18 @@ def simplify_properties(d):
def get_type_schema():
- client = connections.get_connection()
- d = client.indices.get(index="*").body
+ d = connections.get_connection().indices.get(index="*").body
new_d = {}
for index, d2 in d.items():
new_d[index] = simplify_properties(d2["mappings"])
return new_d
-
def wait_for_elasticsearch():
i = 1
while True:
try:
- client = connections.get_connection()
- client.indices.get_alias(index="*")
+ connections.get_connection().indices.get_alias(index="*")
print("Elasticsearch found! Run Flask-app!", flush=True)
return
except ConnectionError:
diff --git a/backend/lib/mail.py b/backend/lib/mail.py
index bab70d1..5865498 100644
--- a/backend/lib/mail.py
+++ b/backend/lib/mail.py
@@ -1,14 +1,33 @@
+import os
+from jinja2 import Environment, FileSystemLoader
from smtplib import *
-from email.mime.text import MIMEText
+from email.message import EmailMessage
-def send_mail(target_mail, subject, sender_mail, msg):
+env = Environment(loader=FileSystemLoader('templates'))
- msg = MIMEText(msg)
+# Credentials
+username = os.getenv("EMAIL_ADDR")
+password = os.getenv("EMAIL_PWD")
+smtp_domain_and_port = os.getenv("EMAIL_SMTP")
+
+assert username
+assert password
+
+def send_mail(target_mail, subject, msg, sender_mail=username):
+ html = env.get_template('html_mail.twig').render(
+ subject=subject,
+ msg=msg
+ )
+
+ msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = sender_mail
msg['To'] = target_mail
+ msg.set_content(html, subtype='html')
- smtp = SMTP('mailserver', port=10025)
- smtp.sendmail("Creative Bots", [target_mail], msg.as_string())
- smtp.quit()
+ domain, port = smtp_domain_and_port.split(":")
+ #with SMTP_SSL('smtp.gmx.de', port=465) as smtp:
+ with SMTP_SSL(domain, port=int(port)) as smtp:
+ smtp.login(username, password)
+ smtp.send_message(msg)
diff --git a/backend/lib/models.py b/backend/lib/models.py
index 921824d..3fef1ef 100644
--- a/backend/lib/models.py
+++ b/backend/lib/models.py
@@ -4,7 +4,10 @@ from elasticsearch_dsl import Document, InnerDoc, Nested, Date, Integer, Keyword
class User(Document):
creation_date = Date()
email = Keyword()
- password_hash = Text(index=False)
+ #password_hash = Text(index=False)
+ password_hash = Keyword()
+ #password_hash = Text(index=True)
+
role = Keyword()
#salt = Text(index=False)
diff --git a/backend/lib/user.py b/backend/lib/user.py
index 10b9414..f5b8bb8 100644
--- a/backend/lib/user.py
+++ b/backend/lib/user.py
@@ -2,6 +2,7 @@
All around managing users
"""
import os, json, hashlib, traceback, logging
+from datetime import datetime, date
from elasticsearch import NotFoundError, Elasticsearch # for normal read/write without vectors
from lib.models import User
@@ -15,7 +16,6 @@ assert elastic_url
def hash_password(s: str) -> str:
return hashlib.md5(s.encode('utf-8')).hexdigest()
-
def create_user(email, password, role="user", verified=False):
user = User(meta={'id': email}, email=email, password_hash=hash_password(password + email), role=role)
user.creation_date = datetime.now()
diff --git a/backend/public/index.html b/backend/public/index.html
index 32dbe0a..f00b931 100644
--- a/backend/public/index.html
+++ b/backend/public/index.html
@@ -260,7 +260,7 @@
- @
+
@@ -270,7 +270,7 @@
@@ -459,6 +459,8 @@
+
+
+