Skip to content

Commit b7cf265

Browse files
Merge pull request #20 from pathbit/feat/challenge-random-36-items-and-strict-click
feat(auth): expandir catalogo de desafios anti-bot para 36 itens e validar clique estrito
2 parents 3aab23c + 28b3b9f commit b7cf265

5 files changed

Lines changed: 172 additions & 21 deletions

File tree

‎src/omini_rtksync/locales/en.json‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,33 @@
293293
"type.oauth": "OAuth 2.0",
294294
"type.synced_model": "Synced model",
295295
"type.virtual_key": "Virtual key",
296-
"auth.authentication": "Authentication"
296+
"auth.authentication": "Authentication",
297+
"auth.item_airplane": "Airplane",
298+
"auth.item_award": "Award",
299+
"auth.item_bicycle": "Bicycle",
300+
"auth.item_camera": "Camera",
301+
"auth.item_cloud": "Cloud",
302+
"auth.item_compass": "Compass",
303+
"auth.item_cpu": "CPU",
304+
"auth.item_cup": "Cup",
305+
"auth.item_droplet": "Droplet",
306+
"auth.item_fire": "Fire",
307+
"auth.item_flag": "Flag",
308+
"auth.item_flower": "Flower",
309+
"auth.item_gem": "Gem",
310+
"auth.item_gift": "Gift",
311+
"auth.item_globe": "Globe",
312+
"auth.item_laptop": "Laptop",
313+
"auth.item_moon": "Moon",
314+
"auth.item_palette": "Palette",
315+
"auth.item_phone": "Phone",
316+
"auth.item_rocket": "Rocket",
317+
"auth.item_sun": "Sun",
318+
"auth.item_terminal": "Terminal",
319+
"auth.item_tree": "Tree",
320+
"auth.item_trophy": "Trophy",
321+
"auth.item_truck": "Truck",
322+
"auth.item_umbrella": "Umbrella",
323+
"auth.item_watch": "Watch",
324+
"auth.item_wifi": "Wi-Fi"
297325
}

‎src/omini_rtksync/locales/es.json‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,33 @@
293293
"type.oauth": "OAuth 2.0",
294294
"type.synced_model": "Modelo sincronizado",
295295
"type.virtual_key": "Clave virtual",
296-
"auth.authentication": "Autenticación"
296+
"auth.authentication": "Autenticación",
297+
"auth.item_airplane": "Avión",
298+
"auth.item_award": "Medalla",
299+
"auth.item_bicycle": "Bicicleta",
300+
"auth.item_camera": "Cámara",
301+
"auth.item_cloud": "Nube",
302+
"auth.item_compass": "Brújula",
303+
"auth.item_cpu": "Procesador",
304+
"auth.item_cup": "Taza",
305+
"auth.item_droplet": "Gota",
306+
"auth.item_fire": "Fuego",
307+
"auth.item_flag": "Bandera",
308+
"auth.item_flower": "Flor",
309+
"auth.item_gem": "Diamante",
310+
"auth.item_gift": "Regalo",
311+
"auth.item_globe": "Globo",
312+
"auth.item_laptop": "Portátil",
313+
"auth.item_moon": "Luna",
314+
"auth.item_palette": "Paleta",
315+
"auth.item_phone": "Teléfono",
316+
"auth.item_rocket": "Cohete",
317+
"auth.item_sun": "Sol",
318+
"auth.item_terminal": "Terminal",
319+
"auth.item_tree": "Árbol",
320+
"auth.item_trophy": "Trofeo",
321+
"auth.item_truck": "Camión",
322+
"auth.item_umbrella": "Paraguas",
323+
"auth.item_watch": "Reloj",
324+
"auth.item_wifi": "Wi-Fi"
297325
}

‎src/omini_rtksync/locales/pt.json‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,33 @@
293293
"type.oauth": "OAuth 2.0",
294294
"type.synced_model": "Modelo sincronizado",
295295
"type.virtual_key": "Chave virtual",
296-
"auth.authentication": "Autenticação"
296+
"auth.authentication": "Autenticação",
297+
"auth.item_airplane": "Avião",
298+
"auth.item_award": "Medalha",
299+
"auth.item_bicycle": "Bicicleta",
300+
"auth.item_camera": "Câmera",
301+
"auth.item_cloud": "Nuvem",
302+
"auth.item_compass": "Bússola",
303+
"auth.item_cpu": "Processador",
304+
"auth.item_cup": "Xícara",
305+
"auth.item_droplet": "Gota",
306+
"auth.item_fire": "Fogo",
307+
"auth.item_flag": "Bandeira",
308+
"auth.item_flower": "Flor",
309+
"auth.item_gem": "Diamante",
310+
"auth.item_gift": "Presente",
311+
"auth.item_globe": "Globo",
312+
"auth.item_laptop": "Notebook",
313+
"auth.item_moon": "Lua",
314+
"auth.item_palette": "Paleta",
315+
"auth.item_phone": "Celular",
316+
"auth.item_rocket": "Foguete",
317+
"auth.item_sun": "Sol",
318+
"auth.item_terminal": "Terminal",
319+
"auth.item_tree": "Árvore",
320+
"auth.item_trophy": "Troféu",
321+
"auth.item_truck": "Caminhão",
322+
"auth.item_umbrella": "Guarda-chuva",
323+
"auth.item_watch": "Relógio",
324+
"auth.item_wifi": "Wi-Fi"
297325
}

