@bmc-soft/keycloak-auth 1.0.11 → 2.0.1

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.
Files changed (99) hide show
  1. package/README.md +115 -59
  2. package/dist/_lib/types/confirmAuthPhase.d.ts +1 -2
  3. package/dist/_lib/types/confirmAuthPhase.d.ts.map +1 -1
  4. package/dist/_lib/types/confirmAuthPhase.js +1 -2
  5. package/dist/_lib/types/confirmAuthPhase.js.map +1 -1
  6. package/dist/axios/adapters/KeycloakTokenProvider.js +8 -8
  7. package/dist/axios/adapters/KeycloakTokenProvider.js.map +1 -1
  8. package/dist/axios/interceptors.js +2 -2
  9. package/dist/axios/interceptors.js.map +1 -1
  10. package/dist/context/KeycloakConfigContext.d.ts +17 -1
  11. package/dist/context/KeycloakConfigContext.d.ts.map +1 -1
  12. package/dist/context/KeycloakConfigContext.js +36 -2
  13. package/dist/context/KeycloakConfigContext.js.map +1 -1
  14. package/dist/context/KeycloakInstanceContext.d.ts +2 -0
  15. package/dist/context/KeycloakInstanceContext.d.ts.map +1 -1
  16. package/dist/context/KeycloakInstanceContext.js +59 -16
  17. package/dist/context/KeycloakInstanceContext.js.map +1 -1
  18. package/dist/context/KeycloakProvider.d.ts +7 -1
  19. package/dist/context/KeycloakProvider.d.ts.map +1 -1
  20. package/dist/context/KeycloakProvider.js +3 -3
  21. package/dist/context/KeycloakProvider.js.map +1 -1
  22. package/dist/context/ReauthContext.d.ts +3 -1
  23. package/dist/context/ReauthContext.d.ts.map +1 -1
  24. package/dist/context/ReauthContext.js +6 -2
  25. package/dist/context/ReauthContext.js.map +1 -1
  26. package/dist/context/TokenContext.d.ts +2 -0
  27. package/dist/context/TokenContext.d.ts.map +1 -1
  28. package/dist/context/TokenContext.js +14 -6
  29. package/dist/context/TokenContext.js.map +1 -1
  30. package/dist/context/index.d.ts +2 -2
  31. package/dist/context/index.d.ts.map +1 -1
  32. package/dist/context/index.js +1 -1
  33. package/dist/context/index.js.map +1 -1
  34. package/dist/context/reauthRequiredRef.d.ts +2 -1
  35. package/dist/context/reauthRequiredRef.d.ts.map +1 -1
  36. package/dist/context/reauthRequiredRef.js.map +1 -1
  37. package/dist/core/adapter.d.ts.map +1 -1
  38. package/dist/core/adapter.js +30 -4
  39. package/dist/core/adapter.js.map +1 -1
  40. package/dist/core/index.d.ts +3 -1
  41. package/dist/core/index.d.ts.map +1 -1
  42. package/dist/core/index.js +1 -0
  43. package/dist/core/index.js.map +1 -1
  44. package/dist/core/sessionPolicy.d.ts +21 -0
  45. package/dist/core/sessionPolicy.d.ts.map +1 -0
  46. package/dist/core/sessionPolicy.js +63 -0
  47. package/dist/core/sessionPolicy.js.map +1 -0
  48. package/dist/core/types.d.ts +14 -0
  49. package/dist/core/types.d.ts.map +1 -1
  50. package/dist/hooks/useKeycloakAuth.d.ts +3 -0
  51. package/dist/hooks/useKeycloakAuth.d.ts.map +1 -1
  52. package/dist/hooks/useKeycloakAuth.js +12 -7
  53. package/dist/hooks/useKeycloakAuth.js.map +1 -1
  54. package/dist/index.d.ts +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/screens/AuthPage/AuthPage.d.ts +2 -0
  58. package/dist/screens/AuthPage/AuthPage.d.ts.map +1 -1
  59. package/dist/screens/AuthPage/AuthPage.js +12 -15
  60. package/dist/screens/AuthPage/AuthPage.js.map +1 -1
  61. package/dist/screens/ConfirmAuthPage/ConfirmAuthPage.d.ts +2 -1
  62. package/dist/screens/ConfirmAuthPage/ConfirmAuthPage.d.ts.map +1 -1
  63. package/dist/screens/ConfirmAuthPage/ConfirmAuthPage.js +67 -52
  64. package/dist/screens/ConfirmAuthPage/ConfirmAuthPage.js.map +1 -1
  65. package/dist/screens/ConfirmAuthPage/index.d.ts +1 -0
  66. package/dist/screens/ConfirmAuthPage/index.d.ts.map +1 -1
  67. package/dist/screens/index.d.ts +1 -0
  68. package/dist/screens/index.d.ts.map +1 -1
  69. package/dist/storage/credentialStorage.d.ts +8 -0
  70. package/dist/storage/credentialStorage.d.ts.map +1 -1
  71. package/dist/storage/credentialStorage.js +99 -1
  72. package/dist/storage/credentialStorage.js.map +1 -1
  73. package/dist/storage/tokenStorage.d.ts +10 -0
  74. package/dist/storage/tokenStorage.d.ts.map +1 -1
  75. package/dist/storage/tokenStorage.js +30 -8
  76. package/dist/storage/tokenStorage.js.map +1 -1
  77. package/dist/ui/LogoutConfirmSheet/LogoutConfirmSheet.js +4 -2
  78. package/dist/ui/LogoutConfirmSheet/LogoutConfirmSheet.js.map +1 -1
  79. package/dist/ui/NumberPad/NumberPad.d.ts.map +1 -1
  80. package/dist/ui/NumberPad/NumberPad.js +16 -9
  81. package/dist/ui/NumberPad/NumberPad.js.map +1 -1
  82. package/dist/ui/PINConfirm/PINConfirm.d.ts.map +1 -1
  83. package/dist/ui/PINConfirm/PINConfirm.js +7 -7
  84. package/dist/ui/PINConfirm/PINConfirm.js.map +1 -1
  85. package/dist/ui/PINSetup/stages/BiometryStage.d.ts.map +1 -1
  86. package/dist/ui/PINSetup/stages/BiometryStage.js +6 -2
  87. package/dist/ui/PINSetup/stages/BiometryStage.js.map +1 -1
  88. package/dist/ui/PINSetup/styles.d.ts +0 -1
  89. package/dist/ui/PINSetup/styles.d.ts.map +1 -1
  90. package/dist/ui/PINSetup/styles.js +0 -1
  91. package/dist/ui/PINSetup/styles.js.map +1 -1
  92. package/dist/ui/WebViewLogin/WebViewLogin.d.ts.map +1 -1
  93. package/dist/ui/WebViewLogin/WebViewLogin.js +2 -2
  94. package/dist/ui/WebViewLogin/WebViewLogin.js.map +1 -1
  95. package/dist/widgets/ReauthBottomSheet/ReauthBottomSheet.d.ts +2 -0
  96. package/dist/widgets/ReauthBottomSheet/ReauthBottomSheet.d.ts.map +1 -1
  97. package/dist/widgets/ReauthBottomSheet/ReauthBottomSheet.js +12 -5
  98. package/dist/widgets/ReauthBottomSheet/ReauthBottomSheet.js.map +1 -1
  99. package/package.json +1 -1
