📧 Invitation
Invitation は、管理者のみの招待作成・検索・一覧表示・削除を authService に追加します。招待の作成時にはワンタイムトークンが生成され、メールが送信されます。
ここから始める
authService がソース提供の統合ポイントです。すべての Invitation ルートは実行時に identities と invitations コレクションを必要としますが、invitations はサービス TypeScript インターフェースではオプションです。作成時にはさらに onetimetokens と 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: '${url} を開いてください',
sender: 'noreply@example.test',
subject: 'あなたの招待',
urlTemplate: 'https://app.example.test/invite?token=${token}',
},
},
},
{mailService},
),
);
| 設定 | デフォルト / ソースの動作 | 効果 |
|---|---|---|
dataStores.identities | 実行時に必須 | checkIdentityType(['admin']) が呼び出し元のアイデンティティを読み込みます。 |
dataStores.invitations | 実行時に必須 | Invitation ハンドラーによって読み書きされます。 |
dataStores.onetimetokens | 作成時にのみ必須 | generateOnetimeToken によって使用されます。 |
configuration.authSecrets | 保護されたアクセス/トークン操作に必須 | Authentication サービスを通過します。 |
configuration.identity.typeIds.admin | これらのルートに必須 | checkIdentityType(['admin']) によって読み込まれます。 |
configuration.invitation.enabled | 作成時にのみ必須 | 真理値でない場合、配信は 500 エラーになります。 |
invitation.emailConfig.bodyTemplate, subject, urlTemplate | 作成時にのみ必須 | すべて真理値である必要があり、そうでなければ配信は 500 エラーになります。sender は sendMail() に渡されますが、実行時チェックはありません。 |
options.mailService | 作成時にのみ必須 | 招待メールを送信します。 |
configuration.authMode | 省略時は Bearer | 'cookie' はクッキートークンの読み取りを選択します。 |
選択されたアダプターはいずれもアクセストークンを必要とします。ユーザーアクセストークンの場合、常にリクエスト指紋を比較します。デフォルトの configuration.checkIp 動作では、IP の不一致はユーザーエージェントの一致も要求します。checkIp: false を設定すると、その IP/ユーザーエージェントブランチをスキップします。アダプターはリクエストホストを収集しますが、現在のセキュリティチェック関数は管理者タイプチェック前にそれを比較しません。
一般的なタスク
| タスク | 起点 | 契約 |
|---|---|---|
| 招待を作成しメールで送信 | createInvitationFeature | createInvitationFeature、createInvitationRoute、createInvitationSchema |
| 招待を一覧表示 | findInvitationsFeature | findInvitationsFeature、findInvitationsRoute、findInvitationsSchema |
| 招待を取得 | getInvitationFeature | getInvitationFeature、getInvitationByIdRoute、getInvitationSchema |
| 招待を削除 | deleteInvitationFeature | deleteInvitationFeature、deleteInvitationRoute、deleteInvitationSchema |
Bearer HTTP ワークフロー
上記のマウントされたサービスでは、Authorization: Bearer <admin-access-token> と createInvitationSchema に一致するボディで POST /api/invitations を送信します。OpenAPI 契約は application/json を宣言します;現在のランタイムバリデータはヘッダーを検査するのではなく解析されたボディを検証し、スキーマ失敗時に 400 Validation Error を報告します。createInvitationRoute はメール配信後に 201 と { invitationId } を返します。共有バリデータは認証済み管理者を要求します。不完全なメール設定は 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 ワークフロー
authMode: 'cookie' の場合、サービスルーターの前に cookie-parser をインストールし、Bearer ヘッダーの代わりに accessToken クッキーを使用して、同じ createInvitationSchema ボディを同じエンドポイントで送信します。必要な管理者アクセスと 201 応答は createInvitationRoute のものに準じます。クッキーが欠如している場合、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"}'
カスタム feature 合成
この断片はパブリック SDK composer を使用します。dataStores が identities、invitations、onetimetokens を含むこと;configuration が有効な auth シークレット、identity.typeIds.admin、および有効化された招待メール設定を含む services.getMergedAuthConfig(...) の結果であること;mailService が利用可能であることを想定します。スタンドアロンの合成でも保護されたルートを公開するため、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 はパブリック HTTP ルートを所有していません。パブリック registerCredentialsRoute は Authentication に属し、登録中に招待トークンを条件付きで検証して受け入れます。
リファレンスマップ
| ページ | 目的 |
|---|---|
| Handlers | ルートパイプライン操作とターミネーター。 |
| Features | Authentication によってマウントされるスキーマからルートへの composer。 |
| Routes | エンドポイント、アクセス、応答契約。 |
| Schemas | リクエスト検証契約。 |
Invitation には blocks.md または validators.md ページがありません;管理者チェックは Authentication validators で文書化されています。
関連モジュール
Authentication は包含サービスと招待トークンを受け入れるパブリック登録フローを提供します。Authentication service はサービス設定を定義します。Mail-service drivers は配信依存性を提供します。Authentication validators は共有管理者アクセスチェックを文書化します。Auth utilities と cookie utilities は選択されたアクセストークン転送を説明します。