registration email added
Some checks failed
Gitea Docker Redeploy / Redploy-App-on-self-via-SSH (push) Failing after 17s
Some checks failed
Gitea Docker Redeploy / Redploy-App-on-self-via-SSH (push) Failing after 17s
This commit is contained in:
parent
e9c1d1815f
commit
83ea3a7a64
@ -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! ========="
|
||||
|
||||
|
||||
|
@ -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,6 +304,14 @@ def create_app():
|
||||
|
||||
case [user]:
|
||||
if user["password_hash"] == hash_password(form.password + form.email):
|
||||
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({
|
||||
@ -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"""
|
||||
<h1>Verify E-Mail</h1>
|
||||
|
||||
Hi!
|
||||
|
||||
Please click on the following link to verify your e-mail:
|
||||
|
||||
|
||||
<a href="http://127.0.0.1:5000/">Click here!</a>
|
||||
<a href="http://127.0.0.1:5000/verify?id={user.password_hash}">Click here!</a>
|
||||
|
||||
"""
|
||||
|
||||
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) + "<br>" + json.dumps(get_module_versions(), indent=4).replace("\n", "<br>")
|
||||
|
||||
return json.dumps(d, indent=4).replace("\n", "<br>")
|
||||
|
||||
|
||||
@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('/<path:path>') #generische Route (auch Unterordner)
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -260,7 +260,7 @@
|
||||
|
||||
<br>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">@
|
||||
<span class="input-group-text">
|
||||
<select name="bots" id="bot_select" class="form-select"></select>
|
||||
</span>
|
||||
<input class="form-control" list="questions" name="question" id="user_input" placeholder="What is...">
|
||||
@ -270,7 +270,7 @@
|
||||
<option value="Is a monad a burito?">
|
||||
<option value="Give the JSON of a graph linking Germanys 9 biggest cities">
|
||||
</datalist>
|
||||
<button id="submit_btn" class="btn btn-success" type="button">Send</button>
|
||||
<button id="submit_btn" class="btn btn-success" type="button">❯</button>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<!-- Button to open the offcanvas sidebar -->
|
||||
@ -459,6 +459,8 @@
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<footer>
|
||||
<div id="fun2" class="container-fluid p-3 bg-primary text-white mt-5">
|
||||
<div class="row">
|
||||
@ -482,6 +484,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
-->
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -684,6 +684,7 @@ window.onload = async ()=>{
|
||||
|
||||
}
|
||||
catch(e){
|
||||
console.error(e);
|
||||
console.error("Registration failed!");
|
||||
}
|
||||
};
|
||||
|
@ -3,6 +3,7 @@ webdriver_manager
|
||||
requests==2.32.3
|
||||
selenium==4.23.1
|
||||
bs4
|
||||
jinja2
|
||||
|
||||
elasticsearch==8.15.0
|
||||
elasticsearch-dsl==8.15.1
|
||||
|
41
backend/templates/html_mail.twig
Normal file
41
backend/templates/html_mail.twig
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ subject }}</title>
|
||||
<meta charset="utf-8">
|
||||
<!--
|
||||
<link rel="stylesheet" type="text/css" hs-webfonts="true" href="https://fonts.googleapis.com/css?family=Lato|Lato:i,b,bi">
|
||||
-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style type="text/css">
|
||||
h1{font-size:56px}
|
||||
h2{font-size:28px;font-weight:900}
|
||||
p{font-weight:100}
|
||||
td{vertical-align:top}
|
||||
#email{margin:auto;width:600px;background-color:#fff}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body bgcolor="#F5F8FA" style="width: 100%; font-family:Lato, sans-serif; font-size:18px;">
|
||||
<div id="email">
|
||||
<table role="presentation" width="100%">
|
||||
<tr>
|
||||
<td bgcolor="#00A4BD" align="center" style="color: white;">
|
||||
<h1>{{ subject }}</h1>
|
||||
</td>
|
||||
</table>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="10px" style="padding: 30px 30px 30px 60px;">
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
{{ msg }}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -19,6 +19,7 @@ services:
|
||||
minio:
|
||||
container_name: ${APP_PREFIX}_minio
|
||||
image: minio/minio
|
||||
restart: always
|
||||
ports:
|
||||
- "29000:9000"
|
||||
- "29001:9001"
|
||||
@ -37,7 +38,8 @@ services:
|
||||
image: neo4j
|
||||
#image: neo4j:3.5
|
||||
#image: neo4j:4.1
|
||||
restart: unless-stopped
|
||||
#restart: unless-stopped
|
||||
restart: always
|
||||
ports:
|
||||
- 7474:7474
|
||||
- 7687:7687
|
||||
@ -104,12 +106,6 @@ services:
|
||||
- /dev/dri
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ollama-webui:
|
||||
# container_name: ${APP_PREFIX}_ollama-webui
|
||||
# image: ghcr.io/ollama-webui/ollama-webui:main
|
||||
|
@ -9,3 +9,9 @@ SECRET=23A344F670E
|
||||
|
||||
#WARN INFO FATAL
|
||||
LOG_LEVEL=WARN
|
||||
|
||||
#Admin E-Mail sender account
|
||||
EMAIL_SMTP=smtp.mail.net:465
|
||||
EMAIL_ADDR=user@mail.net
|
||||
EMAIL_PWD=somepass
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user