package/README.md CHANGED
@@ -60,9 +60,9 @@ import { AuthPage } from '@bmc-soft/keycloak-auth';
60
60
  const LoginScreen = () => (
61
61
  <AuthPage
62
62
  logo={require('./logo.png')}
63
- onSuccess={(token) => {
64
- // Сохраняем токен в сессию приложения и переходим
65
- saveToken(token);
63
+ onSuccess={(accessToken) => {
64
+ // Сохраняем access token в сессию приложения и переходим
65
+ Session.events.onLogin(accessToken);
66
66
  navigation.replace('Home');
67
67
  }}
68
68
  onError={(err) => console.error(err)}
@@ -74,6 +74,18 @@ const LoginScreen = () => (
74
74
 
75
75
  Если используете axios, задайте провайдер токенов (см. [Axios](#axios)) и вызовите `setupAxiosInterceptors` с `tokenProvider` и `onReauthRequired`. Провайдер обычно настраивается внутри KeycloakProvider после инициализации keycloak (см. [Интеграция](#интеграция)).
76
76
 
77
+ ### Требования к Keycloak client
78
+
79
+ Для нового mobile flow настройте Keycloak client как:
80
+
81
+ - **Client type**: public
82
+ - **Flow**: Authorization Code / Standard Flow
83
+ - **PKCE**: required, `S256`
84
+ - **Scope**: разрешён `offline_access`
85
+ - **Redirect URI**: только URI приложения, например `myapp://callback`
86
+
87
+ `client_secret` не передаётся и не хранится в React Native приложении.
88
+
77
89
  ---
78
90
 
79
91
  ## Провайдер и конфигурация
@@ -83,10 +95,12 @@ const LoginScreen = () => (
83
95
  | Проп | Тип | Обязательный | Описание |
84
96
  |------|-----|--------------|----------|
85
97
  | `children` | ReactNode | да | Дерево приложения |
86
- | `config` | KeycloakConfigWith2FA | да | `url`, `realm`, `clientId`; опционально `clientId2fa` для первого входа с 2FA |
98
+ | `config` | KeycloakConfigWith2FA | да | `url`, `realm`, `clientId`; `clientId2fa` оставлен для legacy-сценариев, новый мобильный flow использует один public client + PKCE |
87
99
  | `redirectUri` | string | да | URI OAuth callback (например `myapp://callback`) |
88
100
  | `theme` | KeycloakTheme | нет | Цвета, шрифты, LoaderComponent, компоненты кнопок |
89
101
  | `onTokens` | (tokens: KeycloakTokens) => void | нет | Вызывается при изменении токенов (логин, refresh, logout) |
102
+ | `offlineAccessEnabled` | boolean | нет | Запрашивать `offline_access` в login URL; по умолчанию `true` |
103
+ | `backgroundReauth` | `{ enabled?: boolean; thresholdMs?: number; internalNetworkMode?: 'ip-host-is-internal' }` | нет | Настройки PIN/биометрии после возврата из background; по умолчанию `enabled: true`, `thresholdMs: 60000` |
90
104
  | `autoRefreshToken` | boolean | нет | По умолчанию `true` |
91
105
  | `autoRefreshTokenMinValidity` | number | нет | За сколько секунд до истечения вызывать refresh; по умолчанию `5` |
92
106
  | `onReauthRequired` | () => void | нет | Вызывается при ошибке обновления токена (например показать экран реавторизации) |
@@ -124,20 +138,26 @@ const LoginScreen = () => (
124
138
 
125
139
  #### ConfirmAuthPage
126
140
 
127
- Подтверждение сессии: фазы webview_detect pin webview_with_credentials (если сохранены учётные данные). Используется на экране «Подтверждение PIN» и внутри BottomSheet реавторизации.
141
+ Подтверждение сессии: сначала PIN/биометрия, затем продолжение с текущим access token или refresh через offline token. Если repeat-login не может восстановить токены через offline token, открывается обычный Keycloak login. Скрытый ввод username/password в новом flow не используется.
142
+
143
+ Режимы:
144
+
145
+ - `login` — повторный вход в приложение; при невозможности refresh открывает обычный Keycloak login.
146
+ - `unlock` — локальная разблокировка после background; refresh выполняется только если access token уже истёк.
147
+ - `reauth` — повторная авторизация после 401; refresh через offline token обязателен.
128
148
 
129
149
  | Проп | Тип | По умолчанию | Описание |
130
150
  |------|-----|--------------|----------|
131
- | `onSuccess` | () => void | — | Успех (редирект или PIN без credentials) |
151
+ | `onSuccess` | () => void | — | Успешное локальное подтверждение и восстановление/проверка access token |
132
152
  | `onError` | (error: Error) => void | — | Например неверный PIN |
133
153
  | `onLogout` | () => void | — | После очистки хранилища пакета; в приложении — очистить сессию и перейти на экран входа |
154
+ | `mode` | `'login' \| 'unlock' \| 'reauth'` | `"login"` | Сценарий: повторный вход, unlock после background или reauth после 401 |
134
155
  | `logoutText` | string | "Выйти из аккаунта" | Текст ссылки «Выйти» |
135
156
  | `logo`, `logoHeight`, `logoWidth` | — | 80 | Логотип |
136
157
  | `pinLength` | number | 4 | Длина PIN |
137
158
  | `allowBiometry`, `autoShowBiometry` | boolean | true | Биометрия |
138
159
  | `title`, `description` | string | — | Заголовок и описание блока PIN |
139
160
  | `style` | ViewStyle | — | Стиль контейнера |
140
- | `webViewTimeoutMs` | number | 3000 | Задержка (мс) в фазе webview_detect перед переходом на PIN |
141
161
 
142
162
  ### Виджеты
143
163
 
@@ -152,10 +172,9 @@ BottomSheet с подтверждением PIN для реавторизаци
152
172
  | `onError` | (error: Error) => void | — | Ошибка ввода PIN |
153
173
  | `pinLength` | number | 4 | Длина PIN |
154
174
  | `allowBiometry`, `autoShowBiometry` | boolean | true | Биометрия |
175
+ | `mode` | `'login' \| 'unlock' \| 'reauth'` | авто | Если не передан, `background` открывается как `unlock`, остальные причины как `reauth` |
155
176
  | `title` | string | "Подтвердите вход" | Заголовок |
156
177
  | `description` | string | "Введите PIN-код" | Описание |
157
- | `footer` | ReactNode | — | Опциональный футер |
158
- | `snapPointPercentage` | number | 50 | Высота sheet в % |
159
178
 
160
179
  ### Кнопки выхода
161
180
 
@@ -187,15 +206,15 @@ BottomSheet с подтверждением PIN для реавторизаци
187
206
 
188
207
  Полный API авторизации: инстанс keycloak, токен, login, logout, URL, состояние реавторизации.
189
208
 
190
- Возвращает: `keycloak`, `isInitialized`, `isLoading`, `error`, `token`, `isExpired`, `isAuthenticated`, `updateToken`, `login`, `logout`, `loadUserProfile`, `createLoginUrl`, `createLogoutUrl`, `clearTokens`, `isReauthRequired`, `showReauth`, `hideReauth`.
209
+ Возвращает: `keycloak`, `isInitialized`, `isLoading`, `error`, `accessToken`, `token`, `offlineToken`, `refreshToken`, `isExpired`, `isAuthenticated`, `updateToken`, `login`, `logout`, `loadUserProfile`, `createLoginUrl`, `createLogoutUrl`, `clearTokens`, `isReauthRequired`, `showReauth`, `hideReauth`.
191
210
 
192
211
  ### useToken()
193
212
 
194
- Доступ только к токенам (меньше ре-рендеров). Возвращает: `token`, `refreshToken`, `idToken`, `isExpired`, `updateToken`, `clearTokens`.
213
+ Доступ только к токенам (меньше ре-рендеров). Возвращает: `accessToken`, `token`, `offlineToken`, `refreshToken`, `idToken`, `isExpired`, `updateToken`, `clearTokens`.
195
214
 
196
215
  ### useReauth()
197
216
 
198
- Состояние UI реавторизации. Возвращает: `isReauthRequired`, `showReauth`, `hideReauth`.
217
+ Состояние UI реавторизации. Возвращает: `isReauthRequired`, `reauthReason`, `showReauth`, `hideReauth`.
199
218
 
200
219
  **Состояние isReauthRequired:**
201
220
 
@@ -209,7 +228,7 @@ BottomSheet с подтверждением PIN для реавторизаци
209
228
 
210
229
  Возвращает: `screen: 'login' | 'confirm' | null`, `isLoading`, `error`.
211
230
 
212
- Опции: `shouldShowConfirm?: () => Promise<boolean>` — переопределить стандартную проверку (наличие токенов и PIN).
231
+ Опции: `shouldShowConfirm?: () => Promise<boolean>` — переопределить стандартную проверку (наличие offline token и PIN).
213
232
 
214
233
  ### useKeycloakTheme()
215
234
 
@@ -221,15 +240,15 @@ BottomSheet с подтверждением PIN для реавторизаци
221
240
 
222
241
  ### tokenStorage
223
242
 
224
- Хранение токенов в Keychain. API: `getToken`, `saveToken`, `getRefreshToken`, `saveRefreshToken`, `getIdToken`, `saveIdToken`, `getTokens`, `saveTokens`, `clearTokens`, `hasTokens`.
243
+ Хранение токенов в Keychain. API: `getToken`/`getAccessToken`, `saveToken`/`saveAccessToken`, `getRefreshToken`/`getOfflineToken`, `saveRefreshToken`/`saveOfflineToken`, `getIdToken`, `saveIdToken`, `getTokens`, `saveTokens`, `clearTokens`, `hasTokens`.
225
244
 
226
- После успешного ConfirmAuthPage (например при реавторизации) вызовите `tokenStorage.getToken()`, чтобы получить текущий access token и обновить сессию приложения.
245
+ `refresh_token` из Keycloak при `offline_access` хранится как offline token. Он не отправляется в backend; backend получает только `Authorization: Bearer <accessToken>`. После успешного ConfirmAuthPage вызовите `tokenStorage.getAccessToken()`, чтобы получить текущий access token и обновить сессию приложения.
227
246
 
228
247
  > **Важно**: не храните токены в AsyncStorage. Используйте только Keychain через пакет.
229
248
 
230
249
  ### credentialStorage
231
250
 
232
- Используется внутри пакета для зашифрованных учётных данных и биометрии. Экспортируется для продвинутых сценариев (например очистка PIN/credentials при выходе).
251
+ Используется внутри пакета для PIN-verifier и биометрии. Legacy-хранение зашифрованных credentials оставлено для совместимости, но новый offline_access flow не использует username/password для повторного входа.
233
252
 
234
253
  ---
235
254
 
@@ -264,7 +283,7 @@ BottomSheet с подтверждением PIN для реавторизаци
264
283
 
265
284
  ### 1. Оборачивание приложения в KeycloakProvider
266
285
 
267
- Конфиг и `redirectUri` берут из настроек приложения. Тему (Loader, кнопки, цвета) передайте из темы приложения. В `onTokens` сохраняйте токен в хранилище сессии; в `onReauthRequired` показывайте экран реавторизации.
286
+ Конфиг и `redirectUri` берут из настроек приложения. Тему (Loader, кнопки, цвета) передайте из темы приложения. В `onTokens` сохраняйте access token в хранилище сессии; в `onReauthRequired` показывайте экран реавторизации.
268
287
 
269
288
  **Порядок провайдеров**: если используется `BottomSheetModalProvider` из `@gorhom/bottom-sheet` (например для реавторизации или других модалок), он должен находиться **внутри** KeycloakProvider. Иначе ReauthBottomSheet или ConfirmAuthPage внутри модалки не получат контекст Keycloak. Порядок: `KeycloakProvider` → `BottomSheetModalProvider` → остальное дерево приложения.
270
289
 
@@ -297,8 +316,8 @@ export const App = () => (
297
316
  }}
298
317
  redirectUri="myapp://callback"
299
318
  theme={theme}
300
- onTokens={({ token }) => {
301
- Session.events.onChangeAuthToken(token);
319
+ onTokens={({ accessToken }) => {
320
+ Session.events.onChangeAuthToken(accessToken);
302
321
  }}
303
322
  onReauthRequired={() => {
304
323
  Session.events.onRequireReauth();
@@ -313,26 +332,34 @@ export const App = () => (
313
332
 
314
333
  ### 2. Установка TokenProvider для axios
315
334
 
316
- Провайдер токенов настраивается один раз внутри KeycloakProvider после инициализации keycloak (например во вспомогательном компоненте). Не дублируйте настройку на экране логина.
335
+ Провайдер токенов настраивается один раз внутри KeycloakProvider после инициализации keycloak. Он отдаёт backend только access token, а refresh выполняет через offline token.
317
336
 
318
337
  ```tsx
319
- import { useKeycloakAuth } from '@bmc-soft/keycloak-auth';
320
- import { setKeycloakTokenProvider, resetKeycloakTokenProvider } from './axios';
338
+ import {
339
+ KeycloakTokenProvider,
340
+ setupAxiosInterceptors,
341
+ useKeycloakAuth,
342
+ } from '@bmc-soft/keycloak-auth';
343
+
344
+ const api = axios.create({ baseURL: 'https://api.example.com' });
321
345
 
322
346
  const KeycloakAxiosTokenProviderSetup = ({ children }) => {
323
347
  const { keycloak, isInitialized } = useKeycloakAuth();
324
348
 
325
349
  useEffect(() => {
326
- if (isInitialized && keycloak) {
327
- setKeycloakTokenProvider({
328
- getToken: () => keycloak.token || null,
329
- updateToken: async (minValidity) => {
330
- const result = await keycloak.updateToken(minValidity);
331
- return result !== null;
332
- },
333
- });
334
- }
335
- return () => resetKeycloakTokenProvider();
350
+ if (!isInitialized || !keycloak) return undefined;
351
+
352
+ const { cleanup } = setupAxiosInterceptors(api, {
353
+ tokenProvider: new KeycloakTokenProvider(keycloak),
354
+ onReauthRequired: () => {
355
+ Session.events.onRequireReauth();
356
+ },
357
+ onTokenRefreshed: (accessToken) => {
358
+ Session.events.onChangeAuthToken(accessToken);
359
+ },
360
+ });
361
+
362
+ return cleanup;
336
363
  }, [isInitialized, keycloak]);
337
364
 
338
365
  return <>{children}</>;
@@ -348,29 +375,27 @@ const KeycloakAxiosTokenProviderSetup = ({ children }) => {
348
375
  </KeycloakProvider>
349
376
  ```
350
377
 
351
- Подключение интерцепторов к инстансу axios (там, где он создаётся):
378
+ Если у приложения уже есть свой `tokenProvider`, его методы должны соблюдать тот же контракт:
352
379
 
353
380
  ```tsx
354
- import { setupAxiosInterceptors } from '@bmc-soft/keycloak-auth';
355
- import { getKeycloakTokenProvider } from './keycloakTokenProvider';
356
-
357
- const api = axios.create({ baseURL: 'https://api.example.com' });
358
-
359
381
  setupAxiosInterceptors(api, {
360
382
  tokenProvider: {
361
- getToken: () => getKeycloakTokenProvider()?.getToken() ?? null,
362
- refreshToken: () =>
363
- getKeycloakTokenProvider()
364
- ?.updateToken(120)
365
- .then((ok) => (ok ? getKeycloakTokenProvider()?.getToken() ?? null : null)),
383
+ getToken: () => keycloak.token || null,
384
+ refreshToken: async () => {
385
+ await keycloak.updateToken(-1);
386
+ return keycloak.token || null;
387
+ },
388
+ hasRefreshToken: () => Boolean(keycloak.refreshToken),
389
+ },
390
+ onReauthRequired: () => {
391
+ Session.events.onRequireReauth();
366
392
  },
367
- onReauthRequired: () => Session.events.onRequireReauth(),
368
393
  });
369
394
  ```
370
395
 
371
396
  ### 3. Стек авторизации (Login + Confirm)
372
397
 
373
- Два экрана: Login (AuthPage) и Confirm (ConfirmAuthPage). Начальный маршрут задаётся через `useKeycloakAuthScreen()`: показывать Confirm, если есть токены и PIN, иначе Login.
398
+ Два экрана: Login (AuthPage) и Confirm (ConfirmAuthPage). Начальный маршрут задаётся через `useKeycloakAuthScreen()`: показывать Confirm, если есть offline token и PIN, иначе Login.
374
399
 
375
400
  ```tsx
376
401
  import { useKeycloakAuthScreen, AuthPage, ConfirmAuthPage, tokenStorage } from '@bmc-soft/keycloak-auth';
@@ -395,7 +420,7 @@ export const AuthStack = () => {
395
420
  const LoginScreen = () => (
396
421
  <AuthPage
397
422
  logo={require('./logo.png')}
398
- onSuccess={(token) => Session.events.onLogin(token)}
423
+ onSuccess={(accessToken) => Session.events.onLogin(accessToken)}
399
424
  onError={(err) => console.error(err)}
400
425
  />
401
426
  );
@@ -404,8 +429,8 @@ const ConfirmScreen = () => {
404
429
  const navigation = useNavigation();
405
430
 
406
431
  const onSuccess = useCallback(async () => {
407
- const token = await tokenStorage.getToken();
408
- if (token) Session.events.onLogin(token);
432
+ const accessToken = await tokenStorage.getAccessToken();
433
+ if (accessToken) Session.events.onLogin(accessToken);
409
434
  }, []);
410
435
 
411
436
  return (
@@ -423,7 +448,7 @@ const ConfirmScreen = () => {
423
448
 
424
449
  ### 4. Реавторизация при 401
425
450
 
426
- При 401 интерцепторы вызывают `onReauthRequired`. Можно использовать `isReauthRequired` из `useKeycloakAuth()` как единственный источник правды для отображения реавторизации. Если используете готовый **ReauthBottomSheet** из пакета, он сам открывается и закрывается по `isReauthRequired` — достаточно смонтировать компонент и при необходимости передать коллбэки (`onSuccess`, `onDismiss`). Для кастомной обёртки (свой BottomSheet и контент) можно использовать **ConfirmAuthPage** и вручную управлять видимостью по `isReauthRequired`. После успешного ввода PIN получите токен из пакета, обновите сессию и закройте реавторизацию. Флаг `isReauthRequired` сбрасывается пакетом автоматически при успехе в ReauthBottomSheet/ConfirmAuthPage; в `onSuccess` достаточно своей логики (обновление сессии, закрытие sheet).
451
+ При 401 интерцепторы вызывают `onReauthRequired`. Можно использовать `isReauthRequired` из `useKeycloakAuth()` как единственный источник правды для отображения реавторизации. Если используете готовый **ReauthBottomSheet** из пакета, он сам открывается и закрывается по `isReauthRequired` — достаточно смонтировать компонент и при необходимости передать коллбэки (`onSuccess`, `onDismiss`). Для кастомной обёртки (свой BottomSheet и контент) можно использовать **ConfirmAuthPage** и вручную управлять видимостью по `isReauthRequired`. После успешного ввода PIN получите access token из пакета, обновите сессию и закройте реавторизацию. Флаг `isReauthRequired` сбрасывается пакетом автоматически при успехе в ReauthBottomSheet/ConfirmAuthPage; в `onSuccess` достаточно своей логики (обновление сессии, закрытие sheet).
427
452
 
428
453
  Пример с кастомным BottomSheet и ConfirmAuthPage (управление видимостью вручную):
429
454
 
@@ -440,9 +465,9 @@ export const CustomReauthSheet = () => {
440
465
  }, [showReauth]);
441
466
 
442
467
  const handleSuccess = useCallback(async () => {
443
- const token = await tokenStorage.getToken();
444
- if (token) {
445
- Session.events.onLogin(token);
468
+ const accessToken = await tokenStorage.getAccessToken();
469
+ if (accessToken) {
470
+ Session.events.onLogin(accessToken);
446
471
  Session.events.onReauthCompleted();
447
472
  }
448
473
  sheetRef.current?.close();
@@ -450,13 +475,35 @@ export const CustomReauthSheet = () => {
450
475
 
451
476
  return (
452
477
  <BottomSheet ref={sheetRef} snapPoints={['50%']} enablePanDownToClose>
453
- <ConfirmAuthPage onSuccess={handleSuccess} pinLength={4} />
478
+ <ConfirmAuthPage mode="reauth" onSuccess={handleSuccess} pinLength={4} />
454
479
  </BottomSheet>
455
480
  );
456
481
  };
457
482
  ```
458
483
 
459
- ### 5. Выход
484
+ ### 5. PIN/биометрия после возврата из background
485
+
486
+ Если `backgroundReauth.enabled !== false`, библиотека отслеживает `AppState`: при возврате из background/inactive через более чем `thresholdMs` миллисекунд открывается `ReauthBottomSheet`.
487
+
488
+ По умолчанию:
489
+
490
+ ```tsx
491
+ <KeycloakProvider
492
+ config={{ url: 'https://sso.example.com', realm: 'my-realm', clientId: 'my-app' }}
493
+ redirectUri="myapp://callback"
494
+ backgroundReauth={{
495
+ enabled: true,
496
+ thresholdMs: 60000,
497
+ internalNetworkMode: 'ip-host-is-internal',
498
+ }}
499
+ >
500
+ <App />
501
+ </KeycloakProvider>
502
+ ```
503
+
504
+ Правило внутренней сети: если host в `config.url` является IP-адресом, сеть считается внутренней и background sheet не показывается; если host является DNS-именем, сеть считается внешней.
505
+
506
+ ### 6. Выход
460
507
 
461
508
  Используйте LogoutButtonIcon или LogoutButtonText. По нажатию открывается Modal с WebViewLogout; при успешном выходе вызывается `onLogoutSuccess` — там очищайте сессию приложения.
462
509
 
@@ -494,17 +541,25 @@ KeycloakProvider → инициализация Keycloak → установка
494
541
 
495
542
  useKeycloakAuthScreen → Login (AuthPage) или Confirm (ConfirmAuthPage)
496
543
 
497
- onSuccessSession.onLogin(token) | onLogoutSession.onLogout + навигация
544
+ ConfirmPIN/биометриятекущий access token или refresh через offline token
545
+
546
+ onSuccess → Session.onLogin(accessToken) | onLogout → Session.onLogout + навигация
498
547
 
499
- axios 401 onReauthRequired → ReauthBottomSheet с ConfirmAuthPage
548
+ axios 401 / background > 60с вне внутренней сети → ReauthBottomSheet с ConfirmAuthPage
500
549
 
501
- onSuccess → tokenStorage.getToken() → Session.onLogin + onReauthCompleted → закрыть sheet
550
+ PIN/биометрияrefresh при необходимости → tokenStorage.getAccessToken() → закрыть sheet
502
551
  ```
503
552
 
504
553
  ---
505
554
 
506
555
  ## Архитектура и безопасность
507
556
 
557
+ ### Mobile client и offline_access
558
+
559
+ Для мобильного приложения используйте Keycloak public client + Authorization Code Flow with PKCE (`S256`). `client_secret` не должен попадать в React Native приложение; confidential client допустим только через backend/BFF.
560
+
561
+ При `offlineAccessEnabled=true` библиотека добавляет `offline_access` в login scope. Keycloak возвращает offline token в поле `refresh_token`; библиотека хранит его в Keychain как `offlineToken`/`refreshToken` и использует только для получения новых access token.
562
+
508
563
  ### Иерархия контекстов
509
564
 
510
565
  ```
@@ -520,9 +575,10 @@ KeycloakConfigProvider ← конфиг (редко меняется)
520
575
  ### Безопасность
521
576
 
522
577
  - Токены в OS Keychain (не AsyncStorage)
523
- - PIN шифруется AES перед сохранением
578
+ - PIN хранится как verifier в Keychain; legacy-хранилище encrypted credentials сохранено только для обратной совместимости
579
+ - Offline token не отправляется в backend и используется только для refresh в Keycloak
524
580
  - Запросы по HTTPS
525
- - Учётные данные не хранятся в открытом виде
581
+ - Username/password не используются для repeat-login в новом offline_access flow
526
582
 
527
583
 
528
584
  ## Экспорты
@@ -1,7 +1,6 @@
1
1
  export declare const CONFIRM_AUTH_PHASE: {
2
- readonly WEBVIEW_DETECT: "webview_detect";
3
2
  readonly PIN: "pin";
4
- readonly WEBVIEW_WITH_CREDENTIALS: "webview_with_credentials";
3
+ readonly WEBVIEW_LOGIN: "webview_login";
5
4
  };
6
5
  export type ConfirmAuthPhase = (typeof CONFIRM_AUTH_PHASE)[keyof typeof CONFIRM_AUTH_PHASE];
7
6
  //# sourceMappingURL=confirmAuthPhase.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirmAuthPhase.d.ts","sourceRoot":"","sources":["../../../src/_lib/types/confirmAuthPhase.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"confirmAuthPhase.d.ts","sourceRoot":"","sources":["../../../src/_lib/types/confirmAuthPhase.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC"}
@@ -1,6 +1,5 @@
1
1
  export const CONFIRM_AUTH_PHASE = {
2
- WEBVIEW_DETECT: 'webview_detect',
3
2
  PIN: 'pin',
4
- WEBVIEW_WITH_CREDENTIALS: 'webview_with_credentials',
3
+ WEBVIEW_LOGIN: 'webview_login',
5
4
  };
6
5
  //# sourceMappingURL=confirmAuthPhase.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirmAuthPhase.js","sourceRoot":"","sources":["../../../src/_lib/types/confirmAuthPhase.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,cAAc,EAAE,gBAAgB;IAChC,GAAG,EAAE,KAAK;IACV,wBAAwB,EAAE,0BAA0B;CAC5C,CAAC"}
1
+ {"version":3,"file":"confirmAuthPhase.js","sourceRoot":"","sources":["../../../src/_lib/types/confirmAuthPhase.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,GAAG,EAAE,KAAK;IACV,aAAa,EAAE,eAAe;CACtB,CAAC"}
@@ -10,7 +10,7 @@ export class KeycloakTokenProvider {
10
10
  return token;
11
11
  }
12
12
  const tokens = await tokenStorage.getTokens();
13
- return tokens?.token || null;
13
+ return tokens?.accessToken || tokens?.token || null;
14
14
  }
15
15
  catch (error) {
16
16
  console.error('[KeycloakTokenProvider] Get token error:', error);
@@ -19,15 +19,15 @@ export class KeycloakTokenProvider {
19
19
  }
20
20
  async refreshToken() {
21
21
  try {
22
- const updated = await this.keycloakClient.updateToken(120);
23
- if (!updated) {
24
- return null;
25
- }
22
+ const updated = await this.keycloakClient.updateToken(-1);
26
23
  const { token, refreshToken, idToken } = this.keycloakClient;
27
24
  if (token) {
25
+ if (!updated) {
26
+ return token;
27
+ }
28
28
  await tokenStorage.saveTokens({
29
- token,
30
- refreshToken: refreshToken ?? undefined,
29
+ accessToken: token,
30
+ offlineToken: refreshToken ?? undefined,
31
31
  idToken: idToken ?? undefined,
32
32
  });
33
33
  return token;
@@ -45,7 +45,7 @@ export class KeycloakTokenProvider {
45
45
  return true;
46
46
  }
47
47
  const tokens = await tokenStorage.getTokens();
48
- return !!tokens?.refreshToken;
48
+ return !!(tokens?.offlineToken || tokens?.refreshToken);
49
49
  }
50
50
  catch (error) {
51
51
  console.error('[KeycloakTokenProvider] Has refresh token error:', error);
@@ -1 +1 @@
1
- {"version":3,"file":"KeycloakTokenProvider.js","sourceRoot":"","sources":["../../../src/axios/adapters/KeycloakTokenProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,4BAA4B,CAAC;AAuBxD,MAAM,OAAO,qBAAqB;IAGhC,YAAY,cAAyC;QACnD,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAMD,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YAEH,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACf,CAAC;YAGD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;YAC9C,OAAO,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;YACjE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IASD,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAE3D,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;YAGD,MAAM,EAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC,cAAc,CAAC;YAC3D,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,YAAY,CAAC,UAAU,CAAC;oBAC5B,KAAK;oBACL,YAAY,EAAE,YAAY,IAAI,SAAS;oBACvC,OAAO,EAAE,OAAO,IAAI,SAAS;iBAC9B,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;YACrE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC;YAEH,IAAI,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC;YACd,CAAC;YAGD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;YAC9C,OAAO,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CAOF"}
1
+ {"version":3,"file":"KeycloakTokenProvider.js","sourceRoot":"","sources":["../../../src/axios/adapters/KeycloakTokenProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,4BAA4B,CAAC;AAuBxD,MAAM,OAAO,qBAAqB;IAGhC,YAAY,cAAyC;QACnD,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAMD,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YAEH,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACf,CAAC;YAGD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;YAC9C,OAAO,MAAM,EAAE,WAAW,IAAI,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;YACjE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IASD,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAG1D,MAAM,EAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC,cAAc,CAAC;YAC3D,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,MAAM,YAAY,CAAC,UAAU,CAAC;oBAC5B,WAAW,EAAE,KAAK;oBAClB,YAAY,EAAE,YAAY,IAAI,SAAS;oBACvC,OAAO,EAAE,OAAO,IAAI,SAAS;iBAC9B,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;YACrE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC;YAEH,IAAI,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC;YACd,CAAC;YAGD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;YAC9C,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,YAAY,IAAI,MAAM,EAAE,YAAY,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CAOF"}
@@ -35,7 +35,7 @@ export const setupAxiosInterceptors = (axiosInstance, config = {}) => {
35
35
  }
36
36
  else {
37
37
  const tokens = await tokenStorage.getTokens();
38
- token = tokens?.token || null;
38
+ token = tokens?.accessToken || tokens?.token || null;
39
39
  }
40
40
  if (token) {
41
41
  const formattedToken = tokenProvider?.formatToken?.(token) || `Bearer ${token}`;
@@ -96,7 +96,7 @@ export const setupAxiosInterceptors = (axiosInstance, config = {}) => {
96
96
  }
97
97
  else {
98
98
  const tokens = await tokenStorage.getTokens();
99
- if (!tokens?.refreshToken) {
99
+ if (!tokens?.offlineToken && !tokens?.refreshToken) {
100
100
  throw new Error('No refresh token available');
101
101
  }
102
102
  console.warn('[AxiosInterceptors] Using deprecated built-in refresh logic. Consider using tokenProvider instead.');
@@ -1 +1 @@
1
- {"version":3,"file":"interceptors.js","sourceRoot":"","sources":["../../src/axios/interceptors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interceptors.js","sourceRoot":"","sources":["../../src/axios/interceptors.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,26 @@
1
1
  import React, { type ReactNode } from 'react';
2
- import type { KeycloakConfig, KeycloakConfigWith2FA } from '../core/types';
2
+ import type { BackgroundReauthConfig, InitRecoveryStrategy, KeycloakConfig, KeycloakConfigWith2FA } from '../core';
3
+ interface KeycloakConfigContextValue {
4
+ config: KeycloakConfig;
5
+ offlineAccessEnabled: boolean;
6
+ backgroundReauth: BackgroundReauthConfig;
7
+ clientSecret?: string;
8
+ getClientSecret?: () => string | undefined | Promise<string | undefined>;
9
+ initRecoveryStrategy: InitRecoveryStrategy;
10
+ refreshPinCheck: () => Promise<void>;
11
+ }
3
12
  export interface KeycloakConfigProviderProps {
4
13
  children: ReactNode;
5
14
  config: KeycloakConfigWith2FA;
15
+ offlineAccessEnabled?: boolean;
16
+ backgroundReauth?: BackgroundReauthConfig;
17
+ clientSecret?: string;
18
+ getClientSecret?: () => string | undefined | Promise<string | undefined>;
19
+ initRecoveryStrategy?: InitRecoveryStrategy;
6
20
  }
7
21
  export declare const KeycloakConfigProvider: React.NamedExoticComponent<KeycloakConfigProviderProps>;
8
22
  export declare const useKeycloakConfig: () => KeycloakConfig;
23
+ export declare const useKeycloakSessionOptions: () => Pick<KeycloakConfigContextValue, "offlineAccessEnabled" | "backgroundReauth" | "clientSecret" | "getClientSecret" | "initRecoveryStrategy">;
9
24
  export declare const useKeycloakConfigRefresh: () => (() => Promise<void>);
25
+ export {};
10
26
  //# sourceMappingURL=KeycloakConfigContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"KeycloakConfigContext.d.ts","sourceRoot":"","sources":["../../src/context/KeycloakConfigContext.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EAEZ,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,cAAc,EAAE,qBAAqB,EAAC,MAAM,eAAe,CAAC;AAWzE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,SAAS,CAAC;IAEpB,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAiBD,eAAO,MAAM,sBAAsB,yDAmClC,CAAC;AASF,eAAO,MAAM,iBAAiB,QAAO,cAQpC,CAAC;AAKF,eAAO,MAAM,wBAAwB,QAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAM/D,CAAC"}
1
+ {"version":3,"file":"KeycloakConfigContext.d.ts","sourceRoot":"","sources":["../../src/context/KeycloakConfigContext.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EAEZ,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAGjB,UAAU,0BAA0B;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,gBAAgB,EAAE,sBAAsB,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACzE,oBAAoB,EAAE,oBAAoB,CAAC;IAE3C,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAID,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,SAAS,CAAC;IAEpB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACzE,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAiBD,eAAO,MAAM,sBAAsB,yDAoElC,CAAC;AASF,eAAO,MAAM,iBAAiB,QAAO,cAQpC,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAO,IAAI,CAC/C,0BAA0B,EACxB,sBAAsB,GACtB,kBAAkB,GAClB,cAAc,GACd,iBAAiB,GACjB,sBAAsB,CAezB,CAAC;AAKF,eAAO,MAAM,wBAAwB,QAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAM/D,CAAC"}
@@ -11,7 +11,7 @@ function getEffectiveConfig(config, pinSet) {
11
11
  ...(config.oidcProvider != null && { oidcProvider: config.oidcProvider }),
12
12
  };
13
13
  }
14
- export const KeycloakConfigProvider = React.memo(({ children, config }) => {
14
+ export const KeycloakConfigProvider = React.memo(({ children, config, offlineAccessEnabled, backgroundReauth, clientSecret, getClientSecret, initRecoveryStrategy, }) => {
15
15
  const [pinSet, setPinSet] = useState(null);
16
16
  useEffect(() => {
17
17
  let mounted = true;
@@ -29,7 +29,28 @@ export const KeycloakConfigProvider = React.memo(({ children, config }) => {
29
29
  setPinSet(hasPin);
30
30
  }, []);
31
31
  const effectiveConfig = useMemo(() => getEffectiveConfig(config, pinSet), [config, pinSet]);
32
- const value = useMemo(() => ({ config: effectiveConfig, refreshPinCheck }), [effectiveConfig, refreshPinCheck]);
32
+ const resolvedOfflineAccessEnabled = offlineAccessEnabled ?? config.offlineAccessEnabled ?? true;
33
+ const resolvedClientSecret = clientSecret ?? config.clientSecret;
34
+ const resolvedGetClientSecret = getClientSecret ?? config.getClientSecret;
35
+ const resolvedInitRecoveryStrategy = initRecoveryStrategy ?? 'none';
36
+ const resolvedBackgroundReauth = useMemo(() => backgroundReauth ?? config.backgroundReauth ?? {}, [backgroundReauth, config.backgroundReauth]);
37
+ const value = useMemo(() => ({
38
+ config: effectiveConfig,
39
+ offlineAccessEnabled: resolvedOfflineAccessEnabled,
40
+ backgroundReauth: resolvedBackgroundReauth,
41
+ clientSecret: resolvedClientSecret,
42
+ getClientSecret: resolvedGetClientSecret,
43
+ initRecoveryStrategy: resolvedInitRecoveryStrategy,
44
+ refreshPinCheck,
45
+ }), [
46
+ effectiveConfig,
47
+ resolvedOfflineAccessEnabled,
48
+ resolvedBackgroundReauth,
49
+ resolvedClientSecret,
50
+ resolvedGetClientSecret,
51
+ resolvedInitRecoveryStrategy,
52
+ refreshPinCheck,
53
+ ]);
33
54
  return (<KeycloakConfigContext.Provider value={value}>{children}</KeycloakConfigContext.Provider>);
34
55
  });
35
56
  KeycloakConfigProvider.displayName = 'KeycloakConfigProvider';
@@ -40,6 +61,19 @@ export const useKeycloakConfig = () => {
40
61
  }
41
62
  return context.config;
42
63
  };
64
+ export const useKeycloakSessionOptions = () => {
65
+ const context = useContext(KeycloakConfigContext);
66
+ if (!context) {
67
+ throw new Error('useKeycloakSessionOptions must be used within KeycloakConfigProvider');
68
+ }
69
+ return {
70
+ offlineAccessEnabled: context.offlineAccessEnabled,
71
+ backgroundReauth: context.backgroundReauth,
72
+ clientSecret: context.clientSecret,
73
+ getClientSecret: context.getClientSecret,
74
+ initRecoveryStrategy: context.initRecoveryStrategy,
75
+ };
76
+ };
43
77
  export const useKeycloakConfigRefresh = () => {
44
78
  const context = useContext(KeycloakConfigContext);
45
79
  if (!context) {
@@ -1 +1 @@
1
- {"version":3,"file":"KeycloakConfigContext.js","sourceRoot":"","sources":["../../src/context/KeycloakConfigContext.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KeycloakConfigContext.js","sourceRoot":"","sources":["../../src/context/KeycloakConfigContext.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EACZ,aAAa,EAEb,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,QAAQ,GACT,MAAM,OAAO,CAAC;AAQf,OAAO,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAa7C,MAAM,qBAAqB,GAAG,aAAa,CAAoC,IAAI,CAAC,CAAC;AAgBrF,SAAS,kBAAkB,CAAC,MAA6B,EAAE,MAAsB;IAC/E,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC;IAEzF,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,WAAY,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACtE,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ;QACR,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,IAAI,EAAC,YAAY,EAAE,MAAM,CAAC,YAAY,EAAC,CAAC;KACxE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC,IAAI,CAC9C,CAAC,EACC,QAAQ,EACR,MAAM,EACN,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,oBAAoB,GACrB,EAAE,EAAE;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAC;IAE3D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,iBAAiB,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACvC,IAAI,OAAO,EAAE,CAAC;gBACZ,SAAS,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC7C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,CAAC;QAChD,SAAS,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,CAAC,MAAM,EAAE,MAAM,CAAC,CACjB,CAAC;IAEF,MAAM,4BAA4B,GAAG,oBAAoB,IAAI,MAAM,CAAC,oBAAoB,IAAI,IAAI,CAAC;IACjG,MAAM,oBAAoB,GAAG,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC;IACjE,MAAM,uBAAuB,GAAG,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC;IAC1E,MAAM,4BAA4B,GAAG,oBAAoB,IAAI,MAAM,CAAC;IACpE,MAAM,wBAAwB,GAAG,OAAO,CACtC,GAAG,EAAE,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,IAAI,EAAE,EACvD,CAAC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAC5C,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,MAAM,EAAE,eAAe;QACvB,oBAAoB,EAAE,4BAA4B;QAClD,gBAAgB,EAAE,wBAAwB;QAC1C,YAAY,EAAE,oBAAoB;QAClC,eAAe,EAAE,uBAAuB;QACxC,oBAAoB,EAAE,4BAA4B;QAClD,eAAe;KAChB,CAAC,EACF;QACE,eAAe;QACf,4BAA4B;QAC5B,wBAAwB;QACxB,oBAAoB;QACpB,uBAAuB;QACvB,4BAA4B;QAC5B,eAAe;KAChB,CACF,CAAC;IAEF,OAAO,CACL,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAC1F,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,sBAAsB,CAAC,WAAW,GAAG,wBAAwB,CAAC;AAO9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAmB,EAAE;IACpD,MAAM,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAElD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAOvC,EAAE;IACF,MAAM,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAElD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO;QACL,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;KACnD,CAAC;AACJ,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAA0B,EAAE;IAClE,MAAM,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,OAAO,CAAC,eAAe,CAAC;AACjC,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import React, { type ReactNode } from 'react';
2
2
  import KeycloakReactNativeClient from '../core/client';
3
+ import type { RNKeycloakInitOptions } from '../core';
3
4
  interface KeycloakInstanceContextValue {
4
5
  keycloak: KeycloakReactNativeClient | null;
5
6
  isInitialized: boolean;
@@ -14,6 +15,7 @@ export interface KeycloakInstanceProviderProps {
14
15
  autoRefreshToken?: boolean;
15
16
  autoRefreshTokenMinValidity?: number;
16
17
  onReauthRequired?: () => void;
18
+ initOnLoad?: RNKeycloakInitOptions['onLoad'];
17
19
  }
18
20
  export declare const KeycloakInstanceProvider: React.NamedExoticComponent<KeycloakInstanceProviderProps>;
19
21
  export declare const useKeycloakInstance: () => KeycloakInstanceContextValue;
@@ -1 +1 @@
1
- {"version":3,"file":"KeycloakInstanceContext.d.ts","sourceRoot":"","sources":["../../src/context/KeycloakInstanceContext.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAEZ,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAGf,OAAO,yBAAyB,MAAM,gBAAgB,CAAC;AAKvD,UAAU,4BAA4B;IACpC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAID,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAErC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAID,eAAO,MAAM,wBAAwB,2DAkIpC,CAAC;AAQF,eAAO,MAAM,mBAAmB,QAAO,4BAQtC,CAAC"}
1
+ {"version":3,"file":"KeycloakInstanceContext.d.ts","sourceRoot":"","sources":["../../src/context/KeycloakInstanceContext.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAEZ,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAGf,OAAO,yBAAyB,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,SAAS,CAAC;AAMnD,UAAU,4BAA4B;IACpC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAID,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAErC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE9B,UAAU,CAAC,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;CAC9C;AAID,eAAO,MAAM,wBAAwB,2DA2LpC,CAAC;AAQF,eAAO,MAAM,mBAAmB,QAAO,4BAQtC,CAAC"}