@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.
@@ -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
- logger.error("JWT verification failed:", message);
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.TOKEN_VERIFICATION_ERROR,
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
- errorCodes: { TOKEN_VERIFICATION_ERROR: errorCodes.TOKEN_VERIFICATION_ERROR }
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.17.1";
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: (...args) => console.warn(SDK_LOG_PREFIX, ...args),
2531
- error: (...args) => console.error(SDK_LOG_PREFIX, ...args)
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 };
@@ -1,4 +1,4 @@
1
- import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-Cwk6cG3b.cjs';
1
+ import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-BuDM5tmq.cjs';
2
2
  import '../../types-BeVl-z12.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-w8Twi5lD.js';
1
+ import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-D0x8TBS5.js';
2
2
  import '../../types-BeVl-z12.js';
3
3
 
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feelflow/ffid-sdk",
3
- "version": "5.17.1",
3
+ "version": "5.19.0",
4
4
  "description": "FeelFlow ID Platform SDK for React/Next.js applications",
5
5
  "keywords": [
6
6
  "feelflow",