first commit

This commit is contained in:
2026-06-13 21:46:37 +03:00
commit 650b69a97d
131 changed files with 5951 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

62
client/pages/auth/auth.py Normal file
View File

@@ -0,0 +1,62 @@
import flet as ft
from pages.auth.login import Login
class Auth:
def __init__(self, page: ft.Page):
self.page = page
self.placeholder = ft.Container(
width=350,
border_radius=20,
bgcolor=ft.Colors.BLUE_200 if self.page.theme_mode == ft.ThemeMode.LIGHT else ft.Colors.BLUE_900,
padding=20
)
self.login = Login(self.page, self)
self.placeholder.content = self.login.build()
self.choose_them_color_btn = ft.IconButton(
icon=ft.Icons.DARK_MODE,
on_click=self.change_theme_mode
)
def change_theme_mode(self, e):
self.page.theme_mode = ft.ThemeMode.DARK if self.page.theme_mode == ft.ThemeMode.LIGHT else ft.ThemeMode.LIGHT
self.choose_them_color_btn.icon = ft.Icons.DARK_MODE if self.page.theme_mode == ft.ThemeMode.LIGHT else ft.Icons.SUNNY
self.choose_them_color_btn.update()
self.placeholder.bgcolor = ft.Colors.BLUE_200 if self.page.theme_mode == ft.ThemeMode.LIGHT else ft.Colors.BLUE_800
self.placeholder.update()
self.page.update()
async def set_value(self, key, value):
await ft.SharedPreferences().set(key, str(value))
def build(self):
return ft.Container(
content=ft.Column(
[
# ft.Row(
# [
# self.choose_them_color_btn
# ],
# width=350,
# alignment=ft.MainAxisAlignment.END,
# spacing=20
# ),
ft.Row(
[
ft.Image(
src = "images/logo_juridic_block.png",
width=250
),
],
alignment=ft.MainAxisAlignment.CENTER,
width=350,
),
self.placeholder,
],
alignment=ft.MainAxisAlignment.CENTER,
spacing=20,
expand=True
),
padding=20,
expand=True
)

View File

@@ -0,0 +1,116 @@
import flet as ft
from helpers.emails import send_gmail
from helpers.validations import Validations
import requests
import string
import secrets
import os
class ForgotPassword:
def __init__(self, page: ft.Page, login, auth):
self.page = page
self.login = login
self.auth = auth
self.email = ft.TextField(label="E-mail", expand=True)
self.code = ft.TextField(label="Codul de securitate", expand=True)
self.password = ft.TextField(label="Parola", password=True, can_reveal_password=True, expand=True)
self.confirm_password = ft.TextField(label="Confirmați parola", password=True, can_reveal_password=True, expand=True)
self.error_message = ft.Text(color=ft.Colors.RED)
self.inserted_code = ft.TextField(label="Codul de verificare primit pe email", expand=True)
self.otp_code = self._generate_numeric_code()
self.validate = Validations(self.error_message, self.page)
self.title = ft.Text(
"Ai uitat parola?",
text_align=ft.TextAlign.CENTER,
size=20,
weight=ft.FontWeight.BOLD,
width=350
)
self.main_column = ft.Column(
[
self.title,
self.email,
self.error_message,
ft.Button("Recupereaza parola", on_click=self.send_code_on_email),
],
horizontal_alignment=ft.CrossAxisAlignment.CENTER
)
self.go_to_login = ft.TextButton("Mergeti la autentificare", on_click=self.on_go_to_login_btn_click, width=350)
self.page_column = ft.Column(
[
self.main_column,
ft.Text(),
self.go_to_login
]
)
def _generate_numeric_code(self) -> str:
digits = string.digits
return ''.join(secrets.choice(digits) for _ in range(6))
def send_code_on_email(self, e):
if self.validate.is_valid_email(self.email.value):
self.main_column.controls.clear()
self.main_column.controls.append(self.title)
self.main_column.controls.append(self.inserted_code)
self.main_column.controls.append(self.error_message)
self.main_column.controls.append("Verifica", width=150, on_click=self.verfy_code)
self.main_column.update()
#print(self.otp_code)
send_gmail(
to_email=self.email.value,
subject="Cod de verificare",
body=f"Codul tau de verificare este: {self.otp_code}"
)
def verfy_code(self, e):
inserted_code = self.inserted_code.value
if inserted_code == self.otp_code:
self.main_column.controls.clear()
self.main_column.controls.append(self.title)
self.main_column.controls.append(self.password)
self.main_column.controls.append(self.confirm_password)
self.main_column.controls.append(self.error_message)
self.main_column.controls.append(
ft.Button("Salveaza", width=150, on_click=self.on_save_btn_click)
)
self.error_message.value = ''
else:
self.error_message.value = "Code invalid sau expirat!"
print(inserted_code)
print(self.otp_code)
def on_go_to_login_btn_click(self, e):
self.auth.placeholder.content = self.login.build()
def on_save_btn_click(self, e):
password = self.password.value
repeat_password = self.confirm_password.value
if self.validate.is_password_strong(password):
if self.validate.check_repeat_password(password, repeat_password):
base_url = self.page.session.store.get('api_base_url')
token = os.getenv('PASSWORD_TOKEN')
response = requests.post(f'{base_url}/auth/update_passwrod', json={"email": self.email.value, "password": password, "token": token})
if response.status_code == 200:
self.error_message.value = 'Parola a fost salvata cu succes. Acum va puteti autentifica!'
self.error_message.color = ft.Colors.GREEN
self.error_message.update()
self.page_column.controls.clear()
self.page_column.controls.append(self.title)
self.page_column.controls.append(self.error_message)
self.page_column.controls.append(self.go_to_login)
self.go_to_login.content = "Mergeti la autentificare"
else:
self.error_message.value = 'Recuperarea parolei a esuat. Va rugam conactati administratorul.'
self.error_message.color = ft.Colors.RED
self.error_message.update()
def build(self):
return self.page_column

