Skip to content

Commit 0fb52bb

Browse files
Auth0 (auth.coderic.org): login/logout en tema, Alpine.js y Knockout.js
- auth0_domain: auth.coderic.org, auth0_client_id por sitio - assets/js/auth0-coderic.js: SPA redirect flow, botones Iniciar/Cerrar sesión - assets/js/alpine.js y knockout.js: carga desde CDN (ruta tema /assets/js/) - Layout: contenedor #coderic-auth-buttons en header, Auth0 SPA SDK 2.15 - Botones solo visibles si site.auth0_client_id está definido Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent eb70905 commit 0fb52bb

5 files changed

Lines changed: 133 additions & 8 deletions

File tree

_config.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@ privacy_url: "/privacy"
4444
legal_url: "/legal"
4545
tos_url: "/tos"
4646

47-
# Auth URLs (opcional; los sitios sobreescriben)
47+
# Auth0 (opcional; los sitios sobreescriben)
48+
# OpenID: https://auth.coderic.org/.well-known/openid-configuration
4849
# profile_url: "/profile"
4950
# dashboard_url: "/dashboard"
50-
# auth0_domain: "auth.coderic.org"
51-
# auth_js_path: "/js/auth.js"
51+
auth0_domain: "auth.coderic.org"
52+
auth0_client_id: "" # Cada sitio define su Application (Single Page) en Auth0
53+
# auth_js_path: "/assets/js/auth0-coderic.js" # por defecto el tema carga desde assets/js
5254

5355
# Company (opcional)
5456
# about_url: "/about"

_layouts/default.html

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@
9595
</svg>
9696
</div>
9797
</a>
98+
{% if site.auth0_domain and site.auth0_client_id != nil and site.auth0_client_id != "" %}
99+
<div id="coderic-auth-buttons" class="flex items-center gap-2" aria-label="Autenticación"></div>
100+
{% endif %}
98101
</div>
99102
</div>
100103
</header>
@@ -351,11 +354,22 @@ <h3 class="text-sm font-bold uppercase tracking-wider text-white mb-6">Ecosistem
351354
crossorigin="anonymous"></script>
352355
{% endif %}
353356
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
354-
{% if site.auth0_domain %}
355-
<script src="https://cdn.auth0.com/js/auth0/9.28.0/auth0.min.js"></script>
356-
{% endif %}
357-
{% if site.auth_js_path %}
358-
<script type="text/javascript" src="{{ site.auth_js_path | relative_url }}"></script>
357+
<!-- Tema: Alpine.js y Knockout.js (ruta /assets/js/ para no conflictos con cada proyecto) -->
358+
<script defer src="https://unpkg.com/alpinejs@3.14.3/dist/cdn.min.js"></script>
359+
<script src="https://unpkg.com/knockout@3.5.1/build/output/knockout-latest.js"></script>
360+
{% if site.auth0_domain and site.auth0_client_id != nil and site.auth0_client_id != "" %}
361+
<script src="https://cdn.auth0.com/js/auth0-spa-js/2.15/auth0-spa-js.production.js"></script>
362+
<script>
363+
window.CodericAuth0Config = {
364+
domain: "{{ site.auth0_domain }}",
365+
clientId: "{{ site.auth0_client_id }}",
366+
baseurl: "{{ site.baseurl | default: '' }}",
367+
audience: "{{ site.auth0_audience | default: '' }}"
368+
};
369+
</script>
370+
<script src="{{ '/assets/js/auth0-coderic.js' | relative_url }}"></script>
371+
{% elsif site.auth_js_path %}
372+
<script src="{{ site.auth_js_path | relative_url }}"></script>
359373
{% endif %}
360374
</body>
361375
</html>

assets/js/alpine.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Alpine.js — cargado desde CDN para no duplicar en cada proyecto.
3+
* El layout incluye la versión desde CDN; este archivo documenta la ruta del tema.
4+
*/
5+
(function () {
6+
if (window.Alpine) return;
7+
var s = document.createElement("script");
8+
s.src = "https://unpkg.com/alpinejs@3.14.3/dist/cdn.min.js";
9+
s.defer = true;
10+
document.head.appendChild(s);
11+
})();

