Changeset e84ce32 in Klonkt for src/routes/posts.js


Ignore:
Timestamp:
07/24/2026 05:34:51 PM (7 weeks ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
1a2d8ac
Parents:
318d0c2
Message:

Voogdij-aanvraag als speciaal bericht in Berichten, met accepteer-knop

Robins besluit (optie C): een guardianship-offer hoort bij het kind binnen
te komen in de eigen Klonkt, als speciaal bericht in Berichten, met een
accepteer- en weiger-knop. De kindveiligheid rond het accepteren wordt
out-of-band geregeld door de ouders/guardians zelf; het kind heeft een
Klonkt en de guardians ook.

Berichten toont pending offers (ward-kant van ap_guardianships) bovenaan
als kaart met boei-accent: wie het is, de uitleg-tekst (bespreek dit met je
ouders), en Accepteer/Weiger. Het antwoord loopt door dezelfde C2S
Accept/Reject-pijplijn als de Shaer-apps, dus één pad, één gedrag. De
offer_received-push wijst nu naar Berichten in plaats van /guardian (daar
kon het kind niks).

Changed files:
src/routes/posts.js

  • GET /messages geeft guardianOffers mee (role=ward, status=offered)
  • POST /messages/guardianship: accept/reject via de handshake-module

src/views/pages/messages.ejs

  • offer-kaart met accepteer/weiger-form; nette success/error-teksten

src/services/i18n.js

  • msg.guard_* in nl/en/de

src/services/ActivityPubService.js

  • offer_received-push linkt naar Berichten

remarks: de Shaer-apps volgen apart (adopt-flow eruit, accepteer-optie op
offers; Shaer is voor wards).

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    r318d0c2 re84ce32  
    2020import VideoCoverService from '../services/VideoCoverService.js';
    2121import ActivityPubService from '../services/ActivityPubService.js';
     22import * as Guardianship from '../services/guardianship/index.js';
    2223import { premiumUnlocked } from '../services/PatreonService.js';
    2324import { defaultMinCents as paidDefaultMinCents, patreonUrl as paidPatronUrl } from '../services/PaidPatreonService.js';
     
    930931    return renderPage(req, res, 'partials/messages-append', { items, seen: seenAt, hasMore, nextOffset: offset + FEED_PAGE, moreBase });
    931932  }
     933  // FEP-633c: pending guardianship offers TO this account (ward side) show
     934  // as a special message with an accept button (Robins besluit: the kid
     935  // answers in their own Klonkt; safety is handled out-of-band by the
     936  // guardians themselves).
     937  const guardianOffers = site
     938    ? Guardianship.listOffers(site.slug).filter((o) => o.role === 'ward')
     939    : [];
    932940  renderPage(req, res, 'pages/messages', {
    933941    pageTitleKey: 'msg.title', bodyClass: 'on-special', items, seenAt,
    934     hasMore, nextOffset: offset + FEED_PAGE, moreBase,
     942    hasMore, nextOffset: offset + FEED_PAGE, moreBase, guardianOffers,
    935943    success: req.query.success || null, error: req.query.error || null,
    936944  });
     945});
     946
     947// The kid answers a guardianship offer from Berichten: the same C2S
     948// Accept/Reject pipeline the Shaer apps use (one path, one behavior).
     949router.post('/messages/guardianship', requireSiteManager, async (req, res) => {
     950  const site = res.locals.site;
     951  const back = `${res.locals.siteUrlBase || ''}/messages`;
     952  const answer = req.body.answer === 'accept' ? 'Accept' : (req.body.answer === 'reject' ? 'Reject' : null);
     953  const guardian = String(req.body.guardian || '').trim();
     954  if (!site || !answer || !guardian) return res.redirect(back + '?error=guardianship');
     955  const row = Guardianship.getRelation(site.slug, 'ward', guardian);
     956  if (!row || row.status !== 'offered') return res.redirect(back + '?error=guardianship');
     957  try {
     958    const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
     959    const me = ActivityPubService.actorId(base, site.slug);
     960    const r = await Guardianship.handleGuardianshipOutbox(site, {
     961      type: answer,
     962      object: row.offer_id || { type: 'Relationship', subject: me, relationship: 'shaer:Guardian', object: guardian },
     963    });
     964    if (r && r.status < 400) return res.redirect(back + '?success=' + (answer === 'Accept' ? 'guardian_accepted' : 'guardian_rejected'));
     965  } catch { /* fall through */ }
     966  res.redirect(back + '?error=guardianship');
    937967});
    938968router.get('/fediverse', requireSiteManager, (req, res) => res.redirect(`${res.locals.siteUrlBase || ''}/messages`));
Note: See TracChangeset for help on using the changeset viewer.