| [31680c3] | 1 | /**
|
|---|
| 2 | * [Add to HUB] — een klonkt zelf op de Klonkt Hub zetten (Robin, 30-9).
|
|---|
| 3 | *
|
|---|
| 4 | * WAAROM DIT MEER IS DAN EEN LINK. Aanmelden op de hub betekent: de hub
|
|---|
| 5 | * stuurt een Follow. Met de eigenaarspoort aan (standaard) wacht die Follow
|
|---|
| 6 | * dan op de eigenaar -- dezelfde persoon die net op de knop drukte. Zonder dit
|
|---|
| 7 | * stuk zou die dus eerst zijn klonkt aanmelden en daarna zijn eigen aanmelding
|
|---|
| 8 | * moeten goedkeuren op /connect.
|
|---|
| 9 | *
|
|---|
| 10 | * De klik IS de toestemming. Hij geldt kort (een dag), alleen voor een Follow
|
|---|
| 11 | * van de host van de hub, en alleen als die Follow is ondertekend door de hub
|
|---|
| 12 | * zelf. De poort blijft verder precies wat hij was: niemand anders komt er
|
|---|
| 13 | * zonder ja door, en bij een WARD beslissen nog steeds de guardians -- die
|
|---|
| 14 | * poort staat in ap-inbox VOOR deze, en daar komt dit stuk nooit langs.
|
|---|
| 15 | *
|
|---|
| 16 | * De uitnodiging wordt niet opgebruikt bij de eerste Follow maar loopt af. Een
|
|---|
| 17 | * hub die zijn Follow opnieuw stuurt (na een time-out) krijgt anders alsnog
|
|---|
| 18 | * een wachtend verzoek voor iets dat al beslist was.
|
|---|
| 19 | */
|
|---|
| 20 | import db from '../config/database.js';
|
|---|
| 21 |
|
|---|
| 22 | const GELDIG_MS = 24 * 3600 * 1000;
|
|---|
| 23 |
|
|---|
| 24 | /** De hub waar de knop naartoe wijst. Zelfhosters kunnen een andere kiezen. */
|
|---|
| 25 | export function hubUrl() {
|
|---|
| 26 | return String(process.env.KLONKT_HUB_URL || 'https://hub.klonkt.com').replace(/\/+$/, '');
|
|---|
| 27 | }
|
|---|
| 28 |
|
|---|
| 29 | function hubHost() {
|
|---|
| 30 | try { return new URL(hubUrl()).host.toLowerCase(); } catch { return ''; }
|
|---|
| 31 | }
|
|---|
| 32 |
|
|---|
| 33 | function hostOf(uri) {
|
|---|
| 34 | try { return new URL(uri).host.toLowerCase(); } catch { return ''; }
|
|---|
| 35 | }
|
|---|
| 36 |
|
|---|
| 37 | /** Komt dit actor-adres van de hub? */
|
|---|
| 38 | export const isHubActor = (uri) => !!uri && hostOf(uri) === hubHost();
|
|---|
| 39 |
|
|---|
| 40 | /** De eigenaar zegt ja, vooruit: de volgende dag mag een Follow van de hub door. */
|
|---|
| 41 | export function invite(siteId) {
|
|---|
| 42 | db.prepare('UPDATE sites SET hub_invite_until = ? WHERE id = ?').run(Date.now() + GELDIG_MS, siteId);
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | /** Heeft de eigenaar van `slug` de hub uitgenodigd, en is dat nog geldig? */
|
|---|
| 46 | export function isInvited(slug, actorUri) {
|
|---|
| 47 | if (!isHubActor(actorUri)) return false;
|
|---|
| 48 | const r = db.prepare('SELECT hub_invite_until FROM sites WHERE slug = ?').get(slug);
|
|---|
| 49 | return !!(r && r.hub_invite_until && r.hub_invite_until > Date.now());
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | /** Volgt de hub deze klonkt al? Dan hoort er geen knop maar een bevestiging. */
|
|---|
| 53 | export function onHub(slug) {
|
|---|
| 54 | const rows = db.prepare('SELECT actor_uri FROM ap_followers WHERE slug = ?').all(slug);
|
|---|
| 55 | return rows.some((r) => isHubActor(r.actor_uri));
|
|---|
| 56 | }
|
|---|