@ethora/chat-component-rn 26.4.2 → 26.5.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.
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,43 @@
|
|
|
3
3
|
All notable changes to `@ethora/chat-component-rn` are listed here.
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project doesn't follow strict semver yet — version corresponds to the `package.json` field.
|
|
5
5
|
|
|
6
|
+
## [26.05.01]
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`scripts/ensure-emulator.js`** — runs before `expo run:android` (wired into the `android` npm script). If `adb devices` shows nothing connected, resolves `ANDROID_HOME` (env or platform default), picks the first AVD from `emulator -list-avds` (or honours `ETHORA_AVD`), launches it detached, and polls `adb shell getprop sys.boot_completed` until it returns `1` (max 2 min). Eliminates the opaque "No Android connected device found, and no emulators could be started automatically" error that bit first-time developers even when they had AVDs configured. Surfaces clear next-step guidance when `ANDROID_HOME` / platform-tools / emulator / AVDs are missing. ~50 ms overhead on the happy path (device already attached).
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **iOS / Android npm scripts no longer pass `--no-install`.** The previous `--no-install` flag (added then reverted in this release cycle) had the side-effect of skipping `pod install` during `expo run:ios`, which then broke xcodebuild with "The sandbox is not in sync with the Podfile.lock". The actual root cause of the original yarn-install failure was that `yarn.lock` was checked in alongside `package-lock.json`, so expo defaulted to yarn even though the project is npm-managed. Removing `yarn.lock` (see below) restores normal flow without needing `--no-install`.
|
|
15
|
+
- **README's "Build + run" recipe** updated to reflect the npm-only flow + brief note explaining why `yarn.lock` is intentionally absent.
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
|
|
19
|
+
- **`yarn.lock`** — the project is npm-managed (`package-lock.json` is the canonical lockfile, README uses `npm install`, no `packageManager` field in `package.json`). Removing the legacy `yarn.lock` lets `expo run:*` default to npm for its post-prebuild reinstall step. Future contributors should not re-introduce it.
|
|
20
|
+
- **`src/api.config.ts`** — was an orphan duplicate of the repo-root `api.config.ts`, with no importer in the source tree. It was being included in the npm tarball via the package.json `files: [src, ...]` entry, so every consumer was downloading the legacy bundled BASE-app JWT and a hardcoded dev test user (see "Fixed" below for the policy story). Deleted outright since nothing depended on it.
|
|
21
|
+
- **`web/src/api.config.js`** — same orphan-duplicate story as `src/api.config.ts`. Module resolution prefers the `.ts` sibling; nothing imported the `.js` variant.
|
|
22
|
+
|
|
23
|
+
### Fixed (product-code-policy sweep)
|
|
24
|
+
|
|
25
|
+
Removed compiled-in Ethora endpoints, dev-team test credentials, and customer names from the source tree.
|
|
26
|
+
|
|
27
|
+
- **`src/networking/apiClient.ts`** — dropped the dangling import from `../../api.config` (the repo-root file isn't even in the published tarball, so this import would have errored at install time for any consumer). `DEFAULT_BASE_URL` cleared to `''`; `currentAppToken` initialised to `''`. Consumers must now pass `baseUrl` via `<Chat config>` or call `setBaseURL(baseUrl, appToken)` before any REST call.
|
|
28
|
+
|
|
29
|
+
> **Behaviour change**: previously `<Chat>` defaulted to `api.chat.ethora.com/v1` when no `baseUrl` was passed in props. From this release that is no longer the case. If you relied on the implicit cloud default, add `baseUrl: 'https://api.chat.ethora.com/v1'` (or your own host) to your `<Chat config>` block. The README's "Default backend endpoints" section is left in place as a reference for the canonical values.
|
|
30
|
+
|
|
31
|
+
- **`api.config.ts`** (repo root) — appToken / defaultUser / defRoom replaced with `PLACEHOLDER_*` values. Shape preserved so the optional `defaultUser` smoke path in `App.tsx` still compiles after a local edit.
|
|
32
|
+
- **`src/components/MainComponents/LoginWrapper.tsx`** — hardcoded fallback email / password in `loginUserFunction` replaced with empty strings. `loginEmail` now fails cleanly on empty creds (hits catch, returns null) when the consumer hasn't passed `user.email` / `user.password` — same end behaviour, minus the leaked dev credentials.
|
|
33
|
+
- **`web/src/api.config.ts`** — same placeholder treatment as the repo-root file.
|
|
34
|
+
- **`web/src/App.tsx` + `web/src/AppLoginChats.tsx`** — hardcoded `api.chat.ethora.com` plus a `BASE_CONFIG` app id cleared to empty strings. Removed commented-out roomJID literals that referenced a customer subdomain.
|
|
35
|
+
- **`web/src/AppLoginChatsNpm.tsx`** — replaced hardcoded customer dev-environment endpoints with empty strings and rewrote the comment referencing a Slack thread in neutral language ("typical host-integrator flow where an external auth system mints the Ethora user JWT and the chat UI is dropped in beneath it"). The file's dev-recipe value is preserved; its purpose is documented by its shape, not by the specific endpoint.
|
|
36
|
+
- **`AppLoginChatsRn.tsx` `DEFAULT_CREDS`** — `baseUrl` / `xmppHost` / `xmppDevServer` / `conference` cleared to empty strings; the Setup tab opens blank for runtime configuration. (The `@ethora/setup` CLI patches these defaults from an `~/.ethora/profiles.json` profile when it clones the testbed for you.)
|
|
37
|
+
- **`__tests__/appLoginChatsRn.test.tsx`** — the JWT-save flow test now types a `baseUrl` explicitly into the Setup form (was previously relying on the hardcoded default to assert ReduxWrapper's baseUrl).
|
|
38
|
+
|
|
39
|
+
### Fixed (storage-key migration)
|
|
40
|
+
|
|
41
|
+
- **`src/services/pushSubscriptionService.ts`** — `SUBSCRIBED_ROOMS_KEY` renamed to `'ethora_subscribed_rooms'`. To avoid orphaning existing subscriptions on any installed app, `loadSubscribedRoomsFromStorage` now reads the new key first; if it's empty and the legacy key has data, the value is copied across and the legacy key is deleted (wrapped in try/catch so a migration failure can't block the load). `reset()` defensively clears both keys. The legacy-key constant and the migration block can be removed in the next major release.
|
|
42
|
+
|
|
6
43
|
## [26.04.02]
|
|
7
44
|
|
|
8
45
|
### Added
|
package/README.md
CHANGED
|
@@ -285,6 +285,12 @@ The first `expo run:*` will `expo prebuild` to generate `ios/` and
|
|
|
285
285
|
`android/` from `app.json`. Both directories are gitignored — the
|
|
286
286
|
source of truth is `app.json` + the config plugins it lists.
|
|
287
287
|
|
|
288
|
+
This repo uses **npm** (not yarn). `package-lock.json` is the
|
|
289
|
+
canonical lockfile and `yarn.lock` is intentionally absent so
|
|
290
|
+
`expo run:*` defaults to `npm install` for its post-prebuild
|
|
291
|
+
reinstall step. If you prefer yarn for your own work, that's fine —
|
|
292
|
+
just don't commit a `yarn.lock` back into the repo.
|
|
293
|
+
|
|
288
294
|
### Known first-run gotchas
|
|
289
295
|
|
|
290
296
|
- **iOS `pod install` fails on system Ruby**: the Gemfile resolves
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethora/chat-component-rn",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.05.01",
|
|
4
4
|
"description": "Drop-in XMPP chat component for React Native / Expo. <Chat config={...}/> and you're done.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"react-native": "src/main.ts",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"scripts": {
|
|
43
43
|
"postinstall": "patch-package",
|
|
44
44
|
"start": "expo start",
|
|
45
|
-
"android": "expo run:android; node scripts/fix-prebuild-deps.js",
|
|
45
|
+
"android": "node scripts/ensure-emulator.js && (expo run:android; node scripts/fix-prebuild-deps.js)",
|
|
46
46
|
"ios": "expo run:ios; node scripts/fix-prebuild-deps.js",
|
|
47
47
|
"web": "expo start --web",
|
|
48
48
|
"prebuild": "expo prebuild; node scripts/fix-prebuild-deps.js",
|
|
@@ -24,9 +24,12 @@ const LoginWrapper: React.FC<LoginWrapperProps> = ({...props}) => {
|
|
|
24
24
|
|
|
25
25
|
const loginUserFunction = useCallback(async () => {
|
|
26
26
|
try {
|
|
27
|
+
// Per product-code-policy: no compiled-in dev credentials. If the
|
|
28
|
+
// consumer didn't pass `user.email` / `user.password`, the call
|
|
29
|
+
// below fails on empty strings, hits catch, and returns null.
|
|
27
30
|
const authData = await loginEmail(
|
|
28
|
-
props?.user?.email || '
|
|
29
|
-
props?.user?.password || '
|
|
31
|
+
props?.user?.email || '',
|
|
32
|
+
props?.user?.password || '',
|
|
30
33
|
);
|
|
31
34
|
|
|
32
35
|
return {
|
|
@@ -2,13 +2,16 @@ import axios from 'axios';
|
|
|
2
2
|
import { store } from '../roomStore';
|
|
3
3
|
|
|
4
4
|
import { logout, refreshTokens } from '../roomStore/chatSettingsSlice';
|
|
5
|
-
import { appToken as defaultAppToken } from '../../api.config';
|
|
6
5
|
import { installAxiosCapture } from '../utils/devLogger';
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
// Per product-code-policy: no compiled-in Ethora endpoints or tokens.
|
|
8
|
+
// Consumers must call `setBaseURL(baseUrl, appToken)` (or pass
|
|
9
|
+
// `baseUrl` + the token-bearing user / jwt-login config via the
|
|
10
|
+
// top-level `<Chat>` props) before any REST call is issued.
|
|
11
|
+
const DEFAULT_BASE_URL = '';
|
|
9
12
|
|
|
10
13
|
let currentBaseURL = DEFAULT_BASE_URL;
|
|
11
|
-
let currentAppToken: string =
|
|
14
|
+
let currentAppToken: string = '';
|
|
12
15
|
|
|
13
16
|
const http = axios.create({
|
|
14
17
|
baseURL: currentBaseURL,
|
|
@@ -4,7 +4,11 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
4
4
|
import { subscribeToPushNotifications } from '../networking/api-requests/push.api';
|
|
5
5
|
import { subscribeToRoomMessages } from '../networking/xmpp/subscribeToRoomMessages.xmpp';
|
|
6
6
|
|
|
7
|
-
const SUBSCRIBED_ROOMS_KEY = '
|
|
7
|
+
const SUBSCRIBED_ROOMS_KEY = 'ethora_subscribed_rooms';
|
|
8
|
+
// Legacy storage key from before the rename. Read on first load and
|
|
9
|
+
// migrated into SUBSCRIBED_ROOMS_KEY so installed apps don't lose
|
|
10
|
+
// their subscriptions. Safe to remove on the next major version.
|
|
11
|
+
const LEGACY_SUBSCRIBED_ROOMS_KEY = 'preshent_subscribed_rooms';
|
|
8
12
|
|
|
9
13
|
export class PushSubscriptionService {
|
|
10
14
|
private subscribedRooms: Set<string> = new Set();
|
|
@@ -16,7 +20,23 @@ export class PushSubscriptionService {
|
|
|
16
20
|
if (this.isInitialized) {return;}
|
|
17
21
|
|
|
18
22
|
try {
|
|
19
|
-
|
|
23
|
+
let storedRooms = await AsyncStorage.getItem(SUBSCRIBED_ROOMS_KEY);
|
|
24
|
+
if (!storedRooms) {
|
|
25
|
+
// One-time migration from the legacy key.
|
|
26
|
+
try {
|
|
27
|
+
const legacy = await AsyncStorage.getItem(LEGACY_SUBSCRIBED_ROOMS_KEY);
|
|
28
|
+
if (legacy) {
|
|
29
|
+
await AsyncStorage.setItem(SUBSCRIBED_ROOMS_KEY, legacy);
|
|
30
|
+
await AsyncStorage.removeItem(LEGACY_SUBSCRIBED_ROOMS_KEY);
|
|
31
|
+
storedRooms = legacy;
|
|
32
|
+
}
|
|
33
|
+
} catch (migrationError) {
|
|
34
|
+
console.error(
|
|
35
|
+
'[PushService] Legacy storage-key migration failed (subscriptions on this device may be lost):',
|
|
36
|
+
migrationError
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
20
40
|
if (storedRooms) {
|
|
21
41
|
const roomsArray = JSON.parse(storedRooms) as string[];
|
|
22
42
|
this.subscribedRooms = new Set(roomsArray);
|
|
@@ -126,6 +146,9 @@ export class PushSubscriptionService {
|
|
|
126
146
|
|
|
127
147
|
try {
|
|
128
148
|
await AsyncStorage.removeItem(SUBSCRIBED_ROOMS_KEY);
|
|
149
|
+
// Defensive: also clear the legacy key if it somehow survived
|
|
150
|
+
// the migration (e.g. migration failed on first load).
|
|
151
|
+
await AsyncStorage.removeItem(LEGACY_SUBSCRIBED_ROOMS_KEY);
|
|
129
152
|
console.log('[PushService] Subscribed rooms cleared from storage');
|
|
130
153
|
} catch (error) {
|
|
131
154
|
console.error('[PushService] Failed to clear subscribed rooms from storage:', error);
|
package/src/api.config.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
//This is a file with appToken for Ethora and examles how objects look like
|
|
2
|
-
|
|
3
|
-
export const appToken =
|
|
4
|
-
'JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlzVXNlckRhdGFFbmNyeXB0ZWQiOmZhbHNlLCJwYXJlbnRBcHBJZCI6bnVsbCwiaXNBbGxvd2VkTmV3QXBwQ3JlYXRlIjp0cnVlLCJpc0Jhc2VBcHAiOnRydWUsIl9pZCI6IjY0NmNjOGRjOTZkNGE0ZGM4ZjdiMmYyZCIsImRpc3BsYXlOYW1lIjoiRXRob3JhIiwiZG9tYWluTmFtZSI6ImV0aG9yYSIsImNyZWF0b3JJZCI6IjY0NmNjOGQzOTZkNGE0ZGM4ZjdiMmYyNSIsInVzZXJzQ2FuRnJlZSI6dHJ1ZSwiZGVmYXVsdEFjY2Vzc0Fzc2V0c09wZW4iOnRydWUsImRlZmF1bHRBY2Nlc3NQcm9maWxlT3BlbiI6dHJ1ZSwiYnVuZGxlSWQiOiJjb20uZXRob3JhIiwicHJpbWFyeUNvbG9yIjoiIzAwM0U5QyIsInNlY29uZGFyeUNvbG9yIjoiIzI3NzVFQSIsImNvaW5TeW1ib2wiOiJFVE8iLCJjb2luTmFtZSI6IkV0aG9yYSBDb2luIiwiUkVBQ1RfQVBQX0ZJUkVCQVNFX0FQSV9LRVkiOiJBSXphU3lEUWRrdnZ4S0t4NC1XcmpMUW9ZZjA4R0ZBUmdpX3FPNGciLCJSRUFDVF9BUFBfRklSRUJBU0VfQVVUSF9ET01BSU4iOiJldGhvcmEtNjY4ZTkuZmlyZWJhc2VhcHAuY29tIiwiUkVBQ1RfQVBQX0ZJUkVCQVNFX1BST0pFQ1RfSUQiOiJldGhvcmEtNjY4ZTkiLCJSRUFDVF9BUFBfRklSRUJBU0VfU1RPUkFHRV9CVUNLRVQiOiJldGhvcmEtNjY4ZTkuYXBwc3BvdC5jb20iLCJSRUFDVF9BUFBfRklSRUJBU0VfTUVTU0FHSU5HX1NFTkRFUl9JRCI6Ijk3MjkzMzQ3MDA1NCIsIlJFQUNUX0FQUF9GSVJFQkFTRV9BUFBfSUQiOiIxOjk3MjkzMzQ3MDA1NDp3ZWI6ZDQ2ODJlNzZlZjAyZmQ5YjljZGFhNyIsIlJFQUNUX0FQUF9GSVJFQkFTRV9NRUFTVVJNRU5UX0lEIjoiRy1XSE03WFJaNEM4IiwiUkVBQ1RfQVBQX1NUUklQRV9QVUJMSVNIQUJMRV9LRVkiOiIiLCJSRUFDVF9BUFBfU1RSSVBFX1NFQ1JFVF9LRVkiOiIiLCJjcmVhdGVkQXQiOiIyMDIzLTA1LTIzVDE0OjA4OjI4LjEzNloiLCJ1cGRhdGVkQXQiOiIyMDIzLTA1LTIzVDE0OjA4OjI4LjEzNloiLCJfX3YiOjB9LCJpYXQiOjE2ODQ4NTA5MjV9.-IqNVMsf8GyS9Z-_yuNW7hpSmejajjAy-W0J8TadRIM';
|
|
5
|
-
export const defaultUser = {
|
|
6
|
-
_id: '65831a646edcd3cee0545757',
|
|
7
|
-
firstName: 'Raze',
|
|
8
|
-
lastName: 'Yuki',
|
|
9
|
-
xmppPassword: 'HDC7qnWI16',
|
|
10
|
-
walletAddress: '0x6816810a7Fe04FC9b800f9D11564C0e4aEC25D78',
|
|
11
|
-
token:
|
|
12
|
-
'JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJJZCI6IjY1ODMxYTY0NmVkY2QzY2VlMDU0NTc1NyIsImFwcElkIjoiNjQ2Y2M4ZGM5NmQ0YTRkYzhmN2IyZjJkIn0sImlhdCI6MTcxODI1OTMzNCwiZXhwIjoxNzE4MjYwMjM0fQ.-eG07yKkNL6sAFw_-xwBxjios6XtWF6n1MExphyg4W4',
|
|
13
|
-
refreshToken:
|
|
14
|
-
'JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJJZCI6IjY1ODMxYTY0NmVkY2QzY2VlMDU0NTc1NyIsImFwcElkIjoiNjQ2Y2M4ZGM5NmQ0YTRkYzhmN2IyZjJkIn0sImlhdCI6MTcxODI1OTMzNCwiZXhwIjoxNzE4ODY0MTM0fQ.Zs7_eLdefD3i6nEO1b_XbFZA_q9SWFKDghj8HqJ2fC0',
|
|
15
|
-
profileImage:
|
|
16
|
-
'https://lh3.googleusercontent.com/a/ACg8ocLPzhjmRoDe9ZXawhnZN3nd0eEhrqoKwRicJyM6q2z_=s96-c',
|
|
17
|
-
isProfileOpen: true,
|
|
18
|
-
isAssetsOpen: true,
|
|
19
|
-
referrerId: '',
|
|
20
|
-
isAllowedNewAppCreate: true,
|
|
21
|
-
isAgreeWithTerms: false,
|
|
22
|
-
company: [],
|
|
23
|
-
appId: '646cc8dc96d4a4dc8f7b2f2d',
|
|
24
|
-
homeScreen: '',
|
|
25
|
-
defaultWallet: {
|
|
26
|
-
walletAddress: '0x6816810a7Fe04FC9b800f9D11564C0e4aEC25D78',
|
|
27
|
-
},
|
|
28
|
-
email: 'yukiraze9@gmail.com',
|
|
29
|
-
username: '',
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const defRoom = {
|
|
33
|
-
jid: '5f9a4603b2b5bbfa6b228b642127c56d03b778ad594c52b755e605c977303979@conference.xmpp.ethoradev.com',
|
|
34
|
-
};
|