@cosmicdrift/kumiko-samples 0.348.0 → 0.348.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-samples",
|
|
3
|
-
"version": "0.348.
|
|
3
|
+
"version": "0.348.1",
|
|
4
4
|
"description": "Source trees of the Kumiko sample recipes, sample apps and bundled features in repo layout, for tooling such as few-shot corpus builds.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-bundled-features",
|
|
3
|
-
"version": "0.348.
|
|
3
|
+
"version": "0.348.1",
|
|
4
4
|
"description": "Built-in features — tenant, user, auth, delivery. The stuff you'd rewrite anyway, already typed.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.348.1",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "Email channel decrypts the resolved recipient address so notify to users and tenants works with an active KMS",
|
|
6
|
+
"detail": "Email notifications to resolved users reach the plaintext address under an active KMS\nWith an active PII KMS, an app's `resolveEmail` that reads the stored `user.email` returns ciphertext, and the PII guard rightly refused to send it (`recipient address is a PII ciphertext`). That broke every `notify` target that resolves an address from a user id: a single user, a list of users and `{ tenant }`. The email channel now decrypts the resolved address (`decryptStoredPii`, a no-op without KMS or for plaintext) before it is used for delivery, opt-out checks and the attempt log. The guard is unchanged.",
|
|
7
|
+
"migration": "No action needed. Apps whose resolveEmail returns the raw stored user.email now send to the plaintext address instead of failing with \"recipient address is a PII ciphertext\"."
|
|
8
|
+
},
|
|
2
9
|
{
|
|
3
10
|
"version": "0.342.0",
|
|
4
11
|
"type": "improvement",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PII_ERASED_SENTINEL } from "@cosmicdrift/kumiko-framework/crypto";
|
|
1
2
|
import type { DbRow } from "@cosmicdrift/kumiko-framework/db";
|
|
2
3
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
4
|
import {
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
type NotificationRenderer,
|
|
9
10
|
type RenderedMessage,
|
|
10
11
|
} from "../delivery/index.js";
|
|
12
|
+
import { decryptStoredPii } from "../shared/index.js";
|
|
11
13
|
import { guardEmailMessage } from "./pii-guard.js";
|
|
12
14
|
import type { EmailTransport } from "./types.js";
|
|
13
15
|
|
|
@@ -117,8 +119,12 @@ export function createEmailChannel(options: EmailChannelOptions): DeliveryChanne
|
|
|
117
119
|
name: "email",
|
|
118
120
|
mode: "queued",
|
|
119
121
|
|
|
122
|
+
// resolveEmail typically returns the raw stored user.email, which is ciphertext under an active KMS.
|
|
120
123
|
async resolve(userId, ctx) {
|
|
121
|
-
|
|
124
|
+
const stored = await resolveEmail(userId, ctx);
|
|
125
|
+
if (stored === null) return null;
|
|
126
|
+
const address = await decryptStoredPii(stored, "email", "channel-email:resolve");
|
|
127
|
+
return address === PII_ERASED_SENTINEL ? null : address;
|
|
122
128
|
},
|
|
123
129
|
|
|
124
130
|
render(message, _ctx) {
|