@odla-ai/chapter 0.39.1 → 0.40.0
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/README.md +18 -5
- package/dist/{copy-context-Buz_27Ed.d.ts → copy-context-Dbu9Bbq1.d.ts} +2 -4
- package/dist/index.cjs +40 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +40 -20
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +2 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/member/index.d.ts +2 -2
- package/dist/worker/index.cjs +90 -24
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +8 -5
- package/dist/worker/index.d.ts +8 -5
- package/dist/worker/index.js +90 -24
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/runbooks/greenfield.md +21 -4
package/dist/ui/admin/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as preact from 'preact';
|
|
2
2
|
import { ComponentChildren, JSX } from 'preact';
|
|
3
3
|
import { CrmClient, Crm, CrmRecord } from '@odla-ai/crm';
|
|
4
|
-
import { a as Chapter, b as ChapterCopy, M as MemberContentDocument, E as EffectiveMemberContent, c as MemberContentTierAuthority } from '../../copy-context-
|
|
5
|
-
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-
|
|
4
|
+
import { a as Chapter, b as ChapterCopy, M as MemberContentDocument, E as EffectiveMemberContent, c as MemberContentTierAuthority } from '../../copy-context-Dbu9Bbq1.js';
|
|
5
|
+
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-Dbu9Bbq1.js';
|
|
6
6
|
import { CrmLifecycleAdapter, CrmWorkspaceMasterContext, CrmWorkspaceRecordContext, RecordPanelTab } from '@odla-ai/crm/ui';
|
|
7
7
|
|
|
8
8
|
/** Normalized public auth configuration consumed by the Clerk gate. */
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AdminAccountMenuProps, AdminBuilderLibraryData, AdminChrome, AdminMemberContentData, AdminNote, AdminPage, AdminResource, AdminRouteState, AdminRouteTarget, AdminRouting, AdminSection, AdminSectionContext, AdminWorkspace, AdminWorkspaceNavProps, AdmissionGrantsWorkspace, AvailabilitySectionOptions, BillingSectionOptions, BuilderLibraryAdmin, ChapterAdmin, ChapterAdminAuthAdapter, ChapterAdminAuthConfig, ChapterAdminAuthLoadContext, ChapterAdminProps, ChapterAdminUser, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, LeaderNetworkOverview, MeetingsSectionOptions, MemberContentAdmin, NetworkRecordsWorkspace, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, admissionGrantsWorkspace, applicationLifecycleAdapter, availabilitySection, billingSection, builderLibrarySection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, memberContentSection, networkRecordsWorkspace, peopleSection, useAdminResource } from './admin/index.js';
|
|
2
|
-
export { C as ChapterCopyProvider, u as useChapterCopy } from '../copy-context-
|
|
2
|
+
export { C as ChapterCopyProvider, u as useChapterCopy } from '../copy-context-Dbu9Bbq1.js';
|
|
3
3
|
export { ApiFn, BrandStyle, BrandStyleProps, GiftOfferCards, GiftOfferCardsMode, GiftOfferCardsProps, JoinBookingSimulation, JoinConfig, JoinFlowState, JoinIsland, JoinIslandProps, JoinSimulation, JoinStepRenderContext, JoinSubmitRenderContext, JoinTier, JoinTierRenderContext, MEMBERSHIP_CARD_TOKEN_DEFAULTS, MemberContentArea, MemberContentAreaProps, MemberGifts, MemberProvisionalRenderContext, MembersArea, MembersAreaProps, MembershipCardTokenName, MembershipCards, MembershipCardsMode, MembershipCardsProps, PaymentPriceLines, PaymentStep, PaymentStepProps, PaymentStepSimulation, RescheduleProps, Rescheduler, Slot, SlotPicker, SlotPickerClasses, SlotPickerProps, SubResponse, TierPlaceholder, dayKey, dayLabel, fmtDate, fmtMoney, fullLabel, groupSlotsByDay, loadJoinResume, membershipApplicationHref, tierNeedsPayment, timeLabel, tzShort, useTierSelection } from './member/index.js';
|
|
4
4
|
import 'preact';
|
|
5
5
|
import '@odla-ai/crm';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as preact from 'preact';
|
|
2
2
|
import { ComponentChildren, JSX } from 'preact';
|
|
3
|
-
import { d as MemberContentProjection, e as MemberContentPageProjection, b as ChapterCopy, f as ChapterBrand } from '../../copy-context-
|
|
4
|
-
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-
|
|
3
|
+
import { d as MemberContentProjection, e as MemberContentPageProjection, b as ChapterCopy, f as ChapterBrand } from '../../copy-context-Dbu9Bbq1.js';
|
|
4
|
+
export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-Dbu9Bbq1.js';
|
|
5
5
|
import { FieldType, FieldConditions } from '@odla-ai/crm';
|
|
6
6
|
|
|
7
7
|
/** A bookable slot: a start instant in epoch milliseconds. */
|
package/dist/worker/index.cjs
CHANGED
|
@@ -3382,12 +3382,16 @@ function findApplicationRef(obj) {
|
|
|
3382
3382
|
const applicationId = candidates.map(pick).find(Boolean);
|
|
3383
3383
|
const appId = candidates.map((metadata) => typeof metadata.odlaAppId === "string" ? metadata.odlaAppId : void 0).find(Boolean);
|
|
3384
3384
|
const environment = candidates.map((metadata) => typeof metadata.odlaEnvironment === "string" ? metadata.odlaEnvironment : void 0).find(Boolean);
|
|
3385
|
+
const dataEnvironment = candidates.map((metadata) => typeof metadata.odlaDataEnvironment === "string" ? metadata.odlaDataEnvironment : void 0).find(Boolean);
|
|
3386
|
+
const runtime = candidates.map((metadata) => typeof metadata.odlaRuntime === "string" ? metadata.odlaRuntime : void 0).find(Boolean);
|
|
3385
3387
|
const customerId = typeof obj.customer === "string" ? obj.customer : void 0;
|
|
3386
3388
|
return {
|
|
3387
3389
|
...applicationId ? { applicationId } : {},
|
|
3388
3390
|
...customerId ? { customerId } : {},
|
|
3389
3391
|
...appId ? { appId } : {},
|
|
3390
|
-
...environment ? { environment } : {}
|
|
3392
|
+
...environment ? { environment } : {},
|
|
3393
|
+
...dataEnvironment ? { dataEnvironment } : {},
|
|
3394
|
+
...runtime ? { runtime } : {}
|
|
3391
3395
|
};
|
|
3392
3396
|
}
|
|
3393
3397
|
function findGiftRef(obj) {
|
|
@@ -3397,17 +3401,31 @@ function findGiftRef(obj) {
|
|
|
3397
3401
|
const subscription = obj.subscription_details ?? parent?.subscription_details;
|
|
3398
3402
|
const giftIntentId = pick(metaOf(obj)) ?? pick(metaOf(subscription));
|
|
3399
3403
|
const subscriptionId = typeof obj.subscription === "string" ? obj.subscription : typeof subscription?.subscription === "string" ? String(subscription.subscription) : void 0;
|
|
3400
|
-
|
|
3404
|
+
const candidates = [metaOf(obj), metaOf(subscription)];
|
|
3405
|
+
const pickIdentity = (name) => candidates.map((metadata) => typeof metadata[name] === "string" ? String(metadata[name]) : void 0).find(Boolean);
|
|
3406
|
+
const appId = pickIdentity("odlaAppId");
|
|
3407
|
+
const environment = pickIdentity("odlaEnvironment");
|
|
3408
|
+
const dataEnvironment = pickIdentity("odlaDataEnvironment");
|
|
3409
|
+
const runtime = pickIdentity("odlaRuntime");
|
|
3410
|
+
return {
|
|
3411
|
+
...giftIntentId ? { giftIntentId } : {},
|
|
3412
|
+
providerObjectId: subscriptionId ?? String(obj.id ?? ""),
|
|
3413
|
+
...appId ? { appId } : {},
|
|
3414
|
+
...environment ? { environment } : {},
|
|
3415
|
+
...dataEnvironment ? { dataEnvironment } : {},
|
|
3416
|
+
...runtime ? { runtime } : {}
|
|
3417
|
+
};
|
|
3401
3418
|
}
|
|
3402
3419
|
function normalizeWebhookEvent(event) {
|
|
3403
3420
|
const obj = event.data?.object ?? {};
|
|
3404
3421
|
const gift = findGiftRef(obj);
|
|
3405
3422
|
if (gift.giftIntentId) {
|
|
3423
|
+
const { giftIntentId, providerObjectId, ...identity } = gift;
|
|
3406
3424
|
if (event.type === "payment_intent.succeeded" || event.type === "invoice.paid" && obj.billing_reason === "subscription_create") {
|
|
3407
|
-
return { kind: "gift_paid", giftIntentId
|
|
3425
|
+
return { kind: "gift_paid", giftIntentId, providerObjectId, ...identity };
|
|
3408
3426
|
}
|
|
3409
|
-
if (event.type === "charge.refunded") return { kind: "gift_revoked", giftIntentId
|
|
3410
|
-
if (event.type === "customer.subscription.deleted") return { kind: "gift_revoked", giftIntentId
|
|
3427
|
+
if (event.type === "charge.refunded") return { kind: "gift_revoked", giftIntentId, ...identity, reason: "refunded" };
|
|
3428
|
+
if (event.type === "customer.subscription.deleted") return { kind: "gift_revoked", giftIntentId, ...identity, reason: "canceled" };
|
|
3411
3429
|
return { kind: "ignored", type: event.type };
|
|
3412
3430
|
}
|
|
3413
3431
|
const ref = findApplicationRef(obj);
|
|
@@ -3484,7 +3502,9 @@ function createStripeProvider(config) {
|
|
|
3484
3502
|
groupId: input.groupId,
|
|
3485
3503
|
email: input.email,
|
|
3486
3504
|
odlaAppId: input.appId,
|
|
3487
|
-
odlaEnvironment: input.environment
|
|
3505
|
+
odlaEnvironment: input.environment,
|
|
3506
|
+
odlaDataEnvironment: input.environment,
|
|
3507
|
+
...input.runtime ? { odlaRuntime: input.runtime } : {}
|
|
3488
3508
|
};
|
|
3489
3509
|
let customerId = input.existingCustomerId;
|
|
3490
3510
|
if (!customerId) {
|
|
@@ -3772,12 +3792,16 @@ var clientSecret = (value) => {
|
|
|
3772
3792
|
const nested = confirmation?.client_secret ?? intent?.client_secret;
|
|
3773
3793
|
return typeof nested === "string" && nested ? nested : null;
|
|
3774
3794
|
};
|
|
3775
|
-
async function startGiftProviderCheckout(secretKey, intent, email, existingCustomerId) {
|
|
3795
|
+
async function startGiftProviderCheckout(secretKey, intent, email, existingCustomerId, runtime) {
|
|
3776
3796
|
const offer = intent.offerSnapshot;
|
|
3777
3797
|
const metadata = {
|
|
3778
3798
|
giftIntentId: intent.id,
|
|
3779
3799
|
chapterId: intent.chapterId,
|
|
3780
3800
|
environment: intent.environment,
|
|
3801
|
+
odlaAppId: intent.chapterId,
|
|
3802
|
+
odlaEnvironment: intent.environment,
|
|
3803
|
+
odlaDataEnvironment: intent.environment,
|
|
3804
|
+
...runtime ? { odlaRuntime: runtime } : {},
|
|
3781
3805
|
offerId: intent.offerId
|
|
3782
3806
|
};
|
|
3783
3807
|
let customerId = existingCustomerId;
|
|
@@ -3827,6 +3851,7 @@ async function startGiftIntent(db, input) {
|
|
|
3827
3851
|
id: input.id,
|
|
3828
3852
|
chapterId: input.chapterId,
|
|
3829
3853
|
environment: input.environment,
|
|
3854
|
+
...input.runtime ? { runtime: input.runtime } : {},
|
|
3830
3855
|
purchaserType: input.purchaserType,
|
|
3831
3856
|
purchaserEmailNormalized: input.purchaserEmailNormalized,
|
|
3832
3857
|
...input.purchaserApplicationId ? { purchaserApplicationId: input.purchaserApplicationId } : {},
|
|
@@ -3846,7 +3871,7 @@ async function startGiftIntent(db, input) {
|
|
|
3846
3871
|
stored = write.duplicate ? first2((await db.query({ giftPurchaseIntents: { $: { where: { id: input.id }, limit: 1 } } })).giftPurchaseIntents) : attrs;
|
|
3847
3872
|
if (!write.duplicate) giftCode = prepared.code;
|
|
3848
3873
|
}
|
|
3849
|
-
if (!stored || stored.chapterId !== input.chapterId || stored.environment !== input.environment || stored.offerId !== input.offer.id || stored.purchaserEmailNormalized !== input.purchaserEmailNormalized) {
|
|
3874
|
+
if (!stored || stored.chapterId !== input.chapterId || stored.environment !== input.environment || stored.runtime !== input.runtime || stored.offerId !== input.offer.id || stored.purchaserEmailNormalized !== input.purchaserEmailNormalized) {
|
|
3850
3875
|
throw new Error("gift purchase intent does not match this checkout");
|
|
3851
3876
|
}
|
|
3852
3877
|
if (stored.status === "paid") throw new Error("gift purchase is already paid");
|
|
@@ -3854,7 +3879,8 @@ async function startGiftIntent(db, input) {
|
|
|
3854
3879
|
input.stripeSecret,
|
|
3855
3880
|
stored,
|
|
3856
3881
|
input.purchaserEmail,
|
|
3857
|
-
typeof stored.providerCustomerId === "string" ? stored.providerCustomerId : input.existingCustomerId
|
|
3882
|
+
typeof stored.providerCustomerId === "string" ? stored.providerCustomerId : input.existingCustomerId,
|
|
3883
|
+
input.runtime
|
|
3858
3884
|
);
|
|
3859
3885
|
await db.transact([{ t: "update", ns: "giftPurchaseIntents", id: input.id, attrs: {
|
|
3860
3886
|
status: "checkout_ready",
|
|
@@ -3873,18 +3899,29 @@ async function startGiftIntent(db, input) {
|
|
|
3873
3899
|
};
|
|
3874
3900
|
}
|
|
3875
3901
|
|
|
3902
|
+
// src/stripe-runtime.ts
|
|
3903
|
+
function stripeWebhookSecretName(runtime) {
|
|
3904
|
+
if (!runtime) return "stripe_webhook_secret";
|
|
3905
|
+
if (!/^[a-z0-9]{2,12}$/.test(runtime) || runtime === "prod" || runtime === "production") {
|
|
3906
|
+
throw new Error("ODLA_RUNTIME is invalid");
|
|
3907
|
+
}
|
|
3908
|
+
return `stripe_webhook_secret__${runtime}`;
|
|
3909
|
+
}
|
|
3910
|
+
|
|
3911
|
+
// src/payments-route-support.ts
|
|
3912
|
+
var paymentErrorCode = (error) => error && typeof error === "object" && typeof error.code === "string" ? error.code : "unknown";
|
|
3913
|
+
function paymentLineItems(group) {
|
|
3914
|
+
const standard = Number(group.standardPriceCents ?? 0);
|
|
3915
|
+
const discount = Number(group.foundingDiscountCents ?? 0);
|
|
3916
|
+
return { standardCents: standard, discountCents: discount, dueTodayCents: standard - discount };
|
|
3917
|
+
}
|
|
3918
|
+
|
|
3876
3919
|
// src/worker-routes-payments.ts
|
|
3877
|
-
var codeOf = (err) => err && typeof err === "object" && typeof err.code === "string" ? err.code : "unknown";
|
|
3878
3920
|
async function firstRow2(db, ns, q) {
|
|
3879
3921
|
const res = await db.query({ [ns]: { $: q } });
|
|
3880
3922
|
const rows4 = res[ns];
|
|
3881
3923
|
return Array.isArray(rows4) ? rows4[0] : void 0;
|
|
3882
3924
|
}
|
|
3883
|
-
function lineItems(group) {
|
|
3884
|
-
const standard = Number(group.standardPriceCents ?? 0);
|
|
3885
|
-
const discount = Number(group.foundingDiscountCents ?? 0);
|
|
3886
|
-
return { standardCents: standard, discountCents: discount, dueTodayCents: standard - discount };
|
|
3887
|
-
}
|
|
3888
3925
|
async function findApplication(db, event) {
|
|
3889
3926
|
if ("applicationId" in event && event.applicationId) {
|
|
3890
3927
|
return firstRow2(db, "applications", { where: { id: event.applicationId }, limit: 1 });
|
|
@@ -3975,6 +4012,7 @@ async function startSubscription(req, env, ctx) {
|
|
|
3975
4012
|
chapterId: ctx.chapter.id,
|
|
3976
4013
|
environment: env.ODLA_ENV,
|
|
3977
4014
|
offer,
|
|
4015
|
+
...env.ODLA_RUNTIME ? { runtime: env.ODLA_RUNTIME } : {},
|
|
3978
4016
|
purchaserType: "application",
|
|
3979
4017
|
purchaserEmail: String(app.email ?? ""),
|
|
3980
4018
|
purchaserEmailNormalized: normalizeChapterEmail(String(app.email ?? "")),
|
|
@@ -4007,6 +4045,7 @@ async function startSubscription(req, env, ctx) {
|
|
|
4007
4045
|
result = await provider.createSubscription({
|
|
4008
4046
|
appId: env.ODLA_APP_ID,
|
|
4009
4047
|
environment: env.ODLA_ENV,
|
|
4048
|
+
...env.ODLA_RUNTIME ? { runtime: env.ODLA_RUNTIME } : {},
|
|
4010
4049
|
applicationId,
|
|
4011
4050
|
groupId: String(group.id),
|
|
4012
4051
|
email: String(app.email ?? ""),
|
|
@@ -4015,29 +4054,35 @@ async function startSubscription(req, env, ctx) {
|
|
|
4015
4054
|
existingCustomerId: typeof app.stripeCustomerId === "string" ? app.stripeCustomerId : void 0
|
|
4016
4055
|
});
|
|
4017
4056
|
} catch (err) {
|
|
4018
|
-
return json({ error: "payment setup failed", code:
|
|
4057
|
+
return json({ error: "payment setup failed", code: paymentErrorCode(err) }, 502);
|
|
4019
4058
|
}
|
|
4020
4059
|
await db.transact([
|
|
4021
4060
|
{
|
|
4022
4061
|
t: "update",
|
|
4023
4062
|
ns: "applications",
|
|
4024
4063
|
id: applicationId,
|
|
4025
|
-
attrs: {
|
|
4064
|
+
attrs: {
|
|
4065
|
+
stripeCustomerId: result.customerId,
|
|
4066
|
+
stripeSubscriptionId: result.subscriptionId,
|
|
4067
|
+
...env.ODLA_RUNTIME ? { stripeRuntime: env.ODLA_RUNTIME } : {},
|
|
4068
|
+
refundPolicyAckAt: Date.now()
|
|
4069
|
+
}
|
|
4026
4070
|
}
|
|
4027
4071
|
]);
|
|
4028
|
-
return json({ clientSecret: result.clientSecret, publishableKey: group.stripePublishableKey ?? null, lineItems:
|
|
4072
|
+
return json({ clientSecret: result.clientSecret, publishableKey: group.stripePublishableKey ?? null, lineItems: paymentLineItems(group) });
|
|
4029
4073
|
}
|
|
4030
4074
|
async function ingestWebhook(req, env, ctx) {
|
|
4031
4075
|
const db = ctx.makeDb(env);
|
|
4032
|
-
const webhookSecret = await getVaultSecret(db,
|
|
4076
|
+
const webhookSecret = await getVaultSecret(db, stripeWebhookSecretName(env.ODLA_RUNTIME));
|
|
4033
4077
|
if (!webhookSecret) return json({ error: "webhook not configured" }, 503);
|
|
4034
4078
|
const rawBody = await req.text();
|
|
4035
4079
|
const ingest = await createStripeProvider({ webhookSecret }).ingestWebhook(rawBody, req.headers.get("stripe-signature") ?? "");
|
|
4036
4080
|
if (!ingest.ok) return json({ error: "invalid signature" }, 400);
|
|
4037
4081
|
const { eventId, event } = ingest;
|
|
4038
4082
|
if (event.kind === "ignored") return json({ ok: true, ignored: event.type });
|
|
4039
|
-
const identifiedEnvironment = event.appId !== void 0 || event.environment !== void 0;
|
|
4040
|
-
|
|
4083
|
+
const identifiedEnvironment = event.appId !== void 0 || event.environment !== void 0 || event.dataEnvironment !== void 0 || event.runtime !== void 0;
|
|
4084
|
+
const eventDataEnvironment = event.dataEnvironment ?? event.environment;
|
|
4085
|
+
if (env.ODLA_APP_ID && identifiedEnvironment && (event.appId !== env.ODLA_APP_ID || eventDataEnvironment !== env.ODLA_ENV || event.runtime !== void 0 && event.runtime !== env.ODLA_RUNTIME)) {
|
|
4041
4086
|
return json({ ok: true, matched: false });
|
|
4042
4087
|
}
|
|
4043
4088
|
if (event.kind === "gift_paid" || event.kind === "gift_revoked") {
|
|
@@ -4045,6 +4090,9 @@ async function ingestWebhook(req, env, ctx) {
|
|
|
4045
4090
|
if (!intent || intent.chapterId !== ctx.chapter.id || intent.environment !== env.ODLA_ENV) {
|
|
4046
4091
|
return json({ ok: true, matched: false });
|
|
4047
4092
|
}
|
|
4093
|
+
if (event.runtime === void 0 && typeof intent.runtime === "string" && intent.runtime !== env.ODLA_RUNTIME) {
|
|
4094
|
+
return json({ ok: true, matched: false });
|
|
4095
|
+
}
|
|
4048
4096
|
if (event.kind === "gift_paid") {
|
|
4049
4097
|
if (intent.providerObjectId !== event.providerObjectId) return json({ ok: true, matched: false });
|
|
4050
4098
|
if (intent.status === "refunded" || intent.status === "canceled") return json({ ok: true, matched: false });
|
|
@@ -4068,6 +4116,9 @@ async function ingestWebhook(req, env, ctx) {
|
|
|
4068
4116
|
}
|
|
4069
4117
|
const app = await findApplication(db, event);
|
|
4070
4118
|
if (!app) return json({ ok: true, matched: false });
|
|
4119
|
+
if (event.runtime === void 0 && typeof app.stripeRuntime === "string" && app.stripeRuntime !== env.ODLA_RUNTIME) {
|
|
4120
|
+
return json({ ok: true, matched: false });
|
|
4121
|
+
}
|
|
4071
4122
|
const patch = webhookPatch(event, String(app.status ?? ""));
|
|
4072
4123
|
let next = app;
|
|
4073
4124
|
if (Object.keys(patch).length) {
|
|
@@ -4170,6 +4221,7 @@ var handleGifts = async (req, url, env, ctx) => {
|
|
|
4170
4221
|
offer,
|
|
4171
4222
|
purchaserType: "member",
|
|
4172
4223
|
purchaserEmail: user.email,
|
|
4224
|
+
...env.ODLA_RUNTIME ? { runtime: env.ODLA_RUNTIME } : {},
|
|
4173
4225
|
purchaserEmailNormalized: emailNormalized,
|
|
4174
4226
|
purchaserUserId: user.userId,
|
|
4175
4227
|
...typeof app?.stripeCustomerId === "string" ? { existingCustomerId: app.stripeCustomerId } : {},
|
|
@@ -6098,9 +6150,23 @@ async function saveLocalBuilderLibrary(db, document, environment, expectedRevisi
|
|
|
6098
6150
|
|
|
6099
6151
|
// src/worker-routes-builder-library.ts
|
|
6100
6152
|
var BODY_CAP2 = 1e6;
|
|
6101
|
-
async function verifySource(req, db,
|
|
6153
|
+
async function verifySource(req, db, ctx) {
|
|
6154
|
+
const sources = ctx.chapter.builderLibrary?.sources ?? [];
|
|
6155
|
+
if (ctx.chapter.mode === "chapter") {
|
|
6156
|
+
const secret = await getVaultSecret(db, "network_share_secret");
|
|
6157
|
+
if (!secret) return null;
|
|
6158
|
+
const verified = await (0, import_db10.verifyFederatedRequest)(req, {
|
|
6159
|
+
secret,
|
|
6160
|
+
senders: sources.map((source2) => source2.sourceId)
|
|
6161
|
+
});
|
|
6162
|
+
if (!verified.ok) return null;
|
|
6163
|
+
const source = sources.find((candidate) => candidate.sourceId === verified.sender);
|
|
6164
|
+
return source ? { source, body: verified.body } : null;
|
|
6165
|
+
}
|
|
6102
6166
|
for (const source of sources) {
|
|
6103
|
-
const
|
|
6167
|
+
const target = ctx.chapter.network.targets.find((candidate) => candidate.id === source.sourceId);
|
|
6168
|
+
if (!target) continue;
|
|
6169
|
+
const secret = await getVaultSecret(db, target.secretName);
|
|
6104
6170
|
if (!secret) continue;
|
|
6105
6171
|
const verified = await (0, import_db10.verifyFederatedRequest)(req.clone(), { secret, senders: [source.sourceId] });
|
|
6106
6172
|
if (verified.ok) return { source, body: verified.body };
|
|
@@ -6112,7 +6178,7 @@ var handleBuilderLibraryControl = async (req, url, env, ctx) => {
|
|
|
6112
6178
|
const settings = ctx.chapter.builderLibrary;
|
|
6113
6179
|
if (!settings) return json({ error: "not found" }, 404);
|
|
6114
6180
|
const db = ctx.makeDb(env);
|
|
6115
|
-
const verified = await verifySource(req, db,
|
|
6181
|
+
const verified = await verifySource(req, db, ctx);
|
|
6116
6182
|
if (!verified) return json({ error: "unauthorized" }, 401);
|
|
6117
6183
|
let input;
|
|
6118
6184
|
try {
|