@iblai/web-utils 1.2.8 → 1.2.9

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/index.js CHANGED
@@ -2774,22 +2774,22 @@ async function getUserName(storageService) {
2774
2774
  * @param storageService - Storage service to access localStorage
2775
2775
  * @returns boolean indicating if token has expired
2776
2776
  */
2777
- async function isJwtTokenExpired(storageService) {
2777
+ async function isDmTokenExpired(storageService) {
2778
2778
  try {
2779
2779
  const dmTokenExpires = await storageService.getItem(LOCAL_STORAGE_KEYS.DM_TOKEN_EXPIRES);
2780
2780
  if (!dmTokenExpires) {
2781
- return false; // not expired if dm_token_expires not found
2781
+ return true;
2782
2782
  }
2783
2783
  const expiryTime = new Date(dmTokenExpires).getTime();
2784
2784
  const currentTime = Date.now();
2785
2785
  if (currentTime >= expiryTime) {
2786
- console.warn("[AuthProvider] JWT token has expired");
2786
+ console.warn("[AuthProvider] DM token has expired");
2787
2787
  return true;
2788
2788
  }
2789
2789
  return false;
2790
2790
  }
2791
2791
  catch (error) {
2792
- console.error("[AuthProvider] Error checking JWT token expiry:", error);
2792
+ console.error("[AuthProvider] Error checking DM token expiry:", error);
2793
2793
  return true; // Treat as expired on error
2794
2794
  }
2795
2795
  }
@@ -3008,12 +3008,12 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
3008
3008
  }
3009
3009
  // Check JWT token expiry and force logout for protected routes
3010
3010
  if (isProtectedRoute && storageService) {
3011
- const jwtExpired = await isJwtTokenExpired(storageService);
3012
- if (jwtExpired) {
3013
- console.log("[auth-redirect] JWT token has expired, forcing logout");
3011
+ const dmTokenExpired = await isDmTokenExpired(storageService);
3012
+ if (dmTokenExpired) {
3013
+ console.log("[auth-redirect] DM token has expired, forcing logout");
3014
3014
  // Clear all auth-related storage keys
3015
3015
  clearAuthCookies();
3016
- const reason = "JWT token expired";
3016
+ const reason = "DM token expired";
3017
3017
  onAuthFailure === null || onAuthFailure === void 0 ? void 0 : onAuthFailure(reason);
3018
3018
  safeRedirectToAuthSpa(undefined, undefined, true);
3019
3019
  return;
@@ -13611,6 +13611,7 @@ const buildEndpointFromService = (service, serviceFn) => {
13611
13611
  return { data };
13612
13612
  }
13613
13613
  catch (err) {
13614
+ console.error('[data-layer] API error:', JSON.stringify(err, Object.getOwnPropertyNames(err)));
13614
13615
  if (Object.prototype.hasOwnProperty.call(Config.httpErrorHandlers, err === null || err === void 0 ? void 0 : err.status)) {
13615
13616
  Config.httpErrorHandlers[err === null || err === void 0 ? void 0 : err.status]({ ...((err === null || err === void 0 ? void 0 : err.data) || {}) });
13616
13617
  }
@@ -13681,7 +13682,7 @@ const invokeHttpErrorHandler = (status, error) => {
13681
13682
  }
13682
13683
  };
13683
13684
  /** HTTP status codes that should not be retried (e.g., 402 Payment Required). */
13684
- const NON_RETRYABLE_STATUS_CODES = [402];
13685
+ const NON_RETRYABLE_STATUS_CODES = [402, 401];
13685
13686
  /**
13686
13687
  * Wraps a base query to skip retries for non-retryable HTTP status codes.
13687
13688
  * Uses `retry.fail()` to immediately bail out of the retry loop.
@@ -13736,7 +13737,6 @@ const iblFetchBaseQuery = async (args, api, extraOptions) => {
13736
13737
  error: e,
13737
13738
  }));
13738
13739
  // Extract status from error and invoke HTTP error handlers
13739
- console.log('[MONETIZATION e]', { e });
13740
13740
  const err = e;
13741
13741
  const errorStatus = typeof e === 'object' && e !== null && 'status' in e
13742
13742
  ? e.status
@@ -14419,7 +14419,7 @@ createApi({
14419
14419
  });
14420
14420
 
14421
14421
  const featureTags = {
14422
- PLATFORM_USERS: "PLATFORM_USERS",
14422
+ PLATFORM_USERS: 'PLATFORM_USERS',
14423
14423
  };
14424
14424
 
14425
14425
  createApi({
@@ -14731,10 +14731,10 @@ createApi({
14731
14731
  credentials: 'omit',
14732
14732
  });
14733
14733
  if (!response.ok) {
14734
- const error = new Error('Failed to fetch RBAC group details');
14735
- error.status = response.status;
14736
- error.body = await response.text();
14737
- throw error;
14734
+ throw Object.assign(new Error('Failed to fetch RBAC group details'), {
14735
+ status: response.status,
14736
+ body: await response.text(),
14737
+ });
14738
14738
  }
14739
14739
  return response.json();
14740
14740
  }),
@@ -14768,10 +14768,10 @@ createApi({
14768
14768
  credentials: 'omit',
14769
14769
  });
14770
14770
  if (!response.ok) {
14771
- const error = new Error('Failed to fetch RBAC policy details');
14772
- error.status = response.status;
14773
- error.body = await response.text();
14774
- throw error;
14771
+ throw Object.assign(new Error('Failed to fetch RBAC policy details'), {
14772
+ status: response.status,
14773
+ body: await response.text(),
14774
+ });
14775
14775
  }
14776
14776
  return response.json();
14777
14777
  }),
@@ -14809,15 +14809,33 @@ createApi({
14809
14809
  credentials: 'omit',
14810
14810
  });
14811
14811
  if (!response.ok) {
14812
- const error = new Error('Failed to fetch RBAC role details');
14813
- error.status = response.status;
14814
- error.body = await response.text();
14815
- throw error;
14812
+ throw Object.assign(new Error('Failed to fetch RBAC role details'), {
14813
+ status: response.status,
14814
+ body: await response.text(),
14815
+ });
14816
14816
  }
14817
14817
  return response.json();
14818
14818
  }),
14819
14819
  providesTags: ['RbacRoles'],
14820
14820
  }),
14821
+ getDepartmentMemberCheck: builder.query({
14822
+ ...buildEndpointFromService(SERVICES.DM, async (args) => {
14823
+ const queryParams = new URLSearchParams({ platform_key: args.platform_key });
14824
+ const url = `${iblaiApi.OpenAPI.BASE}/api/core/departments/members/check/?${queryParams.toString()}`;
14825
+ const response = await fetch(url, {
14826
+ method: 'GET',
14827
+ headers: iblaiApi.OpenAPI.HEADERS,
14828
+ credentials: 'omit',
14829
+ });
14830
+ if (!response.ok) {
14831
+ throw Object.assign(new Error('Failed to fetch department member check'), {
14832
+ status: response.status,
14833
+ body: await response.text(),
14834
+ });
14835
+ }
14836
+ return response.json();
14837
+ }),
14838
+ }),
14821
14839
  getRbacMentorAccessList: builder.query({
14822
14840
  ...buildEndpointFromDmService(iblaiApi.CoreService.coreRbacMentorAccessList),
14823
14841
  }),
@@ -16092,6 +16110,7 @@ createApi({
16092
16110
  'catalog-roles',
16093
16111
  'catalog-invitations-course',
16094
16112
  'catalog-invitations-program',
16113
+ 'user-assigned-programs',
16095
16114
  ],
16096
16115
  endpoints: (builder) => ({
16097
16116
  getUserReportedSkills: builder.query({
@@ -16199,15 +16218,56 @@ createApi({
16199
16218
  credentials: 'omit',
16200
16219
  });
16201
16220
  if (!response.ok) {
16202
- const error = new Error('Failed to fetch program invitations');
16203
- error.status = response.status;
16204
- error.body = await response.text();
16205
- throw error;
16221
+ throw Object.assign(new Error('Failed to fetch program invitations'), {
16222
+ status: response.status,
16223
+ body: await response.text(),
16224
+ });
16206
16225
  }
16207
16226
  return response.json();
16208
16227
  }),
16209
16228
  providesTags: ['catalog-invitations-program'],
16210
16229
  }),
16230
+ getUserCatalogPathways: builder.query({
16231
+ ...buildEndpointFromService(SERVICES.DM, async (args) => {
16232
+ const params = new URLSearchParams({
16233
+ username: args.username,
16234
+ platform_key: args.platform_key,
16235
+ });
16236
+ const url = `${iblaiApi.OpenAPI.BASE}/api/catalog/pathways/?${params.toString()}`;
16237
+ const response = await fetch(url, {
16238
+ method: 'GET',
16239
+ headers: iblaiApi.OpenAPI.HEADERS,
16240
+ credentials: 'omit',
16241
+ });
16242
+ if (!response.ok) {
16243
+ throw Object.assign(new Error('Failed to fetch user catalog pathways'), {
16244
+ status: response.status,
16245
+ body: await response.text(),
16246
+ });
16247
+ }
16248
+ return response.json();
16249
+ }),
16250
+ providesTags: ['user-catalog-pathways'],
16251
+ }),
16252
+ getAssignedPrograms: builder.query({
16253
+ ...buildEndpointFromService(SERVICES.DM, async (args) => {
16254
+ const params = new URLSearchParams({ user_id: String(args.user_id) });
16255
+ const url = `${iblaiApi.OpenAPI.BASE}/api/catalog/suggestions/program/user/?${params.toString()}`;
16256
+ const response = await fetch(url, {
16257
+ method: 'GET',
16258
+ headers: iblaiApi.OpenAPI.HEADERS,
16259
+ credentials: 'omit',
16260
+ });
16261
+ if (!response.ok) {
16262
+ throw Object.assign(new Error('Failed to fetch assigned programs'), {
16263
+ status: response.status,
16264
+ body: await response.text(),
16265
+ });
16266
+ }
16267
+ return response.json();
16268
+ }),
16269
+ providesTags: ['user-assigned-programs'],
16270
+ }),
16211
16271
  }),
16212
16272
  });
16213
16273
 
@@ -16229,6 +16289,114 @@ createApi({
16229
16289
  }),
16230
16290
  });
16231
16291
 
16292
+ createApi({
16293
+ reducerPath: 'coursesApiSlice',
16294
+ baseQuery: iblFetchBaseQuery,
16295
+ tagTypes: ['user-enrolled-courses', 'user-assigned-courses'],
16296
+ endpoints: (builder) => ({
16297
+ getUserEnrolledCourses: builder.query({
16298
+ query: ({ username, query }) => {
16299
+ const params = new URLSearchParams();
16300
+ params.set('username', username);
16301
+ if (query) {
16302
+ for (const [k, v] of Object.entries(query)) {
16303
+ if (v !== undefined && v !== null)
16304
+ params.set(k, String(v));
16305
+ }
16306
+ }
16307
+ return {
16308
+ url: `/api/catalog/enrollment/courses/search/?${params.toString()}`,
16309
+ service: SERVICES.DM,
16310
+ method: 'GET',
16311
+ };
16312
+ },
16313
+ providesTags: ['user-enrolled-courses'],
16314
+ }),
16315
+ getUserAssignedCourses: builder.query({
16316
+ query: ({ user_id, query }) => {
16317
+ const params = new URLSearchParams();
16318
+ params.set('user_id', String(user_id));
16319
+ if (query) {
16320
+ for (const [k, v] of Object.entries(query)) {
16321
+ if (v !== undefined && v !== null)
16322
+ params.set(k, String(v));
16323
+ }
16324
+ }
16325
+ return {
16326
+ url: `/api/catalog/suggestions/course/user/?${params.toString()}`,
16327
+ service: SERVICES.DM,
16328
+ method: 'GET',
16329
+ };
16330
+ },
16331
+ providesTags: ['user-assigned-courses'],
16332
+ }),
16333
+ }),
16334
+ });
16335
+
16336
+ createApi({
16337
+ reducerPath: 'courseMetadataApiSlice',
16338
+ baseQuery: iblFetchBaseQuery,
16339
+ endpoints: (builder) => ({
16340
+ getCourseMetaData: builder.query({
16341
+ query: ({ courseKey }) => ({
16342
+ url: `/api/ibl/v1/course_metadata?course_key=${encodeURIComponent(courseKey)}`,
16343
+ service: SERVICES.LMS,
16344
+ method: 'GET',
16345
+ }),
16346
+ }),
16347
+ getCourseCompletionOutlines: builder.query({
16348
+ query: ({ courseKey }) => ({
16349
+ url: `/api/ibl/completion/course_outline/${courseKey}?course_id=${encodeURIComponent(courseKey)}`,
16350
+ service: SERVICES.LMS,
16351
+ method: 'GET',
16352
+ }),
16353
+ }),
16354
+ getCourseEligibility: builder.query({
16355
+ query: ({ courseKey }) => ({
16356
+ url: `/api/ibl/enrollment/enroll_status?course_id=${encodeURIComponent(courseKey)}`,
16357
+ service: SERVICES.LMS,
16358
+ method: 'GET',
16359
+ }),
16360
+ }),
16361
+ createCourseEnrollment: builder.mutation({
16362
+ query: (body) => ({
16363
+ url: `/api/enrollment/v1/enrollment`,
16364
+ service: SERVICES.LMS,
16365
+ method: 'POST',
16366
+ body,
16367
+ }),
16368
+ }),
16369
+ getCourseProgress: builder.query({
16370
+ query: ({ courseKey }) => ({
16371
+ url: `/api/course_home/progress/${courseKey}`,
16372
+ service: SERVICES.LMS,
16373
+ method: 'GET',
16374
+ }),
16375
+ }),
16376
+ getCourseCompletion: builder.query({
16377
+ query: ({ courseKey, userID }) => ({
16378
+ url: `/api/catalog/milestones/completions/course/manage/?course_id=${courseKey}&user_id=${userID}`,
16379
+ service: SERVICES.DM,
16380
+ method: 'GET',
16381
+ }),
16382
+ }),
16383
+ }),
16384
+ });
16385
+
16386
+ createApi({
16387
+ reducerPath: 'edxSsoApiSlice',
16388
+ baseQuery: iblFetchBaseQuery,
16389
+ endpoints: (builder) => ({
16390
+ getEdxSSOToken: builder.query({
16391
+ query: ({ username, redirectUrl }) => ({
16392
+ url: `/ibl/ai/sso/backend/edx/sso-auth-token/generate?username=${encodeURIComponent(username)}&redirect_url=${encodeURIComponent(redirectUrl)}`,
16393
+ service: SERVICES.LMS,
16394
+ method: 'GET',
16395
+ }),
16396
+ }),
16397
+ }),
16398
+ });
16399
+
16232
16400
  createApi({
16233
16401
  reducerPath: 'searchApiSlice',
16234
16402
  baseQuery: iblFakeBaseQuery,
@@ -16902,6 +17070,7 @@ const MEMORY_QUERY_KEYS = {
16902
17070
  MEMSEARCH_MENTOR_MEMORIES: () => ['MEMSEARCH_MENTOR_MEMORIES'],
16903
17071
  MEMSEARCH_MEMORY_CATEGORIES: () => ['MEMSEARCH_MEMORY_CATEGORIES'],
16904
17072
  MEMSEARCH_PLATFORM_CONFIG: () => ['MEMSEARCH_PLATFORM_CONFIG'],
17073
+ MEMSEARCH_STATUS: () => ['MEMSEARCH_STATUS'],
16905
17074
  };
16906
17075
  const MEMSEARCH_ENDPOINTS = {
16907
17076
  // User Memory Settings
@@ -16969,6 +17138,11 @@ const MEMSEARCH_ENDPOINTS = {
16969
17138
  service: SERVICES.AXD,
16970
17139
  path: (org, userId) => `/api/ai-mentor/orgs/${org}/users/${userId}/memsearch-config/`,
16971
17140
  },
17141
+ // Memsearch Status (available to students and admins)
17142
+ GET_MEMSEARCH_STATUS: {
17143
+ service: SERVICES.AXD,
17144
+ path: (org, userId) => `/api/ai-mentor/orgs/${org}/users/${userId}/memsearch-status/`,
17145
+ },
16972
17146
  };
16973
17147
 
16974
17148
  createApi({
@@ -16979,6 +17153,7 @@ createApi({
16979
17153
  ...MEMORY_QUERY_KEYS.MEMSEARCH_MENTOR_MEMORIES(),
16980
17154
  ...MEMORY_QUERY_KEYS.MEMSEARCH_MEMORY_CATEGORIES(),
16981
17155
  ...MEMORY_QUERY_KEYS.MEMSEARCH_PLATFORM_CONFIG(),
17156
+ ...MEMORY_QUERY_KEYS.MEMSEARCH_STATUS(),
16982
17157
  ],
16983
17158
  baseQuery: iblFetchBaseQuery,
16984
17159
  endpoints: (builder) => ({
@@ -17111,6 +17286,14 @@ createApi({
17111
17286
  }),
17112
17287
  invalidatesTags: MEMORY_QUERY_KEYS.MEMSEARCH_PLATFORM_CONFIG(),
17113
17288
  }),
17289
+ // Memsearch Status (student + admin accessible)
17290
+ getMemsearchStatus: builder.query({
17291
+ query: (args) => ({
17292
+ url: MEMSEARCH_ENDPOINTS.GET_MEMSEARCH_STATUS.path(args.org, args.userId),
17293
+ service: MEMSEARCH_ENDPOINTS.GET_MEMSEARCH_STATUS.service,
17294
+ }),
17295
+ providesTags: MEMORY_QUERY_KEYS.MEMSEARCH_STATUS(),
17296
+ }),
17114
17297
  }),
17115
17298
  });
17116
17299
 
@@ -18091,6 +18274,33 @@ createApi({
18091
18274
  }),
18092
18275
  });
18093
18276
 
18277
+ const AUDIT_LOGS_REDUCER_PATH = 'auditLogsApiSlice';
18278
+ const AUDIT_LOGS_QUERY_KEYS = {
18279
+ GET_AUDIT_LOGS: () => ['AUDIT_LOGS'],
18280
+ };
18281
+ const AUDIT_LOGS_ENDPOINTS = {
18282
+ GET_AUDIT_LOGS: {
18283
+ service: SERVICES.AXD,
18284
+ path: (org, userId) => `/api/ai-mentor/orgs/${org}/users/${userId}/mentors/audit-logs/`,
18285
+ },
18286
+ };
18287
+
18288
+ createApi({
18289
+ reducerPath: AUDIT_LOGS_REDUCER_PATH,
18290
+ tagTypes: [...AUDIT_LOGS_QUERY_KEYS.GET_AUDIT_LOGS()],
18291
+ baseQuery: iblFetchBaseQuery,
18292
+ endpoints: (builder) => ({
18293
+ getAuditLogs: builder.query({
18294
+ query: (args) => ({
18295
+ url: AUDIT_LOGS_ENDPOINTS.GET_AUDIT_LOGS.path(args.org, args.userId),
18296
+ service: AUDIT_LOGS_ENDPOINTS.GET_AUDIT_LOGS.service,
18297
+ params: args.params,
18298
+ }),
18299
+ providesTags: AUDIT_LOGS_QUERY_KEYS.GET_AUDIT_LOGS(),
18300
+ }),
18301
+ }),
18302
+ });
18303
+
18094
18304
  function useMentorSettings({ mentorId, tenantKey, username, isPublicRoute, }) {
18095
18305
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
18096
18306
  const isLoggedIn = username !== ANONYMOUS_USERNAME;