View File

@@ -0,0 +1,85 @@
import flet as ft
from pages.auth.register import Register
from pages.auth.forgot_password import ForgotPassword
import requests
from pages.auth.verify_code import VerifyCode
class Login:
def __init__(self, page: ft.Page, auth):
self.auth = auth
self.page = page
self.email = ft.TextField(label="E-mail", expand=True)
self.password = ft.TextField(label='Parola', password=True, can_reveal_password=True, expand=True)
self.error_message = ft.Text(color=ft.Colors.RED)
self.verify_code = VerifyCode(self.page, self.auth)
self.keep_me_auth = ft.Checkbox(label='Pastreaza-ma autentificat', on_change=self.on_keep_me_authenticated)
def on_register_btn_click(self, e):
self.register = Register(self.page, self, self.auth)
self.auth.placeholder.content = self.register.build()
def on_forgot_password_btn_click(self, e):
self.forgot_password = ForgotPassword(self.page, self, self.auth)
self.auth.placeholder.content = self.forgot_password.build()
async def on_login_btn_click(self, e):
email = self.email.value
self.page.session.store.set('email',email)
if not email:
self.error_message.value = 'Toate campurile sunt obligatorii!'
print('email not found')
return
password = self.password.value
if not password:
self.error_message.value = 'Toate campurile sunt obligatorii!'
print('password not found')
return
base_url = self.page.session.store.get('api_base_url')
response = requests.post(f'{base_url}/auth/login', json={"email": email, "password": password})
if response.status_code == 200:
self.auth.placeholder.content = self.verify_code.build()
else:
self.error_message.value = 'Credentiale incorecte!'
print('no user found')
async def set_value(self, key, value):
await ft.SharedPreferences().set(key, str(value))
def on_keep_me_authenticated(self, e):
self.page.session.store.set('keep_me_authenticated', e.data)
def build(self):
return ft.Column(
[
ft.Text(
'Bine ati venit!',
text_align=ft.TextAlign.CENTER,
size=20,
weight=ft.FontWeight.BOLD,
width=350
),
self.email,
self.password,
self.error_message,
ft.Button(
'Autentificare',
on_click=self.on_login_btn_click
),
ft.Row([self.keep_me_auth], alignment=ft.MainAxisAlignment.CENTER),
ft.Row(
[
ft.TextButton(
'Creaza cont',
on_click=self.on_register_btn_click
),
ft.TextButton(
'Ai uitat parola?',
on_click=self.on_forgot_password_btn_click
)
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
)
],
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
)

View File

@@ -0,0 +1,81 @@
import flet as ft
from helpers.validations import Validations
import requests
import time
class Register:
def __init__(self, page, login, auth):
self.page = page
self.login = login
self.auth = auth
self.email = ft.TextField(label="E-mail", expand=True)
self.password = ft.TextField(label="Parola", password=True, can_reveal_password=True, expand=True)
self.confirm_password = ft.TextField(label="Confirmați parola", password=True, can_reveal_password=True, expand=True)
self.error_message = ft.Text(color=ft.Colors.RED)
self.validation = Validations(self.error_message, self.page)
def on_register_btn_click(self, e):
email = self.email.value
password = self.password.value
repeat_password = self.confirm_password.value
if self.validation.are_all_fields_inserted(email, password, repeat_password):
print("All fileds are inserted")
if self.validation.is_valid_email(email):
print("Email valid", email)
if self.validation.is_password_strong(password):
print("Password is strong")
if self.validation.check_repeat_password(password, repeat_password):
print('Password Valid!')
self.error_message.value = "Validam datele, va rugam asteptati!"
self.error_message.color = ft.Colors.WHITE
self.error_message.update()
API_BASE_URL = self.page.session.store.get('api_base_url')
response = requests.post(f"{API_BASE_URL}/auth/register", json={
"workspace_id": 0,
"email": self.email.value,
"password": self.password.value
})
if response.status_code == 201:
self.error_message.value = "Inregistrare finalizata, acum va puteti autentifica!"
self.error_message.color = ft.Colors.WHITE
self.error_message.update()
#time.sleep(3)
#self.auth.placeholder.content = self.login.build()
else:
self.error_message.value = "Exista deja un cont pentru aceasta adresa de e-mail"
self.error_message.update()
def on_go_to_login_btn_click(self, e):
self.auth.placeholder.content = self.login.build()
def build(self):
return ft.Column(
[
ft.Text(
"Creaza cont",
text_align=ft.TextAlign.CENTER,
size=20,
weight=ft.FontWeight.BOLD,
width=350
),
self.email,
self.password,
self.confirm_password,
self.error_message,
ft.Button(
"Inregistreaza-te",
on_click=self.on_register_btn_click
),
ft.Text(),
ft.TextButton(
"Accesati Autentificare",
on_click=self.on_go_to_login_btn_click,
width=350
)
],
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
)

View File

@@ -0,0 +1,60 @@
import flet as ft
import requests
import json
class VerifyCode:
def __init__(self, page: ft.Page, auth):
self.page = page
self.auth = auth
self.code = ft.TextField(label="Codul de verificare primit pe email")
self.verify_btn = ft.Button(
"Verifica",
on_click=self.on_verify_btn_click
)
self.error_message = ft.Text(color=ft.Colors.RED)
async def on_verify_btn_click(self, e):
code = self.code.value
if len(self.code.value) > 0:
API_BASE_URL = self.page.session.store.get('api_base_url')
self.email = self.page.session.store.get('email')
response = requests.post(f"{API_BASE_URL}/auth/verify_code", json={"email": self.email, "code": code})
if response.status_code == 200:
self.error_message.value = "Codul a fost verificat cu succes. Va puteti autentifica."
token = response.json().get("access_token")
self.page.session.store.set('token', token)
response = requests.get(
f"{API_BASE_URL}/auth/me",
headers={"Authorization": f"Bearer {token}"},
timeout=10,
)
user = json.loads(response.text)
print(user)
self.page.session.store.set('user', user)
# Verificăm dacă utilizatorul a bifat "Keep me authenticated"
keep_me = self.page.session.store.get('keep_me_authenticated')
if keep_me == True or keep_me == "true":
await self.set_value("mi_user_id", user['id'])
await self.set_value("mi_tocken", token)
self.page.go('/home')
else:
self.error_message.value = "Code invalid sau expirat!"
else:
self.error_message.value = "Code invalid sau expirat!"
async def set_value(self, key, value):
await ft.SharedPreferences().set(key, str(value))
def build(self):
return ft.Container(
content=ft.Column(
[
self.code,
self.error_message,
self.verify_btn
],
horizontal_alignment=ft.CrossAxisAlignment.CENTER
)
)