Files
service-finder/docs/auth_registration_full_audit_2026-06-07.md
2026-06-10 08:06:07 +00:00

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.vue 3D kártya-forgató (CSS rotateY/rotateX) a register oldallapon.
  • Gyűjtött mezők: lastName, firstName, regEmail, regPassword (min. 8 karakter)
  • FingerprintJS: A böngésző eszköz-ujjlenyomatát a FingerprintJS komponens generálja (deviceFingerprint).
  • Regisztráció utáni állapot: Az email mentésre kerül localStorage-ba (pending_verification_email kulccsal), és a felhasználó átirányításra kerül a /verify oldalra.
  • 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:

  1. Dinamikus konfiguráció lekérése a system.system_parameters táblából:

    • auth_min_password_length → alapértelmezett 8
    • auth_default_role → alapértelmezett "user"
    • auth_registration_hours → alapértelmezett 48
  2. 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)
  3. Email egyediség ellenőrzéseUniqueViolation kezelés Sentinel audit loggal

  4. 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
    )
    
  5. 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(),
    )
    
  6. 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
    )
    
  7. Token slug generálása (security.generate_secure_slug())

  8. Email küldés (EmailManager.send_email()):

    • template_key: "registration_verification"
    • Címzett: user.email
    • Változók: verification_url, user_name, expiry_hours
  9. 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.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 VerifyEmailView a 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

  1. Token validálás:

    • UUID formátum ellenőrzése
    • Létezik-e a token a verification_tokens táblában
    • is_used=False — még nem használták fel
    • expires_at > now() — nem járt le
  2. User aktiválás:

    user.is_active = True
    person.is_active = True
    token.is_used = True
    
  3. 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)
    
  4. 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
    )
    
  5. 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 GeoService a data.zip_codes, data.streets, data.street_types, data.addresses tá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ám
  • identity_docs — Dokumentumok:
    • id_card_number + id_card_expiry
    • driver_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:

  1. 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)
    
  2. 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
    
  3. 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,
    )
    
  4. 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",
    )
    
  5. Branch létrehozása (data.branches):

    branch = Branch(
        organization_id=org.id,
        address_id=address.id,
        name="Központi telephely",
        branch_type="headquarters",
    )
    
  6. OrganizationMember létrehozása (data.organization_members):

    member = OrganizationMember(
        organization_id=org.id,
        user_id=current_user.id,
        role="owner",
    )
    
  7. Gamification XP award:

    • ProfileCompleted esemény → +50 XP
    • EmailVerified + ProfileCompleted kombó → +100 XP (first_login bonus)
  8. P2P referral XP:

    • Ha referred_by_id be van állítva a User-en:
    • A referrer +100 XP-t kap (ReferralUsed esemény)
  9. 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:

  1. email + passwordauthStore.login()
  2. Ha isKycComplete = false → /complete-kyc redirect
  3. Ha isKycComplete = true → /dashboard redirect

Remember Me: localStorage-ban tárolva (login_remember)

7.2 VerifyEmailView.vue — Verifikációs Oldal

URL: /verify?token=...

3 állapot:

  1. Verifying (isVerifying = true):

    • Spinner komponens
    • "Email cím ellenőrzése..." szöveg
    • Token kiolvasása a URL-ből
  2. Success (verifySuccess = true):

    • Zöld pipa animáció (CSS)
    • "Email cím sikeresen megerősítve!"
    • 3 másodperces countdown → /complete-kyc
  3. 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 tartozhat
  • active_user_account: User — Az aktív User
  • address: Address — Lakcím
  • owned_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 tartozik
  • referrer: User — Aki meghívta
  • sales_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
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 - email
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)