Member Portal
Member Portal
📄️ A page of the signed-in member's own email history
Newest first, in the same envelope GET /email/log answers with, but scoped to the acting member: only rows whose eml_per_ID is this person. There is no person id to pass. Rows never carry the body; GET /portal/me/emails/{id} does. Session only — API keys are refused.
📄️ One email from the signed-in member's own history, with its body
The row is returned only when it was addressed to the acting member. Somebody else's row and an id that does not exist are the same 404, so a member cannot learn that an email exists by asking for it. The body is null for the email classes that never store one (account emails carrying a password or a one-time link).
📄️ The signed-in member's calendar subscription
Returns the calendars the church shares with members, which of them this member has subscribed to, and the address their calendar app should use. `url` and `webcalUrl` are null until the member saves a selection for the first time — the token is minted then. Session only; API keys are refused.
📄️ Choose which shared calendars the member's feed carries
Stores the member's selection and mints their feed token the first time. Every id must name a calendar the administrator currently shares with members; anything else is a 400, with the same message whether the calendar does not exist or is simply not shared. At least one calendar is required — a feed of nothing is not a useful thing to hand a calendar app.
📄️ Issue the member a new feed address
Rotates the member's feed token, keeping their calendar selection. The previous address stops answering immediately — this is what a member does when they have shared the old one by accident.
📄️ The signed-in member's own profile
Returns the acting member's person record as the Member Portal renders it. The member is taken from the session; there is no person id to pass. Session only — API keys are refused.
📄️ Update the signed-in member's own profile
Applies the allow-listed fields present in the body to the member's own person record and writes a timeline note naming what changed. Anything else in the body is ignored. Birthday is accepted only when bPortalAllowBirthdayEdit is on.
📄️ The signed-in member's own photo (binary image)
Returns the member's uploaded photo bytes. The portal serves its own copy because AuthMiddleware confines a self-service session to /portal and /api/portal, so /api/person/{id}/photo — which the profile used to point at — answers those sessions with 403 and every avatar renders broken. The member is taken from the session; there is no person id to pass. Cached privately for two hours, the same window the person endpoint uses; the URLs the portal hands out carry a ?v=<mtime> cache-buster so a fresh upload is visible at once.
📄️ Replace the signed-in member's own photo
The /api/person/{id}/photo upload route is behind the EditRecords role, which a self-service login never has, so the portal has its own endpoint for the member's own photo. It calls the same model method and writes the same 'photo' timeline note.
📄️ The signed-in member's own family
Returns the acting member's family, its members, and whether this member is one of the adults who may change it. The family is the member's own; there is no family id to pass.
📄️ Update the signed-in member's own family
Applies the allow-listed fields present in the body to the member's own family and writes a timeline note naming what changed. Only an adult of the family (head or spouse, per sDirRoleHead / sDirRoleSpouse) may call it; every other member gets 403.
📄️ Confirm the member's family details are current
Writes exactly the note the emailed verify link writes — type 'verify', entered by SELF_VERIFY, the text 'No Changes' or the member's comment — so a portal confirmation reaches the People → Verify dashboard the same way a token-link one does.
📄️ The photo of somebody in the signed-in member's own family (binary image)
The read side of the portal's own photo serving, for the faces on the My Family page. The id is checked against the members of the acting member's family — the same enumeration GET /portal/family renders — and anything else is 404, never 403: a 403 would confirm that the id names a real person, which a member outside that family must not learn (design P12). This is the only portal route that takes a person id, and it never names the actor.
📄️ Propose a new member of the signed-in member's family
Creates a person in the member's family marked SELF_REGISTER, exactly as the public registration form does, so the entry waits on People → Self Registrations for staff to review. It is never a live member. Only an adult of the family may call it.
Can't find what you need? Ask in Discord, or open an issue on the ChurchCRM repository.