Files
rar-autopass/app/web/templates/_cont.html
Claude Agent 1648960b13 feat(5.20): US-008 configurare medii RAR per cont (Testare/Productie)
Ruta noua POST /cont/rar-medii: doua sectiuni independente Testare/Productie,
fiecare cu bifa activare + email/parola. La salvare, mediu activat cu creds noi
e validat prin login pe env-ul respectiv (US-007); OK -> criptare Fernet in
rar_creds_{env}_enc + enabled=1; esec -> eroare per-env, creds nesalvate.

Prima activare Productie cere checkbox de confirmare (constientizare L.142).
Mediul implicit (rar_env_default) setabil DOAR pe un mediu disponibil, validat
server-side post-update. Parolele niciodata reflectate in pagina.

_fetch_cont_env_state deriva starea per-env pentru _cont.html; refactor al
handlerelor de cont sa foloseasca env_ctx in loc de are_creds legacy.

tests/test_cont_medii.py: 4 teste (salvare+creds criptate per env, default doar
dintre disponibile, confirmare prod obligatorie, fara echo parola).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:53:50 +00:00

220 lines
10 KiB
HTML

<div class="card" id="card-cont">
<h2 style="font-size:15px; margin:0 0 16px;">Contul meu</h2>
<!-- Sectiunea: Plan curent (US-006 PRD 5.17) -->
{% if plan_linie is defined %}
<div id="sectiune-plan" style="margin-bottom:20px; padding-bottom:20px; border-bottom:1px solid var(--line);">
<h3 style="font-size:var(--fs-sm); color:var(--muted); font-weight:500; margin:0 0 10px;
text-transform:uppercase; letter-spacing:.04em;">Plan curent</h3>
<div style="font-size:var(--fs-md); font-weight:600; margin-bottom:6px;
color:{% if plan_limita_atinsa|default(false) %}var(--err){% elif plan_warn|default(false) %}var(--warn){% else %}var(--ink){% endif %};">
{{ plan_linie }}
</div>
{% if monthly_limit_val is defined and monthly_limit_val is not none and effective_tier_name|default('') == 'free' %}
<div style="font-size:var(--fs-sm); color:var(--muted); margin-bottom:8px;">
Planul Gratuit include {{ monthly_limit_val }} prestatii/luna prin dashboard-ul web.
{% if plan_limita_atinsa|default(false) %}
Limita lunara a fost atinsa — trimiterile noi sunt blocate pana la inceputul lunii urmatoare.
{% elif plan_warn|default(false) %}
Te apropii de limita lunara.
{% endif %}
</div>
{% endif %}
<div style="font-size:var(--fs-sm); color:var(--muted); padding:8px 10px;
border:1px solid var(--line); border-radius:6px; margin-top:4px;">
Vrei sa treci pe Standard, Pro sau Premium?
Contacteaza-ne pentru alocare manuala — nu exista inca plata self-service.
<strong>Pro</strong> adauga import prin API; <strong>Standard</strong> si
<strong>Premium</strong> ridica limita de volum.
</div>
</div>
{% endif %}
<!-- Sectiunea: Date firma (US-002) -->
<div style="margin-bottom:20px; padding-bottom:20px; border-bottom:1px solid var(--line);">
<h3 style="font-size:13px; color:var(--muted); font-weight:500; margin:0 0 8px; text-transform:uppercase; letter-spacing:.04em;">Date firma</h3>
{% if date_firma_mesaj %}
<div class="flash" style="margin-bottom:12px;">{{ date_firma_mesaj }}</div>
{% endif %}
{% if date_firma_eroare %}
<div class="banner" style="margin-bottom:12px; padding:8px 12px;">{{ date_firma_eroare }}</div>
{% endif %}
<form hx-post="/cont/date-firma"
hx-target="#card-cont"
hx-swap="outerHTML">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<p style="margin:0 0 8px;">
<label style="font-size:13px; color:var(--muted);">Companie</label><br>
<input type="text" name="companie" required
value="{{ account_meta.name or '' }}"
style="width:100%; max-width:340px;"
placeholder="Numele firmei (ex. Service Auto SRL)">
</p>
<p style="margin:0 0 8px;">
<label style="font-size:13px; color:var(--muted);">Email contact</label><br>
<input type="email" name="email" required
value="{{ account_meta.email or '' }}"
style="width:100%; max-width:340px;"
placeholder="contact@firma.ro">
</p>
<p style="margin:0 0 12px;">
<label style="font-size:13px; color:var(--muted);">CUI (cod unic de identificare)</label><br>
<input type="text" name="cui" required
value="{{ account_meta.cui or '' }}"
style="width:100%; max-width:340px;"
placeholder="RO12345678">
</p>
<button type="submit">Salveaza datele firmei</button>
</form>
</div>
<!-- Sectiunea: Cheia mea API -->
<div style="margin-bottom:20px; padding-bottom:20px; border-bottom:1px solid var(--line);">
<h3 style="font-size:13px; color:var(--muted); font-weight:500; margin:0 0 8px; text-transform:uppercase; letter-spacing:.04em;">Cheia mea API</h3>
{% if api_key %}
<div class="flash" style="margin-bottom:12px;">Cheia a fost rotita. Salveaz-o acum — nu o vei mai putea vedea.</div>
<div class="card" style="font-family:monospace; word-break:break-all; font-size:14px; background:#0f1115; margin:0 0 8px;">
{{ api_key }}
</div>
<button type="button"
data-key="{{ api_key }}"
onclick="navigator.clipboard.writeText(this.dataset.key).then(()=>this.textContent='Copiat!')">
Copiaza cheia
</button>
<p style="font-size:13px; color:var(--warn); margin:10px 0 0;">
Atentie: la urmatoarea vizita aceasta cheie dispare. Daca o pierzi, roteste din nou.
</p>
{% endif %}
{% if rot_eroare %}
<div class="banner" style="margin-bottom:12px; padding:8px 12px;">{{ rot_eroare }}</div>
{% endif %}
<form hx-post="/cont/roteste-cheie"
hx-target="#card-cont"
hx-swap="outerHTML"
style="margin-top:{% if api_key %}12px{% else %}0{% endif %};">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<button type="submit" style="background:var(--card); color:var(--warn); border-color:var(--warn);">
Roteste cheia API
</button>
<span style="font-size:12px; color:var(--muted); margin-left:8px;">Cheia veche se revoca imediat.</span>
</form>
</div>
<!-- Sectiunea: Credentiale RAR -->
<div>
<h3 style="font-size:13px; color:var(--muted); font-weight:500; margin:0 0 12px; text-transform:uppercase; letter-spacing:.04em;">Credentiale RAR (portal AUTOPASS)</h3>
{% if creds_mesaj %}
<div class="flash" style="margin-bottom:12px;">{{ creds_mesaj }}</div>
{% endif %}
{% if creds_eroare %}
<div class="banner" style="margin-bottom:12px; padding:8px 12px;">{{ creds_eroare }}</div>
{% endif %}
<form hx-post="/cont/rar-medii"
hx-target="#card-cont"
hx-swap="outerHTML">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<!-- Subsectiunea: Testare -->
<div style="margin-bottom:16px; padding-bottom:16px; border-bottom:1px solid var(--line);">
<p style="margin:0 0 6px;">
<label style="font-size:13px; color:var(--muted); display:flex; align-items:center; gap:6px;">
<input type="checkbox" name="test_enabled" value="1" {% if test_enabled %}checked{% endif %}>
Activare Testare
</label>
{% if test_disponibil %}
<span style="font-size:12px; color:var(--ok);">configurat</span>
{% endif %}
</p>
<p style="margin:0 0 8px;">
<label style="font-size:13px; color:var(--muted);">Email RAR Testare</label><br>
<input type="email" name="test_email" style="width:100%; max-width:340px;"
placeholder="email@service.ro">
</p>
<p style="margin:0 0 8px;">
<label style="font-size:13px; color:var(--muted);">Parola RAR Testare</label><br>
<input type="password" name="test_parola" style="width:100%; max-width:340px;"
autocomplete="new-password">
</p>
{% if creds_test_mesaj %}
<div class="flash" style="margin-top:6px;">{{ creds_test_mesaj }}</div>
{% endif %}
{% if creds_test_eroare %}
<div class="banner" style="margin-top:6px; padding:8px 12px;">{{ creds_test_eroare }}</div>
{% endif %}
</div>
<!-- Subsectiunea: Productie -->
<div style="margin-bottom:16px; padding-bottom:16px; border-bottom:1px solid var(--line);">
<p style="margin:0 0 6px;">
<label style="font-size:13px; color:var(--muted); display:flex; align-items:center; gap:6px;">
<input type="checkbox" name="prod_enabled" value="1" {% if prod_enabled %}checked{% endif %}>
Activare Productie
</label>
{% if prod_disponibil %}
<span style="font-size:12px; color:var(--ok);">configurat</span>
{% endif %}
</p>
<p style="margin:0 0 8px;">
<label style="font-size:13px; color:var(--muted);">Email RAR Productie</label><br>
<input type="email" name="prod_email" style="width:100%; max-width:340px;"
placeholder="email@service.ro">
</p>
<p style="margin:0 0 8px;">
<label style="font-size:13px; color:var(--muted);">Parola RAR Productie</label><br>
<input type="password" name="prod_parola" style="width:100%; max-width:340px;"
autocomplete="new-password">
</p>
<p style="margin:0 0 8px;">
<label style="font-size:13px; color:var(--muted); display:flex; align-items:flex-start; gap:6px;">
<input type="checkbox" name="prod_confirmare" value="1" style="margin-top:2px; flex-shrink:0;">
Inteleg ca trimiterile pe Productie sunt declaratii reale (L.142), finale si fara anulare.
</label>
</p>
{% if creds_prod_mesaj %}
<div class="flash" style="margin-top:6px;">{{ creds_prod_mesaj }}</div>
{% endif %}
{% if creds_prod_eroare %}
<div class="banner" style="margin-top:6px; padding:8px 12px;">{{ creds_prod_eroare }}</div>
{% endif %}
</div>
<!-- Selector mediu implicit -->
<div style="margin-bottom:16px;">
<label style="font-size:13px; color:var(--muted);">Mediu implicit pentru trimiteri</label><br>
{% if medii_disponibile %}
<select name="rar_env_default" style="width:100%; max-width:340px; margin-top:4px;">
{% for env in medii_disponibile %}
<option value="{{ env }}"{% if env == rar_env_default %} selected{% endif %}>{{ "Testare" if env == "test" else "Productie" }}</option>
{% endfor %}
</select>
{% else %}
<p style="font-size:13px; color:var(--muted); margin:4px 0 0;">Activeaza si valideaza un mediu intai.</p>
{% endif %}
{% if creds_default_mesaj %}
<div class="flash" style="margin-top:6px;">{{ creds_default_mesaj }}</div>
{% endif %}
{% if creds_default_eroare %}
<div class="banner" style="margin-top:6px; padding:8px 12px;">{{ creds_default_eroare }}</div>
{% endif %}
</div>
<button type="submit">Salveaza mediile RAR</button>
<span style="font-size:12px; color:var(--muted); margin-left:8px;">Parolele stocate criptat, niciodata in clar.</span>
</form>
</div>
</div>