📧 Invitation
Invitation adds administrator-only invitation creation, lookup, listing, and deletion to authService; creating an invitation also creates a one-time token and delivers an email.
Start here
authService is the source-provided integration point. Every Invitation route needs the identities and invitations collections at runtime, although invitations is optional in the service TypeScript interface; creation additionally reaches onetimetokens and mailService.
import express from 'express';
import {services} from '@nodeblocks/backend-sdk';
const app = express();
app.use(express.json());
app.use(
'/api',
services.authService(
{identities, invitations, onetimetokens},
{
authSecrets: {authEncSecret: 'replace-me', authSignSecret: 'replace-me'},
identity: {typeIds: {admin: 'admin-type-id', guest: 'guest-type-id', regular: 'regular-type-id'}},
invitation: {
enabled: true,
emailConfig: {
bodyTemplate: 'Open ${url}',
sender: 'noreply@example.test',
subject: 'Your invitation',
urlTemplate: 'https://app.example.test/invite?token=${token}',
},
},
},
{mailService},
),
);
| Configuration | Default / source behavior | Effect |
|---|---|---|
dataStores.identities | Required at runtime | checkIdentityType(['admin']) loads the caller identity. |
dataStores.invitations | Required at runtime | Read and written by Invitation handlers. |
dataStores.onetimetokens | Required for create only | Used by generateOnetimeToken. |
configuration.authSecrets | Required for protected access/token operations | Passed through the Authentication service. |
configuration.identity.typeIds.admin | Required for these routes | Read by checkIdentityType(['admin']). |
configuration.invitation.enabled | Required for create only | Delivery fails with 500 unless it is truthy. |
invitation.emailConfig.bodyTemplate, subject, urlTemplate | Required for create only | Each must be truthy or delivery fails with 500. sender is passed to sendMail() but is not runtime-checked. |
options.mailService | Required for create only | Sends the invitation email. |
configuration.authMode | Omitted means Bearer | 'cookie' selects cookie token reading. |
Both selected adapters require an access token. For user access tokens they always compare the request fingerprint. With the default configuration.checkIp behavior, an IP mismatch also requires a matching user agent; setting checkIp: false skips that IP/user-agent branch. The adapters collect the request host, but the current security-check function does not compare it before the administrator-type check.
Common tasks
| Task | Start with | Contract |
|---|---|---|
| Create and email an invitation | createInvitationFeature | createInvitationFeature, createInvitationRoute, createInvitationSchema |
| List invitations | findInvitationsFeature | findInvitationsFeature, findInvitationsRoute, findInvitationsSchema |
| Retrieve an invitation | getInvitationFeature | getInvitationFeature, getInvitationByIdRoute, getInvitationSchema |
| Delete an invitation | deleteInvitationFeature | deleteInvitationFeature, deleteInvitationRoute, deleteInvitationSchema |
Bearer HTTP workflow
With the mounted service above, send POST /api/invitations with Authorization: Bearer <admin-access-token> and a body matching createInvitationSchema. The OpenAPI contract declares application/json; its current runtime validator validates the parsed body rather than inspecting the header. createInvitationRoute returns 201 and { invitationId } after email delivery. The shared validators require an authenticated administrator; incomplete mail configuration produces 500.
export API_BASE_URL='http://localhost:8080/api'
export ACCESS_TOKEN='replace-with-an-admin-access-token'
curl -X POST "$API_BASE_URL/invitations" \
-H "authorization: Bearer $ACCESS_TOKEN" \
-H 'content-type: application/json' \
-d '{"email":"invitee@example.test","fromIdentityId":"admin-id"}'
Cookie HTTP workflow
When authMode: 'cookie', install cookie-parser before the service router and send the same createInvitationSchema body with an accessToken cookie instead of the Bearer header. The endpoint, required administrator access, and 201 response remain those of createInvitationRoute. A missing cookie is 401 Unable to detect access token.
export API_BASE_URL='http://localhost:8080/api'
export ACCESS_COOKIE='accessToken=replace-with-an-admin-access-token'
curl -X POST "$API_BASE_URL/invitations" \
-H "cookie: $ACCESS_COOKIE" \
-H 'content-type: application/json' \
-d '{"email":"invitee@example.test","fromIdentityId":"admin-id"}'
Custom feature composition
This fragment uses the public SDK composers. It assumes dataStores contains identities, invitations, and onetimetokens; configuration is a services.getMergedAuthConfig(...) result containing valid auth secrets, identity.typeIds.admin, and enabled invitation email configuration; and mailService is available. A standalone composition still exposes protected routes, so it must provide authenticate.
import {partial} from 'ramda';
import {features, primitives, services, utils} from '@nodeblocks/backend-sdk';
const configuration = services.getMergedAuthConfig(invitationConfiguration);
const invitationService = primitives.defService(
partial(
primitives.compose(
features.createInvitationFeature,
features.findInvitationsFeature,
features.getInvitationFeature,
features.deleteInvitationFeature,
),
[{authenticate: utils.getBearerTokenInfo, configuration, dataStores, mailService}],
),
);
app.use('/api', invitationService);
Invitation owns no public HTTP route. The public registerCredentialsRoute belongs to Authentication and conditionally validates and accepts an invitation token during registration.
Reference map
| Page | Purpose |
|---|---|
| Handlers | Route-pipeline operations and terminators. |
| Features | Schema-to-route composers mounted by Authentication. |
| Routes | Endpoint, access, and response contracts. |
| Schemas | Request validation contracts. |
Invitation has no blocks.md or validators.md page; administrator checks are documented in Authentication validators.
Related modules
Authentication provides the containing service and the public registration flow that accepts an invitation token. Authentication service defines service configuration. Mail-service drivers provide the delivery dependency. Authentication validators document the shared administrator access checks. Auth utilities and cookie utilities describe the selected access-token transports.