@feelflow/ffid-sdk 5.7.0 → 5.9.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/dist/{chunk-FXIDKFXQ.cjs → chunk-A6MOPB7D.cjs} +33 -6
- package/dist/{chunk-YAJN36SD.js → chunk-KENJXMSG.js} +33 -6
- package/dist/components/index.cjs +8 -8
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/{ffid-client-CknwTgly.d.cts → ffid-client-DRjzfAaS.d.cts} +36 -4
- package/dist/{ffid-client-C0k2PTbO.d.ts → ffid-client-gboJROw0.d.ts} +36 -4
- package/dist/{index-EFp_ZgK9.d.cts → index-DSvX4q8E.d.cts} +49 -19
- package/dist/{index-EFp_ZgK9.d.ts → index-DSvX4q8E.d.ts} +49 -19
- package/dist/index.cjs +36 -36
- package/dist/index.d.cts +15 -13
- package/dist/index.d.ts +15 -13
- package/dist/index.js +2 -2
- package/dist/server/index.cjs +33 -6
- package/dist/server/index.d.cts +3 -3
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +33 -6
- package/dist/server/test/index.d.cts +2 -2
- package/dist/server/test/index.d.ts +2 -2
- package/dist/{types-s3y11uT6.d.cts → types-BYdtyO_2.d.cts} +12 -16
- package/dist/{types-s3y11uT6.d.ts → types-BYdtyO_2.d.ts} +12 -16
- package/dist/webhooks/index.d.cts +1 -1
- package/dist/webhooks/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -111,7 +111,16 @@ var SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES = [
|
|
|
111
111
|
function isSessionEligibleSubscriptionStatus(value) {
|
|
112
112
|
return typeof value === "string" && SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES.includes(value);
|
|
113
113
|
}
|
|
114
|
+
function hasOwnKey(value, key) {
|
|
115
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
116
|
+
}
|
|
114
117
|
function normalizeUserinfo(raw) {
|
|
118
|
+
const hasOrganizationId = hasOwnKey(raw, "organization_id");
|
|
119
|
+
const hasOrganizationName = hasOwnKey(raw, "organization_name");
|
|
120
|
+
const organizationFields = hasOrganizationId ? {
|
|
121
|
+
organizationId: raw.organization_id ?? null,
|
|
122
|
+
organizationName: hasOrganizationName ? raw.organization_name ?? null : null
|
|
123
|
+
} : hasOrganizationName ? { organizationName: raw.organization_name ?? null } : {};
|
|
115
124
|
return {
|
|
116
125
|
sub: raw.sub,
|
|
117
126
|
email: raw.email,
|
|
@@ -121,7 +130,7 @@ function normalizeUserinfo(raw) {
|
|
|
121
130
|
department: raw.department ?? null,
|
|
122
131
|
position: raw.position ?? null,
|
|
123
132
|
phoneNumber: raw.phone_number ?? null,
|
|
124
|
-
|
|
133
|
+
...organizationFields,
|
|
125
134
|
subscription: raw.subscription ? {
|
|
126
135
|
subscriptionId: raw.subscription.subscription_id ?? null,
|
|
127
136
|
status: raw.subscription.status ?? null,
|
|
@@ -130,7 +139,16 @@ function normalizeUserinfo(raw) {
|
|
|
130
139
|
seatModel: raw.subscription.seat_model ?? null,
|
|
131
140
|
memberRole: raw.subscription.member_role ?? null,
|
|
132
141
|
organizationId: raw.subscription.organization_id ?? null,
|
|
133
|
-
|
|
142
|
+
organizationName: hasOwnKey(raw.subscription, "organization_name") ? raw.subscription.organization_name ?? null : null,
|
|
143
|
+
hasSeatAssignment: raw.subscription.has_seat_assignment ?? false,
|
|
144
|
+
// #3464: legacy FFID (< this issue) omits the field on the wire.
|
|
145
|
+
// The "unknown" axis is unused — no consumer differentiates "server
|
|
146
|
+
// didn't tell us" from "definitely not scheduled" because the
|
|
147
|
+
// companion `effectiveStatus` already returns `'active'` (not
|
|
148
|
+
// `'active_canceling'`) for legacy backends. Defaulting to `false`
|
|
149
|
+
// here keeps the downstream contract a plain boolean.
|
|
150
|
+
cancelAtPeriodEnd: raw.subscription.cancel_at_period_end ?? false,
|
|
151
|
+
currentPeriodEnd: raw.subscription.current_period_end ?? null
|
|
134
152
|
} : void 0
|
|
135
153
|
};
|
|
136
154
|
}
|
|
@@ -147,11 +165,18 @@ function mapUserinfoSubscriptionToSession(userinfo, serviceCode) {
|
|
|
147
165
|
planCode: subscription.planCode,
|
|
148
166
|
planName: subscription.planCode,
|
|
149
167
|
status: subscription.status,
|
|
150
|
-
|
|
168
|
+
// #3464: userinfo now carries `current_period_end` and
|
|
169
|
+
// `cancel_at_period_end`. Pre-#3464 FFID backends still omit them on
|
|
170
|
+
// the wire (`currentPeriodEnd === null` / `cancelAtPeriodEnd === false`
|
|
171
|
+
// after `normalizeUserinfo` defaults), so the session helper sees
|
|
172
|
+
// plain `'active'` — identical to pre-#3464 behaviour.
|
|
173
|
+
currentPeriodEnd: subscription.currentPeriodEnd,
|
|
151
174
|
trialEnd: null,
|
|
175
|
+
cancelAtPeriodEnd: subscription.cancelAtPeriodEnd,
|
|
152
176
|
seatModel: subscription.seatModel ?? void 0,
|
|
153
177
|
memberRole: subscription.memberRole ?? void 0,
|
|
154
|
-
organizationId: subscription.organizationId
|
|
178
|
+
organizationId: subscription.organizationId,
|
|
179
|
+
organizationName: subscription.organizationName ?? void 0
|
|
155
180
|
}
|
|
156
181
|
];
|
|
157
182
|
}
|
|
@@ -360,7 +385,8 @@ function createVerifyAccessToken(deps) {
|
|
|
360
385
|
department: introspectResponse.department ?? null,
|
|
361
386
|
position: introspectResponse.position ?? null,
|
|
362
387
|
phone_number: introspectResponse.phone_number ?? null,
|
|
363
|
-
organization_id: introspectResponse.organization_id ?? null
|
|
388
|
+
organization_id: introspectResponse.organization_id ?? null,
|
|
389
|
+
organization_name: introspectResponse.organization_name ?? null
|
|
364
390
|
};
|
|
365
391
|
const raw = introspectResponse.subscription ? {
|
|
366
392
|
...base,
|
|
@@ -372,6 +398,7 @@ function createVerifyAccessToken(deps) {
|
|
|
372
398
|
seat_model: introspectResponse.subscription.seat_model,
|
|
373
399
|
member_role: introspectResponse.subscription.member_role,
|
|
374
400
|
organization_id: introspectResponse.subscription.organization_id,
|
|
401
|
+
organization_name: introspectResponse.subscription.organization_name ?? null,
|
|
375
402
|
has_seat_assignment: introspectResponse.subscription.has_seat_assignment ?? false
|
|
376
403
|
}
|
|
377
404
|
} : base;
|
|
@@ -842,7 +869,7 @@ function createProfileMethods(deps) {
|
|
|
842
869
|
}
|
|
843
870
|
|
|
844
871
|
// src/client/version-check.ts
|
|
845
|
-
var SDK_VERSION = "5.
|
|
872
|
+
var SDK_VERSION = "5.9.0";
|
|
846
873
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
847
874
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
848
875
|
function sdkHeaders() {
|
|
@@ -109,7 +109,16 @@ var SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES = [
|
|
|
109
109
|
function isSessionEligibleSubscriptionStatus(value) {
|
|
110
110
|
return typeof value === "string" && SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES.includes(value);
|
|
111
111
|
}
|
|
112
|
+
function hasOwnKey(value, key) {
|
|
113
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
114
|
+
}
|
|
112
115
|
function normalizeUserinfo(raw) {
|
|
116
|
+
const hasOrganizationId = hasOwnKey(raw, "organization_id");
|
|
117
|
+
const hasOrganizationName = hasOwnKey(raw, "organization_name");
|
|
118
|
+
const organizationFields = hasOrganizationId ? {
|
|
119
|
+
organizationId: raw.organization_id ?? null,
|
|
120
|
+
organizationName: hasOrganizationName ? raw.organization_name ?? null : null
|
|
121
|
+
} : hasOrganizationName ? { organizationName: raw.organization_name ?? null } : {};
|
|
113
122
|
return {
|
|
114
123
|
sub: raw.sub,
|
|
115
124
|
email: raw.email,
|
|
@@ -119,7 +128,7 @@ function normalizeUserinfo(raw) {
|
|
|
119
128
|
department: raw.department ?? null,
|
|
120
129
|
position: raw.position ?? null,
|
|
121
130
|
phoneNumber: raw.phone_number ?? null,
|
|
122
|
-
|
|
131
|
+
...organizationFields,
|
|
123
132
|
subscription: raw.subscription ? {
|
|
124
133
|
subscriptionId: raw.subscription.subscription_id ?? null,
|
|
125
134
|
status: raw.subscription.status ?? null,
|
|
@@ -128,7 +137,16 @@ function normalizeUserinfo(raw) {
|
|
|
128
137
|
seatModel: raw.subscription.seat_model ?? null,
|
|
129
138
|
memberRole: raw.subscription.member_role ?? null,
|
|
130
139
|
organizationId: raw.subscription.organization_id ?? null,
|
|
131
|
-
|
|
140
|
+
organizationName: hasOwnKey(raw.subscription, "organization_name") ? raw.subscription.organization_name ?? null : null,
|
|
141
|
+
hasSeatAssignment: raw.subscription.has_seat_assignment ?? false,
|
|
142
|
+
// #3464: legacy FFID (< this issue) omits the field on the wire.
|
|
143
|
+
// The "unknown" axis is unused — no consumer differentiates "server
|
|
144
|
+
// didn't tell us" from "definitely not scheduled" because the
|
|
145
|
+
// companion `effectiveStatus` already returns `'active'` (not
|
|
146
|
+
// `'active_canceling'`) for legacy backends. Defaulting to `false`
|
|
147
|
+
// here keeps the downstream contract a plain boolean.
|
|
148
|
+
cancelAtPeriodEnd: raw.subscription.cancel_at_period_end ?? false,
|
|
149
|
+
currentPeriodEnd: raw.subscription.current_period_end ?? null
|
|
132
150
|
} : void 0
|
|
133
151
|
};
|
|
134
152
|
}
|
|
@@ -145,11 +163,18 @@ function mapUserinfoSubscriptionToSession(userinfo, serviceCode) {
|
|
|
145
163
|
planCode: subscription.planCode,
|
|
146
164
|
planName: subscription.planCode,
|
|
147
165
|
status: subscription.status,
|
|
148
|
-
|
|
166
|
+
// #3464: userinfo now carries `current_period_end` and
|
|
167
|
+
// `cancel_at_period_end`. Pre-#3464 FFID backends still omit them on
|
|
168
|
+
// the wire (`currentPeriodEnd === null` / `cancelAtPeriodEnd === false`
|
|
169
|
+
// after `normalizeUserinfo` defaults), so the session helper sees
|
|
170
|
+
// plain `'active'` — identical to pre-#3464 behaviour.
|
|
171
|
+
currentPeriodEnd: subscription.currentPeriodEnd,
|
|
149
172
|
trialEnd: null,
|
|
173
|
+
cancelAtPeriodEnd: subscription.cancelAtPeriodEnd,
|
|
150
174
|
seatModel: subscription.seatModel ?? void 0,
|
|
151
175
|
memberRole: subscription.memberRole ?? void 0,
|
|
152
|
-
organizationId: subscription.organizationId
|
|
176
|
+
organizationId: subscription.organizationId,
|
|
177
|
+
organizationName: subscription.organizationName ?? void 0
|
|
153
178
|
}
|
|
154
179
|
];
|
|
155
180
|
}
|
|
@@ -358,7 +383,8 @@ function createVerifyAccessToken(deps) {
|
|
|
358
383
|
department: introspectResponse.department ?? null,
|
|
359
384
|
position: introspectResponse.position ?? null,
|
|
360
385
|
phone_number: introspectResponse.phone_number ?? null,
|
|
361
|
-
organization_id: introspectResponse.organization_id ?? null
|
|
386
|
+
organization_id: introspectResponse.organization_id ?? null,
|
|
387
|
+
organization_name: introspectResponse.organization_name ?? null
|
|
362
388
|
};
|
|
363
389
|
const raw = introspectResponse.subscription ? {
|
|
364
390
|
...base,
|
|
@@ -370,6 +396,7 @@ function createVerifyAccessToken(deps) {
|
|
|
370
396
|
seat_model: introspectResponse.subscription.seat_model,
|
|
371
397
|
member_role: introspectResponse.subscription.member_role,
|
|
372
398
|
organization_id: introspectResponse.subscription.organization_id,
|
|
399
|
+
organization_name: introspectResponse.subscription.organization_name ?? null,
|
|
373
400
|
has_seat_assignment: introspectResponse.subscription.has_seat_assignment ?? false
|
|
374
401
|
}
|
|
375
402
|
} : base;
|
|
@@ -840,7 +867,7 @@ function createProfileMethods(deps) {
|
|
|
840
867
|
}
|
|
841
868
|
|
|
842
869
|
// src/client/version-check.ts
|
|
843
|
-
var SDK_VERSION = "5.
|
|
870
|
+
var SDK_VERSION = "5.9.0";
|
|
844
871
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
845
872
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
846
873
|
function sdkHeaders() {
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkA6MOPB7D_cjs = require('../chunk-A6MOPB7D.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "FFIDAnnouncementBadge", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkA6MOPB7D_cjs.FFIDAnnouncementBadge; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "FFIDAnnouncementList", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkA6MOPB7D_cjs.FFIDAnnouncementList; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "FFIDInquiryForm", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkA6MOPB7D_cjs.FFIDInquiryForm; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "FFIDLoginButton", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkA6MOPB7D_cjs.FFIDLoginButton; }
|
|
22
22
|
});
|
|
23
23
|
Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
|
|
24
24
|
enumerable: true,
|
|
25
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkA6MOPB7D_cjs.FFIDOrganizationSwitcher; }
|
|
26
26
|
});
|
|
27
27
|
Object.defineProperty(exports, "FFIDSubscriptionBadge", {
|
|
28
28
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunkA6MOPB7D_cjs.FFIDSubscriptionBadge; }
|
|
30
30
|
});
|
|
31
31
|
Object.defineProperty(exports, "FFIDUserMenu", {
|
|
32
32
|
enumerable: true,
|
|
33
|
-
get: function () { return
|
|
33
|
+
get: function () { return chunkA6MOPB7D_cjs.FFIDUserMenu; }
|
|
34
34
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-
|
|
1
|
+
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-DSvX4q8E.cjs';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-
|
|
1
|
+
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-DSvX4q8E.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-
|
|
1
|
+
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-KENJXMSG.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as EffectiveSubscriptionStatus } from './types-
|
|
1
|
+
import { E as EffectiveSubscriptionStatus } from './types-BYdtyO_2.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Inquiry types exposed by the FFID SDK.
|
|
@@ -740,6 +740,8 @@ interface FFIDSubscription {
|
|
|
740
740
|
memberRole?: FFIDOAuthUserInfoMemberRole | undefined;
|
|
741
741
|
/** Organization ID used to resolve subscription access */
|
|
742
742
|
organizationId?: string | null | undefined;
|
|
743
|
+
/** Organization display name for UI rendering; not used for access resolution */
|
|
744
|
+
organizationName?: string | null | undefined;
|
|
743
745
|
}
|
|
744
746
|
/** OAuth userinfo subscription summary */
|
|
745
747
|
interface FFIDOAuthUserInfoSubscription {
|
|
@@ -757,13 +759,35 @@ interface FFIDOAuthUserInfoSubscription {
|
|
|
757
759
|
seatModel: FFIDSeatModel | null;
|
|
758
760
|
memberRole: FFIDOAuthUserInfoMemberRole | null;
|
|
759
761
|
organizationId: string | null;
|
|
762
|
+
organizationName?: string | null | undefined;
|
|
760
763
|
hasSeatAssignment: boolean | null;
|
|
764
|
+
/**
|
|
765
|
+
* Stripe `cancel_at_period_end` (#3464, SDK 5.8.0). `true` while the
|
|
766
|
+
* subscription is scheduled to terminate at `currentPeriodEnd`. The
|
|
767
|
+
* `normalizeUserinfo` boundary defaults the wire field to `false` when
|
|
768
|
+
* the server omits it (older FFID pre-#3464), so consumers always see
|
|
769
|
+
* a plain boolean and never branch on an "unknown" sentinel — the
|
|
770
|
+
* companion `effectiveStatus` already returns `'active'` (not
|
|
771
|
+
* `'active_canceling'`) for legacy backends since `cancel_at_period_end`
|
|
772
|
+
* is implicitly false there.
|
|
773
|
+
*/
|
|
774
|
+
cancelAtPeriodEnd: boolean;
|
|
775
|
+
/**
|
|
776
|
+
* ISO timestamp of the current billing period end (#3464, SDK 5.8.0).
|
|
777
|
+
* `null` for free / seatless plans, or when serving an older FFID
|
|
778
|
+
* (pre-#3464) that does not populate the field. Exposed so callers
|
|
779
|
+
* can display the cancellation effective date without an `/ext/check`
|
|
780
|
+
* round-trip.
|
|
781
|
+
*/
|
|
782
|
+
currentPeriodEnd: string | null;
|
|
761
783
|
}
|
|
762
784
|
/**
|
|
763
785
|
* Unified user-identity shape returned by `getSession()` (→ `/oauth/userinfo`)
|
|
764
|
-
* and `verifyAccessToken()` (JWT or introspect path). `subscription
|
|
765
|
-
* `organizationId` are scope-gated on `/oauth/userinfo`
|
|
766
|
-
* `subscription:read`); JWT-verify additionally
|
|
786
|
+
* and `verifyAccessToken()` (JWT or introspect path). `subscription`,
|
|
787
|
+
* `organizationId`, and `organizationName` are scope-gated on `/oauth/userinfo`
|
|
788
|
+
* (FFID #3380, requires `subscription:read`); JWT-only verify additionally
|
|
789
|
+
* omits `subscription` and `organizationName` when `includeProfile` is false
|
|
790
|
+
* because the JWT has `org_id` but no `org_name` claim.
|
|
767
791
|
* See per-field JSDoc — misreading `undefined` is a security regression.
|
|
768
792
|
*/
|
|
769
793
|
interface FFIDOAuthUserInfo {
|
|
@@ -781,6 +805,14 @@ interface FFIDOAuthUserInfo {
|
|
|
781
805
|
* — NOT "no organization").
|
|
782
806
|
*/
|
|
783
807
|
organizationId?: string | null | undefined;
|
|
808
|
+
/**
|
|
809
|
+
* Organization display name, `null` if the resolved organization has no name,
|
|
810
|
+
* or `undefined` if the granted scope omits `subscription:read` on
|
|
811
|
+
* `/oauth/userinfo` (FFID #3514), or if the caller used JWT verification
|
|
812
|
+
* without `includeProfile`. JWT payloads carry `org_id` but no `org_name`
|
|
813
|
+
* claim.
|
|
814
|
+
*/
|
|
815
|
+
organizationName?: string | null | undefined;
|
|
784
816
|
/**
|
|
785
817
|
* Subscription summary for `(user, service, organization)`. Branch on
|
|
786
818
|
* `effectiveStatus` (5.3.0+) for access decisions.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as EffectiveSubscriptionStatus } from './types-
|
|
1
|
+
import { E as EffectiveSubscriptionStatus } from './types-BYdtyO_2.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Inquiry types exposed by the FFID SDK.
|
|
@@ -740,6 +740,8 @@ interface FFIDSubscription {
|
|
|
740
740
|
memberRole?: FFIDOAuthUserInfoMemberRole | undefined;
|
|
741
741
|
/** Organization ID used to resolve subscription access */
|
|
742
742
|
organizationId?: string | null | undefined;
|
|
743
|
+
/** Organization display name for UI rendering; not used for access resolution */
|
|
744
|
+
organizationName?: string | null | undefined;
|
|
743
745
|
}
|
|
744
746
|
/** OAuth userinfo subscription summary */
|
|
745
747
|
interface FFIDOAuthUserInfoSubscription {
|
|
@@ -757,13 +759,35 @@ interface FFIDOAuthUserInfoSubscription {
|
|
|
757
759
|
seatModel: FFIDSeatModel | null;
|
|
758
760
|
memberRole: FFIDOAuthUserInfoMemberRole | null;
|
|
759
761
|
organizationId: string | null;
|
|
762
|
+
organizationName?: string | null | undefined;
|
|
760
763
|
hasSeatAssignment: boolean | null;
|
|
764
|
+
/**
|
|
765
|
+
* Stripe `cancel_at_period_end` (#3464, SDK 5.8.0). `true` while the
|
|
766
|
+
* subscription is scheduled to terminate at `currentPeriodEnd`. The
|
|
767
|
+
* `normalizeUserinfo` boundary defaults the wire field to `false` when
|
|
768
|
+
* the server omits it (older FFID pre-#3464), so consumers always see
|
|
769
|
+
* a plain boolean and never branch on an "unknown" sentinel — the
|
|
770
|
+
* companion `effectiveStatus` already returns `'active'` (not
|
|
771
|
+
* `'active_canceling'`) for legacy backends since `cancel_at_period_end`
|
|
772
|
+
* is implicitly false there.
|
|
773
|
+
*/
|
|
774
|
+
cancelAtPeriodEnd: boolean;
|
|
775
|
+
/**
|
|
776
|
+
* ISO timestamp of the current billing period end (#3464, SDK 5.8.0).
|
|
777
|
+
* `null` for free / seatless plans, or when serving an older FFID
|
|
778
|
+
* (pre-#3464) that does not populate the field. Exposed so callers
|
|
779
|
+
* can display the cancellation effective date without an `/ext/check`
|
|
780
|
+
* round-trip.
|
|
781
|
+
*/
|
|
782
|
+
currentPeriodEnd: string | null;
|
|
761
783
|
}
|
|
762
784
|
/**
|
|
763
785
|
* Unified user-identity shape returned by `getSession()` (→ `/oauth/userinfo`)
|
|
764
|
-
* and `verifyAccessToken()` (JWT or introspect path). `subscription
|
|
765
|
-
* `organizationId` are scope-gated on `/oauth/userinfo`
|
|
766
|
-
* `subscription:read`); JWT-verify additionally
|
|
786
|
+
* and `verifyAccessToken()` (JWT or introspect path). `subscription`,
|
|
787
|
+
* `organizationId`, and `organizationName` are scope-gated on `/oauth/userinfo`
|
|
788
|
+
* (FFID #3380, requires `subscription:read`); JWT-only verify additionally
|
|
789
|
+
* omits `subscription` and `organizationName` when `includeProfile` is false
|
|
790
|
+
* because the JWT has `org_id` but no `org_name` claim.
|
|
767
791
|
* See per-field JSDoc — misreading `undefined` is a security regression.
|
|
768
792
|
*/
|
|
769
793
|
interface FFIDOAuthUserInfo {
|
|
@@ -781,6 +805,14 @@ interface FFIDOAuthUserInfo {
|
|
|
781
805
|
* — NOT "no organization").
|
|
782
806
|
*/
|
|
783
807
|
organizationId?: string | null | undefined;
|
|
808
|
+
/**
|
|
809
|
+
* Organization display name, `null` if the resolved organization has no name,
|
|
810
|
+
* or `undefined` if the granted scope omits `subscription:read` on
|
|
811
|
+
* `/oauth/userinfo` (FFID #3514), or if the caller used JWT verification
|
|
812
|
+
* without `includeProfile`. JWT payloads carry `org_id` but no `org_name`
|
|
813
|
+
* claim.
|
|
814
|
+
*/
|
|
815
|
+
organizationName?: string | null | undefined;
|
|
784
816
|
/**
|
|
785
817
|
* Subscription summary for `(user, service, organization)`. Branch on
|
|
786
818
|
* `effectiveStatus` (5.3.0+) for access decisions.
|
|
@@ -57,22 +57,18 @@ interface FFIDCacheConfig {
|
|
|
57
57
|
* This is the FFID-internal runtime-expired case (see
|
|
58
58
|
* `getEffectiveSubscriptionStatus` on the server). Deny access.
|
|
59
59
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* `
|
|
63
|
-
* `
|
|
64
|
-
* `
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* access-granting (no security regression on the userinfo path); when the
|
|
73
|
-
* server's `EffectiveSubscriptionStatus` is later extended to emit
|
|
74
|
-
* `active_canceling`, this docstring MUST be updated to drop the
|
|
75
|
-
* session-only note.
|
|
60
|
+
* **`active_canceling` is mirrored on the server (#3464, SDK 5.8.0).**
|
|
61
|
+
* Earlier (#3460, SDK 5.7.0) the literal was a session-only enrichment;
|
|
62
|
+
* since FFID #3464 the backend `EffectiveSubscriptionStatus` and both
|
|
63
|
+
* `/api/v1/subscriptions/ext/check` + `/oauth/userinfo` emit
|
|
64
|
+
* `active_canceling` directly when `cancel_at_period_end=true` and the
|
|
65
|
+
* period is still live. SDK consumers receive the same literal whether
|
|
66
|
+
* they read it from the session-derived `computeEffectiveStatusFromSession`
|
|
67
|
+
* or the server-derived `effectiveStatus` on the userinfo / ext-check
|
|
68
|
+
* paths. Pre-#3464 FFID backends omit `cancelAtPeriodEnd` on the wire; the
|
|
69
|
+
* SDK `normalizeUserinfo` boundary defaults it to `false`, so downstream
|
|
70
|
+
* consumers see a plain boolean and `computeEffectiveStatus` returns the
|
|
71
|
+
* original `'active'` verdict for legacy deployments.
|
|
76
72
|
*
|
|
77
73
|
* @see /api/v1/subscriptions/ext/check
|
|
78
74
|
* @see docs/03-implementation/EXPIRED_CONTRACT_HANDLING.md
|
|
@@ -267,6 +263,8 @@ interface FFIDSubscription {
|
|
|
267
263
|
memberRole?: FFIDOAuthUserInfoMemberRole | undefined;
|
|
268
264
|
/** Organization ID used to resolve subscription access */
|
|
269
265
|
organizationId?: string | null | undefined;
|
|
266
|
+
/** Organization display name for UI rendering; not used for access resolution */
|
|
267
|
+
organizationName?: string | null | undefined;
|
|
270
268
|
}
|
|
271
269
|
/** OAuth userinfo subscription summary */
|
|
272
270
|
interface FFIDOAuthUserInfoSubscription {
|
|
@@ -284,13 +282,35 @@ interface FFIDOAuthUserInfoSubscription {
|
|
|
284
282
|
seatModel: FFIDSeatModel | null;
|
|
285
283
|
memberRole: FFIDOAuthUserInfoMemberRole | null;
|
|
286
284
|
organizationId: string | null;
|
|
285
|
+
organizationName?: string | null | undefined;
|
|
287
286
|
hasSeatAssignment: boolean | null;
|
|
287
|
+
/**
|
|
288
|
+
* Stripe `cancel_at_period_end` (#3464, SDK 5.8.0). `true` while the
|
|
289
|
+
* subscription is scheduled to terminate at `currentPeriodEnd`. The
|
|
290
|
+
* `normalizeUserinfo` boundary defaults the wire field to `false` when
|
|
291
|
+
* the server omits it (older FFID pre-#3464), so consumers always see
|
|
292
|
+
* a plain boolean and never branch on an "unknown" sentinel — the
|
|
293
|
+
* companion `effectiveStatus` already returns `'active'` (not
|
|
294
|
+
* `'active_canceling'`) for legacy backends since `cancel_at_period_end`
|
|
295
|
+
* is implicitly false there.
|
|
296
|
+
*/
|
|
297
|
+
cancelAtPeriodEnd: boolean;
|
|
298
|
+
/**
|
|
299
|
+
* ISO timestamp of the current billing period end (#3464, SDK 5.8.0).
|
|
300
|
+
* `null` for free / seatless plans, or when serving an older FFID
|
|
301
|
+
* (pre-#3464) that does not populate the field. Exposed so callers
|
|
302
|
+
* can display the cancellation effective date without an `/ext/check`
|
|
303
|
+
* round-trip.
|
|
304
|
+
*/
|
|
305
|
+
currentPeriodEnd: string | null;
|
|
288
306
|
}
|
|
289
307
|
/**
|
|
290
308
|
* Unified user-identity shape returned by `getSession()` (→ `/oauth/userinfo`)
|
|
291
|
-
* and `verifyAccessToken()` (JWT or introspect path). `subscription
|
|
292
|
-
* `organizationId` are scope-gated on `/oauth/userinfo`
|
|
293
|
-
* `subscription:read`); JWT-verify additionally
|
|
309
|
+
* and `verifyAccessToken()` (JWT or introspect path). `subscription`,
|
|
310
|
+
* `organizationId`, and `organizationName` are scope-gated on `/oauth/userinfo`
|
|
311
|
+
* (FFID #3380, requires `subscription:read`); JWT-only verify additionally
|
|
312
|
+
* omits `subscription` and `organizationName` when `includeProfile` is false
|
|
313
|
+
* because the JWT has `org_id` but no `org_name` claim.
|
|
294
314
|
* See per-field JSDoc — misreading `undefined` is a security regression.
|
|
295
315
|
*/
|
|
296
316
|
interface FFIDOAuthUserInfo {
|
|
@@ -308,6 +328,14 @@ interface FFIDOAuthUserInfo {
|
|
|
308
328
|
* — NOT "no organization").
|
|
309
329
|
*/
|
|
310
330
|
organizationId?: string | null | undefined;
|
|
331
|
+
/**
|
|
332
|
+
* Organization display name, `null` if the resolved organization has no name,
|
|
333
|
+
* or `undefined` if the granted scope omits `subscription:read` on
|
|
334
|
+
* `/oauth/userinfo` (FFID #3514), or if the caller used JWT verification
|
|
335
|
+
* without `includeProfile`. JWT payloads carry `org_id` but no `org_name`
|
|
336
|
+
* claim.
|
|
337
|
+
*/
|
|
338
|
+
organizationName?: string | null | undefined;
|
|
311
339
|
/**
|
|
312
340
|
* Subscription summary for `(user, service, organization)`. Branch on
|
|
313
341
|
* `effectiveStatus` (5.3.0+) for access decisions.
|
|
@@ -836,6 +864,7 @@ interface FFIDTokenIntrospectionResponse {
|
|
|
836
864
|
token_type?: 'Bearer';
|
|
837
865
|
client_id?: string;
|
|
838
866
|
organization_id?: string | null;
|
|
867
|
+
organization_name?: string | null;
|
|
839
868
|
subscription?: {
|
|
840
869
|
subscription_id: string | null;
|
|
841
870
|
status: FFIDOAuthUserInfoSubscription['status'];
|
|
@@ -845,6 +874,7 @@ interface FFIDTokenIntrospectionResponse {
|
|
|
845
874
|
seat_model: FFIDOAuthUserInfoSubscription['seatModel'];
|
|
846
875
|
member_role: FFIDOAuthUserInfoSubscription['memberRole'];
|
|
847
876
|
organization_id: string | null;
|
|
877
|
+
organization_name?: string | null;
|
|
848
878
|
has_seat_assignment?: boolean;
|
|
849
879
|
};
|
|
850
880
|
}
|
|
@@ -57,22 +57,18 @@ interface FFIDCacheConfig {
|
|
|
57
57
|
* This is the FFID-internal runtime-expired case (see
|
|
58
58
|
* `getEffectiveSubscriptionStatus` on the server). Deny access.
|
|
59
59
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* `
|
|
63
|
-
* `
|
|
64
|
-
* `
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* access-granting (no security regression on the userinfo path); when the
|
|
73
|
-
* server's `EffectiveSubscriptionStatus` is later extended to emit
|
|
74
|
-
* `active_canceling`, this docstring MUST be updated to drop the
|
|
75
|
-
* session-only note.
|
|
60
|
+
* **`active_canceling` is mirrored on the server (#3464, SDK 5.8.0).**
|
|
61
|
+
* Earlier (#3460, SDK 5.7.0) the literal was a session-only enrichment;
|
|
62
|
+
* since FFID #3464 the backend `EffectiveSubscriptionStatus` and both
|
|
63
|
+
* `/api/v1/subscriptions/ext/check` + `/oauth/userinfo` emit
|
|
64
|
+
* `active_canceling` directly when `cancel_at_period_end=true` and the
|
|
65
|
+
* period is still live. SDK consumers receive the same literal whether
|
|
66
|
+
* they read it from the session-derived `computeEffectiveStatusFromSession`
|
|
67
|
+
* or the server-derived `effectiveStatus` on the userinfo / ext-check
|
|
68
|
+
* paths. Pre-#3464 FFID backends omit `cancelAtPeriodEnd` on the wire; the
|
|
69
|
+
* SDK `normalizeUserinfo` boundary defaults it to `false`, so downstream
|
|
70
|
+
* consumers see a plain boolean and `computeEffectiveStatus` returns the
|
|
71
|
+
* original `'active'` verdict for legacy deployments.
|
|
76
72
|
*
|
|
77
73
|
* @see /api/v1/subscriptions/ext/check
|
|
78
74
|
* @see docs/03-implementation/EXPIRED_CONTRACT_HANDLING.md
|
|
@@ -267,6 +263,8 @@ interface FFIDSubscription {
|
|
|
267
263
|
memberRole?: FFIDOAuthUserInfoMemberRole | undefined;
|
|
268
264
|
/** Organization ID used to resolve subscription access */
|
|
269
265
|
organizationId?: string | null | undefined;
|
|
266
|
+
/** Organization display name for UI rendering; not used for access resolution */
|
|
267
|
+
organizationName?: string | null | undefined;
|
|
270
268
|
}
|
|
271
269
|
/** OAuth userinfo subscription summary */
|
|
272
270
|
interface FFIDOAuthUserInfoSubscription {
|
|
@@ -284,13 +282,35 @@ interface FFIDOAuthUserInfoSubscription {
|
|
|
284
282
|
seatModel: FFIDSeatModel | null;
|
|
285
283
|
memberRole: FFIDOAuthUserInfoMemberRole | null;
|
|
286
284
|
organizationId: string | null;
|
|
285
|
+
organizationName?: string | null | undefined;
|
|
287
286
|
hasSeatAssignment: boolean | null;
|
|
287
|
+
/**
|
|
288
|
+
* Stripe `cancel_at_period_end` (#3464, SDK 5.8.0). `true` while the
|
|
289
|
+
* subscription is scheduled to terminate at `currentPeriodEnd`. The
|
|
290
|
+
* `normalizeUserinfo` boundary defaults the wire field to `false` when
|
|
291
|
+
* the server omits it (older FFID pre-#3464), so consumers always see
|
|
292
|
+
* a plain boolean and never branch on an "unknown" sentinel — the
|
|
293
|
+
* companion `effectiveStatus` already returns `'active'` (not
|
|
294
|
+
* `'active_canceling'`) for legacy backends since `cancel_at_period_end`
|
|
295
|
+
* is implicitly false there.
|
|
296
|
+
*/
|
|
297
|
+
cancelAtPeriodEnd: boolean;
|
|
298
|
+
/**
|
|
299
|
+
* ISO timestamp of the current billing period end (#3464, SDK 5.8.0).
|
|
300
|
+
* `null` for free / seatless plans, or when serving an older FFID
|
|
301
|
+
* (pre-#3464) that does not populate the field. Exposed so callers
|
|
302
|
+
* can display the cancellation effective date without an `/ext/check`
|
|
303
|
+
* round-trip.
|
|
304
|
+
*/
|
|
305
|
+
currentPeriodEnd: string | null;
|
|
288
306
|
}
|
|
289
307
|
/**
|
|
290
308
|
* Unified user-identity shape returned by `getSession()` (→ `/oauth/userinfo`)
|
|
291
|
-
* and `verifyAccessToken()` (JWT or introspect path). `subscription
|
|
292
|
-
* `organizationId` are scope-gated on `/oauth/userinfo`
|
|
293
|
-
* `subscription:read`); JWT-verify additionally
|
|
309
|
+
* and `verifyAccessToken()` (JWT or introspect path). `subscription`,
|
|
310
|
+
* `organizationId`, and `organizationName` are scope-gated on `/oauth/userinfo`
|
|
311
|
+
* (FFID #3380, requires `subscription:read`); JWT-only verify additionally
|
|
312
|
+
* omits `subscription` and `organizationName` when `includeProfile` is false
|
|
313
|
+
* because the JWT has `org_id` but no `org_name` claim.
|
|
294
314
|
* See per-field JSDoc — misreading `undefined` is a security regression.
|
|
295
315
|
*/
|
|
296
316
|
interface FFIDOAuthUserInfo {
|
|
@@ -308,6 +328,14 @@ interface FFIDOAuthUserInfo {
|
|
|
308
328
|
* — NOT "no organization").
|
|
309
329
|
*/
|
|
310
330
|
organizationId?: string | null | undefined;
|
|
331
|
+
/**
|
|
332
|
+
* Organization display name, `null` if the resolved organization has no name,
|
|
333
|
+
* or `undefined` if the granted scope omits `subscription:read` on
|
|
334
|
+
* `/oauth/userinfo` (FFID #3514), or if the caller used JWT verification
|
|
335
|
+
* without `includeProfile`. JWT payloads carry `org_id` but no `org_name`
|
|
336
|
+
* claim.
|
|
337
|
+
*/
|
|
338
|
+
organizationName?: string | null | undefined;
|
|
311
339
|
/**
|
|
312
340
|
* Subscription summary for `(user, service, organization)`. Branch on
|
|
313
341
|
* `effectiveStatus` (5.3.0+) for access decisions.
|
|
@@ -836,6 +864,7 @@ interface FFIDTokenIntrospectionResponse {
|
|
|
836
864
|
token_type?: 'Bearer';
|
|
837
865
|
client_id?: string;
|
|
838
866
|
organization_id?: string | null;
|
|
867
|
+
organization_name?: string | null;
|
|
839
868
|
subscription?: {
|
|
840
869
|
subscription_id: string | null;
|
|
841
870
|
status: FFIDOAuthUserInfoSubscription['status'];
|
|
@@ -845,6 +874,7 @@ interface FFIDTokenIntrospectionResponse {
|
|
|
845
874
|
seat_model: FFIDOAuthUserInfoSubscription['seatModel'];
|
|
846
875
|
member_role: FFIDOAuthUserInfoSubscription['memberRole'];
|
|
847
876
|
organization_id: string | null;
|
|
877
|
+
organization_name?: string | null;
|
|
848
878
|
has_seat_assignment?: boolean;
|
|
849
879
|
};
|
|
850
880
|
}
|