31 KiB
🔐 Teljes Regisztrációs Folyamat Audit — 2026-06-07
📋 Összefoglaló
A Service Finder regisztrációs rendszere 4 fázisból áll, amelyek a Lite regisztrációtól a teljes KYC-n át a felhasználói fiók aktiválásáig vezetnek. A folyamat több rétegű (frontend → backend → adatbázis → e-mail), és Shadow Identity kezeléssel, Device Fingerprinting-gel, valamint dinamikus konfigurációval bővül.
🧭 1. Regisztrációs Folyamat Áttekintése (4 Fázis)
flowchart LR
A[Lite Regisztráció<br/>1. Fázis] -->|Email + Jelszó| B[Email Verifikáció<br/>Magic Link<br/>2. Fázis]
B -->|Auto-login JWT| C[KYC 1. lépés<br/>Cím - Soft KYC<br/>3. Fázis]
C --> D[KYC 2. lépés<br/>Személyes adatok<br/>4. Fázis]
D --> E[Fiók Aktiválva<br/>Szervezet + Pénztárca]
📦 2. Fázis 1: Lite Regisztráció
2.1 Frontend: LoginModal.vue
- Belépési pont: A
LoginModal.vue3D kártya-forgató (CSS rotateY/rotateX) aregisteroldallapon. - Gyűjtött mezők:
lastName,firstName,regEmail,regPassword(min. 8 karakter) - FingerprintJS: A böngésző eszköz-ujjlenyomatát a
FingerprintJSkomponens generálja (deviceFingerprint). - Regisztráció utáni állapot: Az email mentésre kerül
localStorage-ba (pending_verification_emailkulccsal), és a felhasználó átirányításra kerül a/verifyoldalra. - 60 másodperces cooldown: Az újraküldés gomb 60 másodpercig inaktív (időzítés a localStorage-ban).
2.2 API Végpont: POST /auth/register
Fájl: backend/app/api/v1/endpoints/auth.py:21
@router.post("/register", status_code=status.HTTP_201_CREATED)
async def register(user_in: UserLiteRegister, db: AsyncSession = Depends(get_db)):
Bemenő adatok (Pydantic UserLiteRegister):
| Mező | Típus | Kötelező | Megjegyzés |
|---|---|---|---|
email |
EmailStr |
Igen | Unique constraint |
password |
str |
Igen | Min 8 karakter (dinamikus) |
first_name |
str |
Igen | |
last_name |
str |
Igen | |
region_code |
str |
Nem | Példa: "HU", "AT" |
lang |
str |
Nem | Nyelvi preferencia |
timezone |
str |
Nem | |
referred_by_code |
str |
Nem | P2P referral kód |
Válasz: {"status": "success", "user_id": int, "email": str}
2.3 Backend Szolgáltatás: AuthService.register_lite()
Fájl: backend/app/services/auth_service.py:62
Folyamat:
-
Dinamikus konfiguráció lekérése a
system.system_parameterstáblából:auth_min_password_length→ alapértelmezett8auth_default_role→ alapértelmezett"user"auth_registration_hours→ alapértelmezett48
-
Jelszó komplexitás ellenőrzése (
_validate_password_complexity):- Minimális hossz (dinamikus)
- Nagybetű, kisbetű, szám követelmény?
- Regionális beállítások (pl. speciális karakterek)
-
Email egyediség ellenőrzése —
UniqueViolationkezelés Sentinel audit loggal -
Person rekord létrehozása (
identity.persons):person = Person( first_name=user_in.first_name, last_name=user_in.last_name, is_ghost=False, # Valódi személy ) -
User rekord létrehozása (
identity.users):user = User( email=user_in.email, hashed_password=pwd_context.hash(password), role=default_role, person=person, # Kapcsolat is_active=False, # Inaktív amíg nem verifikálta az emailt preferred_language=user_in.lang, region_code=user_in.region_code, referral_code=generate_secure_slug(), ) -
VerificationToken létrehozása (
identity.verification_tokens):token = VerificationToken( user_id=user.id, token_type="registration", # vagy "email_verification" expires_at=utcnow() + timedelta(hours=reg_token_hours), # 48h ) -
Token slug generálása (
security.generate_secure_slug()) -
Email küldés (
EmailManager.send_email()):template_key:"registration_verification"- Címzett:
user.email - Változók:
verification_url,user_name,expiry_hours
-
Sentinel Audit log:
EVENT.REGISTRATION_INITIATED
2.4 Adatbázis Írások (Fázis 1)
| Tábla | Séma | Művelet | Státusz |
|---|---|---|---|
persons |
identity |
INSERT |
is_active=False, is_ghost=False |
users |
identity |
INSERT |
is_active=False, role='user' |
verification_tokens |
identity |
INSERT |
token_type='registration', expires_at=now+48h |
📧 3. Fázis 2: Email Verifikáció (Magic Link)
3.1 Frontend: VerifyEmailView.vue
Három állapot:
| Állapot | Leírás |
|---|---|
isVerifying |
Spinner + "Email verifikálása..." szöveg, amíg a backend válaszol |
verifySuccess |
Zöld pipa animáció + 3 másodperces visszaszámlálás, majd átirányítás /complete-kyc |
default |
Email cím megadása + újraküldés gomb (cooldown-nal) |
Magic Link működése:
- A link token-t tartalmaz URL paraméterként (
?token=...) - A
VerifyEmailViewa token-t kiolvassa a query paraméterből - Meghívja az
authStore.verifyAccount(token)metódust - Automatikusan generál egy új
deviceFingerprint-et a FingerprintJS-el
3.2 Auth Store Metódus: verifyAccount()
async function verifyAccount(verificationToken: string, deviceFingerprint?: string) {
const response = await api.post('/auth/verify-email', {
token: verificationToken,
device_fingerprint: deviceFingerprint
});
// Ha a válasz JWT token-t tartalmaz -> auto-login
if (response.data.access_token) {
// Token-ek elmentése localStorage-be
token.value = response.data.access_token;
refreshToken.value = response.data.refresh_token;
// Felhasználói profil betöltése
await fetchUser();
}
}
3.3 API Végpont: POST /auth/verify-email
Fájl: backend/app/api/v1/endpoints/auth.py:142
Válasz: Token séma (access_token, refresh_token, token_type, is_active)
3.4 Backend Szolgáltatás: AuthService.verify_email()
Fájl: backend/app/services/auth_service.py:319
-
Token validálás:
- UUID formátum ellenőrzése
- Létezik-e a token a
verification_tokenstáblában is_used=False— még nem használták felexpires_at > now()— nem járt le
-
User aktiválás:
user.is_active = True person.is_active = True token.is_used = True -
Device Fingerprint rögzítés:
# Ha device_fingerprint érkezett: device = await get_or_create_device(db, device_fingerprint) await create_user_device_link(db, user.id, device.id) -
JWT Token generálás (auto-login):
access_token, refresh_token = create_tokens( data={"sub": str(user.id), "role": user.role.value}, remember_me=False # Magic Link esetén nincs remember_me ) -
Sentinel Audit log:
EVENT.EMAIL_VERIFIED
3.5 Adatbázis Írások (Fázis 2)
| Tábla | Séma | Művelet | Változás |
|---|---|---|---|
users |
identity |
UPDATE |
is_active=False → True |
persons |
identity |
UPDATE |
is_active=False → True |
verification_tokens |
identity |
UPDATE |
is_used=False → True |
devices |
identity |
INSERT/SELECT |
Ha új eszköz → létrehozás |
user_device_links |
identity |
INSERT |
User-Device kapcsolat |
🏠 4. Fázis 3: KYC 1. Lépés — Cím (Soft KYC)
4.1 Frontend: CompleteKycView.vue — 1. Lépés
Gyűjtött mezők:
| Mező | Típus | Kötelező |
|---|---|---|
country |
Select | Igen (HU/AT/SK/DE/RO/CZ) |
zip_code |
Input | Igen |
city |
Input | Igen (auto-fill zip lookup-ból) |
street_name |
Input | Nem |
street_type |
Select | Nem (utca, tér, stb.) |
street_number |
Input | Nem |
building |
Input | Nem |
staircase |
Input | Nem |
floor |
Input | Nem |
door |
Input | Nem |
Speciális funkciók:
- Irányítószám keresés:
/api/v1/system/zip-lookup— automatikus város kitöltés - Skip gomb: Csak irányítószám + város megadása kötelező, a többi opcionális
- Cím adatbázis: A
GeoServiceadata.zip_codes,data.streets,data.street_types,data.addressestáblákat használja
4.2 API Végpont: POST /auth/complete-kyc
Fájl: backend/app/api/v1/endpoints/auth.py:289
@router.post("/complete-kyc")
async def complete_kyc(
kyc_in: UserKYCComplete,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
4.3 Backend Szolgáltatás: AuthService.complete_kyc()
Fájl: backend/app/services/auth_service.py:177
Bemenő adatok (Pydantic UserKYCComplete):
| Mező | Típus | Kötelező |
|---|---|---|
phone |
str |
Igen |
birth_place |
str |
Igen |
birth_date |
date |
Igen |
mothers_name |
str |
Igen |
address |
nested | Igen (zip_code + city minimum) |
identity_docs |
list[dict] |
Nem (ID card + driver's license) |
ice_contact |
ICEContact |
Nem |
preferred_language |
str |
Nem |
preferred_currency |
str |
Nem |
device_fingerprint |
str |
Nem |
Alapértelmezett mezők a UserKYCComplete-ben:
phone: Optional[str] = None
birth_place: Optional[str] = None
birth_date: Optional[date] = None
mothers_name: Optional[str] = None
identity_docs: Optional[List[dict]] = None
ice_contact: Optional[ICEContact] = None
preferred_language: Optional[str] = None
preferred_currency: Optional[str] = None
🏢 5. Fázis 4: KYC 2. Lépés — Teljes Aktiválás
5.1 Frontend: CompleteKycView.vue — 2. Lépés
Gyűjtött mezők:
phone— Telefonszámidentity_docs— Dokumentumok:id_card_number+id_card_expirydriver_license_number+driver_license_expiry
preferred_language/preferred_currency— Nyelv és pénznem preferencia
5.2 Auth Store Metódus: completeKyc()
async function completeKyc(kycData: Record<string, any>): Promise<boolean> {
try {
await api.post('/auth/complete-kyc', kycData);
await fetchUser(); // Profil frissítése
return true;
} catch (err) {
// Hibakezelés
return false;
}
}
5.3 Backend Szolgáltatás: AuthService.complete_kyc() — Teljes logika
flowchart TD
A[KYC adatok érkeznek] --> B[Shadow Identity keresés]
B --> C{Van duplicate Person?}
C -->|Igen| D[Merge Person rekordok]
C -->|Nem| E[Folytatás jelenlegi Person-nal]
D --> E
E --> F[Cím létrehozása GeoService]
F --> G[Personal Organization létrehozása]
G --> H[Wallet létrehozása]
H --> I[Branch létrehozása]
I --> J[OrganizationMember létrehozása]
J --> K[Gamification XP award]
K --> L[P2P referral XP (ha van)]
L --> M[Sikeres válasz]
Részletes lépések:
-
Shadow Identity keresés és merge:
# Ellenőrzi, hogy a person rekordhoz tartozik-e másik User # Ha igen, összefésüli az adatokat (identity_hash alapján) existing_person = await check_shadow_person(db, kyc_in) if existing_person and existing_person.id != current_user.person_id: # Merge logika: a régebbi person adatai átkerülnek az újra await merge_persons(db, source_id=existing_person.id, target_id=current_user.person_id) -
Cím létrehozása (GeoService.get_or_create_full_address()):
address = await GeoService.get_or_create_full_address( db, kyc_in.address.dict(), user_id=current_user.id ) current_user.person.address_id = address.id -
Personal Organization létrehozása:
org = Organization( name=f"{person.first_name} {person.last_name} Személyes", org_type="personal", owner_id=current_user.id, is_verified=True, ) -
Wallet létrehozása (
finance.wallets):wallet = Wallet( user_id=current_user.id, earned_credits=0, purchased_credits=0, service_coins=0, currency=kyc_in.preferred_currency or "HUF", ) -
Branch létrehozása (
data.branches):branch = Branch( organization_id=org.id, address_id=address.id, name="Központi telephely", branch_type="headquarters", ) -
OrganizationMember létrehozása (
data.organization_members):member = OrganizationMember( organization_id=org.id, user_id=current_user.id, role="owner", ) -
Gamification XP award:
ProfileCompletedesemény → +50 XPEmailVerified+ProfileCompletedkombó → +100 XP (first_login bonus)
-
P2P referral XP:
- Ha
referred_by_idbe van állítva a User-en: - A referrer +100 XP-t kap (
ReferralUsedesemény)
- Ha
-
Sentinel Audit log:
EVENT.KYC_COMPLETED
5.4 Adatbázis Írások (Fázis 4)
| Tábla | Séma | Művelet |
|---|---|---|
persons |
identity |
UPDATE (phone, birth_data, address_id, identity_docs, ice_contact) |
addresses |
data |
INSERT |
zip_codes |
data |
INSERT/SELECT (auto-learning) |
streets |
data |
INSERT/SELECT (auto-learning) |
organizations |
data |
INSERT (personal org) |
wallets |
finance |
INSERT |
branches |
data |
INSERT (headquarters) |
organization_members |
data |
INSERT (owner role) |
gamification_events |
gamification |
INSERT (XP award) |
🔑 6. Token Élettartamok és Kezelés
6.1 JWT Token-ek
Forrás: backend/app/core/security.py:17
def create_tokens(data: Dict[str, Any], remember_me: bool = False) -> Tuple[str, str]:
# Access Token
access_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) # 30 perc
access_token = create_access_token(data=data, expires_delta=access_expires)
# Refresh Token
refresh_days = settings.REFRESH_TOKEN_EXPIRE_DAYS # 7 nap (alap)
if remember_me:
refresh_days = 30 # 30 nap ha "Emlékezz rám"
refresh_expires = timedelta(days=refresh_days)
refresh_token = create_refresh_token(data=data, expires_delta=refresh_expires)
return access_token, refresh_token
| Token | Élettartam | Beállítási Forrás |
|---|---|---|
| Access Token | 30 perc | settings.ACCESS_TOKEN_EXPIRE_MINUTES (static) |
| Refresh Token (alap) | 1 nap | settings.REFRESH_TOKEN_EXPIRE_DAYS=7 → runtime override: 1 nap |
| Refresh Token (remember_me) | 30 nap | Runtime override remember_me=True |
| Verification Token (regisztráció) | 48 óra | system_parameters.auth_registration_hours (dinamikus) |
| Verification Token (jelszó reset) | 2 óra | system_parameters.auth_password_reset_hours (dinamikus) |
6.2 Token Használati Minta
Regisztráció → Nincs token (csak user_id + email vissza)
Email verifikáció → Access (30p) + Refresh (1d/30d) → Auto-login
Bejelentkezés → Access (30p) + Refresh (1d/30d)
Jelszó reset → Nincs token (csak sikeres üzenet)
6.3 Dekódolás és Validáció
Forrás: backend/app/core/security.py:43
def decode_token(token: str) -> Optional[Dict[str, Any]]:
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[ALGORITHM])
return payload
except JWTError:
return None
6.4 Dependency Injection: get_current_user()
Fájl: backend/app/api/deps.py:55
async def get_current_user(
token: str = Depends(oauth2_scheme), # Authorization: Bearer <token>
db: AsyncSession = Depends(get_db),
) -> User:
payload = decode_token(token)
if payload is None:
raise HTTPException(status_code=401, detail="INVALID_TOKEN")
user = await db.get(User, int(payload.get("sub")))
if user is None:
raise HTTPException(status_code=401, detail="USER_NOT_FOUND")
return user
🖥️ 7. Frontend Felületek Részletes Leírása
7.1 LoginModal.vue — 3D Kártya-forgató
Technológia: CSS 3D transzformációk (rotateY, rotateX)
Négy oldal:
| Oldal | CSS Osztály | Trigger |
|---|---|---|
| Login | .card-face-front |
Alapértelmezett |
| Register | .card-face-back |
"Regisztráció" gomb |
| Forgot Password | .card-face-left |
"Elfelejtett jelszó" link |
| Resend Verification | .card-face-top |
"Újraküldés" link |
Login folyamat:
email+password→authStore.login()- Ha
isKycComplete= false →/complete-kycredirect - Ha
isKycComplete= true →/dashboardredirect
Remember Me: localStorage-ban tárolva (login_remember)
7.2 VerifyEmailView.vue — Verifikációs Oldal
URL: /verify?token=...
3 állapot:
-
Verifying (
isVerifying = true):- Spinner komponens
- "Email cím ellenőrzése..." szöveg
- Token kiolvasása a URL-ből
-
Success (
verifySuccess = true):- Zöld pipa animáció (CSS)
- "Email cím sikeresen megerősítve!"
- 3 másodperces countdown →
/complete-kyc
-
Default (nincs token a URL-ben):
- Email input mező
- "Újraküldés" gomb
- 60 másodperes cooldown
7.3 CompleteKycView.vue — 2-lépéses KYC
Védett route: Csak hitelesített felhasználók számára (requiresAuth guard).
Step 1 — Cím adatok:
- Ország választó (HU/AT/SK/DE/RO/CZ flag-ekkel)
- Irányítószám + automatikus város kitöltés
- Utca, házszám, épület, lépcsőház, emelet, ajtó (opcionális)
- "Kihagyás" gomb (ha csak zip+city van megadva)
Step 2 — Személyes adatok:
- Telefonszám
- Születési hely, dátum
- Anyja neve
- Dokumentumok (személyi + jogosítvány)
- ICE kapcsolattartó
- Nyelv és pénznem preferencia
7.4 Router Guardok
Fájl: frontend/src/router/index.ts:49
router.beforeEach(async (to, _from, next) => {
const authStore = useAuthStore();
await authStore.init(); // Token-ek betöltése localStorage-ból
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
next('/'); // Vissza a Landing-re
} else if (to.path === '/' && authStore.isAuthenticated) {
next('/dashboard'); // Már bejelentkezett → dashboard
} else {
next();
}
});
🗄️ 8. Adatbázis Séma Részletek
8.1 Person — identity.persons
| Mező | Típus | Default | Megjegyzés |
|---|---|---|---|
id |
BigInt PK |
auto | |
uuid |
UUID |
uuid4() |
Publikus azonosító |
address_id |
Int FK |
NULL |
→ data.addresses.id |
first_name |
String(100) |
||
last_name |
String(100) |
||
middle_name |
String(100) |
NULL |
|
phone |
String(20) |
NULL |
|
birth_place |
String(200) |
NULL |
|
birth_date |
Date |
NULL |
|
mothers_name |
String(200) |
NULL |
|
identity_hash |
String(64) |
NULL |
SHA-256 hash a deduplikációhoz |
identity_docs |
JSON |
NULL |
Dokumentumok listája |
ice_contact |
JSON |
NULL |
ICE kapcsolattartó |
avatar_url |
String(500) |
NULL |
|
lifetime_xp |
Integer |
0 |
Gamification |
penalty_points |
Integer |
0 |
|
social_reputation |
Float |
0.0 |
|
is_sales_agent |
Boolean |
False |
|
is_active |
Boolean |
False |
Aktiválás után True |
is_ghost |
Boolean |
False |
Ideiglenes rekord |
merged_into_id |
Int FK |
NULL |
Shadow Identity merge cél |
created_at |
DateTime |
utcnow() |
|
updated_at |
DateTime |
utcnow() |
Relációk:
users: List[User]— Egy személyhez több User tartozhatactive_user_account: User— Az aktív Useraddress: Address— Lakcímowned_business_entities: List[Organization]— Tulajdonolt szervezetek
8.2 User — identity.users
| Mező | Típus | Default | Megjegyzés |
|---|---|---|---|
id |
Int PK |
auto | |
email |
String(255) |
UNIQUE, login azonosító | |
hashed_password |
String(255) |
bcrypt hash | |
role |
Enum(UserRole) |
user |
user, admin, superadmin, manager, agent, api |
person_id |
BigInt FK |
NULL |
→ identity.persons.id |
subscription_plan |
String(50) |
NULL |
|
is_vip |
Boolean |
False |
|
referral_code |
String(20) |
NULL |
UNIQUE, P2P meghívó |
referred_by_id |
Int FK |
NULL |
→ identity.users.id |
is_active |
Boolean |
False |
Verifikáció után True |
is_deleted |
Boolean |
False |
Soft delete (GDPR) |
folder_slug |
String(64) |
NULL |
|
preferred_language |
String(10) |
NULL |
|
region_code |
String(10) |
NULL |
|
preferred_currency |
String(3) |
NULL |
|
ui_mode |
String(20) |
NULL |
|
scope_level |
Enum |
NULL |
RBAC scope |
scope_id |
Int |
NULL |
|
custom_permissions |
JSON |
NULL |
|
alternative_emails |
JSON |
NULL |
|
email_history |
JSON |
NULL |
|
created_at |
DateTime |
utcnow() |
|
updated_at |
DateTime |
utcnow() |
Relációk:
person: Person— A személy, akihez a fiók tartozikreferrer: User— Aki meghívtasales_agent: User— Értékesítési ügynök
8.3 VerificationToken — identity.verification_tokens
| Mező | Típus | Default | Megjegyzés |
|---|---|---|---|
token |
UUID PK |
uuid4() |
|
user_id |
Int FK |
→ identity.users.id |
|
token_type |
String(50) |
registration, password_reset, email_change |
|
extra_data |
JSON |
NULL |
|
expires_at |
DateTime |
||
is_used |
Boolean |
False |
|
created_at |
DateTime |
utcnow() |
8.4 Wallet — finance.wallets
| Mező | Típus | Default | Megjegyzés |
|---|---|---|---|
id |
Int PK |
auto | |
user_id |
Int FK |
→ identity.users.id |
|
earned_credits |
Integer |
0 |
|
purchased_credits |
Integer |
0 |
|
service_coins |
Integer |
0 |
|
currency |
String(3) |
HUF |
8.5 Device — identity.devices
| Mező | Típus | Megjegyzés |
|---|---|---|
id |
Int PK |
|
fingerprint_hash |
String(255) |
FingerprintJS hash |
user_agent |
Text |
|
ip_address |
String(45) |
|
created_at |
DateTime |
8.6 UserDeviceLink — identity.user_device_links
| Mező | Típus | Megjegyzés |
|---|---|---|
id |
UUID PK |
|
user_id |
Int FK |
→ identity.users.id |
device_hash |
String(255) |
|
first_seen_at |
DateTime |
|
last_seen_at |
DateTime |
🎭 9. Shadow Identity (Személy Összefésülés)
Mechanizmus: Amikor a KYC befejeződik, a rendszer ellenőrzi, hogy a megadott adatok (pl. identity_hash alapján) egyeznek-e egy másik Person rekorddal. Ha igen, a két rekord összefésülésre kerül:
async def merge_persons(db: AsyncSession, source_id: int, target_id: int):
source = await db.get(Person, source_id)
target = await db.get(Person, target_id)
# Source User-ek átirányítása a Target Person-hoz
for user in source.users:
user.person_id = target.id
# Source megjelölése merge-eltként
source.merged_into_id = target.id
source.is_active = False
await db.commit()
Trigger: complete_kyc() függvényben, az adatok validálása után.
⚙️ 10. Dinamikus Konfiguráció
Forrás: system.system_parameters tábla → Settings.get_db_setting()
Fájl: backend/app/core/config.py:140
| Paraméter | Alapértelmezett | Hatás |
|---|---|---|
auth_min_password_length |
8 |
Jelszó minimális hossza |
auth_max_password_length |
128 |
Jelszó maximális hossza |
auth_default_role |
user |
Alapértelmezett szerepkör |
auth_registration_hours |
48 |
Verifikációs token élettartam (óra) |
auth_password_reset_hours |
2 |
Jelszó reset token élettartam (óra) |
auth_max_login_attempts |
5 |
Maximális bejelentkezési kísérlet |
📧 11. Email Rendszer
Forrás: backend/app/services/email_manager.py:18
| Szolgáltató | Prioritás | Módszer |
|---|---|---|
| Brevo API | 1. | REST API kulcsos hitelesítés |
| Brevo SMTP | 2. | smtp-relay.brevo.com:587 |
| Fallback SMTP | 3. | Általános SMTP (SSL/TLS) |
Email sablonok:
| Sablon kulcs | Használat |
|---|---|
registration_verification |
Regisztráció utáni verifikációs email |
password_reset |
Jelszó visszaállítás |
welcome |
Sikeres verifikáció utáni üdvözlő email |
Sablonok: A locale_manager segítségével i18n támogatással, nyelv-specifikus HTML template-ek.
🛡️ 12. Sentinel Audit Log Események
| Esemény | Fázis | Naplózott adatok |
|---|---|---|
EVENT.REGISTRATION_INITIATED |
1 | email, ip, user_agent |
EVENT.EMAIL_VERIFIED |
2 | user_id, token_id |
EVENT.KYC_COMPLETED |
4 | user_id, person_id |
EVENT.LOGIN_SUCCESS |
- | user_id, device_fingerprint |
EVENT.LOGIN_FAILED |
- | email, attempt_count |
EVENT.PASSWORD_RESET_REQUESTED |
- | |
EVENT.PASSWORD_RESET_COMPLETED |
- | user_id |
🔄 13. Teljes Adatfolyam Diagram
sequenceDiagram
participant U as User (Böngésző)
participant FE as Vue Frontend
participant API as FastAPI Backend
participant DB as PostgreSQL
participant Email as Email Service
Note over U,Email: FÁZIS 1: Lite Regisztráció
U->>FE: Adatok megadása (email, név, jelszó)
FE->>FE: FingerprintJS generálás
FE->>API: POST /auth/register
API->>DB: SELECT system_parameters (dinamikus config)
API->>DB: INSERT person (is_active=False)
API->>DB: INSERT user (is_active=False)
API->>DB: INSERT verification_token (48h)
API->>Email: Küldés (verifikációs link)
API-->>FE: {status: "success", user_id, email}
FE->>U: Átirányítás /verify oldalra
Note over U,Email: FÁZIS 2: Email Verifikáció
U->>FE: Email megnyitása → Magic Link kattintás
FE->>FE: Token kiolvasás URL-ből
FE->>API: POST /auth/verify-email (token, device_fingerprint)
API->>DB: SELECT verification_token (is_used=False, expires>now)
API->>DB: UPDATE user SET is_active=True
API->>DB: UPDATE person SET is_active=True
API->>DB: UPDATE token SET is_used=True
API->>DB: INSERT device + user_device_link
API-->>FE: {access_token, refresh_token} → AUTO-LOGIN
FE->>FE: Token-ek mentése localStorage-be
FE->>FE: 3 másodperc countdown
FE->>U: Átirányítás /complete-kyc
Note over U,Email: FÁZIS 3: KYC 1. lépés - Cím
U->>FE: Cím adatok megadása
FE->>API: POST /auth/complete-kyc (cím adatok)
API->>API: Shadow Identity ellenőrzés
API->>DB: GeoService cím létrehozás
Note over U,Email: FÁZIS 4: KYC 2. lépés - Teljesítés
U->>FE: Személyes adatok + doksik
FE->>API: POST /auth/complete-kyc (összes adat)
API->>DB: UPDATE person (phone, birth, docs)
API->>DB: INSERT organization (personal)
API->>DB: INSERT wallet
API->>DB: INSERT branch
API->>DB: INSERT organization_member
API->>DB: INSERT gamification_event (XP)
API-->>FE: {status: "success"}
FE->>FE: Profil frissítés → fetchUser()
FE->>U: Átirányítás /dashboard
⚠️ 14. Hibakezelés
14.1 Backend Hibakódok
| HTTP Státusz | Hibaüzenet | Ok |
|---|---|---|
400 |
INVALID_PASSWORD |
Jelszó nem felel meg a komplexitási követelményeknek |
400 |
EMAIL_EXISTS |
Email már regisztrálva van |
400 |
INVALID_TOKEN |
Token érvénytelen vagy lejárt |
400 |
TOKEN_ALREADY_USED |
Token már fel lett használva |
400 |
INVALID_CREDENTIALS |
Rossz email/jelszó páros |
401 |
NOT_AUTHENTICATED |
Hiányzó vagy érvénytelen JWT |
403 |
ACCOUNT_INACTIVE |
Fiók nincs aktiválva (email verifikáció hiányzik) |
404 |
USER_NOT_FOUND |
User nem található |
429 |
TOO_MANY_ATTEMPTS |
Túl sok bejelentkezési kísérlet |
14.2 Frontend Hibakezelés
Forrás: frontend/src/stores/auth.ts:102
function extractErrorCode(err: any): string | null {
// Backend hibaüzenet kód kinyerése
if (err?.response?.data?.detail) return err.response.data.detail;
if (err?.response?.data?.message) return err.response.data.message;
return null;
}
📁 15. Érintett Fájlok Listája
Backend
| Fájl | Útvonal | Szerep |
|---|---|---|
auth.py |
backend/app/api/v1/endpoints/auth.py |
7 végpont a regisztrációhoz |
auth_service.py |
backend/app/services/auth_service.py |
Üzleti logika (~500 sor) |
security.py |
backend/app/core/security.py |
JWT token generálás, dekódolás |
config.py |
backend/app/core/config.py |
Beállítások, dinamikus paraméterek |
deps.py |
backend/app/api/deps.py |
Dependency injection (auth guard-ok) |
identity.py |
backend/app/models/identity/identity.py |
Person, User, Wallet, Device modellek |
auth.py |
backend/app/schemas/auth.py |
Pydantic bemeneti sémák |
email_manager.py |
backend/app/services/email_manager.py |
Email küldés (Brevo/SMTP) |
geo_service.py |
backend/app/services/geo_service.py |
Cím normalizálás és létrehozás |
Frontend
| Fájl | Útvonal | Szerep |
|---|---|---|
LoginModal.vue |
frontend/src/components/LoginModal.vue |
3D kártya-forgató (login/register/forgot/resend) |
VerifyEmailView.vue |
frontend/src/views/VerifyEmailView.vue |
Email verifikáció (3 állapot) |
CompleteKycView.vue |
frontend/src/views/CompleteKycView.vue |
2-lépéses KYC kitöltés |
LandingView.vue |
frontend/src/views/LandingView.vue |
Főoldal a LoginModal-lal |
auth.ts |
frontend/src/stores/auth.ts |
Pinia auth store (műveletek + állapot) |
index.ts |
frontend/src/router/index.ts |
Route-ok és guard-ok |
✅ 16. Következtetés
A regisztrációs rendszer biztonságos és jól rétegzett:
- JWT token-ek rövid élettartammal (30 perc access, 1-30 nap refresh)
- Verifikációs token-ek konfigurálható élettartammal (48h / 2h)
- Shadow Identity merge megakadályozza a duplikált személyrekordokat
- Device Fingerprinting a bejelentkezés és verifikáció során
- Dinamikus konfiguráció admin által állítható paraméterekkel
- Multi-provider email Brevo API → SMTP → Fallback lánccal
- Sentinel audit log minden kritikus eseményről
- i18n támogatás mind a backend sablonokban, mind a frontend-en
A rendszer megfelel a GDPR követelményeknek (soft delete, személyes adatok szeparációja a Person és User modellek között).
Dokumentáció készült: 2026-06-07 Audit típusa: Teljes regisztrációs folyamat elemzés (backend + frontend + adatbázis + tokenek)