assets/js/auth0-coderic.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* Auth0 (auth.coderic.org) — Login/Logout en el tema Coderic.
3+
* Requiere: window.CodericAuth0Config = { domain, clientId, baseurl } y Auth0 SPA SDK cargado.
4+
*/
5+
(function () {
6+
"use strict";
7+
8+
var config = window.CodericAuth0Config;
9+
if (!config || !config.domain || !config.clientId) return;
10+
11+
var container = document.getElementById("coderic-auth-buttons");
12+
if (!container) return;
13+
14+
var baseurl = (config.baseurl || "").replace(/\/$/, "");
15+
var redirectUri = window.location.origin + baseurl + "/";
16+
17+
function renderLoggedOut() {
18+
container.innerHTML =
19+
'<button type="button" id="coderic-login-btn" class="px-4 py-2 text-sm font-medium text-white bg-orange-600 rounded-md hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-orange-500">Iniciar sesión</button>';
20+
document.getElementById("coderic-login-btn").addEventListener("click", function () {
21+
window.CodericAuth0Client.loginWithRedirect();
22+
});
23+
}
24+
25+
function renderLoggedIn(user) {
26+
var name = (user && (user.name || user.nickname || user.email)) || "Usuario";
27+
container.innerHTML =
28+
'<span class="text-sm text-gray-600 mr-2">' +
29+
escapeHtml(name) +
30+
'</span><button type="button" id="coderic-logout-btn" class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-orange-500">Cerrar sesión</button>';
31+
document.getElementById("coderic-logout-btn").addEventListener("click", function () {
32+
window.CodericAuth0Client.logout({
33+
logoutParams: { returnTo: redirectUri },
34+
});
35+
});
36+
}
37+
38+
function escapeHtml(s) {
39+
var div = document.createElement("div");
40+
div.textContent = s;
41+
return div.innerHTML;
42+
}
43+
44+
function init() {
45+
if (typeof createAuth0Client === "undefined") {
46+
container.innerHTML = "";
47+
return;
48+
}
49+
createAuth0Client({
50+
domain: config.domain,
51+
clientId: config.clientId,
52+
authorizationParams: {
53+
redirect_uri: redirectUri,
54+
audience: config.audience || undefined,
55+
},
56+
cacheLocation: "memory",
57+
}).then(function (client) {
58+
window.CodericAuth0Client = client;
59+
var q = new URLSearchParams(window.location.search);
60+
if (q.has("code") && q.has("state")) {
61+
client.handleRedirectCallback().then(function () {
62+
window.history.replaceState({}, document.title, baseurl + "/");
63+
return client.getUser();
64+
}).then(function (user) {
65+
renderLoggedIn(user);
66+
}).catch(function () {
67+
renderLoggedOut();
68+
});
69+
return;
70+
}
71+
client.isAuthenticated().then(function (ok) {
72+
if (ok) {
73+
client.getUser().then(renderLoggedIn);
74+
} else {
75+
renderLoggedOut();
76+
}
77+
});
78+
}).catch(function () {
79+
renderLoggedOut();
80+
});
81+
}
82+
83+
if (document.readyState === "loading") {
84+
document.addEventListener("DOMContentLoaded", init);
85+
} else {
86+
init();
87+
}
88+
})();

assets/js/knockout.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Knockout.js — cargado desde CDN para no duplicar en cada proyecto.
3+
* El layout incluye la versión desde CDN; este archivo documenta la ruta del tema.
4+
*/
5+
(function () {
6+
if (window.ko) return;
7+
var s = document.createElement("script");
8+
s.src = "https://unpkg.com/knockout@3.5.1/build/output/knockout-latest.js";
9+
document.head.appendChild(s);
10+
})();

0 commit comments

Comments
 (0)