‎src/omini_rtksync/protecao.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,34 @@
5050
("bell", "bi-bell-fill"),
5151
("lightning", "bi-lightning-fill"),
5252
("gear", "bi-gear-fill"),
53+
("sun", "bi-sun-fill"),
54+
("moon", "bi-moon-stars-fill"),
55+
("cloud", "bi-cloud-fill"),
56+
("fire", "bi-fire"),
57+
("droplet", "bi-droplet-fill"),
58+
("tree", "bi-tree-fill"),
59+
("flower", "bi-flower1"),
60+
("gem", "bi-gem"),
61+
("trophy", "bi-trophy-fill"),
62+
("award", "bi-award-fill"),
63+
("gift", "bi-gift-fill"),
64+
("compass", "bi-compass-fill"),
65+
("flag", "bi-flag-fill"),
66+
("globe", "bi-globe"),
67+
("camera", "bi-camera-fill"),
68+
("cup", "bi-cup-hot-fill"),
69+
("palette", "bi-palette-fill"),
70+
("umbrella", "bi-umbrella-fill"),
71+
("rocket", "bi-rocket-takeoff-fill"),
72+
("airplane", "bi-airplane-fill"),
73+
("bicycle", "bi-bicycle"),
74+
("truck", "bi-truck"),
75+
("cpu", "bi-cpu-fill"),
76+
("terminal", "bi-terminal-fill"),
77+
("laptop", "bi-laptop"),
78+
("phone", "bi-phone-fill"),
79+
("watch", "bi-watch"),
80+
("wifi", "bi-wifi"),
5381
)
5482
MAPA_ICONES: Dict[str, str] = dict(ITENS_DESAFIO)
5583

‎src/omini_rtksync/render.py‎

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ def render_login_page(
430430
)
431431
grade_botoes = "".join(botoes)
432432
desafio_html = f"""
433-
<div class="mb-3 p-3 rounded" style="background:var(--bg);border:1px solid var(--line)">
433+
<div id="box-desafio" class="mb-3 p-3 rounded" style="background:var(--bg);border:1px solid var(--line);transition:border-color .2s">
434434
<label class="form-label small d-flex align-items-center gap-2 mb-2 text-warning fw-semibold">
435435
<i class="bi bi-shield-check" aria-hidden="true"></i>
436436
<span>{esc(instrucao)}</span>
@@ -440,19 +440,58 @@ def render_login_page(
440440
<div class="d-flex gap-2 justify-content-between my-1" role="group" aria-label="{esc(translate("auth.challenge", lang))}">
441441
{grade_botoes}
442442
</div>
443+
<div id="desafio-feedback" class="small mt-2 text-center text-info fw-semibold" style="display:none"></div>
444+
<div id="desafio-erro" class="small mt-2 text-danger fw-semibold" style="display:none">
445+
<i class="bi bi-exclamation-octagon-fill me-1" aria-hidden="true"></i>{esc(translate("auth.select_challenge", lang))}
446+
</div>
443447
</div>
444448
<script>
445-
document.querySelectorAll('.desafio-btn').forEach(btn => {{
446-
btn.addEventListener('click', function() {{
447-
document.querySelectorAll('.desafio-btn').forEach(b => {{
448-
b.classList.remove('btn-primary', 'active');
449-
b.classList.add('btn-outline-secondary');
449+
(function() {{
450+
const btns = document.querySelectorAll('.desafio-btn');
451+
const inputResp = document.getElementById('resposta');
452+
const feedback = document.getElementById('desafio-feedback');
453+
const erroBox = document.getElementById('desafio-erro');
454+
const boxDesafio = document.getElementById('box-desafio');
455+
456+
btns.forEach(btn => {{
457+
btn.addEventListener('click', function() {{
458+
btns.forEach(b => {{
459+
b.classList.remove('btn-primary', 'active', 'border-primary', 'shadow-sm');
460+
b.classList.add('btn-outline-secondary');
461+
b.setAttribute('aria-pressed', 'false');
462+
}});
463+
this.classList.remove('btn-outline-secondary');
464+
this.classList.add('btn-primary', 'active', 'border-primary', 'shadow-sm');
465+
this.setAttribute('aria-pressed', 'true');
466+
const val = this.getAttribute('data-val');
467+
const title = this.getAttribute('title') || val;
468+
if (inputResp) inputResp.value = val;
469+
if (feedback) {{
470+
feedback.innerHTML = '<i class="bi bi-check-circle-fill text-success me-1"></i> ' + title;
471+
feedback.style.display = 'block';
472+
}}
473+
if (erroBox) erroBox.style.display = 'none';
474+
if (boxDesafio) {{
475+
boxDesafio.style.borderColor = 'var(--line)';
476+
boxDesafio.classList.remove('border-danger');
477+
}}
450478
}});
451-
this.classList.remove('btn-outline-secondary');
452-
this.classList.add('btn-primary', 'active');
453-
document.getElementById('resposta').value = this.getAttribute('data-val');
454479
}});
455-
}});
480+
481+
const form = document.querySelector('form[action="/login"]');
482+
if (form) {{
483+
form.addEventListener('submit', function(e) {{
484+
if (inputResp && !inputResp.value) {{
485+
e.preventDefault();
486+
if (erroBox) erroBox.style.display = 'block';
487+
if (boxDesafio) {{
488+
boxDesafio.style.borderColor = 'var(--bs-danger)';
489+
boxDesafio.classList.add('border-danger');
490+
}}
491+
}}
492+
}});
493+
}}
494+
}})();
456495
</script>"""
457496
else:
458497
desafio_html = (
@@ -463,23 +502,23 @@ def render_login_page(
463502
botoes_sso = []
464503
if oidc_nome and saml_nome and oidc_nome == saml_nome:
465504
rotulo_oidc = f"{oidc_nome} (OIDC)"
466-
rotulo_saml = f"{saml_nome} (SAML)"
505+
rotulo_saml = f"{saml_nome} (SAML 2.0)"
467506
else:
468-
rotulo_oidc = oidc_nome
469-
rotulo_saml = saml_nome
507+
rotulo_oidc = f"{oidc_nome} (OIDC)" if oidc_nome and "oidc" not in oidc_nome.lower() else oidc_nome
508+
rotulo_saml = f"{saml_nome} (SAML 2.0)" if saml_nome and "saml" not in saml_nome.lower() else saml_nome
470509

471510
if rotulo_oidc:
472511
botoes_sso.append(
473512
f'<a class="btn btn-outline-light w-100 d-inline-flex align-items-center '
474513
f'justify-content-center gap-2 mb-2" href="/sso/oidc/iniciar" rel="nofollow">'
475-
f'<i class="bi bi-shield-check" aria-hidden="true"></i>'
514+
f'<i class="bi bi-shield-check text-info" aria-hidden="true"></i>'
476515
f'{esc(translate("sso.sign_in_with", lang, provider=rotulo_oidc))}</a>'
477516
)
478517
if rotulo_saml:
479518
botoes_sso.append(
480519
f'<a class="btn btn-outline-light w-100 d-inline-flex align-items-center '
481520
f'justify-content-center gap-2 mb-2" href="/sso/saml/iniciar" rel="nofollow">'
482-
f'<i class="bi bi-shield-lock" aria-hidden="true"></i>'
521+
f'<i class="bi bi-shield-lock text-warning" aria-hidden="true"></i>'
483522
f'{esc(translate("sso.sign_in_with", lang, provider=rotulo_saml))}</a>'
484523
)
485524
elif sso_indisponivel and not botoes_sso:
@@ -1500,9 +1539,9 @@ def render_sso_modal(
15001539
if hasattr(sso_view, "base_url"):
15011540
sso_obj = sso_view
15021541
prov = sso_obj.provedor
1503-
senha_hab = sso_obj.senha_esta_ligada()
1504-
oidc_hab = sso_obj.oidc_esta_ligado()
1505-
saml_hab = sso_obj.saml_esta_ligado()
1542+
senha_hab = sso_obj.senha_habilitada
1543+
oidc_hab = sso_obj.oidc_habilitado
1544+
saml_hab = sso_obj.saml_habilitado
15061545
base_url = sso_obj.base_url or ""
15071546
issuer = sso_obj.issuer or ""
15081547
client_id = sso_obj.client_id or ""

0 commit comments

Comments
 (0)