@feelflow/ffid-sdk 1.11.0 → 1.14.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.
@@ -432,7 +432,7 @@ function createBillingMethods(deps) {
432
432
  }
433
433
 
434
434
  // src/client/version-check.ts
435
- var SDK_VERSION = "1.11.0";
435
+ var SDK_VERSION = "1.14.0";
436
436
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
437
437
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
438
438
  function sdkHeaders() {
@@ -478,6 +478,22 @@ npm install @feelflow/ffid-sdk@latest \u3067\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8
478
478
  var OAUTH_TOKEN_ENDPOINT = "/api/v1/oauth/token";
479
479
  var OAUTH_REVOKE_ENDPOINT = "/api/v1/oauth/revoke";
480
480
  var MS_PER_SECOND = 1e3;
481
+ function validateTokenResponse(tokenResponse) {
482
+ const invalid = [];
483
+ if (!tokenResponse.access_token) {
484
+ invalid.push("access_token");
485
+ }
486
+ if (!tokenResponse.refresh_token) {
487
+ invalid.push("refresh_token");
488
+ }
489
+ if (typeof tokenResponse.expires_in !== "number" || tokenResponse.expires_in <= 0) {
490
+ invalid.push("expires_in");
491
+ }
492
+ if (invalid.length > 0) {
493
+ return `\u30C8\u30FC\u30AF\u30F3\u30EC\u30B9\u30DD\u30F3\u30B9\u306B\u4E0D\u6B63\u306A\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u3042\u308A\u307E\u3059: ${invalid.join(", ")}`;
494
+ }
495
+ return null;
496
+ }
481
497
  function createOAuthTokenMethods(deps) {
482
498
  const {
483
499
  baseUrl,
@@ -547,6 +563,16 @@ function createOAuthTokenMethods(deps) {
547
563
  }
548
564
  };
549
565
  }
566
+ const validationError = validateTokenResponse(tokenResponse);
567
+ if (validationError) {
568
+ logger.error("Token exchange validation failed:", validationError);
569
+ return {
570
+ error: {
571
+ code: errorCodes.TOKEN_EXCHANGE_ERROR,
572
+ message: validationError
573
+ }
574
+ };
575
+ }
550
576
  tokenStore.setTokens({
551
577
  accessToken: tokenResponse.access_token,
552
578
  refreshToken: tokenResponse.refresh_token,
@@ -615,6 +641,16 @@ function createOAuthTokenMethods(deps) {
615
641
  }
616
642
  };
617
643
  }
644
+ const validationError = validateTokenResponse(tokenResponse);
645
+ if (validationError) {
646
+ logger.error("Token refresh validation failed:", validationError);
647
+ return {
648
+ error: {
649
+ code: errorCodes.TOKEN_REFRESH_ERROR,
650
+ message: validationError
651
+ }
652
+ };
653
+ }
618
654
  tokenStore.setTokens({
619
655
  accessToken: tokenResponse.access_token,
620
656
  refreshToken: tokenResponse.refresh_token,
@@ -868,11 +904,17 @@ async function generateCodeChallenge(verifier) {
868
904
  const digest = await crypto.subtle.digest("SHA-256", data);
869
905
  return base64UrlEncode(digest);
870
906
  }
871
- function storeCodeVerifier(verifier) {
907
+ function storeCodeVerifier(verifier, logger) {
872
908
  try {
873
- if (typeof window === "undefined") return;
909
+ if (typeof window === "undefined") {
910
+ logger?.warn("storeCodeVerifier: sessionStorage is not available in SSR context");
911
+ return false;
912
+ }
874
913
  window.sessionStorage.setItem(VERIFIER_STORAGE_KEY, verifier);
875
- } catch {
914
+ return true;
915
+ } catch (error) {
916
+ logger?.warn("storeCodeVerifier: sessionStorage \u3078\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
917
+ return false;
876
918
  }
877
919
  }
878
920
  function base64UrlEncode(buffer) {
@@ -886,6 +928,7 @@ function base64UrlEncode(buffer) {
886
928
 
887
929
  // src/client/redirect.ts
888
930
  var OAUTH_AUTHORIZE_ENDPOINT = "/api/v1/oauth/authorize";
931
+ var AUTH_LOGOUT_ENDPOINT = "/api/v1/auth/logout";
889
932
  var STATE_RANDOM_BYTES = 16;
890
933
  var HEX_BASE2 = 16;
891
934
  function generateRandomState() {
@@ -904,32 +947,34 @@ function createRedirectMethods(deps) {
904
947
  } = deps;
905
948
  async function redirectToAuthorize() {
906
949
  const verifier = generateCodeVerifier();
907
- storeCodeVerifier(verifier);
950
+ storeCodeVerifier(verifier, logger);
951
+ let challenge;
908
952
  try {
909
- const challenge = await generateCodeChallenge(verifier);
910
- const state = generateRandomState();
911
- const redirectUri = resolvedRedirectUri ?? window.location.origin + window.location.pathname;
912
- const params = new URLSearchParams({
913
- response_type: "code",
914
- client_id: clientId,
915
- redirect_uri: redirectUri,
916
- state,
917
- code_challenge: challenge,
918
- code_challenge_method: "S256"
919
- });
920
- const authorizeUrl = `${baseUrl}${OAUTH_AUTHORIZE_ENDPOINT}?${params.toString()}`;
921
- logger.debug("Redirecting to authorize:", authorizeUrl);
922
- window.location.href = authorizeUrl;
923
- return true;
953
+ challenge = await generateCodeChallenge(verifier);
924
954
  } catch (error) {
955
+ const errorMessage = error instanceof Error ? error.message : "PKCE \u30B3\u30FC\u30C9\u30C1\u30E3\u30EC\u30F3\u30B8\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F";
925
956
  logger.error("PKCE \u30B3\u30FC\u30C9\u30C1\u30E3\u30EC\u30F3\u30B8\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
926
- return false;
957
+ return { success: false, error: errorMessage };
927
958
  }
959
+ const state = generateRandomState();
960
+ const redirectUri = resolvedRedirectUri ?? window.location.origin + window.location.pathname;
961
+ const params = new URLSearchParams({
962
+ response_type: "code",
963
+ client_id: clientId,
964
+ redirect_uri: redirectUri,
965
+ state,
966
+ code_challenge: challenge,
967
+ code_challenge_method: "S256"
968
+ });
969
+ const authorizeUrl = `${baseUrl}${OAUTH_AUTHORIZE_ENDPOINT}?${params.toString()}`;
970
+ logger.debug("Redirecting to authorize:", authorizeUrl);
971
+ window.location.href = authorizeUrl;
972
+ return { success: true };
928
973
  }
929
974
  async function redirectToLogin() {
930
975
  if (typeof window === "undefined") {
931
- logger.debug("Cannot redirect in SSR context");
932
- return false;
976
+ logger.warn("SSR \u74B0\u5883\u3067\u306F\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3067\u304D\u307E\u305B\u3093");
977
+ return { success: false, error: "SSR \u74B0\u5883\u3067\u306F\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3067\u304D\u307E\u305B\u3093" };
933
978
  }
934
979
  if (authMode === "token") {
935
980
  return redirectToAuthorize();
@@ -938,17 +983,289 @@ function createRedirectMethods(deps) {
938
983
  const loginUrl = `${baseUrl}/login?redirect=${encodeURIComponent(currentUrl)}&service=${encodeURIComponent(serviceCode)}`;
939
984
  logger.debug("Redirecting to login:", loginUrl);
940
985
  window.location.href = loginUrl;
941
- return true;
986
+ return { success: true };
942
987
  }
943
988
  function getLoginUrl(redirectUrl) {
944
- const redirect = redirectUrl ?? (typeof window !== "undefined" ? window.location.href : "");
989
+ let redirect;
990
+ if (redirectUrl != null) {
991
+ redirect = redirectUrl;
992
+ } else if (typeof window !== "undefined") {
993
+ redirect = window.location.href;
994
+ } else {
995
+ logger.warn("getLoginUrl: SSR \u74B0\u5883\u3067 redirectUrl \u304C\u672A\u6307\u5B9A\u306E\u305F\u3081\u7A7A\u6587\u5B57\u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3057\u307E\u3059");
996
+ redirect = "";
997
+ }
945
998
  return `${baseUrl}/login?redirect=${encodeURIComponent(redirect)}&service=${encodeURIComponent(serviceCode)}`;
946
999
  }
947
1000
  function getSignupUrl(redirectUrl) {
948
- const redirect = redirectUrl ?? (typeof window !== "undefined" ? window.location.href : "");
1001
+ let redirect;
1002
+ if (redirectUrl != null) {
1003
+ redirect = redirectUrl;
1004
+ } else if (typeof window !== "undefined") {
1005
+ redirect = window.location.href;
1006
+ } else {
1007
+ logger.warn("getSignupUrl: SSR \u74B0\u5883\u3067 redirectUrl \u304C\u672A\u6307\u5B9A\u306E\u305F\u3081\u7A7A\u6587\u5B57\u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3057\u307E\u3059");
1008
+ redirect = "";
1009
+ }
949
1010
  return `${baseUrl}/signup?redirect=${encodeURIComponent(redirect)}&service=${encodeURIComponent(serviceCode)}`;
950
1011
  }
951
- return { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl };
1012
+ function getLogoutUrl(postLogoutRedirectUri) {
1013
+ const url = new URL(`${baseUrl}${AUTH_LOGOUT_ENDPOINT}`);
1014
+ url.searchParams.set("client_id", clientId);
1015
+ if (postLogoutRedirectUri != null) {
1016
+ url.searchParams.set("post_logout_redirect_uri", postLogoutRedirectUri);
1017
+ }
1018
+ return url.toString();
1019
+ }
1020
+ function redirectToLogout(postLogoutRedirectUri) {
1021
+ if (typeof window === "undefined") {
1022
+ logger.warn("SSR \u74B0\u5883\u3067\u306F\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3067\u304D\u307E\u305B\u3093");
1023
+ return { success: false, error: "SSR \u74B0\u5883\u3067\u306F\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3067\u304D\u307E\u305B\u3093" };
1024
+ }
1025
+ const logoutUrl = getLogoutUrl(postLogoutRedirectUri);
1026
+ logger.debug("Redirecting to logout:", logoutUrl);
1027
+ window.location.href = logoutUrl;
1028
+ return { success: true };
1029
+ }
1030
+ return { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout };
1031
+ }
1032
+
1033
+ // src/client/password-reset.ts
1034
+ var RESET_PASSWORD_BASE = "/api/v1/auth/reset-password";
1035
+ function isBlank(value) {
1036
+ return !value || !value.trim();
1037
+ }
1038
+ function createPasswordResetMethods(deps) {
1039
+ const { baseUrl, logger, createError, fetchWithAuth, errorCodes } = deps;
1040
+ async function fetchPublic(endpoint, options = {}) {
1041
+ const url = `${baseUrl}${endpoint}`;
1042
+ logger.debug("Fetching (public):", url);
1043
+ let response;
1044
+ try {
1045
+ response = await fetch(url, {
1046
+ ...options,
1047
+ credentials: "include",
1048
+ headers: {
1049
+ "Content-Type": "application/json",
1050
+ ...sdkHeaders(),
1051
+ ...options.headers
1052
+ }
1053
+ });
1054
+ } catch (error) {
1055
+ logger.error("Network error:", error);
1056
+ return {
1057
+ error: {
1058
+ code: errorCodes.NETWORK_ERROR,
1059
+ message: error instanceof Error ? error.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
1060
+ }
1061
+ };
1062
+ }
1063
+ let raw;
1064
+ try {
1065
+ raw = await response.json();
1066
+ } catch (parseError) {
1067
+ logger.error("Parse error:", parseError, "Status:", response.status);
1068
+ return {
1069
+ error: {
1070
+ code: errorCodes.PARSE_ERROR,
1071
+ message: `\u30B5\u30FC\u30D0\u30FC\u304B\u3089\u4E0D\u6B63\u306A\u30EC\u30B9\u30DD\u30F3\u30B9\u3092\u53D7\u4FE1\u3057\u307E\u3057\u305F (status: ${response.status})`
1072
+ }
1073
+ };
1074
+ }
1075
+ logger.debug("Response (public):", response.status, raw);
1076
+ checkVersionHeader(response, logger);
1077
+ if (!response.ok) {
1078
+ return {
1079
+ error: raw.error ?? {
1080
+ code: errorCodes.UNKNOWN_ERROR,
1081
+ message: "\u30D1\u30B9\u30EF\u30FC\u30C9\u30EA\u30BB\u30C3\u30C8\u306B\u5931\u6557\u3057\u307E\u3057\u305F"
1082
+ }
1083
+ };
1084
+ }
1085
+ if (raw.data === void 0) {
1086
+ return {
1087
+ error: {
1088
+ code: errorCodes.UNKNOWN_ERROR,
1089
+ message: "\u30B5\u30FC\u30D0\u30FC\u304B\u3089\u30C7\u30FC\u30BF\u304C\u8FD4\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F"
1090
+ }
1091
+ };
1092
+ }
1093
+ return { data: raw.data };
1094
+ }
1095
+ async function requestPasswordReset(email) {
1096
+ if (isBlank(email)) {
1097
+ return {
1098
+ error: createError("VALIDATION_ERROR", "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306F\u5FC5\u9808\u3067\u3059")
1099
+ };
1100
+ }
1101
+ return fetchPublic(
1102
+ RESET_PASSWORD_BASE,
1103
+ {
1104
+ method: "POST",
1105
+ body: JSON.stringify({ email })
1106
+ }
1107
+ );
1108
+ }
1109
+ async function verifyPasswordResetToken(accessToken) {
1110
+ if (isBlank(accessToken)) {
1111
+ return {
1112
+ error: createError("VALIDATION_ERROR", "\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3\u306F\u5FC5\u9808\u3067\u3059")
1113
+ };
1114
+ }
1115
+ const query = new URLSearchParams({
1116
+ access_token: accessToken,
1117
+ type: "recovery"
1118
+ });
1119
+ return fetchPublic(
1120
+ `${RESET_PASSWORD_BASE}/verify?${query.toString()}`
1121
+ );
1122
+ }
1123
+ async function establishResetSession(accessToken, refreshToken) {
1124
+ if (isBlank(accessToken)) {
1125
+ return {
1126
+ error: createError("VALIDATION_ERROR", "\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3\u306F\u5FC5\u9808\u3067\u3059")
1127
+ };
1128
+ }
1129
+ if (isBlank(refreshToken)) {
1130
+ return {
1131
+ error: createError("VALIDATION_ERROR", "\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5\u30C8\u30FC\u30AF\u30F3\u306F\u5FC5\u9808\u3067\u3059")
1132
+ };
1133
+ }
1134
+ return fetchPublic(
1135
+ `${RESET_PASSWORD_BASE}/session`,
1136
+ {
1137
+ method: "POST",
1138
+ body: JSON.stringify({ accessToken, refreshToken })
1139
+ }
1140
+ );
1141
+ }
1142
+ async function confirmPasswordReset(password) {
1143
+ if (isBlank(password)) {
1144
+ return {
1145
+ error: createError("VALIDATION_ERROR", "\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u5FC5\u9808\u3067\u3059")
1146
+ };
1147
+ }
1148
+ return fetchWithAuth(
1149
+ `${RESET_PASSWORD_BASE}/confirm`,
1150
+ {
1151
+ method: "POST",
1152
+ body: JSON.stringify({ password })
1153
+ }
1154
+ );
1155
+ }
1156
+ return {
1157
+ requestPasswordReset,
1158
+ verifyPasswordResetToken,
1159
+ establishResetSession,
1160
+ confirmPasswordReset
1161
+ };
1162
+ }
1163
+
1164
+ // src/client/otp.ts
1165
+ var OTP_BASE = "/api/v1/auth/otp";
1166
+ function isBlank2(value) {
1167
+ return !value || !value.trim();
1168
+ }
1169
+ function createOtpMethods(deps) {
1170
+ const { baseUrl, logger, createError, errorCodes } = deps;
1171
+ async function fetchPublic(endpoint, options = {}) {
1172
+ const url = `${baseUrl}${endpoint}`;
1173
+ logger.debug("Fetching (public):", url);
1174
+ let response;
1175
+ try {
1176
+ response = await fetch(url, {
1177
+ ...options,
1178
+ credentials: "include",
1179
+ headers: {
1180
+ "Content-Type": "application/json",
1181
+ ...sdkHeaders(),
1182
+ ...options.headers
1183
+ }
1184
+ });
1185
+ } catch (error) {
1186
+ logger.error("Network error:", error);
1187
+ return {
1188
+ error: {
1189
+ code: errorCodes.NETWORK_ERROR,
1190
+ message: error instanceof Error ? error.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
1191
+ }
1192
+ };
1193
+ }
1194
+ let raw;
1195
+ try {
1196
+ raw = await response.json();
1197
+ } catch (parseError) {
1198
+ logger.error("Parse error:", parseError, "Status:", response.status);
1199
+ return {
1200
+ error: {
1201
+ code: errorCodes.PARSE_ERROR,
1202
+ message: `\u30B5\u30FC\u30D0\u30FC\u304B\u3089\u4E0D\u6B63\u306A\u30EC\u30B9\u30DD\u30F3\u30B9\u3092\u53D7\u4FE1\u3057\u307E\u3057\u305F (status: ${response.status})`
1203
+ }
1204
+ };
1205
+ }
1206
+ logger.debug("Response (public):", response.status, raw);
1207
+ checkVersionHeader(response, logger);
1208
+ if (!response.ok) {
1209
+ return {
1210
+ error: raw.error ?? {
1211
+ code: errorCodes.UNKNOWN_ERROR,
1212
+ message: "OTP\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F"
1213
+ }
1214
+ };
1215
+ }
1216
+ if (raw.data === void 0) {
1217
+ return {
1218
+ error: {
1219
+ code: errorCodes.UNKNOWN_ERROR,
1220
+ message: "\u30B5\u30FC\u30D0\u30FC\u304B\u3089\u30C7\u30FC\u30BF\u304C\u8FD4\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F"
1221
+ }
1222
+ };
1223
+ }
1224
+ return { data: raw.data };
1225
+ }
1226
+ async function sendOtp(email, options) {
1227
+ if (isBlank2(email)) {
1228
+ return {
1229
+ error: createError("VALIDATION_ERROR", "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306F\u5FC5\u9808\u3067\u3059")
1230
+ };
1231
+ }
1232
+ return fetchPublic(
1233
+ `${OTP_BASE}/send`,
1234
+ {
1235
+ method: "POST",
1236
+ body: JSON.stringify({
1237
+ email,
1238
+ ...options?.redirectUrl ? { redirectUrl: options.redirectUrl } : {}
1239
+ })
1240
+ }
1241
+ );
1242
+ }
1243
+ async function verifyOtp(params) {
1244
+ if (isBlank2(params.accessToken)) {
1245
+ return {
1246
+ error: createError("VALIDATION_ERROR", "\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3\u306F\u5FC5\u9808\u3067\u3059")
1247
+ };
1248
+ }
1249
+ if (isBlank2(params.refreshToken)) {
1250
+ return {
1251
+ error: createError("VALIDATION_ERROR", "\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5\u30C8\u30FC\u30AF\u30F3\u306F\u5FC5\u9808\u3067\u3059")
1252
+ };
1253
+ }
1254
+ return fetchPublic(
1255
+ `${OTP_BASE}/verify`,
1256
+ {
1257
+ method: "POST",
1258
+ body: JSON.stringify({
1259
+ accessToken: params.accessToken,
1260
+ refreshToken: params.refreshToken
1261
+ })
1262
+ }
1263
+ );
1264
+ }
1265
+ return {
1266
+ sendOtp,
1267
+ verifyOtp
1268
+ };
952
1269
  }
953
1270
 
954
1271
  // src/client/ffid-client.ts
@@ -1083,6 +1400,9 @@ function createFFIDClient(config) {
1083
1400
  }
1084
1401
  };
1085
1402
  }
1403
+ } else {
1404
+ logger.warn("Token refresh failed, returning refresh error:", refreshResult.error);
1405
+ return { error: refreshResult.error };
1086
1406
  }
1087
1407
  }
1088
1408
  let raw;
@@ -1133,7 +1453,7 @@ function createFFIDClient(config) {
1133
1453
  }
1134
1454
  return signOutCookie();
1135
1455
  }
1136
- const { redirectToLogin, getLoginUrl, getSignupUrl } = createRedirectMethods({
1456
+ const { redirectToLogin, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout } = createRedirectMethods({
1137
1457
  authMode,
1138
1458
  baseUrl,
1139
1459
  clientId,
@@ -1160,6 +1480,24 @@ function createFFIDClient(config) {
1160
1480
  fetchWithAuth,
1161
1481
  createError
1162
1482
  });
1483
+ const {
1484
+ requestPasswordReset,
1485
+ verifyPasswordResetToken,
1486
+ establishResetSession,
1487
+ confirmPasswordReset
1488
+ } = createPasswordResetMethods({
1489
+ baseUrl,
1490
+ logger,
1491
+ createError,
1492
+ fetchWithAuth,
1493
+ errorCodes: FFID_ERROR_CODES
1494
+ });
1495
+ const { sendOtp, verifyOtp } = createOtpMethods({
1496
+ baseUrl,
1497
+ logger,
1498
+ createError,
1499
+ errorCodes: FFID_ERROR_CODES
1500
+ });
1163
1501
  const verifyAccessToken = createVerifyAccessToken({
1164
1502
  authMode,
1165
1503
  baseUrl,
@@ -1176,7 +1514,9 @@ function createFFIDClient(config) {
1176
1514
  getSession,
1177
1515
  signOut,
1178
1516
  redirectToLogin,
1517
+ redirectToLogout,
1179
1518
  getLoginUrl,
1519
+ getLogoutUrl,
1180
1520
  getSignupUrl,
1181
1521
  createError,
1182
1522
  exchangeCodeForTokens,
@@ -1185,6 +1525,12 @@ function createFFIDClient(config) {
1185
1525
  createCheckoutSession,
1186
1526
  createPortalSession,
1187
1527
  verifyAccessToken,
1528
+ requestPasswordReset,
1529
+ verifyPasswordResetToken,
1530
+ establishResetSession,
1531
+ confirmPasswordReset,
1532
+ sendOtp,
1533
+ verifyOtp,
1188
1534
  /** Token store (token mode only) */
1189
1535
  tokenStore,
1190
1536
  /** Resolved auth mode */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feelflow/ffid-sdk",
3
- "version": "1.11.0",
3
+ "version": "1.14.0",
4
4
  "description": "FeelFlow ID Platform SDK for React/Next.js applications",
5
5
  "keywords": [
6
6
  "feelflow",