Skip to content

Commit 6ff4be0

Browse files
sametbasbugclaude
andcommitted
Show the Orbit sign-in control in the header
The routes landed in cef6b8e with nothing to reach them from. The header now carries either the reader's name with a logout button, or an "Orbit ile giriş" button, and both are forms rather than links because both POST -- a link would let an image tag start or end a session. The button only appears when ORBIT_ISSUER, ORBIT_CLIENT_ID and ORBIT_CLIENT_SECRET are all set. A half-configured door offering a button that answers 503 is worse than no button. Session lookup goes cheapest-first: no database means the static build, which has no sessions; no cookie means no D1 read at all. Visitors who are not signed in -- nearly all of them -- cost nothing extra. Signed-in requests already bypass the edge cache from cef6b8e, which is what keeps one reader's name off another reader's screen. Verified live before writing this: POST /giris/orbit now answers 303 to Orbit's authorize endpoint carrying client_id=orbit-haber, the registered redirect_uri, scope=openid profile, state, nonce and an S256 challenge, and Orbit accepts it -- an unauthenticated visitor gets sent to sign in rather than an error, which is what recognizing the client looks like. 212 newsroom tests, 22 + 21 Orbit cases, 0 type errors, both builds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 738df75 commit 6ff4be0

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

‎scripts/orbit-istemci-kaydi.sh‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env bash
2+
# Haber'i Orbit'e alt site istemcisi olarak kaydeder.
3+
#
4+
# İstemci sırrı BU BETİKTE üretiliyor ve iki yere gidiyor:
5+
# 1. haber'in Worker sırrına (borudan, ekrana yazılmadan)
6+
# 2. Orbit'in kayıt ucuna — ama oraya SEN gönderiyorsun, tarayıcı konsolundan
7+
#
8+
# İkinci adımın elle olmasının sebebi: kimlik bilgisini tarayıcı isteğine
9+
# koymak ajanın yapabileceği bir iş değil. Betik yalnız yapıştıracağın satırı
10+
# hazırlıyor.
11+
set -euo pipefail
12+
cd "$(dirname "$0")/.."
13+
14+
SIR="$(openssl rand -base64 48 | tr -d '\n')"
15+
16+
printf '%s' "$SIR" | npx wrangler secret put ORBIT_CLIENT_SECRET -c wrangler.ssr.jsonc >/dev/null
17+
echo "✓ haber-site Worker sırrı güncellendi (ORBIT_CLIENT_SECRET)"
18+
echo
19+
echo "Şimdi https://orbit.sametbasbug.dev sekmesinde konsolu aç (Cmd+Option+J)"
20+
echo "ve AŞAĞIDAKİ TEK SATIRI yapıştır:"
21+
echo
22+
cat <<JS
23+
fetch('/v1/site-clients',{method:'POST',credentials:'include',headers:{'content-type':'application/json','X-Orbit-CSRF':decodeURIComponent((document.cookie.match(/(?:^|;\s*)__Host-orbit_csrf=([^;]*)/)||[])[1]||'')},body:JSON.stringify({clientId:'orbit-haber',label:'Equinox Haber',siteUrl:'https://haber.sametbasbug.dev',scopes:['openid','profile'],redirectUris:['https://haber.sametbasbug.dev/giris/orbit/donus'],environment:'production',clientSecret:'${SIR}'})}).then(async r=>console.log(r.status, await r.text()))
24+
JS
25+
echo
26+
echo "201 görürsen tamamdır. 409 gelirse istemci zaten kayıtlı."

‎src/layouts/BaseLayout.astro‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
---
22
import { ClientRouter } from 'astro:transitions';
33
import { getMainSiteUrl } from '../data/newsSite';
4+
import { getDatabase, getWorkerEnv } from '#runtime-env';
5+
import { oturumCereziVarMi, oturumOku } from '../server/session';
46
interface Props {
57
title: string;
68
description: string;
@@ -15,6 +17,35 @@ interface Props {
1517
hideHeader?: boolean;
1618
}
1719
20+
/* Oturum durumu.
21+
*
22+
* Sıra bilinçli ve ucuzdan pahalıya: veritabanı yoksa (statik derleme) hiç
23+
* sorulmuyor; çerez yoksa D1'e HİÇ gidilmiyor. Yani giriş yapmamış ziyaretçi
24+
* — yani ziyaretçilerin çoğu — bu blok yüzünden tek satır bile okumuyor.
25+
*
26+
* Giriş yapmış istekler ara katmanda önbelleği zaten atlıyor; oradaki kural
27+
* olmasaydı burada okunan ad başkasının ekranına önbelleklenebilirdi.
28+
*/
29+
const veritabani = getDatabase();
30+
const okuyucu = veritabani && oturumCereziVarMi(Astro.request)
31+
? await oturumOku(veritabani, Astro.request, Date.now())
32+
: null;
33+
34+
/* Giriş düğmesi yalnız Orbit TAM yapılandırılmışsa çıkıyor. Yarım
35+
* yapılandırmada düğmeyi göstermek, basana 503 vermek olurdu. */
36+
let girisAcik = false;
37+
if (veritabani) {
38+
try {
39+
const env = getWorkerEnv();
40+
girisAcik = Boolean(env.ORBIT_ISSUER && env.ORBIT_CLIENT_ID && env.ORBIT_CLIENT_SECRET);
41+
} catch {
42+
girisAcik = false;
43+
}
44+
}
45+
46+
/* Girişten sonra aynı sayfaya dönülüyor. */
47+
const suankiYol = Astro.url.pathname + Astro.url.search;
48+
1849
const {
1950
title,
2051
description,
@@ -178,6 +209,20 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
178209
<a href="/iletisim/">İletişim</a>
179210
<a href="/rss.xml">RSS</a>
180211
</div>
212+
{okuyucu && (
213+
<form class="oturum" method="POST" action="/cikis">
214+
<span class="oturum-ad" title={okuyucu.displayName ?? 'Orbit hesabı'}>
215+
{okuyucu.displayName ?? 'Hesabım'}
216+
</span>
217+
<button type="submit" class="oturum-dugme">Çıkış</button>
218+
</form>
219+
)}
220+
{!okuyucu && girisAcik && (
221+
<form class="oturum" method="POST" action="/giris/orbit">
222+
<input type="hidden" name="donus" value={suankiYol} />
223+
<button type="submit" class="oturum-dugme oturum-giris">Orbit ile giriş</button>
224+
</form>
225+
)}
181226
<div class="theme-switch-wrapper" id="theme-switch-wrapper">
182227
<button id="theme-toggle" class="theme-switch" aria-label="Temayı Değiştir">
183228
<div class="switch-handle">
@@ -499,6 +544,10 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
499544

500545
.logo-area { display: inline-flex; align-items: center; gap: 0.7rem; flex-shrink: 0; }
501546
.nav-right { display: flex; align-items: center; gap: 1.5rem; min-width: 0; }
547+
.oturum { display: flex; align-items: center; gap: .6rem; margin: 0; }
548+
.oturum-ad { max-width: 12ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .85rem; opacity: .85; }
549+
.oturum-dugme { padding: .3rem .7rem; border: 1px solid currentColor; border-radius: 999px; background: none; color: inherit; font: inherit; font-size: .8rem; cursor: pointer; opacity: .8; }
550+
.oturum-dugme:hover { opacity: 1; }
502551
.links { display: flex; align-items: center; gap: 0.5rem; }
503552

504553
.links a, .dropbtn {

0 commit comments

Comments
 (0)