credits: hide AI Lab affiliation only for alz@bii.dk
Restore the "Part of AI Lab" credit block in all three views and hide it client-side once /auth/me (or fresh login) identifies the viewer as alz@bii.dk. Everyone else sees it as before. Marked with data-ailab; hidden via inline display:none since the flex containers override the [hidden] attribute. No inline scripts — logic lives in the existing page JS, CSP stays script-src 'self'. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b4babd82d5
commit
b3bd5e4af6
6 changed files with 69 additions and 0 deletions
|
|
@ -2681,6 +2681,11 @@ html {
|
||||||
<span class="support-credit-name">Innofounder</span>
|
<span class="support-credit-name">Innofounder</span>
|
||||||
<span class="support-credit-auth">Innovationsfonden</span>
|
<span class="support-credit-auth">Innovationsfonden</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="support-credit" data-ailab>
|
||||||
|
<span class="support-credit-label">Part of</span>
|
||||||
|
<span class="support-credit-name">AI Lab</span>
|
||||||
|
<span class="support-credit-auth">BioInnovation Institute</span>
|
||||||
|
</div>
|
||||||
<div class="support-credit">
|
<div class="support-credit">
|
||||||
<span class="support-credit-label">Part of</span>
|
<span class="support-credit-label">Part of</span>
|
||||||
<span class="support-credit-name">The Regulatory AI-Sandbox</span>
|
<span class="support-credit-name">The Regulatory AI-Sandbox</span>
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,11 @@
|
||||||
<span class="m-credit-name">Innofounder</span>
|
<span class="m-credit-name">Innofounder</span>
|
||||||
<span class="m-credit-auth">Innovationsfonden</span>
|
<span class="m-credit-auth">Innovationsfonden</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="m-credit" data-ailab>
|
||||||
|
<span class="m-credit-label">Part of</span>
|
||||||
|
<span class="m-credit-name">AI Lab</span>
|
||||||
|
<span class="m-credit-auth">BioInnovation Institute</span>
|
||||||
|
</div>
|
||||||
<div class="m-credit">
|
<div class="m-credit">
|
||||||
<span class="m-credit-label">Part of</span>
|
<span class="m-credit-label">Part of</span>
|
||||||
<span class="m-credit-name">The Regulatory AI-Sandbox</span>
|
<span class="m-credit-name">The Regulatory AI-Sandbox</span>
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,30 @@
|
||||||
// protected/mobile/index.html and never by the desktop view.
|
// protected/mobile/index.html and never by the desktop view.
|
||||||
// ─────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/* ───── AI Lab credit visibility ─────
|
||||||
|
The "Part of AI Lab" affiliation credit is shown to everyone except
|
||||||
|
one viewer, who has asked that it never appear while they present.
|
||||||
|
Hidden client-side once /auth/me returns the email. Compared
|
||||||
|
lower-cased so casing doesn't matter; the container is display:flex,
|
||||||
|
so an inline display:none is used (it beats the stylesheet rule,
|
||||||
|
where the [hidden] attribute would not). ───── */
|
||||||
|
const AILAB_HIDE_EMAIL = 'alz@bii.dk';
|
||||||
|
function applyAilabVisibility(email) {
|
||||||
|
if (!email || email.trim().toLowerCase() !== AILAB_HIDE_EMAIL) return;
|
||||||
|
document.querySelectorAll('[data-ailab]').forEach((el) => {
|
||||||
|
el.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
(async function checkSession() {
|
(async function checkSession() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/auth/me', { credentials: 'same-origin' });
|
const res = await fetch('/auth/me', { credentials: 'same-origin' });
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const data = await res.json().catch(() => ({}));
|
||||||
|
applyAilabVisibility(data.email);
|
||||||
} catch {
|
} catch {
|
||||||
// Network error — do not boot the user out; desktop behaviour is
|
// Network error — do not boot the user out; desktop behaviour is
|
||||||
// the same. If the next action actually needs the server, we'll
|
// the same. If the next action actually needs the server, we'll
|
||||||
|
|
|
||||||
|
|
@ -465,6 +465,22 @@ document.querySelectorAll('.dot-btn').forEach(btn => {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* ─────────────────────────────────────────────────────────────
|
||||||
|
AI Lab credit visibility — the "Part of AI Lab" affiliation in the
|
||||||
|
hero foot is shown to everyone except one viewer, who has asked that
|
||||||
|
it never appear while they present. Hidden client-side once /auth/me
|
||||||
|
returns the email. Compared lower-cased so casing doesn't matter;
|
||||||
|
the container is display:flex, so an inline display:none is used (it
|
||||||
|
beats the stylesheet rule, where the [hidden] attribute would not).
|
||||||
|
───────────────────────────────────────────────────────────── */
|
||||||
|
const AILAB_HIDE_EMAIL = 'alz@bii.dk';
|
||||||
|
function applyAilabVisibility(email) {
|
||||||
|
if (!email || email.trim().toLowerCase() !== AILAB_HIDE_EMAIL) return;
|
||||||
|
document.querySelectorAll('[data-ailab]').forEach((el) => {
|
||||||
|
el.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* ─────────────────────────────────────────────────────────────
|
/* ─────────────────────────────────────────────────────────────
|
||||||
First name propagation — fetched from /auth/me on load.
|
First name propagation — fetched from /auth/me on load.
|
||||||
Used by Scene 3 ("This is why we've invited you, [Name].").
|
Used by Scene 3 ("This is why we've invited you, [Name].").
|
||||||
|
|
@ -477,6 +493,7 @@ document.querySelectorAll('.dot-btn').forEach(btn => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
window.__fenjaFirstName = data.firstName || null;
|
window.__fenjaFirstName = data.firstName || null;
|
||||||
|
applyAilabVisibility(data.email);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Offline — leave undefined; bifrost.js falls back to the
|
// Offline — leave undefined; bifrost.js falls back to the
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,11 @@
|
||||||
<span class="welcome-credit-name">Innofounder</span>
|
<span class="welcome-credit-name">Innofounder</span>
|
||||||
<span class="welcome-credit-auth">Innovationsfonden</span>
|
<span class="welcome-credit-auth">Innovationsfonden</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="welcome-credit" data-ailab>
|
||||||
|
<span class="welcome-credit-label">Part of</span>
|
||||||
|
<span class="welcome-credit-name">AI Lab</span>
|
||||||
|
<span class="welcome-credit-auth">BioInnovation Institute</span>
|
||||||
|
</div>
|
||||||
<div class="welcome-credit">
|
<div class="welcome-credit">
|
||||||
<span class="welcome-credit-label">Part of</span>
|
<span class="welcome-credit-label">Part of</span>
|
||||||
<span class="welcome-credit-name">The Regulatory AI-Sandbox</span>
|
<span class="welcome-credit-name">The Regulatory AI-Sandbox</span>
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,21 @@
|
||||||
requestAnimationFrame(() => setTimeout(() => wrap.classList.add('is-ready'), 120));
|
requestAnimationFrame(() => setTimeout(() => wrap.classList.add('is-ready'), 120));
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/* ───── AI Lab credit visibility ─────
|
||||||
|
The "Part of AI Lab" affiliation credit is shown to everyone except
|
||||||
|
one viewer, who has asked that it never appear while they present.
|
||||||
|
Hidden client-side once we know the email — compared lower-cased so
|
||||||
|
casing in the invite list or the typed address doesn't matter. The
|
||||||
|
container is display:flex, so an inline display:none is used (it beats
|
||||||
|
the stylesheet rule; the [hidden] attribute would not). ───── */
|
||||||
|
const AILAB_HIDE_EMAIL = 'alz@bii.dk';
|
||||||
|
function applyAilabVisibility(email) {
|
||||||
|
if (!email || email.trim().toLowerCase() !== AILAB_HIDE_EMAIL) return;
|
||||||
|
document.querySelectorAll('[data-ailab]').forEach((el) => {
|
||||||
|
el.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* ───── Step transitions ───── */
|
/* ───── Step transitions ───── */
|
||||||
const steps = {
|
const steps = {
|
||||||
email: document.getElementById('step-email'),
|
email: document.getElementById('step-email'),
|
||||||
|
|
@ -146,6 +161,9 @@ emailForm.addEventListener('submit', async (e) => {
|
||||||
// welcome step and advance.
|
// welcome step and advance.
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
setWelcomeTitle(data.firstName || null);
|
setWelcomeTitle(data.firstName || null);
|
||||||
|
// /auth/login returns {ok, firstName} — no email — so use the
|
||||||
|
// address the visitor just authenticated with.
|
||||||
|
applyAilabVisibility(email);
|
||||||
setAck(emailAck, '', false);
|
setAck(emailAck, '', false);
|
||||||
showStep('welcome');
|
showStep('welcome');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -173,6 +191,7 @@ document.getElementById('welcome-continue').addEventListener('click', () => {
|
||||||
authed = true;
|
authed = true;
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
firstName = data.firstName || null;
|
firstName = data.firstName || null;
|
||||||
|
applyAilabVisibility(data.email);
|
||||||
}
|
}
|
||||||
} catch { /* offline — fall through to email */ }
|
} catch { /* offline — fall through to email */ }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue