@feelflow/ffid-sdk 5.17.1 → 5.19.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 +77 -0
- package/dist/{chunk-26X62P76.js → chunk-D3PZ6SZB.js} +138 -18
- package/dist/{chunk-A2KK6L63.cjs → chunk-TW2FXASO.cjs} +137 -16
- package/dist/components/index.cjs +8 -8
- package/dist/components/index.js +1 -1
- package/dist/{ffid-client-Cwk6cG3b.d.cts → ffid-client-BuDM5tmq.d.cts} +214 -1
- package/dist/{ffid-client-w8Twi5lD.d.ts → ffid-client-D0x8TBS5.d.ts} +214 -1
- package/dist/index.cjs +45 -41
- package/dist/index.d.cts +241 -1
- package/dist/index.d.ts +241 -1
- package/dist/index.js +2 -2
- package/dist/server/index.cjs +137 -16
- package/dist/server/index.d.cts +34 -6
- package/dist/server/index.d.ts +34 -6
- package/dist/server/index.js +138 -18
- package/dist/server/test/index.d.cts +1 -1
- package/dist/server/test/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_API_BASE_URL } from '../chunk-JEVK2XUM.js';
|
|
2
2
|
export { DEFAULT_API_BASE_URL, DEFAULT_OAUTH_SCOPES } from '../chunk-JEVK2XUM.js';
|
|
3
|
-
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
|
3
|
+
import { createRemoteJWKSet, jwtVerify, errors } from 'jose';
|
|
4
4
|
|
|
5
5
|
// src/auth/token-store.ts
|
|
6
6
|
var STORAGE_KEY = "ffid_tokens";
|
|
@@ -224,10 +224,29 @@ function createJwtVerifier(deps) {
|
|
|
224
224
|
return { data: userInfo };
|
|
225
225
|
} catch (error) {
|
|
226
226
|
const message = error instanceof Error ? error.message : "JWT\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F";
|
|
227
|
-
|
|
227
|
+
if (error instanceof errors.JWTExpired) {
|
|
228
|
+
logger.debug("JWT verification failed (token expired):", message);
|
|
229
|
+
return {
|
|
230
|
+
error: createError(
|
|
231
|
+
errorCodes.TOKEN_EXPIRED,
|
|
232
|
+
"\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u3066\u3044\u307E\u3059"
|
|
233
|
+
)
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
const isTokenLevelError = error instanceof errors.JWTClaimValidationFailed || error instanceof errors.JWTInvalid || error instanceof errors.JWSInvalid || error instanceof errors.JWSSignatureVerificationFailed || error instanceof errors.JOSEAlgNotAllowed || error instanceof errors.JOSENotSupported || error instanceof errors.JWKSNoMatchingKey || error instanceof errors.JWKSMultipleMatchingKeys;
|
|
237
|
+
if (isTokenLevelError) {
|
|
238
|
+
logger.warn("JWT verification failed:", message);
|
|
239
|
+
return {
|
|
240
|
+
error: createError(
|
|
241
|
+
errorCodes.TOKEN_VERIFICATION_ERROR,
|
|
242
|
+
`JWT\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${message}`
|
|
243
|
+
)
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
logger.error("JWT verification failed (JWKS fetch):", message);
|
|
228
247
|
return {
|
|
229
248
|
error: createError(
|
|
230
|
-
errorCodes.
|
|
249
|
+
errorCodes.NETWORK_ERROR,
|
|
231
250
|
`JWT\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${message}`
|
|
232
251
|
)
|
|
233
252
|
};
|
|
@@ -252,7 +271,9 @@ function createVerifyAccessToken(deps) {
|
|
|
252
271
|
serviceCode,
|
|
253
272
|
logger,
|
|
254
273
|
createError,
|
|
255
|
-
|
|
274
|
+
// structural superset of JwtVerifierDeps.errorCodes — passing it
|
|
275
|
+
// wholesale removes the hand-transcription drift point
|
|
276
|
+
errorCodes
|
|
256
277
|
});
|
|
257
278
|
}
|
|
258
279
|
return jwtVerify2;
|
|
@@ -848,6 +869,93 @@ function createMembersMethods(deps) {
|
|
|
848
869
|
return { listMembers, addMember, updateMemberRole, removeMember };
|
|
849
870
|
}
|
|
850
871
|
|
|
872
|
+
// src/client/provisioning-methods.ts
|
|
873
|
+
var USER_PROVISION_ENDPOINT = "/api/v1/ext/users/provision";
|
|
874
|
+
var ORGANIZATION_PROVISION_ENDPOINT = "/api/v1/ext/organizations/provision";
|
|
875
|
+
var MAX_PROVISION_MEMBERS = 100;
|
|
876
|
+
var ASSIGNABLE_MEMBER_ROLES = {
|
|
877
|
+
admin: true,
|
|
878
|
+
member: true,
|
|
879
|
+
viewer: true
|
|
880
|
+
};
|
|
881
|
+
function isAssignableMemberRole(role) {
|
|
882
|
+
return Object.hasOwn(ASSIGNABLE_MEMBER_ROLES, role);
|
|
883
|
+
}
|
|
884
|
+
function createProvisioningMethods(deps) {
|
|
885
|
+
const { fetchWithAuth, createError, authMode } = deps;
|
|
886
|
+
function serviceKeyModeError() {
|
|
887
|
+
if (authMode === "service-key") return null;
|
|
888
|
+
return createError(
|
|
889
|
+
"VALIDATION_ERROR",
|
|
890
|
+
"provisionUser / provisionOrganization \u306F service-key \u8A8D\u8A3C\uFF08X-Service-Api-Key\uFF09\u3067\u306E\u307F\u5229\u7528\u3067\u304D\u307E\u3059\u3002Bearer / cookie \u30E2\u30FC\u30C9\u3067\u306F\u547C\u3073\u51FA\u305B\u307E\u305B\u3093"
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
async function provisionUser(params) {
|
|
894
|
+
const modeError = serviceKeyModeError();
|
|
895
|
+
if (modeError) return { error: modeError };
|
|
896
|
+
if (!params.email || !params.email.trim()) {
|
|
897
|
+
return { error: createError("VALIDATION_ERROR", "email \u306F\u5FC5\u9808\u3067\u3059") };
|
|
898
|
+
}
|
|
899
|
+
const body = { email: params.email.trim() };
|
|
900
|
+
if (params.profile !== void 0) body.profile = params.profile;
|
|
901
|
+
if (params.dryRun !== void 0) body.dryRun = params.dryRun;
|
|
902
|
+
return fetchWithAuth(USER_PROVISION_ENDPOINT, {
|
|
903
|
+
method: "POST",
|
|
904
|
+
body: JSON.stringify(body)
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
async function provisionOrganization(params) {
|
|
908
|
+
const modeError = serviceKeyModeError();
|
|
909
|
+
if (modeError) return { error: modeError };
|
|
910
|
+
if (!params.name || !params.name.trim()) {
|
|
911
|
+
return { error: createError("VALIDATION_ERROR", "name \u306F\u5FC5\u9808\u3067\u3059") };
|
|
912
|
+
}
|
|
913
|
+
if (!params.ownerEmail || !params.ownerEmail.trim()) {
|
|
914
|
+
return { error: createError("VALIDATION_ERROR", "ownerEmail \u306F\u5FC5\u9808\u3067\u3059") };
|
|
915
|
+
}
|
|
916
|
+
if (params.members) {
|
|
917
|
+
if (params.members.length > MAX_PROVISION_MEMBERS) {
|
|
918
|
+
return {
|
|
919
|
+
error: createError(
|
|
920
|
+
"VALIDATION_ERROR",
|
|
921
|
+
`members \u306F1\u30EA\u30AF\u30A8\u30B9\u30C8\u3042\u305F\u308A\u6700\u5927 ${MAX_PROVISION_MEMBERS} \u4EF6\u307E\u3067\u3067\u3059`
|
|
922
|
+
)
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
for (const member of params.members) {
|
|
926
|
+
if (!member.email || !member.email.trim()) {
|
|
927
|
+
return { error: createError("VALIDATION_ERROR", "members[].email \u306F\u5FC5\u9808\u3067\u3059") };
|
|
928
|
+
}
|
|
929
|
+
if (!isAssignableMemberRole(member.role)) {
|
|
930
|
+
return {
|
|
931
|
+
error: createError(
|
|
932
|
+
"VALIDATION_ERROR",
|
|
933
|
+
"members[].role \u306F admin\u3001member\u3001viewer \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
934
|
+
)
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
const body = {
|
|
940
|
+
name: params.name.trim(),
|
|
941
|
+
ownerEmail: params.ownerEmail.trim()
|
|
942
|
+
};
|
|
943
|
+
if (params.billingEmail !== void 0) body.billingEmail = params.billingEmail.trim();
|
|
944
|
+
if (params.members !== void 0) {
|
|
945
|
+
body.members = params.members.map((member) => ({
|
|
946
|
+
email: member.email.trim(),
|
|
947
|
+
role: member.role
|
|
948
|
+
}));
|
|
949
|
+
}
|
|
950
|
+
if (params.dryRun !== void 0) body.dryRun = params.dryRun;
|
|
951
|
+
return fetchWithAuth(ORGANIZATION_PROVISION_ENDPOINT, {
|
|
952
|
+
method: "POST",
|
|
953
|
+
body: JSON.stringify(body)
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
return { provisionUser, provisionOrganization };
|
|
957
|
+
}
|
|
958
|
+
|
|
851
959
|
// src/client/seat-methods.ts
|
|
852
960
|
function seatsEndpoint(subscriptionId) {
|
|
853
961
|
return `/api/v1/subscriptions/ext/${encodeURIComponent(subscriptionId)}/seats/assignments`;
|
|
@@ -1092,7 +1200,7 @@ function createNonContractMethods(deps) {
|
|
|
1092
1200
|
}
|
|
1093
1201
|
|
|
1094
1202
|
// src/client/version-check.ts
|
|
1095
|
-
var SDK_VERSION = "5.
|
|
1203
|
+
var SDK_VERSION = "5.19.0";
|
|
1096
1204
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
1097
1205
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
1098
1206
|
function sdkHeaders() {
|
|
@@ -2519,6 +2627,19 @@ var BLOCKING_EFFECTIVE_STATUSES = [
|
|
|
2519
2627
|
"trial_expired"
|
|
2520
2628
|
];
|
|
2521
2629
|
|
|
2630
|
+
// src/client/error-codes.ts
|
|
2631
|
+
var FFID_ERROR_CODES = {
|
|
2632
|
+
NETWORK_ERROR: "NETWORK_ERROR",
|
|
2633
|
+
PARSE_ERROR: "PARSE_ERROR",
|
|
2634
|
+
UNKNOWN_ERROR: "UNKNOWN_ERROR",
|
|
2635
|
+
TOKEN_EXCHANGE_ERROR: "TOKEN_EXCHANGE_ERROR",
|
|
2636
|
+
TOKEN_REFRESH_ERROR: "TOKEN_REFRESH_ERROR",
|
|
2637
|
+
NO_TOKENS: "NO_TOKENS",
|
|
2638
|
+
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR",
|
|
2639
|
+
TOKEN_EXPIRED: "TOKEN_EXPIRED",
|
|
2640
|
+
STATE_MISMATCH_ERROR: "STATE_MISMATCH_ERROR"
|
|
2641
|
+
};
|
|
2642
|
+
|
|
2522
2643
|
// src/client/ffid-client.ts
|
|
2523
2644
|
var UNAUTHORIZED_STATUS2 = 401;
|
|
2524
2645
|
var SDK_LOG_PREFIX = "[FFID SDK]";
|
|
@@ -2527,8 +2648,10 @@ var noopLogger = {
|
|
|
2527
2648
|
},
|
|
2528
2649
|
info: () => {
|
|
2529
2650
|
},
|
|
2530
|
-
warn: (
|
|
2531
|
-
|
|
2651
|
+
warn: () => {
|
|
2652
|
+
},
|
|
2653
|
+
error: () => {
|
|
2654
|
+
}
|
|
2532
2655
|
};
|
|
2533
2656
|
var consoleLogger = {
|
|
2534
2657
|
debug: (...args) => console.debug(SDK_LOG_PREFIX, ...args),
|
|
@@ -2536,16 +2659,6 @@ var consoleLogger = {
|
|
|
2536
2659
|
warn: (...args) => console.warn(SDK_LOG_PREFIX, ...args),
|
|
2537
2660
|
error: (...args) => console.error(SDK_LOG_PREFIX, ...args)
|
|
2538
2661
|
};
|
|
2539
|
-
var FFID_ERROR_CODES = {
|
|
2540
|
-
NETWORK_ERROR: "NETWORK_ERROR",
|
|
2541
|
-
PARSE_ERROR: "PARSE_ERROR",
|
|
2542
|
-
UNKNOWN_ERROR: "UNKNOWN_ERROR",
|
|
2543
|
-
TOKEN_EXCHANGE_ERROR: "TOKEN_EXCHANGE_ERROR",
|
|
2544
|
-
TOKEN_REFRESH_ERROR: "TOKEN_REFRESH_ERROR",
|
|
2545
|
-
NO_TOKENS: "NO_TOKENS",
|
|
2546
|
-
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR",
|
|
2547
|
-
STATE_MISMATCH_ERROR: "STATE_MISMATCH_ERROR"
|
|
2548
|
-
};
|
|
2549
2662
|
var EXT_CHECK_ENDPOINT = "/api/v1/subscriptions/ext/check";
|
|
2550
2663
|
var DEFAULT_ALLOW_GRACE = true;
|
|
2551
2664
|
var DEFAULT_SERVICE_ACCESS_FAIL_POLICY = "failClosed";
|
|
@@ -2928,6 +3041,11 @@ function createFFIDClient(config) {
|
|
|
2928
3041
|
createError,
|
|
2929
3042
|
serviceCode: config.serviceCode
|
|
2930
3043
|
});
|
|
3044
|
+
const { provisionUser, provisionOrganization } = createProvisioningMethods({
|
|
3045
|
+
fetchWithAuth,
|
|
3046
|
+
createError,
|
|
3047
|
+
authMode
|
|
3048
|
+
});
|
|
2931
3049
|
const { getProfile, updateProfile } = createProfileMethods({
|
|
2932
3050
|
fetchWithAuth,
|
|
2933
3051
|
createError
|
|
@@ -3023,6 +3141,8 @@ function createFFIDClient(config) {
|
|
|
3023
3141
|
addMember,
|
|
3024
3142
|
updateMemberRole,
|
|
3025
3143
|
removeMember,
|
|
3144
|
+
provisionUser,
|
|
3145
|
+
provisionOrganization,
|
|
3026
3146
|
getProfile,
|
|
3027
3147
|
updateProfile,
|
|
3028
3148
|
// Non-contract ext API coverage (#3783)
|
|
@@ -3215,4 +3335,4 @@ function getFFIDConsentFromCookieHeader(cookieHeader) {
|
|
|
3215
3335
|
return decodeConsentCookie(decodeURIComponent(value));
|
|
3216
3336
|
}
|
|
3217
3337
|
|
|
3218
|
-
export { ALL_DENIED_EXCEPT_NECESSARY, CONSENT_COOKIE_NAME, COOKIE_VERSION, createFFIDClient, createKVCacheAdapter, createMemoryCacheAdapter, createTokenStore, createVerifyAccessToken, decodeConsentCookie, encodeConsentCookie, getFFIDConsentFromCookieHeader, getFFIDConsentFromCookies };
|
|
3338
|
+
export { ALL_DENIED_EXCEPT_NECESSARY, CONSENT_COOKIE_NAME, COOKIE_VERSION, FFID_ERROR_CODES, createFFIDClient, createKVCacheAdapter, createMemoryCacheAdapter, createTokenStore, createVerifyAccessToken, decodeConsentCookie, encodeConsentCookie, getFFIDConsentFromCookieHeader, getFFIDConsentFromCookies };
|